@struktoai/mirage-agents 0.0.1-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 +230 -0
- package/dist/chunk-KAHWIK63.js +38 -0
- package/dist/chunk-KAHWIK63.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/dist/langchain/index.d.ts +30 -0
- package/dist/langchain/index.js +306 -0
- package/dist/langchain/index.js.map +1 -0
- package/dist/mastra/index.d.ts +45 -0
- package/dist/mastra/index.js +146 -0
- package/dist/mastra/index.js.map +1 -0
- package/dist/openai/index.d.ts +25 -0
- package/dist/openai/index.js +81 -0
- package/dist/openai/index.js.map +1 -0
- package/dist/pi/index.d.ts +21 -0
- package/dist/pi/index.js +142 -0
- package/dist/pi/index.js.map +1 -0
- package/dist/prompt-CbBVJuUY.d.ts +11 -0
- package/dist/vercel/index.d.ts +70 -0
- package/dist/vercel/index.js +235 -0
- package/dist/vercel/index.js.map +1 -0
- package/package.json +97 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as _mastra_core_tools from '@mastra/core/tools';
|
|
2
|
+
import { Workspace } from '@struktoai/mirage-core';
|
|
3
|
+
|
|
4
|
+
declare function mirageTools(ws: Workspace): {
|
|
5
|
+
execute: _mastra_core_tools.Tool<{
|
|
6
|
+
command: string;
|
|
7
|
+
}, {
|
|
8
|
+
stdout: string;
|
|
9
|
+
stderr: string;
|
|
10
|
+
exitCode: number;
|
|
11
|
+
}, unknown, unknown, _mastra_core_tools.ToolExecutionContext<unknown, unknown, unknown>, "mirage-execute", unknown>;
|
|
12
|
+
readFile: _mastra_core_tools.Tool<{
|
|
13
|
+
path: string;
|
|
14
|
+
}, {
|
|
15
|
+
content?: string | undefined;
|
|
16
|
+
error?: string | undefined;
|
|
17
|
+
}, unknown, unknown, _mastra_core_tools.ToolExecutionContext<unknown, unknown, unknown>, "mirage-read-file", unknown>;
|
|
18
|
+
writeFile: _mastra_core_tools.Tool<{
|
|
19
|
+
path: string;
|
|
20
|
+
content: string;
|
|
21
|
+
}, {
|
|
22
|
+
path: string;
|
|
23
|
+
}, unknown, unknown, _mastra_core_tools.ToolExecutionContext<unknown, unknown, unknown>, "mirage-write-file", unknown>;
|
|
24
|
+
editFile: _mastra_core_tools.Tool<{
|
|
25
|
+
path: string;
|
|
26
|
+
oldString: string;
|
|
27
|
+
newString: string;
|
|
28
|
+
replaceAll?: boolean | undefined;
|
|
29
|
+
}, {
|
|
30
|
+
path?: string | undefined;
|
|
31
|
+
occurrences?: number | undefined;
|
|
32
|
+
error?: string | undefined;
|
|
33
|
+
}, unknown, unknown, _mastra_core_tools.ToolExecutionContext<unknown, unknown, unknown>, "mirage-edit-file", unknown>;
|
|
34
|
+
ls: _mastra_core_tools.Tool<{
|
|
35
|
+
path: string;
|
|
36
|
+
}, {
|
|
37
|
+
files?: {
|
|
38
|
+
path: string;
|
|
39
|
+
is_dir: boolean;
|
|
40
|
+
}[] | undefined;
|
|
41
|
+
error?: string | undefined;
|
|
42
|
+
}, unknown, unknown, _mastra_core_tools.ToolExecutionContext<unknown, unknown, unknown>, "mirage-ls", unknown>;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export { mirageTools };
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// src/mastra/index.ts
|
|
2
|
+
import { createTool } from "@mastra/core/tools";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
function parentOf(path) {
|
|
5
|
+
const trimmed = path.replace(/\/+$/, "");
|
|
6
|
+
const idx = trimmed.lastIndexOf("/");
|
|
7
|
+
if (idx <= 0) return "/";
|
|
8
|
+
return trimmed.slice(0, idx);
|
|
9
|
+
}
|
|
10
|
+
async function ensureParent(ws, path) {
|
|
11
|
+
const parent = parentOf(path);
|
|
12
|
+
if (parent === "/" || parent === "") return;
|
|
13
|
+
if (await ws.fs.exists(parent)) return;
|
|
14
|
+
await ensureParent(ws, parent);
|
|
15
|
+
try {
|
|
16
|
+
await ws.fs.mkdir(parent);
|
|
17
|
+
} catch (err) {
|
|
18
|
+
if (!await ws.fs.exists(parent)) throw err;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function mirageTools(ws) {
|
|
22
|
+
return {
|
|
23
|
+
execute: createTool({
|
|
24
|
+
id: "mirage-execute",
|
|
25
|
+
description: "Execute a shell command in the Mirage workspace and return stdout, stderr, and exitCode.",
|
|
26
|
+
inputSchema: z.object({
|
|
27
|
+
command: z.string().describe("The shell command to execute.")
|
|
28
|
+
}),
|
|
29
|
+
outputSchema: z.object({
|
|
30
|
+
stdout: z.string(),
|
|
31
|
+
stderr: z.string(),
|
|
32
|
+
exitCode: z.number()
|
|
33
|
+
}),
|
|
34
|
+
execute: async (inputData) => {
|
|
35
|
+
const { command } = inputData;
|
|
36
|
+
const io = await ws.execute(command);
|
|
37
|
+
return {
|
|
38
|
+
stdout: io.stdoutText,
|
|
39
|
+
stderr: io.stderrText,
|
|
40
|
+
exitCode: io.exitCode
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}),
|
|
44
|
+
readFile: createTool({
|
|
45
|
+
id: "mirage-read-file",
|
|
46
|
+
description: "Read the contents of a file from the Mirage workspace as UTF-8 text.",
|
|
47
|
+
inputSchema: z.object({
|
|
48
|
+
path: z.string().describe("Absolute path inside the workspace.")
|
|
49
|
+
}),
|
|
50
|
+
outputSchema: z.object({
|
|
51
|
+
content: z.string().optional(),
|
|
52
|
+
error: z.string().optional()
|
|
53
|
+
}),
|
|
54
|
+
execute: async (inputData) => {
|
|
55
|
+
const { path } = inputData;
|
|
56
|
+
try {
|
|
57
|
+
const content = await ws.fs.readFileText(path);
|
|
58
|
+
return { content };
|
|
59
|
+
} catch (err) {
|
|
60
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}),
|
|
64
|
+
writeFile: createTool({
|
|
65
|
+
id: "mirage-write-file",
|
|
66
|
+
description: "Write content to a file in the Mirage workspace. Creates missing parent directories.",
|
|
67
|
+
inputSchema: z.object({
|
|
68
|
+
path: z.string().describe("Absolute path inside the workspace."),
|
|
69
|
+
content: z.string().describe("UTF-8 text content to write.")
|
|
70
|
+
}),
|
|
71
|
+
outputSchema: z.object({ path: z.string() }),
|
|
72
|
+
execute: async (inputData) => {
|
|
73
|
+
const { path, content } = inputData;
|
|
74
|
+
await ensureParent(ws, path);
|
|
75
|
+
await ws.fs.writeFile(path, content);
|
|
76
|
+
return { path };
|
|
77
|
+
}
|
|
78
|
+
}),
|
|
79
|
+
editFile: createTool({
|
|
80
|
+
id: "mirage-edit-file",
|
|
81
|
+
description: "Replace a string inside an existing file. Errors if the string appears more than once unless replaceAll is true.",
|
|
82
|
+
inputSchema: z.object({
|
|
83
|
+
path: z.string().describe("Absolute path of the file to edit."),
|
|
84
|
+
oldString: z.string().describe("The exact string to replace."),
|
|
85
|
+
newString: z.string().describe("The replacement string."),
|
|
86
|
+
replaceAll: z.boolean().optional().describe("Replace every occurrence rather than requiring a unique match.")
|
|
87
|
+
}),
|
|
88
|
+
outputSchema: z.object({
|
|
89
|
+
path: z.string().optional(),
|
|
90
|
+
occurrences: z.number().optional(),
|
|
91
|
+
error: z.string().optional()
|
|
92
|
+
}),
|
|
93
|
+
execute: async (inputData) => {
|
|
94
|
+
const { path, oldString, newString, replaceAll } = inputData;
|
|
95
|
+
let current;
|
|
96
|
+
try {
|
|
97
|
+
current = await ws.fs.readFileText(path);
|
|
98
|
+
} catch {
|
|
99
|
+
return { error: `Error: file '${path}' not found` };
|
|
100
|
+
}
|
|
101
|
+
const count = current.split(oldString).length - 1;
|
|
102
|
+
if (count === 0) {
|
|
103
|
+
return { error: `Error: string not found in file: '${oldString}'` };
|
|
104
|
+
}
|
|
105
|
+
if (count > 1 && replaceAll !== true) {
|
|
106
|
+
return {
|
|
107
|
+
error: `Error: string '${oldString}' appears ${String(count)} times. Use replaceAll=true`
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
const next = replaceAll === true ? current.split(oldString).join(newString) : current.replace(oldString, newString);
|
|
111
|
+
await ws.fs.writeFile(path, next);
|
|
112
|
+
return { path, occurrences: replaceAll === true ? count : 1 };
|
|
113
|
+
}
|
|
114
|
+
}),
|
|
115
|
+
ls: createTool({
|
|
116
|
+
id: "mirage-ls",
|
|
117
|
+
description: "List entries of a directory in the Mirage workspace.",
|
|
118
|
+
inputSchema: z.object({
|
|
119
|
+
path: z.string().describe("Absolute directory path inside the workspace.")
|
|
120
|
+
}),
|
|
121
|
+
outputSchema: z.object({
|
|
122
|
+
files: z.array(z.object({ path: z.string(), is_dir: z.boolean() })).optional(),
|
|
123
|
+
error: z.string().optional()
|
|
124
|
+
}),
|
|
125
|
+
execute: async (inputData) => {
|
|
126
|
+
const { path } = inputData;
|
|
127
|
+
let entries;
|
|
128
|
+
try {
|
|
129
|
+
entries = await ws.fs.readdir(path);
|
|
130
|
+
} catch (err) {
|
|
131
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
132
|
+
}
|
|
133
|
+
const files = [];
|
|
134
|
+
for (const entry of entries) {
|
|
135
|
+
const isDir = await ws.fs.isDir(entry);
|
|
136
|
+
files.push({ path: entry, is_dir: isDir });
|
|
137
|
+
}
|
|
138
|
+
return { files };
|
|
139
|
+
}
|
|
140
|
+
})
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
export {
|
|
144
|
+
mirageTools
|
|
145
|
+
};
|
|
146
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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'\n\nfunction parentOf(path: string): string {\n const trimmed = path.replace(/\\/+$/, '')\n const idx = trimmed.lastIndexOf('/')\n if (idx <= 0) return '/'\n return trimmed.slice(0, idx)\n}\n\nasync function ensureParent(ws: Workspace, path: string): Promise<void> {\n const parent = parentOf(path)\n if (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;AAElB,SAAS,SAAS,MAAsB;AACtC,QAAM,UAAU,KAAK,QAAQ,QAAQ,EAAE;AACvC,QAAM,MAAM,QAAQ,YAAY,GAAG;AACnC,MAAI,OAAO,EAAG,QAAO;AACrB,SAAO,QAAQ,MAAM,GAAG,GAAG;AAC7B;AAEA,eAAe,aAAa,IAAe,MAA6B;AACtE,QAAM,SAAS,SAAS,IAAI;AAC5B,MAAI,WAAW,OAAO,WAAW,GAAI;AACrC,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":[]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Workspace } from '@struktoai/mirage-core';
|
|
2
|
+
import { Editor, ApplyPatchOperation, ApplyPatchResult, Shell, ShellAction, ShellResult } from '@openai/agents';
|
|
3
|
+
export { B as BuildSystemPromptOptions, M as MIRAGE_SYSTEM_PROMPT, b as buildSystemPrompt } from '../prompt-CbBVJuUY.js';
|
|
4
|
+
|
|
5
|
+
declare class MirageEditor implements Editor {
|
|
6
|
+
private readonly ws;
|
|
7
|
+
constructor(ws: Workspace);
|
|
8
|
+
createFile(op: Extract<ApplyPatchOperation, {
|
|
9
|
+
type: 'create_file';
|
|
10
|
+
}>): Promise<ApplyPatchResult>;
|
|
11
|
+
updateFile(op: Extract<ApplyPatchOperation, {
|
|
12
|
+
type: 'update_file';
|
|
13
|
+
}>): Promise<ApplyPatchResult>;
|
|
14
|
+
deleteFile(op: Extract<ApplyPatchOperation, {
|
|
15
|
+
type: 'delete_file';
|
|
16
|
+
}>): Promise<ApplyPatchResult>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
declare class MirageShell implements Shell {
|
|
20
|
+
private readonly ws;
|
|
21
|
+
constructor(ws: Workspace);
|
|
22
|
+
run(action: ShellAction): Promise<ShellResult>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { MirageEditor, MirageShell };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MIRAGE_SYSTEM_PROMPT,
|
|
3
|
+
buildSystemPrompt
|
|
4
|
+
} from "../chunk-KAHWIK63.js";
|
|
5
|
+
|
|
6
|
+
// src/openai/editor.ts
|
|
7
|
+
import { applyDiff } from "@openai/agents";
|
|
8
|
+
function parentOf(path) {
|
|
9
|
+
const trimmed = path.replace(/\/+$/, "");
|
|
10
|
+
const idx = trimmed.lastIndexOf("/");
|
|
11
|
+
if (idx <= 0) return "/";
|
|
12
|
+
return trimmed.slice(0, idx);
|
|
13
|
+
}
|
|
14
|
+
async function ensureParent(ws, path) {
|
|
15
|
+
const parent = parentOf(path);
|
|
16
|
+
if (parent === "/" || parent === "") return;
|
|
17
|
+
if (await ws.fs.exists(parent)) return;
|
|
18
|
+
await ensureParent(ws, parent);
|
|
19
|
+
try {
|
|
20
|
+
await ws.fs.mkdir(parent);
|
|
21
|
+
} catch (err) {
|
|
22
|
+
if (!await ws.fs.exists(parent)) throw err;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
var MirageEditor = class {
|
|
26
|
+
constructor(ws) {
|
|
27
|
+
this.ws = ws;
|
|
28
|
+
}
|
|
29
|
+
ws;
|
|
30
|
+
async createFile(op) {
|
|
31
|
+
await ensureParent(this.ws, op.path);
|
|
32
|
+
const content = applyDiff("", op.diff, "create");
|
|
33
|
+
await this.ws.fs.writeFile(op.path, content);
|
|
34
|
+
return { status: "completed" };
|
|
35
|
+
}
|
|
36
|
+
async updateFile(op) {
|
|
37
|
+
let current;
|
|
38
|
+
try {
|
|
39
|
+
current = await this.ws.fs.readFileText(op.path);
|
|
40
|
+
} catch {
|
|
41
|
+
return { status: "failed", output: `File not found: ${op.path}` };
|
|
42
|
+
}
|
|
43
|
+
const next = applyDiff(current, op.diff);
|
|
44
|
+
await this.ws.fs.writeFile(op.path, next);
|
|
45
|
+
return { status: "completed" };
|
|
46
|
+
}
|
|
47
|
+
async deleteFile(op) {
|
|
48
|
+
if (!await this.ws.fs.exists(op.path)) {
|
|
49
|
+
return { status: "failed", output: `File not found: ${op.path}` };
|
|
50
|
+
}
|
|
51
|
+
await this.ws.fs.unlink(op.path);
|
|
52
|
+
return { status: "completed" };
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// src/openai/shell.ts
|
|
57
|
+
var MirageShell = class {
|
|
58
|
+
constructor(ws) {
|
|
59
|
+
this.ws = ws;
|
|
60
|
+
}
|
|
61
|
+
ws;
|
|
62
|
+
async run(action) {
|
|
63
|
+
const output = [];
|
|
64
|
+
for (const cmd of action.commands) {
|
|
65
|
+
const io = await this.ws.execute(cmd);
|
|
66
|
+
output.push({
|
|
67
|
+
stdout: io.stdoutText,
|
|
68
|
+
stderr: io.stderrText,
|
|
69
|
+
outcome: { type: "exit", exitCode: io.exitCode }
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return { output };
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
export {
|
|
76
|
+
MIRAGE_SYSTEM_PROMPT,
|
|
77
|
+
MirageEditor,
|
|
78
|
+
MirageShell,
|
|
79
|
+
buildSystemPrompt
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/openai/editor.ts","../../src/openai/shell.ts"],"sourcesContent":["// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Workspace } from '@struktoai/mirage-core'\nimport { applyDiff } from '@openai/agents'\nimport type { ApplyPatchOperation, ApplyPatchResult, Editor } from '@openai/agents'\n\nfunction parentOf(path: string): string {\n const trimmed = path.replace(/\\/+$/, '')\n const idx = trimmed.lastIndexOf('/')\n if (idx <= 0) return '/'\n return trimmed.slice(0, idx)\n}\n\nasync function ensureParent(ws: Workspace, path: string): Promise<void> {\n const parent = parentOf(path)\n if (parent === '/' || parent === '') return\n if (await ws.fs.exists(parent)) return\n await ensureParent(ws, parent)\n try {\n await ws.fs.mkdir(parent)\n } catch (err) {\n // Tolerate mkdir race: another caller may have created the dir between exists() and mkdir().\n if (!(await ws.fs.exists(parent))) throw err\n }\n}\n\nexport class MirageEditor implements Editor {\n constructor(private readonly ws: Workspace) {}\n\n async createFile(\n op: Extract<ApplyPatchOperation, { type: 'create_file' }>,\n ): Promise<ApplyPatchResult> {\n await ensureParent(this.ws, op.path)\n const content = applyDiff('', op.diff, 'create')\n await this.ws.fs.writeFile(op.path, content)\n return { status: 'completed' }\n }\n\n async updateFile(\n op: Extract<ApplyPatchOperation, { type: 'update_file' }>,\n ): Promise<ApplyPatchResult> {\n let current: string\n try {\n current = await this.ws.fs.readFileText(op.path)\n } catch {\n return { status: 'failed', output: `File not found: ${op.path}` }\n }\n const next = applyDiff(current, op.diff)\n await this.ws.fs.writeFile(op.path, next)\n return { status: 'completed' }\n }\n\n async deleteFile(\n op: Extract<ApplyPatchOperation, { type: 'delete_file' }>,\n ): Promise<ApplyPatchResult> {\n if (!(await this.ws.fs.exists(op.path))) {\n return { status: 'failed', output: `File not found: ${op.path}` }\n }\n await this.ws.fs.unlink(op.path)\n return { status: 'completed' }\n }\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Workspace } from '@struktoai/mirage-core'\nimport type { Shell, ShellAction, ShellResult, ShellOutputResult } from '@openai/agents'\n\nexport class MirageShell implements Shell {\n constructor(private readonly ws: Workspace) {}\n\n async run(action: ShellAction): Promise<ShellResult> {\n const output: ShellOutputResult[] = []\n for (const cmd of action.commands) {\n const io = await this.ws.execute(cmd)\n output.push({\n stdout: io.stdoutText,\n stderr: io.stderrText,\n outcome: { type: 'exit', exitCode: io.exitCode },\n })\n }\n return { output }\n }\n}\n"],"mappings":";;;;;;AAeA,SAAS,iBAAiB;AAG1B,SAAS,SAAS,MAAsB;AACtC,QAAM,UAAU,KAAK,QAAQ,QAAQ,EAAE;AACvC,QAAM,MAAM,QAAQ,YAAY,GAAG;AACnC,MAAI,OAAO,EAAG,QAAO;AACrB,SAAO,QAAQ,MAAM,GAAG,GAAG;AAC7B;AAEA,eAAe,aAAa,IAAe,MAA6B;AACtE,QAAM,SAAS,SAAS,IAAI;AAC5B,MAAI,WAAW,OAAO,WAAW,GAAI;AACrC,MAAI,MAAM,GAAG,GAAG,OAAO,MAAM,EAAG;AAChC,QAAM,aAAa,IAAI,MAAM;AAC7B,MAAI;AACF,UAAM,GAAG,GAAG,MAAM,MAAM;AAAA,EAC1B,SAAS,KAAK;AAEZ,QAAI,CAAE,MAAM,GAAG,GAAG,OAAO,MAAM,EAAI,OAAM;AAAA,EAC3C;AACF;AAEO,IAAM,eAAN,MAAqC;AAAA,EAC1C,YAA6B,IAAe;AAAf;AAAA,EAAgB;AAAA,EAAhB;AAAA,EAE7B,MAAM,WACJ,IAC2B;AAC3B,UAAM,aAAa,KAAK,IAAI,GAAG,IAAI;AACnC,UAAM,UAAU,UAAU,IAAI,GAAG,MAAM,QAAQ;AAC/C,UAAM,KAAK,GAAG,GAAG,UAAU,GAAG,MAAM,OAAO;AAC3C,WAAO,EAAE,QAAQ,YAAY;AAAA,EAC/B;AAAA,EAEA,MAAM,WACJ,IAC2B;AAC3B,QAAI;AACJ,QAAI;AACF,gBAAU,MAAM,KAAK,GAAG,GAAG,aAAa,GAAG,IAAI;AAAA,IACjD,QAAQ;AACN,aAAO,EAAE,QAAQ,UAAU,QAAQ,mBAAmB,GAAG,IAAI,GAAG;AAAA,IAClE;AACA,UAAM,OAAO,UAAU,SAAS,GAAG,IAAI;AACvC,UAAM,KAAK,GAAG,GAAG,UAAU,GAAG,MAAM,IAAI;AACxC,WAAO,EAAE,QAAQ,YAAY;AAAA,EAC/B;AAAA,EAEA,MAAM,WACJ,IAC2B;AAC3B,QAAI,CAAE,MAAM,KAAK,GAAG,GAAG,OAAO,GAAG,IAAI,GAAI;AACvC,aAAO,EAAE,QAAQ,UAAU,QAAQ,mBAAmB,GAAG,IAAI,GAAG;AAAA,IAClE;AACA,UAAM,KAAK,GAAG,GAAG,OAAO,GAAG,IAAI;AAC/B,WAAO,EAAE,QAAQ,YAAY;AAAA,EAC/B;AACF;;;ACxDO,IAAM,cAAN,MAAmC;AAAA,EACxC,YAA6B,IAAe;AAAf;AAAA,EAAgB;AAAA,EAAhB;AAAA,EAE7B,MAAM,IAAI,QAA2C;AACnD,UAAM,SAA8B,CAAC;AACrC,eAAW,OAAO,OAAO,UAAU;AACjC,YAAM,KAAK,MAAM,KAAK,GAAG,QAAQ,GAAG;AACpC,aAAO,KAAK;AAAA,QACV,QAAQ,GAAG;AAAA,QACX,QAAQ,GAAG;AAAA,QACX,SAAS,EAAE,MAAM,QAAQ,UAAU,GAAG,SAAS;AAAA,MACjD,CAAC;AAAA,IACH;AACA,WAAO,EAAE,OAAO;AAAA,EAClB;AACF;","names":[]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Workspace } from '@struktoai/mirage-core';
|
|
2
|
+
import { ExtensionFactory, ReadOperations, WriteOperations, EditOperations, BashOperations, GrepOperations, FindOperations, LsOperations } from '@mariozechner/pi-coding-agent';
|
|
3
|
+
export { B as BuildSystemPromptOptions, M as MIRAGE_SYSTEM_PROMPT, b as buildSystemPrompt } from '../prompt-CbBVJuUY.js';
|
|
4
|
+
|
|
5
|
+
interface MirageExtensionOptions {
|
|
6
|
+
cwd?: string;
|
|
7
|
+
}
|
|
8
|
+
declare function mirageExtension(ws: Workspace, opts?: MirageExtensionOptions): ExtensionFactory;
|
|
9
|
+
|
|
10
|
+
interface MirageOperationsBundle {
|
|
11
|
+
read: ReadOperations;
|
|
12
|
+
write: WriteOperations;
|
|
13
|
+
edit: EditOperations;
|
|
14
|
+
bash: BashOperations;
|
|
15
|
+
grep: GrepOperations;
|
|
16
|
+
find: FindOperations;
|
|
17
|
+
ls: LsOperations;
|
|
18
|
+
}
|
|
19
|
+
declare function mirageOperations(ws: Workspace): MirageOperationsBundle;
|
|
20
|
+
|
|
21
|
+
export { type MirageExtensionOptions, type MirageOperationsBundle, mirageExtension, mirageOperations };
|
package/dist/pi/index.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MIRAGE_SYSTEM_PROMPT,
|
|
3
|
+
buildSystemPrompt
|
|
4
|
+
} from "../chunk-KAHWIK63.js";
|
|
5
|
+
|
|
6
|
+
// src/pi/extension.ts
|
|
7
|
+
import {
|
|
8
|
+
createBashToolDefinition,
|
|
9
|
+
createEditToolDefinition,
|
|
10
|
+
createFindToolDefinition,
|
|
11
|
+
createGrepToolDefinition,
|
|
12
|
+
createLsToolDefinition,
|
|
13
|
+
createReadToolDefinition,
|
|
14
|
+
createWriteToolDefinition
|
|
15
|
+
} from "@mariozechner/pi-coding-agent";
|
|
16
|
+
|
|
17
|
+
// src/pi/operations.ts
|
|
18
|
+
import picomatch from "picomatch";
|
|
19
|
+
async function ensureParent(ws, dir) {
|
|
20
|
+
const norm = dir.replace(/\/+$/, "") || "/";
|
|
21
|
+
if (norm === "/" || await ws.fs.exists(norm)) return;
|
|
22
|
+
const parent = norm.substring(0, norm.lastIndexOf("/")) || "/";
|
|
23
|
+
await ensureParent(ws, parent);
|
|
24
|
+
try {
|
|
25
|
+
await ws.fs.mkdir(norm);
|
|
26
|
+
} catch (err) {
|
|
27
|
+
if (await ws.fs.isDir(norm)) return;
|
|
28
|
+
throw err;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async function walkDirectory(ws, dir, cwdPrefix, matcher, opts, results) {
|
|
32
|
+
if (results.length >= opts.limit) return;
|
|
33
|
+
let entries;
|
|
34
|
+
try {
|
|
35
|
+
entries = await ws.fs.readdir(dir);
|
|
36
|
+
} catch {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
for (const full of entries) {
|
|
40
|
+
if (results.length >= opts.limit) return;
|
|
41
|
+
const rel = full.startsWith(cwdPrefix) ? full.slice(cwdPrefix.length) : full;
|
|
42
|
+
if (opts.ignoreMatchers.some((m) => m(rel))) continue;
|
|
43
|
+
const isDir = await ws.fs.isDir(full);
|
|
44
|
+
if (matcher(rel)) results.push(full);
|
|
45
|
+
if (isDir) await walkDirectory(ws, full, cwdPrefix, matcher, opts, results);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function mirageOperations(ws) {
|
|
49
|
+
const read = {
|
|
50
|
+
readFile: async (absolutePath) => {
|
|
51
|
+
const bytes = await ws.fs.readFile(absolutePath, { raw: true });
|
|
52
|
+
return Buffer.from(bytes);
|
|
53
|
+
},
|
|
54
|
+
access: async (absolutePath) => {
|
|
55
|
+
await ws.fs.stat(absolutePath);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const write = {
|
|
59
|
+
writeFile: async (absolutePath, content) => {
|
|
60
|
+
await ws.fs.writeFile(absolutePath, content);
|
|
61
|
+
},
|
|
62
|
+
mkdir: async (dir) => {
|
|
63
|
+
await ensureParent(ws, dir);
|
|
64
|
+
if (!await ws.fs.exists(dir)) {
|
|
65
|
+
await ws.fs.mkdir(dir);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const edit = {
|
|
70
|
+
readFile: read.readFile,
|
|
71
|
+
writeFile: write.writeFile,
|
|
72
|
+
access: read.access
|
|
73
|
+
};
|
|
74
|
+
const bash = {
|
|
75
|
+
exec: async (command, _cwd, options) => {
|
|
76
|
+
const result = await ws.execute(command);
|
|
77
|
+
const combined = result.stdoutText + result.stderrText;
|
|
78
|
+
if (combined.length > 0) {
|
|
79
|
+
options.onData(Buffer.from(combined));
|
|
80
|
+
}
|
|
81
|
+
return { exitCode: result.exitCode };
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const grep = {
|
|
85
|
+
isDirectory: async (absolutePath) => ws.fs.isDir(absolutePath),
|
|
86
|
+
readFile: async (absolutePath) => ws.fs.readFileText(absolutePath)
|
|
87
|
+
};
|
|
88
|
+
const find = {
|
|
89
|
+
exists: async (absolutePath) => ws.fs.exists(absolutePath),
|
|
90
|
+
glob: async (pattern, cwd, options) => {
|
|
91
|
+
const matcher = picomatch(pattern, { dot: false });
|
|
92
|
+
const ignoreMatchers = options.ignore.map((p) => picomatch(p, { dot: false }));
|
|
93
|
+
const root = cwd.replace(/\/+$/, "") || "/";
|
|
94
|
+
const cwdPrefix = root === "/" ? "/" : `${root}/`;
|
|
95
|
+
const results = [];
|
|
96
|
+
await walkDirectory(
|
|
97
|
+
ws,
|
|
98
|
+
root,
|
|
99
|
+
cwdPrefix,
|
|
100
|
+
matcher,
|
|
101
|
+
{ ignoreMatchers, limit: options.limit },
|
|
102
|
+
results
|
|
103
|
+
);
|
|
104
|
+
return results;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const ls = {
|
|
108
|
+
exists: async (absolutePath) => ws.fs.exists(absolutePath),
|
|
109
|
+
stat: async (absolutePath) => {
|
|
110
|
+
const isDir = await ws.fs.isDir(absolutePath);
|
|
111
|
+
return { isDirectory: () => isDir };
|
|
112
|
+
},
|
|
113
|
+
readdir: async (absolutePath) => {
|
|
114
|
+
const entries = await ws.fs.readdir(absolutePath);
|
|
115
|
+
const prefix = absolutePath === "/" ? "/" : `${absolutePath.replace(/\/+$/, "")}/`;
|
|
116
|
+
return entries.map((e) => e.startsWith(prefix) ? e.slice(prefix.length) : e);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
return { read, write, edit, bash, grep, find, ls };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// src/pi/extension.ts
|
|
123
|
+
function mirageExtension(ws, opts = {}) {
|
|
124
|
+
const cwd = opts.cwd ?? "/";
|
|
125
|
+
const ops = mirageOperations(ws);
|
|
126
|
+
return (pi) => {
|
|
127
|
+
pi.registerTool(createReadToolDefinition(cwd, { operations: ops.read }));
|
|
128
|
+
pi.registerTool(createWriteToolDefinition(cwd, { operations: ops.write }));
|
|
129
|
+
pi.registerTool(createEditToolDefinition(cwd, { operations: ops.edit }));
|
|
130
|
+
pi.registerTool(createBashToolDefinition(cwd, { operations: ops.bash }));
|
|
131
|
+
pi.registerTool(createGrepToolDefinition(cwd, { operations: ops.grep }));
|
|
132
|
+
pi.registerTool(createFindToolDefinition(cwd, { operations: ops.find }));
|
|
133
|
+
pi.registerTool(createLsToolDefinition(cwd, { operations: ops.ls }));
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
export {
|
|
137
|
+
MIRAGE_SYSTEM_PROMPT,
|
|
138
|
+
buildSystemPrompt,
|
|
139
|
+
mirageExtension,
|
|
140
|
+
mirageOperations
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/pi/extension.ts","../../src/pi/operations.ts"],"sourcesContent":["// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Workspace } from '@struktoai/mirage-core'\nimport {\n createBashToolDefinition,\n createEditToolDefinition,\n createFindToolDefinition,\n createGrepToolDefinition,\n createLsToolDefinition,\n createReadToolDefinition,\n createWriteToolDefinition,\n type ExtensionFactory,\n} from '@mariozechner/pi-coding-agent'\nimport { mirageOperations } from './operations.ts'\n\nexport interface MirageExtensionOptions {\n cwd?: string\n}\n\nexport function mirageExtension(\n ws: Workspace,\n opts: MirageExtensionOptions = {},\n): ExtensionFactory {\n const cwd = opts.cwd ?? '/'\n const ops = mirageOperations(ws)\n return (pi) => {\n pi.registerTool(createReadToolDefinition(cwd, { operations: ops.read }))\n pi.registerTool(createWriteToolDefinition(cwd, { operations: ops.write }))\n pi.registerTool(createEditToolDefinition(cwd, { operations: ops.edit }))\n pi.registerTool(createBashToolDefinition(cwd, { operations: ops.bash }))\n pi.registerTool(createGrepToolDefinition(cwd, { operations: ops.grep }))\n pi.registerTool(createFindToolDefinition(cwd, { operations: ops.find }))\n pi.registerTool(createLsToolDefinition(cwd, { operations: ops.ls }))\n }\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 {\n BashOperations,\n EditOperations,\n FindOperations,\n GrepOperations,\n LsOperations,\n ReadOperations,\n WriteOperations,\n} from '@mariozechner/pi-coding-agent'\nimport picomatch from 'picomatch'\n\nexport interface MirageOperationsBundle {\n read: ReadOperations\n write: WriteOperations\n edit: EditOperations\n bash: BashOperations\n grep: GrepOperations\n find: FindOperations\n ls: LsOperations\n}\n\nasync function ensureParent(ws: Workspace, dir: string): Promise<void> {\n const norm = dir.replace(/\\/+$/, '') || '/'\n if (norm === '/' || (await ws.fs.exists(norm))) return\n const parent = norm.substring(0, norm.lastIndexOf('/')) || '/'\n await ensureParent(ws, parent)\n try {\n await ws.fs.mkdir(norm)\n } catch (err) {\n if (await ws.fs.isDir(norm)) return\n throw err\n }\n}\n\ninterface WalkOptions {\n ignoreMatchers: ((path: string) => boolean)[]\n limit: number\n}\n\nasync function walkDirectory(\n ws: Workspace,\n dir: string,\n cwdPrefix: string,\n matcher: (relativePath: string) => boolean,\n opts: WalkOptions,\n results: string[],\n): Promise<void> {\n if (results.length >= opts.limit) return\n let entries: string[]\n try {\n entries = await ws.fs.readdir(dir)\n } catch {\n return\n }\n for (const full of entries) {\n if (results.length >= opts.limit) return\n const rel = full.startsWith(cwdPrefix) ? full.slice(cwdPrefix.length) : full\n if (opts.ignoreMatchers.some((m) => m(rel))) continue\n const isDir = await ws.fs.isDir(full)\n if (matcher(rel)) results.push(full)\n if (isDir) await walkDirectory(ws, full, cwdPrefix, matcher, opts, results)\n }\n}\n\nexport function mirageOperations(ws: Workspace): MirageOperationsBundle {\n const read: ReadOperations = {\n readFile: async (absolutePath: string) => {\n const bytes = await ws.fs.readFile(absolutePath, { raw: true })\n return Buffer.from(bytes)\n },\n access: async (absolutePath: string) => {\n await ws.fs.stat(absolutePath)\n },\n }\n\n const write: WriteOperations = {\n writeFile: async (absolutePath: string, content: string) => {\n await ws.fs.writeFile(absolutePath, content)\n },\n mkdir: async (dir: string) => {\n await ensureParent(ws, dir)\n if (!(await ws.fs.exists(dir))) {\n await ws.fs.mkdir(dir)\n }\n },\n }\n\n const edit: EditOperations = {\n readFile: read.readFile,\n writeFile: write.writeFile,\n access: read.access,\n }\n\n const bash: BashOperations = {\n exec: async (command, _cwd, options) => {\n const result = await ws.execute(command)\n const combined = result.stdoutText + result.stderrText\n if (combined.length > 0) {\n options.onData(Buffer.from(combined))\n }\n return { exitCode: result.exitCode }\n },\n }\n\n const grep: GrepOperations = {\n isDirectory: async (absolutePath: string) => ws.fs.isDir(absolutePath),\n readFile: async (absolutePath: string) => ws.fs.readFileText(absolutePath),\n }\n\n const find: FindOperations = {\n exists: async (absolutePath: string) => ws.fs.exists(absolutePath),\n glob: async (pattern, cwd, options) => {\n const matcher = picomatch(pattern, { dot: false })\n const ignoreMatchers = options.ignore.map((p) => picomatch(p, { dot: false }))\n const root = cwd.replace(/\\/+$/, '') || '/'\n const cwdPrefix = root === '/' ? '/' : `${root}/`\n const results: string[] = []\n await walkDirectory(\n ws,\n root,\n cwdPrefix,\n matcher,\n { ignoreMatchers, limit: options.limit },\n results,\n )\n return results\n },\n }\n\n const ls: LsOperations = {\n exists: async (absolutePath: string) => ws.fs.exists(absolutePath),\n stat: async (absolutePath: string) => {\n const isDir = await ws.fs.isDir(absolutePath)\n return { isDirectory: () => isDir }\n },\n readdir: async (absolutePath: string) => {\n const entries = await ws.fs.readdir(absolutePath)\n const prefix = absolutePath === '/' ? '/' : `${absolutePath.replace(/\\/+$/, '')}/`\n return entries.map((e) => (e.startsWith(prefix) ? e.slice(prefix.length) : e))\n },\n }\n\n return { read, write, edit, bash, grep, find, ls }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -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\nAll file paths live under /mirage/. Do not access paths outside this folder.\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/seconds\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_file/write_file/edit_file 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 };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as ai from 'ai';
|
|
2
|
+
import { Workspace } from '@struktoai/mirage-node';
|
|
3
|
+
|
|
4
|
+
type ReadFileResult = {
|
|
5
|
+
kind: 'text';
|
|
6
|
+
path: string;
|
|
7
|
+
mimeType: string;
|
|
8
|
+
content: string;
|
|
9
|
+
bytes: number;
|
|
10
|
+
} | {
|
|
11
|
+
kind: 'media';
|
|
12
|
+
path: string;
|
|
13
|
+
mimeType: string;
|
|
14
|
+
base64: string;
|
|
15
|
+
bytes: number;
|
|
16
|
+
} | {
|
|
17
|
+
kind: 'binary';
|
|
18
|
+
path: string;
|
|
19
|
+
mimeType: string;
|
|
20
|
+
bytes: number;
|
|
21
|
+
note: string;
|
|
22
|
+
} | {
|
|
23
|
+
error: string;
|
|
24
|
+
};
|
|
25
|
+
declare function mirageTools(ws: Workspace): {
|
|
26
|
+
execute: ai.Tool<{
|
|
27
|
+
command: string;
|
|
28
|
+
}, {
|
|
29
|
+
stdout: string;
|
|
30
|
+
stderr: string;
|
|
31
|
+
exitCode: number;
|
|
32
|
+
}>;
|
|
33
|
+
readFile: ai.Tool<{
|
|
34
|
+
path: string;
|
|
35
|
+
}, ReadFileResult>;
|
|
36
|
+
writeFile: ai.Tool<{
|
|
37
|
+
path: string;
|
|
38
|
+
content: string;
|
|
39
|
+
}, {
|
|
40
|
+
path: string;
|
|
41
|
+
}>;
|
|
42
|
+
editFile: ai.Tool<{
|
|
43
|
+
path: string;
|
|
44
|
+
oldString: string;
|
|
45
|
+
newString: string;
|
|
46
|
+
replaceAll?: boolean | undefined;
|
|
47
|
+
}, {
|
|
48
|
+
error: string;
|
|
49
|
+
path?: never;
|
|
50
|
+
occurrences?: never;
|
|
51
|
+
} | {
|
|
52
|
+
path: string;
|
|
53
|
+
occurrences: number;
|
|
54
|
+
error?: never;
|
|
55
|
+
}>;
|
|
56
|
+
ls: ai.Tool<{
|
|
57
|
+
path: string;
|
|
58
|
+
}, {
|
|
59
|
+
error: string;
|
|
60
|
+
files?: never;
|
|
61
|
+
} | {
|
|
62
|
+
files: {
|
|
63
|
+
path: string;
|
|
64
|
+
is_dir: boolean;
|
|
65
|
+
}[];
|
|
66
|
+
error?: never;
|
|
67
|
+
}>;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export { mirageTools };
|