@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
80 lines • 3.76 kB
JavaScript
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
import { fileStreamOp } from "../utils.js";
import { cpGeneric, parseFlags } from "../../cp.js";
import { flatScopes, readdirOp, relayCopy, relayWrite, statOp } from "../utils.js";
import { FlagView } from "../../../../spec/flag_view.js";
import { specOf } from "../../../../spec/builtins.js";
import { rstripSlash } from "../../../../../utils/slash.js";
import { linkView, mountView } from "../../../utils/links.js";
// List a directory for cp -x: a mount root below the operands is empty, so
// the copy makes the mount point and reads nothing on the other filesystem,
// as GNU's --one-file-system does.
function ownFilesystem(readdir, mounts, starts, path) {
if (!starts.has(path.virtual) && mounts.isRoot(path.virtual))
return Promise.resolve([]);
return readdir(path);
}
// The links below a directory that cp -x reaches: none under a mount root its
// listing leaves empty, at or below the directory.
function ownLinks(links, mounts, starts, directory) {
const below = `${rstripSlash(directory)}/`;
return links.subtree(directory).filter(([virtual]) => {
const root = rstripSlash(mounts.rootOf(virtual)) || '/';
return starts.has(root) || !`${root}/`.startsWith(below);
});
}
// Copy operands that span mounts via the shared generic cp. Pure wiring: the
// generic runs in its primitive (no native copy) mode, reading from the
// source mount and writing to the destination mount through dispatch-relayed
// primitives.
export async function runCp(scopes, flagKwargs, dispatch,
// Maps an operand to its storage identity so two prefixes over one
// store compare equal.
storageKey,
// The namespace's links, which a copy that does not follow them recreates
// by name.
vfs,
// The working directory a typed link source resolves against.
cwd = '/',
// Where -i reads its answers.
stdin = null) {
const flat = flatScopes(scopes);
const stat = statOp(dispatch);
const fl = new FlagView(flagKwargs, specOf('cp'));
const mounts = fl.asBool('one_file_system') ? mountView(vfs) : undefined;
const starts = new Set(scopes.map((s) => s.virtual));
const relayed = readdirOp(dispatch);
const readdir = mounts === undefined ? relayed : (p) => ownFilesystem(relayed, mounts, starts, p);
const nsLinks = linkView(vfs);
const links = mounts === undefined || nsLinks === undefined
? nsLinks
: { ...nsLinks, subtree: (d) => ownLinks(nsLinks, mounts, starts, d) };
const write = (p, data) => relayWrite(dispatch, p, data);
const mkdir = async (p) => {
await dispatch('mkdir', p);
};
const copy = (src, dst) => relayCopy(dispatch, src, dst);
const strategy = { read: fileStreamOp(dispatch), write, mkdir, readdir, copy };
return cpGeneric(flat, stat, strategy, parseFlags(fl), storageKey, undefined, undefined, links === undefined
? undefined
: {
links,
dispatch,
cwd,
relay: strategy,
relayStat: stat,
}, stdin, dispatch);
}
//# sourceMappingURL=cp.js.map