@adhdev/daemon-core 0.9.75 → 0.9.76-rc.2

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.
@@ -144,6 +144,7 @@ export interface LocalMeshNodeEntry {
144
144
  id: string;
145
145
  workspace: string;
146
146
  repoRoot?: string;
147
+ daemonId?: string;
147
148
  userOverrides: Partial<RepoMeshNodeCapabilities>;
148
149
  policy: RepoMeshNodePolicy;
149
150
  /** For single-machine mesh: same daemon, different worktree */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.9.75",
4
- "description": "ADHDev daemon core \u2014 CDP, IDE detection, providers, command execution",
3
+ "version": "0.9.76-rc.2",
4
+ "description": "ADHDev daemon core CDP, IDE detection, providers, command execution",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {
@@ -266,10 +266,16 @@ export class ProviderCliAdapter implements CliAdapter {
266
266
  const currentSnapshot = normalizeScreenSnapshot(screenText);
267
267
  const lastSnapshot = this.lastScreenSnapshot;
268
268
  if (!lastSnapshot || lastSnapshot === currentSnapshot) return screenText;
269
+ const staleSnapshotLooksActive = /\besc to (?:interrupt|stop)\b|Enter to interrupt, Ctrl\+C to cancel/i.test(lastSnapshot);
270
+ const currentScreenLooksIdle = /(?:^|\n|\r)\s*[❯›>]\s*(?:\n|\r|$)/.test(screenText)
271
+ && !/\besc to (?:interrupt|stop)\b|Enter to interrupt, Ctrl\+C to cancel/i.test(screenText);
272
+ if (staleSnapshotLooksActive && currentScreenLooksIdle) return screenText;
273
+ if (currentSnapshot.length >= lastSnapshot.length) return screenText;
269
274
  // Terminal screen reads can miss a just-rendered completed Hermes box while
270
275
  // the normalized snapshot captured during output still has it. Feed both
271
276
  // views to provider parsers so flattened snapshot-only final bubbles do
272
- // not disappear from read_chat/chat_tail.
277
+ // not disappear from read_chat/chat_tail, but only when the older snapshot
278
+ // carries extra content instead of stale status chrome.
273
279
  return `${screenText}\n${lastSnapshot}`;
274
280
  }
275
281
 
@@ -92,7 +92,7 @@ function buildNodeConfigSection(mesh: LocalMeshEntry): string {
92
92
  for (const n of mesh.nodes) {
93
93
  const labels: string[] = [];
94
94
  if (n.isLocalWorktree) labels.push('worktree');
95
- if (n.policy.readOnly) labels.push('read-only');
95
+ if (n.policy?.readOnly) labels.push('read-only');
96
96
  const suffix = labels.length ? ` [${labels.join(', ')}]` : '';
97
97
  lines.push(`- **${n.workspace}** (${n.id})${suffix}`);
98
98
  }
@@ -139,7 +139,7 @@ const WORKFLOW_SECTION = `## Orchestration Workflow
139
139
  3. **Delegate** — For each task:
140
140
  a. Pick the best node (consider: health, dirty state, current workload).
141
141
  b. If no session exists, call \`mesh_launch_session\` to start one.
142
- c. Call \`mesh_send_task\` with a clear, self-contained natural-language instruction.
142
+ c. Call \`mesh_send_task\` with a **complete, self-contained** instruction that includes all context the agent needs (file paths, line numbers, what to change, why). Do not send partial instructions expecting future follow-up.
143
143
  4. **Monitor** — Periodically call \`mesh_read_chat\` to check progress. Handle approvals via \`mesh_approve\`.
144
144
  5. **Verify** — When a task reports completion, call \`mesh_git_status\` to verify changes were made.
145
145
  6. **Checkpoint** — Call \`mesh_checkpoint\` to save the work.
@@ -147,10 +147,12 @@ const WORKFLOW_SECTION = `## Orchestration Workflow
147
147
 
148
148
  const RULES_SECTION = `## Rules
149
149
 
150
- - **Be conversational.** Delegate work the way a tech lead would clear, specific instructions in natural language.
151
- - **Don't inspect code.** Trust the agent's output. Verify via git diff/status, not by reading source files.
150
+ - **Minimize coordinator context.** The coordinator's job is routing, not implementing. Do not read source files, run commands, or analyze code directly — delegate all of that to node agents. Your context should stay lean.
151
+ - **Delegate analysis too.** If you need to understand a bug or explore the codebase, send that investigation as a task to a node. Do not do it yourself.
152
+ - **Front-load the task message.** When calling \`mesh_send_task\`, include everything the agent needs: what files to touch, what the problem is, what the fix should look like. The agent won't ask follow-up questions.
153
+ - **Don't inspect code.** Trust the agent's output. Verify via \`mesh_git_status\`, not by reading source files.
152
154
  - **Don't over-parallelize.** Start with 1-2 concurrent tasks. Scale up if they succeed.
153
155
  - **Handle failures gracefully.** If a task fails, read the chat to understand why, then retry or reassign.
154
- - **Keep the user informed.** Report progress after each delegation round.
156
+ - **Keep the user informed.** Report progress after each delegation round — one or two sentences, not a narration.
155
157
  - **Respect node capabilities.** Don't send build tasks to read-only nodes. Don't push from nodes that aren't allowed to.
156
158
  - **Never fabricate tool results.** Always call the actual tool; never pretend you did.`;
@@ -184,6 +184,7 @@ export interface LocalMeshNodeEntry {
184
184
  id: string;
185
185
  workspace: string;
186
186
  repoRoot?: string;
187
+ daemonId?: string;
187
188
  userOverrides: Partial<RepoMeshNodeCapabilities>;
188
189
  policy: RepoMeshNodePolicy;
189
190
  /** For single-machine mesh: same daemon, different worktree */
@@ -1,6 +0,0 @@
1
- declare const DEFAULT_SESSION_HOST_COLS = 80;
2
- declare const DEFAULT_SESSION_HOST_ROWS = 32;
3
- declare function resolveSessionHostCols(value: number | undefined): number;
4
- declare function resolveSessionHostRows(value: number | undefined): number;
5
-
6
- export { DEFAULT_SESSION_HOST_COLS, DEFAULT_SESSION_HOST_ROWS, resolveSessionHostCols, resolveSessionHostRows };
@@ -1,6 +0,0 @@
1
- declare const DEFAULT_SESSION_HOST_COLS = 80;
2
- declare const DEFAULT_SESSION_HOST_ROWS = 32;
3
- declare function resolveSessionHostCols(value: number | undefined): number;
4
- declare function resolveSessionHostRows(value: number | undefined): number;
5
-
6
- export { DEFAULT_SESSION_HOST_COLS, DEFAULT_SESSION_HOST_ROWS, resolveSessionHostCols, resolveSessionHostRows };
@@ -1,49 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/defaults.ts
21
- var defaults_exports = {};
22
- __export(defaults_exports, {
23
- DEFAULT_SESSION_HOST_COLS: () => DEFAULT_SESSION_HOST_COLS,
24
- DEFAULT_SESSION_HOST_ROWS: () => DEFAULT_SESSION_HOST_ROWS,
25
- resolveSessionHostCols: () => resolveSessionHostCols,
26
- resolveSessionHostRows: () => resolveSessionHostRows
27
- });
28
- module.exports = __toCommonJS(defaults_exports);
29
- var DEFAULT_SESSION_HOST_COLS = 80;
30
- var DEFAULT_SESSION_HOST_ROWS = 32;
31
- function normalizeSessionHostDimension(value, fallback) {
32
- if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
33
- const rounded = Math.floor(value);
34
- return rounded > 0 ? rounded : fallback;
35
- }
36
- function resolveSessionHostCols(value) {
37
- return normalizeSessionHostDimension(value, DEFAULT_SESSION_HOST_COLS);
38
- }
39
- function resolveSessionHostRows(value) {
40
- return normalizeSessionHostDimension(value, DEFAULT_SESSION_HOST_ROWS);
41
- }
42
- // Annotate the CommonJS export names for ESM import in node:
43
- 0 && (module.exports = {
44
- DEFAULT_SESSION_HOST_COLS,
45
- DEFAULT_SESSION_HOST_ROWS,
46
- resolveSessionHostCols,
47
- resolveSessionHostRows
48
- });
49
- //# sourceMappingURL=defaults.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/defaults.ts"],"sourcesContent":["export const DEFAULT_SESSION_HOST_COLS = 80;\nexport const DEFAULT_SESSION_HOST_ROWS = 32;\n\nfunction normalizeSessionHostDimension(value: number | undefined, fallback: number): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) return fallback;\n const rounded = Math.floor(value);\n return rounded > 0 ? rounded : fallback;\n}\n\nexport function resolveSessionHostCols(value: number | undefined): number {\n return normalizeSessionHostDimension(value, DEFAULT_SESSION_HOST_COLS);\n}\n\nexport function resolveSessionHostRows(value: number | undefined): number {\n return normalizeSessionHostDimension(value, DEFAULT_SESSION_HOST_ROWS);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,IAAM,4BAA4B;AAClC,IAAM,4BAA4B;AAEzC,SAAS,8BAA8B,OAA2B,UAA0B;AAC1F,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,EAAG,QAAO;AACjE,QAAM,UAAU,KAAK,MAAM,KAAK;AAChC,SAAO,UAAU,IAAI,UAAU;AACjC;AAEO,SAAS,uBAAuB,OAAmC;AACxE,SAAO,8BAA8B,OAAO,yBAAyB;AACvE;AAEO,SAAS,uBAAuB,OAAmC;AACxE,SAAO,8BAA8B,OAAO,yBAAyB;AACvE;","names":[]}
@@ -1,21 +0,0 @@
1
- // src/defaults.ts
2
- var DEFAULT_SESSION_HOST_COLS = 80;
3
- var DEFAULT_SESSION_HOST_ROWS = 32;
4
- function normalizeSessionHostDimension(value, fallback) {
5
- if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
6
- const rounded = Math.floor(value);
7
- return rounded > 0 ? rounded : fallback;
8
- }
9
- function resolveSessionHostCols(value) {
10
- return normalizeSessionHostDimension(value, DEFAULT_SESSION_HOST_COLS);
11
- }
12
- function resolveSessionHostRows(value) {
13
- return normalizeSessionHostDimension(value, DEFAULT_SESSION_HOST_ROWS);
14
- }
15
- export {
16
- DEFAULT_SESSION_HOST_COLS,
17
- DEFAULT_SESSION_HOST_ROWS,
18
- resolveSessionHostCols,
19
- resolveSessionHostRows
20
- };
21
- //# sourceMappingURL=defaults.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/defaults.ts"],"sourcesContent":["export const DEFAULT_SESSION_HOST_COLS = 80;\nexport const DEFAULT_SESSION_HOST_ROWS = 32;\n\nfunction normalizeSessionHostDimension(value: number | undefined, fallback: number): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) return fallback;\n const rounded = Math.floor(value);\n return rounded > 0 ? rounded : fallback;\n}\n\nexport function resolveSessionHostCols(value: number | undefined): number {\n return normalizeSessionHostDimension(value, DEFAULT_SESSION_HOST_COLS);\n}\n\nexport function resolveSessionHostRows(value: number | undefined): number {\n return normalizeSessionHostDimension(value, DEFAULT_SESSION_HOST_ROWS);\n}\n"],"mappings":";AAAO,IAAM,4BAA4B;AAClC,IAAM,4BAA4B;AAEzC,SAAS,8BAA8B,OAA2B,UAA0B;AAC1F,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,EAAG,QAAO;AACjE,QAAM,UAAU,KAAK,MAAM,KAAK;AAChC,SAAO,UAAU,IAAI,UAAU;AACjC;AAEO,SAAS,uBAAuB,OAAmC;AACxE,SAAO,8BAA8B,OAAO,yBAAyB;AACvE;AAEO,SAAS,uBAAuB,OAAmC;AACxE,SAAO,8BAA8B,OAAO,yBAAyB;AACvE;","names":[]}
@@ -1,444 +0,0 @@
1
- import * as net from 'net';
2
- export { DEFAULT_SESSION_HOST_COLS, DEFAULT_SESSION_HOST_ROWS, resolveSessionHostCols, resolveSessionHostRows } from './defaults.mjs';
3
-
4
- type SessionTransport = 'pty';
5
- type SessionHostCategory = 'cli' | 'acp' | 'shell';
6
- type SessionLifecycle = 'starting' | 'running' | 'stopping' | 'stopped' | 'failed' | 'interrupted';
7
- type SessionClientType = 'daemon' | 'web' | 'local-terminal';
8
- type SessionOwnerType = 'agent' | 'user';
9
- interface SessionLaunchCommand {
10
- command: string;
11
- args: string[];
12
- env?: Record<string, string>;
13
- }
14
- interface SessionWriteOwner {
15
- clientId: string;
16
- ownerType: SessionOwnerType;
17
- acquiredAt: number;
18
- }
19
- interface SessionAttachedClient {
20
- clientId: string;
21
- type: SessionClientType;
22
- readOnly: boolean;
23
- attachedAt: number;
24
- lastSeenAt: number;
25
- }
26
- interface SessionBufferSnapshot {
27
- seq: number;
28
- text: string;
29
- truncated: boolean;
30
- cols?: number;
31
- rows?: number;
32
- }
33
- interface SessionBufferState {
34
- scrollbackBytes: number;
35
- snapshotSeq: number;
36
- }
37
- type SessionHostSurfaceKind = 'live_runtime' | 'recovery_snapshot' | 'inactive_record';
38
- interface SessionHostRecord {
39
- sessionId: string;
40
- runtimeKey: string;
41
- displayName: string;
42
- workspaceLabel: string;
43
- transport: SessionTransport;
44
- providerType: string;
45
- category: SessionHostCategory;
46
- workspace: string;
47
- launchCommand: SessionLaunchCommand;
48
- osPid?: number;
49
- createdAt: number;
50
- startedAt?: number;
51
- lastActivityAt: number;
52
- lifecycle: SessionLifecycle;
53
- surfaceKind?: SessionHostSurfaceKind;
54
- writeOwner: SessionWriteOwner | null;
55
- attachedClients: SessionAttachedClient[];
56
- buffer: SessionBufferState;
57
- meta: Record<string, unknown>;
58
- }
59
- interface CreateSessionPayload {
60
- sessionId?: string;
61
- runtimeKey?: string;
62
- displayName?: string;
63
- providerType: string;
64
- category: SessionHostCategory;
65
- workspace: string;
66
- launchCommand: SessionLaunchCommand;
67
- cols?: number;
68
- rows?: number;
69
- clientId?: string;
70
- clientType?: SessionClientType;
71
- meta?: Record<string, unknown>;
72
- }
73
- interface AttachSessionPayload {
74
- sessionId: string;
75
- clientId: string;
76
- clientType: SessionClientType;
77
- readOnly?: boolean;
78
- }
79
- interface DetachSessionPayload {
80
- sessionId: string;
81
- clientId: string;
82
- }
83
- interface SendInputPayload {
84
- sessionId: string;
85
- clientId: string;
86
- data: string;
87
- }
88
- interface ResizeSessionPayload {
89
- sessionId: string;
90
- cols: number;
91
- rows: number;
92
- }
93
- interface StopSessionPayload {
94
- sessionId: string;
95
- }
96
- interface ResumeSessionPayload {
97
- sessionId: string;
98
- }
99
- interface AcquireWritePayload {
100
- sessionId: string;
101
- clientId: string;
102
- ownerType: SessionOwnerType;
103
- force?: boolean;
104
- }
105
- interface ReleaseWritePayload {
106
- sessionId: string;
107
- clientId: string;
108
- }
109
- interface GetSnapshotPayload {
110
- sessionId: string;
111
- sinceSeq?: number;
112
- }
113
- interface ClearSessionBufferPayload {
114
- sessionId: string;
115
- }
116
- interface UpdateSessionMetaPayload {
117
- sessionId: string;
118
- meta: Record<string, unknown>;
119
- replace?: boolean;
120
- }
121
- interface GetHostDiagnosticsPayload {
122
- includeSessions?: boolean;
123
- limit?: number;
124
- }
125
- interface ForceDetachClientPayload {
126
- sessionId: string;
127
- clientId: string;
128
- }
129
- interface SendSignalPayload {
130
- sessionId: string;
131
- signal: string;
132
- }
133
- interface RestartSessionPayload {
134
- sessionId: string;
135
- }
136
- interface PruneDuplicateSessionsPayload {
137
- providerType?: string;
138
- workspace?: string;
139
- dryRun?: boolean;
140
- }
141
- interface SessionHostDuplicateSessionGroup {
142
- bindingKey: string;
143
- providerType: string;
144
- workspace: string;
145
- providerSessionId: string;
146
- keptSessionId: string;
147
- prunedSessionIds: string[];
148
- }
149
- interface SessionHostPruneDuplicatesResult {
150
- duplicateGroupCount: number;
151
- keptSessionIds: string[];
152
- prunedSessionIds: string[];
153
- groups: SessionHostDuplicateSessionGroup[];
154
- }
155
- interface SessionHostLogEntry {
156
- timestamp: number;
157
- level: 'debug' | 'info' | 'warn' | 'error';
158
- message: string;
159
- sessionId?: string;
160
- data?: Record<string, unknown>;
161
- }
162
- interface SessionHostRequestTrace {
163
- timestamp: number;
164
- requestId: string;
165
- type: SessionHostRequest['type'];
166
- sessionId?: string;
167
- clientId?: string;
168
- success: boolean;
169
- durationMs: number;
170
- error?: string;
171
- }
172
- interface SessionHostRuntimeTransition {
173
- timestamp: number;
174
- sessionId: string;
175
- action: string;
176
- lifecycle?: SessionLifecycle;
177
- detail?: string;
178
- success?: boolean;
179
- error?: string;
180
- }
181
- interface SessionHostDiagnostics {
182
- hostStartedAt: number;
183
- endpoint: string;
184
- runtimeCount: number;
185
- sessions?: SessionHostRecord[];
186
- liveRuntimes?: SessionHostRecord[];
187
- recoverySnapshots?: SessionHostRecord[];
188
- inactiveRecords?: SessionHostRecord[];
189
- recentLogs: SessionHostLogEntry[];
190
- recentRequests: SessionHostRequestTrace[];
191
- recentTransitions: SessionHostRuntimeTransition[];
192
- }
193
- type SessionHostRequest = {
194
- type: 'create_session';
195
- payload: CreateSessionPayload;
196
- } | {
197
- type: 'attach_session';
198
- payload: AttachSessionPayload;
199
- } | {
200
- type: 'detach_session';
201
- payload: DetachSessionPayload;
202
- } | {
203
- type: 'send_input';
204
- payload: SendInputPayload;
205
- } | {
206
- type: 'resize_session';
207
- payload: ResizeSessionPayload;
208
- } | {
209
- type: 'stop_session';
210
- payload: StopSessionPayload;
211
- } | {
212
- type: 'resume_session';
213
- payload: ResumeSessionPayload;
214
- } | {
215
- type: 'acquire_write';
216
- payload: AcquireWritePayload;
217
- } | {
218
- type: 'release_write';
219
- payload: ReleaseWritePayload;
220
- } | {
221
- type: 'get_snapshot';
222
- payload: GetSnapshotPayload;
223
- } | {
224
- type: 'clear_session_buffer';
225
- payload: ClearSessionBufferPayload;
226
- } | {
227
- type: 'update_session_meta';
228
- payload: UpdateSessionMetaPayload;
229
- } | {
230
- type: 'get_host_diagnostics';
231
- payload?: GetHostDiagnosticsPayload;
232
- } | {
233
- type: 'force_detach_client';
234
- payload: ForceDetachClientPayload;
235
- } | {
236
- type: 'send_signal';
237
- payload: SendSignalPayload;
238
- } | {
239
- type: 'restart_session';
240
- payload: RestartSessionPayload;
241
- } | {
242
- type: 'prune_duplicate_sessions';
243
- payload?: PruneDuplicateSessionsPayload;
244
- } | {
245
- type: 'list_sessions';
246
- payload?: {};
247
- };
248
- interface SessionHostResponse<T = unknown> {
249
- success: boolean;
250
- result?: T;
251
- error?: string;
252
- }
253
- type SessionHostEvent = {
254
- type: 'session_created';
255
- sessionId: string;
256
- record: SessionHostRecord;
257
- } | {
258
- type: 'session_started';
259
- sessionId: string;
260
- pid?: number;
261
- } | {
262
- type: 'session_resumed';
263
- sessionId: string;
264
- pid?: number;
265
- } | {
266
- type: 'session_output';
267
- sessionId: string;
268
- seq: number;
269
- data: string;
270
- } | {
271
- type: 'session_cleared';
272
- sessionId: string;
273
- } | {
274
- type: 'session_exit';
275
- sessionId: string;
276
- exitCode: number | null;
277
- } | {
278
- type: 'session_stopped';
279
- sessionId: string;
280
- } | {
281
- type: 'session_resized';
282
- sessionId: string;
283
- cols: number;
284
- rows: number;
285
- } | {
286
- type: 'write_owner_changed';
287
- sessionId: string;
288
- owner: SessionWriteOwner | null;
289
- } | {
290
- type: 'client_attached';
291
- sessionId: string;
292
- client: SessionAttachedClient;
293
- } | {
294
- type: 'client_detached';
295
- sessionId: string;
296
- clientId: string;
297
- } | {
298
- type: 'host_log';
299
- entry: SessionHostLogEntry;
300
- } | {
301
- type: 'request_trace';
302
- trace: SessionHostRequestTrace;
303
- } | {
304
- type: 'runtime_transition';
305
- transition: SessionHostRuntimeTransition;
306
- };
307
- interface SessionHostRequestEnvelope {
308
- kind: 'request';
309
- requestId: string;
310
- request: SessionHostRequest;
311
- }
312
- interface SessionHostResponseEnvelope {
313
- kind: 'response';
314
- requestId: string;
315
- response: SessionHostResponse;
316
- }
317
- interface SessionHostEventEnvelope {
318
- kind: 'event';
319
- event: SessionHostEvent;
320
- }
321
- type SessionHostWireEnvelope = SessionHostRequestEnvelope | SessionHostResponseEnvelope | SessionHostEventEnvelope;
322
-
323
- interface SessionRingBufferOptions {
324
- maxBytes?: number;
325
- }
326
- declare const DEFAULT_SESSION_RING_BUFFER_MAX_BYTES: number;
327
- declare class SessionRingBuffer {
328
- private maxBytes;
329
- private chunks;
330
- private nextSeq;
331
- private totalBytes;
332
- constructor(options?: SessionRingBufferOptions);
333
- append(data: string): number;
334
- snapshot(sinceSeq?: number): SessionBufferSnapshot;
335
- getState(): {
336
- scrollbackBytes: number;
337
- snapshotSeq: number;
338
- };
339
- clear(): void;
340
- restore(snapshot: {
341
- seq: number;
342
- text: string;
343
- }): void;
344
- private trim;
345
- }
346
-
347
- declare class SessionHostRegistry {
348
- private sessions;
349
- createSession(payload: CreateSessionPayload): SessionHostRecord;
350
- restoreSession(record: SessionHostRecord, snapshot?: {
351
- seq: number;
352
- text: string;
353
- } | null): SessionHostRecord;
354
- listSessions(): SessionHostRecord[];
355
- getSession(sessionId: string): SessionHostRecord | null;
356
- attachClient(payload: AttachSessionPayload): SessionHostRecord;
357
- detachClient(payload: DetachSessionPayload): SessionHostRecord;
358
- acquireWrite(payload: AcquireWritePayload): SessionHostRecord;
359
- releaseWrite(payload: ReleaseWritePayload): SessionHostRecord;
360
- appendOutput(sessionId: string, data: string): {
361
- record: SessionHostRecord;
362
- seq: number;
363
- };
364
- getSnapshot(sessionId: string, sinceSeq?: number): SessionBufferSnapshot;
365
- clearBuffer(sessionId: string): SessionHostRecord;
366
- updateSessionMeta(sessionId: string, meta: Record<string, unknown>, replace?: boolean): SessionHostRecord;
367
- markStarted(sessionId: string, pid?: number): SessionHostRecord;
368
- markStopped(sessionId: string, lifecycle?: 'stopped' | 'failed'): SessionHostRecord;
369
- setLifecycle(sessionId: string, lifecycle: 'starting' | 'running' | 'stopping' | 'stopped' | 'failed' | 'interrupted'): SessionHostRecord;
370
- deleteSession(sessionId: string): boolean;
371
- private requireSession;
372
- private cloneRecord;
373
- }
374
-
375
- declare function getWorkspaceLabel(workspace: string): string;
376
- declare function buildRuntimeDisplayName(payload: Pick<CreateSessionPayload, 'displayName' | 'providerType' | 'workspace'>): string;
377
- declare function buildRuntimeKey(payload: Pick<CreateSessionPayload, 'runtimeKey' | 'displayName' | 'providerType' | 'workspace'>, existingKeys: Iterable<string>): string;
378
- interface SessionHostSurfaceRecordLike {
379
- lifecycle?: string | null;
380
- surfaceKind?: SessionHostSurfaceKind | null;
381
- meta?: Record<string, unknown> | null;
382
- }
383
- declare function isSessionHostLiveRuntime(record: SessionHostSurfaceRecordLike | null | undefined): boolean;
384
- declare function getSessionHostRecoveryLabel(meta: Record<string, unknown> | null | undefined): string | null;
385
- declare function isSessionHostRecoverySnapshot(record: SessionHostSurfaceRecordLike | null | undefined): boolean;
386
- declare function getSessionHostSurfaceKind(record: SessionHostSurfaceRecordLike | null | undefined): SessionHostSurfaceKind;
387
- declare function resolveAttachableRuntimeRecord(records: SessionHostRecord[], identifier: string): SessionHostRecord;
388
- declare function resolveRuntimeRecord(records: SessionHostRecord[], identifier: string): SessionHostRecord;
389
- declare function formatRuntimeOwner(record: Pick<SessionHostRecord, 'writeOwner'>): string;
390
-
391
- interface SessionHostEndpoint {
392
- kind: 'unix' | 'pipe';
393
- path: string;
394
- }
395
- declare function getDefaultSessionHostEndpoint(appName?: string): SessionHostEndpoint;
396
- declare function createLineParser(onEnvelope: (envelope: SessionHostWireEnvelope) => void): (chunk: Buffer | string) => void;
397
- interface SessionHostClientOptions {
398
- endpoint?: SessionHostEndpoint;
399
- appName?: string;
400
- }
401
- declare class SessionHostClient {
402
- readonly endpoint: SessionHostEndpoint;
403
- private socket;
404
- private requestWaiters;
405
- private eventListeners;
406
- constructor(options?: SessionHostClientOptions);
407
- connect(): Promise<void>;
408
- onEvent(listener: (event: SessionHostEvent) => void): () => void;
409
- request<T = unknown>(request: SessionHostRequest): Promise<SessionHostResponse<T>>;
410
- close(): Promise<void>;
411
- }
412
- declare function createResponseEnvelope(requestId: string, response: SessionHostResponse): SessionHostResponseEnvelope;
413
- declare function writeEnvelope(socket: Pick<net.Socket, 'write'>, envelope: SessionHostWireEnvelope): void;
414
-
415
- /**
416
- * Shared PTY spawn environment utilities.
417
- *
418
- * Centralises npm/pnpm/yarn env variable stripping, terminal colour env
419
- * injection, and node-pty spawn-helper permission fixing.
420
- *
421
- * Used by daemon-core (provider-cli-adapter), session-host-daemon (runtime),
422
- * and daemon-cloud (session-host).
423
- */
424
- /**
425
- * Strip package-manager injected environment variables that can interfere
426
- * with child CLI processes and apply terminal colour defaults.
427
- */
428
- declare function sanitizeSpawnEnv(baseEnv: NodeJS.ProcessEnv, overrides?: Record<string, string>): Record<string, string>;
429
- /**
430
- * Apply preferred terminal colour environment variables.
431
- * Ensures TERM is set to xterm-256color and enables colour on Windows.
432
- */
433
- declare function applyTerminalColorEnv(env: Record<string, string>): void;
434
- /**
435
- * Ensure node-pty's spawn-helper binary has execute permissions.
436
- *
437
- * npm's default umask can strip +x from the prebuilt spawn-helper on macOS/Linux,
438
- * causing EACCES when node-pty tries to fork. Best-effort fix.
439
- *
440
- * @param logFn Optional log callback for reporting the fix.
441
- */
442
- declare function ensureNodePtySpawnHelperPermissions(logFn?: (msg: string) => void): void;
443
-
444
- export { type AcquireWritePayload, type AttachSessionPayload, type ClearSessionBufferPayload, type CreateSessionPayload, DEFAULT_SESSION_RING_BUFFER_MAX_BYTES, type DetachSessionPayload, type ForceDetachClientPayload, type GetHostDiagnosticsPayload, type GetSnapshotPayload, type PruneDuplicateSessionsPayload, type ReleaseWritePayload, type ResizeSessionPayload, type RestartSessionPayload, type ResumeSessionPayload, type SendInputPayload, type SendSignalPayload, type SessionAttachedClient, type SessionBufferSnapshot, type SessionClientType, type SessionHostCategory, SessionHostClient, type SessionHostClientOptions, type SessionHostDiagnostics, type SessionHostDuplicateSessionGroup, type SessionHostEndpoint, type SessionHostEvent, type SessionHostEventEnvelope, type SessionHostLogEntry, type SessionHostPruneDuplicatesResult, type SessionHostRecord, SessionHostRegistry, type SessionHostRequest, type SessionHostRequestEnvelope, type SessionHostRequestTrace, type SessionHostResponse, type SessionHostResponseEnvelope, type SessionHostRuntimeTransition, type SessionHostSurfaceKind, type SessionHostWireEnvelope, type SessionLaunchCommand, type SessionLifecycle, type SessionOwnerType, SessionRingBuffer, type SessionRingBufferOptions, type SessionTransport, type SessionWriteOwner, type StopSessionPayload, type UpdateSessionMetaPayload, applyTerminalColorEnv, buildRuntimeDisplayName, buildRuntimeKey, createLineParser, createResponseEnvelope, ensureNodePtySpawnHelperPermissions, formatRuntimeOwner, getDefaultSessionHostEndpoint, getSessionHostRecoveryLabel, getSessionHostSurfaceKind, getWorkspaceLabel, isSessionHostLiveRuntime, isSessionHostRecoverySnapshot, resolveAttachableRuntimeRecord, resolveRuntimeRecord, sanitizeSpawnEnv, writeEnvelope };