@themoltnet/pi-extension 0.1.0

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 (44) hide show
  1. package/LICENSE +235 -0
  2. package/README.md +122 -0
  3. package/dist/commands/index.d.ts +5 -0
  4. package/dist/commands/index.d.ts.map +1 -0
  5. package/dist/commands/index.js +4 -0
  6. package/dist/commands/index.js.map +1 -0
  7. package/dist/commands/moltnet-reflect.d.ts +3 -0
  8. package/dist/commands/moltnet-reflect.d.ts.map +1 -0
  9. package/dist/commands/moltnet-reflect.js +36 -0
  10. package/dist/commands/moltnet-reflect.js.map +1 -0
  11. package/dist/commands/resolve-issue.d.ts +3 -0
  12. package/dist/commands/resolve-issue.d.ts.map +1 -0
  13. package/dist/commands/resolve-issue.js +82 -0
  14. package/dist/commands/resolve-issue.js.map +1 -0
  15. package/dist/commands/sandbox.d.ts +3 -0
  16. package/dist/commands/sandbox.d.ts.map +1 -0
  17. package/dist/commands/sandbox.js +20 -0
  18. package/dist/commands/sandbox.js.map +1 -0
  19. package/dist/commands/types.d.ts +33 -0
  20. package/dist/commands/types.d.ts.map +1 -0
  21. package/dist/commands/types.js +2 -0
  22. package/dist/commands/types.js.map +1 -0
  23. package/dist/index.d.ts +9 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +392 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/moltnet-tools.d.ts +13 -0
  28. package/dist/moltnet-tools.d.ts.map +1 -0
  29. package/dist/moltnet-tools.js +126 -0
  30. package/dist/moltnet-tools.js.map +1 -0
  31. package/dist/snapshot.d.ts +41 -0
  32. package/dist/snapshot.d.ts.map +1 -0
  33. package/dist/snapshot.js +251 -0
  34. package/dist/snapshot.js.map +1 -0
  35. package/dist/tool-operations.d.ts +13 -0
  36. package/dist/tool-operations.d.ts.map +1 -0
  37. package/dist/tool-operations.js +142 -0
  38. package/dist/tool-operations.js.map +1 -0
  39. package/dist/tsconfig.tsbuildinfo +1 -0
  40. package/dist/vm-manager.d.ts +48 -0
  41. package/dist/vm-manager.d.ts.map +1 -0
  42. package/dist/vm-manager.js +222 -0
  43. package/dist/vm-manager.js.map +1 -0
  44. package/package.json +62 -0
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/commands/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import type { ExtensionAPI } from '@mariozechner/pi-coding-agent';
2
+ export default function moltnetExtension(pi: ExtensionAPI): void;
3
+ export { createMoltNetTools } from './moltnet-tools.js';
4
+ export type { EnsureSnapshotOptions, SandboxConfig, SnapshotConfig, } from './snapshot.js';
5
+ export { ensureSnapshot } from './snapshot.js';
6
+ export { createGondolinBashOps, createGondolinEditOps, createGondolinReadOps, createGondolinWriteOps, toGuestPath, } from './tool-operations.js';
7
+ export type { ManagedVm, VmConfig, VmCredentials } from './vm-manager.js';
8
+ export { activateAgentEnv, findMainWorktree, loadCredentials, resumeVm, } from './vm-manager.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EACV,YAAY,EAEb,MAAM,+BAA+B,CAAC;AA2BvC,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,EAAE,YAAY,QA+axD;AAGD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,YAAY,EACV,qBAAqB,EACrB,aAAa,EACb,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,QAAQ,GACT,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,392 @@
1
+ /**
2
+ * @themoltnet/pi-extension — MoltNet pi extension
3
+ *
4
+ * Sandboxes tool execution in a Gondolin VM with:
5
+ * - Auto-built and cached VM snapshots
6
+ * - Credential injection (pi OAuth + MoltNet identity)
7
+ * - Egress policy (only LLM provider + MoltNet API)
8
+ * - Tool redirection (read/write/edit/bash → VM)
9
+ * - MoltNet custom tools (diary entries — run on host via SDK)
10
+ * - Optional git worktree per session
11
+ *
12
+ * Usage:
13
+ * pi -e @themoltnet/pi-extension
14
+ * pi -e @themoltnet/pi-extension --agent legreffier
15
+ * pi -e @themoltnet/pi-extension --worktree-branch feat/my-task
16
+ * pi -e @themoltnet/pi-extension --sandbox-config ./sandbox.json
17
+ *
18
+ * Sandbox config resolution (first match):
19
+ * 1. --sandbox-config flag (explicit path to JSON)
20
+ * 2. sandbox.json in cwd (convention)
21
+ * 3. Base only (git, gh, moltnet CLI, agent user)
22
+ */
23
+ import { execFileSync } from 'node:child_process';
24
+ import { existsSync, readFileSync } from 'node:fs';
25
+ import path from 'node:path';
26
+ import { createBashTool, createEditTool, createReadTool, createWriteTool, } from '@mariozechner/pi-coding-agent';
27
+ import { connect } from '@themoltnet/sdk';
28
+ import { registerMoltnetReflectCommand, registerResolveIssueCommand, registerSandboxCommand, } from './commands/index.js';
29
+ import { createMoltNetTools } from './moltnet-tools.js';
30
+ import { ensureSnapshot } from './snapshot.js';
31
+ import { createGondolinBashOps, createGondolinEditOps, createGondolinReadOps, createGondolinWriteOps, } from './tool-operations.js';
32
+ import { activateAgentEnv, findMainWorktree, resumeVm } from './vm-manager.js';
33
+ const GUEST_WORKSPACE = '/workspace';
34
+ export default function moltnetExtension(pi) {
35
+ // -- Flags ------------------------------------------------------------------
36
+ pi.registerFlag('agent', {
37
+ description: 'MoltNet agent name (required — pass --agent <name>)',
38
+ type: 'string',
39
+ default: '',
40
+ });
41
+ pi.registerFlag('worktree-branch', {
42
+ description: 'Create a fresh git worktree for this session on the given branch',
43
+ type: 'string',
44
+ default: '',
45
+ });
46
+ pi.registerFlag('sandbox-config', {
47
+ description: 'Path to sandbox config JSON (overrides sandbox.json in cwd)',
48
+ type: 'string',
49
+ default: '',
50
+ });
51
+ // -- Sandbox config resolution ------------------------------------------------
52
+ function resolveSandboxConfig() {
53
+ const flagPath = pi.getFlag('sandbox-config');
54
+ if (flagPath) {
55
+ const abs = path.isAbsolute(flagPath)
56
+ ? flagPath
57
+ : path.join(process.cwd(), flagPath);
58
+ return JSON.parse(readFileSync(abs, 'utf8'));
59
+ }
60
+ const conventionPath = path.join(process.cwd(), 'sandbox.json');
61
+ if (existsSync(conventionPath)) {
62
+ return JSON.parse(readFileSync(conventionPath, 'utf8'));
63
+ }
64
+ return undefined;
65
+ }
66
+ // -- State ------------------------------------------------------------------
67
+ const localCwd = process.cwd();
68
+ const localRead = createReadTool(localCwd);
69
+ const localWrite = createWriteTool(localCwd);
70
+ const localEdit = createEditTool(localCwd);
71
+ const localBash = createBashTool(localCwd);
72
+ let vm = null;
73
+ let vmStarting = null;
74
+ let worktreePath = null;
75
+ let moltnetAgent = null;
76
+ let diaryId = null;
77
+ // -- VM bootstrap -----------------------------------------------------------
78
+ async function ensureVm(ctx) {
79
+ if (vm)
80
+ return vm;
81
+ if (vmStarting)
82
+ return vmStarting;
83
+ vmStarting = (async () => {
84
+ const agentName = pi.getFlag('agent');
85
+ if (!agentName) {
86
+ throw new Error('Missing --agent flag. Usage: pi -e @themoltnet/pi-extension --agent <name>');
87
+ }
88
+ const worktreeBranch = pi.getFlag('worktree-branch');
89
+ // 1. Ensure snapshot exists (auto-build on first run)
90
+ ctx?.ui.setStatus('sandbox', ctx.ui.theme.fg('accent', 'Sandbox: preparing...'));
91
+ const sandboxConfig = resolveSandboxConfig();
92
+ const checkpointPath = await ensureSnapshot({
93
+ config: sandboxConfig?.snapshot,
94
+ onProgress: (msg) => {
95
+ ctx?.ui.setStatus('sandbox', ctx.ui.theme.fg('accent', `Sandbox: ${msg}`));
96
+ },
97
+ });
98
+ // 2. Create worktree if requested
99
+ const mainRepo = findMainWorktree();
100
+ let mountPath = localCwd;
101
+ if (worktreeBranch) {
102
+ const repoName = path.basename(mainRepo);
103
+ const suffix = worktreeBranch.replace(/\//g, '-');
104
+ worktreePath = path.resolve(mainRepo, '..', `${repoName}-${suffix}`);
105
+ ctx?.ui.setStatus('sandbox', ctx.ui.theme.fg('accent', `Sandbox: creating worktree ${suffix}...`));
106
+ if (!existsSync(worktreePath)) {
107
+ execFileSync('git', ['worktree', 'add', '-b', worktreeBranch, worktreePath], { cwd: mainRepo, stdio: 'pipe' });
108
+ }
109
+ mountPath = worktreePath;
110
+ }
111
+ // 3. Resume VM from snapshot
112
+ ctx?.ui.setStatus('sandbox', ctx.ui.theme.fg('accent', 'Sandbox: starting...'));
113
+ const managed = await resumeVm({
114
+ checkpointPath,
115
+ agentName,
116
+ mountPath,
117
+ sandboxConfig,
118
+ });
119
+ // 4. Activate agent env on the host (mirrors `moltnet start`)
120
+ activateAgentEnv(managed.credentials.agentEnv, mainRepo);
121
+ // 5. Connect to MoltNet on the host side (for custom tools)
122
+ moltnetAgent = await connect({ configDir: managed.agentDir });
123
+ diaryId = managed.credentials.agentEnv.MOLTNET_DIARY_ID ?? null;
124
+ vm = managed.vm;
125
+ const label = worktreePath
126
+ ? `${mountPath} → ${GUEST_WORKSPACE}`
127
+ : `${localCwd} → ${GUEST_WORKSPACE}`;
128
+ ctx?.ui.setStatus('sandbox', ctx.ui.theme.fg('accent', `Sandbox: running (${label})`));
129
+ ctx?.ui.notify(`Sandbox ready. Agent: ${agentName}`, 'info');
130
+ return managed.vm;
131
+ })();
132
+ return vmStarting;
133
+ }
134
+ // -- Lifecycle hooks --------------------------------------------------------
135
+ pi.on('session_start', async (_event, ctx) => {
136
+ await ensureVm(ctx);
137
+ });
138
+ pi.on('session_shutdown', async (_event, ctx) => {
139
+ // Record session errors before losing the MoltNet connection
140
+ try {
141
+ await createErrorEntry(ctx, 'session shutdown');
142
+ }
143
+ catch {
144
+ // Best-effort — session is shutting down
145
+ }
146
+ if (!vm)
147
+ return;
148
+ ctx.ui.setStatus('sandbox', ctx.ui.theme.fg('muted', 'Sandbox: stopping'));
149
+ try {
150
+ await vm.close();
151
+ }
152
+ finally {
153
+ vm = null;
154
+ vmStarting = null;
155
+ moltnetAgent = null;
156
+ }
157
+ });
158
+ pi.on('before_agent_start', async (event, ctx) => {
159
+ await ensureVm(ctx);
160
+ const modified = event.systemPrompt.replace(`Current working directory: ${localCwd}`, `Current working directory: ${GUEST_WORKSPACE} (sandbox, mounted from host: ${worktreePath ?? localCwd})`);
161
+ return { systemPrompt: modified };
162
+ });
163
+ // -- Tool overrides (read/write/edit/bash → VM) ----------------------------
164
+ pi.registerTool({
165
+ ...localRead,
166
+ async execute(id, params, signal, onUpdate, ctx) {
167
+ const activeVm = await ensureVm(ctx);
168
+ const tool = createReadTool(localCwd, {
169
+ operations: createGondolinReadOps(activeVm, localCwd),
170
+ });
171
+ return tool.execute(id, params, signal, onUpdate);
172
+ },
173
+ });
174
+ pi.registerTool({
175
+ ...localWrite,
176
+ async execute(id, params, signal, onUpdate, ctx) {
177
+ const activeVm = await ensureVm(ctx);
178
+ const tool = createWriteTool(localCwd, {
179
+ operations: createGondolinWriteOps(activeVm, localCwd),
180
+ });
181
+ return tool.execute(id, params, signal, onUpdate);
182
+ },
183
+ });
184
+ pi.registerTool({
185
+ ...localEdit,
186
+ async execute(id, params, signal, onUpdate, ctx) {
187
+ const activeVm = await ensureVm(ctx);
188
+ const tool = createEditTool(localCwd, {
189
+ operations: createGondolinEditOps(activeVm, localCwd),
190
+ });
191
+ return tool.execute(id, params, signal, onUpdate);
192
+ },
193
+ });
194
+ pi.registerTool({
195
+ ...localBash,
196
+ label: 'bash (sandbox)',
197
+ async execute(id, params, signal, onUpdate, ctx) {
198
+ const activeVm = await ensureVm(ctx);
199
+ const tool = createBashTool(localCwd, {
200
+ operations: createGondolinBashOps(activeVm, localCwd),
201
+ });
202
+ return tool.execute(id, params, signal, onUpdate);
203
+ },
204
+ });
205
+ pi.on('user_bash', (_event, _ctx) => {
206
+ if (!vm)
207
+ return;
208
+ return { operations: createGondolinBashOps(vm, localCwd) };
209
+ });
210
+ // -- MoltNet custom tools (run on host, not in VM) -------------------------
211
+ const moltnetTools = createMoltNetTools({
212
+ getAgent: () => moltnetAgent,
213
+ getDiaryId: () => diaryId,
214
+ });
215
+ for (const tool of moltnetTools) {
216
+ pi.registerTool(tool);
217
+ }
218
+ // -- Session learning (error tracking + automatic reflection) ---------------
219
+ const sessionErrors = [];
220
+ const sessionStartTime = Date.now();
221
+ function getAgentGhToken() {
222
+ const gitConfigGlobal = process.env.GIT_CONFIG_GLOBAL;
223
+ if (!gitConfigGlobal)
224
+ return null;
225
+ try {
226
+ const credsDir = path.dirname(gitConfigGlobal);
227
+ const credsPath = path.join(credsDir, 'moltnet.json');
228
+ if (!existsSync(credsPath))
229
+ return null;
230
+ return execFileSync('npx', ['@themoltnet/cli', 'github', 'token', '--credentials', credsPath], {
231
+ encoding: 'utf8',
232
+ cwd: worktreePath ?? localCwd,
233
+ stdio: ['pipe', 'pipe', 'pipe'],
234
+ }).trim();
235
+ }
236
+ catch {
237
+ return null;
238
+ }
239
+ }
240
+ let cachedGitBranch = null;
241
+ async function getGitBranch() {
242
+ try {
243
+ // When the sandbox is running, read branch from the guest workspace
244
+ // (the agent may have created/switched branches inside the VM).
245
+ if (vm) {
246
+ const r = await vm.exec('git -C /workspace branch --show-current');
247
+ if (r.exitCode === 0 && r.stdout?.trim()) {
248
+ cachedGitBranch = r.stdout.trim();
249
+ return cachedGitBranch;
250
+ }
251
+ }
252
+ // Fallback: read from host worktree
253
+ cachedGitBranch =
254
+ execFileSync('git', ['branch', '--show-current'], {
255
+ encoding: 'utf8',
256
+ cwd: worktreePath ?? localCwd,
257
+ stdio: ['pipe', 'pipe', 'pipe'],
258
+ }).trim() || null;
259
+ return cachedGitBranch;
260
+ }
261
+ catch {
262
+ return cachedGitBranch;
263
+ }
264
+ }
265
+ async function getSessionMeta(ctx) {
266
+ const agentName = pi.getFlag('agent');
267
+ const gitBranch = await getGitBranch();
268
+ const sessionName = ctx.sessionManager.getSessionName();
269
+ const sessionId = ctx.sessionManager.getSessionId();
270
+ const modelName = ctx.model?.name ?? ctx.model?.id ?? 'unknown';
271
+ const durationMs = Date.now() - sessionStartTime;
272
+ const durationMin = Math.round(durationMs / 60_000);
273
+ return {
274
+ agentName,
275
+ gitBranch,
276
+ sessionName,
277
+ sessionId,
278
+ modelName,
279
+ cwd: ctx.cwd,
280
+ worktree: worktreePath,
281
+ durationMin,
282
+ };
283
+ }
284
+ function formatMetaBlock(meta) {
285
+ const lines = [
286
+ `| Field | Value |`,
287
+ `|-------|-------|`,
288
+ `| Agent | ${meta.agentName} |`,
289
+ `| Model | ${meta.modelName} |`,
290
+ `| Branch | ${meta.gitBranch ?? 'detached/unknown'} |`,
291
+ `| CWD | ${meta.cwd} |`,
292
+ ];
293
+ if (meta.worktree)
294
+ lines.push(`| Worktree | ${meta.worktree} |`);
295
+ if (meta.sessionName)
296
+ lines.push(`| Session | ${meta.sessionName} |`);
297
+ lines.push(`| Duration | ~${meta.durationMin} min |`);
298
+ return lines.join('\n');
299
+ }
300
+ // Track tool errors with full context
301
+ pi.on('tool_result', async (event, _ctx) => {
302
+ if (event.isError) {
303
+ sessionErrors.push({
304
+ toolName: event.toolName,
305
+ toolCallId: event.toolCallId,
306
+ input: event.input,
307
+ error: event.content
308
+ ?.filter((c) => c.type === 'text')
309
+ .map((c) => c.text)
310
+ .join('\n')
311
+ .slice(0, 500) ?? 'unknown error',
312
+ timestamp: Date.now(),
313
+ });
314
+ }
315
+ });
316
+ async function createErrorEntry(ctx, trigger, extra) {
317
+ if (!moltnetAgent || !diaryId)
318
+ return;
319
+ if (sessionErrors.length === 0)
320
+ return;
321
+ const meta = await getSessionMeta(ctx);
322
+ const errorSummary = sessionErrors
323
+ .map((e) => {
324
+ const inputSnippet = JSON.stringify(e.input).slice(0, 100);
325
+ return `- **${e.toolName}** (${new Date(e.timestamp).toISOString()})\n Input: \`${inputSnippet}\`\n Error: ${e.error.slice(0, 200)}`;
326
+ })
327
+ .join('\n');
328
+ const branchTag = meta.gitBranch
329
+ ? `branch:${meta.gitBranch.replace(/\//g, '-')}`
330
+ : null;
331
+ const tags = ['session-learning', 'errors', 'episodic'];
332
+ if (branchTag)
333
+ tags.push(branchTag);
334
+ await moltnetAgent.entries.create(diaryId, {
335
+ title: `Session incidents: ${sessionErrors.length} tool failure(s) on ${meta.gitBranch ?? 'unknown'}`,
336
+ content: [
337
+ `## Session incident log (${trigger})`,
338
+ '',
339
+ formatMetaBlock(meta),
340
+ '',
341
+ '### Errors encountered',
342
+ '',
343
+ errorSummary,
344
+ ...(extra ? ['', extra] : []),
345
+ '',
346
+ '_Auto-generated by @themoltnet/pi-extension session learning._',
347
+ ].join('\n'),
348
+ tags,
349
+ importance: sessionErrors.length >= 3 ? 7 : 4,
350
+ entryType: 'episodic',
351
+ });
352
+ }
353
+ // On session_tree (branch navigation) — record errors for the current branch
354
+ pi.on('session_tree', async (event, ctx) => {
355
+ try {
356
+ await createErrorEntry(ctx, 'tree navigation', `Branch navigated: \`${event.oldLeafId}\` → \`${event.newLeafId}\``);
357
+ sessionErrors.length = 0;
358
+ }
359
+ catch {
360
+ // Don't let diary failures break the session
361
+ }
362
+ });
363
+ // -- Commands ---------------------------------------------------------------
364
+ const state = {
365
+ get vm() {
366
+ return vm;
367
+ },
368
+ get worktreePath() {
369
+ return worktreePath;
370
+ },
371
+ localCwd,
372
+ get diaryId() {
373
+ return diaryId;
374
+ },
375
+ get moltnetAgent() {
376
+ return moltnetAgent;
377
+ },
378
+ sessionErrors,
379
+ getSessionMeta,
380
+ getAgentGhToken,
381
+ ensureVm,
382
+ };
383
+ registerSandboxCommand(pi, state);
384
+ registerResolveIssueCommand(pi, state);
385
+ registerMoltnetReflectCommand(pi, state);
386
+ }
387
+ // Re-export modules for programmatic use
388
+ export { createMoltNetTools } from './moltnet-tools.js';
389
+ export { ensureSnapshot } from './snapshot.js';
390
+ export { createGondolinBashOps, createGondolinEditOps, createGondolinReadOps, createGondolinWriteOps, toGuestPath, } from './tool-operations.js';
391
+ export { activateAgentEnv, findMainWorktree, loadCredentials, resumeVm, } from './vm-manager.js';
392
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { ToolDefinition } from '@mariozechner/pi-coding-agent';
2
+ import type { connect } from '@themoltnet/sdk';
3
+ type MoltNetAgent = Awaited<ReturnType<typeof connect>>;
4
+ export interface MoltNetToolsConfig {
5
+ getAgent(): MoltNetAgent | null;
6
+ getDiaryId(): string | null;
7
+ }
8
+ /**
9
+ * Create all MoltNet tool definitions, ready to pass to `pi.registerTool()`.
10
+ */
11
+ export declare function createMoltNetTools(config: MoltNetToolsConfig): ToolDefinition<any, any>[];
12
+ export {};
13
+ //# sourceMappingURL=moltnet-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"moltnet-tools.d.ts","sourceRoot":"","sources":["../src/moltnet-tools.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEpE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C,KAAK,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC,CAAC;AAExD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,IAAI,YAAY,GAAG,IAAI,CAAC;IAChC,UAAU,IAAI,MAAM,GAAG,IAAI,CAAC;CAC7B;AASD;;GAEG;AAEH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,kBAAkB,GACzB,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CA4I5B"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * MoltNet custom tools for pi.
3
+ *
4
+ * Factory that produces ready-to-register pi tool definitions.
5
+ * These tools run on the host (not in the VM) via the MoltNet SDK,
6
+ * so agent credentials never touch the VM filesystem.
7
+ */
8
+ import { Type } from '@mariozechner/pi-ai';
9
+ import { defineTool } from '@mariozechner/pi-coding-agent';
10
+ function ensureConnected(config) {
11
+ const agent = config.getAgent();
12
+ const diaryId = config.getDiaryId();
13
+ if (!agent || !diaryId)
14
+ throw new Error('MoltNet not connected');
15
+ return { agent, diaryId };
16
+ }
17
+ /**
18
+ * Create all MoltNet tool definitions, ready to pass to `pi.registerTool()`.
19
+ */
20
+ export function createMoltNetTools(config) {
21
+ const listEntries = defineTool({
22
+ name: 'moltnet_list_entries',
23
+ label: 'List MoltNet Diary Entries',
24
+ description: 'List recent entries from the MoltNet diary. Returns title, tags, importance, and creation date.',
25
+ parameters: Type.Object({
26
+ limit: Type.Optional(Type.Number({ description: 'Max entries to return (default 10)' })),
27
+ tag: Type.Optional(Type.String({ description: 'Filter by tag (optional)' })),
28
+ }),
29
+ async execute(_id, params) {
30
+ const { agent, diaryId } = ensureConnected(config);
31
+ const query = {
32
+ limit: params.limit ?? 10,
33
+ orderBy: 'createdAt',
34
+ order: 'desc',
35
+ };
36
+ if (params.tag)
37
+ query.tag = params.tag;
38
+ const entries = await agent.entries.list(diaryId, query);
39
+ const text = JSON.stringify(entries.items?.map((e) => ({
40
+ id: e.id,
41
+ title: e.title,
42
+ tags: e.tags,
43
+ importance: e.importance,
44
+ createdAt: e.createdAt,
45
+ contentPreview: typeof e.content === 'string' ? e.content.slice(0, 200) : undefined,
46
+ })), null, 2);
47
+ return { content: [{ type: 'text', text }], details: {} };
48
+ },
49
+ });
50
+ const getEntry = defineTool({
51
+ name: 'moltnet_get_entry',
52
+ label: 'Get MoltNet Diary Entry',
53
+ description: 'Get the full content of a specific diary entry by ID.',
54
+ parameters: Type.Object({
55
+ entryId: Type.String({ description: 'The entry ID to fetch' }),
56
+ }),
57
+ async execute(_id, params) {
58
+ const { agent } = ensureConnected(config);
59
+ const entry = await agent.entries.get(params.entryId);
60
+ const text = JSON.stringify({
61
+ id: entry.id,
62
+ title: entry.title,
63
+ content: entry.content,
64
+ tags: entry.tags,
65
+ importance: entry.importance,
66
+ createdAt: entry.createdAt,
67
+ }, null, 2);
68
+ return { content: [{ type: 'text', text }], details: {} };
69
+ },
70
+ });
71
+ const searchEntries = defineTool({
72
+ name: 'moltnet_search_entries',
73
+ label: 'Search MoltNet Diary Entries',
74
+ description: 'Search diary entries by semantic query. Uses vector similarity to find relevant entries.',
75
+ parameters: Type.Object({
76
+ query: Type.String({
77
+ description: 'Natural language search query',
78
+ }),
79
+ limit: Type.Optional(Type.Number({ description: 'Max results (default 5)' })),
80
+ }),
81
+ async execute(_id, params) {
82
+ const { agent, diaryId } = ensureConnected(config);
83
+ const results = await agent.entries.search({
84
+ diaryId,
85
+ query: params.query,
86
+ limit: params.limit ?? 5,
87
+ });
88
+ const text = JSON.stringify(results.results?.map((e) => ({
89
+ id: e.id,
90
+ title: e.title,
91
+ tags: e.tags,
92
+ importance: e.importance,
93
+ contentPreview: typeof e.content === 'string' ? e.content.slice(0, 200) : undefined,
94
+ })), null, 2);
95
+ return { content: [{ type: 'text', text }], details: {} };
96
+ },
97
+ });
98
+ const createEntry = defineTool({
99
+ name: 'moltnet_create_entry',
100
+ label: 'Create MoltNet Diary Entry',
101
+ description: 'Create a new diary entry to record decisions, findings, incidents, or reflections.',
102
+ parameters: Type.Object({
103
+ title: Type.String({
104
+ description: 'Entry title (concise, descriptive)',
105
+ }),
106
+ content: Type.String({ description: 'Entry content (markdown)' }),
107
+ tags: Type.Optional(Type.Array(Type.String(), {
108
+ description: 'Tags for categorization',
109
+ })),
110
+ importance: Type.Optional(Type.Number({ description: 'Importance 1-10 (default 5)' })),
111
+ }),
112
+ async execute(_id, params) {
113
+ const { agent, diaryId } = ensureConnected(config);
114
+ const entry = await agent.entries.create(diaryId, {
115
+ title: params.title,
116
+ content: params.content,
117
+ tags: params.tags ?? [],
118
+ importance: params.importance ?? 5,
119
+ });
120
+ const text = JSON.stringify({ id: entry.id, title: entry.title, createdAt: entry.createdAt }, null, 2);
121
+ return { content: [{ type: 'text', text }], details: {} };
122
+ },
123
+ });
124
+ return [listEntries, getEntry, searchEntries, createEntry];
125
+ }
126
+ //# sourceMappingURL=moltnet-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"moltnet-tools.js","sourceRoot":"","sources":["../src/moltnet-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ export interface SandboxConfig {
2
+ /** Snapshot build settings. */
3
+ snapshot?: {
4
+ /** Shell commands to run after the base setup. */
5
+ setupCommands?: string[];
6
+ /** Additional hosts to allow network access during build. */
7
+ allowedHosts?: string[];
8
+ /** Overlay disk size (default '3G'). */
9
+ overlaySize?: string;
10
+ };
11
+ /** VFS shadow settings — hide host paths from the guest. */
12
+ vfs?: {
13
+ /** Paths (relative to workspace root) to shadow from the host mount. */
14
+ shadow?: string[];
15
+ /** What to do with writes to shadowed paths: 'deny' or 'tmpfs' (default 'tmpfs'). */
16
+ shadowMode?: 'deny' | 'tmpfs';
17
+ };
18
+ /** Environment variable overrides for the guest VM (applied on top of defaults). */
19
+ env?: Record<string, string>;
20
+ /** VM resource allocation. */
21
+ resources?: {
22
+ /** Memory size in qemu syntax (default '1G'). */
23
+ memory?: string;
24
+ /** CPU count (default 2). */
25
+ cpus?: number;
26
+ };
27
+ }
28
+ /** Extract snapshot-specific config for backwards compat with ensureSnapshot. */
29
+ export type SnapshotConfig = NonNullable<SandboxConfig['snapshot']>;
30
+ export interface EnsureSnapshotOptions {
31
+ config?: SnapshotConfig;
32
+ onProgress?: (message: string) => void;
33
+ /** Max number of old snapshots to keep (default 1). */
34
+ maxCached?: number;
35
+ }
36
+ /**
37
+ * Ensure a cached snapshot exists, building one if needed.
38
+ * Returns the absolute path to the qcow2 checkpoint file.
39
+ */
40
+ export declare function ensureSnapshot(options?: EnsureSnapshotOptions): Promise<string>;
41
+ //# sourceMappingURL=snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAkCA,MAAM,WAAW,aAAa;IAC5B,+BAA+B;IAC/B,QAAQ,CAAC,EAAE;QACT,kDAAkD;QAClD,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,6DAA6D;QAC7D,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,wCAAwC;QACxC,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,4DAA4D;IAC5D,GAAG,CAAC,EAAE;QACJ,wEAAwE;QACxE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,qFAAqF;QACrF,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;KAC/B,CAAC;IACF,oFAAoF;IACpF,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,8BAA8B;IAC9B,SAAS,CAAC,EAAE;QACV,iDAAiD;QACjD,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,6BAA6B;QAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,iFAAiF;AACjF,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC;AA+FpE,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,MAAM,CAAC,CAuFjB"}