@struktoai/mirage-agents 0.0.4 → 0.0.5-alpha.1

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 CHANGED
@@ -46,7 +46,8 @@ await ws.execute('cp /s3/report.csv /data/local.csv')
46
46
  await ws.execute('wc -l $(find /s3/data -name "*.jsonl")')
47
47
 
48
48
  // Commands are extensible: register new commands, or override one per
49
- // resource + filetype, e.g. `cat` on S3 Parquet renders rows as JSON.
49
+ // resource + filetype. Mirage ships no filetype renderers, so a format
50
+ // like Parquet renders however you register it.
50
51
  ws.command('summarize', ...)
51
52
  ws.command('cat', { resource: 's3', filetype: 'parquet' }, ...)
52
53
 
@@ -120,7 +120,7 @@ var MirageToolOperations = class {
120
120
  };
121
121
 
122
122
  // src/tool-descriptions.ts
123
- var EXECUTE_DESCRIPTION = "Run a shell-style command on the Mirage virtual filesystem. Supports cat, grep, find, head, tail, ls, wc, sort, uniq, tee, pipe, and any other Unix command on mounted resources (S3, disk, RAM, etc.). Also supports reading structured files: cat on .parquet/.orc/.csv returns a table.";
123
+ var EXECUTE_DESCRIPTION = "Run a shell-style command on the Mirage virtual filesystem. Supports cat, grep, find, head, tail, ls, wc, sort, uniq, tee, pipe, and any other Unix command on mounted resources (S3, disk, RAM, etc.). Files with no registered renderer, such as .parquet or .orc, read back as raw bytes.";
124
124
  var READ_DESCRIPTION = "Read the contents of a file on the Mirage virtual filesystem. Returns line-numbered text. Optionally pass 'offset' (default 0) to start at a given line and 'limit' (default 2000) to cap the number of lines returned.";
125
125
  var WRITE_DESCRIPTION = "Write content to a new file on the Mirage virtual filesystem. Fails if the file already exists; use edit to modify an existing file.";
126
126
  var EDIT_DESCRIPTION = "Replace a string in an existing file on the Mirage virtual filesystem. Fails if the file changed since it was last read, old_string is not found, or old_string appears more than once. Pass replace_all=true (default false) to replace every occurrence.";
@@ -136,4 +136,4 @@ export {
136
136
  LS_DESCRIPTION,
137
137
  GREP_DESCRIPTION
138
138
  };
139
- //# sourceMappingURL=chunk-OLFSAPC6.js.map
139
+ //# sourceMappingURL=chunk-Y4G25V5V.js.map
@@ -1 +1 @@
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 'Also supports reading structured files: cat on .parquet/.orc/.csv returns a table.'\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
+ {"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":[]}
@@ -2,10 +2,9 @@
2
2
  var 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.
3
3
 
4
4
  Capabilities beyond standard filesystem:
5
- - cat on .parquet, .orc, .feather files returns a formatted table
6
5
  - head -n 5 on data files returns the first 5 rows
7
- - grep works natively on CSV, JSON, Parquet \u2014 not just text
8
- - Pipes work: cat data.parquet | grep error | sort | uniq | wc -l
6
+ - grep works on structured text such as CSV and JSON, not just plain text
7
+ - Pipes work: cat data.csv | grep error | sort | uniq | wc -l
9
8
  - head, tail, cut, wc, sort, uniq, tee, xargs are all available
10
9
 
11
10
  You can write Python code and execute it. The workspace is pre-configured with your data sources mounted at their respective paths.
@@ -33,4 +32,4 @@ export {
33
32
  MIRAGE_SYSTEM_PROMPT,
34
33
  buildSystemPrompt
35
34
  };
36
- //# sourceMappingURL=chunk-ODKR5YZI.js.map
35
+ //# sourceMappingURL=chunk-ZPXFVDYT.js.map
@@ -0,0 +1 @@
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":[]}
@@ -3,7 +3,7 @@ import { Options } from '@anthropic-ai/claude-agent-sdk';
3
3
  import { Workspace } from '@struktoai/mirage-core';
4
4
  import { M as MirageToolOperationsOptions } from '../tool-descriptions-7CgIovZc.js';
5
5
  export { E as EDIT_DESCRIPTION, a as EXECUTE_DESCRIPTION, G as GREP_DESCRIPTION, L as LS_DESCRIPTION, R as READ_DESCRIPTION, W as WRITE_DESCRIPTION } from '../tool-descriptions-7CgIovZc.js';
6
- export { M as MIRAGE_SYSTEM_PROMPT, b as buildSystemPrompt } from '../prompt-Ca4hc1Ul.js';
6
+ export { M as MIRAGE_SYSTEM_PROMPT, b as buildSystemPrompt } from '../prompt-B_6pxgjj.js';
7
7
 
8
8
  declare function MirageServer(workspace: Workspace, options?: MirageToolOperationsOptions): _anthropic_ai_claude_agent_sdk.McpSdkServerConfigWithInstance;
9
9
 
@@ -6,11 +6,11 @@ import {
6
6
  MirageToolOperations,
7
7
  READ_DESCRIPTION,
8
8
  WRITE_DESCRIPTION
9
- } from "../chunk-OLFSAPC6.js";
9
+ } from "../chunk-Y4G25V5V.js";
10
10
  import {
11
11
  MIRAGE_SYSTEM_PROMPT,
12
12
  buildSystemPrompt
13
- } from "../chunk-ODKR5YZI.js";
13
+ } from "../chunk-ZPXFVDYT.js";
14
14
  import "../chunk-XEQB7N3F.js";
15
15
 
16
16
  // src/claude-agent-sdk/server.ts
@@ -1,6 +1,6 @@
1
1
  import { Workspace } from '@struktoai/mirage-node';
2
2
  import { SandboxBackendProtocolV2, ExecuteResponse, LsResult, ReadResult, ReadRawResult, WriteResult, EditResult, GrepResult, GlobResult, FileUploadResponse, FileDownloadResponse } from 'deepagents';
3
- export { B as BuildSystemPromptOptions, M as MIRAGE_SYSTEM_PROMPT, b as buildSystemPrompt } from '../prompt-Ca4hc1Ul.js';
3
+ export { B as BuildSystemPromptOptions, M as MIRAGE_SYSTEM_PROMPT, b as buildSystemPrompt } from '../prompt-B_6pxgjj.js';
4
4
  import '@struktoai/mirage-core';
5
5
 
6
6
  interface LangchainWorkspaceOptions {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MIRAGE_SYSTEM_PROMPT,
3
3
  buildSystemPrompt
4
- } from "../chunk-ODKR5YZI.js";
4
+ } from "../chunk-ZPXFVDYT.js";
5
5
 
6
6
  // src/langchain/convert.ts
7
7
  function ioToExecuteResponse(io) {
@@ -106,7 +106,6 @@ function extOf(path) {
106
106
  if (dot < 0) return "";
107
107
  return path.slice(dot + 1).toLowerCase();
108
108
  }
109
- var MIRAGE_RENDERED_AS_TEXT = /* @__PURE__ */ new Set(["parquet", "h5", "hdf5", "feather"]);
110
109
  function mimeFor(path) {
111
110
  const ext = extOf(path);
112
111
  if (ext === "json" || ext === "jsonl") return "application/json";
@@ -114,7 +113,6 @@ function mimeFor(path) {
114
113
  if (ext === "html" || ext === "htm") return "text/html";
115
114
  if (ext === "md") return "text/markdown";
116
115
  if (TEXT_EXTENSIONS.has(ext)) return "text/plain";
117
- if (MIRAGE_RENDERED_AS_TEXT.has(ext)) return "text/plain";
118
116
  if (ext === "png") return "image/png";
119
117
  if (ext === "jpg" || ext === "jpeg") return "image/jpeg";
120
118
  if (ext === "pdf") return "application/pdf";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/langchain/convert.ts","../../src/langchain/backend.ts","../../src/langchain/messages.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 { ExecuteResponse, FileInfo, GrepMatch } from 'deepagents'\n\ninterface IOLike {\n stdoutText: string\n stderrText: string\n exitCode: number | null\n}\n\nexport function ioToExecuteResponse(io: IOLike): ExecuteResponse {\n const stdout = io.stdoutText\n const stderr = io.stderrText\n let output = stdout\n if (stderr.length > 0) {\n output = stdout.length > 0 ? `${stdout}\\n${stderr}` : stderr\n }\n return { output, exitCode: io.exitCode, truncated: false }\n}\n\nexport function ioToGrepMatches(io: IOLike): GrepMatch[] {\n const stdout = io.stdoutText.trim()\n if (stdout.length === 0) return []\n const matches: GrepMatch[] = []\n for (const line of stdout.split('\\n')) {\n const firstColon = line.indexOf(':')\n if (firstColon < 0) continue\n const secondColon = line.indexOf(':', firstColon + 1)\n if (secondColon < 0) continue\n const path = line.slice(0, firstColon)\n const lineNumStr = line.slice(firstColon + 1, secondColon)\n const text = line.slice(secondColon + 1)\n const lineNum = Number.parseInt(lineNumStr, 10)\n if (Number.isNaN(lineNum)) continue\n matches.push({ path, line: lineNum, text })\n }\n return matches\n}\n\nexport function ioToFileInfos(io: IOLike): FileInfo[] {\n const stdout = io.stdoutText.trim()\n if (stdout.length === 0) return []\n const infos: FileInfo[] = []\n for (const raw of stdout.split('\\n')) {\n const entry = raw.trim()\n if (entry.length === 0) continue\n const isDir = entry.endsWith('/')\n infos.push({ path: isDir ? entry.slice(0, -1) : entry, is_dir: isDir })\n }\n return infos\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-node'\nimport type {\n EditResult,\n ExecuteResponse,\n FileData,\n FileDownloadResponse,\n FileInfo,\n FileUploadResponse,\n GlobResult,\n GrepResult,\n LsResult,\n ReadRawResult,\n ReadResult,\n SandboxBackendProtocolV2 as SandboxBackendProtocol,\n WriteResult,\n} from 'deepagents'\nimport { ioToExecuteResponse, ioToFileInfos, ioToGrepMatches } from './convert.ts'\nimport { gnuDirname } from '@struktoai/mirage-core'\n\nconst TEXT_EXTENSIONS = new Set([\n 'txt',\n 'md',\n 'json',\n 'jsonl',\n 'yaml',\n 'yml',\n 'csv',\n 'tsv',\n 'xml',\n 'html',\n 'htm',\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 'fish',\n 'sql',\n 'log',\n 'env',\n 'ini',\n 'toml',\n 'conf',\n 'cfg',\n])\n\nfunction shellQuote(s: string): string {\n if (/^[A-Za-z0-9_./-]+$/.test(s)) return s\n return `'${s.replaceAll(`'`, `'\\\\''`)}'`\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 extOf(path: string): string {\n const dot = path.lastIndexOf('.')\n if (dot < 0) return ''\n return path.slice(dot + 1).toLowerCase()\n}\n\nconst MIRAGE_RENDERED_AS_TEXT = new Set(['parquet', 'h5', 'hdf5', 'feather'])\n\nfunction mimeFor(path: string): string {\n const ext = extOf(path)\n if (ext === 'json' || ext === 'jsonl') return 'application/json'\n if (ext === 'csv') return 'text/csv'\n if (ext === 'html' || ext === 'htm') return 'text/html'\n if (ext === 'md') return 'text/markdown'\n if (TEXT_EXTENSIONS.has(ext)) return 'text/plain'\n if (MIRAGE_RENDERED_AS_TEXT.has(ext)) return 'text/plain'\n if (ext === 'png') return 'image/png'\n if (ext === 'jpg' || ext === 'jpeg') return 'image/jpeg'\n if (ext === 'pdf') return 'application/pdf'\n return 'application/octet-stream'\n}\n\nfunction isTextMime(mimeType: string): boolean {\n return mimeType.startsWith('text/') || mimeType === 'application/json'\n}\n\nconst ANTHROPIC_BINARY_MIMES = new Set([\n 'application/pdf',\n 'image/jpeg',\n 'image/png',\n 'image/gif',\n 'image/webp',\n])\n\nexport interface LangchainWorkspaceOptions {\n sandboxId?: string\n}\n\nexport class LangchainWorkspace implements SandboxBackendProtocol {\n readonly id: string\n private readonly ws: Workspace\n\n constructor(workspace: Workspace, options: LangchainWorkspaceOptions = {}) {\n this.ws = workspace\n this.id = options.sandboxId ?? 'mirage'\n }\n\n async execute(command: string): Promise<ExecuteResponse> {\n const io = await this.ws.execute(command)\n return ioToExecuteResponse(io)\n }\n\n async ls(path: string): Promise<LsResult> {\n let entries: string[]\n try {\n entries = await this.ws.fs.readdir(path)\n } catch (err) {\n return { error: err instanceof Error ? err.message : String(err) }\n }\n const files: FileInfo[] = []\n for (const entry of entries) {\n const isDir = await this.ws.fs.isDir(entry)\n files.push({ path: entry, is_dir: isDir })\n }\n return { files }\n }\n\n async read(filePath: string, offset = 0, limit = 500): Promise<ReadResult> {\n const mimeType = mimeFor(filePath)\n let bytes: Uint8Array\n try {\n bytes = await this.ws.fs.readFile(filePath)\n } catch (err) {\n return { error: err instanceof Error ? err.message : String(err) }\n }\n if (!isTextMime(mimeType)) {\n if (ANTHROPIC_BINARY_MIMES.has(mimeType)) {\n return { content: bytes, mimeType }\n }\n return {\n error: `Binary file '${filePath}' (${mimeType}, ${String(bytes.length)} bytes). Use shell commands (head, file, wc, od) via execute() to inspect.`,\n }\n }\n const text = new TextDecoder('utf-8').decode(bytes)\n const lines = text.split('\\n')\n if (offset >= lines.length) {\n return {\n error: `Line offset ${String(offset)} exceeds file length (${String(lines.length)} lines)`,\n }\n }\n const end = Math.min(offset + limit, lines.length)\n return { content: lines.slice(offset, end).join('\\n'), mimeType }\n }\n\n async readRaw(filePath: string): Promise<ReadRawResult> {\n let stat: Awaited<ReturnType<Workspace['fs']['stat']>>\n let bytes: Uint8Array\n try {\n stat = await this.ws.fs.stat(filePath)\n bytes = await this.ws.fs.readFile(filePath)\n } catch (err) {\n return { error: err instanceof Error ? err.message : String(err) }\n }\n const mimeType = mimeFor(filePath)\n const content: string | Uint8Array = isTextMime(mimeType)\n ? new TextDecoder('utf-8').decode(bytes)\n : bytes\n const modified = stat.modified ?? new Date().toISOString()\n const data: FileData = {\n content,\n mimeType,\n created_at: modified,\n modified_at: modified,\n }\n return { data }\n }\n\n async write(filePath: string, content: string): Promise<WriteResult> {\n if (await this.ws.fs.exists(filePath)) {\n return { error: `Error: file '${filePath}' already exists` }\n }\n await ensureParent(this.ws, filePath)\n await this.ws.fs.writeFile(filePath, content)\n return { path: filePath }\n }\n\n async edit(\n filePath: string,\n oldString: string,\n newString: string,\n replaceAll = false,\n ): Promise<EditResult> {\n let current: string\n try {\n current = await this.ws.fs.readFileText(filePath)\n } catch {\n return { error: `Error: file '${filePath}' 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) {\n return {\n error: `Error: string '${oldString}' appears ${String(count)} times. Use replaceAll=true`,\n }\n }\n const next = replaceAll\n ? current.split(oldString).join(newString)\n : current.replace(oldString, newString)\n await this.ws.fs.writeFile(filePath, next)\n return { path: filePath, occurrences: replaceAll ? count : 1 }\n }\n\n async grep(pattern: string, path?: string | null, glob?: string | null): Promise<GrepResult> {\n const parts: string[] = ['grep', '-rn']\n if (glob !== undefined && glob !== null && glob.length > 0) {\n parts.push('--include', shellQuote(glob))\n }\n parts.push(shellQuote(pattern))\n parts.push(shellQuote(path ?? '/'))\n const io = await this.ws.execute(parts.join(' '))\n return { matches: ioToGrepMatches(io) }\n }\n\n async glob(pattern: string, path = '/'): Promise<GlobResult> {\n const name = pattern.includes('/') ? (pattern.split('/').pop() ?? pattern) : pattern\n const io = await this.ws.execute(`find ${shellQuote(path)} -name ${shellQuote(name)}`)\n return { files: ioToFileInfos(io) }\n }\n\n async uploadFiles(\n files: readonly (readonly [string, Uint8Array])[],\n ): Promise<FileUploadResponse[]> {\n const results: FileUploadResponse[] = []\n for (const [path, data] of files) {\n await ensureParent(this.ws, path)\n await this.ws.fs.writeFile(path, data)\n results.push({ path, error: null })\n }\n return results\n }\n\n async downloadFiles(paths: readonly string[]): Promise<FileDownloadResponse[]> {\n const results: FileDownloadResponse[] = []\n for (const path of paths) {\n try {\n const content = await this.ws.fs.readFile(path)\n results.push({ path, content, error: null })\n } catch {\n results.push({ path, content: null, error: 'file_not_found' })\n }\n }\n return results\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\ninterface MessageLike {\n content?: unknown\n}\n\ninterface ContentBlock {\n type?: string\n text?: string\n}\n\nfunction isTextBlock(value: unknown): value is { type: 'text'; text: string } {\n if (typeof value !== 'object' || value === null) return false\n const block = value as ContentBlock\n return block.type === 'text' && typeof block.text === 'string'\n}\n\nexport function extractText(messages: readonly MessageLike[]): string[] {\n const texts: string[] = []\n for (const msg of messages) {\n if (!('content' in msg) || msg.content === undefined || msg.content === null) continue\n const content = msg.content\n if (typeof content === 'string') {\n if (content.trim().length > 0) texts.push(content)\n continue\n }\n if (Array.isArray(content)) {\n for (const block of content) {\n if (isTextBlock(block) && block.text.trim().length > 0) {\n texts.push(block.text)\n }\n }\n }\n }\n return texts\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/langchain/convert.ts","../../src/langchain/backend.ts","../../src/langchain/messages.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 { ExecuteResponse, FileInfo, GrepMatch } from 'deepagents'\n\ninterface IOLike {\n stdoutText: string\n stderrText: string\n exitCode: number | null\n}\n\nexport function ioToExecuteResponse(io: IOLike): ExecuteResponse {\n const stdout = io.stdoutText\n const stderr = io.stderrText\n let output = stdout\n if (stderr.length > 0) {\n output = stdout.length > 0 ? `${stdout}\\n${stderr}` : stderr\n }\n return { output, exitCode: io.exitCode, truncated: false }\n}\n\nexport function ioToGrepMatches(io: IOLike): GrepMatch[] {\n const stdout = io.stdoutText.trim()\n if (stdout.length === 0) return []\n const matches: GrepMatch[] = []\n for (const line of stdout.split('\\n')) {\n const firstColon = line.indexOf(':')\n if (firstColon < 0) continue\n const secondColon = line.indexOf(':', firstColon + 1)\n if (secondColon < 0) continue\n const path = line.slice(0, firstColon)\n const lineNumStr = line.slice(firstColon + 1, secondColon)\n const text = line.slice(secondColon + 1)\n const lineNum = Number.parseInt(lineNumStr, 10)\n if (Number.isNaN(lineNum)) continue\n matches.push({ path, line: lineNum, text })\n }\n return matches\n}\n\nexport function ioToFileInfos(io: IOLike): FileInfo[] {\n const stdout = io.stdoutText.trim()\n if (stdout.length === 0) return []\n const infos: FileInfo[] = []\n for (const raw of stdout.split('\\n')) {\n const entry = raw.trim()\n if (entry.length === 0) continue\n const isDir = entry.endsWith('/')\n infos.push({ path: isDir ? entry.slice(0, -1) : entry, is_dir: isDir })\n }\n return infos\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-node'\nimport type {\n EditResult,\n ExecuteResponse,\n FileData,\n FileDownloadResponse,\n FileInfo,\n FileUploadResponse,\n GlobResult,\n GrepResult,\n LsResult,\n ReadRawResult,\n ReadResult,\n SandboxBackendProtocolV2 as SandboxBackendProtocol,\n WriteResult,\n} from 'deepagents'\nimport { ioToExecuteResponse, ioToFileInfos, ioToGrepMatches } from './convert.ts'\nimport { gnuDirname } from '@struktoai/mirage-core'\n\nconst TEXT_EXTENSIONS = new Set([\n 'txt',\n 'md',\n 'json',\n 'jsonl',\n 'yaml',\n 'yml',\n 'csv',\n 'tsv',\n 'xml',\n 'html',\n 'htm',\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 'fish',\n 'sql',\n 'log',\n 'env',\n 'ini',\n 'toml',\n 'conf',\n 'cfg',\n])\n\nfunction shellQuote(s: string): string {\n if (/^[A-Za-z0-9_./-]+$/.test(s)) return s\n return `'${s.replaceAll(`'`, `'\\\\''`)}'`\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 extOf(path: string): string {\n const dot = path.lastIndexOf('.')\n if (dot < 0) return ''\n return path.slice(dot + 1).toLowerCase()\n}\n\nfunction mimeFor(path: string): string {\n const ext = extOf(path)\n if (ext === 'json' || ext === 'jsonl') return 'application/json'\n if (ext === 'csv') return 'text/csv'\n if (ext === 'html' || ext === 'htm') return 'text/html'\n if (ext === 'md') return 'text/markdown'\n if (TEXT_EXTENSIONS.has(ext)) return 'text/plain'\n if (ext === 'png') return 'image/png'\n if (ext === 'jpg' || ext === 'jpeg') return 'image/jpeg'\n if (ext === 'pdf') return 'application/pdf'\n return 'application/octet-stream'\n}\n\nfunction isTextMime(mimeType: string): boolean {\n return mimeType.startsWith('text/') || mimeType === 'application/json'\n}\n\nconst ANTHROPIC_BINARY_MIMES = new Set([\n 'application/pdf',\n 'image/jpeg',\n 'image/png',\n 'image/gif',\n 'image/webp',\n])\n\nexport interface LangchainWorkspaceOptions {\n sandboxId?: string\n}\n\nexport class LangchainWorkspace implements SandboxBackendProtocol {\n readonly id: string\n private readonly ws: Workspace\n\n constructor(workspace: Workspace, options: LangchainWorkspaceOptions = {}) {\n this.ws = workspace\n this.id = options.sandboxId ?? 'mirage'\n }\n\n async execute(command: string): Promise<ExecuteResponse> {\n const io = await this.ws.execute(command)\n return ioToExecuteResponse(io)\n }\n\n async ls(path: string): Promise<LsResult> {\n let entries: string[]\n try {\n entries = await this.ws.fs.readdir(path)\n } catch (err) {\n return { error: err instanceof Error ? err.message : String(err) }\n }\n const files: FileInfo[] = []\n for (const entry of entries) {\n const isDir = await this.ws.fs.isDir(entry)\n files.push({ path: entry, is_dir: isDir })\n }\n return { files }\n }\n\n async read(filePath: string, offset = 0, limit = 500): Promise<ReadResult> {\n const mimeType = mimeFor(filePath)\n let bytes: Uint8Array\n try {\n bytes = await this.ws.fs.readFile(filePath)\n } catch (err) {\n return { error: err instanceof Error ? err.message : String(err) }\n }\n if (!isTextMime(mimeType)) {\n if (ANTHROPIC_BINARY_MIMES.has(mimeType)) {\n return { content: bytes, mimeType }\n }\n return {\n error: `Binary file '${filePath}' (${mimeType}, ${String(bytes.length)} bytes). Use shell commands (head, file, wc, od) via execute() to inspect.`,\n }\n }\n const text = new TextDecoder('utf-8').decode(bytes)\n const lines = text.split('\\n')\n if (offset >= lines.length) {\n return {\n error: `Line offset ${String(offset)} exceeds file length (${String(lines.length)} lines)`,\n }\n }\n const end = Math.min(offset + limit, lines.length)\n return { content: lines.slice(offset, end).join('\\n'), mimeType }\n }\n\n async readRaw(filePath: string): Promise<ReadRawResult> {\n let stat: Awaited<ReturnType<Workspace['fs']['stat']>>\n let bytes: Uint8Array\n try {\n stat = await this.ws.fs.stat(filePath)\n bytes = await this.ws.fs.readFile(filePath)\n } catch (err) {\n return { error: err instanceof Error ? err.message : String(err) }\n }\n const mimeType = mimeFor(filePath)\n const content: string | Uint8Array = isTextMime(mimeType)\n ? new TextDecoder('utf-8').decode(bytes)\n : bytes\n const modified = stat.modified ?? new Date().toISOString()\n const data: FileData = {\n content,\n mimeType,\n created_at: modified,\n modified_at: modified,\n }\n return { data }\n }\n\n async write(filePath: string, content: string): Promise<WriteResult> {\n if (await this.ws.fs.exists(filePath)) {\n return { error: `Error: file '${filePath}' already exists` }\n }\n await ensureParent(this.ws, filePath)\n await this.ws.fs.writeFile(filePath, content)\n return { path: filePath }\n }\n\n async edit(\n filePath: string,\n oldString: string,\n newString: string,\n replaceAll = false,\n ): Promise<EditResult> {\n let current: string\n try {\n current = await this.ws.fs.readFileText(filePath)\n } catch {\n return { error: `Error: file '${filePath}' 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) {\n return {\n error: `Error: string '${oldString}' appears ${String(count)} times. Use replaceAll=true`,\n }\n }\n const next = replaceAll\n ? current.split(oldString).join(newString)\n : current.replace(oldString, newString)\n await this.ws.fs.writeFile(filePath, next)\n return { path: filePath, occurrences: replaceAll ? count : 1 }\n }\n\n async grep(pattern: string, path?: string | null, glob?: string | null): Promise<GrepResult> {\n const parts: string[] = ['grep', '-rn']\n if (glob !== undefined && glob !== null && glob.length > 0) {\n parts.push('--include', shellQuote(glob))\n }\n parts.push(shellQuote(pattern))\n parts.push(shellQuote(path ?? '/'))\n const io = await this.ws.execute(parts.join(' '))\n return { matches: ioToGrepMatches(io) }\n }\n\n async glob(pattern: string, path = '/'): Promise<GlobResult> {\n const name = pattern.includes('/') ? (pattern.split('/').pop() ?? pattern) : pattern\n const io = await this.ws.execute(`find ${shellQuote(path)} -name ${shellQuote(name)}`)\n return { files: ioToFileInfos(io) }\n }\n\n async uploadFiles(\n files: readonly (readonly [string, Uint8Array])[],\n ): Promise<FileUploadResponse[]> {\n const results: FileUploadResponse[] = []\n for (const [path, data] of files) {\n await ensureParent(this.ws, path)\n await this.ws.fs.writeFile(path, data)\n results.push({ path, error: null })\n }\n return results\n }\n\n async downloadFiles(paths: readonly string[]): Promise<FileDownloadResponse[]> {\n const results: FileDownloadResponse[] = []\n for (const path of paths) {\n try {\n const content = await this.ws.fs.readFile(path)\n results.push({ path, content, error: null })\n } catch {\n results.push({ path, content: null, error: 'file_not_found' })\n }\n }\n return results\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\ninterface MessageLike {\n content?: unknown\n}\n\ninterface ContentBlock {\n type?: string\n text?: string\n}\n\nfunction isTextBlock(value: unknown): value is { type: 'text'; text: string } {\n if (typeof value !== 'object' || value === null) return false\n const block = value as ContentBlock\n return block.type === 'text' && typeof block.text === 'string'\n}\n\nexport function extractText(messages: readonly MessageLike[]): string[] {\n const texts: string[] = []\n for (const msg of messages) {\n if (!('content' in msg) || msg.content === undefined || msg.content === null) continue\n const content = msg.content\n if (typeof content === 'string') {\n if (content.trim().length > 0) texts.push(content)\n continue\n }\n if (Array.isArray(content)) {\n for (const block of content) {\n if (isTextBlock(block) && block.text.trim().length > 0) {\n texts.push(block.text)\n }\n }\n }\n }\n return texts\n}\n"],"mappings":";;;;;;AAsBO,SAAS,oBAAoB,IAA6B;AAC/D,QAAM,SAAS,GAAG;AAClB,QAAM,SAAS,GAAG;AAClB,MAAI,SAAS;AACb,MAAI,OAAO,SAAS,GAAG;AACrB,aAAS,OAAO,SAAS,IAAI,GAAG,MAAM;AAAA,EAAK,MAAM,KAAK;AAAA,EACxD;AACA,SAAO,EAAE,QAAQ,UAAU,GAAG,UAAU,WAAW,MAAM;AAC3D;AAEO,SAAS,gBAAgB,IAAyB;AACvD,QAAM,SAAS,GAAG,WAAW,KAAK;AAClC,MAAI,OAAO,WAAW,EAAG,QAAO,CAAC;AACjC,QAAM,UAAuB,CAAC;AAC9B,aAAW,QAAQ,OAAO,MAAM,IAAI,GAAG;AACrC,UAAM,aAAa,KAAK,QAAQ,GAAG;AACnC,QAAI,aAAa,EAAG;AACpB,UAAM,cAAc,KAAK,QAAQ,KAAK,aAAa,CAAC;AACpD,QAAI,cAAc,EAAG;AACrB,UAAM,OAAO,KAAK,MAAM,GAAG,UAAU;AACrC,UAAM,aAAa,KAAK,MAAM,aAAa,GAAG,WAAW;AACzD,UAAM,OAAO,KAAK,MAAM,cAAc,CAAC;AACvC,UAAM,UAAU,OAAO,SAAS,YAAY,EAAE;AAC9C,QAAI,OAAO,MAAM,OAAO,EAAG;AAC3B,YAAQ,KAAK,EAAE,MAAM,MAAM,SAAS,KAAK,CAAC;AAAA,EAC5C;AACA,SAAO;AACT;AAEO,SAAS,cAAc,IAAwB;AACpD,QAAM,SAAS,GAAG,WAAW,KAAK;AAClC,MAAI,OAAO,WAAW,EAAG,QAAO,CAAC;AACjC,QAAM,QAAoB,CAAC;AAC3B,aAAW,OAAO,OAAO,MAAM,IAAI,GAAG;AACpC,UAAM,QAAQ,IAAI,KAAK;AACvB,QAAI,MAAM,WAAW,EAAG;AACxB,UAAM,QAAQ,MAAM,SAAS,GAAG;AAChC,UAAM,KAAK,EAAE,MAAM,QAAQ,MAAM,MAAM,GAAG,EAAE,IAAI,OAAO,QAAQ,MAAM,CAAC;AAAA,EACxE;AACA,SAAO;AACT;;;AC/BA,SAAS,kBAAkB;AAE3B,IAAM,kBAAkB,oBAAI,IAAI;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,WAAW,GAAmB;AACrC,MAAI,qBAAqB,KAAK,CAAC,EAAG,QAAO;AACzC,SAAO,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC;AACvC;AAEA,eAAe,aAAa,IAAe,MAA6B;AACtE,QAAM,SAAS,WAAW,IAAI;AAC9B,MAAI,WAAW,OAAO,WAAW,MAAM,WAAW,IAAK;AACvD,MAAI,MAAM,GAAG,GAAG,OAAO,MAAM,EAAG;AAChC,QAAM,aAAa,IAAI,MAAM;AAC7B,MAAI;AACF,UAAM,GAAG,GAAG,MAAM,MAAM;AAAA,EAC1B,SAAS,KAAK;AACZ,QAAI,CAAE,MAAM,GAAG,GAAG,OAAO,MAAM,EAAI,OAAM;AAAA,EAC3C;AACF;AAEA,SAAS,MAAM,MAAsB;AACnC,QAAM,MAAM,KAAK,YAAY,GAAG;AAChC,MAAI,MAAM,EAAG,QAAO;AACpB,SAAO,KAAK,MAAM,MAAM,CAAC,EAAE,YAAY;AACzC;AAEA,SAAS,QAAQ,MAAsB;AACrC,QAAM,MAAM,MAAM,IAAI;AACtB,MAAI,QAAQ,UAAU,QAAQ,QAAS,QAAO;AAC9C,MAAI,QAAQ,MAAO,QAAO;AAC1B,MAAI,QAAQ,UAAU,QAAQ,MAAO,QAAO;AAC5C,MAAI,QAAQ,KAAM,QAAO;AACzB,MAAI,gBAAgB,IAAI,GAAG,EAAG,QAAO;AACrC,MAAI,QAAQ,MAAO,QAAO;AAC1B,MAAI,QAAQ,SAAS,QAAQ,OAAQ,QAAO;AAC5C,MAAI,QAAQ,MAAO,QAAO;AAC1B,SAAO;AACT;AAEA,SAAS,WAAW,UAA2B;AAC7C,SAAO,SAAS,WAAW,OAAO,KAAK,aAAa;AACtD;AAEA,IAAM,yBAAyB,oBAAI,IAAI;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAMM,IAAM,qBAAN,MAA2D;AAAA,EACvD;AAAA,EACQ;AAAA,EAEjB,YAAY,WAAsB,UAAqC,CAAC,GAAG;AACzE,SAAK,KAAK;AACV,SAAK,KAAK,QAAQ,aAAa;AAAA,EACjC;AAAA,EAEA,MAAM,QAAQ,SAA2C;AACvD,UAAM,KAAK,MAAM,KAAK,GAAG,QAAQ,OAAO;AACxC,WAAO,oBAAoB,EAAE;AAAA,EAC/B;AAAA,EAEA,MAAM,GAAG,MAAiC;AACxC,QAAI;AACJ,QAAI;AACF,gBAAU,MAAM,KAAK,GAAG,GAAG,QAAQ,IAAI;AAAA,IACzC,SAAS,KAAK;AACZ,aAAO,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE;AAAA,IACnE;AACA,UAAM,QAAoB,CAAC;AAC3B,eAAW,SAAS,SAAS;AAC3B,YAAM,QAAQ,MAAM,KAAK,GAAG,GAAG,MAAM,KAAK;AAC1C,YAAM,KAAK,EAAE,MAAM,OAAO,QAAQ,MAAM,CAAC;AAAA,IAC3C;AACA,WAAO,EAAE,MAAM;AAAA,EACjB;AAAA,EAEA,MAAM,KAAK,UAAkB,SAAS,GAAG,QAAQ,KAA0B;AACzE,UAAM,WAAW,QAAQ,QAAQ;AACjC,QAAI;AACJ,QAAI;AACF,cAAQ,MAAM,KAAK,GAAG,GAAG,SAAS,QAAQ;AAAA,IAC5C,SAAS,KAAK;AACZ,aAAO,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE;AAAA,IACnE;AACA,QAAI,CAAC,WAAW,QAAQ,GAAG;AACzB,UAAI,uBAAuB,IAAI,QAAQ,GAAG;AACxC,eAAO,EAAE,SAAS,OAAO,SAAS;AAAA,MACpC;AACA,aAAO;AAAA,QACL,OAAO,gBAAgB,QAAQ,MAAM,QAAQ,KAAK,OAAO,MAAM,MAAM,CAAC;AAAA,MACxE;AAAA,IACF;AACA,UAAM,OAAO,IAAI,YAAY,OAAO,EAAE,OAAO,KAAK;AAClD,UAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,QAAI,UAAU,MAAM,QAAQ;AAC1B,aAAO;AAAA,QACL,OAAO,eAAe,OAAO,MAAM,CAAC,yBAAyB,OAAO,MAAM,MAAM,CAAC;AAAA,MACnF;AAAA,IACF;AACA,UAAM,MAAM,KAAK,IAAI,SAAS,OAAO,MAAM,MAAM;AACjD,WAAO,EAAE,SAAS,MAAM,MAAM,QAAQ,GAAG,EAAE,KAAK,IAAI,GAAG,SAAS;AAAA,EAClE;AAAA,EAEA,MAAM,QAAQ,UAA0C;AACtD,QAAI;AACJ,QAAI;AACJ,QAAI;AACF,aAAO,MAAM,KAAK,GAAG,GAAG,KAAK,QAAQ;AACrC,cAAQ,MAAM,KAAK,GAAG,GAAG,SAAS,QAAQ;AAAA,IAC5C,SAAS,KAAK;AACZ,aAAO,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE;AAAA,IACnE;AACA,UAAM,WAAW,QAAQ,QAAQ;AACjC,UAAM,UAA+B,WAAW,QAAQ,IACpD,IAAI,YAAY,OAAO,EAAE,OAAO,KAAK,IACrC;AACJ,UAAM,WAAW,KAAK,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzD,UAAM,OAAiB;AAAA,MACrB;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MACZ,aAAa;AAAA,IACf;AACA,WAAO,EAAE,KAAK;AAAA,EAChB;AAAA,EAEA,MAAM,MAAM,UAAkB,SAAuC;AACnE,QAAI,MAAM,KAAK,GAAG,GAAG,OAAO,QAAQ,GAAG;AACrC,aAAO,EAAE,OAAO,gBAAgB,QAAQ,mBAAmB;AAAA,IAC7D;AACA,UAAM,aAAa,KAAK,IAAI,QAAQ;AACpC,UAAM,KAAK,GAAG,GAAG,UAAU,UAAU,OAAO;AAC5C,WAAO,EAAE,MAAM,SAAS;AAAA,EAC1B;AAAA,EAEA,MAAM,KACJ,UACA,WACA,WACA,aAAa,OACQ;AACrB,QAAI;AACJ,QAAI;AACF,gBAAU,MAAM,KAAK,GAAG,GAAG,aAAa,QAAQ;AAAA,IAClD,QAAQ;AACN,aAAO,EAAE,OAAO,gBAAgB,QAAQ,cAAc;AAAA,IACxD;AACA,UAAM,QAAQ,QAAQ,MAAM,SAAS,EAAE,SAAS;AAChD,QAAI,UAAU,GAAG;AACf,aAAO,EAAE,OAAO,qCAAqC,SAAS,IAAI;AAAA,IACpE;AACA,QAAI,QAAQ,KAAK,CAAC,YAAY;AAC5B,aAAO;AAAA,QACL,OAAO,kBAAkB,SAAS,aAAa,OAAO,KAAK,CAAC;AAAA,MAC9D;AAAA,IACF;AACA,UAAM,OAAO,aACT,QAAQ,MAAM,SAAS,EAAE,KAAK,SAAS,IACvC,QAAQ,QAAQ,WAAW,SAAS;AACxC,UAAM,KAAK,GAAG,GAAG,UAAU,UAAU,IAAI;AACzC,WAAO,EAAE,MAAM,UAAU,aAAa,aAAa,QAAQ,EAAE;AAAA,EAC/D;AAAA,EAEA,MAAM,KAAK,SAAiB,MAAsB,MAA2C;AAC3F,UAAM,QAAkB,CAAC,QAAQ,KAAK;AACtC,QAAI,SAAS,UAAa,SAAS,QAAQ,KAAK,SAAS,GAAG;AAC1D,YAAM,KAAK,aAAa,WAAW,IAAI,CAAC;AAAA,IAC1C;AACA,UAAM,KAAK,WAAW,OAAO,CAAC;AAC9B,UAAM,KAAK,WAAW,QAAQ,GAAG,CAAC;AAClC,UAAM,KAAK,MAAM,KAAK,GAAG,QAAQ,MAAM,KAAK,GAAG,CAAC;AAChD,WAAO,EAAE,SAAS,gBAAgB,EAAE,EAAE;AAAA,EACxC;AAAA,EAEA,MAAM,KAAK,SAAiB,OAAO,KAA0B;AAC3D,UAAM,OAAO,QAAQ,SAAS,GAAG,IAAK,QAAQ,MAAM,GAAG,EAAE,IAAI,KAAK,UAAW;AAC7E,UAAM,KAAK,MAAM,KAAK,GAAG,QAAQ,QAAQ,WAAW,IAAI,CAAC,UAAU,WAAW,IAAI,CAAC,EAAE;AACrF,WAAO,EAAE,OAAO,cAAc,EAAE,EAAE;AAAA,EACpC;AAAA,EAEA,MAAM,YACJ,OAC+B;AAC/B,UAAM,UAAgC,CAAC;AACvC,eAAW,CAAC,MAAM,IAAI,KAAK,OAAO;AAChC,YAAM,aAAa,KAAK,IAAI,IAAI;AAChC,YAAM,KAAK,GAAG,GAAG,UAAU,MAAM,IAAI;AACrC,cAAQ,KAAK,EAAE,MAAM,OAAO,KAAK,CAAC;AAAA,IACpC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,OAA2D;AAC7E,UAAM,UAAkC,CAAC;AACzC,eAAW,QAAQ,OAAO;AACxB,UAAI;AACF,cAAM,UAAU,MAAM,KAAK,GAAG,GAAG,SAAS,IAAI;AAC9C,gBAAQ,KAAK,EAAE,MAAM,SAAS,OAAO,KAAK,CAAC;AAAA,MAC7C,QAAQ;AACN,gBAAQ,KAAK,EAAE,MAAM,SAAS,MAAM,OAAO,iBAAiB,CAAC;AAAA,MAC/D;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;;;ACnQA,SAAS,YAAY,OAAyD;AAC5E,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,QAAM,QAAQ;AACd,SAAO,MAAM,SAAS,UAAU,OAAO,MAAM,SAAS;AACxD;AAEO,SAAS,YAAY,UAA4C;AACtE,QAAM,QAAkB,CAAC;AACzB,aAAW,OAAO,UAAU;AAC1B,QAAI,EAAE,aAAa,QAAQ,IAAI,YAAY,UAAa,IAAI,YAAY,KAAM;AAC9E,UAAM,UAAU,IAAI;AACpB,QAAI,OAAO,YAAY,UAAU;AAC/B,UAAI,QAAQ,KAAK,EAAE,SAAS,EAAG,OAAM,KAAK,OAAO;AACjD;AAAA,IACF;AACA,QAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,iBAAW,SAAS,SAAS;AAC3B,YAAI,YAAY,KAAK,KAAK,MAAM,KAAK,KAAK,EAAE,SAAS,GAAG;AACtD,gBAAM,KAAK,MAAM,IAAI;AAAA,QACvB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
package/dist/mcp/index.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  MirageToolOperations,
7
7
  READ_DESCRIPTION,
8
8
  WRITE_DESCRIPTION
9
- } from "../chunk-OLFSAPC6.js";
9
+ } from "../chunk-Y4G25V5V.js";
10
10
  import {
11
11
  FileVersionTracker,
12
12
  StaleMirageFileError
@@ -2,7 +2,7 @@ import { Workspace } from '@struktoai/mirage-core';
2
2
  import * as _openai_agents from '@openai/agents';
3
3
  import { Editor, ApplyPatchOperation, ApplyPatchResult, ToolOutputText, ToolOutputImage, ToolOutputFileContent, Shell, ShellAction, ShellResult } from '@openai/agents';
4
4
  import { z } from 'zod';
5
- export { B as BuildSystemPromptOptions, M as MIRAGE_SYSTEM_PROMPT, b as buildSystemPrompt } from '../prompt-Ca4hc1Ul.js';
5
+ export { B as BuildSystemPromptOptions, M as MIRAGE_SYSTEM_PROMPT, b as buildSystemPrompt } from '../prompt-B_6pxgjj.js';
6
6
 
7
7
  declare class MirageEditor implements Editor {
8
8
  private readonly ws;
@@ -1,10 +1,10 @@
1
- import {
2
- MIRAGE_SYSTEM_PROMPT,
3
- buildSystemPrompt
4
- } from "../chunk-ODKR5YZI.js";
5
1
  import {
6
2
  readWorkspaceFile
7
3
  } from "../chunk-IMI7BLEG.js";
4
+ import {
5
+ MIRAGE_SYSTEM_PROMPT,
6
+ buildSystemPrompt
7
+ } from "../chunk-ZPXFVDYT.js";
8
8
 
9
9
  // src/openai/editor.ts
10
10
  import { applyDiff } from "@openai/agents";
@@ -1,6 +1,6 @@
1
1
  import { Workspace } from '@struktoai/mirage-core';
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-Ca4hc1Ul.js';
3
+ export { B as BuildSystemPromptOptions, M as MIRAGE_SYSTEM_PROMPT, b as buildSystemPrompt } from '../prompt-B_6pxgjj.js';
4
4
  export { S as StaleMirageFileError } from '../file-version-Clij-pms.js';
5
5
 
6
6
  interface MirageOperationsOptions {
package/dist/pi/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MIRAGE_SYSTEM_PROMPT,
3
3
  buildSystemPrompt
4
- } from "../chunk-ODKR5YZI.js";
4
+ } from "../chunk-ZPXFVDYT.js";
5
5
  import {
6
6
  FileVersionTracker,
7
7
  StaleMirageFileError
@@ -0,0 +1,11 @@
1
+ import { Workspace } from '@struktoai/mirage-core';
2
+
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
+ interface BuildSystemPromptOptions {
5
+ workspace?: Workspace;
6
+ mountInfo?: Record<string, string>;
7
+ extraInstructions?: string;
8
+ }
9
+ declare function buildSystemPrompt(opts?: BuildSystemPromptOptions): string;
10
+
11
+ export { type BuildSystemPromptOptions as B, MIRAGE_SYSTEM_PROMPT as M, buildSystemPrompt as b };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@struktoai/mirage-agents",
3
- "version": "0.0.4",
3
+ "version": "0.0.5-alpha.1",
4
4
  "description": "A Unified Virtual Filesystem For AI Agents",
5
5
  "keywords": [
6
6
  "bash",
@@ -78,7 +78,7 @@
78
78
  "@modelcontextprotocol/sdk": "^1.29.0",
79
79
  "picomatch": "^4.0.4",
80
80
  "zod": "^4.0.0",
81
- "@struktoai/mirage-core": "0.0.4"
81
+ "@struktoai/mirage-core": "0.0.5-alpha.1"
82
82
  },
83
83
  "peerDependencies": {
84
84
  "@anthropic-ai/claude-agent-sdk": "^0.3.215",
@@ -130,7 +130,7 @@
130
130
  "tsup": "^8.5.0",
131
131
  "typescript": "^6.0.0",
132
132
  "vitest": "^3.2.6",
133
- "@struktoai/mirage-node": "0.0.4"
133
+ "@struktoai/mirage-node": "0.0.5-alpha.1"
134
134
  },
135
135
  "scripts": {
136
136
  "build": "tsup",
@@ -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- cat on .parquet, .orc, .feather files returns a formatted table\n- head -n 5 on data files returns the first 5 rows\n- grep works natively on CSV, JSON, Parquet — not just text\n- Pipes work: cat data.parquet | 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;AAAA;AAoB7B,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":[]}
@@ -1,11 +0,0 @@
1
- import { Workspace } from '@struktoai/mirage-core';
2
-
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- cat on .parquet, .orc, .feather files returns a formatted table\n- head -n 5 on data files returns the first 5 rows\n- grep works natively on CSV, JSON, Parquet \u2014 not just text\n- Pipes work: cat data.parquet | 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
- interface BuildSystemPromptOptions {
5
- workspace?: Workspace;
6
- mountInfo?: Record<string, string>;
7
- extraInstructions?: string;
8
- }
9
- declare function buildSystemPrompt(opts?: BuildSystemPromptOptions): string;
10
-
11
- export { type BuildSystemPromptOptions as B, MIRAGE_SYSTEM_PROMPT as M, buildSystemPrompt as b };