@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,490 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { JsonLineProcess } from './process.js';
3
+ /** Upstream fixed hook-history loss in 2.1.83 and interrupted-tool resume in 2.1.265. */
4
+ export function claudeResumeUnavailableReason(version) {
5
+ const match = /^(\d+)\.(\d+)\.(\d+)(?:\s|$)/.exec(version.trim());
6
+ const [major, minor, patch] = match ? match.slice(1).map(Number) : [];
7
+ if (major > 2 || (major === 2 && (minor > 1 || (minor === 1 && patch >= 265))))
8
+ return;
9
+ return 'Saved-session recovery requires a session started with Claude Code 2.1.265 or newer. Earlier versions can lose message/tool history; update the native runner and start a new session.';
10
+ }
11
+ function record(value) {
12
+ return value !== null && typeof value === 'object' ? value : {};
13
+ }
14
+ function textContent(content) {
15
+ if (typeof content === 'string')
16
+ return content;
17
+ if (!Array.isArray(content))
18
+ return undefined;
19
+ return (content
20
+ .map((block) => {
21
+ const value = record(block);
22
+ return value.type === 'text' && typeof value.text === 'string' ? value.text : '';
23
+ })
24
+ .join('') || undefined);
25
+ }
26
+ function toolUseBlocks(content) {
27
+ if (!Array.isArray(content))
28
+ return [];
29
+ return content
30
+ .map(record)
31
+ .filter((block) => block.type === 'tool_use' ||
32
+ block.type === 'server_tool_use' ||
33
+ block.type === 'mcp_tool_use');
34
+ }
35
+ function toolResultBlocks(content) {
36
+ if (!Array.isArray(content))
37
+ return [];
38
+ return content.map(record).filter((block) => block.type === 'tool_result');
39
+ }
40
+ /**
41
+ * Claude Code's documented stream-json mode is bidirectional: the host sends
42
+ * user/control messages over stdin and receives structured events over stdout.
43
+ * This deliberately runs the installed Claude binary; it does not reproduce
44
+ * Claude's agent loop or authentication through an SDK.
45
+ */
46
+ export const claudeNativeAdapter = {
47
+ resumeUnavailableReason: claudeResumeUnavailableReason,
48
+ capabilities: {
49
+ modes: ['default'],
50
+ streaming: true,
51
+ tools: true,
52
+ approvals: true,
53
+ questions: true,
54
+ interrupt: true,
55
+ resume: true,
56
+ },
57
+ async start(options, emit) {
58
+ const nativeSessionId = options.resumeSessionId ?? randomUUID();
59
+ let identityConfirmed = false;
60
+ let commandId;
61
+ let turnId;
62
+ let turnStarted = false;
63
+ let closed = false;
64
+ let protocolFailure;
65
+ let initialized = false;
66
+ let interruptedCommandId;
67
+ let pendingInterrupt;
68
+ let resolveInitialized;
69
+ let rejectInitialized;
70
+ const pendingCommands = new Map();
71
+ const pendingRequests = new Map();
72
+ const activeTools = new Set();
73
+ const publish = (event) => emit({ commandId, turnId, ...event });
74
+ const finishTurn = (data = {}) => {
75
+ if (!turnStarted && !commandId)
76
+ return;
77
+ publish({
78
+ type: 'turn.completed',
79
+ status: interruptedCommandId !== undefined && interruptedCommandId === commandId
80
+ ? 'interrupted'
81
+ : data.isError === true
82
+ ? 'failed'
83
+ : data.subtype === 'interrupted'
84
+ ? 'interrupted'
85
+ : 'completed',
86
+ data,
87
+ });
88
+ turnId = undefined;
89
+ interruptedCommandId = undefined;
90
+ turnStarted = false;
91
+ commandId = undefined;
92
+ activeTools.clear();
93
+ };
94
+ const startTurn = (nativeId) => {
95
+ if (turnStarted)
96
+ return;
97
+ turnStarted = true;
98
+ turnId = nativeId;
99
+ publish({ type: 'turn.started', nativeId });
100
+ };
101
+ let process;
102
+ const failStartup = (error) => {
103
+ if (protocolFailure)
104
+ return;
105
+ protocolFailure = error;
106
+ if (!initialized)
107
+ rejectInitialized?.(error);
108
+ publish({ type: 'error', status: 'failed', text: error.message });
109
+ };
110
+ const onMessage = (message) => {
111
+ if (protocolFailure)
112
+ return;
113
+ // Resume startup hooks use a temporary process session before loading the
114
+ // saved conversation. Only conversation events bind its native identity.
115
+ const conversationEvent = ['user', 'assistant', 'stream_event', 'result', 'control_request'].includes(String(message.type)) ||
116
+ (message.type === 'system' && message.subtype === 'init');
117
+ const sessionId = conversationEvent && typeof message.session_id === 'string'
118
+ ? message.session_id
119
+ : undefined;
120
+ if (sessionId) {
121
+ if (nativeSessionId !== sessionId) {
122
+ failStartup(new Error('Claude reported a different native session identity'));
123
+ process.child.kill();
124
+ return;
125
+ }
126
+ if (!identityConfirmed) {
127
+ identityConfirmed = true;
128
+ publish({
129
+ type: 'session.started',
130
+ nativeId: nativeSessionId,
131
+ data: { identityConfirmed: true },
132
+ });
133
+ }
134
+ }
135
+ if (message.type === 'control_response') {
136
+ const response = record(message.response);
137
+ if (pendingInterrupt && response.request_id === pendingInterrupt.requestId) {
138
+ const pending = pendingInterrupt;
139
+ pendingInterrupt = undefined;
140
+ clearTimeout(pending.timer);
141
+ if (response.subtype === 'success') {
142
+ // This CLI reports an interrupted result as success. Only its native
143
+ // control acknowledgement for the still-active turn authorizes the mapping.
144
+ if (commandId === pending.commandId)
145
+ interruptedCommandId = pending.commandId;
146
+ pending.resolve();
147
+ }
148
+ else {
149
+ pending.reject(new Error('Claude rejected the interrupt request'));
150
+ }
151
+ return;
152
+ }
153
+ if (response.request_id === 'farmslot-initialize') {
154
+ if (response.subtype === 'success') {
155
+ initialized = true;
156
+ resolveInitialized?.();
157
+ }
158
+ else {
159
+ rejectInitialized?.(new Error('Claude rejected stream-json initialization'));
160
+ }
161
+ }
162
+ return;
163
+ }
164
+ if (message.type === 'control_request') {
165
+ const requestId = typeof message.request_id === 'string' ? message.request_id : undefined;
166
+ if (!requestId) {
167
+ publish({ type: 'error', text: 'Claude sent a control request without an id' });
168
+ return;
169
+ }
170
+ const request = record(message.request);
171
+ const subtype = request.subtype;
172
+ if (subtype === 'can_use_tool') {
173
+ pendingRequests.set(requestId, request);
174
+ const toolName = typeof request.tool_name === 'string' ? request.tool_name : undefined;
175
+ const input = record(request.input);
176
+ const toolUseId = typeof request.tool_use_id === 'string' ? request.tool_use_id : undefined;
177
+ if (toolName === 'AskUserQuestion') {
178
+ const questions = Array.isArray(input.questions)
179
+ ? input.questions.map(record).flatMap((question) => typeof question.question === 'string'
180
+ ? [
181
+ {
182
+ // Claude's native handler indexes answers by the question text.
183
+ id: question.question,
184
+ prompt: question.question,
185
+ options: Array.isArray(question.options)
186
+ ? question.options.map(record).flatMap((option) => typeof option.label === 'string'
187
+ ? [
188
+ {
189
+ label: option.label,
190
+ ...(typeof option.description === 'string'
191
+ ? { description: option.description }
192
+ : {}),
193
+ },
194
+ ]
195
+ : [])
196
+ : [],
197
+ multiSelect: question.multiSelect === true,
198
+ },
199
+ ]
200
+ : [])
201
+ : [];
202
+ publish({
203
+ type: 'question.requested',
204
+ nativeId: requestId,
205
+ request: { id: requestId, title: 'Answer runner questions', questions },
206
+ data: { toolName, input, toolUseId },
207
+ });
208
+ }
209
+ else {
210
+ publish({
211
+ type: 'approval.requested',
212
+ nativeId: requestId,
213
+ request: {
214
+ id: requestId,
215
+ title: 'Allow runner action?',
216
+ detail: typeof input.command === 'string' ? input.command : toolName,
217
+ },
218
+ data: { toolName, input, toolUseId },
219
+ });
220
+ }
221
+ return;
222
+ }
223
+ // A host must not grant control operations it has not implemented.
224
+ process.write({
225
+ type: 'control_response',
226
+ response: {
227
+ subtype: 'error',
228
+ request_id: requestId,
229
+ error: `Unsupported Claude control request: ${String(subtype)}`,
230
+ },
231
+ });
232
+ publish({ type: 'error', text: `Unsupported Claude control request: ${String(subtype)}` });
233
+ return;
234
+ }
235
+ if (message.type === 'user') {
236
+ const replayedText = textContent(record(message.message).content);
237
+ if (replayedText) {
238
+ const acceptedCommandId = pendingCommands.get(replayedText);
239
+ if (acceptedCommandId) {
240
+ pendingCommands.delete(replayedText);
241
+ commandId = acceptedCommandId;
242
+ publish({ type: 'command.accepted', commandId: acceptedCommandId, text: replayedText });
243
+ }
244
+ }
245
+ for (const result of toolResultBlocks(record(message.message).content)) {
246
+ const toolId = typeof result.tool_use_id === 'string' ? result.tool_use_id : undefined;
247
+ if (toolId && activeTools.delete(toolId)) {
248
+ publish({
249
+ type: 'tool.completed',
250
+ nativeId: toolId,
251
+ tool: {
252
+ name: 'Claude tool',
253
+ output: result.content,
254
+ status: result.is_error === true ? 'failed' : 'completed',
255
+ },
256
+ data: result,
257
+ });
258
+ }
259
+ }
260
+ return;
261
+ }
262
+ if (message.type === 'stream_event') {
263
+ const event = record(message.event);
264
+ if (event.type === 'message_start') {
265
+ const eventMessage = record(event.message);
266
+ startTurn(typeof eventMessage.id === 'string' ? eventMessage.id : undefined);
267
+ }
268
+ if (event.type === 'content_block_delta') {
269
+ const delta = record(event.delta);
270
+ if (delta.type === 'text_delta' && typeof delta.text === 'string') {
271
+ startTurn();
272
+ publish({
273
+ type: 'text.delta',
274
+ nativeId: typeof event.index === 'number' ? String(event.index) : undefined,
275
+ text: delta.text,
276
+ });
277
+ }
278
+ }
279
+ return;
280
+ }
281
+ if (message.type === 'assistant') {
282
+ startTurn();
283
+ const assistant = record(message.message);
284
+ for (const tool of toolUseBlocks(assistant.content)) {
285
+ const toolId = typeof tool.id === 'string' ? tool.id : undefined;
286
+ if (toolId && !activeTools.has(toolId)) {
287
+ activeTools.add(toolId);
288
+ publish({
289
+ type: 'tool.started',
290
+ nativeId: toolId,
291
+ tool: {
292
+ name: typeof tool.name === 'string' ? tool.name : 'Claude tool',
293
+ input: tool.input,
294
+ },
295
+ data: tool,
296
+ });
297
+ }
298
+ }
299
+ return;
300
+ }
301
+ if (message.type === 'result') {
302
+ if (message.is_error === true) {
303
+ const errors = Array.isArray(message.errors)
304
+ ? message.errors.filter((error) => typeof error === 'string')
305
+ : [];
306
+ publish({
307
+ type: 'error',
308
+ text: (typeof message.result === 'string' && message.result) ||
309
+ errors.join('\n') ||
310
+ 'Native runner reported a failed turn',
311
+ data: { subtype: message.subtype },
312
+ });
313
+ }
314
+ finishTurn({ subtype: message.subtype, isError: message.is_error });
315
+ }
316
+ };
317
+ process = new JsonLineProcess(options.executable, [
318
+ '--print',
319
+ '--input-format',
320
+ 'stream-json',
321
+ '--output-format',
322
+ 'stream-json',
323
+ '--verbose',
324
+ '--include-partial-messages',
325
+ '--replay-user-messages',
326
+ '--permission-prompt-tool',
327
+ 'stdio',
328
+ ...(options.model ? ['--model', options.model] : []),
329
+ ...(options.resumeSessionId
330
+ ? ['--resume', options.resumeSessionId]
331
+ : ['--session-id', nativeSessionId]),
332
+ ], options, onMessage, (error, processStopped) => {
333
+ if (pendingInterrupt) {
334
+ clearTimeout(pendingInterrupt.timer);
335
+ pendingInterrupt.reject(error ?? new Error('Claude closed before interrupt acknowledgement'));
336
+ pendingInterrupt = undefined;
337
+ }
338
+ if (closed)
339
+ return;
340
+ const failure = protocolFailure ??
341
+ (error || !initialized
342
+ ? (error ?? new Error('Claude closed before initialization'))
343
+ : undefined);
344
+ if (!initialized)
345
+ rejectInitialized?.(failure ?? new Error('Claude closed before initialization'));
346
+ closed = true;
347
+ publish({
348
+ type: 'session.closed',
349
+ ...(failure ? { status: 'failed' } : {}),
350
+ data: { processStopped, ...(failure ? { error: failure.message } : {}) },
351
+ });
352
+ });
353
+ try {
354
+ await new Promise((resolve, reject) => {
355
+ resolveInitialized = resolve;
356
+ rejectInitialized = reject;
357
+ const timeout = setTimeout(() => reject(new Error('Claude stream-json initialization timed out')), 30_000);
358
+ resolveInitialized = () => {
359
+ clearTimeout(timeout);
360
+ resolve();
361
+ };
362
+ rejectInitialized = (error) => {
363
+ clearTimeout(timeout);
364
+ reject(error);
365
+ };
366
+ process.write({
367
+ type: 'control_request',
368
+ request_id: 'farmslot-initialize',
369
+ request: { subtype: 'initialize', hooks: null },
370
+ });
371
+ });
372
+ if (!nativeSessionId)
373
+ throw new Error('Claude did not provide a native session id during initialization');
374
+ if (options.resumeSessionId && nativeSessionId !== options.resumeSessionId) {
375
+ throw new Error('Claude resumed a different native session');
376
+ }
377
+ if (!identityConfirmed)
378
+ publish({
379
+ type: 'session.started',
380
+ nativeId: nativeSessionId,
381
+ data: { identityConfirmed: false },
382
+ });
383
+ }
384
+ catch (error) {
385
+ await process.close();
386
+ throw error;
387
+ }
388
+ return {
389
+ nativeSessionId,
390
+ async send(text, id) {
391
+ if (!text)
392
+ throw new Error('Claude prompt must not be empty');
393
+ // Correlation is assigned before writing. Native replay may arrive after
394
+ // tool requests and streamed output, so send must not wait for that replay.
395
+ commandId = id;
396
+ pendingCommands.set(text, id);
397
+ try {
398
+ process.write({ type: 'user', message: { role: 'user', content: text } });
399
+ }
400
+ catch (error) {
401
+ pendingCommands.delete(text);
402
+ commandId = undefined;
403
+ throw error;
404
+ }
405
+ },
406
+ async respond(requestId, response) {
407
+ const request = pendingRequests.get(requestId);
408
+ if (!request)
409
+ throw new Error('Native request is stale or belongs to another session');
410
+ const toolName = typeof request.tool_name === 'string' ? request.tool_name : undefined;
411
+ if (toolName === 'AskUserQuestion') {
412
+ if (!response.answers)
413
+ throw new Error('Question response requires answers');
414
+ const input = record(request.input);
415
+ const answers = {};
416
+ for (const rawQuestion of Array.isArray(input.questions) ? input.questions : []) {
417
+ const question = record(rawQuestion);
418
+ if (typeof question.question !== 'string')
419
+ continue;
420
+ const selected = response.answers[question.question];
421
+ if (!selected || selected.length === 0)
422
+ continue;
423
+ answers[question.question] = question.multiSelect === true ? selected : selected[0];
424
+ }
425
+ process.write({
426
+ type: 'control_response',
427
+ response: {
428
+ subtype: 'success',
429
+ request_id: requestId,
430
+ response: { behavior: 'allow', updatedInput: { ...input, answers } },
431
+ },
432
+ });
433
+ }
434
+ else {
435
+ if (!response.decision)
436
+ throw new Error('Approval response requires a decision');
437
+ process.write({
438
+ type: 'control_response',
439
+ response: {
440
+ subtype: 'success',
441
+ request_id: requestId,
442
+ response: response.decision === 'approve'
443
+ ? { behavior: 'allow', updatedInput: request.input }
444
+ : { behavior: 'deny', message: 'User declined tool execution.' },
445
+ },
446
+ });
447
+ }
448
+ pendingRequests.delete(requestId);
449
+ publish({
450
+ type: 'approval.resolved',
451
+ nativeId: requestId,
452
+ data: { decision: response.decision, answers: response.answers },
453
+ });
454
+ },
455
+ async interrupt() {
456
+ if (!commandId)
457
+ throw new Error('No active native turn to interrupt');
458
+ if (pendingInterrupt)
459
+ throw new Error('Claude interrupt acknowledgement is pending');
460
+ const interruptedId = commandId;
461
+ await new Promise((resolve, reject) => {
462
+ const requestId = `farmslot-interrupt:${interruptedId}`;
463
+ const timer = setTimeout(() => {
464
+ pendingInterrupt = undefined;
465
+ reject(new Error('Claude interrupt acknowledgement timed out'));
466
+ }, 30_000);
467
+ pendingInterrupt = { requestId, commandId: interruptedId, resolve, reject, timer };
468
+ try {
469
+ process.write({
470
+ type: 'control_request',
471
+ request_id: requestId,
472
+ request: { subtype: 'interrupt' },
473
+ });
474
+ }
475
+ catch (error) {
476
+ clearTimeout(timer);
477
+ pendingInterrupt = undefined;
478
+ reject(error);
479
+ }
480
+ });
481
+ },
482
+ async close() {
483
+ if (closed)
484
+ return;
485
+ await process.close();
486
+ },
487
+ };
488
+ },
489
+ };
490
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/native/claude.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { NativeSessionCreateParams, NativeSessionEnsureParams, NativeSessionInfo, NativeSessionReadResult, NativeSessionResponse, NativeSessionSendResult } from '@farmslot/protocol';
2
+ /** The same client is usable by gateway and execution-node services. */
3
+ export declare class NativeSessionClient {
4
+ readonly executionNodeId: string;
5
+ readonly root: string;
6
+ private starting?;
7
+ constructor(root?: string, executionNodeId?: string);
8
+ private host;
9
+ private assertHostNode;
10
+ private start;
11
+ private call;
12
+ create(owner: string, params: NativeSessionCreateParams): Promise<NativeSessionInfo>;
13
+ ensure(owner: string, params: NativeSessionEnsureParams): Promise<NativeSessionInfo>;
14
+ list(owner: string): Promise<NativeSessionInfo[]>;
15
+ read(owner: string, id: string, after?: number, limit?: number): Promise<NativeSessionReadResult>;
16
+ send(owner: string, id: string, commandId: string, text: string): Promise<NativeSessionSendResult>;
17
+ respond(owner: string, id: string, requestId: string, response: NativeSessionResponse): Promise<void>;
18
+ interrupt(owner: string, id: string): Promise<void>;
19
+ close(owner: string, id: string): Promise<void>;
20
+ }
21
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/native/client.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,yBAAyB,EACzB,yBAAyB,EACzB,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,uBAAuB,EACxB,MAAM,oBAAoB,CAAC;AAM5B,wEAAwE;AACxE,qBAAa,mBAAmB;IAK5B,QAAQ,CAAC,eAAe;IAJ1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,CAAwB;gBAEvC,IAAI,SAAmF,EAC9E,eAAe,SAAU;YAItB,IAAI;IAiBlB,OAAO,CAAC,cAAc;YAIR,KAAK;YAmCL,IAAI;IAQlB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,yBAAyB;IAKvD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,yBAAyB;IAKvD,IAAI,CAAC,KAAK,EAAE,MAAM;IAGlB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;IAG9D,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAG/D,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,qBAAqB;IAGrF,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAGnC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;CAGhC"}
@@ -0,0 +1,106 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { closeSync, existsSync, openSync } from 'node:fs';
3
+ import { join, resolve } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { farmslotHome } from '@farmslot/protocol/node/farmslot-home';
6
+ import { requestHost } from './ipc.js';
7
+ import { alive, privateDirectory, readJson } from './storage.js';
8
+ /** The same client is usable by gateway and execution-node services. */
9
+ export class NativeSessionClient {
10
+ constructor(root = process.env.FARMSLOT_NATIVE_STATE_DIR ?? join(farmslotHome(), 'native-sessions'), executionNodeId = 'local') {
11
+ this.executionNodeId = executionNodeId;
12
+ this.root = resolve(root);
13
+ }
14
+ async host() {
15
+ privateDirectory(this.root);
16
+ const path = join(this.root, 'host.json');
17
+ if (existsSync(path)) {
18
+ const host = readJson(path);
19
+ this.assertHostNode(host);
20
+ if (alive(host.pid) && existsSync(join(this.root, 'ready.json')) && existsSync(host.socket))
21
+ return host;
22
+ }
23
+ if (this.starting)
24
+ return this.starting;
25
+ this.starting = this.start();
26
+ try {
27
+ return await this.starting;
28
+ }
29
+ finally {
30
+ this.starting = undefined;
31
+ }
32
+ }
33
+ assertHostNode(host) {
34
+ if ((host.executionNodeId ?? 'local') !== this.executionNodeId)
35
+ throw new Error('Native state directory belongs to another execution node');
36
+ }
37
+ async start() {
38
+ privateDirectory(this.root);
39
+ const source = import.meta.url.endsWith('.ts');
40
+ const entry = fileURLToPath(new URL(`./supervisor.${source ? 'ts' : 'js'}`, import.meta.url));
41
+ const args = source
42
+ ? ['--import', import.meta.resolve('tsx'), entry, this.root]
43
+ : [entry, this.root];
44
+ const log = openSync(join(this.root, 'host.log'), 'a', 0o600);
45
+ const child = spawn(process.execPath, args, {
46
+ detached: true,
47
+ stdio: ['ignore', log, log],
48
+ env: { ...process.env, FARMSLOT_NATIVE_EXECUTION_NODE_ID: this.executionNodeId },
49
+ });
50
+ closeSync(log);
51
+ child.unref();
52
+ let spawnError;
53
+ child.on('error', (error) => {
54
+ spawnError = error;
55
+ });
56
+ const deadline = Date.now() + 10_000;
57
+ while (Date.now() < deadline) {
58
+ if (spawnError)
59
+ throw spawnError;
60
+ const path = join(this.root, 'host.json');
61
+ if (existsSync(path)) {
62
+ const host = readJson(path);
63
+ this.assertHostNode(host);
64
+ if (alive(host.pid) && existsSync(join(this.root, 'ready.json')) && existsSync(host.socket))
65
+ return host;
66
+ }
67
+ await new Promise((resolve) => setTimeout(resolve, 25));
68
+ }
69
+ throw new Error(`Native host unavailable; inspect ${join(this.root, 'host.log')}. No command was retried.`);
70
+ }
71
+ async call(request) {
72
+ const host = await this.host();
73
+ if (request.method === 'ensure' && !host.supportsEnsure)
74
+ throw new Error('Native host upgrade required for idempotent creation; existing sessions remain available');
75
+ return requestHost(host, request);
76
+ }
77
+ create(owner, params) {
78
+ if (params.executionNodeId !== undefined && params.executionNodeId !== this.executionNodeId)
79
+ throw new Error('Native session targets another execution node');
80
+ return this.call({ method: 'create', owner, params });
81
+ }
82
+ ensure(owner, params) {
83
+ if (params.executionNodeId !== undefined && params.executionNodeId !== this.executionNodeId)
84
+ throw new Error('Native session targets another execution node');
85
+ return this.call({ method: 'ensure', owner, params });
86
+ }
87
+ list(owner) {
88
+ return this.call({ method: 'list', owner });
89
+ }
90
+ read(owner, id, after, limit) {
91
+ return this.call({ method: 'read', owner, id, after, limit });
92
+ }
93
+ send(owner, id, commandId, text) {
94
+ return this.call({ method: 'send', owner, id, commandId, text });
95
+ }
96
+ respond(owner, id, requestId, response) {
97
+ return this.call({ method: 'respond', owner, id, requestId, response });
98
+ }
99
+ interrupt(owner, id) {
100
+ return this.call({ method: 'interrupt', owner, id });
101
+ }
102
+ close(owner, id) {
103
+ return this.call({ method: 'close', owner, id });
104
+ }
105
+ }
106
+ //# sourceMappingURL=client.js.map