UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

123 lines • 4.49 kB
// ========= 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 { IOResult } from "../io/types.js"; import { isBuiltinGrammar, registeredSpec } from "./spec/builtins.js"; import { compileSpec } from "./spec/compile.js"; import { OWN_OPTION_LOOP } from "./spec/constants.js"; import { helpPage, versionLine } from "./spec/standard.js"; /** * One command as a mount registers it: the grammar (with `--help` and * `--version` added), the backend it belongs to, the file extension it * handles (null for every file), the handler, how to merge a run split * across mounts, whether it changes files, and its output limit. */ export class Command { name; spec; vfs; filetype; fn; aggregate; write; limit; constructor(init) { this.name = init.name; this.spec = init.spec; this.vfs = init.vfs; this.filetype = init.filetype ?? null; this.fn = init.fn; this.aggregate = init.aggregate ?? null; this.write = init.write ?? false; this.limit = init.limit ?? null; Object.freeze(this); } } /** A fixed list of commands, looked up by name and file extension. */ export class CommandCatalog extends Array { #byKey; constructor(commands) { super(...commands); const byKey = new Map(); for (const command of commands) { byKey.set(CommandCatalog.key(command.name, command.filetype), command); } this.#byKey = byKey; Object.freeze(this); } get size() { return this.length; } toArray() { return this; } get(name, filetype = null) { return this.#byKey.get(CommandCatalog.key(name, filetype)) ?? null; } require(name, filetype = null) { const found = this.get(name, filetype); if (found === null) { throw new Error(`command '${name}' with filetype ${String(filetype)} is not registered`); } return found; } static key(name, filetype) { return `${name}\0${filetype ?? ''}`; } static get [Symbol.species]() { return Array; } } const ENC = new TextEncoder(); /** * Add `--help` and `--version` to a command, as GNU tools have. * * Either one prints to stdout and exits 0 without running the handler. A * command that declares its own `--version`, or a program that runs its own * option loop (OWN_OPTION_LOOP), answers that option itself. */ function answerStandardOptions(name, spec, fn) { const ownVersion = compileSpec(spec).options.some((o) => o.names.includes('--version')); const ownHelp = isBuiltinGrammar(name, spec) && OWN_OPTION_LOOP.has(name); const helpText = helpPage(name, spec); const versionText = versionLine(name); const wrapped = async (accessor, paths, texts, ctx) => { if (!ownHelp && ctx.flags.help === true) return [ENC.encode(helpText), new IOResult()]; if (!ownVersion && ctx.flags.version === true) { return [ENC.encode(versionText), new IOResult()]; } return fn(accessor, paths, texts, ctx); }; return { spec: registeredSpec(name, spec), fn: wrapped }; } /** * Register a handler as a command of one or more VFSes: one * `Command` per VFS, with the handler wrapped to answer `--help` * and `--version`. */ export function command(options) { const vfsNames = Array.isArray(options.vfs) ? options.vfs : [options.vfs]; const { spec, fn } = answerStandardOptions(options.name, options.spec, options.fn); return vfsNames.map((vfs) => new Command({ name: options.name, spec, vfs, filetype: options.filetype ?? null, fn, aggregate: options.aggregate ?? null, write: options.write ?? false, limit: options.limit ?? null, })); } //# sourceMappingURL=config.js.map