@adhdev/daemon-core 0.9.82-rc.17 โ†’ 0.9.82-rc.170

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 (221) hide show
  1. package/dist/boot/process-hardening.d.ts +50 -0
  2. package/dist/chat/source-machine.d.ts +166 -0
  3. package/dist/chat/source-resolver.d.ts +104 -0
  4. package/dist/chat/subscription-updates.d.ts +1 -0
  5. package/dist/cli-adapter-types.d.ts +22 -2
  6. package/dist/cli-adapters/cli-script-runner.d.ts +117 -0
  7. package/dist/cli-adapters/cli-state-engine.d.ts +178 -0
  8. package/dist/cli-adapters/provider-cli-adapter.d.ts +106 -63
  9. package/dist/cli-adapters/provider-cli-parse.d.ts +4 -0
  10. package/dist/cli-adapters/provider-cli-shared.d.ts +29 -0
  11. package/dist/cli-adapters/raw-terminal-io.d.ts +37 -0
  12. package/dist/commands/handler.d.ts +110 -0
  13. package/dist/commands/mesh-coordinator.d.ts +72 -1
  14. package/dist/commands/router.d.ts +22 -0
  15. package/dist/config/chat-history.d.ts +7 -0
  16. package/dist/config/config.d.ts +5 -0
  17. package/dist/config/mesh-config.d.ts +71 -1
  18. package/dist/git/git-commands.d.ts +5 -1
  19. package/dist/index.d.ts +35 -6
  20. package/dist/index.js +18621 -3760
  21. package/dist/index.js.map +1 -1
  22. package/dist/index.mjs +18525 -3732
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/installer.d.ts +1 -4
  25. package/dist/ipc/local-ipc-server.d.ts +91 -0
  26. package/dist/launch.d.ts +1 -1
  27. package/dist/logging/async-batch-writer.d.ts +10 -0
  28. package/dist/mesh/beads-db.d.ts +72 -0
  29. package/dist/mesh/contracts.d.ts +164 -0
  30. package/dist/mesh/coordinator-prompt.d.ts +30 -0
  31. package/dist/mesh/coordinator-registry.d.ts +59 -0
  32. package/dist/mesh/mesh-active-work.d.ts +90 -0
  33. package/dist/mesh/mesh-events.d.ts +96 -5
  34. package/dist/mesh/mesh-fast-forward.d.ts +39 -0
  35. package/dist/mesh/mesh-host-ownership.d.ts +9 -0
  36. package/dist/mesh/mesh-ledger.d.ts +58 -1
  37. package/dist/mesh/mesh-refine-status.d.ts +26 -0
  38. package/dist/mesh/mesh-work-queue.d.ts +44 -5
  39. package/dist/mesh/preview-freshness.d.ts +18 -0
  40. package/dist/mesh/refine-config.d.ts +193 -0
  41. package/dist/mesh/worktree-bootstrap-config.d.ts +113 -0
  42. package/dist/providers/approval-utils.d.ts +13 -0
  43. package/dist/providers/cli-provider-instance.d.ts +9 -3
  44. package/dist/providers/contracts.d.ts +98 -5
  45. package/dist/providers/external-sources.d.ts +71 -0
  46. package/dist/providers/native-history/antigravity-cli-transcript.d.ts +100 -0
  47. package/dist/providers/native-history/claude-cli-transcript.d.ts +70 -0
  48. package/dist/providers/native-history/codex-cli-transcript.d.ts +73 -0
  49. package/dist/providers/native-history/dispatcher.d.ts +24 -0
  50. package/dist/providers/native-history/hermes-cli-transcript.d.ts +30 -0
  51. package/dist/providers/native-history/index.d.ts +13 -0
  52. package/dist/providers/provider-instance.d.ts +3 -0
  53. package/dist/providers/provider-loader.d.ts +26 -4
  54. package/dist/providers/provider-trust.d.ts +31 -0
  55. package/dist/providers/read-chat-contract.d.ts +29 -0
  56. package/dist/providers/sdk/v1/builders/acp/detect-status.d.ts +68 -0
  57. package/dist/providers/sdk/v1/builders/cli/detect-status.d.ts +85 -0
  58. package/dist/providers/sdk/v1/builders/cli/parse-approval-squash.d.ts +59 -0
  59. package/dist/providers/sdk/v1/builders/cli/parse-approval.d.ts +65 -0
  60. package/dist/providers/sdk/v1/builders/cli/parse-session.d.ts +91 -0
  61. package/dist/providers/sdk/v1/builders/cli/visible-region.d.ts +42 -0
  62. package/dist/providers/sdk/v1/fixture-tooling/format.d.ts +126 -0
  63. package/dist/providers/sdk/v1/fixture-tooling/index.d.ts +8 -0
  64. package/dist/providers/sdk/v1/fixture-tooling/replay.d.ts +38 -0
  65. package/dist/providers/sdk/v1/index.d.ts +30 -0
  66. package/dist/providers/sdk/v1/sandbox/README-design.d.ts +193 -0
  67. package/dist/providers/sdk/v1/sandbox/require-whitelist.d.ts +74 -0
  68. package/dist/providers/sdk/v1/sandbox/script-runner.d.ts +98 -0
  69. package/dist/providers/sdk/v1/types/cli/index.d.ts +277 -0
  70. package/dist/providers/sdk/v1/types/common/index.d.ts +169 -0
  71. package/dist/providers/sdk/v1/validators/index.d.ts +5 -0
  72. package/dist/providers/sdk/v1/validators/manifest.d.ts +40 -0
  73. package/dist/providers/sdk/v1/validators/taint.d.ts +52 -0
  74. package/dist/providers/spec/adapter.d.ts +56 -0
  75. package/dist/providers/spec/cli-adapter.d.ts +95 -0
  76. package/dist/providers/spec/driver.d.ts +149 -0
  77. package/dist/providers/spec/evaluator.d.ts +47 -0
  78. package/dist/providers/spec/loader.d.ts +14 -0
  79. package/dist/providers/spec/native-history-executor.d.ts +39 -0
  80. package/dist/providers/spec/route.d.ts +4 -0
  81. package/dist/providers/spec/schema.gen.d.ts +511 -0
  82. package/dist/providers/spec/types.d.ts +212 -0
  83. package/dist/providers/transcript-v2.d.ts +176 -0
  84. package/dist/providers/types/interactive-prompt.d.ts +48 -0
  85. package/dist/repo-mesh-types.d.ts +100 -1
  86. package/dist/sessions/registry.d.ts +3 -0
  87. package/dist/shared-types.d.ts +42 -1
  88. package/dist/status/reporter.d.ts +2 -0
  89. package/dist/status/snapshot.d.ts +1 -0
  90. package/dist/types.d.ts +5 -0
  91. package/package.json +7 -2
  92. package/src/agent-stream/poller.ts +2 -3
  93. package/src/boot/daemon-lifecycle.ts +17 -10
  94. package/src/boot/process-hardening.ts +89 -0
  95. package/src/chat/source-machine.ts +534 -0
  96. package/src/chat/source-resolver.ts +0 -0
  97. package/src/chat/subscription-updates.ts +14 -1
  98. package/src/cli-adapter-types.d.ts +1 -0
  99. package/src/cli-adapter-types.ts +21 -2
  100. package/src/cli-adapters/cli-script-runner.ts +421 -0
  101. package/src/cli-adapters/cli-state-engine.ts +1086 -0
  102. package/src/cli-adapters/provider-cli-adapter.d.ts +1 -1
  103. package/src/cli-adapters/provider-cli-adapter.ts +670 -1137
  104. package/src/cli-adapters/provider-cli-parse.d.ts +1 -0
  105. package/src/cli-adapters/provider-cli-parse.ts +13 -0
  106. package/src/cli-adapters/provider-cli-runtime.ts +3 -1
  107. package/src/cli-adapters/provider-cli-shared.d.ts +2 -0
  108. package/src/cli-adapters/provider-cli-shared.ts +59 -11
  109. package/src/cli-adapters/raw-terminal-io.ts +252 -0
  110. package/src/cli-adapters/terminal-backends/ghostty-vt-backend.ts +17 -1
  111. package/src/cli-adapters/terminal-backends/xterm-backend.ts +8 -1
  112. package/src/commands/chat-commands.ts +1597 -60
  113. package/src/commands/cli-manager.ts +214 -3
  114. package/src/commands/handler.ts +809 -2
  115. package/src/commands/mesh-coordinator.ts +231 -127
  116. package/src/commands/router.ts +3559 -502
  117. package/src/config/chat-history.ts +87 -24
  118. package/src/config/config.ts +12 -0
  119. package/src/config/mesh-config.ts +264 -2
  120. package/src/config/recent-activity.ts +8 -2
  121. package/src/daemon/dev-cli-debug.ts +10 -1
  122. package/src/detection/ide-detector.ts +26 -16
  123. package/src/git/git-commands.ts +17 -5
  124. package/src/git/git-worktree.ts +8 -1
  125. package/src/index.ts +113 -5
  126. package/src/installer.d.ts +1 -1
  127. package/src/installer.ts +8 -6
  128. package/src/ipc/local-ipc-server.ts +278 -0
  129. package/src/launch.d.ts +1 -1
  130. package/src/launch.ts +37 -28
  131. package/src/logging/async-batch-writer.ts +55 -0
  132. package/src/logging/logger.ts +2 -1
  133. package/src/mesh/beads-db.ts +479 -0
  134. package/src/mesh/contracts.ts +329 -0
  135. package/src/mesh/coordinator-prompt.ts +204 -30
  136. package/src/mesh/coordinator-registry.ts +121 -0
  137. package/src/mesh/mesh-active-work.ts +437 -0
  138. package/src/mesh/mesh-events.ts +879 -61
  139. package/src/mesh/mesh-fast-forward.ts +430 -0
  140. package/src/mesh/mesh-host-ownership.ts +73 -0
  141. package/src/mesh/mesh-ledger.ts +457 -104
  142. package/src/mesh/mesh-refine-status.ts +144 -0
  143. package/src/mesh/mesh-work-queue.ts +216 -158
  144. package/src/mesh/preview-freshness.ts +118 -0
  145. package/src/mesh/refine-config.ts +366 -0
  146. package/src/mesh/worktree-bootstrap-config.ts +247 -0
  147. package/src/providers/approval-utils.d.ts +4 -0
  148. package/src/providers/approval-utils.ts +47 -5
  149. package/src/providers/chat-message-normalization.ts +4 -11
  150. package/src/providers/cli-provider-instance.ts +452 -54
  151. package/src/providers/contracts.ts +105 -5
  152. package/src/providers/external-sources.ts +218 -0
  153. package/src/providers/ide-provider-instance.ts +19 -5
  154. package/src/providers/native-history/antigravity-cli-transcript.ts +643 -0
  155. package/src/providers/native-history/claude-cli-transcript.ts +396 -0
  156. package/src/providers/native-history/codex-cli-transcript.ts +419 -0
  157. package/src/providers/native-history/dispatcher.ts +227 -0
  158. package/src/providers/native-history/hermes-cli-transcript.ts +230 -0
  159. package/src/providers/native-history/index.ts +30 -0
  160. package/src/providers/provider-instance.ts +3 -0
  161. package/src/providers/provider-loader.ts +585 -50
  162. package/src/providers/provider-schema.ts +31 -13
  163. package/src/providers/provider-trust.ts +114 -0
  164. package/src/providers/read-chat-contract.ts +76 -16
  165. package/src/providers/sdk/README.md +49 -0
  166. package/src/providers/sdk/v1/builders/acp/detect-status.ts +144 -0
  167. package/src/providers/sdk/v1/builders/cli/detect-status.ts +262 -0
  168. package/src/providers/sdk/v1/builders/cli/parse-approval-squash.ts +158 -0
  169. package/src/providers/sdk/v1/builders/cli/parse-approval.ts +250 -0
  170. package/src/providers/sdk/v1/builders/cli/parse-session.ts +276 -0
  171. package/src/providers/sdk/v1/builders/cli/visible-region.ts +143 -0
  172. package/src/providers/sdk/v1/fixture-tooling/format.ts +130 -0
  173. package/src/providers/sdk/v1/fixture-tooling/index.ts +22 -0
  174. package/src/providers/sdk/v1/fixture-tooling/replay.ts +352 -0
  175. package/src/providers/sdk/v1/index.ts +152 -0
  176. package/src/providers/sdk/v1/sandbox/README-design.ts +195 -0
  177. package/src/providers/sdk/v1/sandbox/require-whitelist.ts +472 -0
  178. package/src/providers/sdk/v1/sandbox/script-runner.ts +150 -0
  179. package/src/providers/sdk/v1/schemas/cli/provider.schema.json +458 -0
  180. package/src/providers/sdk/v1/schemas/primitives/acp-session-protocol-v1.json +131 -0
  181. package/src/providers/sdk/v1/schemas/primitives/native-history-codex-rollout-v1.json +66 -0
  182. package/src/providers/sdk/v1/schemas/primitives/tui-approval-squash-v1.json +91 -0
  183. package/src/providers/sdk/v1/schemas/primitives/tui-assistant-block-v1.json +91 -0
  184. package/src/providers/sdk/v1/schemas/primitives/tui-cue-ordering-v1.json +47 -0
  185. package/src/providers/sdk/v1/schemas/primitives/tui-dispatch-order-v1.json +32 -0
  186. package/src/providers/sdk/v1/schemas/primitives/tui-footer-chrome-v1.json +42 -0
  187. package/src/providers/sdk/v1/schemas/primitives/tui-index-finder-v1.json +27 -0
  188. package/src/providers/sdk/v1/schemas/primitives/tui-modal-v1.json +125 -0
  189. package/src/providers/sdk/v1/schemas/primitives/tui-prompt-marker-v1.json +45 -0
  190. package/src/providers/sdk/v1/schemas/primitives/tui-session-id-extraction-v1.json +46 -0
  191. package/src/providers/sdk/v1/schemas/primitives/tui-settled-prompt-v1.json +71 -0
  192. package/src/providers/sdk/v1/schemas/primitives/tui-spinner-v1.json +83 -0
  193. package/src/providers/sdk/v1/schemas/primitives/tui-transcript-pty-v1.json +83 -0
  194. package/src/providers/sdk/v1/schemas/primitives/tui-visible-region-v1.json +57 -0
  195. package/src/providers/sdk/v1/schemas/primitives/tui-welcome-screen-v1.json +35 -0
  196. package/src/providers/sdk/v1/types/cli/index.ts +365 -0
  197. package/src/providers/sdk/v1/types/common/index.ts +210 -0
  198. package/src/providers/sdk/v1/validators/index.ts +19 -0
  199. package/src/providers/sdk/v1/validators/manifest.ts +110 -0
  200. package/src/providers/sdk/v1/validators/taint.ts +309 -0
  201. package/src/providers/spec/adapter.ts +168 -0
  202. package/src/providers/spec/cli-adapter.ts +430 -0
  203. package/src/providers/spec/driver.ts +502 -0
  204. package/src/providers/spec/evaluator.ts +298 -0
  205. package/src/providers/spec/loader.ts +130 -0
  206. package/src/providers/spec/native-history-executor.ts +623 -0
  207. package/src/providers/spec/route.ts +51 -0
  208. package/src/providers/spec/schema.gen.ts +511 -0
  209. package/src/providers/spec/schema.json +211 -0
  210. package/src/providers/spec/types.ts +231 -0
  211. package/src/providers/transcript-v2.ts +567 -0
  212. package/src/providers/types/interactive-prompt.ts +297 -0
  213. package/src/providers/version-archive.ts +38 -20
  214. package/src/repo-mesh-types.ts +110 -1
  215. package/src/sessions/registry.ts +3 -0
  216. package/src/shared-types.ts +45 -1
  217. package/src/status/builders.ts +24 -6
  218. package/src/status/reporter.ts +15 -0
  219. package/src/status/snapshot.ts +84 -25
  220. package/src/system/host-memory.ts +29 -12
  221. package/src/types.ts +5 -0
@@ -18,6 +18,7 @@ import { loadConfig } from '../config/config.js';
18
18
  import { loadState, saveState } from '../config/state-store.js';
19
19
  import { getWorkspaceState, resolveLaunchDirectory } from '../config/workspaces.js';
20
20
  import { appendRecentActivity } from '../config/recent-activity.js';
21
+ import { unregisterMeshCoordinator } from '../mesh/coordinator-registry.js';
21
22
  import { upsertSavedProviderSession } from '../config/saved-sessions.js';
22
23
  import { buildLegacyModelModeSummaryMetadata, normalizeProviderSummaryMetadata } from '../providers/summary-metadata.js';
23
24
  import { CliProviderInstance } from '../providers/cli-provider-instance.js';
@@ -80,6 +81,114 @@ export interface CliManagerDeps {
80
81
 
81
82
  type CommandResult = { success: boolean;[key: string]: unknown };
82
83
 
84
+ const BUSY_AGENT_STATUSES = new Set(['generating', 'running', 'streaming', 'starting', 'busy', 'waiting', 'waiting_approval', 'long_generating']);
85
+ const ZERO_MESSAGE_STARTING_SEND_WAIT_MS = 2_000;
86
+
87
+ function normalizeAgentStatus(value: unknown): string {
88
+ return typeof value === 'string' ? value.trim().toLowerCase() : '';
89
+ }
90
+
91
+ function hasNonEmptyModalButtons(activeModal: unknown): boolean {
92
+ const buttons = (activeModal as any)?.buttons;
93
+ return Array.isArray(buttons) && buttons.some((button) => String(button || '').trim().length > 0);
94
+ }
95
+
96
+ function hasAdapterPendingResponse(adapter: any): boolean {
97
+ if (adapter?.isWaitingForResponse === true) return true;
98
+ if (adapter?.currentTurnScope) return true;
99
+ try {
100
+ if (typeof adapter?.isProcessing === 'function' && adapter.isProcessing()) return true;
101
+ } catch { /* defensive: send guard should not fail on diagnostics */ }
102
+ try {
103
+ const partial = typeof adapter?.getPartialResponse === 'function' ? adapter.getPartialResponse() : '';
104
+ if (typeof partial === 'string' && partial.trim()) return true;
105
+ } catch { /* defensive: missing partial means no pending evidence */ }
106
+ return false;
107
+ }
108
+
109
+ function countMessages(value: unknown): number {
110
+ return Array.isArray(value) ? value.length : 0;
111
+ }
112
+
113
+ function hasFinalAssistantMessage(value: unknown): boolean {
114
+ const messages = Array.isArray(value) ? value : [];
115
+ const last = messages[messages.length - 1] as any;
116
+ if (!last || last.role !== 'assistant') return false;
117
+ if (last.bubbleState === 'streaming') return false;
118
+ if (last.meta?.streaming === true) return false;
119
+ return typeof last.content === 'string' && last.content.trim().length > 0;
120
+ }
121
+
122
+ function hasZeroMessageStartingLaunch(adapter: any): boolean {
123
+ const adapterStatus = adapter?.getStatus?.({ allowParse: false }) ?? adapter?.getStatus?.() ?? {};
124
+ const parsedStatus = typeof adapter?.getScriptParsedStatus === 'function'
125
+ ? adapter.getScriptParsedStatus()
126
+ : {};
127
+ const adapterRawStatus = normalizeAgentStatus(adapterStatus?.status);
128
+ const parsedRawStatus = normalizeAgentStatus(parsedStatus?.status);
129
+ if (adapterRawStatus !== 'starting') return false;
130
+ if (parsedRawStatus && parsedRawStatus !== 'starting' && parsedRawStatus !== 'generating') return false;
131
+ if (hasNonEmptyModalButtons(adapterStatus?.activeModal ?? adapterStatus?.modal ?? parsedStatus?.activeModal ?? parsedStatus?.modal)) return false;
132
+ if (countMessages(adapterStatus?.messages) > 0 || countMessages(parsedStatus?.messages) > 0) return false;
133
+ return !hasAdapterPendingResponse(adapter);
134
+ }
135
+
136
+ function hasCompletedStartingLaunch(adapter: any): boolean {
137
+ const adapterStatus = adapter?.getStatus?.({ allowParse: false }) ?? adapter?.getStatus?.() ?? {};
138
+ const adapterRawStatus = normalizeAgentStatus(adapterStatus?.status);
139
+ if (adapterRawStatus !== 'starting') return false;
140
+ if (hasAdapterPendingResponse(adapter)) return false;
141
+
142
+ const parsedStatus = typeof adapter?.getScriptParsedStatus === 'function'
143
+ ? adapter.getScriptParsedStatus()
144
+ : {};
145
+ const parsedRawStatus = normalizeAgentStatus(parsedStatus?.status);
146
+ if (parsedRawStatus !== 'idle') return false;
147
+ if (hasNonEmptyModalButtons(adapterStatus?.activeModal ?? adapterStatus?.modal ?? parsedStatus?.activeModal ?? parsedStatus?.modal)) return false;
148
+ return hasFinalAssistantMessage(parsedStatus?.messages);
149
+ }
150
+
151
+ function shouldSuppressStaleParsedBusyStatus(adapterStatus: string, parsedStatus: any, adapter: any): boolean {
152
+ const parsedRawStatus = normalizeAgentStatus(parsedStatus?.status);
153
+ if (!BUSY_AGENT_STATUSES.has(parsedRawStatus)) return false;
154
+ if (adapterStatus !== 'idle') return false;
155
+ if (hasNonEmptyModalButtons(parsedStatus?.activeModal ?? parsedStatus?.modal)) return false;
156
+ return !hasAdapterPendingResponse(adapter);
157
+ }
158
+
159
+ function getEffectiveAgentSendStatus(adapter: any): string {
160
+ const adapterStatus = normalizeAgentStatus(adapter?.getStatus?.({ allowParse: false })?.status ?? adapter?.getStatus?.()?.status);
161
+ if (adapterStatus === 'starting' && hasCompletedStartingLaunch(adapter)) return 'idle';
162
+ if (adapterStatus && adapterStatus !== 'idle') return adapterStatus;
163
+ if (adapterStatus !== 'idle') return adapterStatus;
164
+
165
+ if (typeof adapter?.getScriptParsedStatus !== 'function') return adapterStatus;
166
+ try {
167
+ const parsedStatus = adapter.getScriptParsedStatus();
168
+ const parsedRawStatus = normalizeAgentStatus(parsedStatus?.status);
169
+ if (BUSY_AGENT_STATUSES.has(parsedRawStatus) && !shouldSuppressStaleParsedBusyStatus(adapterStatus, parsedStatus, adapter)) {
170
+ return parsedRawStatus;
171
+ }
172
+ } catch {
173
+ return adapterStatus;
174
+ }
175
+ return adapterStatus;
176
+ }
177
+
178
+ async function waitForZeroMessageStartingLaunch(adapter: any): Promise<boolean> {
179
+ try {
180
+ if (!hasZeroMessageStartingLaunch(adapter)) return false;
181
+ } catch {
182
+ return false;
183
+ }
184
+ await new Promise(resolve => setTimeout(resolve, ZERO_MESSAGE_STARTING_SEND_WAIT_MS));
185
+ try {
186
+ return hasZeroMessageStartingLaunch(adapter);
187
+ } catch {
188
+ return false;
189
+ }
190
+ }
191
+
83
192
  export interface CliTransportFactoryParams {
84
193
  runtimeId: string;
85
194
  providerType: string;
@@ -255,10 +364,14 @@ function detectExplicitProviderSessionId(
255
364
 
256
365
  const subcommands = resume?.sessionIdFromSubcommand;
257
366
  if (Array.isArray(subcommands) && subcommands.length > 0) {
367
+ const hasResumeSubcommand = args.some((arg) => subcommands.includes(arg));
258
368
  const subcommandSessionId = readSubcommandSessionId(args, subcommands);
259
369
  if (subcommandSessionId) {
260
370
  return { providerSessionId: subcommandSessionId, launchMode: 'resume' };
261
371
  }
372
+ if (hasResumeSubcommand) {
373
+ return { launchMode: 'resume' };
374
+ }
262
375
  }
263
376
 
264
377
  return { launchMode: 'manual' };
@@ -292,6 +405,12 @@ export function resolveCliSessionBinding(
292
405
  launchMode: explicit.launchMode,
293
406
  };
294
407
  }
408
+ if (explicit.launchMode === 'resume') {
409
+ return {
410
+ cliArgs: baseArgs,
411
+ launchMode: 'resume',
412
+ };
413
+ }
295
414
  if (explicit.launchMode === 'manual' && hasArg(baseArgs || [], ['--session-id'])) {
296
415
  return {
297
416
  cliArgs: baseArgs,
@@ -435,7 +554,9 @@ export class DaemonCliManager {
435
554
  providerSessionId,
436
555
  attachExisting,
437
556
  );
438
- return new ProviderCliAdapter(resolvedProvider as CliProviderModule, workingDir, cliArgs, extraEnv || {}, transportFactory);
557
+ const adapter = new ProviderCliAdapter(resolvedProvider as CliProviderModule, workingDir, cliArgs, extraEnv || {}, transportFactory);
558
+ if (providerSessionId) adapter.updateRuntimeMeta({ providerSessionId });
559
+ return adapter;
439
560
  }
440
561
 
441
562
  throw new Error(`No CLI provider found for '${cliType}'. Create a provider.js in providers/cli/${cliType}/`);
@@ -457,6 +578,7 @@ export class DaemonCliManager {
457
578
  this.deps.removeAgentTracking(key);
458
579
  sessionRegistry?.unregisterByInstanceKey(key);
459
580
  instanceManager?.removeInstance(key);
581
+ unregisterMeshCoordinator(key);
460
582
  LOG.info('CLI', `๐Ÿงน Auto-cleaned ${status.status} CLI: ${cliType}`);
461
583
  this.deps.onStatusChange();
462
584
  }
@@ -516,6 +638,17 @@ export class DaemonCliManager {
516
638
  transport: 'pty',
517
639
  adapterKey: key,
518
640
  instanceKey: key,
641
+ // attachExisting === true means we're restoring an already-spawned
642
+ // hosted runtime after a daemon restart, not starting a fresh PTY.
643
+ // The real spawn time is in the past and we don't have it on the
644
+ // restored descriptor; pinning spawnedAtMs to Date.now() in that
645
+ // case would push the native-history session-floor cutoff past
646
+ // every existing transcript file, so the agy/hermes/claude reader
647
+ // would return null even though the transcript on disk is fresh.
648
+ // 0 disables the floor for this session โ€” recent_window_ms in the
649
+ // spec still bounds how far back we look. Fresh launches still
650
+ // get a proper floor so prior-session leak protection holds.
651
+ spawnedAtMs: attachExisting ? 0 : Date.now(),
519
652
  });
520
653
  } catch (spawnErr: any) {
521
654
  LOG.error('CLI', `[${cliType}] Spawn failed: ${spawnErr?.message}`);
@@ -783,6 +916,7 @@ export class DaemonCliManager {
783
916
  this.deps.removeAgentTracking(key);
784
917
  this.deps.getSessionRegistry?.()?.unregisterByInstanceKey(key);
785
918
  this.deps.getInstanceManager()?.removeInstance(key);
919
+ unregisterMeshCoordinator(key);
786
920
  LOG.info('CLI', `๐Ÿ›‘ Agent stopped: ${adapter.cliType} in ${adapter.workingDir}`);
787
921
  this.deps.onStatusChange();
788
922
  } else {
@@ -792,6 +926,7 @@ export class DaemonCliManager {
792
926
  this.deps.getSessionRegistry?.()?.unregisterByInstanceKey(key);
793
927
  im.removeInstance(key);
794
928
  this.deps.removeAgentTracking(key);
929
+ unregisterMeshCoordinator(key);
795
930
  LOG.warn('CLI', `๐Ÿงน Force-removed orphan entry: ${key}`);
796
931
  this.deps.onStatusChange();
797
932
  }
@@ -964,6 +1099,25 @@ export class DaemonCliManager {
964
1099
  env: args?.env,
965
1100
  })
966
1101
  : null;
1102
+ // Untrusted-provider gate: an external source that ships JS
1103
+ // hooks needs explicit user confirmation before its first
1104
+ // launch. Dashboards add `confirmExternalUntrusted: true` to
1105
+ // the launch args after showing the trust modal. Without
1106
+ // that ack we refuse to spawn and tell the caller why.
1107
+ const provLookup = this.providerLoader.getMeta(this.providerLoader.resolveAlias(cliType)) as any;
1108
+ const provTrust = provLookup?._sourceTrust;
1109
+ if (provTrust === 'external-untrusted' && args?.confirmExternalUntrusted !== true) {
1110
+ return {
1111
+ success: false,
1112
+ error: 'untrusted_external_provider',
1113
+ provider: {
1114
+ type: provLookup?.type ?? cliType,
1115
+ sourceName: provLookup?._sourceName ?? null,
1116
+ trust: provTrust,
1117
+ },
1118
+ hint: 'Resend launch_cli with confirmExternalUntrusted=true after the user explicitly approves running JavaScript from this 3rd-party source.',
1119
+ };
1120
+ }
967
1121
  const started = await this.startSession(
968
1122
  cliType,
969
1123
  dir,
@@ -1030,6 +1184,45 @@ export class DaemonCliManager {
1030
1184
  this.deps.onStatusChange();
1031
1185
  return { success: true, id: found.key, mode };
1032
1186
  }
1187
+ case 'record_provider_pty': {
1188
+ const cliType = args?.type || args?.cliType;
1189
+ if (!cliType) {
1190
+ return { success: false, error: '`type` (provider type) is required', code: 'MISSING_TYPE' };
1191
+ }
1192
+ const targetSessionId = typeof args?.targetSessionId === 'string' ? args.targetSessionId : '';
1193
+ const dir = args?.dir || '';
1194
+ const found = (targetSessionId ? this.findAdapterBySessionId(targetSessionId) : null)
1195
+ || this.findAdapter(cliType, { instanceKey: targetSessionId, dir });
1196
+ if (!found) {
1197
+ return {
1198
+ success: false,
1199
+ error: `No running ${cliType} session. Launch one first (adhdev launch ${cliType}) or pass --target-session-id.`,
1200
+ code: 'NO_RUNNING_SESSION',
1201
+ };
1202
+ }
1203
+ const instance = this.deps.getInstanceManager()?.getInstance(found.key);
1204
+ if (!(instance instanceof CliProviderInstance)) {
1205
+ return { success: false, error: 'CLI instance not available', code: 'CLI_INSTANCE_NOT_FOUND' };
1206
+ }
1207
+ const adapter = instance.getAdapter();
1208
+ if (!adapter || typeof (adapter as any).getAccumulatedRawBuffer !== 'function') {
1209
+ return { success: false, error: 'Adapter does not expose PTY buffer', code: 'ADAPTER_NOT_RECORDABLE' };
1210
+ }
1211
+ const buffer = (adapter as any).getAccumulatedRawBuffer() as { text: string; droppedChars: number };
1212
+ const maxBytes = Number(args?.maxBytes) > 0 ? Number(args.maxBytes) : 262144;
1213
+ const truncated = buffer.text.length > maxBytes;
1214
+ const ptyBytes = truncated ? buffer.text.slice(-maxBytes) : buffer.text;
1215
+ return {
1216
+ success: true,
1217
+ cliType,
1218
+ sessionId: found.key,
1219
+ ptyBytes,
1220
+ bytes: ptyBytes.length,
1221
+ truncated,
1222
+ droppedChars: buffer.droppedChars,
1223
+ capturedAt: Date.now(),
1224
+ };
1225
+ }
1033
1226
  case 'restart_session': {
1034
1227
  const cliType = args?.cliType || args?.agentType || args?.ideType;
1035
1228
  const cfg = loadConfig();
@@ -1073,6 +1266,12 @@ export class DaemonCliManager {
1073
1266
  const { adapter, key } = found;
1074
1267
 
1075
1268
  if (action === 'send_chat') {
1269
+ let currentStatus = getEffectiveAgentSendStatus(adapter);
1270
+ if (currentStatus === 'starting' && await waitForZeroMessageStartingLaunch(adapter)) {
1271
+ currentStatus = 'idle';
1272
+ } else if (currentStatus === 'starting') {
1273
+ currentStatus = getEffectiveAgentSendStatus(adapter);
1274
+ }
1076
1275
  const input = normalizeInputEnvelope(args?.input ? { input: args.input } : args);
1077
1276
  const provider = this.providerLoader.resolve(agentType) || this.providerLoader.getMeta(agentType);
1078
1277
  if (provider?.category === 'acp') {
@@ -1082,8 +1281,20 @@ export class DaemonCliManager {
1082
1281
  }
1083
1282
  const message = input.textFallback;
1084
1283
  if (!message) throw new Error('message required for send_chat');
1085
- await adapter.sendMessage(message);
1086
- return { success: true, status: 'generating' };
1284
+ const forceSend = args?.force === true || args?.forceSend === true;
1285
+ if (forceSend && typeof (adapter as any).forceSendMessage === 'function') {
1286
+ await (adapter as any).forceSendMessage(message);
1287
+ } else if (forceSend) {
1288
+ await adapter.sendMessage(message, { force: true });
1289
+ } else {
1290
+ await adapter.sendMessage(message);
1291
+ }
1292
+ return {
1293
+ success: true,
1294
+ status: BUSY_AGENT_STATUSES.has(currentStatus) ? currentStatus : 'generating',
1295
+ ...(BUSY_AGENT_STATUSES.has(currentStatus) ? { queued: true, queuedReason: 'agent_runtime_busy' } : {}),
1296
+ ...(forceSend ? { forceSent: true, queued: false } : {}),
1297
+ };
1087
1298
  } else if (action === 'clear_history') {
1088
1299
  if (typeof adapter.clearHistory === 'function') adapter.clearHistory();
1089
1300
  return { success: true, cleared: true };