@jini-ai/daemon 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 (142) hide show
  1. package/LICENSE +201 -0
  2. package/dist/agent-executor.d.ts +458 -0
  3. package/dist/agent-executor.d.ts.map +1 -0
  4. package/dist/agent-executor.js +1277 -0
  5. package/dist/agent-executor.js.map +1 -0
  6. package/dist/artifacts/index.d.ts +14 -0
  7. package/dist/artifacts/index.d.ts.map +1 -0
  8. package/dist/artifacts/index.js +14 -0
  9. package/dist/artifacts/index.js.map +1 -0
  10. package/dist/artifacts/manifest.d.ts +90 -0
  11. package/dist/artifacts/manifest.d.ts.map +1 -0
  12. package/dist/artifacts/manifest.js +229 -0
  13. package/dist/artifacts/manifest.js.map +1 -0
  14. package/dist/artifacts/publication-guard.d.ts +28 -0
  15. package/dist/artifacts/publication-guard.d.ts.map +1 -0
  16. package/dist/artifacts/publication-guard.js +77 -0
  17. package/dist/artifacts/publication-guard.js.map +1 -0
  18. package/dist/artifacts/runtime-compat.d.ts +37 -0
  19. package/dist/artifacts/runtime-compat.d.ts.map +1 -0
  20. package/dist/artifacts/runtime-compat.js +33 -0
  21. package/dist/artifacts/runtime-compat.js.map +1 -0
  22. package/dist/artifacts/store.d.ts +85 -0
  23. package/dist/artifacts/store.d.ts.map +1 -0
  24. package/dist/artifacts/store.js +92 -0
  25. package/dist/artifacts/store.js.map +1 -0
  26. package/dist/artifacts/stub-guard.d.ts +73 -0
  27. package/dist/artifacts/stub-guard.d.ts.map +1 -0
  28. package/dist/artifacts/stub-guard.js +198 -0
  29. package/dist/artifacts/stub-guard.js.map +1 -0
  30. package/dist/artifacts/text-suppression.d.ts +68 -0
  31. package/dist/artifacts/text-suppression.d.ts.map +1 -0
  32. package/dist/artifacts/text-suppression.js +184 -0
  33. package/dist/artifacts/text-suppression.js.map +1 -0
  34. package/dist/close-status.d.ts +86 -0
  35. package/dist/close-status.d.ts.map +1 -0
  36. package/dist/close-status.js +91 -0
  37. package/dist/close-status.js.map +1 -0
  38. package/dist/continuation/continuation-transport.d.ts +41 -0
  39. package/dist/continuation/continuation-transport.d.ts.map +1 -0
  40. package/dist/continuation/continuation-transport.js +18 -0
  41. package/dist/continuation/continuation-transport.js.map +1 -0
  42. package/dist/continuation/index.d.ts +4 -0
  43. package/dist/continuation/index.d.ts.map +1 -0
  44. package/dist/continuation/index.js +4 -0
  45. package/dist/continuation/index.js.map +1 -0
  46. package/dist/continuation/journal.d.ts +37 -0
  47. package/dist/continuation/journal.d.ts.map +1 -0
  48. package/dist/continuation/journal.js +23 -0
  49. package/dist/continuation/journal.js.map +1 -0
  50. package/dist/continuation/run-start-handler.d.ts +75 -0
  51. package/dist/continuation/run-start-handler.d.ts.map +1 -0
  52. package/dist/continuation/run-start-handler.js +32 -0
  53. package/dist/continuation/run-start-handler.js.map +1 -0
  54. package/dist/delegated-tool-bridge.d.ts +53 -0
  55. package/dist/delegated-tool-bridge.d.ts.map +1 -0
  56. package/dist/delegated-tool-bridge.js +92 -0
  57. package/dist/delegated-tool-bridge.js.map +1 -0
  58. package/dist/event-log.d.ts +134 -0
  59. package/dist/event-log.d.ts.map +1 -0
  60. package/dist/event-log.js +108 -0
  61. package/dist/event-log.js.map +1 -0
  62. package/dist/frontend-capability-tools.d.ts +102 -0
  63. package/dist/frontend-capability-tools.d.ts.map +1 -0
  64. package/dist/frontend-capability-tools.js +68 -0
  65. package/dist/frontend-capability-tools.js.map +1 -0
  66. package/dist/frontend-session-registry.d.ts +127 -0
  67. package/dist/frontend-session-registry.d.ts.map +1 -0
  68. package/dist/frontend-session-registry.js +180 -0
  69. package/dist/frontend-session-registry.js.map +1 -0
  70. package/dist/index.d.ts +38 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +38 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/legacy-data-migration.d.ts +104 -0
  75. package/dist/legacy-data-migration.d.ts.map +1 -0
  76. package/dist/legacy-data-migration.js +239 -0
  77. package/dist/legacy-data-migration.js.map +1 -0
  78. package/dist/routines/index.d.ts +12 -0
  79. package/dist/routines/index.d.ts.map +1 -0
  80. package/dist/routines/index.js +12 -0
  81. package/dist/routines/index.js.map +1 -0
  82. package/dist/routines/routine-store.d.ts +77 -0
  83. package/dist/routines/routine-store.d.ts.map +1 -0
  84. package/dist/routines/routine-store.js +162 -0
  85. package/dist/routines/routine-store.js.map +1 -0
  86. package/dist/routines/schedule.d.ts +72 -0
  87. package/dist/routines/schedule.d.ts.map +1 -0
  88. package/dist/routines/schedule.js +263 -0
  89. package/dist/routines/schedule.js.map +1 -0
  90. package/dist/routines/scheduler.d.ts +34 -0
  91. package/dist/routines/scheduler.d.ts.map +1 -0
  92. package/dist/routines/scheduler.js +330 -0
  93. package/dist/routines/scheduler.js.map +1 -0
  94. package/dist/routines/types.d.ts +131 -0
  95. package/dist/routines/types.d.ts.map +1 -0
  96. package/dist/routines/types.js +9 -0
  97. package/dist/routines/types.js.map +1 -0
  98. package/dist/run/core/failure-taxonomy.d.ts +27 -0
  99. package/dist/run/core/failure-taxonomy.d.ts.map +1 -0
  100. package/dist/run/core/failure-taxonomy.js +16 -0
  101. package/dist/run/core/failure-taxonomy.js.map +1 -0
  102. package/dist/run/core/index.d.ts +5 -0
  103. package/dist/run/core/index.d.ts.map +1 -0
  104. package/dist/run/core/index.js +5 -0
  105. package/dist/run/core/index.js.map +1 -0
  106. package/dist/run/core/result.d.ts +25 -0
  107. package/dist/run/core/result.d.ts.map +1 -0
  108. package/dist/run/core/result.js +52 -0
  109. package/dist/run/core/result.js.map +1 -0
  110. package/dist/run/core/retry.d.ts +106 -0
  111. package/dist/run/core/retry.d.ts.map +1 -0
  112. package/dist/run/core/retry.js +210 -0
  113. package/dist/run/core/retry.js.map +1 -0
  114. package/dist/run/diagnostics/diagnostics.d.ts +86 -0
  115. package/dist/run/diagnostics/diagnostics.d.ts.map +1 -0
  116. package/dist/run/diagnostics/diagnostics.js +211 -0
  117. package/dist/run/diagnostics/diagnostics.js.map +1 -0
  118. package/dist/run/diagnostics/index.d.ts +3 -0
  119. package/dist/run/diagnostics/index.d.ts.map +1 -0
  120. package/dist/run/diagnostics/index.js +3 -0
  121. package/dist/run/diagnostics/index.js.map +1 -0
  122. package/dist/run/index.d.ts +16 -0
  123. package/dist/run/index.d.ts.map +1 -0
  124. package/dist/run/index.js +16 -0
  125. package/dist/run/index.js.map +1 -0
  126. package/dist/run-lifecycle.d.ts +118 -0
  127. package/dist/run-lifecycle.d.ts.map +1 -0
  128. package/dist/run-lifecycle.js +451 -0
  129. package/dist/run-lifecycle.js.map +1 -0
  130. package/dist/terminal-session.d.ts +139 -0
  131. package/dist/terminal-session.d.ts.map +1 -0
  132. package/dist/terminal-session.js +316 -0
  133. package/dist/terminal-session.js.map +1 -0
  134. package/dist/tokens.d.ts +9 -0
  135. package/dist/tokens.d.ts.map +1 -0
  136. package/dist/tokens.js +19 -0
  137. package/dist/tokens.js.map +1 -0
  138. package/dist/tool-executor.d.ts +97 -0
  139. package/dist/tool-executor.d.ts.map +1 -0
  140. package/dist/tool-executor.js +198 -0
  141. package/dist/tool-executor.js.map +1 -0
  142. package/package.json +51 -0
@@ -0,0 +1,451 @@
1
+ /**
2
+ * `RunLifecycle` — start/stream/cancel/resume a run keyed on an opaque
3
+ * `contextRef` (extraction-plan §2.1: runs key on an opaque `contextRef`,
4
+ * never a product-record identifier), generalized from OD's `design.runs` service
5
+ * (`apps/daemon/src/runtimes/runs.ts` + the terminal-decision half of
6
+ * `apps/daemon/src/runtimes/start-chat-run.ts`, `arch/server-startserver-endgame`
7
+ * branch — see `source-map.md` for exact line citations).
8
+ *
9
+ * Scope boundary: this module owns the run *state machine* and its event
10
+ * log — create, transition, emit, replay, cancellation-intent propagation,
11
+ * idempotent start/finish, resume. It does not spawn or signal a subprocess;
12
+ * that is `@jini-ai/agent-runtime`'s job (extraction-plan task 7). A driver
13
+ * (today: this package's tests; later: agent-runtime) calls `emit()` for
14
+ * agent/stdout/stderr/error events, observes cancellation via
15
+ * `onCancelRequested`, and calls `finish()` once it knows the real outcome.
16
+ */
17
+ import { randomUUID } from 'node:crypto';
18
+ import { RUN_PROTOCOL_VERSION, isTerminalRunState } from '@jini-ai/protocol';
19
+ import { createInactivityWatchdog } from './close-status.js';
20
+ /** Vocabulary-firewall bridge: `RunState` uses `'cancelled'` (extraction-plan §12 C5's own cited canary), `RunEndPayload.status` uses `'canceled'`. Both live in `@jini-ai/protocol`, which is out of scope for this task — bridged here rather than fixed upstream. */
21
+ const TERMINAL_OUTCOME_TO_END_STATUS = {
22
+ succeeded: 'succeeded',
23
+ failed: 'failed',
24
+ cancelled: 'canceled',
25
+ };
26
+ function toPublicStatus(record) {
27
+ const status = {
28
+ id: record.status.id,
29
+ state: record.status.state,
30
+ startedAt: record.status.startedAt,
31
+ updatedAt: record.status.updatedAt,
32
+ };
33
+ if (record.status.endedAt !== undefined) {
34
+ return { ...status, endedAt: record.status.endedAt };
35
+ }
36
+ return status;
37
+ }
38
+ /**
39
+ * Bridges `@jini-ai/daemon`'s own `EventLogEntry` (`{id, event, data, recordedAt}`) to
40
+ * `@jini-ai/protocol`'s canonical `RunEvent` envelope. `EventLogEntry` carries no `runId` of its
41
+ * own (the log is already scoped by the `runId` parameter every `EventLog` method takes), so
42
+ * this is the one place that stamps it onto the outgoing envelope.
43
+ */
44
+ function toRunEvent(runId, entry) {
45
+ return {
46
+ runId,
47
+ eventId: `${runId}:${entry.id}`,
48
+ opaqueCursor: entry.id,
49
+ protocolVersion: RUN_PROTOCOL_VERSION,
50
+ ts: entry.recordedAt,
51
+ kind: entry.event,
52
+ payload: entry.data,
53
+ durability: 'durable',
54
+ };
55
+ }
56
+ function isRecord(value) {
57
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
58
+ }
59
+ function terminalStateFromEndEntry(entry) {
60
+ if (!isRecord(entry.data))
61
+ return { state: 'failed', resumable: false };
62
+ const status = entry.data.status;
63
+ const state = status === 'succeeded' ? 'succeeded' : status === 'canceled' ? 'cancelled' : 'failed';
64
+ return { state, resumable: entry.data.resumable === true };
65
+ }
66
+ /**
67
+ * Creates the in-process `RunLifecycle` reference implementation.
68
+ *
69
+ * @param input.eventLog - The durable `EventLog` port this lifecycle appends to and replays from.
70
+ * @returns A `RunLifecycle` backed by an in-memory run registry plus the injected `EventLog`.
71
+ * @complexity Per-call complexities documented on each method; the registry itself is a `Map` keyed by `runId` (O(1) lookup).
72
+ * @overallScore 100/100
73
+ */
74
+ export function createRunLifecycle(input) {
75
+ const { eventLog } = input;
76
+ const runs = new Map();
77
+ const idempotencyIndex = new Map();
78
+ let hydration = null;
79
+ function requireRun(runId) {
80
+ const record = runs.get(runId);
81
+ if (!record) {
82
+ throw new Error(`RunLifecycle: unknown run "${runId}"`);
83
+ }
84
+ return record;
85
+ }
86
+ /**
87
+ * A subscriber is a transport-owned callback (e.g. an SSE writer) outside this module's
88
+ * control. One subscriber throwing (a dead socket, a broken client) must never abort the
89
+ * fan-out to the others, nor propagate out through `emit()`/`finish()` into driver code that
90
+ * has nothing to do with that transport — see CR-R1 in
91
+ * `ADS-memory/reports/code-review/CR-backend-coverage-push-2026-07-20.md`.
92
+ */
93
+ function notifySubscribers(record, event) {
94
+ for (const subscriber of record.subscribers) {
95
+ try {
96
+ subscriber(event);
97
+ }
98
+ catch {
99
+ // Isolated by design — see the function doc above.
100
+ }
101
+ }
102
+ }
103
+ async function appendEvent(runId, record, event, data) {
104
+ const entry = await eventLog.append({ runId, event, data });
105
+ const runEvent = toRunEvent(runId, entry);
106
+ notifySubscribers(record, runEvent);
107
+ return runEvent;
108
+ }
109
+ function resolveTerminalWaiters(record) {
110
+ const waiters = record.terminalWaiters.splice(0, record.terminalWaiters.length);
111
+ const status = toPublicStatus(record);
112
+ for (const resolve of waiters) {
113
+ resolve(status);
114
+ }
115
+ }
116
+ /**
117
+ * Fires when a run's inactivity watchdog times out with no intervening
118
+ * `emit()`/`finish()`. Classified as a resumable failure (`code: null,
119
+ * signal: null`), mirroring OD's own timeout/inactivity classification
120
+ * (`isResumableFailure` in the researched `run-failure-classification.ts`
121
+ * treats timeout/inactivity as one of only two resumable categories).
122
+ * A run that already reached a terminal state before the timer fired
123
+ * (a normal race with `finish()`) is left untouched.
124
+ */
125
+ async function handleInactivityTimeout(runId) {
126
+ const record = runs.get(runId);
127
+ if (!record || isTerminalRunState(record.status.state)) {
128
+ return;
129
+ }
130
+ try {
131
+ await lifecycle.finish({ runId, status: 'failed', code: null, signal: null, resumable: true });
132
+ }
133
+ catch (error) {
134
+ const context = { source: 'inactivity-timeout', runId, error };
135
+ try {
136
+ if (input.onInternalError) {
137
+ input.onInternalError(context);
138
+ }
139
+ else {
140
+ // eslint-disable-next-line no-console
141
+ console.error(`[@jini-ai/daemon] internal error (inactivity-timeout, runId=${runId})`, error);
142
+ }
143
+ }
144
+ catch (sinkError) {
145
+ // A diagnostic sink must not turn a contained timer failure into another unhandled
146
+ // rejection.
147
+ // eslint-disable-next-line no-console
148
+ console.error(`[@jini-ai/daemon] internal error sink failed (inactivity-timeout, runId=${runId})`, sinkError);
149
+ }
150
+ }
151
+ }
152
+ const lifecycle = {
153
+ async rehydrate() {
154
+ if (hydration)
155
+ return hydration;
156
+ hydration = (async () => {
157
+ const rehydratedNonTerminalRunIds = [];
158
+ for (const runId of await eventLog.listRunIds()) {
159
+ if (runs.has(runId))
160
+ continue;
161
+ const replay = await eventLog.replay(runId, null);
162
+ if (replay.kind !== 'ok' || replay.entries.length === 0)
163
+ continue;
164
+ const entries = replay.entries;
165
+ const startEntry = entries.find((entry) => entry.event === 'start');
166
+ const endEntry = [...entries].reverse().find((entry) => entry.event === 'end');
167
+ const startData = startEntry && isRecord(startEntry.data) ? startEntry.data : null;
168
+ const firstEntry = entries[0];
169
+ const lastEntry = entries[entries.length - 1];
170
+ const terminal = endEntry === undefined ? null : terminalStateFromEndEntry(endEntry);
171
+ const contextRef = typeof startData?.contextRef === 'string' ? startData.contextRef : undefined;
172
+ const idempotencyKey = typeof startData?.idempotencyKey === 'string' ? startData.idempotencyKey : undefined;
173
+ const record = {
174
+ contextRef,
175
+ status: {
176
+ id: runId,
177
+ state: terminal?.state ?? 'running',
178
+ startedAt: startEntry?.recordedAt ?? firstEntry.recordedAt,
179
+ updatedAt: lastEntry.recordedAt,
180
+ endedAt: endEntry?.recordedAt,
181
+ },
182
+ resumable: terminal?.resumable ?? false,
183
+ cancelRequested: false,
184
+ lastCancelRequest: undefined,
185
+ cancelListeners: new Set(),
186
+ subscribers: new Set(),
187
+ terminalWaiters: [],
188
+ terminalEndEntry: endEntry,
189
+ watchdog: undefined,
190
+ startPromise: undefined,
191
+ finishPromise: undefined,
192
+ };
193
+ runs.set(runId, record);
194
+ if (idempotencyKey !== undefined)
195
+ idempotencyIndex.set(idempotencyKey, runId);
196
+ if (terminal === null)
197
+ rehydratedNonTerminalRunIds.push(runId);
198
+ }
199
+ // A process restart cannot retain an in-memory child process or cancellation listener.
200
+ // Persist an honest terminal outcome instead of advertising an orphaned run as still live.
201
+ for (const runId of rehydratedNonTerminalRunIds) {
202
+ await lifecycle.finish({ runId, status: 'failed', code: null, signal: null, resumable: true });
203
+ }
204
+ })();
205
+ return hydration;
206
+ },
207
+ async start(startInput) {
208
+ if (startInput.idempotencyKey !== undefined) {
209
+ const existingRunId = idempotencyIndex.get(startInput.idempotencyKey);
210
+ if (existingRunId) {
211
+ const existing = requireRun(existingRunId);
212
+ await existing.startPromise;
213
+ return { run: toPublicStatus(existing), started: false };
214
+ }
215
+ }
216
+ const runId = startInput.runId ?? randomUUID();
217
+ if (runs.has(runId)) {
218
+ throw new Error(`RunLifecycle: run "${runId}" already exists`);
219
+ }
220
+ const now = Date.now();
221
+ const record = {
222
+ contextRef: startInput.contextRef,
223
+ status: { id: runId, state: 'running', startedAt: now, updatedAt: now, endedAt: undefined },
224
+ resumable: false,
225
+ cancelRequested: false,
226
+ lastCancelRequest: undefined,
227
+ cancelListeners: new Set(),
228
+ subscribers: new Set(),
229
+ terminalWaiters: [],
230
+ terminalEndEntry: undefined,
231
+ watchdog: undefined,
232
+ startPromise: undefined,
233
+ finishPromise: undefined,
234
+ };
235
+ runs.set(runId, record);
236
+ if (startInput.idempotencyKey !== undefined) {
237
+ idempotencyIndex.set(startInput.idempotencyKey, runId);
238
+ }
239
+ const startPayload = {
240
+ runId,
241
+ contextRef: startInput.contextRef,
242
+ ...(startInput.agentId !== undefined ? { agentId: startInput.agentId } : {}),
243
+ ...(startInput.idempotencyKey !== undefined ? { idempotencyKey: startInput.idempotencyKey } : {}),
244
+ };
245
+ const startPromise = appendEvent(runId, record, 'start', startPayload).then(() => undefined);
246
+ record.startPromise = startPromise;
247
+ try {
248
+ await startPromise;
249
+ record.startPromise = undefined;
250
+ }
251
+ catch (error) {
252
+ runs.delete(runId);
253
+ if (startInput.idempotencyKey !== undefined &&
254
+ idempotencyIndex.get(startInput.idempotencyKey) === runId) {
255
+ idempotencyIndex.delete(startInput.idempotencyKey);
256
+ }
257
+ throw error;
258
+ }
259
+ if (startInput.inactivityTimeoutMs !== undefined) {
260
+ record.watchdog = createInactivityWatchdog({
261
+ timeoutMs: startInput.inactivityTimeoutMs,
262
+ onTimeout: () => {
263
+ void handleInactivityTimeout(runId);
264
+ },
265
+ });
266
+ }
267
+ return { run: toPublicStatus(record), started: true };
268
+ },
269
+ async get(runId) {
270
+ const record = runs.get(runId);
271
+ return record ? toPublicStatus(record) : undefined;
272
+ },
273
+ async list(contextRef) {
274
+ const all = Array.from(runs.values());
275
+ const filtered = contextRef === undefined ? all : all.filter((record) => record.contextRef === contextRef);
276
+ return filtered.map(toPublicStatus);
277
+ },
278
+ async cancel(request) {
279
+ const record = requireRun(request.runId);
280
+ await record.startPromise;
281
+ if (record.finishPromise) {
282
+ return record.finishPromise;
283
+ }
284
+ if (isTerminalRunState(record.status.state)) {
285
+ return toPublicStatus(record);
286
+ }
287
+ record.cancelRequested = true;
288
+ record.lastCancelRequest = request;
289
+ record.status.updatedAt = Date.now();
290
+ for (const listener of record.cancelListeners) {
291
+ listener(request);
292
+ }
293
+ return toPublicStatus(record);
294
+ },
295
+ /**
296
+ * Registers a cancel-intent listener. If `cancel()` was already called
297
+ * for this run before this subscription, the listener fires immediately
298
+ * with the original request (mirrors `AbortSignal`'s `aborted`+`addEventListener`
299
+ * pairing) — otherwise a driver that attaches after the cancel already
300
+ * happened would silently never learn about it, since a plain
301
+ * subscribe-for-future-events registry has no memory of past firings.
302
+ */
303
+ onCancelRequested(runId, listener) {
304
+ const record = requireRun(runId);
305
+ if (record.cancelRequested && record.lastCancelRequest) {
306
+ listener(record.lastCancelRequest);
307
+ }
308
+ record.cancelListeners.add(listener);
309
+ return () => record.cancelListeners.delete(listener);
310
+ },
311
+ async emit(runId, driverInput) {
312
+ const record = requireRun(runId);
313
+ await record.startPromise;
314
+ if (record.finishPromise || isTerminalRunState(record.status.state)) {
315
+ throw new Error(`RunLifecycle: cannot emit "${driverInput.event}" on terminal run "${runId}" — drivers must stop emitting once finish() has been called`);
316
+ }
317
+ record.watchdog?.noteActivity();
318
+ return appendEvent(runId, record, driverInput.event, driverInput.data);
319
+ },
320
+ async finish(finishInput) {
321
+ const record = requireRun(finishInput.runId);
322
+ await record.startPromise;
323
+ if (record.finishPromise) {
324
+ return record.finishPromise;
325
+ }
326
+ if (isTerminalRunState(record.status.state)) {
327
+ return toPublicStatus(record);
328
+ }
329
+ const finishing = (async () => {
330
+ const endPayload = {
331
+ code: finishInput.code,
332
+ signal: finishInput.signal,
333
+ status: TERMINAL_OUTCOME_TO_END_STATUS[finishInput.status],
334
+ resumable: finishInput.resumable,
335
+ ...(finishInput.sessionRef !== undefined ? { sessionRef: finishInput.sessionRef } : {}),
336
+ };
337
+ const endEntry = await eventLog.append({ runId: finishInput.runId, event: 'end', data: endPayload });
338
+ // Commit the in-memory terminal transition only after its durable end entry exists. Until
339
+ // then `finishPromise` reserves the transition and blocks emits/concurrent finishes.
340
+ record.watchdog?.cancel();
341
+ record.status.state = finishInput.status;
342
+ record.status.updatedAt = endEntry.recordedAt;
343
+ record.status.endedAt = endEntry.recordedAt;
344
+ record.resumable = finishInput.resumable;
345
+ record.terminalEndEntry = endEntry;
346
+ const endEvent = toRunEvent(finishInput.runId, endEntry);
347
+ notifySubscribers(record, endEvent);
348
+ resolveTerminalWaiters(record);
349
+ return toPublicStatus(record);
350
+ })();
351
+ record.finishPromise = finishing;
352
+ try {
353
+ return await finishing;
354
+ }
355
+ finally {
356
+ if (record.finishPromise === finishing) {
357
+ record.finishPromise = undefined;
358
+ }
359
+ }
360
+ },
361
+ async resume(runId) {
362
+ const record = requireRun(runId);
363
+ const eligible = isTerminalRunState(record.status.state) && record.resumable;
364
+ if (!eligible) {
365
+ return { run: toPublicStatus(record), resumed: false };
366
+ }
367
+ const now = Date.now();
368
+ record.status.state = 'running';
369
+ record.status.updatedAt = now;
370
+ record.status.endedAt = undefined;
371
+ record.resumable = false;
372
+ record.cancelRequested = false;
373
+ record.lastCancelRequest = undefined;
374
+ record.terminalEndEntry = undefined;
375
+ // No protocol event is emitted here: none of RunProtocolEvent's six
376
+ // kinds represents "resumed" (extraction-plan scope decision — see
377
+ // source-map.md). The event log's cursor sequence continues
378
+ // unbroken; only RunStatus.state changes.
379
+ return { run: toPublicStatus(record), resumed: true };
380
+ },
381
+ async waitForTerminal(runId) {
382
+ const record = requireRun(runId);
383
+ if (isTerminalRunState(record.status.state)) {
384
+ return toPublicStatus(record);
385
+ }
386
+ return new Promise((resolve) => {
387
+ record.terminalWaiters.push(resolve);
388
+ });
389
+ },
390
+ async stream(runId, onEvent, options = {}) {
391
+ const record = runs.get(runId);
392
+ if (!record) {
393
+ return { kind: 'unknown-run' };
394
+ }
395
+ await record.startPromise;
396
+ // Subscribe before awaiting the durable replay. Any event appended while the replay query is
397
+ // in flight is buffered, then delivered after the replay entries, so a reconnect cannot lose
398
+ // the narrow replay→subscribe interval or observe the live event ahead of older history.
399
+ let replaying = true;
400
+ const bufferedLiveEvents = [];
401
+ const subscriber = (event) => {
402
+ if (replaying)
403
+ bufferedLiveEvents.push(event);
404
+ else
405
+ onEvent(event);
406
+ };
407
+ record.subscribers.add(subscriber);
408
+ try {
409
+ const replay = await eventLog.replay(runId, options.afterCursor ?? null);
410
+ if (replay.kind !== 'ok') {
411
+ record.subscribers.delete(subscriber);
412
+ return replay;
413
+ }
414
+ const deliveredEventIds = new Set();
415
+ for (const entry of replay.entries) {
416
+ const event = toRunEvent(runId, entry);
417
+ deliveredEventIds.add(event.eventId);
418
+ onEvent(event);
419
+ }
420
+ for (const event of bufferedLiveEvents) {
421
+ if (!deliveredEventIds.has(event.eventId)) {
422
+ deliveredEventIds.add(event.eventId);
423
+ onEvent(event);
424
+ }
425
+ }
426
+ replaying = false;
427
+ const terminal = isTerminalRunState(record.status.state);
428
+ if (terminal && record.terminalEndEntry) {
429
+ const terminalEvent = toRunEvent(runId, record.terminalEndEntry);
430
+ if (!deliveredEventIds.has(terminalEvent.eventId)) {
431
+ deliveredEventIds.add(terminalEvent.eventId);
432
+ onEvent(terminalEvent);
433
+ }
434
+ }
435
+ if (terminal) {
436
+ record.subscribers.delete(subscriber);
437
+ return { kind: 'ok', unsubscribe: () => { } };
438
+ }
439
+ return { kind: 'ok', unsubscribe: () => record.subscribers.delete(subscriber) };
440
+ }
441
+ catch (error) {
442
+ // Subscription is installed before durable replay to close the replay→live race. Any
443
+ // replay I/O or consumer callback failure must therefore remove it before propagating.
444
+ record.subscribers.delete(subscriber);
445
+ throw error;
446
+ }
447
+ },
448
+ };
449
+ return lifecycle;
450
+ }
451
+ //# sourceMappingURL=run-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-lifecycle.js","sourceRoot":"","sources":["../src/run-lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ import type { Principal, ToolPolicy, ToolRegistration } from '@jini-ai/core';
2
+ import { type PtySpawn, type TerminalService, type TerminalSseSink } from '@jini-ai/platform';
3
+ export type { TerminalSseSink } from '@jini-ai/platform';
4
+ /** The `ToolRegistry` id `terminal.create` executes through — see module doc §2. */
5
+ export declare const TERMINAL_CREATE_TOOL_ID = "terminal.create";
6
+ /**
7
+ * Deny-by-default `ToolPolicy` for `terminal.create`. Matching
8
+ * `db-ops.ts`'s `denyAllDaemonDbPolicy` / `@jini-ai/deploy`'s
9
+ * `denyAllDeployPublishPolicy` precedent: spawning an interactive shell is
10
+ * strictly more dangerous than any of those (it is not one bounded
11
+ * operation but an open-ended session), so a host must explicitly opt in
12
+ * with its own policy rather than getting a working shell spawner for free
13
+ * merely by registering the tool.
14
+ */
15
+ export declare const denyAllTerminalCreatePolicy: ToolPolicy;
16
+ /**
17
+ * The real, `node-pty`-backed {@link PtySpawn}. Dynamically imports
18
+ * `node-pty` (mirroring OD's origin `await import('node-pty')`, not a
19
+ * static top-level import) so a host process whose platform/environment
20
+ * lacks a usable `node-pty` addon can still boot — only an actual
21
+ * `terminal.create` call fails, cleanly, rather than crashing at
22
+ * module-eval time. Before the first spawn, repairs `node-pty`'s bundled
23
+ * `spawn-helper` binary's executable bit (pnpm unpacks it non-executable —
24
+ * see `@jini-ai/platform`'s `terminal.ts` module doc for the full story) via
25
+ * that package's own `spawnHelperCandidatePaths`/`ensureSpawnHelperExecutable`,
26
+ * but with the resolver anchored at **this** module
27
+ * (`createRequire(import.meta.url)` here, not `@jini-ai/platform`'s own
28
+ * default): `@jini-ai/platform` deliberately does not depend on `node-pty`, so
29
+ * its default `require.resolve('node-pty')` would not find the copy this
30
+ * package (`@jini-ai/daemon`) actually declares — this is exactly the
31
+ * resolver injection seam `spawnHelperCandidatePaths` was built for.
32
+ */
33
+ export declare function loadRealSpawnPty(): Promise<PtySpawn>;
34
+ /** The public, principal-neutral session snapshot this module exposes — deliberately its own shape rather than re-exporting `@jini-ai/platform`'s `TerminalSession` verbatim, since that type carries an OD-shaped per-session grouping key (see `@jini-ai/platform`'s `terminal.ts`) this module replaces entirely with the caller-supplied `resourceRef` (see {@link CreateTerminalSessionOptions}), tracked only in this module's own metadata and never forwarded to `@jini-ai/platform` at all — this package's own identifier-neutrality lint (`__tests__/identifier-lint.test.ts`) forbids that origin field's exact name from appearing anywhere in this package's source. */
35
+ export interface TerminalSessionInfo {
36
+ readonly id: string;
37
+ readonly resourceRef: string | null;
38
+ readonly cwd: string;
39
+ readonly shell: string;
40
+ readonly cols: number;
41
+ readonly rows: number;
42
+ readonly status: 'running' | 'exited';
43
+ readonly createdAt: number;
44
+ readonly updatedAt: number;
45
+ readonly exitCode: number | null;
46
+ readonly signal: string | null;
47
+ }
48
+ export interface CreateTerminalSessionOptions {
49
+ /** Opaque grouping/scoping reference (e.g. what `@jini-ai/http`'s `workspace-root.ts` resolved `cwd` from) — tracked by this module only, never forwarded to `@jini-ai/platform`. */
50
+ readonly resourceRef?: string | null;
51
+ readonly cwd: string;
52
+ readonly cols?: number;
53
+ readonly rows?: number;
54
+ readonly shell?: string | null;
55
+ }
56
+ export interface TerminalSessionListFilter {
57
+ readonly resourceRef?: string;
58
+ }
59
+ export type TerminalSessionAccessResult = {
60
+ readonly status: 'not-found';
61
+ } | {
62
+ readonly status: 'ok';
63
+ readonly session: TerminalSessionInfo;
64
+ };
65
+ /**
66
+ * Result of a `write`/`resize`/`kill` call. `'not-found'` covers both "no
67
+ * such session" and "this session belongs to a different principal" —
68
+ * identically, never distinguishably — see {@link checkOwnership}'s doc.
69
+ * `'ok'` with `ok: false` covers a session that exists and is owned by the
70
+ * caller but could not actually perform the action (already exited, killed
71
+ * by a racing call, or the underlying pty call itself failed) — mirroring
72
+ * `@jini-ai/platform`'s own `write`/`resize`/`kill` boolean-return contract.
73
+ */
74
+ export type TerminalSessionActionResult = {
75
+ readonly status: 'not-found';
76
+ } | {
77
+ readonly status: 'ok';
78
+ readonly ok: boolean;
79
+ readonly session: TerminalSessionInfo | null;
80
+ };
81
+ export type TerminalSessionAttachResult = 'attached' | 'ended' | 'not-found';
82
+ export interface TerminalSessionManager {
83
+ /** The one call gated through `ToolExecutor` (see module doc §2) — this method is what `createTerminalToolRegistrations`'s handler calls, never invoked directly by a route. */
84
+ create(principal: Principal, options: CreateTerminalSessionOptions): Promise<TerminalSessionInfo>;
85
+ get(principal: Principal, id: string): TerminalSessionAccessResult;
86
+ /** Sessions the given principal owns, optionally narrowed by `resourceRef`. Never returns another principal's sessions. */
87
+ list(principal: Principal, filter?: TerminalSessionListFilter): readonly TerminalSessionInfo[];
88
+ write(principal: Principal, id: string, input: string): Promise<TerminalSessionActionResult>;
89
+ resize(principal: Principal, id: string, cols: number, rows: number): Promise<TerminalSessionActionResult>;
90
+ kill(principal: Principal, id: string, signal?: string): Promise<TerminalSessionActionResult>;
91
+ /** Replays scrollback after `lastEventId` and attaches `sink` for live output — ownership-checked the same as `write`/`resize`/`kill`, since reading a session's output is exactly as sensitive as writing to it. */
92
+ attach(principal: Principal, id: string, lastEventId: number, sink: TerminalSseSink): TerminalSessionAttachResult;
93
+ /** No ownership check: removing a sink that was never attached (e.g. a foreign/unknown id) is already a safe no-op at the `@jini-ai/platform` layer, and detach carries no capability of its own. */
94
+ detach(id: string, sink: TerminalSseSink): void;
95
+ shutdownActive(options?: {
96
+ graceMs?: number;
97
+ }): Promise<void>;
98
+ }
99
+ export interface CreateTerminalSessionManagerOptions {
100
+ /** Injected for tests (a fake session manager without a real pty) or an alternate host wiring. @default a fresh `@jini-ai/platform` `TerminalService` backed by {@link loadRealSpawnPty}. */
101
+ readonly terminalService?: TerminalService;
102
+ /** @default {@link loadRealSpawnPty} */
103
+ readonly loadSpawnPty?: () => Promise<PtySpawn>;
104
+ readonly maxEvents?: number;
105
+ readonly maxBufferBytes?: number;
106
+ readonly exitTailBytes?: number;
107
+ readonly flushIntervalMs?: number;
108
+ readonly flushThresholdBytes?: number;
109
+ readonly ttlMs?: number;
110
+ readonly shutdownGraceMs?: number;
111
+ }
112
+ /**
113
+ * Builds the reference `TerminalSessionManager`: an in-process wrapper
114
+ * around a `@jini-ai/platform` `TerminalService` adding session ownership,
115
+ * the kill/write/resize lock, and (via {@link createTerminalToolRegistrations})
116
+ * `ToolExecutor` gating for creation. See module doc for the full design.
117
+ */
118
+ export declare function createTerminalSessionManager(options?: CreateTerminalSessionManagerOptions): TerminalSessionManager;
119
+ export interface CreateTerminalToolRegistrationsOptions {
120
+ readonly manager: TerminalSessionManager;
121
+ /** @default {@link denyAllTerminalCreatePolicy} — see its doc for why a permissive default was rejected. */
122
+ readonly policy?: ToolPolicy;
123
+ readonly requiresConfirmation?: boolean;
124
+ readonly timeoutMs?: number;
125
+ }
126
+ export interface TerminalToolRegistrations {
127
+ readonly create: ToolRegistration;
128
+ }
129
+ /**
130
+ * Builds the `{descriptor, handler, policy}` triple a host registers
131
+ * against `@jini-ai/core`'s `ToolRegistry` so `terminal.create` becomes
132
+ * reachable only via `ToolExecutor.execute(principal, run,
133
+ * 'terminal.create', input)` — never by a route calling
134
+ * `manager.create()` directly, which would bypass authorization and the
135
+ * audit trail (matching `db-ops.ts`'s `createDaemonDbToolRegistrations`
136
+ * precedent).
137
+ */
138
+ export declare function createTerminalToolRegistrations(options: CreateTerminalToolRegistrationsOptions): TerminalToolRegistrations;
139
+ //# sourceMappingURL=terminal-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-session.d.ts","sourceRoot":"","sources":["../src/terminal-session.ts"],"names":[],"mappings":"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"}