@struktoai/mirage-agents 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +138 -80
- package/dist/chunk-3N5GLSL7.js +33 -0
- package/dist/chunk-3N5GLSL7.js.map +1 -0
- package/dist/{chunk-IMI7BLEG.js → chunk-DIUKTEAK.js} +12 -11
- package/dist/chunk-DIUKTEAK.js.map +1 -0
- package/dist/{chunk-Y4G25V5V.js → chunk-GEO2G6YZ.js} +10 -19
- package/dist/chunk-GEO2G6YZ.js.map +1 -0
- package/dist/{chunk-ZPXFVDYT.js → chunk-S6DWWJVF.js} +1 -1
- package/dist/chunk-S6DWWJVF.js.map +1 -0
- package/dist/{chunk-XEQB7N3F.js → chunk-YJS2FVEB.js} +29 -11
- package/dist/chunk-YJS2FVEB.js.map +1 -0
- package/dist/claude-agent-sdk/index.d.ts +4 -4
- package/dist/claude-agent-sdk/index.js +5 -4
- package/dist/claude-agent-sdk/index.js.map +1 -1
- package/dist/{file-version-Clij-pms.d.ts → file-version-CE2J_nkn.d.ts} +2 -1
- package/dist/langchain/index.d.ts +3 -3
- package/dist/langchain/index.js +21 -5
- package/dist/langchain/index.js.map +1 -1
- package/dist/mastra/index.d.ts +8 -1
- package/dist/mastra/index.js +13 -3
- package/dist/mastra/index.js.map +1 -1
- package/dist/mcp/index.d.ts +4 -4
- package/dist/mcp/index.js +4 -3
- package/dist/mcp/index.js.map +1 -1
- package/dist/openai/index.d.ts +2 -2
- package/dist/openai/index.js +19 -10
- package/dist/openai/index.js.map +1 -1
- package/dist/opencode/index.d.ts +2 -2
- package/dist/opencode/index.js +10 -6
- package/dist/opencode/index.js.map +1 -1
- package/dist/pi/index.d.ts +3 -3
- package/dist/pi/index.js +11 -5
- package/dist/pi/index.js.map +1 -1
- package/dist/{prompt-B_6pxgjj.d.ts → prompt-CgKmMkVe.d.ts} +1 -1
- package/dist/{tool-descriptions-7CgIovZc.d.ts → tool-descriptions-C6xBOUjO.d.ts} +1 -1
- package/dist/vercel/index.d.ts +1 -1
- package/dist/vercel/index.js +5 -3
- package/dist/vercel/index.js.map +1 -1
- package/package.json +26 -23
- package/dist/chunk-IMI7BLEG.js.map +0 -1
- package/dist/chunk-XEQB7N3F.js.map +0 -1
- package/dist/chunk-Y4G25V5V.js.map +0 -1
- package/dist/chunk-ZPXFVDYT.js.map +0 -1
package/dist/openai/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/openai/editor.ts","../../src/openai/execute.ts","../../src/openai/read-file.ts","../../src/openai/shell.ts"],"sourcesContent":["// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Workspace } from '@struktoai/mirage-core'\nimport { applyDiff } from '@openai/agents'\nimport type { ApplyPatchOperation, ApplyPatchResult, Editor } from '@openai/agents'\nimport { gnuDirname } from '@struktoai/mirage-core'\n\nasync function ensureParent(ws: Workspace, path: string): Promise<void> {\n const parent = gnuDirname(path)\n if (parent === '/' || parent === '' || parent === '.') return\n if (await ws.fs.exists(parent)) return\n await ensureParent(ws, parent)\n try {\n await ws.fs.mkdir(parent)\n } catch (err) {\n // Tolerate mkdir race: another caller may have created the dir between exists() and mkdir().\n if (!(await ws.fs.exists(parent))) throw err\n }\n}\n\nexport class MirageEditor implements Editor {\n constructor(private readonly ws: Workspace) {}\n\n async createFile(\n op: Extract<ApplyPatchOperation, { type: 'create_file' }>,\n ): Promise<ApplyPatchResult> {\n await ensureParent(this.ws, op.path)\n const content = applyDiff('', op.diff, 'create')\n await this.ws.fs.writeFile(op.path, content)\n return { status: 'completed' }\n }\n\n async updateFile(\n op: Extract<ApplyPatchOperation, { type: 'update_file' }>,\n ): Promise<ApplyPatchResult> {\n let current: string\n try {\n current = await this.ws.fs.readFileText(op.path)\n } catch {\n return { status: 'failed', output: `File not found: ${op.path}` }\n }\n const next = applyDiff(current, op.diff)\n await this.ws.fs.writeFile(op.path, next)\n return { status: 'completed' }\n }\n\n async deleteFile(\n op: Extract<ApplyPatchOperation, { type: 'delete_file' }>,\n ): Promise<ApplyPatchResult> {\n if (!(await this.ws.fs.exists(op.path))) {\n return { status: 'failed', output: `File not found: ${op.path}` }\n }\n await this.ws.fs.unlink(op.path)\n return { status: 'completed' }\n }\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Workspace } from '@struktoai/mirage-core'\nimport { tool } from '@openai/agents'\nimport { z } from 'zod'\n\nfunction formatExecuteOutput(stdout: string, stderr: string, exitCode: number): string {\n const sections = [`exit code: ${String(exitCode)}`]\n if (stdout !== '') sections.push(`stdout:\\n${stdout}`)\n if (stderr !== '') sections.push(`stderr:\\n${stderr}`)\n return sections.join('\\n')\n}\n\nasync function executeOutput(ws: Workspace, command: string): Promise<string> {\n try {\n const result = await ws.execute(command)\n return formatExecuteOutput(result.stdoutText, result.stderrText, result.exitCode)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return `Unable to execute command: ${message}`\n }\n}\n\nexport function mirageExecuteTool(ws: Workspace) {\n return tool({\n name: 'execute',\n description:\n 'Execute a shell command inside the Mirage workspace and return its stdout, stderr, and exit code.',\n parameters: z.object({\n command: z.string().describe('Shell command to execute inside the Mirage workspace.'),\n }),\n execute: async ({ command }) => executeOutput(ws, command),\n })\n}\n","import type { Workspace } from '@struktoai/mirage-core'\nimport {\n tool,\n type ToolOutputFileContent,\n type ToolOutputImage,\n type ToolOutputText,\n} from '@openai/agents'\nimport { z } from 'zod'\nimport { readWorkspaceFile } from '../read-file.ts'\n\nexport type MirageReadFileOutput = ToolOutputText | ToolOutputImage | ToolOutputFileContent\n\nasync function readFileOutput(ws: Workspace, path: string): Promise<MirageReadFileOutput> {\n try {\n const result = await readWorkspaceFile(ws, path)\n if (result.kind === 'text') {\n return { type: 'text', text: result.content }\n }\n if (result.kind === 'image') {\n return {\n type: 'image',\n image: { data: Uint8Array.from(result.data), mediaType: result.mimeType },\n }\n }\n if (result.kind === 'file') {\n return {\n type: 'file',\n file: {\n data: Uint8Array.from(result.data),\n mediaType: result.mimeType,\n filename: result.filename,\n },\n }\n }\n return { type: 'text', text: result.note }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return { type: 'text', text: `Unable to read ${path}: ${message}` }\n }\n}\n\nexport function mirageReadFileTool(ws: Workspace) {\n return tool({\n name: 'read_file',\n description:\n 'Read a file from the Mirage workspace. Returns UTF-8 text directly, images as model-visible image input, PDFs as model-visible file input, and a metadata description for other binary formats.',\n parameters: z.object({\n path: z.string().describe('Absolute path inside the Mirage workspace.'),\n }),\n execute: async ({ path }) => readFileOutput(ws, path),\n })\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Workspace } from '@struktoai/mirage-core'\nimport type { Shell, ShellAction, ShellResult, ShellOutputResult } from '@openai/agents'\n\nexport class MirageShell implements Shell {\n constructor(private readonly ws: Workspace) {}\n\n async run(action: ShellAction): Promise<ShellResult> {\n const output: ShellOutputResult[] = []\n for (const cmd of action.commands) {\n const io = await this.ws.execute(cmd)\n output.push({\n stdout: io.stdoutText,\n stderr: io.stderrText,\n outcome: { type: 'exit', exitCode: io.exitCode },\n })\n }\n return { output }\n }\n}\n"],"mappings":"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","names":["tool","z","tool","z"]}
|
|
1
|
+
{"version":3,"sources":["../../src/openai/editor.ts","../../src/openai/execute.ts","../../src/openai/read-file.ts","../../src/openai/shell.ts"],"sourcesContent":["// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { gnuDirname } from '@struktoai/mirage-core/utils/path'\nimport type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport { applyDiff } from '@openai/agents'\nimport type { ApplyPatchOperation, ApplyPatchResult, Editor } from '@openai/agents'\n\nasync function ensureParent(ws: Workspace, path: string): Promise<void> {\n const parent = gnuDirname(path)\n if (parent === '/' || parent === '' || parent === '.') return\n if (await ws.fs.exists(parent)) return\n await ensureParent(ws, parent)\n try {\n await ws.fs.mkdir(parent)\n } catch (err) {\n // Tolerate mkdir race: another caller may have created the dir between exists() and mkdir().\n if (!(await ws.fs.exists(parent))) throw err\n }\n}\n\nexport class MirageEditor implements Editor {\n constructor(private readonly ws: Workspace) {}\n\n async createFile(\n op: Extract<ApplyPatchOperation, { type: 'create_file' }>,\n ): Promise<ApplyPatchResult> {\n await ensureParent(this.ws, op.path)\n const content = applyDiff('', op.diff, 'create')\n await this.ws.fs.writeFile(op.path, content)\n return { status: 'completed' }\n }\n\n async updateFile(\n op: Extract<ApplyPatchOperation, { type: 'update_file' }>,\n ): Promise<ApplyPatchResult> {\n let current: string\n try {\n current = await this.ws.fs.readFileText(op.path)\n } catch {\n return { status: 'failed', output: `File not found: ${op.path}` }\n }\n const next = applyDiff(current, op.diff)\n await this.ws.fs.writeFile(op.path, next)\n return { status: 'completed' }\n }\n\n async deleteFile(\n op: Extract<ApplyPatchOperation, { type: 'delete_file' }>,\n ): Promise<ApplyPatchResult> {\n if (!(await this.ws.fs.exists(op.path))) {\n return { status: 'failed', output: `File not found: ${op.path}` }\n }\n await this.ws.fs.unlink(op.path)\n return { status: 'completed' }\n }\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport { tool } from '@openai/agents'\nimport { z } from 'zod'\nimport type { Refusal } from '@struktoai/mirage-core/types'\nimport { withRefusal } from '../io-text.ts'\n\nfunction formatExecuteOutput(\n stdout: string,\n stderr: string,\n exitCode: number,\n refusal: Refusal | null,\n): string {\n const sections = [`exit code: ${String(exitCode)}`]\n if (stdout !== '') sections.push(`stdout:\\n${stdout}`)\n const err = withRefusal(stderr, refusal)\n if (err !== '') sections.push(`stderr:\\n${err}`)\n return sections.join('\\n')\n}\n\nasync function executeOutput(ws: Workspace, command: string): Promise<string> {\n try {\n const result = await ws.execute(command)\n return formatExecuteOutput(\n result.stdoutText,\n result.stderrText,\n result.exitCode,\n result.refusal,\n )\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return `Unable to execute command: ${message}`\n }\n}\n\nexport function mirageExecuteTool(ws: Workspace) {\n return tool({\n name: 'execute',\n description:\n 'Execute a shell command inside the Mirage workspace and return its stdout, stderr, and exit code.',\n parameters: z.object({\n command: z.string().describe('Shell command to execute inside the Mirage workspace.'),\n }),\n execute: async ({ command }) => executeOutput(ws, command),\n })\n}\n","import type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport {\n tool,\n type ToolOutputFileContent,\n type ToolOutputImage,\n type ToolOutputText,\n} from '@openai/agents'\nimport { z } from 'zod'\nimport { readWorkspaceFile } from '../read-file.ts'\n\nexport type MirageReadFileOutput = ToolOutputText | ToolOutputImage | ToolOutputFileContent\n\nasync function readFileOutput(ws: Workspace, path: string): Promise<MirageReadFileOutput> {\n try {\n const result = await readWorkspaceFile(ws, path)\n if (result.kind === 'text') {\n return { type: 'text', text: result.content }\n }\n if (result.kind === 'image') {\n return {\n type: 'image',\n image: { data: Uint8Array.from(result.data), mediaType: result.mimeType },\n }\n }\n if (result.kind === 'file') {\n return {\n type: 'file',\n file: {\n data: Uint8Array.from(result.data),\n mediaType: result.mimeType,\n filename: result.filename,\n },\n }\n }\n return { type: 'text', text: result.note }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return { type: 'text', text: `Unable to read ${path}: ${message}` }\n }\n}\n\nexport function mirageReadFileTool(ws: Workspace) {\n return tool({\n name: 'read_file',\n description:\n 'Read a file from the Mirage workspace. Returns UTF-8 text directly, images as model-visible image input, PDFs as model-visible file input, and a metadata description for other binary formats.',\n parameters: z.object({\n path: z.string().describe('Absolute path inside the Mirage workspace.'),\n }),\n execute: async ({ path }) => readFileOutput(ws, path),\n })\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport type { Shell, ShellAction, ShellResult, ShellOutputResult } from '@openai/agents'\nimport { withRefusal } from '../io-text.ts'\n\nexport class MirageShell implements Shell {\n constructor(private readonly ws: Workspace) {}\n\n async run(action: ShellAction): Promise<ShellResult> {\n const output: ShellOutputResult[] = []\n for (const cmd of action.commands) {\n const io = await this.ws.execute(cmd)\n output.push({\n stdout: io.stdoutText,\n stderr: withRefusal(io.stderrText, io.refusal),\n outcome: { type: 'exit', exitCode: io.exitCode },\n })\n }\n return { output }\n }\n}\n"],"mappings":"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","names":["tool","z","tool","z"]}
|
package/dist/opencode/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ToolContext, Plugin, ToolDefinition } from '@opencode-ai/plugin';
|
|
2
2
|
import { Workspace } from '@struktoai/mirage-node';
|
|
3
|
-
export { S as StaleMirageFileError } from '../file-version-
|
|
4
|
-
import '@struktoai/mirage-core';
|
|
3
|
+
export { S as StaleMirageFileError } from '../file-version-CE2J_nkn.js';
|
|
4
|
+
import '@struktoai/mirage-core/workspace/workspace/workspace';
|
|
5
5
|
|
|
6
6
|
type WsResolver = (ctx: ToolContext) => Workspace | Promise<Workspace>;
|
|
7
7
|
type WsLike = Workspace | WsResolver;
|
package/dist/opencode/index.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
readWorkspaceFile
|
|
3
|
-
} from "../chunk-IMI7BLEG.js";
|
|
4
1
|
import {
|
|
5
2
|
FileVersionTracker,
|
|
6
3
|
StaleMirageFileError
|
|
7
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-YJS2FVEB.js";
|
|
5
|
+
import {
|
|
6
|
+
withRefusal
|
|
7
|
+
} from "../chunk-3N5GLSL7.js";
|
|
8
|
+
import {
|
|
9
|
+
readWorkspaceFile
|
|
10
|
+
} from "../chunk-DIUKTEAK.js";
|
|
8
11
|
|
|
9
12
|
// src/opencode/index.ts
|
|
10
13
|
import { tool } from "@opencode-ai/plugin";
|
|
11
|
-
import { encodeBase64
|
|
14
|
+
import { encodeBase64 } from "@struktoai/mirage-core/utils/base64";
|
|
15
|
+
import { gnuDirname } from "@struktoai/mirage-core/utils/path";
|
|
12
16
|
var z = tool.schema;
|
|
13
17
|
function isResolver(ws) {
|
|
14
18
|
return typeof ws === "function";
|
|
@@ -162,7 +166,7 @@ function mirageTools(ws, options = {}) {
|
|
|
162
166
|
const parts = [];
|
|
163
167
|
if (io.stdoutText.length > 0) parts.push(io.stdoutText);
|
|
164
168
|
if (io.stderrText.length > 0) parts.push(io.stderrText);
|
|
165
|
-
return parts.join("\n").trim();
|
|
169
|
+
return withRefusal(parts.join("\n"), io.refusal).trim();
|
|
166
170
|
}
|
|
167
171
|
});
|
|
168
172
|
const glob = tool({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/opencode/index.ts"],"sourcesContent":["// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { tool, type Plugin, type ToolContext, type ToolDefinition } from '@opencode-ai/plugin'\nimport type { Workspace } from '@struktoai/mirage-node'\nimport { encodeBase64, gnuDirname } from '@struktoai/mirage-core'\nimport { FileVersionTracker } from '../file-version.ts'\nimport { readWorkspaceFile } from '../read-file.ts'\n\nconst z = tool.schema\n\nexport type WsResolver = (ctx: ToolContext) => Workspace | Promise<Workspace>\nexport type WsLike = Workspace | WsResolver\n\nexport interface MirageOpenCodeOptions {\n staleWriteProtection?: boolean\n}\n\ntype SessionTrackers = Map<string, FileVersionTracker>\n\nfunction isResolver(ws: WsLike): ws is WsResolver {\n return typeof ws === 'function'\n}\n\nasync function resolveWs(ws: WsLike, ctx: ToolContext): Promise<Workspace> {\n return isResolver(ws) ? ws(ctx) : ws\n}\n\nasync function ensureParent(ws: Workspace, path: string): Promise<void> {\n const parent = gnuDirname(path)\n if (parent === '/' || parent === '' || parent === '.') return\n if (await ws.fs.exists(parent)) return\n await ensureParent(ws, parent)\n try {\n await ws.fs.mkdir(parent)\n } catch (err) {\n if (!(await ws.fs.exists(parent))) throw err\n }\n}\n\nfunction errMsg(err: unknown): string {\n return err instanceof Error ? err.message : String(err)\n}\n\nfunction trackerFor(\n trackers: WeakMap<Workspace, SessionTrackers>,\n ws: Workspace,\n ctx: ToolContext,\n enabled: boolean,\n): FileVersionTracker {\n let sessions = trackers.get(ws)\n if (sessions === undefined) {\n sessions = new Map<string, FileVersionTracker>()\n trackers.set(ws, sessions)\n }\n let tracker = sessions.get(ctx.sessionID)\n if (tracker === undefined) {\n tracker = new FileVersionTracker(ws, enabled)\n sessions.set(ctx.sessionID, tracker)\n }\n return tracker\n}\n\nexport function mirageTools(\n ws: WsLike,\n options: MirageOpenCodeOptions = {},\n): Record<string, ToolDefinition> {\n const trackers = new WeakMap<Workspace, SessionTrackers>()\n const staleWriteProtection = options.staleWriteProtection ?? true\n const read = tool({\n description:\n 'Read a file. Returns UTF-8 text for source/data files, attaches PDFs and images for multimodal models, and returns metadata for other binary files.',\n args: {\n filePath: z.string().describe('Absolute path of the file to read.'),\n },\n execute: async ({ filePath }, ctx) => {\n const w = await resolveWs(ws, ctx)\n const versions = trackerFor(trackers, w, ctx, staleWriteProtection)\n try {\n const result = await readWorkspaceFile(w, filePath, versions.read.bind(versions))\n if (result.kind === 'text') return result.content\n if (result.kind === 'image' || result.kind === 'file') {\n const filename = result.path.split('/').pop() ?? result.path\n return {\n output: `${result.path} (${result.mimeType}, ${String(result.bytes)} bytes)`,\n attachments: [\n {\n type: 'file' as const,\n mime: result.mimeType,\n url: `data:${result.mimeType};base64,${encodeBase64(result.data)}`,\n filename,\n },\n ],\n }\n }\n return result.note\n } catch (err) {\n return `Error: ${errMsg(err)}`\n }\n },\n })\n\n const write = tool({\n description: 'Write content to a file. Creates missing parent directories.',\n args: {\n filePath: z.string().describe('Absolute path of the file to write.'),\n content: z.string().describe('UTF-8 text content to write.'),\n },\n execute: async ({ filePath, content }, ctx) => {\n const w = await resolveWs(ws, ctx)\n const versions = trackerFor(trackers, w, ctx, staleWriteProtection)\n try {\n await ensureParent(w, filePath)\n await versions.write(filePath, content)\n return `Wrote ${String(content.length)} bytes to ${filePath}`\n } catch (err) {\n return `Error: ${errMsg(err)}`\n }\n },\n })\n\n const edit = tool({\n description:\n 'Replace a string inside an existing file. Errors if the string appears more than once unless replaceAll is true.',\n args: {\n filePath: z.string().describe('Absolute path of the file to edit.'),\n oldString: z.string().describe('The exact string to replace.'),\n newString: z.string().describe('The replacement string.'),\n replaceAll: z\n .boolean()\n .optional()\n .describe('Replace every occurrence rather than requiring a unique match.'),\n },\n execute: async ({ filePath, oldString, newString, replaceAll }, ctx) => {\n const w = await resolveWs(ws, ctx)\n const versions = trackerFor(trackers, w, ctx, staleWriteProtection)\n let current: string\n try {\n current = (await versions.readForEdit(filePath)).toString('utf8')\n } catch (err) {\n if (await w.fs.exists(filePath)) return `Error: ${errMsg(err)}`\n return `Error: file '${filePath}' not found`\n }\n const count = current.split(oldString).length - 1\n if (count === 0) {\n return `Error: string not found in file: '${oldString}'`\n }\n if (count > 1 && replaceAll !== true) {\n return `Error: string '${oldString}' appears ${String(count)} times. Use replaceAll=true`\n }\n const next =\n replaceAll === true\n ? current.split(oldString).join(newString)\n : current.replace(oldString, newString)\n try {\n await versions.writeEdit(filePath, next)\n } catch (err) {\n return `Error: ${errMsg(err)}`\n }\n const occurrences = replaceAll === true ? count : 1\n return `Edited ${filePath} (${String(occurrences)} occurrence${occurrences === 1 ? '' : 's'})`\n },\n })\n\n const ls = tool({\n description: 'List entries of a directory.',\n args: {\n path: z.string().describe('Absolute directory path.'),\n },\n execute: async ({ path }, ctx) => {\n const w = await resolveWs(ws, ctx)\n let entries: string[]\n try {\n entries = await w.fs.readdir(path)\n } catch (err) {\n return `Error: ${errMsg(err)}`\n }\n const lines: string[] = []\n for (const entry of entries) {\n const isDir = await w.fs.isDir(entry)\n lines.push(isDir ? `${entry}/` : entry)\n }\n return lines.join('\\n')\n },\n })\n\n const bash = tool({\n description: 'Execute a shell command and return stdout, stderr, and exit code.',\n args: {\n command: z.string().describe('The shell command to execute.'),\n },\n execute: async ({ command }, ctx) => {\n const w = await resolveWs(ws, ctx)\n const io = await w.execute(command)\n const parts: string[] = []\n if (io.stdoutText.length > 0) parts.push(io.stdoutText)\n if (io.stderrText.length > 0) parts.push(io.stderrText)\n return parts.join('\\n').trim()\n },\n })\n\n const glob = tool({\n description: 'Find files matching a name pattern.',\n args: {\n pattern: z.string().describe('Filename pattern (e.g. \"*.ts\").'),\n path: z.string().optional().describe('Directory to search under. Defaults to /.'),\n },\n execute: async ({ pattern, path }, ctx) => {\n const w = await resolveWs(ws, ctx)\n const root = path ?? '/'\n const io = await w.execute(`find ${root} -name '${pattern.replace(/'/g, \"'\\\\''\")}'`)\n return io.stdoutText.trim()\n },\n })\n\n const grep = tool({\n description: 'Search for a regex pattern in files.',\n args: {\n pattern: z.string().describe('Pattern to search for.'),\n path: z.string().optional().describe('Directory or file to search under. Defaults to /.'),\n },\n execute: async ({ pattern, path }, ctx) => {\n const w = await resolveWs(ws, ctx)\n const root = path ?? '/'\n const escaped = pattern.replace(/'/g, \"'\\\\''\")\n const io = await w.execute(`grep -rn '${escaped}' ${root}`)\n return io.stdoutText.trim()\n },\n })\n\n return { read, write, edit, ls, bash, glob, grep }\n}\n\nexport function miragePlugin(ws: WsLike, options: MirageOpenCodeOptions = {}): Plugin {\n return () => Promise.resolve({ tool: mirageTools(ws, options) })\n}\n\nexport { StaleMirageFileError } from '../file-version.ts'\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/opencode/index.ts"],"sourcesContent":["// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { tool, type Plugin, type ToolContext, type ToolDefinition } from '@opencode-ai/plugin'\nimport type { Workspace } from '@struktoai/mirage-node'\nimport { encodeBase64 } from '@struktoai/mirage-core/utils/base64'\nimport { gnuDirname } from '@struktoai/mirage-core/utils/path'\nimport { FileVersionTracker } from '../file-version.ts'\nimport { readWorkspaceFile } from '../read-file.ts'\nimport { withRefusal } from '../io-text.ts'\n\nconst z = tool.schema\n\nexport type WsResolver = (ctx: ToolContext) => Workspace | Promise<Workspace>\nexport type WsLike = Workspace | WsResolver\n\nexport interface MirageOpenCodeOptions {\n staleWriteProtection?: boolean\n}\n\ntype SessionTrackers = Map<string, FileVersionTracker>\n\nfunction isResolver(ws: WsLike): ws is WsResolver {\n return typeof ws === 'function'\n}\n\nasync function resolveWs(ws: WsLike, ctx: ToolContext): Promise<Workspace> {\n return isResolver(ws) ? ws(ctx) : ws\n}\n\nasync function ensureParent(ws: Workspace, path: string): Promise<void> {\n const parent = gnuDirname(path)\n if (parent === '/' || parent === '' || parent === '.') return\n if (await ws.fs.exists(parent)) return\n await ensureParent(ws, parent)\n try {\n await ws.fs.mkdir(parent)\n } catch (err) {\n if (!(await ws.fs.exists(parent))) throw err\n }\n}\n\nfunction errMsg(err: unknown): string {\n return err instanceof Error ? err.message : String(err)\n}\n\nfunction trackerFor(\n trackers: WeakMap<Workspace, SessionTrackers>,\n ws: Workspace,\n ctx: ToolContext,\n enabled: boolean,\n): FileVersionTracker {\n let sessions = trackers.get(ws)\n if (sessions === undefined) {\n sessions = new Map<string, FileVersionTracker>()\n trackers.set(ws, sessions)\n }\n let tracker = sessions.get(ctx.sessionID)\n if (tracker === undefined) {\n tracker = new FileVersionTracker(ws, enabled)\n sessions.set(ctx.sessionID, tracker)\n }\n return tracker\n}\n\nexport function mirageTools(\n ws: WsLike,\n options: MirageOpenCodeOptions = {},\n): Record<string, ToolDefinition> {\n const trackers = new WeakMap<Workspace, SessionTrackers>()\n const staleWriteProtection = options.staleWriteProtection ?? true\n const read = tool({\n description:\n 'Read a file. Returns UTF-8 text for source/data files, attaches PDFs and images for multimodal models, and returns metadata for other binary files.',\n args: {\n filePath: z.string().describe('Absolute path of the file to read.'),\n },\n execute: async ({ filePath }, ctx) => {\n const w = await resolveWs(ws, ctx)\n const versions = trackerFor(trackers, w, ctx, staleWriteProtection)\n try {\n const result = await readWorkspaceFile(w, filePath, versions.read.bind(versions))\n if (result.kind === 'text') return result.content\n if (result.kind === 'image' || result.kind === 'file') {\n const filename = result.path.split('/').pop() ?? result.path\n return {\n output: `${result.path} (${result.mimeType}, ${String(result.bytes)} bytes)`,\n attachments: [\n {\n type: 'file' as const,\n mime: result.mimeType,\n url: `data:${result.mimeType};base64,${encodeBase64(result.data)}`,\n filename,\n },\n ],\n }\n }\n return result.note\n } catch (err) {\n return `Error: ${errMsg(err)}`\n }\n },\n })\n\n const write = tool({\n description: 'Write content to a file. Creates missing parent directories.',\n args: {\n filePath: z.string().describe('Absolute path of the file to write.'),\n content: z.string().describe('UTF-8 text content to write.'),\n },\n execute: async ({ filePath, content }, ctx) => {\n const w = await resolveWs(ws, ctx)\n const versions = trackerFor(trackers, w, ctx, staleWriteProtection)\n try {\n await ensureParent(w, filePath)\n await versions.write(filePath, content)\n return `Wrote ${String(content.length)} bytes to ${filePath}`\n } catch (err) {\n return `Error: ${errMsg(err)}`\n }\n },\n })\n\n const edit = tool({\n description:\n 'Replace a string inside an existing file. Errors if the string appears more than once unless replaceAll is true.',\n args: {\n filePath: z.string().describe('Absolute path of the file to edit.'),\n oldString: z.string().describe('The exact string to replace.'),\n newString: z.string().describe('The replacement string.'),\n replaceAll: z\n .boolean()\n .optional()\n .describe('Replace every occurrence rather than requiring a unique match.'),\n },\n execute: async ({ filePath, oldString, newString, replaceAll }, ctx) => {\n const w = await resolveWs(ws, ctx)\n const versions = trackerFor(trackers, w, ctx, staleWriteProtection)\n let current: string\n try {\n current = (await versions.readForEdit(filePath)).toString('utf8')\n } catch (err) {\n if (await w.fs.exists(filePath)) return `Error: ${errMsg(err)}`\n return `Error: file '${filePath}' not found`\n }\n const count = current.split(oldString).length - 1\n if (count === 0) {\n return `Error: string not found in file: '${oldString}'`\n }\n if (count > 1 && replaceAll !== true) {\n return `Error: string '${oldString}' appears ${String(count)} times. Use replaceAll=true`\n }\n const next =\n replaceAll === true\n ? current.split(oldString).join(newString)\n : current.replace(oldString, newString)\n try {\n await versions.writeEdit(filePath, next)\n } catch (err) {\n return `Error: ${errMsg(err)}`\n }\n const occurrences = replaceAll === true ? count : 1\n return `Edited ${filePath} (${String(occurrences)} occurrence${occurrences === 1 ? '' : 's'})`\n },\n })\n\n const ls = tool({\n description: 'List entries of a directory.',\n args: {\n path: z.string().describe('Absolute directory path.'),\n },\n execute: async ({ path }, ctx) => {\n const w = await resolveWs(ws, ctx)\n let entries: string[]\n try {\n entries = await w.fs.readdir(path)\n } catch (err) {\n return `Error: ${errMsg(err)}`\n }\n const lines: string[] = []\n for (const entry of entries) {\n const isDir = await w.fs.isDir(entry)\n lines.push(isDir ? `${entry}/` : entry)\n }\n return lines.join('\\n')\n },\n })\n\n const bash = tool({\n description: 'Execute a shell command and return stdout, stderr, and exit code.',\n args: {\n command: z.string().describe('The shell command to execute.'),\n },\n execute: async ({ command }, ctx) => {\n const w = await resolveWs(ws, ctx)\n const io = await w.execute(command)\n const parts: string[] = []\n if (io.stdoutText.length > 0) parts.push(io.stdoutText)\n if (io.stderrText.length > 0) parts.push(io.stderrText)\n return withRefusal(parts.join('\\n'), io.refusal).trim()\n },\n })\n\n const glob = tool({\n description: 'Find files matching a name pattern.',\n args: {\n pattern: z.string().describe('Filename pattern (e.g. \"*.ts\").'),\n path: z.string().optional().describe('Directory to search under. Defaults to /.'),\n },\n execute: async ({ pattern, path }, ctx) => {\n const w = await resolveWs(ws, ctx)\n const root = path ?? '/'\n const io = await w.execute(`find ${root} -name '${pattern.replace(/'/g, \"'\\\\''\")}'`)\n return io.stdoutText.trim()\n },\n })\n\n const grep = tool({\n description: 'Search for a regex pattern in files.',\n args: {\n pattern: z.string().describe('Pattern to search for.'),\n path: z.string().optional().describe('Directory or file to search under. Defaults to /.'),\n },\n execute: async ({ pattern, path }, ctx) => {\n const w = await resolveWs(ws, ctx)\n const root = path ?? '/'\n const escaped = pattern.replace(/'/g, \"'\\\\''\")\n const io = await w.execute(`grep -rn '${escaped}' ${root}`)\n return io.stdoutText.trim()\n },\n })\n\n return { read, write, edit, ls, bash, glob, grep }\n}\n\nexport function miragePlugin(ws: WsLike, options: MirageOpenCodeOptions = {}): Plugin {\n return () => Promise.resolve({ tool: mirageTools(ws, options) })\n}\n\nexport { StaleMirageFileError } from '../file-version.ts'\n"],"mappings":"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","names":[]}
|
package/dist/pi/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Workspace } from '@struktoai/mirage-core';
|
|
1
|
+
import { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace';
|
|
2
2
|
import { ReadOperations, WriteOperations, EditOperations, BashOperations, GrepOperations, FindOperations, LsOperations, InlineExtension } from '@earendil-works/pi-coding-agent';
|
|
3
|
-
export { B as BuildSystemPromptOptions, M as MIRAGE_SYSTEM_PROMPT, b as buildSystemPrompt } from '../prompt-
|
|
4
|
-
export { S as StaleMirageFileError } from '../file-version-
|
|
3
|
+
export { B as BuildSystemPromptOptions, M as MIRAGE_SYSTEM_PROMPT, b as buildSystemPrompt } from '../prompt-CgKmMkVe.js';
|
|
4
|
+
export { S as StaleMirageFileError } from '../file-version-CE2J_nkn.js';
|
|
5
5
|
|
|
6
6
|
interface MirageOperationsOptions {
|
|
7
7
|
staleWriteProtection?: boolean;
|
package/dist/pi/index.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FileVersionTracker,
|
|
3
|
+
StaleMirageFileError
|
|
4
|
+
} from "../chunk-YJS2FVEB.js";
|
|
1
5
|
import {
|
|
2
6
|
MIRAGE_SYSTEM_PROMPT,
|
|
3
7
|
buildSystemPrompt
|
|
4
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-S6DWWJVF.js";
|
|
5
9
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from "../chunk-
|
|
10
|
+
decode,
|
|
11
|
+
refusalLine
|
|
12
|
+
} from "../chunk-3N5GLSL7.js";
|
|
9
13
|
|
|
10
14
|
// src/pi/extension.ts
|
|
11
15
|
import {
|
|
@@ -19,7 +23,7 @@ import {
|
|
|
19
23
|
} from "@earendil-works/pi-coding-agent";
|
|
20
24
|
|
|
21
25
|
// src/pi/operations.ts
|
|
22
|
-
import { rstripSlash } from "@struktoai/mirage-core";
|
|
26
|
+
import { rstripSlash } from "@struktoai/mirage-core/utils/slash";
|
|
23
27
|
import picomatch from "picomatch";
|
|
24
28
|
async function ensureParent(ws, dir) {
|
|
25
29
|
const norm = rstripSlash(dir) || "/";
|
|
@@ -89,6 +93,8 @@ function mirageOperations(ws, options = {}) {
|
|
|
89
93
|
if (result.stderr.length > 0) {
|
|
90
94
|
options2.onData(Buffer.from(result.stderr));
|
|
91
95
|
}
|
|
96
|
+
const why = refusalLine(decode(result.stdout) + decode(result.stderr), result.refusal);
|
|
97
|
+
if (why.length > 0) options2.onData(Buffer.from(why));
|
|
92
98
|
return { exitCode: result.exitCode };
|
|
93
99
|
}
|
|
94
100
|
};
|
package/dist/pi/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/pi/extension.ts","../../src/pi/operations.ts"],"sourcesContent":["// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Workspace } from '@struktoai/mirage-core'\nimport {\n createBashToolDefinition,\n createEditToolDefinition,\n createFindToolDefinition,\n createGrepToolDefinition,\n createLsToolDefinition,\n createReadToolDefinition,\n createWriteToolDefinition,\n type BashOperations,\n type InlineExtension,\n} from '@earendil-works/pi-coding-agent'\nimport { buildSystemPrompt } from '../prompt.ts'\nimport { mirageOperations, type MirageOperationsOptions } from './operations.ts'\n\nexport interface MirageExtensionOptions extends MirageOperationsOptions {\n cwd?: string\n systemPrompt?: string | false\n}\n\nfunction bashAtCwd(operations: BashOperations, cwd: string): BashOperations {\n return {\n exec: (command, _hostCwd, options) => operations.exec(command, cwd, options),\n }\n}\n\nexport function mirageExtension(ws: Workspace, opts: MirageExtensionOptions = {}): InlineExtension {\n const cwd = opts.cwd ?? '/'\n const ops = mirageOperations(ws, opts)\n const userBash = bashAtCwd(ops.bash, cwd)\n const systemPrompt =\n opts.systemPrompt === false\n ? undefined\n : (opts.systemPrompt ?? buildSystemPrompt({ workspace: ws }))\n return {\n name: 'mirage',\n factory: (pi) => {\n pi.registerTool(createReadToolDefinition(cwd, { operations: ops.read }))\n pi.registerTool(createWriteToolDefinition(cwd, { operations: ops.write }))\n pi.registerTool(createEditToolDefinition(cwd, { operations: ops.edit }))\n pi.registerTool(createBashToolDefinition(cwd, { operations: ops.bash }))\n pi.registerTool(createGrepToolDefinition(cwd, { operations: ops.grep }))\n pi.registerTool(createFindToolDefinition(cwd, { operations: ops.find }))\n pi.registerTool(createLsToolDefinition(cwd, { operations: ops.ls }))\n pi.on('user_bash', () => ({ operations: userBash }))\n if (systemPrompt !== undefined) {\n pi.on('before_agent_start', (event) => ({\n systemPrompt: `${event.systemPrompt}\\n\\n${systemPrompt}`,\n }))\n }\n },\n }\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { rstripSlash, type ExecuteResult, type Workspace } from '@struktoai/mirage-core'\nimport type {\n BashOperations,\n EditOperations,\n FindOperations,\n GrepOperations,\n LsOperations,\n ReadOperations,\n WriteOperations,\n} from '@earendil-works/pi-coding-agent'\nimport picomatch from 'picomatch'\nimport { FileVersionTracker } from '../file-version.ts'\n\nexport { StaleMirageFileError } from '../file-version.ts'\n\nexport interface MirageOperationsOptions {\n staleWriteProtection?: boolean\n}\n\nexport interface MirageOperationsBundle {\n read: ReadOperations\n write: WriteOperations\n edit: EditOperations\n bash: BashOperations\n grep: GrepOperations\n find: FindOperations\n ls: LsOperations\n}\n\nasync function ensureParent(ws: Workspace, dir: string): Promise<void> {\n const norm = rstripSlash(dir) || '/'\n if (norm === '/' || (await ws.fs.exists(norm))) return\n const parent = norm.substring(0, norm.lastIndexOf('/')) || '/'\n await ensureParent(ws, parent)\n try {\n await ws.fs.mkdir(norm)\n } catch (err) {\n if (await ws.fs.isDir(norm)) return\n throw err\n }\n}\n\ninterface WalkOptions {\n ignoreMatchers: ((path: string) => boolean)[]\n limit: number\n}\n\nasync function walkDirectory(\n ws: Workspace,\n dir: string,\n cwdPrefix: string,\n matcher: (relativePath: string) => boolean,\n opts: WalkOptions,\n results: string[],\n): Promise<void> {\n if (results.length >= opts.limit) return\n const entries = await ws.fs.readdir(dir)\n for (const full of entries) {\n if (results.length >= opts.limit) return\n const rel = full.startsWith(cwdPrefix) ? full.slice(cwdPrefix.length) : full\n if (opts.ignoreMatchers.some((m) => m(rel))) continue\n const isDir = await ws.fs.isDir(full)\n if (matcher(rel)) results.push(full)\n if (isDir) await walkDirectory(ws, full, cwdPrefix, matcher, opts, results)\n }\n}\n\nexport function mirageOperations(\n ws: Workspace,\n options: MirageOperationsOptions = {},\n): MirageOperationsBundle {\n const versions = new FileVersionTracker(ws, options.staleWriteProtection ?? true)\n const read: ReadOperations = {\n readFile: (absolutePath: string) => versions.read(absolutePath),\n access: async (absolutePath: string) => {\n await ws.fs.stat(absolutePath)\n },\n }\n\n const write: WriteOperations = {\n writeFile: (absolutePath: string, content: string) => versions.write(absolutePath, content),\n mkdir: async (dir: string) => {\n await ensureParent(ws, dir)\n if (!(await ws.fs.exists(dir))) {\n await ws.fs.mkdir(dir)\n }\n },\n }\n\n const edit: EditOperations = {\n readFile: (absolutePath: string) => versions.readForEdit(absolutePath),\n writeFile: (absolutePath: string, content: string) => versions.writeEdit(absolutePath, content),\n access: read.access,\n }\n\n const bash: BashOperations = {\n exec: async (command, cwd, options) => {\n const timeoutSignal =\n options.timeout !== undefined && options.timeout > 0\n ? AbortSignal.timeout(options.timeout * 1000)\n : undefined\n const signal =\n options.signal !== undefined && timeoutSignal !== undefined\n ? AbortSignal.any([options.signal, timeoutSignal])\n : (options.signal ?? timeoutSignal)\n let result: ExecuteResult\n try {\n result =\n signal === undefined\n ? await ws.execute(command, { cwd })\n : await ws.execute(command, { cwd, signal })\n } catch (error) {\n if (options.signal?.aborted === true) {\n throw new Error('aborted')\n }\n if (timeoutSignal?.aborted === true) {\n throw new Error('timeout:' + String(options.timeout))\n }\n throw error\n }\n if (result.stdout.length > 0) {\n options.onData(Buffer.from(result.stdout))\n }\n if (result.stderr.length > 0) {\n options.onData(Buffer.from(result.stderr))\n }\n return { exitCode: result.exitCode }\n },\n }\n\n const grep: GrepOperations = {\n isDirectory: async (absolutePath: string) => ws.fs.isDir(absolutePath),\n readFile: async (absolutePath: string) => (await versions.read(absolutePath)).toString('utf-8'),\n }\n\n const find: FindOperations = {\n exists: async (absolutePath: string) => ws.fs.exists(absolutePath),\n glob: async (pattern, cwd, options) => {\n const matcher = picomatch(pattern, { dot: false })\n const ignoreMatchers = options.ignore.map((p) => picomatch(p, { dot: false }))\n const root = rstripSlash(cwd) || '/'\n const cwdPrefix = root === '/' ? '/' : `${root}/`\n const results: string[] = []\n await walkDirectory(\n ws,\n root,\n cwdPrefix,\n matcher,\n { ignoreMatchers, limit: options.limit },\n results,\n )\n return results\n },\n }\n\n const ls: LsOperations = {\n exists: async (absolutePath: string) => ws.fs.exists(absolutePath),\n stat: async (absolutePath: string) => {\n const isDir = await ws.fs.isDir(absolutePath)\n return { isDirectory: () => isDir }\n },\n readdir: async (absolutePath: string) => {\n const entries = await ws.fs.readdir(absolutePath)\n const prefix = absolutePath === '/' ? '/' : `${rstripSlash(absolutePath)}/`\n return entries.map((e) => (e.startsWith(prefix) ? e.slice(prefix.length) : e))\n },\n }\n\n return { read, write, edit, bash, grep, find, ls }\n}\n"],"mappings":"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","names":["options"]}
|
|
1
|
+
{"version":3,"sources":["../../src/pi/extension.ts","../../src/pi/operations.ts"],"sourcesContent":["// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport {\n createBashToolDefinition,\n createEditToolDefinition,\n createFindToolDefinition,\n createGrepToolDefinition,\n createLsToolDefinition,\n createReadToolDefinition,\n createWriteToolDefinition,\n type BashOperations,\n type InlineExtension,\n} from '@earendil-works/pi-coding-agent'\nimport { buildSystemPrompt } from '../prompt.ts'\nimport { mirageOperations, type MirageOperationsOptions } from './operations.ts'\n\nexport interface MirageExtensionOptions extends MirageOperationsOptions {\n cwd?: string\n systemPrompt?: string | false\n}\n\nfunction bashAtCwd(operations: BashOperations, cwd: string): BashOperations {\n return {\n exec: (command, _hostCwd, options) => operations.exec(command, cwd, options),\n }\n}\n\nexport function mirageExtension(ws: Workspace, opts: MirageExtensionOptions = {}): InlineExtension {\n const cwd = opts.cwd ?? '/'\n const ops = mirageOperations(ws, opts)\n const userBash = bashAtCwd(ops.bash, cwd)\n const systemPrompt =\n opts.systemPrompt === false\n ? undefined\n : (opts.systemPrompt ?? buildSystemPrompt({ workspace: ws }))\n return {\n name: 'mirage',\n factory: (pi) => {\n pi.registerTool(createReadToolDefinition(cwd, { operations: ops.read }))\n pi.registerTool(createWriteToolDefinition(cwd, { operations: ops.write }))\n pi.registerTool(createEditToolDefinition(cwd, { operations: ops.edit }))\n pi.registerTool(createBashToolDefinition(cwd, { operations: ops.bash }))\n pi.registerTool(createGrepToolDefinition(cwd, { operations: ops.grep }))\n pi.registerTool(createFindToolDefinition(cwd, { operations: ops.find }))\n pi.registerTool(createLsToolDefinition(cwd, { operations: ops.ls }))\n pi.on('user_bash', () => ({ operations: userBash }))\n if (systemPrompt !== undefined) {\n pi.on('before_agent_start', (event) => ({\n systemPrompt: `${event.systemPrompt}\\n\\n${systemPrompt}`,\n }))\n }\n },\n }\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { rstripSlash } from '@struktoai/mirage-core/utils/slash'\nimport type { ExecuteResult, Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport type {\n BashOperations,\n EditOperations,\n FindOperations,\n GrepOperations,\n LsOperations,\n ReadOperations,\n WriteOperations,\n} from '@earendil-works/pi-coding-agent'\nimport picomatch from 'picomatch'\nimport { FileVersionTracker } from '../file-version.ts'\nimport { decode, refusalLine } from '../io-text.ts'\n\nexport { StaleMirageFileError } from '../file-version.ts'\n\nexport interface MirageOperationsOptions {\n staleWriteProtection?: boolean\n}\n\nexport interface MirageOperationsBundle {\n read: ReadOperations\n write: WriteOperations\n edit: EditOperations\n bash: BashOperations\n grep: GrepOperations\n find: FindOperations\n ls: LsOperations\n}\n\nasync function ensureParent(ws: Workspace, dir: string): Promise<void> {\n const norm = rstripSlash(dir) || '/'\n if (norm === '/' || (await ws.fs.exists(norm))) return\n const parent = norm.substring(0, norm.lastIndexOf('/')) || '/'\n await ensureParent(ws, parent)\n try {\n await ws.fs.mkdir(norm)\n } catch (err) {\n if (await ws.fs.isDir(norm)) return\n throw err\n }\n}\n\ninterface WalkOptions {\n ignoreMatchers: ((path: string) => boolean)[]\n limit: number\n}\n\nasync function walkDirectory(\n ws: Workspace,\n dir: string,\n cwdPrefix: string,\n matcher: (relativePath: string) => boolean,\n opts: WalkOptions,\n results: string[],\n): Promise<void> {\n if (results.length >= opts.limit) return\n const entries = await ws.fs.readdir(dir)\n for (const full of entries) {\n if (results.length >= opts.limit) return\n const rel = full.startsWith(cwdPrefix) ? full.slice(cwdPrefix.length) : full\n if (opts.ignoreMatchers.some((m) => m(rel))) continue\n const isDir = await ws.fs.isDir(full)\n if (matcher(rel)) results.push(full)\n if (isDir) await walkDirectory(ws, full, cwdPrefix, matcher, opts, results)\n }\n}\n\nexport function mirageOperations(\n ws: Workspace,\n options: MirageOperationsOptions = {},\n): MirageOperationsBundle {\n const versions = new FileVersionTracker(ws, options.staleWriteProtection ?? true)\n const read: ReadOperations = {\n readFile: (absolutePath: string) => versions.read(absolutePath),\n access: async (absolutePath: string) => {\n await ws.fs.stat(absolutePath)\n },\n }\n\n const write: WriteOperations = {\n writeFile: (absolutePath: string, content: string) => versions.write(absolutePath, content),\n mkdir: async (dir: string) => {\n await ensureParent(ws, dir)\n if (!(await ws.fs.exists(dir))) {\n await ws.fs.mkdir(dir)\n }\n },\n }\n\n const edit: EditOperations = {\n readFile: (absolutePath: string) => versions.readForEdit(absolutePath),\n writeFile: (absolutePath: string, content: string) => versions.writeEdit(absolutePath, content),\n access: read.access,\n }\n\n const bash: BashOperations = {\n exec: async (command, cwd, options) => {\n const timeoutSignal =\n options.timeout !== undefined && options.timeout > 0\n ? AbortSignal.timeout(options.timeout * 1000)\n : undefined\n const signal =\n options.signal !== undefined && timeoutSignal !== undefined\n ? AbortSignal.any([options.signal, timeoutSignal])\n : (options.signal ?? timeoutSignal)\n let result: ExecuteResult\n try {\n result =\n signal === undefined\n ? await ws.execute(command, { cwd })\n : await ws.execute(command, { cwd, signal })\n } catch (error) {\n if (options.signal?.aborted === true) {\n throw new Error('aborted')\n }\n if (timeoutSignal?.aborted === true) {\n throw new Error('timeout:' + String(options.timeout))\n }\n throw error\n }\n if (result.stdout.length > 0) {\n options.onData(Buffer.from(result.stdout))\n }\n if (result.stderr.length > 0) {\n options.onData(Buffer.from(result.stderr))\n }\n // The record, described once, unless what was just streamed\n // already says why (an operand-scoped refusal's own line).\n const why = refusalLine(decode(result.stdout) + decode(result.stderr), result.refusal)\n if (why.length > 0) options.onData(Buffer.from(why))\n return { exitCode: result.exitCode }\n },\n }\n\n const grep: GrepOperations = {\n isDirectory: async (absolutePath: string) => ws.fs.isDir(absolutePath),\n readFile: async (absolutePath: string) => (await versions.read(absolutePath)).toString('utf-8'),\n }\n\n const find: FindOperations = {\n exists: async (absolutePath: string) => ws.fs.exists(absolutePath),\n glob: async (pattern, cwd, options) => {\n const matcher = picomatch(pattern, { dot: false })\n const ignoreMatchers = options.ignore.map((p) => picomatch(p, { dot: false }))\n const root = rstripSlash(cwd) || '/'\n const cwdPrefix = root === '/' ? '/' : `${root}/`\n const results: string[] = []\n await walkDirectory(\n ws,\n root,\n cwdPrefix,\n matcher,\n { ignoreMatchers, limit: options.limit },\n results,\n )\n return results\n },\n }\n\n const ls: LsOperations = {\n exists: async (absolutePath: string) => ws.fs.exists(absolutePath),\n stat: async (absolutePath: string) => {\n const isDir = await ws.fs.isDir(absolutePath)\n return { isDirectory: () => isDir }\n },\n readdir: async (absolutePath: string) => {\n const entries = await ws.fs.readdir(absolutePath)\n const prefix = absolutePath === '/' ? '/' : `${rstripSlash(absolutePath)}/`\n return entries.map((e) => (e.startsWith(prefix) ? e.slice(prefix.length) : e))\n },\n }\n\n return { read, write, edit, bash, grep, find, ls }\n}\n"],"mappings":"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","names":["options"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Workspace } from '@struktoai/mirage-core';
|
|
1
|
+
import { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace';
|
|
2
2
|
|
|
3
3
|
declare const MIRAGE_SYSTEM_PROMPT = "Your filesystem is powered by Mirage \u2014 a virtual filesystem that mounts cloud storage, local files, and in-memory data as a unified file tree.\n\nCapabilities beyond standard filesystem:\n- head -n 5 on data files returns the first 5 rows\n- grep works on structured text such as CSV and JSON, not just plain text\n- Pipes work: cat data.csv | grep error | sort | uniq | wc -l\n- head, tail, cut, wc, sort, uniq, tee, xargs are all available\n\nYou can write Python code and execute it. The workspace is pre-configured with your data sources mounted at their respective paths.\n\nUse the execute tool for complex operations. Use read/write/edit for simple file operations.\n";
|
|
4
4
|
interface BuildSystemPromptOptions {
|
package/dist/vercel/index.d.ts
CHANGED
package/dist/vercel/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
readWorkspaceFile
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-DIUKTEAK.js";
|
|
4
4
|
|
|
5
5
|
// src/vercel/index.ts
|
|
6
|
-
import { encodeBase64
|
|
6
|
+
import { encodeBase64 } from "@struktoai/mirage-core/utils/base64";
|
|
7
|
+
import { gnuDirname } from "@struktoai/mirage-core/utils/path";
|
|
7
8
|
import { tool } from "ai";
|
|
8
9
|
import { z } from "zod";
|
|
9
10
|
async function ensureParent(ws, path) {
|
|
@@ -53,7 +54,8 @@ function mirageTools(ws) {
|
|
|
53
54
|
return {
|
|
54
55
|
stdout: io.stdoutText,
|
|
55
56
|
stderr: io.stderrText,
|
|
56
|
-
exitCode: io.exitCode
|
|
57
|
+
exitCode: io.exitCode,
|
|
58
|
+
refusal: io.refusal
|
|
57
59
|
};
|
|
58
60
|
}
|
|
59
61
|
}),
|
package/dist/vercel/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/vercel/index.ts"],"sourcesContent":["// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { encodeBase64, gnuDirname, type Workspace } from '@struktoai/mirage-core'\nimport { tool, type ToolSet } from 'ai'\nimport { z } from 'zod'\nimport { readWorkspaceFile } from '../read-file.ts'\n\nasync function ensureParent(ws: Workspace, path: string): Promise<void> {\n const parent = gnuDirname(path)\n if (parent === '/' || parent === '' || parent === '.') return\n if (await ws.fs.exists(parent)) return\n await ensureParent(ws, parent)\n try {\n await ws.fs.mkdir(parent)\n } catch (err) {\n if (!(await ws.fs.exists(parent))) throw err\n }\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n return encodeBase64(bytes)\n}\n\ntype ReadFileResult =\n | { kind: 'text'; path: string; mimeType: string; content: string; bytes: number }\n | { kind: 'media'; path: string; mimeType: string; base64: string; bytes: number }\n | { kind: 'binary'; path: string; mimeType: string; bytes: number; note: string }\n | { error: string }\n\nfunction isError(r: ReadFileResult): r is { error: string } {\n return 'error' in r\n}\n\nasync function readFileResult(ws: Workspace, path: string): Promise<ReadFileResult> {\n try {\n const result = await readWorkspaceFile(ws, path)\n if (result.kind === 'text') return result\n if (result.kind === 'image' || result.kind === 'file') {\n return {\n kind: 'media',\n path: result.path,\n mimeType: result.mimeType,\n base64: bytesToBase64(result.data),\n bytes: result.bytes,\n }\n }\n return result\n } catch (error) {\n return { error: error instanceof Error ? error.message : String(error) }\n }\n}\n\nexport function mirageTools(ws: Workspace): ToolSet {\n return {\n execute: tool({\n description:\n 'Execute a shell command in the Mirage workspace and return stdout, stderr, and exitCode.',\n inputSchema: z.object({\n command: z.string().describe('The shell command to execute.'),\n }),\n execute: async ({ command }) => {\n const io = await ws.execute(command)\n return {\n stdout: io.stdoutText,\n stderr: io.stderrText,\n exitCode: io.exitCode,\n }\n },\n }),\n\n readFile: tool({\n description:\n 'Read a file from the Mirage workspace. Text files (utf-8 source/data) come back as text; PDFs and images (png/jpeg/gif/webp) come back as base64 media that is forwarded to the model as a multimodal attachment; other binaries return a metadata stub.',\n inputSchema: z.object({\n path: z.string().describe('Absolute path inside the workspace.'),\n }),\n execute: async ({ path }): Promise<ReadFileResult> => readFileResult(ws, path),\n toModelOutput: ({ output }) => {\n const out: ReadFileResult = output\n if (isError(out)) return { type: 'error-text', value: out.error }\n if (out.kind === 'text') return { type: 'text', value: out.content }\n if (out.kind === 'media') {\n return {\n type: 'content',\n value: [\n {\n type: 'text',\n text: `[${out.path}] ${out.mimeType} (${String(out.bytes)} bytes)`,\n },\n {\n type: 'file',\n data: { type: 'data', data: out.base64 },\n mediaType: out.mimeType,\n },\n ],\n }\n }\n return { type: 'text', value: out.note }\n },\n }),\n\n writeFile: tool({\n description:\n 'Write content to a file in the Mirage workspace. Creates missing parent directories.',\n inputSchema: z.object({\n path: z.string().describe('Absolute path inside the workspace.'),\n content: z.string().describe('UTF-8 text content to write.'),\n }),\n execute: async ({ path, content }) => {\n await ensureParent(ws, path)\n await ws.fs.writeFile(path, content)\n return { path }\n },\n }),\n\n editFile: tool({\n description:\n 'Replace a string inside an existing file. Errors if the string appears more than once unless replaceAll is true.',\n inputSchema: z.object({\n path: z.string().describe('Absolute path of the file to edit.'),\n oldString: z.string().describe('The exact string to replace.'),\n newString: z.string().describe('The replacement string.'),\n replaceAll: z\n .boolean()\n .optional()\n .describe('Replace every occurrence rather than requiring a unique match.'),\n }),\n execute: async ({ path, oldString, newString, replaceAll }) => {\n let current: string\n try {\n current = await ws.fs.readFileText(path)\n } catch {\n return { error: `Error: file '${path}' not found` }\n }\n const count = current.split(oldString).length - 1\n if (count === 0) {\n return { error: `Error: string not found in file: '${oldString}'` }\n }\n if (count > 1 && replaceAll !== true) {\n return {\n error: `Error: string '${oldString}' appears ${String(count)} times. Use replaceAll=true`,\n }\n }\n const next =\n replaceAll === true\n ? current.split(oldString).join(newString)\n : current.replace(oldString, newString)\n await ws.fs.writeFile(path, next)\n return { path, occurrences: replaceAll === true ? count : 1 }\n },\n }),\n\n ls: tool({\n description: 'List entries of a directory in the Mirage workspace.',\n inputSchema: z.object({\n path: z.string().describe('Absolute directory path inside the workspace.'),\n }),\n execute: async ({ path }) => {\n let entries: string[]\n try {\n entries = await ws.fs.readdir(path)\n } catch (err) {\n return { error: err instanceof Error ? err.message : String(err) }\n }\n const files: { path: string; is_dir: boolean }[] = []\n for (const entry of entries) {\n const isDir = await ws.fs.isDir(entry)\n files.push({ path: entry, is_dir: isDir })\n }\n return { files }\n },\n }),\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/vercel/index.ts"],"sourcesContent":["// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { encodeBase64 } from '@struktoai/mirage-core/utils/base64'\nimport { gnuDirname } from '@struktoai/mirage-core/utils/path'\nimport type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport { tool, type ToolSet } from 'ai'\nimport { z } from 'zod'\nimport { readWorkspaceFile } from '../read-file.ts'\n\nasync function ensureParent(ws: Workspace, path: string): Promise<void> {\n const parent = gnuDirname(path)\n if (parent === '/' || parent === '' || parent === '.') return\n if (await ws.fs.exists(parent)) return\n await ensureParent(ws, parent)\n try {\n await ws.fs.mkdir(parent)\n } catch (err) {\n if (!(await ws.fs.exists(parent))) throw err\n }\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n return encodeBase64(bytes)\n}\n\ntype ReadFileResult =\n | { kind: 'text'; path: string; mimeType: string; content: string; bytes: number }\n | { kind: 'media'; path: string; mimeType: string; base64: string; bytes: number }\n | { kind: 'binary'; path: string; mimeType: string; bytes: number; note: string }\n | { error: string }\n\nfunction isError(r: ReadFileResult): r is { error: string } {\n return 'error' in r\n}\n\nasync function readFileResult(ws: Workspace, path: string): Promise<ReadFileResult> {\n try {\n const result = await readWorkspaceFile(ws, path)\n if (result.kind === 'text') return result\n if (result.kind === 'image' || result.kind === 'file') {\n return {\n kind: 'media',\n path: result.path,\n mimeType: result.mimeType,\n base64: bytesToBase64(result.data),\n bytes: result.bytes,\n }\n }\n return result\n } catch (error) {\n return { error: error instanceof Error ? error.message : String(error) }\n }\n}\n\nexport function mirageTools(ws: Workspace): ToolSet {\n return {\n execute: tool({\n description:\n 'Execute a shell command in the Mirage workspace and return stdout, stderr, and exitCode.',\n inputSchema: z.object({\n command: z.string().describe('The shell command to execute.'),\n }),\n execute: async ({ command }) => {\n const io = await ws.execute(command)\n return {\n stdout: io.stdoutText,\n stderr: io.stderrText,\n exitCode: io.exitCode,\n refusal: io.refusal,\n }\n },\n }),\n\n readFile: tool({\n description:\n 'Read a file from the Mirage workspace. Text files (utf-8 source/data) come back as text; PDFs and images (png/jpeg/gif/webp) come back as base64 media that is forwarded to the model as a multimodal attachment; other binaries return a metadata stub.',\n inputSchema: z.object({\n path: z.string().describe('Absolute path inside the workspace.'),\n }),\n execute: async ({ path }): Promise<ReadFileResult> => readFileResult(ws, path),\n toModelOutput: ({ output }) => {\n const out: ReadFileResult = output\n if (isError(out)) return { type: 'error-text', value: out.error }\n if (out.kind === 'text') return { type: 'text', value: out.content }\n if (out.kind === 'media') {\n return {\n type: 'content',\n value: [\n {\n type: 'text',\n text: `[${out.path}] ${out.mimeType} (${String(out.bytes)} bytes)`,\n },\n {\n type: 'file',\n data: { type: 'data', data: out.base64 },\n mediaType: out.mimeType,\n },\n ],\n }\n }\n return { type: 'text', value: out.note }\n },\n }),\n\n writeFile: tool({\n description:\n 'Write content to a file in the Mirage workspace. Creates missing parent directories.',\n inputSchema: z.object({\n path: z.string().describe('Absolute path inside the workspace.'),\n content: z.string().describe('UTF-8 text content to write.'),\n }),\n execute: async ({ path, content }) => {\n await ensureParent(ws, path)\n await ws.fs.writeFile(path, content)\n return { path }\n },\n }),\n\n editFile: tool({\n description:\n 'Replace a string inside an existing file. Errors if the string appears more than once unless replaceAll is true.',\n inputSchema: z.object({\n path: z.string().describe('Absolute path of the file to edit.'),\n oldString: z.string().describe('The exact string to replace.'),\n newString: z.string().describe('The replacement string.'),\n replaceAll: z\n .boolean()\n .optional()\n .describe('Replace every occurrence rather than requiring a unique match.'),\n }),\n execute: async ({ path, oldString, newString, replaceAll }) => {\n let current: string\n try {\n current = await ws.fs.readFileText(path)\n } catch {\n return { error: `Error: file '${path}' not found` }\n }\n const count = current.split(oldString).length - 1\n if (count === 0) {\n return { error: `Error: string not found in file: '${oldString}'` }\n }\n if (count > 1 && replaceAll !== true) {\n return {\n error: `Error: string '${oldString}' appears ${String(count)} times. Use replaceAll=true`,\n }\n }\n const next =\n replaceAll === true\n ? current.split(oldString).join(newString)\n : current.replace(oldString, newString)\n await ws.fs.writeFile(path, next)\n return { path, occurrences: replaceAll === true ? count : 1 }\n },\n }),\n\n ls: tool({\n description: 'List entries of a directory in the Mirage workspace.',\n inputSchema: z.object({\n path: z.string().describe('Absolute directory path inside the workspace.'),\n }),\n execute: async ({ path }) => {\n let entries: string[]\n try {\n entries = await ws.fs.readdir(path)\n } catch (err) {\n return { error: err instanceof Error ? err.message : String(err) }\n }\n const files: { path: string; is_dir: boolean }[] = []\n for (const entry of entries) {\n const isDir = await ws.fs.isDir(entry)\n files.push({ path: entry, is_dir: isDir })\n }\n return { files }\n },\n }),\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@struktoai/mirage-agents",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "A Unified Virtual Filesystem For AI Agents",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bash",
|
|
@@ -31,6 +31,9 @@
|
|
|
31
31
|
"access": "public"
|
|
32
32
|
},
|
|
33
33
|
"type": "module",
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=20.10.0"
|
|
36
|
+
},
|
|
34
37
|
"main": "./dist/index.js",
|
|
35
38
|
"types": "./dist/index.d.ts",
|
|
36
39
|
"exports": {
|
|
@@ -75,19 +78,19 @@
|
|
|
75
78
|
"dist"
|
|
76
79
|
],
|
|
77
80
|
"dependencies": {
|
|
78
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
81
|
+
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
79
82
|
"picomatch": "^4.0.4",
|
|
80
83
|
"zod": "^4.0.0",
|
|
81
|
-
"@struktoai/mirage-core": "0.0.
|
|
84
|
+
"@struktoai/mirage-core": "0.0.6"
|
|
82
85
|
},
|
|
83
86
|
"peerDependencies": {
|
|
84
|
-
"@anthropic-ai/claude-agent-sdk": "^0.3.
|
|
85
|
-
"@earendil-works/pi-coding-agent": "^0.
|
|
86
|
-
"@mastra/core": "^1.
|
|
87
|
-
"@opencode-ai/plugin": "^1.18.
|
|
88
|
-
"@openai/agents": "^0.
|
|
89
|
-
"ai": "^7.0.
|
|
90
|
-
"deepagents": "^1.
|
|
87
|
+
"@anthropic-ai/claude-agent-sdk": "^0.3.233",
|
|
88
|
+
"@earendil-works/pi-coding-agent": "^0.84.2",
|
|
89
|
+
"@mastra/core": "^1.59.0",
|
|
90
|
+
"@opencode-ai/plugin": "^1.18.18",
|
|
91
|
+
"@openai/agents": "^0.16.0",
|
|
92
|
+
"ai": "^7.0.66",
|
|
93
|
+
"deepagents": "^1.12.4"
|
|
91
94
|
},
|
|
92
95
|
"peerDependenciesMeta": {
|
|
93
96
|
"@anthropic-ai/claude-agent-sdk": {
|
|
@@ -113,24 +116,24 @@
|
|
|
113
116
|
}
|
|
114
117
|
},
|
|
115
118
|
"devDependencies": {
|
|
116
|
-
"@anthropic-ai/claude-agent-sdk": "^0.3.
|
|
117
|
-
"@earendil-works/pi-coding-agent": "^0.
|
|
118
|
-
"@langchain/core": "^1.2.
|
|
119
|
-
"@langchain/langgraph": "^1.4.
|
|
120
|
-
"@langchain/langgraph-checkpoint": "^1.1.
|
|
121
|
-
"@langchain/langgraph-sdk": "^1.9.
|
|
122
|
-
"@mastra/core": "^1.
|
|
123
|
-
"@opencode-ai/plugin": "^1.18.
|
|
124
|
-
"@openai/agents": "^0.
|
|
119
|
+
"@anthropic-ai/claude-agent-sdk": "^0.3.233",
|
|
120
|
+
"@earendil-works/pi-coding-agent": "^0.84.2",
|
|
121
|
+
"@langchain/core": "^1.2.8",
|
|
122
|
+
"@langchain/langgraph": "^1.4.10",
|
|
123
|
+
"@langchain/langgraph-checkpoint": "^1.1.3",
|
|
124
|
+
"@langchain/langgraph-sdk": "^1.9.29",
|
|
125
|
+
"@mastra/core": "^1.59.0",
|
|
126
|
+
"@opencode-ai/plugin": "^1.18.18",
|
|
127
|
+
"@openai/agents": "^0.16.0",
|
|
125
128
|
"@types/node": "^22.0.0",
|
|
126
129
|
"@types/picomatch": "^4.0.3",
|
|
127
|
-
"ai": "^7.0.
|
|
128
|
-
"deepagents": "^1.
|
|
129
|
-
"langchain": "^1.5.
|
|
130
|
+
"ai": "^7.0.66",
|
|
131
|
+
"deepagents": "^1.12.4",
|
|
132
|
+
"langchain": "^1.5.9",
|
|
130
133
|
"tsup": "^8.5.0",
|
|
131
134
|
"typescript": "^6.0.0",
|
|
132
135
|
"vitest": "^3.2.6",
|
|
133
|
-
"@struktoai/mirage-node": "0.0.
|
|
136
|
+
"@struktoai/mirage-node": "0.0.6"
|
|
134
137
|
},
|
|
135
138
|
"scripts": {
|
|
136
139
|
"build": "tsup",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/read-file.ts","../src/read-file/constants.ts"],"sourcesContent":["import { detectFileType, FileType, type FileStat, type Workspace } from '@struktoai/mirage-core'\nimport {\n MIME_FOR_EXTENSION,\n MIME_FOR_FILE_TYPE,\n MODEL_IMAGE_MIMES,\n READ_FILE_MIME,\n TEXT_FILE_EXTENSIONS,\n type ReadFileMime,\n} from './read-file/constants.ts'\n\ninterface WorkspaceFileBase {\n path: string\n mimeType: ReadFileMime\n bytes: number\n}\n\nexport type WorkspaceFileReadResult =\n | (WorkspaceFileBase & { kind: 'text'; content: string })\n | (WorkspaceFileBase & { kind: 'image'; data: Uint8Array })\n | (WorkspaceFileBase & { kind: 'file'; data: Uint8Array; filename: string })\n | (WorkspaceFileBase & { kind: 'binary'; note: string })\n\nexport type WorkspaceFileReader = (path: string) => Promise<Uint8Array>\n\nfunction extOf(path: string): string {\n const dot = path.lastIndexOf('.')\n const slash = path.lastIndexOf('/')\n if (dot < 0 || dot < slash) return ''\n return path.slice(dot + 1).toLowerCase()\n}\n\nfunction filenameOf(path: string): string {\n const slash = path.lastIndexOf('/')\n const filename = slash < 0 ? path : path.slice(slash + 1)\n return filename === '' ? 'file' : filename\n}\n\nfunction mimeForExtension(path: string): ReadFileMime | undefined {\n const ext = extOf(path)\n return (\n MIME_FOR_EXTENSION[ext] ??\n (TEXT_FILE_EXTENSIONS.has(ext) ? READ_FILE_MIME.PLAIN_TEXT : undefined)\n )\n}\n\nfunction mimeForDetectedType(type: FileType): ReadFileMime {\n return MIME_FOR_FILE_TYPE[type] ?? READ_FILE_MIME.BINARY\n}\n\nfunction mimeFor(path: string, bytes: Uint8Array, stat: FileStat): ReadFileMime {\n const extensionMime = mimeForExtension(path)\n if (extensionMime !== undefined) return extensionMime\n if (extOf(path) !== '') return READ_FILE_MIME.BINARY\n return mimeForDetectedType(detectFileType(bytes, stat))\n}\n\nfunction isTextMime(mimeType: ReadFileMime): boolean {\n return (\n mimeType.startsWith('text/') ||\n mimeType === READ_FILE_MIME.JSON ||\n mimeType === READ_FILE_MIME.SVG\n )\n}\n\nexport async function readWorkspaceFile(\n ws: Workspace,\n path: string,\n reader?: WorkspaceFileReader,\n): Promise<WorkspaceFileReadResult> {\n const stat = await ws.fs.stat(path)\n if (stat.type === FileType.DIRECTORY) {\n throw new Error(`Cannot read directory as a file: ${path}`)\n }\n const data = reader === undefined ? await ws.fs.readFile(path, { raw: true }) : await reader(path)\n const mimeType = mimeFor(path, data, stat)\n const base = { path, mimeType, bytes: data.byteLength }\n\n if (isTextMime(mimeType)) {\n return {\n ...base,\n kind: 'text',\n content: new TextDecoder('utf-8', { fatal: false }).decode(data),\n }\n }\n if (MODEL_IMAGE_MIMES.has(mimeType)) {\n return { ...base, kind: 'image', data }\n }\n if (mimeType === READ_FILE_MIME.PDF) {\n return { ...base, kind: 'file', data, filename: filenameOf(path) }\n }\n return {\n ...base,\n kind: 'binary',\n note:\n `Binary file ${path} (${mimeType}, ${String(data.byteLength)} bytes). ` +\n 'Use the execute tool with shell commands (head, file, wc, od) to inspect.',\n }\n}\n","import { FileType, type FileType as MirageFileType } from '@struktoai/mirage-core'\n\nexport const READ_FILE_MIME = Object.freeze({\n BINARY: 'application/octet-stream',\n CSV: 'text/csv',\n HTML: 'text/html',\n IMAGE_GIF: 'image/gif',\n IMAGE_JPEG: 'image/jpeg',\n IMAGE_PNG: 'image/png',\n IMAGE_WEBP: 'image/webp',\n JSON: 'application/json',\n MARKDOWN: 'text/markdown',\n PDF: 'application/pdf',\n PLAIN_TEXT: 'text/plain',\n SVG: 'image/svg+xml',\n} as const)\n\nexport type ReadFileMime = (typeof READ_FILE_MIME)[keyof typeof READ_FILE_MIME]\n\nexport const TEXT_FILE_EXTENSIONS: ReadonlySet<string> = new Set([\n 'txt',\n 'yaml',\n 'yml',\n 'tsv',\n 'xml',\n 'js',\n 'mjs',\n 'cjs',\n 'ts',\n 'tsx',\n 'jsx',\n 'py',\n 'rb',\n 'rs',\n 'go',\n 'java',\n 'c',\n 'cpp',\n 'h',\n 'hpp',\n 'sh',\n 'bash',\n 'zsh',\n 'sql',\n 'log',\n 'env',\n 'ini',\n 'toml',\n 'conf',\n 'cfg',\n])\n\nexport const MIME_FOR_EXTENSION: Readonly<Record<string, ReadFileMime>> = Object.freeze({\n json: READ_FILE_MIME.JSON,\n jsonl: READ_FILE_MIME.JSON,\n csv: READ_FILE_MIME.CSV,\n html: READ_FILE_MIME.HTML,\n htm: READ_FILE_MIME.HTML,\n md: READ_FILE_MIME.MARKDOWN,\n svg: READ_FILE_MIME.SVG,\n png: READ_FILE_MIME.IMAGE_PNG,\n jpg: READ_FILE_MIME.IMAGE_JPEG,\n jpeg: READ_FILE_MIME.IMAGE_JPEG,\n gif: READ_FILE_MIME.IMAGE_GIF,\n webp: READ_FILE_MIME.IMAGE_WEBP,\n pdf: READ_FILE_MIME.PDF,\n})\n\nexport const MIME_FOR_FILE_TYPE: Readonly<Partial<Record<MirageFileType, ReadFileMime>>> =\n Object.freeze({\n [FileType.JSON]: READ_FILE_MIME.JSON,\n [FileType.CSV]: READ_FILE_MIME.CSV,\n [FileType.TEXT]: READ_FILE_MIME.PLAIN_TEXT,\n [FileType.IMAGE_PNG]: READ_FILE_MIME.IMAGE_PNG,\n [FileType.IMAGE_JPEG]: READ_FILE_MIME.IMAGE_JPEG,\n [FileType.IMAGE_GIF]: READ_FILE_MIME.IMAGE_GIF,\n [FileType.PDF]: READ_FILE_MIME.PDF,\n })\n\nexport const MODEL_IMAGE_MIMES: ReadonlySet<ReadFileMime> = new Set([\n READ_FILE_MIME.IMAGE_JPEG,\n READ_FILE_MIME.IMAGE_PNG,\n READ_FILE_MIME.IMAGE_GIF,\n READ_FILE_MIME.IMAGE_WEBP,\n])\n"],"mappings":"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","names":["FileType","FileType"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/file-version.ts"],"sourcesContent":["// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { createHash } from 'node:crypto'\nimport type { Workspace } from '@struktoai/mirage-core'\n\nexport class StaleMirageFileError extends Error {\n readonly path: string\n\n constructor(path: string) {\n super(`File changed since it was last read: ${path}. Read the file again before modifying it.`)\n this.name = 'StaleMirageFileError'\n this.path = path\n }\n}\n\nfunction fingerprint(content: Uint8Array | string): string {\n return createHash('sha256').update(content).digest('base64url')\n}\n\nasync function readBuffer(ws: Workspace, path: string): Promise<Buffer> {\n const bytes = await ws.fs.readFile(path, { raw: true })\n return Buffer.from(bytes)\n}\n\nexport class FileVersionTracker {\n private readonly readVersions = new Map<string, string>()\n private readonly editVersions = new Map<string, string>()\n\n constructor(\n private readonly ws: Workspace,\n private readonly enabled = true,\n ) {}\n\n private async currentVersion(path: string): Promise<string | null> {\n if (!(await this.ws.fs.exists(path))) return null\n return fingerprint(await readBuffer(this.ws, path))\n }\n\n private async assertVersion(path: string, expected: string): Promise<void> {\n if ((await this.currentVersion(path)) !== expected) {\n throw new StaleMirageFileError(path)\n }\n }\n\n private recordWrite(path: string, content: string): void {\n if (!this.enabled) return\n this.readVersions.set(path, fingerprint(content))\n this.editVersions.delete(path)\n }\n\n async read(path: string): Promise<Buffer> {\n const content = await readBuffer(this.ws, path)\n if (this.enabled) this.readVersions.set(path, fingerprint(content))\n return content\n }\n\n async readForEdit(path: string): Promise<Buffer> {\n const content = await readBuffer(this.ws, path)\n if (!this.enabled) return content\n const version = fingerprint(content)\n const readVersion = this.readVersions.get(path)\n if (readVersion !== undefined && readVersion !== version) {\n throw new StaleMirageFileError(path)\n }\n this.editVersions.set(path, version)\n return content\n }\n\n async write(path: string, content: string): Promise<void> {\n if (this.enabled) {\n const readVersion = this.readVersions.get(path)\n if (readVersion !== undefined) await this.assertVersion(path, readVersion)\n }\n await this.ws.fs.writeFile(path, content)\n this.recordWrite(path, content)\n }\n\n async writeEdit(path: string, content: string): Promise<void> {\n if (this.enabled) {\n const editVersion = this.editVersions.get(path)\n if (editVersion !== undefined) await this.assertVersion(path, editVersion)\n }\n await this.ws.fs.writeFile(path, content)\n this.recordWrite(path, content)\n }\n}\n"],"mappings":";AAcA,SAAS,kBAAkB;AAGpB,IAAM,uBAAN,cAAmC,MAAM;AAAA,EACrC;AAAA,EAET,YAAY,MAAc;AACxB,UAAM,wCAAwC,IAAI,4CAA4C;AAC9F,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACd;AACF;AAEA,SAAS,YAAY,SAAsC;AACzD,SAAO,WAAW,QAAQ,EAAE,OAAO,OAAO,EAAE,OAAO,WAAW;AAChE;AAEA,eAAe,WAAW,IAAe,MAA+B;AACtE,QAAM,QAAQ,MAAM,GAAG,GAAG,SAAS,MAAM,EAAE,KAAK,KAAK,CAAC;AACtD,SAAO,OAAO,KAAK,KAAK;AAC1B;AAEO,IAAM,qBAAN,MAAyB;AAAA,EAI9B,YACmB,IACA,UAAU,MAC3B;AAFiB;AACA;AAAA,EAChB;AAAA,EAFgB;AAAA,EACA;AAAA,EALF,eAAe,oBAAI,IAAoB;AAAA,EACvC,eAAe,oBAAI,IAAoB;AAAA,EAOxD,MAAc,eAAe,MAAsC;AACjE,QAAI,CAAE,MAAM,KAAK,GAAG,GAAG,OAAO,IAAI,EAAI,QAAO;AAC7C,WAAO,YAAY,MAAM,WAAW,KAAK,IAAI,IAAI,CAAC;AAAA,EACpD;AAAA,EAEA,MAAc,cAAc,MAAc,UAAiC;AACzE,QAAK,MAAM,KAAK,eAAe,IAAI,MAAO,UAAU;AAClD,YAAM,IAAI,qBAAqB,IAAI;AAAA,IACrC;AAAA,EACF;AAAA,EAEQ,YAAY,MAAc,SAAuB;AACvD,QAAI,CAAC,KAAK,QAAS;AACnB,SAAK,aAAa,IAAI,MAAM,YAAY,OAAO,CAAC;AAChD,SAAK,aAAa,OAAO,IAAI;AAAA,EAC/B;AAAA,EAEA,MAAM,KAAK,MAA+B;AACxC,UAAM,UAAU,MAAM,WAAW,KAAK,IAAI,IAAI;AAC9C,QAAI,KAAK,QAAS,MAAK,aAAa,IAAI,MAAM,YAAY,OAAO,CAAC;AAClE,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,YAAY,MAA+B;AAC/C,UAAM,UAAU,MAAM,WAAW,KAAK,IAAI,IAAI;AAC9C,QAAI,CAAC,KAAK,QAAS,QAAO;AAC1B,UAAM,UAAU,YAAY,OAAO;AACnC,UAAM,cAAc,KAAK,aAAa,IAAI,IAAI;AAC9C,QAAI,gBAAgB,UAAa,gBAAgB,SAAS;AACxD,YAAM,IAAI,qBAAqB,IAAI;AAAA,IACrC;AACA,SAAK,aAAa,IAAI,MAAM,OAAO;AACnC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MAAM,MAAc,SAAgC;AACxD,QAAI,KAAK,SAAS;AAChB,YAAM,cAAc,KAAK,aAAa,IAAI,IAAI;AAC9C,UAAI,gBAAgB,OAAW,OAAM,KAAK,cAAc,MAAM,WAAW;AAAA,IAC3E;AACA,UAAM,KAAK,GAAG,GAAG,UAAU,MAAM,OAAO;AACxC,SAAK,YAAY,MAAM,OAAO;AAAA,EAChC;AAAA,EAEA,MAAM,UAAU,MAAc,SAAgC;AAC5D,QAAI,KAAK,SAAS;AAChB,YAAM,cAAc,KAAK,aAAa,IAAI,IAAI;AAC9C,UAAI,gBAAgB,OAAW,OAAM,KAAK,cAAc,MAAM,WAAW;AAAA,IAC3E;AACA,UAAM,KAAK,GAAG,GAAG,UAAU,MAAM,OAAO;AACxC,SAAK,YAAY,MAAM,OAAO;AAAA,EAChC;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tool-operations.ts","../src/io-text.ts","../src/tool-descriptions.ts"],"sourcesContent":["// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { ExecuteResult, Workspace } from '@struktoai/mirage-core'\nimport { gnuDirname } from '@struktoai/mirage-core'\nimport { FileVersionTracker, StaleMirageFileError } from './file-version.ts'\nimport { decode, ioToStr } from './io-text.ts'\n\nexport interface ToolResult {\n [key: string]: unknown\n content: { type: 'text'; text: string }[]\n isError?: boolean\n}\n\nexport interface MirageToolOperationsOptions {\n staleWriteProtection?: boolean\n}\n\nfunction textResult(text: string): ToolResult {\n return { content: [{ type: 'text', text }] }\n}\n\nfunction errorResult(text: string): ToolResult {\n return { content: [{ type: 'text', text }], isError: true }\n}\n\nfunction ioResult(io: ExecuteResult): ToolResult {\n const result = textResult(ioToStr(io))\n if (io.exitCode !== 0) result.isError = true\n return result\n}\n\nfunction shQuote(value: string): string {\n return `'${value.replace(/'/g, \"'\\\\''\")}'`\n}\n\nasync function ensureParents(ws: Workspace, path: string): Promise<void> {\n const parent = gnuDirname(path)\n if (parent === '/' || parent === '' || parent === '.') return\n if (await ws.fs.exists(parent)) return\n await ensureParents(ws, parent)\n try {\n await ws.fs.mkdir(parent)\n } catch (err) {\n if (!(await ws.fs.exists(parent))) throw err\n }\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\nexport class MirageToolOperations {\n private readonly versions: FileVersionTracker\n\n constructor(\n private readonly ws: Workspace,\n options: MirageToolOperationsOptions = {},\n ) {\n this.versions = new FileVersionTracker(ws, options.staleWriteProtection ?? true)\n }\n\n async execute(command: string): Promise<ToolResult> {\n return ioResult(await this.ws.execute(command))\n }\n\n async read(path: string, offset = 0, limit = 2000): Promise<ToolResult> {\n let data: Uint8Array\n try {\n data = await this.versions.read(path)\n } catch (err) {\n if (!(await this.ws.fs.exists(path))) {\n return errorResult(`Error: file '${path}' not found`)\n }\n return errorResult(`Error: ${errorMessage(err)}`)\n }\n const text = decode(data)\n const raw = text.length === 0 ? [] : text.split(/(?<=\\n)/)\n const lines = raw.length > 0 && raw[raw.length - 1] === '' ? raw.slice(0, -1) : raw\n const sliced = lines.slice(offset, offset + limit)\n const numbered = sliced.map((line, i) => `${String(i + offset + 1).padStart(6)}\\t${line}`)\n return textResult(numbered.join(''))\n }\n\n async write(path: string, content: string): Promise<ToolResult> {\n if (await this.ws.fs.exists(path)) {\n return errorResult(`Error: file '${path}' already exists`)\n }\n await ensureParents(this.ws, path)\n await this.versions.write(path, content)\n return textResult(`Written: ${path}`)\n }\n\n async edit(\n path: string,\n oldString: string,\n newString: string,\n replaceAll = false,\n ): Promise<ToolResult> {\n let content: string\n try {\n content = (await this.versions.readForEdit(path)).toString('utf8')\n } catch (err) {\n if (err instanceof StaleMirageFileError) return errorResult(`Error: ${err.message}`)\n if (!(await this.ws.fs.exists(path))) {\n return errorResult(`Error: file '${path}' not found`)\n }\n return errorResult(`Error: ${errorMessage(err)}`)\n }\n const count = content.split(oldString).length - 1\n if (count === 0) {\n return errorResult(`Error: string not found in file: '${oldString}'`)\n }\n if (count > 1 && !replaceAll) {\n return errorResult(`Error: string appears ${String(count)} times. Pass replace_all=true`)\n }\n const newContent = replaceAll\n ? content.split(oldString).join(newString)\n : content.replace(oldString, newString)\n try {\n await this.versions.writeEdit(path, newContent)\n } catch (err) {\n return errorResult(`Error: ${errorMessage(err)}`)\n }\n const occurrences = replaceAll ? count : 1\n return textResult(`Edited: ${path} (${String(occurrences)} occurrence(s))`)\n }\n\n async ls(path: string): Promise<ToolResult> {\n return ioResult(await this.ws.execute(`ls ${shQuote(path)}`))\n }\n\n async grep(pattern: string, path: string): Promise<ToolResult> {\n const io = await this.ws.execute(`grep -rn ${shQuote(pattern)} ${shQuote(path)}`)\n return textResult(ioToStr(io))\n }\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { ExecuteResult } from '@struktoai/mirage-core'\n\nexport function decode(value: Uint8Array | null | undefined): string {\n if (value === null || value === undefined) return ''\n return new TextDecoder('utf-8').decode(value)\n}\n\nexport function ioToStr(io: ExecuteResult): string {\n const stdout = io.stdoutText\n const stderr = io.stderrText\n if (stderr) return stdout ? `${stdout}\\n${stderr}` : stderr\n return stdout\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nexport const EXECUTE_DESCRIPTION =\n 'Run a shell-style command on the Mirage virtual filesystem. ' +\n 'Supports cat, grep, find, head, tail, ls, wc, sort, uniq, tee, pipe, ' +\n 'and any other Unix command on mounted resources (S3, disk, RAM, etc.). ' +\n 'Files with no registered renderer, such as .parquet or .orc, read back as raw bytes.'\n\nexport const READ_DESCRIPTION =\n 'Read the contents of a file on the Mirage virtual filesystem. ' +\n 'Returns line-numbered text. ' +\n \"Optionally pass 'offset' (default 0) to start at a given line \" +\n \"and 'limit' (default 2000) to cap the number of lines returned.\"\n\nexport const WRITE_DESCRIPTION =\n 'Write content to a new file on the Mirage virtual filesystem. ' +\n 'Fails if the file already exists; use edit to modify an existing file.'\n\nexport const EDIT_DESCRIPTION =\n 'Replace a string in an existing file on the Mirage virtual filesystem. ' +\n 'Fails if the file changed since it was last read, old_string is not found, ' +\n 'or old_string appears more than once. ' +\n 'Pass replace_all=true (default false) to replace every occurrence.'\n\nexport const LS_DESCRIPTION =\n 'List files and directories at the given path on the Mirage virtual filesystem.'\n\nexport const GREP_DESCRIPTION =\n 'Search for a pattern in files on the Mirage virtual filesystem. ' +\n 'Supports regex. Searches recursively under path.'\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/prompt.ts"],"sourcesContent":["// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Workspace } from '@struktoai/mirage-core'\n\nexport const MIRAGE_SYSTEM_PROMPT = `Your filesystem is powered by Mirage — a virtual filesystem that mounts cloud storage, local files, and in-memory data as a unified file tree.\n\nCapabilities beyond standard filesystem:\n- head -n 5 on data files returns the first 5 rows\n- grep works on structured text such as CSV and JSON, not just plain text\n- Pipes work: cat data.csv | grep error | sort | uniq | wc -l\n- head, tail, cut, wc, sort, uniq, tee, xargs are all available\n\nYou can write Python code and execute it. The workspace is pre-configured with your data sources mounted at their respective paths.\n\nUse the execute tool for complex operations. Use read/write/edit for simple file operations.\n`\n\nexport interface BuildSystemPromptOptions {\n workspace?: Workspace\n mountInfo?: Record<string, string>\n extraInstructions?: string\n}\n\nexport function buildSystemPrompt(opts: BuildSystemPromptOptions = {}): string {\n const parts: string[] = [MIRAGE_SYSTEM_PROMPT]\n if (opts.workspace !== undefined) {\n parts.push('Mounted data sources:\\n' + opts.workspace.filePrompt)\n } else if (opts.mountInfo !== undefined && Object.keys(opts.mountInfo).length > 0) {\n parts.push('\\nMounted data sources:')\n for (const [prefix, description] of Object.entries(opts.mountInfo)) {\n parts.push(`- ${prefix} — ${description}`)\n }\n parts.push('')\n }\n if (opts.extraInstructions !== undefined && opts.extraInstructions.length > 0) {\n parts.push(opts.extraInstructions)\n }\n return parts.join('\\n')\n}\n"],"mappings":";AAgBO,IAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmB7B,SAAS,kBAAkB,OAAiC,CAAC,GAAW;AAC7E,QAAM,QAAkB,CAAC,oBAAoB;AAC7C,MAAI,KAAK,cAAc,QAAW;AAChC,UAAM,KAAK,4BAA4B,KAAK,UAAU,UAAU;AAAA,EAClE,WAAW,KAAK,cAAc,UAAa,OAAO,KAAK,KAAK,SAAS,EAAE,SAAS,GAAG;AACjF,UAAM,KAAK,yBAAyB;AACpC,eAAW,CAAC,QAAQ,WAAW,KAAK,OAAO,QAAQ,KAAK,SAAS,GAAG;AAClE,YAAM,KAAK,KAAK,MAAM,WAAM,WAAW,EAAE;AAAA,IAC3C;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AACA,MAAI,KAAK,sBAAsB,UAAa,KAAK,kBAAkB,SAAS,GAAG;AAC7E,UAAM,KAAK,KAAK,iBAAiB;AAAA,EACnC;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":[]}
|