@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.
Files changed (43) hide show
  1. package/README.md +138 -80
  2. package/dist/chunk-3N5GLSL7.js +33 -0
  3. package/dist/chunk-3N5GLSL7.js.map +1 -0
  4. package/dist/{chunk-IMI7BLEG.js → chunk-DIUKTEAK.js} +12 -11
  5. package/dist/chunk-DIUKTEAK.js.map +1 -0
  6. package/dist/{chunk-Y4G25V5V.js → chunk-GEO2G6YZ.js} +10 -19
  7. package/dist/chunk-GEO2G6YZ.js.map +1 -0
  8. package/dist/{chunk-ZPXFVDYT.js → chunk-S6DWWJVF.js} +1 -1
  9. package/dist/chunk-S6DWWJVF.js.map +1 -0
  10. package/dist/{chunk-XEQB7N3F.js → chunk-YJS2FVEB.js} +29 -11
  11. package/dist/chunk-YJS2FVEB.js.map +1 -0
  12. package/dist/claude-agent-sdk/index.d.ts +4 -4
  13. package/dist/claude-agent-sdk/index.js +5 -4
  14. package/dist/claude-agent-sdk/index.js.map +1 -1
  15. package/dist/{file-version-Clij-pms.d.ts → file-version-CE2J_nkn.d.ts} +2 -1
  16. package/dist/langchain/index.d.ts +3 -3
  17. package/dist/langchain/index.js +21 -5
  18. package/dist/langchain/index.js.map +1 -1
  19. package/dist/mastra/index.d.ts +8 -1
  20. package/dist/mastra/index.js +13 -3
  21. package/dist/mastra/index.js.map +1 -1
  22. package/dist/mcp/index.d.ts +4 -4
  23. package/dist/mcp/index.js +4 -3
  24. package/dist/mcp/index.js.map +1 -1
  25. package/dist/openai/index.d.ts +2 -2
  26. package/dist/openai/index.js +19 -10
  27. package/dist/openai/index.js.map +1 -1
  28. package/dist/opencode/index.d.ts +2 -2
  29. package/dist/opencode/index.js +10 -6
  30. package/dist/opencode/index.js.map +1 -1
  31. package/dist/pi/index.d.ts +3 -3
  32. package/dist/pi/index.js +11 -5
  33. package/dist/pi/index.js.map +1 -1
  34. package/dist/{prompt-B_6pxgjj.d.ts → prompt-CgKmMkVe.d.ts} +1 -1
  35. package/dist/{tool-descriptions-7CgIovZc.d.ts → tool-descriptions-C6xBOUjO.d.ts} +1 -1
  36. package/dist/vercel/index.d.ts +1 -1
  37. package/dist/vercel/index.js +5 -3
  38. package/dist/vercel/index.js.map +1 -1
  39. package/package.json +26 -23
  40. package/dist/chunk-IMI7BLEG.js.map +0 -1
  41. package/dist/chunk-XEQB7N3F.js.map +0 -1
  42. package/dist/chunk-Y4G25V5V.js.map +0 -1
  43. package/dist/chunk-ZPXFVDYT.js.map +0 -1
@@ -24,6 +24,15 @@ var FileVersionTracker = class {
24
24
  enabled;
25
25
  readVersions = /* @__PURE__ */ new Map();
26
26
  editVersions = /* @__PURE__ */ new Map();
27
+ // The stamp key for a path: one key per file, not per spelling.
28
+ // readFile and writeFile follow the namespace symlink table, so
29
+ // `/alias` and `/target` are the same file. Keying by the caller's
30
+ // spelling would give each its own stamp, and an edit that arrived
31
+ // through the other name would find no prior version and skip the
32
+ // staleness check entirely.
33
+ key(path) {
34
+ return this.ws.namespace.follow(path);
35
+ }
27
36
  async currentVersion(path) {
28
37
  if (!await this.ws.fs.exists(path)) return null;
29
38
  return fingerprint(await readBuffer(this.ws, path));
@@ -33,42 +42,51 @@ var FileVersionTracker = class {
33
42
  throw new StaleMirageFileError(path);
34
43
  }
35
44
  }
36
- recordWrite(path, content) {
45
+ // Stamp what a later read will return, not the bytes handed in. A
46
+ // mount that does not store writes verbatim answers with something
47
+ // else, so stamping the input would make the very next write or edit
48
+ // look stale with nobody having touched the file.
49
+ async recordWrite(path, key) {
37
50
  if (!this.enabled) return;
38
- this.readVersions.set(path, fingerprint(content));
39
- this.editVersions.delete(path);
51
+ const version = await this.currentVersion(path);
52
+ if (version === null) this.readVersions.delete(key);
53
+ else this.readVersions.set(key, version);
54
+ this.editVersions.delete(key);
40
55
  }
41
56
  async read(path) {
42
57
  const content = await readBuffer(this.ws, path);
43
- if (this.enabled) this.readVersions.set(path, fingerprint(content));
58
+ if (this.enabled) this.readVersions.set(this.key(path), fingerprint(content));
44
59
  return content;
45
60
  }
46
61
  async readForEdit(path) {
47
62
  const content = await readBuffer(this.ws, path);
48
63
  if (!this.enabled) return content;
64
+ const key = this.key(path);
49
65
  const version = fingerprint(content);
50
- const readVersion = this.readVersions.get(path);
66
+ const readVersion = this.readVersions.get(key);
51
67
  if (readVersion !== void 0 && readVersion !== version) {
52
68
  throw new StaleMirageFileError(path);
53
69
  }
54
- this.editVersions.set(path, version);
70
+ this.editVersions.set(key, version);
55
71
  return content;
56
72
  }
57
73
  async write(path, content) {
74
+ const key = this.key(path);
58
75
  if (this.enabled) {
59
- const readVersion = this.readVersions.get(path);
76
+ const readVersion = this.readVersions.get(key);
60
77
  if (readVersion !== void 0) await this.assertVersion(path, readVersion);
61
78
  }
62
79
  await this.ws.fs.writeFile(path, content);
63
- this.recordWrite(path, content);
80
+ await this.recordWrite(path, key);
64
81
  }
65
82
  async writeEdit(path, content) {
83
+ const key = this.key(path);
66
84
  if (this.enabled) {
67
- const editVersion = this.editVersions.get(path);
85
+ const editVersion = this.editVersions.get(key);
68
86
  if (editVersion !== void 0) await this.assertVersion(path, editVersion);
69
87
  }
70
88
  await this.ws.fs.writeFile(path, content);
71
- this.recordWrite(path, content);
89
+ await this.recordWrite(path, key);
72
90
  }
73
91
  };
74
92
 
@@ -76,4 +94,4 @@ export {
76
94
  StaleMirageFileError,
77
95
  FileVersionTracker
78
96
  };
79
- //# sourceMappingURL=chunk-XEQB7N3F.js.map
97
+ //# sourceMappingURL=chunk-YJS2FVEB.js.map
@@ -0,0 +1 @@
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/workspace/workspace/workspace'\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 // The stamp key for a path: one key per file, not per spelling.\n // readFile and writeFile follow the namespace symlink table, so\n // `/alias` and `/target` are the same file. Keying by the caller's\n // spelling would give each its own stamp, and an edit that arrived\n // through the other name would find no prior version and skip the\n // staleness check entirely.\n private key(path: string): string {\n return this.ws.namespace.follow(path)\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 // Stamp what a later read will return, not the bytes handed in. A\n // mount that does not store writes verbatim answers with something\n // else, so stamping the input would make the very next write or edit\n // look stale with nobody having touched the file.\n private async recordWrite(path: string, key: string): Promise<void> {\n if (!this.enabled) return\n const version = await this.currentVersion(path)\n if (version === null) this.readVersions.delete(key)\n else this.readVersions.set(key, version)\n this.editVersions.delete(key)\n }\n\n async read(path: string): Promise<Buffer> {\n const content = await readBuffer(this.ws, path)\n if (this.enabled) this.readVersions.set(this.key(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 key = this.key(path)\n const version = fingerprint(content)\n const readVersion = this.readVersions.get(key)\n if (readVersion !== undefined && readVersion !== version) {\n throw new StaleMirageFileError(path)\n }\n this.editVersions.set(key, version)\n return content\n }\n\n async write(path: string, content: string): Promise<void> {\n const key = this.key(path)\n if (this.enabled) {\n const readVersion = this.readVersions.get(key)\n if (readVersion !== undefined) await this.assertVersion(path, readVersion)\n }\n await this.ws.fs.writeFile(path, content)\n await this.recordWrite(path, key)\n }\n\n async writeEdit(path: string, content: string): Promise<void> {\n const key = this.key(path)\n if (this.enabled) {\n const editVersion = this.editVersions.get(key)\n if (editVersion !== undefined) await this.assertVersion(path, editVersion)\n }\n await this.ws.fs.writeFile(path, content)\n await this.recordWrite(path, key)\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,9 +1,9 @@
1
1
  import * as _anthropic_ai_claude_agent_sdk from '@anthropic-ai/claude-agent-sdk';
2
2
  import { Options } from '@anthropic-ai/claude-agent-sdk';
3
- import { Workspace } from '@struktoai/mirage-core';
4
- import { M as MirageToolOperationsOptions } from '../tool-descriptions-7CgIovZc.js';
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-B_6pxgjj.js';
3
+ import { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace';
4
+ import { M as MirageToolOperationsOptions } from '../tool-descriptions-C6xBOUjO.js';
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-C6xBOUjO.js';
6
+ export { M as MIRAGE_SYSTEM_PROMPT, b as buildSystemPrompt } from '../prompt-CgKmMkVe.js';
7
7
 
8
8
  declare function MirageServer(workspace: Workspace, options?: MirageToolOperationsOptions): _anthropic_ai_claude_agent_sdk.McpSdkServerConfigWithInstance;
9
9
 
@@ -6,15 +6,16 @@ import {
6
6
  MirageToolOperations,
7
7
  READ_DESCRIPTION,
8
8
  WRITE_DESCRIPTION
9
- } from "../chunk-Y4G25V5V.js";
9
+ } from "../chunk-GEO2G6YZ.js";
10
+ import "../chunk-YJS2FVEB.js";
10
11
  import {
11
12
  MIRAGE_SYSTEM_PROMPT,
12
13
  buildSystemPrompt
13
- } from "../chunk-ZPXFVDYT.js";
14
- import "../chunk-XEQB7N3F.js";
14
+ } from "../chunk-S6DWWJVF.js";
15
+ import "../chunk-3N5GLSL7.js";
15
16
 
16
17
  // src/claude-agent-sdk/server.ts
17
- import { VERSION } from "@struktoai/mirage-core";
18
+ import { VERSION } from "@struktoai/mirage-core/version";
18
19
  import { createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk";
19
20
  import { z } from "zod";
20
21
  function MirageServer(workspace, options = {}) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/claude-agent-sdk/server.ts","../../src/claude-agent-sdk/options.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 { VERSION } from '@struktoai/mirage-core'\nimport { createSdkMcpServer, tool } from '@anthropic-ai/claude-agent-sdk'\nimport { z } from 'zod'\nimport {\n MirageToolOperations,\n type MirageToolOperationsOptions,\n type ToolResult,\n} from '../tool-operations.ts'\nimport {\n EDIT_DESCRIPTION,\n EXECUTE_DESCRIPTION,\n GREP_DESCRIPTION,\n LS_DESCRIPTION,\n READ_DESCRIPTION,\n WRITE_DESCRIPTION,\n} from './descriptions.ts'\n\nexport async function runExecute(ws: Workspace, command: string): Promise<ToolResult> {\n return new MirageToolOperations(ws).execute(command)\n}\n\nexport async function runRead(\n ws: Workspace,\n path: string,\n offset = 0,\n limit = 2000,\n): Promise<ToolResult> {\n return new MirageToolOperations(ws).read(path, offset, limit)\n}\n\nexport async function runWrite(ws: Workspace, path: string, content: string): Promise<ToolResult> {\n return new MirageToolOperations(ws).write(path, content)\n}\n\nexport async function runEdit(\n ws: Workspace,\n path: string,\n oldString: string,\n newString: string,\n replaceAll = false,\n): Promise<ToolResult> {\n return new MirageToolOperations(ws).edit(path, oldString, newString, replaceAll)\n}\n\nexport async function runLs(ws: Workspace, path: string): Promise<ToolResult> {\n return new MirageToolOperations(ws).ls(path)\n}\n\nexport async function runGrep(ws: Workspace, pattern: string, path: string): Promise<ToolResult> {\n return new MirageToolOperations(ws).grep(pattern, path)\n}\n\nexport function MirageServer(workspace: Workspace, options: MirageToolOperationsOptions = {}) {\n const operations = new MirageToolOperations(workspace, options)\n return createSdkMcpServer({\n name: 'mirage',\n version: VERSION,\n alwaysLoad: true,\n tools: [\n tool('execute_command', EXECUTE_DESCRIPTION, { command: z.string() }, (args) =>\n operations.execute(args.command),\n ),\n tool(\n 'read',\n READ_DESCRIPTION,\n { path: z.string(), offset: z.number().optional(), limit: z.number().optional() },\n (args) => operations.read(args.path, args.offset, args.limit),\n { annotations: { readOnlyHint: true } },\n ),\n tool('write', WRITE_DESCRIPTION, { path: z.string(), content: z.string() }, (args) =>\n operations.write(args.path, args.content),\n ),\n tool(\n 'edit',\n EDIT_DESCRIPTION,\n {\n path: z.string(),\n old_string: z.string(),\n new_string: z.string(),\n replace_all: z.boolean().optional(),\n },\n (args) => operations.edit(args.path, args.old_string, args.new_string, args.replace_all),\n ),\n tool('ls', LS_DESCRIPTION, { path: z.string() }, (args) => operations.ls(args.path), {\n annotations: { readOnlyHint: true },\n }),\n tool(\n 'grep',\n GREP_DESCRIPTION,\n { pattern: z.string(), path: z.string() },\n (args) => operations.grep(args.pattern, args.path),\n { annotations: { readOnlyHint: true } },\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 type { Workspace } from '@struktoai/mirage-core'\nimport type { Options } from '@anthropic-ai/claude-agent-sdk'\nimport { buildSystemPrompt } from '../prompt.ts'\nimport { MirageServer } from './server.ts'\n\nexport interface BuildOptionsOptions {\n systemPrompt?: string\n}\n\nexport function buildOptions(workspace: Workspace, opts: BuildOptionsOptions = {}): Options {\n return {\n mcpServers: { mirage: MirageServer(workspace) },\n allowedTools: ['mcp__mirage__*'],\n systemPrompt: opts.systemPrompt ?? buildSystemPrompt({ workspace }),\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,SAAS,eAAe;AACxB,SAAS,oBAAoB,YAAY;AACzC,SAAS,SAAS;AAkDX,SAAS,aAAa,WAAsB,UAAuC,CAAC,GAAG;AAC5F,QAAM,aAAa,IAAI,qBAAqB,WAAW,OAAO;AAC9D,SAAO,mBAAmB;AAAA,IACxB,MAAM;AAAA,IACN,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,OAAO;AAAA,MACL;AAAA,QAAK;AAAA,QAAmB;AAAA,QAAqB,EAAE,SAAS,EAAE,OAAO,EAAE;AAAA,QAAG,CAAC,SACrE,WAAW,QAAQ,KAAK,OAAO;AAAA,MACjC;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA,EAAE,MAAM,EAAE,OAAO,GAAG,QAAQ,EAAE,OAAO,EAAE,SAAS,GAAG,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE;AAAA,QAChF,CAAC,SAAS,WAAW,KAAK,KAAK,MAAM,KAAK,QAAQ,KAAK,KAAK;AAAA,QAC5D,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,MACxC;AAAA,MACA;AAAA,QAAK;AAAA,QAAS;AAAA,QAAmB,EAAE,MAAM,EAAE,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE;AAAA,QAAG,CAAC,SAC3E,WAAW,MAAM,KAAK,MAAM,KAAK,OAAO;AAAA,MAC1C;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,UACE,MAAM,EAAE,OAAO;AAAA,UACf,YAAY,EAAE,OAAO;AAAA,UACrB,YAAY,EAAE,OAAO;AAAA,UACrB,aAAa,EAAE,QAAQ,EAAE,SAAS;AAAA,QACpC;AAAA,QACA,CAAC,SAAS,WAAW,KAAK,KAAK,MAAM,KAAK,YAAY,KAAK,YAAY,KAAK,WAAW;AAAA,MACzF;AAAA,MACA,KAAK,MAAM,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,SAAS,WAAW,GAAG,KAAK,IAAI,GAAG;AAAA,QACnF,aAAa,EAAE,cAAc,KAAK;AAAA,MACpC,CAAC;AAAA,MACD;AAAA,QACE;AAAA,QACA;AAAA,QACA,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE;AAAA,QACxC,CAAC,SAAS,WAAW,KAAK,KAAK,SAAS,KAAK,IAAI;AAAA,QACjD,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,MACxC;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;ACvFO,SAAS,aAAa,WAAsB,OAA4B,CAAC,GAAY;AAC1F,SAAO;AAAA,IACL,YAAY,EAAE,QAAQ,aAAa,SAAS,EAAE;AAAA,IAC9C,cAAc,CAAC,gBAAgB;AAAA,IAC/B,cAAc,KAAK,gBAAgB,kBAAkB,EAAE,UAAU,CAAC;AAAA,EACpE;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/claude-agent-sdk/server.ts","../../src/claude-agent-sdk/options.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 { VERSION } from '@struktoai/mirage-core/version'\nimport type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport { createSdkMcpServer, tool } from '@anthropic-ai/claude-agent-sdk'\nimport { z } from 'zod'\nimport {\n MirageToolOperations,\n type MirageToolOperationsOptions,\n type ToolResult,\n} from '../tool-operations.ts'\nimport {\n EDIT_DESCRIPTION,\n EXECUTE_DESCRIPTION,\n GREP_DESCRIPTION,\n LS_DESCRIPTION,\n READ_DESCRIPTION,\n WRITE_DESCRIPTION,\n} from './descriptions.ts'\n\nexport async function runExecute(ws: Workspace, command: string): Promise<ToolResult> {\n return new MirageToolOperations(ws).execute(command)\n}\n\nexport async function runRead(\n ws: Workspace,\n path: string,\n offset = 0,\n limit = 2000,\n): Promise<ToolResult> {\n return new MirageToolOperations(ws).read(path, offset, limit)\n}\n\nexport async function runWrite(ws: Workspace, path: string, content: string): Promise<ToolResult> {\n return new MirageToolOperations(ws).write(path, content)\n}\n\nexport async function runEdit(\n ws: Workspace,\n path: string,\n oldString: string,\n newString: string,\n replaceAll = false,\n): Promise<ToolResult> {\n return new MirageToolOperations(ws).edit(path, oldString, newString, replaceAll)\n}\n\nexport async function runLs(ws: Workspace, path: string): Promise<ToolResult> {\n return new MirageToolOperations(ws).ls(path)\n}\n\nexport async function runGrep(ws: Workspace, pattern: string, path: string): Promise<ToolResult> {\n return new MirageToolOperations(ws).grep(pattern, path)\n}\n\nexport function MirageServer(workspace: Workspace, options: MirageToolOperationsOptions = {}) {\n const operations = new MirageToolOperations(workspace, options)\n return createSdkMcpServer({\n name: 'mirage',\n version: VERSION,\n alwaysLoad: true,\n tools: [\n tool('execute_command', EXECUTE_DESCRIPTION, { command: z.string() }, (args) =>\n operations.execute(args.command),\n ),\n tool(\n 'read',\n READ_DESCRIPTION,\n { path: z.string(), offset: z.number().optional(), limit: z.number().optional() },\n (args) => operations.read(args.path, args.offset, args.limit),\n { annotations: { readOnlyHint: true } },\n ),\n tool('write', WRITE_DESCRIPTION, { path: z.string(), content: z.string() }, (args) =>\n operations.write(args.path, args.content),\n ),\n tool(\n 'edit',\n EDIT_DESCRIPTION,\n {\n path: z.string(),\n old_string: z.string(),\n new_string: z.string(),\n replace_all: z.boolean().optional(),\n },\n (args) => operations.edit(args.path, args.old_string, args.new_string, args.replace_all),\n ),\n tool('ls', LS_DESCRIPTION, { path: z.string() }, (args) => operations.ls(args.path), {\n annotations: { readOnlyHint: true },\n }),\n tool(\n 'grep',\n GREP_DESCRIPTION,\n { pattern: z.string(), path: z.string() },\n (args) => operations.grep(args.pattern, args.path),\n { annotations: { readOnlyHint: true } },\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 type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport type { Options } from '@anthropic-ai/claude-agent-sdk'\nimport { buildSystemPrompt } from '../prompt.ts'\nimport { MirageServer } from './server.ts'\n\nexport interface BuildOptionsOptions {\n systemPrompt?: string\n}\n\nexport function buildOptions(workspace: Workspace, opts: BuildOptionsOptions = {}): Options {\n return {\n mcpServers: { mirage: MirageServer(workspace) },\n allowedTools: ['mcp__mirage__*'],\n systemPrompt: opts.systemPrompt ?? buildSystemPrompt({ workspace }),\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAcA,SAAS,eAAe;AAExB,SAAS,oBAAoB,YAAY;AACzC,SAAS,SAAS;AAkDX,SAAS,aAAa,WAAsB,UAAuC,CAAC,GAAG;AAC5F,QAAM,aAAa,IAAI,qBAAqB,WAAW,OAAO;AAC9D,SAAO,mBAAmB;AAAA,IACxB,MAAM;AAAA,IACN,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,OAAO;AAAA,MACL;AAAA,QAAK;AAAA,QAAmB;AAAA,QAAqB,EAAE,SAAS,EAAE,OAAO,EAAE;AAAA,QAAG,CAAC,SACrE,WAAW,QAAQ,KAAK,OAAO;AAAA,MACjC;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA,EAAE,MAAM,EAAE,OAAO,GAAG,QAAQ,EAAE,OAAO,EAAE,SAAS,GAAG,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE;AAAA,QAChF,CAAC,SAAS,WAAW,KAAK,KAAK,MAAM,KAAK,QAAQ,KAAK,KAAK;AAAA,QAC5D,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,MACxC;AAAA,MACA;AAAA,QAAK;AAAA,QAAS;AAAA,QAAmB,EAAE,MAAM,EAAE,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE;AAAA,QAAG,CAAC,SAC3E,WAAW,MAAM,KAAK,MAAM,KAAK,OAAO;AAAA,MAC1C;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,UACE,MAAM,EAAE,OAAO;AAAA,UACf,YAAY,EAAE,OAAO;AAAA,UACrB,YAAY,EAAE,OAAO;AAAA,UACrB,aAAa,EAAE,QAAQ,EAAE,SAAS;AAAA,QACpC;AAAA,QACA,CAAC,SAAS,WAAW,KAAK,KAAK,MAAM,KAAK,YAAY,KAAK,YAAY,KAAK,WAAW;AAAA,MACzF;AAAA,MACA,KAAK,MAAM,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,SAAS,WAAW,GAAG,KAAK,IAAI,GAAG;AAAA,QACnF,aAAa,EAAE,cAAc,KAAK;AAAA,MACpC,CAAC;AAAA,MACD;AAAA,QACE;AAAA,QACA;AAAA,QACA,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE;AAAA,QACxC,CAAC,SAAS,WAAW,KAAK,KAAK,SAAS,KAAK,IAAI;AAAA,QACjD,EAAE,aAAa,EAAE,cAAc,KAAK,EAAE;AAAA,MACxC;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;ACvFO,SAAS,aAAa,WAAsB,OAA4B,CAAC,GAAY;AAC1F,SAAO;AAAA,IACL,YAAY,EAAE,QAAQ,aAAa,SAAS,EAAE;AAAA,IAC9C,cAAc,CAAC,gBAAgB;AAAA,IAC/B,cAAc,KAAK,gBAAgB,kBAAkB,EAAE,UAAU,CAAC;AAAA,EACpE;AACF;","names":[]}
@@ -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 class StaleMirageFileError extends Error {
4
4
  readonly path: string;
@@ -10,6 +10,7 @@ declare class FileVersionTracker {
10
10
  private readonly readVersions;
11
11
  private readonly editVersions;
12
12
  constructor(ws: Workspace, enabled?: boolean);
13
+ private key;
13
14
  private currentVersion;
14
15
  private assertVersion;
15
16
  private recordWrite;
@@ -1,7 +1,7 @@
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-B_6pxgjj.js';
4
- import '@struktoai/mirage-core';
3
+ export { B as BuildSystemPromptOptions, M as MIRAGE_SYSTEM_PROMPT, b as buildSystemPrompt } from '../prompt-CgKmMkVe.js';
4
+ import '@struktoai/mirage-core/workspace/workspace/workspace';
5
5
 
6
6
  interface LangchainWorkspaceOptions {
7
7
  sandboxId?: string;
@@ -16,7 +16,7 @@ declare class LangchainWorkspace implements SandboxBackendProtocolV2 {
16
16
  readRaw(filePath: string): Promise<ReadRawResult>;
17
17
  write(filePath: string, content: string): Promise<WriteResult>;
18
18
  edit(filePath: string, oldString: string, newString: string, replaceAll?: boolean): Promise<EditResult>;
19
- grep(pattern: string, path?: string | null, glob?: string | null): Promise<GrepResult>;
19
+ grep(pattern: string, path?: string | null, glob?: string | null, maxCount?: number | null): Promise<GrepResult>;
20
20
  glob(pattern: string, path?: string): Promise<GlobResult>;
21
21
  uploadFiles(files: readonly (readonly [string, Uint8Array])[]): Promise<FileUploadResponse[]>;
22
22
  downloadFiles(paths: readonly string[]): Promise<FileDownloadResponse[]>;
@@ -1,7 +1,10 @@
1
1
  import {
2
2
  MIRAGE_SYSTEM_PROMPT,
3
3
  buildSystemPrompt
4
- } from "../chunk-ZPXFVDYT.js";
4
+ } from "../chunk-S6DWWJVF.js";
5
+ import {
6
+ withRefusal
7
+ } from "../chunk-3N5GLSL7.js";
5
8
 
6
9
  // src/langchain/convert.ts
7
10
  function ioToExecuteResponse(io) {
@@ -12,7 +15,11 @@ function ioToExecuteResponse(io) {
12
15
  output = stdout.length > 0 ? `${stdout}
13
16
  ${stderr}` : stderr;
14
17
  }
15
- return { output, exitCode: io.exitCode, truncated: false };
18
+ return {
19
+ output: withRefusal(output, io.refusal ?? null),
20
+ exitCode: io.exitCode,
21
+ truncated: false
22
+ };
16
23
  }
17
24
  function ioToGrepMatches(io) {
18
25
  const stdout = io.stdoutText.trim();
@@ -46,7 +53,7 @@ function ioToFileInfos(io) {
46
53
  }
47
54
 
48
55
  // src/langchain/backend.ts
49
- import { gnuDirname } from "@struktoai/mirage-core";
56
+ import { gnuDirname } from "@struktoai/mirage-core/utils/path";
50
57
  var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
51
58
  "txt",
52
59
  "md",
@@ -227,7 +234,12 @@ var LangchainWorkspace = class {
227
234
  await this.ws.fs.writeFile(filePath, next);
228
235
  return { path: filePath, occurrences: replaceAll ? count : 1 };
229
236
  }
230
- async grep(pattern, path, glob) {
237
+ // maxCount is a total cap across every file, which is not what `grep -m`
238
+ // means (that one caps each file separately), so it is applied to the
239
+ // collected matches rather than pushed onto the command line. A run that
240
+ // hits the cap with matches left over is truncated; one that lands on it
241
+ // exactly is complete.
242
+ async grep(pattern, path, glob, maxCount) {
231
243
  const parts = ["grep", "-rn"];
232
244
  if (glob !== void 0 && glob !== null && glob.length > 0) {
233
245
  parts.push("--include", shellQuote(glob));
@@ -235,7 +247,11 @@ var LangchainWorkspace = class {
235
247
  parts.push(shellQuote(pattern));
236
248
  parts.push(shellQuote(path ?? "/"));
237
249
  const io = await this.ws.execute(parts.join(" "));
238
- return { matches: ioToGrepMatches(io) };
250
+ const matches = ioToGrepMatches(io);
251
+ if (maxCount === void 0 || maxCount === null || matches.length <= maxCount) {
252
+ return { matches };
253
+ }
254
+ return { matches: matches.slice(0, maxCount), truncated: true };
239
255
  }
240
256
  async glob(pattern, path = "/") {
241
257
  const name = pattern.includes("/") ? pattern.split("/").pop() ?? pattern : pattern;
@@ -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\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":"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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'\nimport type { Refusal } from '@struktoai/mirage-core/types'\nimport { withRefusal } from '../io-text.ts'\n\ninterface IOLike {\n stdoutText: string\n stderrText: string\n exitCode: number | null\n refusal?: Refusal | 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 {\n output: withRefusal(output, io.refusal ?? null),\n exitCode: io.exitCode,\n truncated: false,\n }\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/utils/path'\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 // maxCount is a total cap across every file, which is not what `grep -m`\n // means (that one caps each file separately), so it is applied to the\n // collected matches rather than pushed onto the command line. A run that\n // hits the cap with matches left over is truncated; one that lands on it\n // exactly is complete.\n async grep(\n pattern: string,\n path?: string | null,\n glob?: string | null,\n maxCount?: number | null,\n ): 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 const matches = ioToGrepMatches(io)\n if (maxCount === undefined || maxCount === null || matches.length <= maxCount) {\n return { matches }\n }\n return { matches: matches.slice(0, maxCount), truncated: true }\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,5 +1,5 @@
1
1
  import * as _mastra_core_tools from '@mastra/core/tools';
2
- import { Workspace } from '@struktoai/mirage-core';
2
+ import { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace';
3
3
 
4
4
  declare function mirageTools(ws: Workspace): {
5
5
  execute: _mastra_core_tools.Tool<{
@@ -8,6 +8,13 @@ declare function mirageTools(ws: Workspace): {
8
8
  stdout: string;
9
9
  stderr: string;
10
10
  exitCode: number;
11
+ refusal: {
12
+ kind: "deny" | "pending" | "failed";
13
+ reason: string;
14
+ policy: string;
15
+ scope: "command" | "operand";
16
+ askId: string | null;
17
+ } | null;
11
18
  }, unknown, unknown, _mastra_core_tools.ToolExecutionContext<unknown, unknown, unknown>, "mirage-execute", unknown>;
12
19
  readFile: _mastra_core_tools.Tool<{
13
20
  path: string;
@@ -1,7 +1,7 @@
1
1
  // src/mastra/index.ts
2
+ import { gnuDirname } from "@struktoai/mirage-core/utils/path";
2
3
  import { createTool } from "@mastra/core/tools";
3
4
  import { z } from "zod";
4
- import { gnuDirname } from "@struktoai/mirage-core";
5
5
  async function ensureParent(ws, path) {
6
6
  const parent = gnuDirname(path);
7
7
  if (parent === "/" || parent === "" || parent === ".") return;
@@ -24,7 +24,16 @@ function mirageTools(ws) {
24
24
  outputSchema: z.object({
25
25
  stdout: z.string(),
26
26
  stderr: z.string(),
27
- exitCode: z.number()
27
+ exitCode: z.number(),
28
+ // Why the line did not run, null on every ordinary run; the
29
+ // reason a bash-voiced stderr leaves out.
30
+ refusal: z.object({
31
+ kind: z.enum(["deny", "pending", "failed"]),
32
+ reason: z.string(),
33
+ policy: z.string(),
34
+ scope: z.enum(["command", "operand"]),
35
+ askId: z.string().nullable()
36
+ }).nullable()
28
37
  }),
29
38
  execute: async (inputData) => {
30
39
  const { command } = inputData;
@@ -32,7 +41,8 @@ function mirageTools(ws) {
32
41
  return {
33
42
  stdout: io.stdoutText,
34
43
  stderr: io.stderrText,
35
- exitCode: io.exitCode
44
+ exitCode: io.exitCode,
45
+ refusal: io.refusal
36
46
  };
37
47
  }
38
48
  }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/mastra/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 type { Workspace } from '@struktoai/mirage-core'\nimport { createTool } from '@mastra/core/tools'\nimport { z } from 'zod'\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 if (!(await ws.fs.exists(parent))) throw err\n }\n}\n\nexport function mirageTools(ws: Workspace) {\n return {\n execute: createTool({\n id: 'mirage-execute',\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 outputSchema: z.object({\n stdout: z.string(),\n stderr: z.string(),\n exitCode: z.number(),\n }),\n execute: async (inputData) => {\n const { command } = inputData as { command: string }\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: createTool({\n id: 'mirage-read-file',\n description: 'Read the contents of a file from the Mirage workspace as UTF-8 text.',\n inputSchema: z.object({\n path: z.string().describe('Absolute path inside the workspace.'),\n }),\n outputSchema: z.object({\n content: z.string().optional(),\n error: z.string().optional(),\n }),\n execute: async (inputData) => {\n const { path } = inputData as { path: string }\n try {\n const content = await ws.fs.readFileText(path)\n return { content }\n } catch (err) {\n return { error: err instanceof Error ? err.message : String(err) }\n }\n },\n }),\n\n writeFile: createTool({\n id: 'mirage-write-file',\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 outputSchema: z.object({ path: z.string() }),\n execute: async (inputData) => {\n const { path, content } = inputData as { path: string; content: string }\n await ensureParent(ws, path)\n await ws.fs.writeFile(path, content)\n return { path }\n },\n }),\n\n editFile: createTool({\n id: 'mirage-edit-file',\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 outputSchema: z.object({\n path: z.string().optional(),\n occurrences: z.number().optional(),\n error: z.string().optional(),\n }),\n execute: async (inputData) => {\n const { path, oldString, newString, replaceAll } = inputData as {\n path: string\n oldString: string\n newString: string\n replaceAll?: boolean\n }\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: createTool({\n id: 'mirage-ls',\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 outputSchema: z.object({\n files: z.array(z.object({ path: z.string(), is_dir: z.boolean() })).optional(),\n error: z.string().optional(),\n }),\n execute: async (inputData) => {\n const { path } = inputData as { path: string }\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":";AAeA,SAAS,kBAAkB;AAC3B,SAAS,SAAS;AAClB,SAAS,kBAAkB;AAE3B,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;AAEO,SAAS,YAAY,IAAe;AACzC,SAAO;AAAA,IACL,SAAS,WAAW;AAAA,MAClB,IAAI;AAAA,MACJ,aACE;AAAA,MACF,aAAa,EAAE,OAAO;AAAA,QACpB,SAAS,EAAE,OAAO,EAAE,SAAS,+BAA+B;AAAA,MAC9D,CAAC;AAAA,MACD,cAAc,EAAE,OAAO;AAAA,QACrB,QAAQ,EAAE,OAAO;AAAA,QACjB,QAAQ,EAAE,OAAO;AAAA,QACjB,UAAU,EAAE,OAAO;AAAA,MACrB,CAAC;AAAA,MACD,SAAS,OAAO,cAAc;AAC5B,cAAM,EAAE,QAAQ,IAAI;AACpB,cAAM,KAAK,MAAM,GAAG,QAAQ,OAAO;AACnC,eAAO;AAAA,UACL,QAAQ,GAAG;AAAA,UACX,QAAQ,GAAG;AAAA,UACX,UAAU,GAAG;AAAA,QACf;AAAA,MACF;AAAA,IACF,CAAC;AAAA,IAED,UAAU,WAAW;AAAA,MACnB,IAAI;AAAA,MACJ,aAAa;AAAA,MACb,aAAa,EAAE,OAAO;AAAA,QACpB,MAAM,EAAE,OAAO,EAAE,SAAS,qCAAqC;AAAA,MACjE,CAAC;AAAA,MACD,cAAc,EAAE,OAAO;AAAA,QACrB,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,QAC7B,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,MAC7B,CAAC;AAAA,MACD,SAAS,OAAO,cAAc;AAC5B,cAAM,EAAE,KAAK,IAAI;AACjB,YAAI;AACF,gBAAM,UAAU,MAAM,GAAG,GAAG,aAAa,IAAI;AAC7C,iBAAO,EAAE,QAAQ;AAAA,QACnB,SAAS,KAAK;AACZ,iBAAO,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE;AAAA,QACnE;AAAA,MACF;AAAA,IACF,CAAC;AAAA,IAED,WAAW,WAAW;AAAA,MACpB,IAAI;AAAA,MACJ,aACE;AAAA,MACF,aAAa,EAAE,OAAO;AAAA,QACpB,MAAM,EAAE,OAAO,EAAE,SAAS,qCAAqC;AAAA,QAC/D,SAAS,EAAE,OAAO,EAAE,SAAS,8BAA8B;AAAA,MAC7D,CAAC;AAAA,MACD,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAAA,MAC3C,SAAS,OAAO,cAAc;AAC5B,cAAM,EAAE,MAAM,QAAQ,IAAI;AAC1B,cAAM,aAAa,IAAI,IAAI;AAC3B,cAAM,GAAG,GAAG,UAAU,MAAM,OAAO;AACnC,eAAO,EAAE,KAAK;AAAA,MAChB;AAAA,IACF,CAAC;AAAA,IAED,UAAU,WAAW;AAAA,MACnB,IAAI;AAAA,MACJ,aACE;AAAA,MACF,aAAa,EAAE,OAAO;AAAA,QACpB,MAAM,EAAE,OAAO,EAAE,SAAS,oCAAoC;AAAA,QAC9D,WAAW,EAAE,OAAO,EAAE,SAAS,8BAA8B;AAAA,QAC7D,WAAW,EAAE,OAAO,EAAE,SAAS,yBAAyB;AAAA,QACxD,YAAY,EACT,QAAQ,EACR,SAAS,EACT,SAAS,gEAAgE;AAAA,MAC9E,CAAC;AAAA,MACD,cAAc,EAAE,OAAO;AAAA,QACrB,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,QAC1B,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,QACjC,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,MAC7B,CAAC;AAAA,MACD,SAAS,OAAO,cAAc;AAC5B,cAAM,EAAE,MAAM,WAAW,WAAW,WAAW,IAAI;AAMnD,YAAI;AACJ,YAAI;AACF,oBAAU,MAAM,GAAG,GAAG,aAAa,IAAI;AAAA,QACzC,QAAQ;AACN,iBAAO,EAAE,OAAO,gBAAgB,IAAI,cAAc;AAAA,QACpD;AACA,cAAM,QAAQ,QAAQ,MAAM,SAAS,EAAE,SAAS;AAChD,YAAI,UAAU,GAAG;AACf,iBAAO,EAAE,OAAO,qCAAqC,SAAS,IAAI;AAAA,QACpE;AACA,YAAI,QAAQ,KAAK,eAAe,MAAM;AACpC,iBAAO;AAAA,YACL,OAAO,kBAAkB,SAAS,aAAa,OAAO,KAAK,CAAC;AAAA,UAC9D;AAAA,QACF;AACA,cAAM,OACJ,eAAe,OACX,QAAQ,MAAM,SAAS,EAAE,KAAK,SAAS,IACvC,QAAQ,QAAQ,WAAW,SAAS;AAC1C,cAAM,GAAG,GAAG,UAAU,MAAM,IAAI;AAChC,eAAO,EAAE,MAAM,aAAa,eAAe,OAAO,QAAQ,EAAE;AAAA,MAC9D;AAAA,IACF,CAAC;AAAA,IAED,IAAI,WAAW;AAAA,MACb,IAAI;AAAA,MACJ,aAAa;AAAA,MACb,aAAa,EAAE,OAAO;AAAA,QACpB,MAAM,EAAE,OAAO,EAAE,SAAS,+CAA+C;AAAA,MAC3E,CAAC;AAAA,MACD,cAAc,EAAE,OAAO;AAAA,QACrB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,SAAS;AAAA,QAC7E,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,MAC7B,CAAC;AAAA,MACD,SAAS,OAAO,cAAc;AAC5B,cAAM,EAAE,KAAK,IAAI;AACjB,YAAI;AACJ,YAAI;AACF,oBAAU,MAAM,GAAG,GAAG,QAAQ,IAAI;AAAA,QACpC,SAAS,KAAK;AACZ,iBAAO,EAAE,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE;AAAA,QACnE;AACA,cAAM,QAA6C,CAAC;AACpD,mBAAW,SAAS,SAAS;AAC3B,gBAAM,QAAQ,MAAM,GAAG,GAAG,MAAM,KAAK;AACrC,gBAAM,KAAK,EAAE,MAAM,OAAO,QAAQ,MAAM,CAAC;AAAA,QAC3C;AACA,eAAO,EAAE,MAAM;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/mastra/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 { gnuDirname } from '@struktoai/mirage-core/utils/path'\nimport type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport { createTool } from '@mastra/core/tools'\nimport { z } from 'zod'\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\nexport function mirageTools(ws: Workspace) {\n return {\n execute: createTool({\n id: 'mirage-execute',\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 outputSchema: z.object({\n stdout: z.string(),\n stderr: z.string(),\n exitCode: z.number(),\n // Why the line did not run, null on every ordinary run; the\n // reason a bash-voiced stderr leaves out.\n refusal: z\n .object({\n kind: z.enum(['deny', 'pending', 'failed']),\n reason: z.string(),\n policy: z.string(),\n scope: z.enum(['command', 'operand']),\n askId: z.string().nullable(),\n })\n .nullable(),\n }),\n execute: async (inputData) => {\n const { command } = inputData as { command: string }\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: createTool({\n id: 'mirage-read-file',\n description: 'Read the contents of a file from the Mirage workspace as UTF-8 text.',\n inputSchema: z.object({\n path: z.string().describe('Absolute path inside the workspace.'),\n }),\n outputSchema: z.object({\n content: z.string().optional(),\n error: z.string().optional(),\n }),\n execute: async (inputData) => {\n const { path } = inputData as { path: string }\n try {\n const content = await ws.fs.readFileText(path)\n return { content }\n } catch (err) {\n return { error: err instanceof Error ? err.message : String(err) }\n }\n },\n }),\n\n writeFile: createTool({\n id: 'mirage-write-file',\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 outputSchema: z.object({ path: z.string() }),\n execute: async (inputData) => {\n const { path, content } = inputData as { path: string; content: string }\n await ensureParent(ws, path)\n await ws.fs.writeFile(path, content)\n return { path }\n },\n }),\n\n editFile: createTool({\n id: 'mirage-edit-file',\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 outputSchema: z.object({\n path: z.string().optional(),\n occurrences: z.number().optional(),\n error: z.string().optional(),\n }),\n execute: async (inputData) => {\n const { path, oldString, newString, replaceAll } = inputData as {\n path: string\n oldString: string\n newString: string\n replaceAll?: boolean\n }\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: createTool({\n id: 'mirage-ls',\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 outputSchema: z.object({\n files: z.array(z.object({ path: z.string(), is_dir: z.boolean() })).optional(),\n error: z.string().optional(),\n }),\n execute: async (inputData) => {\n const { path } = inputData as { path: string }\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,8 +1,8 @@
1
- import { Workspace } from '@struktoai/mirage-core';
1
+ import { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace';
2
2
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
- import { M as MirageToolOperationsOptions } from '../tool-descriptions-7CgIovZc.js';
4
- export { E as EDIT_DESCRIPTION, a as EXECUTE_DESCRIPTION, G as GREP_DESCRIPTION, L as LS_DESCRIPTION, b as MirageToolOperations, R as READ_DESCRIPTION, T as ToolResult, W as WRITE_DESCRIPTION } from '../tool-descriptions-7CgIovZc.js';
5
- export { F as FileVersionTracker, S as StaleMirageFileError } from '../file-version-Clij-pms.js';
3
+ import { M as MirageToolOperationsOptions } from '../tool-descriptions-C6xBOUjO.js';
4
+ export { E as EDIT_DESCRIPTION, a as EXECUTE_DESCRIPTION, G as GREP_DESCRIPTION, L as LS_DESCRIPTION, b as MirageToolOperations, R as READ_DESCRIPTION, T as ToolResult, W as WRITE_DESCRIPTION } from '../tool-descriptions-C6xBOUjO.js';
5
+ export { F as FileVersionTracker, S as StaleMirageFileError } from '../file-version-CE2J_nkn.js';
6
6
 
7
7
  interface MirageMcpServerOptions extends MirageToolOperationsOptions {
8
8
  name?: string;
package/dist/mcp/index.js CHANGED
@@ -6,14 +6,15 @@ import {
6
6
  MirageToolOperations,
7
7
  READ_DESCRIPTION,
8
8
  WRITE_DESCRIPTION
9
- } from "../chunk-Y4G25V5V.js";
9
+ } from "../chunk-GEO2G6YZ.js";
10
10
  import {
11
11
  FileVersionTracker,
12
12
  StaleMirageFileError
13
- } from "../chunk-XEQB7N3F.js";
13
+ } from "../chunk-YJS2FVEB.js";
14
+ import "../chunk-3N5GLSL7.js";
14
15
 
15
16
  // src/mcp/server.ts
16
- import { VERSION } from "@struktoai/mirage-core";
17
+ import { VERSION } from "@struktoai/mirage-core/version";
17
18
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
18
19
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
19
20
  import { z } from "zod";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/mcp/server.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 { VERSION } from '@struktoai/mirage-core'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { z } from 'zod'\nimport {\n EDIT_DESCRIPTION,\n EXECUTE_DESCRIPTION,\n GREP_DESCRIPTION,\n LS_DESCRIPTION,\n READ_DESCRIPTION,\n WRITE_DESCRIPTION,\n} from '../tool-descriptions.ts'\nimport { MirageToolOperations, type MirageToolOperationsOptions } from '../tool-operations.ts'\n\nexport interface MirageMcpServerOptions extends MirageToolOperationsOptions {\n name?: string\n version?: string\n}\n\nexport function createMirageMcpServer(\n workspace: Workspace,\n options: MirageMcpServerOptions = {},\n): McpServer {\n const operations = new MirageToolOperations(workspace, options)\n const server = new McpServer({\n name: options.name ?? 'mirage',\n version: options.version ?? VERSION,\n })\n\n server.registerTool(\n 'execute_command',\n { description: EXECUTE_DESCRIPTION, inputSchema: { command: z.string() } },\n (args) => operations.execute(args.command),\n )\n server.registerTool(\n 'read',\n {\n description: READ_DESCRIPTION,\n inputSchema: {\n path: z.string(),\n offset: z.number().int().min(0).optional(),\n limit: z.number().int().min(1).optional(),\n },\n annotations: { readOnlyHint: true },\n },\n (args) => operations.read(args.path, args.offset, args.limit),\n )\n server.registerTool(\n 'write',\n { description: WRITE_DESCRIPTION, inputSchema: { path: z.string(), content: z.string() } },\n (args) => operations.write(args.path, args.content),\n )\n server.registerTool(\n 'edit',\n {\n description: EDIT_DESCRIPTION,\n inputSchema: {\n path: z.string(),\n old_string: z.string(),\n new_string: z.string(),\n replace_all: z.boolean().optional(),\n },\n },\n (args) => operations.edit(args.path, args.old_string, args.new_string, args.replace_all),\n )\n server.registerTool(\n 'ls',\n {\n description: LS_DESCRIPTION,\n inputSchema: { path: z.string() },\n annotations: { readOnlyHint: true },\n },\n (args) => operations.ls(args.path),\n )\n server.registerTool(\n 'grep',\n {\n description: GREP_DESCRIPTION,\n inputSchema: { pattern: z.string(), path: z.string() },\n annotations: { readOnlyHint: true },\n },\n (args) => operations.grep(args.pattern, args.path),\n )\n\n return server\n}\n\nexport async function serveMirageMcp(\n workspace: Workspace,\n options: MirageMcpServerOptions = {},\n): Promise<McpServer> {\n const server = createMirageMcpServer(workspace, options)\n await server.connect(new StdioServerTransport())\n return server\n}\n"],"mappings":";;;;;;;;;;;;;;;AAeA,SAAS,eAAe;AACxB,SAAS,iBAAiB;AAC1B,SAAS,4BAA4B;AACrC,SAAS,SAAS;AAgBX,SAAS,sBACd,WACA,UAAkC,CAAC,GACxB;AACX,QAAM,aAAa,IAAI,qBAAqB,WAAW,OAAO;AAC9D,QAAM,SAAS,IAAI,UAAU;AAAA,IAC3B,MAAM,QAAQ,QAAQ;AAAA,IACtB,SAAS,QAAQ,WAAW;AAAA,EAC9B,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,EAAE,aAAa,qBAAqB,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE;AAAA,IACzE,CAAC,SAAS,WAAW,QAAQ,KAAK,OAAO;AAAA,EAC3C;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM,EAAE,OAAO;AAAA,QACf,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,QACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,MAC1C;AAAA,MACA,aAAa,EAAE,cAAc,KAAK;AAAA,IACpC;AAAA,IACA,CAAC,SAAS,WAAW,KAAK,KAAK,MAAM,KAAK,QAAQ,KAAK,KAAK;AAAA,EAC9D;AACA,SAAO;AAAA,IACL;AAAA,IACA,EAAE,aAAa,mBAAmB,aAAa,EAAE,MAAM,EAAE,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE,EAAE;AAAA,IACzF,CAAC,SAAS,WAAW,MAAM,KAAK,MAAM,KAAK,OAAO;AAAA,EACpD;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM,EAAE,OAAO;AAAA,QACf,YAAY,EAAE,OAAO;AAAA,QACrB,YAAY,EAAE,OAAO;AAAA,QACrB,aAAa,EAAE,QAAQ,EAAE,SAAS;AAAA,MACpC;AAAA,IACF;AAAA,IACA,CAAC,SAAS,WAAW,KAAK,KAAK,MAAM,KAAK,YAAY,KAAK,YAAY,KAAK,WAAW;AAAA,EACzF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE;AAAA,MAChC,aAAa,EAAE,cAAc,KAAK;AAAA,IACpC;AAAA,IACA,CAAC,SAAS,WAAW,GAAG,KAAK,IAAI;AAAA,EACnC;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,aAAa,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE;AAAA,MACrD,aAAa,EAAE,cAAc,KAAK;AAAA,IACpC;AAAA,IACA,CAAC,SAAS,WAAW,KAAK,KAAK,SAAS,KAAK,IAAI;AAAA,EACnD;AAEA,SAAO;AACT;AAEA,eAAsB,eACpB,WACA,UAAkC,CAAC,GACf;AACpB,QAAM,SAAS,sBAAsB,WAAW,OAAO;AACvD,QAAM,OAAO,QAAQ,IAAI,qBAAqB,CAAC;AAC/C,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../src/mcp/server.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 { VERSION } from '@struktoai/mirage-core/version'\nimport type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { z } from 'zod'\nimport {\n EDIT_DESCRIPTION,\n EXECUTE_DESCRIPTION,\n GREP_DESCRIPTION,\n LS_DESCRIPTION,\n READ_DESCRIPTION,\n WRITE_DESCRIPTION,\n} from '../tool-descriptions.ts'\nimport { MirageToolOperations, type MirageToolOperationsOptions } from '../tool-operations.ts'\n\nexport interface MirageMcpServerOptions extends MirageToolOperationsOptions {\n name?: string\n version?: string\n}\n\nexport function createMirageMcpServer(\n workspace: Workspace,\n options: MirageMcpServerOptions = {},\n): McpServer {\n const operations = new MirageToolOperations(workspace, options)\n const server = new McpServer({\n name: options.name ?? 'mirage',\n version: options.version ?? VERSION,\n })\n\n server.registerTool(\n 'execute_command',\n { description: EXECUTE_DESCRIPTION, inputSchema: { command: z.string() } },\n (args) => operations.execute(args.command),\n )\n server.registerTool(\n 'read',\n {\n description: READ_DESCRIPTION,\n inputSchema: {\n path: z.string(),\n offset: z.number().int().min(0).optional(),\n limit: z.number().int().min(1).optional(),\n },\n annotations: { readOnlyHint: true },\n },\n (args) => operations.read(args.path, args.offset, args.limit),\n )\n server.registerTool(\n 'write',\n { description: WRITE_DESCRIPTION, inputSchema: { path: z.string(), content: z.string() } },\n (args) => operations.write(args.path, args.content),\n )\n server.registerTool(\n 'edit',\n {\n description: EDIT_DESCRIPTION,\n inputSchema: {\n path: z.string(),\n old_string: z.string(),\n new_string: z.string(),\n replace_all: z.boolean().optional(),\n },\n },\n (args) => operations.edit(args.path, args.old_string, args.new_string, args.replace_all),\n )\n server.registerTool(\n 'ls',\n {\n description: LS_DESCRIPTION,\n inputSchema: { path: z.string() },\n annotations: { readOnlyHint: true },\n },\n (args) => operations.ls(args.path),\n )\n server.registerTool(\n 'grep',\n {\n description: GREP_DESCRIPTION,\n inputSchema: { pattern: z.string(), path: z.string() },\n annotations: { readOnlyHint: true },\n },\n (args) => operations.grep(args.pattern, args.path),\n )\n\n return server\n}\n\nexport async function serveMirageMcp(\n workspace: Workspace,\n options: MirageMcpServerOptions = {},\n): Promise<McpServer> {\n const server = createMirageMcpServer(workspace, options)\n await server.connect(new StdioServerTransport())\n return server\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAcA,SAAS,eAAe;AAExB,SAAS,iBAAiB;AAC1B,SAAS,4BAA4B;AACrC,SAAS,SAAS;AAgBX,SAAS,sBACd,WACA,UAAkC,CAAC,GACxB;AACX,QAAM,aAAa,IAAI,qBAAqB,WAAW,OAAO;AAC9D,QAAM,SAAS,IAAI,UAAU;AAAA,IAC3B,MAAM,QAAQ,QAAQ;AAAA,IACtB,SAAS,QAAQ,WAAW;AAAA,EAC9B,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,EAAE,aAAa,qBAAqB,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE;AAAA,IACzE,CAAC,SAAS,WAAW,QAAQ,KAAK,OAAO;AAAA,EAC3C;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM,EAAE,OAAO;AAAA,QACf,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,QACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,MAC1C;AAAA,MACA,aAAa,EAAE,cAAc,KAAK;AAAA,IACpC;AAAA,IACA,CAAC,SAAS,WAAW,KAAK,KAAK,MAAM,KAAK,QAAQ,KAAK,KAAK;AAAA,EAC9D;AACA,SAAO;AAAA,IACL;AAAA,IACA,EAAE,aAAa,mBAAmB,aAAa,EAAE,MAAM,EAAE,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE,EAAE;AAAA,IACzF,CAAC,SAAS,WAAW,MAAM,KAAK,MAAM,KAAK,OAAO;AAAA,EACpD;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM,EAAE,OAAO;AAAA,QACf,YAAY,EAAE,OAAO;AAAA,QACrB,YAAY,EAAE,OAAO;AAAA,QACrB,aAAa,EAAE,QAAQ,EAAE,SAAS;AAAA,MACpC;AAAA,IACF;AAAA,IACA,CAAC,SAAS,WAAW,KAAK,KAAK,MAAM,KAAK,YAAY,KAAK,YAAY,KAAK,WAAW;AAAA,EACzF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE;AAAA,MAChC,aAAa,EAAE,cAAc,KAAK;AAAA,IACpC;AAAA,IACA,CAAC,SAAS,WAAW,GAAG,KAAK,IAAI;AAAA,EACnC;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,aAAa,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE;AAAA,MACrD,aAAa,EAAE,cAAc,KAAK;AAAA,IACpC;AAAA,IACA,CAAC,SAAS,WAAW,KAAK,KAAK,SAAS,KAAK,IAAI;AAAA,EACnD;AAEA,SAAO;AACT;AAEA,eAAsB,eACpB,WACA,UAAkC,CAAC,GACf;AACpB,QAAM,SAAS,sBAAsB,WAAW,OAAO;AACvD,QAAM,OAAO,QAAQ,IAAI,qBAAqB,CAAC;AAC/C,SAAO;AACT;","names":[]}
@@ -1,8 +1,8 @@
1
- import { Workspace } from '@struktoai/mirage-core';
1
+ import { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace';
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-B_6pxgjj.js';
5
+ export { B as BuildSystemPromptOptions, M as MIRAGE_SYSTEM_PROMPT, b as buildSystemPrompt } from '../prompt-CgKmMkVe.js';
6
6
 
7
7
  declare class MirageEditor implements Editor {
8
8
  private readonly ws;
@@ -1,14 +1,17 @@
1
- import {
2
- readWorkspaceFile
3
- } from "../chunk-IMI7BLEG.js";
4
1
  import {
5
2
  MIRAGE_SYSTEM_PROMPT,
6
3
  buildSystemPrompt
7
- } from "../chunk-ZPXFVDYT.js";
4
+ } from "../chunk-S6DWWJVF.js";
5
+ import {
6
+ withRefusal
7
+ } from "../chunk-3N5GLSL7.js";
8
+ import {
9
+ readWorkspaceFile
10
+ } from "../chunk-DIUKTEAK.js";
8
11
 
9
12
  // src/openai/editor.ts
13
+ import { gnuDirname } from "@struktoai/mirage-core/utils/path";
10
14
  import { applyDiff } from "@openai/agents";
11
- import { gnuDirname } from "@struktoai/mirage-core";
12
15
  async function ensureParent(ws, path) {
13
16
  const parent = gnuDirname(path);
14
17
  if (parent === "/" || parent === "" || parent === ".") return;
@@ -54,18 +57,24 @@ var MirageEditor = class {
54
57
  // src/openai/execute.ts
55
58
  import { tool } from "@openai/agents";
56
59
  import { z } from "zod";
57
- function formatExecuteOutput(stdout, stderr, exitCode) {
60
+ function formatExecuteOutput(stdout, stderr, exitCode, refusal) {
58
61
  const sections = [`exit code: ${String(exitCode)}`];
59
62
  if (stdout !== "") sections.push(`stdout:
60
63
  ${stdout}`);
61
- if (stderr !== "") sections.push(`stderr:
62
- ${stderr}`);
64
+ const err = withRefusal(stderr, refusal);
65
+ if (err !== "") sections.push(`stderr:
66
+ ${err}`);
63
67
  return sections.join("\n");
64
68
  }
65
69
  async function executeOutput(ws, command) {
66
70
  try {
67
71
  const result = await ws.execute(command);
68
- return formatExecuteOutput(result.stdoutText, result.stderrText, result.exitCode);
72
+ return formatExecuteOutput(
73
+ result.stdoutText,
74
+ result.stderrText,
75
+ result.exitCode,
76
+ result.refusal
77
+ );
69
78
  } catch (error) {
70
79
  const message = error instanceof Error ? error.message : String(error);
71
80
  return `Unable to execute command: ${message}`;
@@ -138,7 +147,7 @@ var MirageShell = class {
138
147
  const io = await this.ws.execute(cmd);
139
148
  output.push({
140
149
  stdout: io.stdoutText,
141
- stderr: io.stderrText,
150
+ stderr: withRefusal(io.stderrText, io.refusal),
142
151
  outcome: { type: "exit", exitCode: io.exitCode }
143
152
  });
144
153
  }