@farmslot/agent-runtime 0.8.0 → 0.9.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 (97) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +2 -2
  3. package/bin/farmslot-agent.mjs +3 -43
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/native/affinity.test.d.ts +2 -0
  9. package/dist/native/affinity.test.d.ts.map +1 -0
  10. package/dist/native/affinity.test.js +30 -0
  11. package/dist/native/affinity.test.js.map +1 -0
  12. package/dist/native/claude.d.ts +11 -0
  13. package/dist/native/claude.d.ts.map +1 -0
  14. package/dist/native/claude.js +490 -0
  15. package/dist/native/claude.js.map +1 -0
  16. package/dist/native/client.d.ts +21 -0
  17. package/dist/native/client.d.ts.map +1 -0
  18. package/dist/native/client.js +106 -0
  19. package/dist/native/client.js.map +1 -0
  20. package/dist/native/codex.d.ts +3 -0
  21. package/dist/native/codex.d.ts.map +1 -0
  22. package/dist/native/codex.js +266 -0
  23. package/dist/native/codex.js.map +1 -0
  24. package/dist/native/durability.test.d.ts +2 -0
  25. package/dist/native/durability.test.d.ts.map +1 -0
  26. package/dist/native/durability.test.js +516 -0
  27. package/dist/native/durability.test.js.map +1 -0
  28. package/dist/native/host.d.ts +2 -0
  29. package/dist/native/host.d.ts.map +1 -0
  30. package/dist/native/host.js +90 -0
  31. package/dist/native/host.js.map +1 -0
  32. package/dist/native/index.d.ts +4 -0
  33. package/dist/native/index.d.ts.map +1 -0
  34. package/dist/native/index.js +3 -0
  35. package/dist/native/index.js.map +1 -0
  36. package/dist/native/ipc.d.ts +49 -0
  37. package/dist/native/ipc.d.ts.map +1 -0
  38. package/dist/native/ipc.js +109 -0
  39. package/dist/native/ipc.js.map +1 -0
  40. package/dist/native/manager.d.ts +43 -0
  41. package/dist/native/manager.d.ts.map +1 -0
  42. package/dist/native/manager.js +510 -0
  43. package/dist/native/manager.js.map +1 -0
  44. package/dist/native/process-tree.d.ts +15 -0
  45. package/dist/native/process-tree.d.ts.map +1 -0
  46. package/dist/native/process-tree.js +128 -0
  47. package/dist/native/process-tree.js.map +1 -0
  48. package/dist/native/process-tree.test.d.ts +2 -0
  49. package/dist/native/process-tree.test.d.ts.map +1 -0
  50. package/dist/native/process-tree.test.js +49 -0
  51. package/dist/native/process-tree.test.js.map +1 -0
  52. package/dist/native/process.d.ts +34 -0
  53. package/dist/native/process.d.ts.map +1 -0
  54. package/dist/native/process.js +223 -0
  55. package/dist/native/process.js.map +1 -0
  56. package/dist/native/service.d.ts +7 -0
  57. package/dist/native/service.d.ts.map +1 -0
  58. package/dist/native/service.js +117 -0
  59. package/dist/native/service.js.map +1 -0
  60. package/dist/native/storage.d.ts +11 -0
  61. package/dist/native/storage.d.ts.map +1 -0
  62. package/dist/native/storage.js +102 -0
  63. package/dist/native/storage.js.map +1 -0
  64. package/dist/native/supervisor.d.ts +2 -0
  65. package/dist/native/supervisor.d.ts.map +1 -0
  66. package/dist/native/supervisor.js +127 -0
  67. package/dist/native/supervisor.js.map +1 -0
  68. package/dist/native/types.d.ts +26 -0
  69. package/dist/native/types.d.ts.map +1 -0
  70. package/dist/native/types.js +2 -0
  71. package/dist/native/types.js.map +1 -0
  72. package/dist/native/workspace-files.d.ts +6 -0
  73. package/dist/native/workspace-files.d.ts.map +1 -0
  74. package/dist/native/workspace-files.js +62 -0
  75. package/dist/native/workspace-files.js.map +1 -0
  76. package/dist/native/workspace.d.ts +5 -0
  77. package/dist/native/workspace.d.ts.map +1 -0
  78. package/dist/native/workspace.js +120 -0
  79. package/dist/native/workspace.js.map +1 -0
  80. package/dist/task-init/index.d.ts +66 -0
  81. package/dist/task-init/index.d.ts.map +1 -0
  82. package/dist/task-init/index.js +120 -0
  83. package/dist/task-init/index.js.map +1 -0
  84. package/dist/task-init/task-document.d.ts +98 -0
  85. package/dist/task-init/task-document.d.ts.map +1 -0
  86. package/dist/task-init/task-document.js +184 -0
  87. package/dist/task-init/task-document.js.map +1 -0
  88. package/dist/task-init/write.d.ts +48 -0
  89. package/dist/task-init/write.d.ts.map +1 -0
  90. package/dist/task-init/write.js +70 -0
  91. package/dist/task-init/write.js.map +1 -0
  92. package/package.json +13 -4
  93. package/scripts/checklist-target.cjs +5 -3
  94. package/scripts/execution-template-cli.mjs +9 -7
  95. package/scripts/mark-checklist-step.cjs +4 -2
  96. package/scripts/task-init-cli.mjs +166 -0
  97. package/scripts/worker-terminal-contract.cjs +15 -3
@@ -0,0 +1,128 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ function processes() {
3
+ // OS process metadata only. Never inspect native stdout or process environments.
4
+ // Start metadata survives exec and process-title changes, unlike command text.
5
+ const output = execFileSync('ps', ['-axo', 'pid=,ppid=,pgid=,lstart='], {
6
+ encoding: 'utf8',
7
+ stdio: ['ignore', 'pipe', 'pipe'],
8
+ maxBuffer: 16 * 1024 * 1024,
9
+ timeout: 1_000,
10
+ });
11
+ const result = new Map();
12
+ for (const line of output.split('\n')) {
13
+ const match = /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(.+)$/.exec(line);
14
+ if (match)
15
+ result.set(Number(match[1]), {
16
+ pid: Number(match[1]),
17
+ parent: Number(match[2]),
18
+ group: Number(match[3]),
19
+ identity: match[4],
20
+ });
21
+ }
22
+ return result;
23
+ }
24
+ function signal(identity, kind) {
25
+ const current = processes().get(identity.pid);
26
+ if (!current || current.identity !== identity.identity)
27
+ return;
28
+ try {
29
+ process.kill(identity.pid, kind);
30
+ }
31
+ catch (error) {
32
+ if (error.code !== 'ESRCH')
33
+ throw error;
34
+ }
35
+ }
36
+ /** Tracks detached descendants while their ancestry is still observable. */
37
+ export class NativeProcessTree {
38
+ constructor(root) {
39
+ this.root = root;
40
+ this.owned = new Map();
41
+ const identity = processes().get(root)?.identity;
42
+ if (!identity)
43
+ throw new Error('Native process identity is unavailable');
44
+ this.rootIdentity = identity;
45
+ this.capture();
46
+ }
47
+ capture() {
48
+ const snapshot = processes();
49
+ const root = snapshot.get(this.root);
50
+ if (root?.identity === this.rootIdentity) {
51
+ this.owned.set(root.pid, root);
52
+ }
53
+ for (const [pid, identity] of this.owned) {
54
+ if (snapshot.get(pid)?.identity !== identity.identity)
55
+ this.owned.delete(pid);
56
+ }
57
+ // A current, known member proves this is still the original runner group.
58
+ const ownsGroup = [...this.owned.values()].some((entry) => entry.group === this.root);
59
+ if (ownsGroup) {
60
+ for (const entry of snapshot.values()) {
61
+ if (entry.group === this.root)
62
+ this.owned.set(entry.pid, entry);
63
+ }
64
+ }
65
+ let changed = true;
66
+ while (changed) {
67
+ changed = false;
68
+ for (const entry of snapshot.values()) {
69
+ if (!this.owned.has(entry.pid) && this.owned.has(entry.parent)) {
70
+ this.owned.set(entry.pid, entry);
71
+ changed = true;
72
+ }
73
+ }
74
+ }
75
+ }
76
+ /** Freeze observed owners before the final ancestry scan, preventing new child launches. */
77
+ stop() {
78
+ this.capture();
79
+ const errors = [];
80
+ const attempt = (operation) => {
81
+ try {
82
+ operation();
83
+ }
84
+ catch (error) {
85
+ // Continue trying the other owned processes, but never claim successful cleanup.
86
+ errors.push(error);
87
+ }
88
+ };
89
+ for (const entry of this.owned.values())
90
+ attempt(() => signal(entry, 'SIGSTOP'));
91
+ attempt(() => this.capture());
92
+ attempt(() => this.stopGroup());
93
+ for (const entry of [...this.owned.values()].reverse())
94
+ attempt(() => signal(entry, 'SIGKILL'));
95
+ if (errors.length)
96
+ throw new AggregateError(errors, `Native process tree cleanup failed: ${errors.map((error) => (error instanceof Error ? error.message : String(error))).join('; ')}`);
97
+ }
98
+ empty() {
99
+ this.capture();
100
+ if (this.owned.size > 0)
101
+ return false;
102
+ // A reused group cannot be signaled safely or counted as proof of cleanup.
103
+ return ![...processes().values()].some((entry) => entry.group === this.root);
104
+ }
105
+ stopGroup() {
106
+ const snapshot = processes();
107
+ const members = [...snapshot.values()].filter((entry) => entry.group === this.root);
108
+ if (!members.length)
109
+ return;
110
+ if (!members.some((entry) => this.owned.get(entry.pid)?.identity === entry.identity))
111
+ throw new Error('Native process group ownership could not be verified');
112
+ try {
113
+ process.kill(-this.root, 'SIGKILL');
114
+ }
115
+ catch (error) {
116
+ if (error.code !== 'ESRCH')
117
+ throw error;
118
+ }
119
+ }
120
+ /** Graceful stop begins with the native root, retaining descendants for final cleanup. */
121
+ terminate() {
122
+ this.capture();
123
+ const root = this.owned.get(this.root);
124
+ if (root)
125
+ signal(root, 'SIGTERM');
126
+ }
127
+ }
128
+ //# sourceMappingURL=process-tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-tree.js","sourceRoot":"","sources":["../../src/native/process-tree.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=process-tree.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-tree.test.d.ts","sourceRoot":"","sources":["../../src/native/process-tree.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,49 @@
1
+ import assert from 'node:assert/strict';
2
+ import { spawn } from 'node:child_process';
3
+ import { once } from 'node:events';
4
+ import test from 'node:test';
5
+ import { NativeProcessTree } from './process-tree.js';
6
+ import { alive } from './storage.js';
7
+ test('cleanup retains a detached child after its title changes and parent exits', async () => {
8
+ const childCode = `
9
+ process.send(process.pid);
10
+ process.on('message', () => { process.title = 'native-renamed-tool'; process.send('renamed'); });
11
+ setInterval(() => {}, 1000);
12
+ `;
13
+ const root = spawn(process.execPath, [
14
+ '-e',
15
+ `
16
+ const child = require('node:child_process').spawn(process.execPath, ['-e', ${JSON.stringify(childCode)}], {
17
+ detached: true, stdio: ['ignore', 'ignore', 'ignore', 'ipc']
18
+ });
19
+ child.on('message', message => process.send(message));
20
+ process.on('message', () => child.send('rename'));
21
+ `,
22
+ ], { detached: true, stdio: ['ignore', 'ignore', 'ignore', 'ipc'] });
23
+ let descendant;
24
+ try {
25
+ [descendant] = await once(root, 'message');
26
+ assert.ok(typeof descendant === 'number');
27
+ const tree = new NativeProcessTree(root.pid);
28
+ const renamed = once(root, 'message');
29
+ root.send('rename');
30
+ assert.equal((await renamed)[0], 'renamed');
31
+ const exited = once(root, 'exit');
32
+ root.kill('SIGKILL');
33
+ await exited;
34
+ assert.ok(alive(descendant));
35
+ tree.stop();
36
+ const deadline = Date.now() + 3_000;
37
+ while (alive(descendant) && Date.now() < deadline)
38
+ await new Promise((resolve) => setTimeout(resolve, 20));
39
+ assert.equal(alive(descendant), false, 'Detached renamed child survived cleanup');
40
+ assert.equal(tree.empty(), true);
41
+ }
42
+ finally {
43
+ if (root.pid && alive(root.pid))
44
+ root.kill('SIGKILL');
45
+ if (descendant && alive(descendant))
46
+ process.kill(descendant, 'SIGKILL');
47
+ }
48
+ });
49
+ //# sourceMappingURL=process-tree.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-tree.test.js","sourceRoot":"","sources":["../../src/native/process-tree.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,IAAI,CAAC,2EAA2E,EAAE,KAAK,IAAI,EAAE;IAC3F,MAAM,SAAS,GAAG;;;;GAIjB,CAAC;IACF,MAAM,IAAI,GAAG,KAAK,CAChB,OAAO,CAAC,QAAQ,EAChB;QACE,IAAI;QACJ;iFAC2E,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;;;;;GAKvG;KACE,EACD,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,CACjE,CAAC;IACF,IAAI,UAA8B,CAAC;IACnC,IAAI,CAAC;QACH,CAAC,UAAU,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC3C,MAAM,CAAC,EAAE,CAAC,OAAO,UAAU,KAAK,QAAQ,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,GAAI,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpB,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrB,MAAM,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QACpC,OAAO,KAAK,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ;YAC/C,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;QAC1D,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,yCAAyC,CAAC,CAAC;QAClF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;IACnC,CAAC;YAAS,CAAC;QACT,IAAI,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtD,IAAI,UAAU,IAAI,KAAK,CAAC,UAAU,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAC3E,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { type ChildProcessWithoutNullStreams } from 'node:child_process';
2
+ /** JSON framing only. Human-readable stderr never supplies session state. */
3
+ export declare class JsonLineProcess {
4
+ private readonly onExit;
5
+ readonly child: ChildProcessWithoutNullStreams;
6
+ private nextId;
7
+ private tree?;
8
+ private treeTimer?;
9
+ private closed;
10
+ private finish;
11
+ private finished;
12
+ private cleanupError?;
13
+ private cleanupStarted;
14
+ private stopTimer?;
15
+ private closing;
16
+ private failure?;
17
+ private pending;
18
+ constructor(executable: string, args: string[], options: {
19
+ cwd: string;
20
+ env?: NodeJS.ProcessEnv;
21
+ onSpawn?: (pid: number, identity: string) => void;
22
+ }, onMessage: (message: Record<string, unknown>) => void, onExit: (error: Error | undefined, processStopped: boolean) => void);
23
+ private fail;
24
+ write(message: unknown): void;
25
+ request(method: string, params: unknown): Promise<unknown>;
26
+ private closePromise?;
27
+ close(): Promise<void>;
28
+ private beginStop;
29
+ /** Internal completion never rejects; callers of close receive any cleanup failure. */
30
+ private beginCleanup;
31
+ private settle;
32
+ private cleanGroup;
33
+ }
34
+ //# sourceMappingURL=process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/native/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,8BAA8B,EAAS,MAAM,oBAAoB,CAAC;AAqBhF,6EAA6E;AAC7E,qBAAa,eAAe;IA6BxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IA5BzB,QAAQ,CAAC,KAAK,EAAE,8BAA8B,CAAC;IAC/C,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,IAAI,CAAC,CAAoB;IACjC,OAAO,CAAC,SAAS,CAAC,CAAiB;IACnC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,QAAQ,CAEb;IACH,OAAO,CAAC,YAAY,CAAC,CAAQ;IAC7B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,SAAS,CAAC,CAAiB;IACnC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAC,CAAQ;IACxB,OAAO,CAAC,OAAO,CAGX;gBAGF,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;QACxB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;KACnD,EACD,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,EACpC,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,EAAE,cAAc,EAAE,OAAO,KAAK,IAAI;IAwFtF,OAAO,CAAC,IAAI;IAWZ,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAK7B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAkB1D,OAAO,CAAC,YAAY,CAAC,CAAgB;IACrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAOtB,OAAO,CAAC,SAAS;IAYjB,uFAAuF;IACvF,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,MAAM;YAiBA,UAAU;CAgBzB"}
@@ -0,0 +1,223 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { randomUUID } from 'node:crypto';
3
+ import { createInterface } from 'node:readline';
4
+ import { NativeProcessTree } from './process-tree.js';
5
+ // Wait for the host's durable process registration before executing the native binary.
6
+ // Reading one byte leaves all subsequent native JSON on stdin untouched.
7
+ const registeredLaunch = `
8
+ const fs = require('node:fs');
9
+ const { spawn } = require('node:child_process');
10
+ if (fs.readSync(0, Buffer.alloc(1), 0, 1, null) !== 1) process.exit(1);
11
+ const child = spawn(process.argv[2], process.argv.slice(3), { stdio: 'inherit' });
12
+ child.on('error', error => { process.stderr.write(error.message); process.exit(1); });
13
+ process.on('SIGTERM', () => child.kill('SIGTERM'));
14
+ child.on('exit', (code, signal) => {
15
+ if (signal) { process.removeAllListeners(signal); process.kill(process.pid, signal); }
16
+ else process.exit(code ?? 1);
17
+ });
18
+ `;
19
+ /** JSON framing only. Human-readable stderr never supplies session state. */
20
+ export class JsonLineProcess {
21
+ constructor(executable, args, options, onMessage, onExit) {
22
+ this.onExit = onExit;
23
+ this.nextId = 0;
24
+ this.closed = false;
25
+ this.finished = new Promise((resolve) => {
26
+ this.finish = resolve;
27
+ });
28
+ this.cleanupStarted = false;
29
+ this.closing = false;
30
+ this.pending = new Map();
31
+ const identity = `farmslot-native-${randomUUID()}`;
32
+ this.child = spawn(process.execPath, ['-e', registeredLaunch, '--', identity, executable, ...args], {
33
+ cwd: options.cwd,
34
+ env: options.env,
35
+ stdio: 'pipe',
36
+ detached: true,
37
+ });
38
+ this.child.stderr.resume();
39
+ const lines = createInterface({ input: this.child.stdout });
40
+ lines.on('line', (line) => {
41
+ if (this.closed)
42
+ return;
43
+ let message;
44
+ try {
45
+ if (Buffer.byteLength(line) > 1024 * 1024)
46
+ throw new Error('Native event exceeds 1 MiB');
47
+ const decoded = JSON.parse(line);
48
+ if (!decoded || typeof decoded !== 'object' || Array.isArray(decoded)) {
49
+ throw new Error('Native protocol messages must be objects');
50
+ }
51
+ message = decoded;
52
+ }
53
+ catch (error) {
54
+ this.fail(new Error('Native runner emitted invalid JSON', { cause: error }));
55
+ this.beginStop();
56
+ return;
57
+ }
58
+ if (typeof message.id === 'number' && !message.method && this.pending.has(message.id)) {
59
+ const request = this.pending.get(message.id);
60
+ clearTimeout(request.timer);
61
+ this.pending.delete(message.id);
62
+ if (message.error)
63
+ request.reject(new Error(JSON.stringify(message.error)));
64
+ else
65
+ request.resolve(message.result);
66
+ }
67
+ else {
68
+ try {
69
+ onMessage(message);
70
+ }
71
+ catch (error) {
72
+ // A malformed runner event terminates its own session, not the gateway.
73
+ this.fail(new Error('Native runner protocol event failed', { cause: error }));
74
+ this.beginStop();
75
+ }
76
+ }
77
+ });
78
+ this.child.on('error', (error) => {
79
+ this.fail(error);
80
+ this.beginCleanup();
81
+ });
82
+ this.child.on('exit', (code, signal) => {
83
+ this.fail(this.failure ??
84
+ // Native signal handlers may return the conventional 128 + SIGTERM exit code.
85
+ (this.closing &&
86
+ (code === 0 || code === 143 || signal === 'SIGTERM' || signal === 'SIGKILL')
87
+ ? undefined
88
+ : new Error(`Native runner exited: code=${code}, signal=${signal}`)));
89
+ // Do not await close: descendants can retain inherited stdio after the runner exits.
90
+ this.beginCleanup();
91
+ });
92
+ this.child.stdin.on('error', (error) => {
93
+ this.fail(error);
94
+ this.beginStop();
95
+ });
96
+ try {
97
+ if (this.child.pid) {
98
+ this.tree = new NativeProcessTree(this.child.pid);
99
+ this.treeTimer = setInterval(() => {
100
+ try {
101
+ this.tree.capture();
102
+ }
103
+ catch (error) {
104
+ // Loss of process ownership evidence fails this session and its cleanup claim.
105
+ this.beginCleanup(new Error('Native process census failed', { cause: error }));
106
+ }
107
+ }, 100);
108
+ this.treeTimer.unref();
109
+ options.onSpawn?.(this.child.pid, identity);
110
+ }
111
+ this.child.stdin.write('\n');
112
+ }
113
+ catch (error) {
114
+ this.fail(error instanceof Error ? error : new Error(String(error)));
115
+ this.beginCleanup();
116
+ throw error;
117
+ }
118
+ }
119
+ fail(error) {
120
+ this.failure ??= error;
121
+ if (this.closed)
122
+ return;
123
+ this.closed = true;
124
+ for (const request of this.pending.values()) {
125
+ clearTimeout(request.timer);
126
+ request.reject(error ?? new Error('Native runner closed'));
127
+ }
128
+ this.pending.clear();
129
+ }
130
+ write(message) {
131
+ if (this.closed)
132
+ throw new Error('Native runner is closed');
133
+ this.child.stdin.write(`${JSON.stringify(message)}\n`);
134
+ }
135
+ request(method, params) {
136
+ const id = ++this.nextId;
137
+ return new Promise((resolve, reject) => {
138
+ const timer = setTimeout(() => {
139
+ this.pending.delete(id);
140
+ reject(new Error(`Native request timed out: ${method}; acceptance is unknown`));
141
+ }, 30_000);
142
+ this.pending.set(id, { resolve, reject, timer });
143
+ try {
144
+ this.write({ id, method, params });
145
+ }
146
+ catch (error) {
147
+ clearTimeout(timer);
148
+ this.pending.delete(id);
149
+ reject(error);
150
+ }
151
+ });
152
+ }
153
+ close() {
154
+ this.beginStop();
155
+ return (this.closePromise ??= this.finished.then(() => {
156
+ if (this.cleanupError)
157
+ throw this.cleanupError;
158
+ }));
159
+ }
160
+ beginStop() {
161
+ if (this.closing || this.cleanupStarted)
162
+ return;
163
+ this.closing = true;
164
+ this.fail(undefined);
165
+ try {
166
+ this.tree?.terminate();
167
+ this.stopTimer = setTimeout(() => this.beginCleanup(), 3_000);
168
+ }
169
+ catch (error) {
170
+ this.beginCleanup(new Error('Native termination failed', { cause: error }));
171
+ }
172
+ }
173
+ /** Internal completion never rejects; callers of close receive any cleanup failure. */
174
+ beginCleanup(error) {
175
+ if (this.cleanupStarted)
176
+ return;
177
+ this.cleanupStarted = true;
178
+ this.cleanupError = error;
179
+ this.fail(error);
180
+ clearInterval(this.treeTimer);
181
+ clearTimeout(this.stopTimer);
182
+ void this.cleanGroup().then(() => this.settle(), (cleanupError) => {
183
+ this.cleanupError = new Error(`Native child cleanup failed: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`, { cause: cleanupError });
184
+ this.settle();
185
+ });
186
+ }
187
+ settle() {
188
+ // Detach host pipe handles even when cleanup failed and a descendant retained them.
189
+ this.child.stdin.destroy();
190
+ this.child.stdout.destroy();
191
+ this.child.stderr.destroy();
192
+ try {
193
+ this.onExit(this.cleanupError ?? this.failure, !this.cleanupError);
194
+ }
195
+ catch (error) {
196
+ // The owner could not record completion. Surface that failure to close's caller.
197
+ this.cleanupError = new Error('Native process completion could not be recorded', {
198
+ cause: error,
199
+ });
200
+ }
201
+ finally {
202
+ this.finish();
203
+ }
204
+ }
205
+ async cleanGroup() {
206
+ if (!this.child.pid)
207
+ return;
208
+ if (!this.tree) {
209
+ // The launch gate is still closed, so no native descendants have started.
210
+ this.child.kill('SIGKILL');
211
+ throw new Error('Native process ownership could not be established');
212
+ }
213
+ this.tree.stop();
214
+ const deadline = Date.now() + 3_000;
215
+ while (Date.now() < deadline) {
216
+ if (this.tree.empty() && (this.child.exitCode !== null || this.child.signalCode !== null))
217
+ return;
218
+ await new Promise((resolve) => setTimeout(resolve, 20));
219
+ }
220
+ throw new Error('Native child processes did not stop');
221
+ }
222
+ }
223
+ //# sourceMappingURL=process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/native/process.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { NativeSessionClient } from './client.js';
2
+ export declare class NativeSessionMethodError extends Error {
3
+ readonly code: 'INVALID_PARAMS' | 'NATIVE_SESSION_ERROR';
4
+ constructor(code: 'INVALID_PARAMS' | 'NATIVE_SESSION_ERROR', message: string);
5
+ }
6
+ export declare function routeNativeSession(client: NativeSessionClient, principal: string, method: string, value: unknown): Promise<unknown>;
7
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/native/service.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAIvD,qBAAa,wBAAyB,SAAQ,KAAK;IAE/C,QAAQ,CAAC,IAAI,EAAE,gBAAgB,GAAG,sBAAsB;gBAA/C,IAAI,EAAE,gBAAgB,GAAG,sBAAsB,EACxD,OAAO,EAAE,MAAM;CAKlB;AASD,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,mBAAmB,EAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,OAAO,CAAC,CAqHlB"}
@@ -0,0 +1,117 @@
1
+ import { Methods, } from '@farmslot/protocol';
2
+ import { nativeWorkspaceChanges, nativeWorkspaceDiff, nativeWorkspaceList } from './workspace.js';
3
+ import { readWorkspaceText } from './workspace-files.js';
4
+ export class NativeSessionMethodError extends Error {
5
+ constructor(code, message) {
6
+ super(message);
7
+ this.code = code;
8
+ this.name = 'NativeSessionMethodError';
9
+ }
10
+ }
11
+ function string(params, key) {
12
+ const value = params[key];
13
+ if (typeof value !== 'string' || !value.trim())
14
+ throw new NativeSessionMethodError('INVALID_PARAMS', `${key} must be a nonempty string`);
15
+ return value;
16
+ }
17
+ export async function routeNativeSession(client, principal, method, value) {
18
+ if (!value || typeof value !== 'object' || Array.isArray(value))
19
+ throw new NativeSessionMethodError('INVALID_PARAMS', 'Expected native session parameters');
20
+ const p = value;
21
+ if (p.executionNodeId !== undefined && p.executionNodeId !== client.executionNodeId)
22
+ throw new NativeSessionMethodError('INVALID_PARAMS', 'Native session targets another execution node');
23
+ try {
24
+ switch (method) {
25
+ case Methods.NATIVE_SESSION_WORKSPACE_LIST:
26
+ case Methods.NATIVE_SESSION_WORKSPACE_READ:
27
+ case Methods.NATIVE_SESSION_WORKSPACE_CHANGES:
28
+ case Methods.NATIVE_SESSION_WORKSPACE_DIFF: {
29
+ const { session } = await client.read(principal, string(p, 'sessionId'), undefined, 1);
30
+ if (method === Methods.NATIVE_SESSION_WORKSPACE_CHANGES)
31
+ return await nativeWorkspaceChanges(session.cwd);
32
+ const path = string(p, 'path');
33
+ if (method === Methods.NATIVE_SESSION_WORKSPACE_LIST)
34
+ return await nativeWorkspaceList(session.cwd, path);
35
+ if (method === Methods.NATIVE_SESSION_WORKSPACE_DIFF)
36
+ return { path, diff: await nativeWorkspaceDiff(session.cwd, path) };
37
+ return { path, content: await readWorkspaceText(session.cwd, path) };
38
+ }
39
+ case Methods.NATIVE_SESSION_CREATE:
40
+ case Methods.NATIVE_SESSION_ENSURE: {
41
+ const params = {
42
+ runner: string(p, 'runner'),
43
+ cwd: string(p, 'cwd'),
44
+ };
45
+ if (p.model !== undefined)
46
+ params.model = string(p, 'model');
47
+ if (p.mode !== undefined) {
48
+ if (p.mode !== 'default' && p.mode !== 'plan')
49
+ throw new NativeSessionMethodError('INVALID_PARAMS', 'Unknown native interaction mode');
50
+ params.mode = p.mode;
51
+ }
52
+ if (method === Methods.NATIVE_SESSION_ENSURE) {
53
+ if (p.resumeSessionId !== undefined)
54
+ throw new NativeSessionMethodError('INVALID_PARAMS', 'Reserved sessionId is not for resume');
55
+ return {
56
+ session: await client.ensure(principal, {
57
+ ...params,
58
+ sessionId: string(p, 'sessionId'),
59
+ }),
60
+ };
61
+ }
62
+ if (p.resumeSessionId !== undefined)
63
+ params.resumeSessionId = string(p, 'resumeSessionId');
64
+ return { session: await client.create(principal, params) };
65
+ }
66
+ case Methods.NATIVE_SESSION_LIST:
67
+ return { sessions: await client.list(principal) };
68
+ case Methods.NATIVE_SESSION_READ:
69
+ if (p.limit !== undefined && typeof p.limit !== 'number')
70
+ throw new NativeSessionMethodError('INVALID_PARAMS', 'limit must be an integer');
71
+ if (p.after !== undefined && typeof p.after !== 'number')
72
+ throw new NativeSessionMethodError('INVALID_PARAMS', 'after must be an integer');
73
+ return await client.read(principal, string(p, 'sessionId'), p.after, p.limit);
74
+ case Methods.NATIVE_SESSION_SEND: {
75
+ const commandId = string(p, 'commandId');
76
+ return await client.send(principal, string(p, 'sessionId'), commandId, string(p, 'text'));
77
+ }
78
+ case Methods.NATIVE_SESSION_RESPOND: {
79
+ const response = {};
80
+ if (p.decision !== undefined) {
81
+ if (p.decision !== 'approve' && p.decision !== 'deny')
82
+ throw new NativeSessionMethodError('INVALID_PARAMS', 'Unknown approval decision');
83
+ response.decision = p.decision;
84
+ }
85
+ if (p.answers !== undefined) {
86
+ if (!p.answers ||
87
+ typeof p.answers !== 'object' ||
88
+ Array.isArray(p.answers) ||
89
+ !Object.values(p.answers).every((answers) => Array.isArray(answers) && answers.every((answer) => typeof answer === 'string')))
90
+ throw new NativeSessionMethodError('INVALID_PARAMS', 'answers must map question IDs to string arrays');
91
+ response.answers = p.answers;
92
+ }
93
+ if (Boolean(response.decision) === Boolean(response.answers))
94
+ throw new NativeSessionMethodError('INVALID_PARAMS', 'Supply either a decision or answers');
95
+ await client.respond(principal, string(p, 'sessionId'), string(p, 'requestId'), response);
96
+ return { responded: true };
97
+ }
98
+ case Methods.NATIVE_SESSION_INTERRUPT:
99
+ await client.interrupt(principal, string(p, 'sessionId'));
100
+ return { interrupted: true };
101
+ case Methods.NATIVE_SESSION_CLOSE:
102
+ await client.close(principal, string(p, 'sessionId'));
103
+ return {
104
+ closed: true,
105
+ session: (await client.read(principal, string(p, 'sessionId'))).session,
106
+ };
107
+ default:
108
+ throw new Error('Unknown native session method');
109
+ }
110
+ }
111
+ catch (error) {
112
+ if (error instanceof NativeSessionMethodError)
113
+ throw error;
114
+ throw new NativeSessionMethodError('NATIVE_SESSION_ERROR', error.message);
115
+ }
116
+ }
117
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/native/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /** Drop only an incomplete final write before any recovery reader or writer proceeds. */
2
+ export declare function readJournal(path: string): string[];
3
+ export declare function privateDirectory(path: string): void;
4
+ export declare function durableWrite(path: string, value: unknown): void;
5
+ export declare function readJson<T>(path: string): T;
6
+ export declare function alive(pid: number): boolean;
7
+ export declare function signalGroup(pid: number, signal: NodeJS.Signals): void;
8
+ /** Structured process argv evidence, never runner stdout or a terminal rendering. */
9
+ export declare function matchesProcess(pid: number, identity: string): boolean;
10
+ export declare function appendDurable(path: string, value: unknown): void;
11
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/native/storage.ts"],"names":[],"mappings":"AAcA,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAalD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAKnD;AACD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAgB/D;AACD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,CAM3C;AACD,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQ1C;AACD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAOrE;AAED,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAcrE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAQhE"}