@adhdev/daemon-core 0.9.82-rc.552 → 0.9.82-rc.554

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 (39) hide show
  1. package/dist/cli-adapter-types.d.ts +29 -0
  2. package/dist/cli-adapters/provider-cli-adapter.d.ts +80 -1
  3. package/dist/cli-adapters/provider-cli-shared.d.ts +55 -0
  4. package/dist/cli-adapters/terminal-screen.d.ts +5 -0
  5. package/dist/commands/stream-commands.d.ts +31 -0
  6. package/dist/index.d.ts +1 -1
  7. package/dist/index.js +789 -15
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.mjs +785 -12
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/mesh/mesh-ledger.d.ts +1 -1
  12. package/dist/mesh/mesh-refine-gates.d.ts +86 -0
  13. package/dist/providers/cli-provider-instance.d.ts +97 -0
  14. package/dist/providers/provider-instance.d.ts +9 -0
  15. package/dist/providers/spec/adapter.d.ts +7 -0
  16. package/dist/providers/spec/cli-adapter.d.ts +64 -0
  17. package/dist/providers/spec/fsm-driver.d.ts +11 -0
  18. package/dist/repo-mesh-types.d.ts +23 -0
  19. package/package.json +3 -3
  20. package/src/cli-adapter-types.ts +29 -0
  21. package/src/cli-adapters/provider-cli-adapter.ts +135 -0
  22. package/src/cli-adapters/provider-cli-shared.ts +172 -0
  23. package/src/cli-adapters/terminal-screen.ts +5 -0
  24. package/src/commands/handler.ts +4 -0
  25. package/src/commands/router-refine.ts +40 -1
  26. package/src/commands/router.ts +15 -0
  27. package/src/commands/stream-commands.ts +125 -0
  28. package/src/index.ts +1 -0
  29. package/src/mesh/coordinator-prompt.ts +2 -0
  30. package/src/mesh/mesh-events-utils.ts +15 -0
  31. package/src/mesh/mesh-ledger.ts +6 -0
  32. package/src/mesh/mesh-refine-gates.ts +256 -0
  33. package/src/providers/cli-provider-instance.ts +277 -6
  34. package/src/providers/provider-instance-manager.ts +11 -0
  35. package/src/providers/provider-instance.ts +10 -0
  36. package/src/providers/spec/adapter.ts +7 -0
  37. package/src/providers/spec/cli-adapter.ts +122 -0
  38. package/src/providers/spec/fsm-driver.ts +5 -0
  39. package/src/repo-mesh-types.ts +35 -0
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import type { ChatMessage } from './types.js';
7
7
  import type { InteractivePrompt, InteractivePromptResponse } from './providers/types/interactive-prompt.js';
8
+ import type { MeshSendKeyItem, MeshSendKeyName } from './cli-adapters/provider-cli-shared.js';
8
9
  export interface CliAdapterStatus {
9
10
  status?: string;
10
11
  parsedStatus?: string;
@@ -118,6 +119,34 @@ export interface CliAdapter {
118
119
  cancel(): void;
119
120
  isProcessing(): boolean;
120
121
  isReady(): boolean;
122
+ isAlive?(): boolean;
123
+ getTerminalScreenSnapshot?(maxBytes?: number): {
124
+ text: string;
125
+ cursor: {
126
+ col: number;
127
+ row: number;
128
+ };
129
+ cols: number;
130
+ rows: number;
131
+ truncated: boolean;
132
+ originalBytes: number;
133
+ returnedBytes: number;
134
+ hash: string;
135
+ };
136
+ injectKeys?(items: MeshSendKeyItem[], opts?: {
137
+ allowModalOverride?: boolean;
138
+ }): Promise<{
139
+ ok: true;
140
+ keys: MeshSendKeyName[];
141
+ hasDestructive: boolean;
142
+ submits: boolean;
143
+ bytes: number;
144
+ } | {
145
+ ok: false;
146
+ refused: 'submit_race' | 'actionable_modal';
147
+ keys: MeshSendKeyName[];
148
+ hasDestructive: boolean;
149
+ }>;
121
150
  setOnStatusChange(callback: () => void): void;
122
151
  updateRuntimeSettings?(settings: Record<string, unknown>): void;
123
152
  setCliScripts?(scripts: Record<string, unknown>): void;
@@ -16,7 +16,7 @@
16
16
  import type { CliAdapter, CliLaunchInfo } from '../cli-adapter-types.js';
17
17
  import type { InteractivePromptResponse } from '../providers/types/interactive-prompt.js';
18
18
  import { type PtyRuntimeMetadata, type PtyTransportFactory } from './pty-transport.js';
19
- import { type CliProviderModule, type CliScripts, type CliSessionStatus, type CliTraceEntry, type ParsedSession } from './provider-cli-shared.js';
19
+ import { type MeshSendKeyItem, type MeshSendKeyName, type CliProviderModule, type CliScripts, type CliSessionStatus, type CliTraceEntry, type ParsedSession } from './provider-cli-shared.js';
20
20
  import { CliStateEngine, type CliBufferSnapshot } from './cli-state-engine.js';
21
21
  import { type TurnParseScope } from './provider-cli-parse.js';
22
22
  import { type ProviderResolutionMeta } from './provider-cli-config.js';
@@ -109,6 +109,8 @@ export declare class ProviderCliAdapter implements CliAdapter {
109
109
  private static readonly MAX_ACCUMULATED_BUFFER;
110
110
  private parsedStatusCache;
111
111
  private static readonly SCREEN_SNAPSHOT_MIN_INTERVAL_MS;
112
+ private static readonly TERMINAL_SNAPSHOT_DEFAULT_MAX_BYTES;
113
+ private static readonly TERMINAL_SNAPSHOT_ABSOLUTE_MAX_BYTES;
112
114
  private static readonly STATIC_IDLE_POLL_CONFIRM_COUNT;
113
115
  private readonly providerResolutionMeta;
114
116
  private getBufferState;
@@ -340,6 +342,83 @@ export declare class ProviderCliAdapter implements CliAdapter {
340
342
  /** Returns a point-in-time snapshot of all buffer/screen state for external consumers (e.g. CliStateEngine). */
341
343
  getSnapshot(): CliBufferSnapshot;
342
344
  isAlive(): boolean;
345
+ /**
346
+ * MESH-READ-TERMINAL (feature 2: RAW terminal read). Narrow, least-privilege
347
+ * read of the CURRENT rendered viewport for mesh_read_terminal. Deliberately
348
+ * NARROWER than getSnapshot()/getDebugSnapshot():
349
+ * - It returns ONLY the terminal's current rendered viewport (what a human
350
+ * would see on screen right now), the cursor position and the viewport
351
+ * size. NO debug buffers, NO parser/FSM state, NO scrollback/history.
352
+ * - It does NOT call getParseScreenText() (which may graft an older snapshot
353
+ * onto the current frame for parse accuracy) — the caller asked for the
354
+ * live viewport, not a parse-optimized composite.
355
+ * - The payload is bounded in BYTES (UTF-8) with bottom-tail preservation so
356
+ * a screen of multi-byte glyphs can never exceed the MCP payload cap. See
357
+ * truncateToByteTailByLine.
358
+ *
359
+ * SECURITY NOTE: the raw viewport can contain tokens / command args / env
360
+ * values / user data. Callers MUST gate this on mesh ownership and MUST NOT
361
+ * log the returned text. Opt-in redaction is intentionally out of scope for
362
+ * this feature and left as a future enhancement.
363
+ *
364
+ * `maxBytes` is clamped to [1KiB, ABSOLUTE_MAX] (default 32KiB, hard cap 64KiB).
365
+ */
366
+ getTerminalScreenSnapshot(maxBytes?: number): {
367
+ text: string;
368
+ cursor: {
369
+ col: number;
370
+ row: number;
371
+ };
372
+ cols: number;
373
+ rows: number;
374
+ truncated: boolean;
375
+ originalBytes: number;
376
+ returnedBytes: number;
377
+ hash: string;
378
+ };
379
+ /**
380
+ * MESH-SEND-KEYS (feature 3: key injection). Inject a STRUCTURED key sequence
381
+ * into the PTY for the mesh_send_keys tool. Reuses the same serialized write
382
+ * path as sends (writeToPty via writeRaw semantics) so the injection FIFO-
383
+ * orders behind any in-flight write.
384
+ *
385
+ * Two guards run INSIDE this method, immediately before the write, so they see
386
+ * a consistent snapshot of the adapter's submit/echo/queue state (no async gap
387
+ * between check and write — the encode is synchronous and the write is chained
388
+ * atomically after it):
389
+ *
390
+ * 1. submit-race recheck (echo-gate): even though writeToPty is FIFO, an
391
+ * already-SCHEDULED echo-gated Enter (engine.submitPendingUntil in the
392
+ * future), an armed stuck-submit retry (submitRetryTimer), or an in-flight
393
+ * pending-outbound flush can submit at a DIFFERENT tick than our write —
394
+ * so an injected literal could be submitted by a pending Enter, or our
395
+ * ENTER could submit a half-typed pending body. When any of those is live
396
+ * we REFUSE the injection rather than interleave.
397
+ *
398
+ * 2. modal fail-closed: if the session is parked on an actionable approval
399
+ * modal, refuse a NON-destructive injection (ENTER/text/arrows) and direct
400
+ * the caller to mesh_approve — so a modal choice can't be confirmed via
401
+ * send_keys to bypass the approval policy. (A destructive ESC/CTRL_C, which
402
+ * dismisses rather than confirms, is allowed to proceed past this gate; it
403
+ * is separately gated by confirm_destructive + policy at the tool layer.)
404
+ *
405
+ * The caller (tool layer) owns the destructive-key double gate and the audit
406
+ * ledger. This method NEVER logs the literal text (only key enums / byte len).
407
+ */
408
+ injectKeys(items: MeshSendKeyItem[], opts?: {
409
+ allowModalOverride?: boolean;
410
+ }): Promise<{
411
+ ok: true;
412
+ keys: MeshSendKeyName[];
413
+ hasDestructive: boolean;
414
+ submits: boolean;
415
+ bytes: number;
416
+ } | {
417
+ ok: false;
418
+ refused: 'submit_race' | 'actionable_modal';
419
+ keys: MeshSendKeyName[];
420
+ hasDestructive: boolean;
421
+ }>;
343
422
  flushOutboundQueue(): void;
344
423
  writeRaw(data: string | Buffer): Promise<void>;
345
424
  resolveModal(buttonIndex: number): void;
@@ -295,6 +295,61 @@ export declare class TerminalTranscriptAccumulator {
295
295
  private applyCsi;
296
296
  }
297
297
  export declare function sanitizeTerminalText(str: string): string;
298
+ /** Named PTY keys the send-keys tool accepts (closed enum). */
299
+ export type MeshSendKeyName = 'ENTER' | 'ESC' | 'CTRL_C' | 'UP' | 'DOWN' | 'LEFT' | 'RIGHT' | 'TAB' | 'BACKSPACE';
300
+ /** Exact terminal byte sequence for each named key. */
301
+ export declare const MESH_SEND_KEY_ENCODING: Record<MeshSendKeyName, string>;
302
+ export declare const MESH_DESTRUCTIVE_KEYS: ReadonlySet<MeshSendKeyName>;
303
+ export type MeshSendKeyItem = {
304
+ text: string;
305
+ } | {
306
+ key: MeshSendKeyName;
307
+ };
308
+ export interface MeshSendKeysEncodeResult {
309
+ /** The concatenated byte sequence to write to the PTY (single atomic write). */
310
+ sequence: string;
311
+ /** Named keys present, in order (for audit — text bodies are NOT recorded). */
312
+ keys: MeshSendKeyName[];
313
+ /** True if any item is a destructive key (CTRL_C / ESC). */
314
+ hasDestructive: boolean;
315
+ /** True if the sequence submits (ends with an ENTER/CR) — informational. */
316
+ submits: boolean;
317
+ }
318
+ /** Per-call limits (auditability + safety — no unbounded blast). */
319
+ export declare const MESH_SEND_KEYS_MAX_ITEMS = 64;
320
+ export declare const MESH_SEND_KEYS_MAX_TEXT_BYTES = 4096;
321
+ /**
322
+ * Validate + encode a structured key sequence into the exact bytes to write.
323
+ * Throws on an invalid key name, an over-limit item count, or an over-limit
324
+ * total text byte length. text+ENTER (or any text followed by ENTER) is encoded
325
+ * as ONE contiguous string so the caller can submit it in a single atomic write
326
+ * — no interleaving between the text and its submit key.
327
+ */
328
+ export declare function encodeMeshSendKeys(items: MeshSendKeyItem[]): MeshSendKeysEncodeResult;
329
+ /**
330
+ * MESH-READ-TERMINAL (feature 2): result of a byte-bounded, bottom-tail terminal
331
+ * screen truncation. The bound is in BYTES (UTF-8), not characters, because a
332
+ * screen full of multi-byte glyphs can blow past an MCP payload cap even when the
333
+ * character count looks safe. The bottom (tail) of the screen is preserved — the
334
+ * prompt, an active modal and the most recent output all live at the bottom — so
335
+ * a truncated read still shows the coordinator the actionable frame.
336
+ */
337
+ export interface ByteTailTruncation {
338
+ text: string;
339
+ truncated: boolean;
340
+ /** UTF-8 byte length of the full input before truncation. */
341
+ originalBytes: number;
342
+ /** UTF-8 byte length of the returned (possibly truncated) text. */
343
+ returnedBytes: number;
344
+ }
345
+ /**
346
+ * Truncate `text` to at most `maxBytes` UTF-8 bytes, preserving whole lines from
347
+ * the BOTTOM up (the prompt/modal/recent output). Never splits a line and never
348
+ * splits a UTF-8 code point (whole-line granularity guarantees valid UTF-8). If
349
+ * even the single last line exceeds the bound, that line is hard-clipped on a
350
+ * safe UTF-8 boundary from its END so the tail is still returned intact-ish.
351
+ */
352
+ export declare function truncateToByteTailByLine(text: string, maxBytes: number): ByteTailTruncation;
298
353
  export declare function listCliScriptNames(scripts: CliScripts | undefined): string[];
299
354
  export declare function buildCliScreenSnapshot(text: string): CliScreenSnapshot;
300
355
  export declare const buildCliSpawnEnv: typeof sanitizeSpawnEnv;
@@ -21,6 +21,11 @@ export declare class TerminalScreen {
21
21
  col: number;
22
22
  row: number;
23
23
  };
24
+ /** Current viewport dimensions (cols × rows). */
25
+ getSize(): {
26
+ cols: number;
27
+ rows: number;
28
+ };
24
29
  dispose(): void;
25
30
  private createBackend;
26
31
  }
@@ -7,6 +7,37 @@ export declare function handleSelectSession(h: CommandHelpers, args: any): Promi
7
7
  export declare function handleOpenPanel(h: CommandHelpers, args: any): Promise<CommandResult>;
8
8
  export declare function handlePtyInput(h: CommandHelpers, args: any): Promise<CommandResult>;
9
9
  export declare function handlePtyResize(_h: CommandHelpers, args: any): CommandResult;
10
+ /**
11
+ * MESH-READ-TERMINAL (feature 2: RAW terminal read). Reads the CURRENT rendered
12
+ * PTY viewport of a specific mesh worker session for the mesh_read_terminal tool.
13
+ *
14
+ * This is the daemon-side `read_terminal` verb. It runs BOTH on the coordinator
15
+ * (for a locally-hosted worker) and, after router forwarding
16
+ * (MESH_FORWARDABLE_SESSION_COMMANDS + _meshDirectDispatch), on the OWNING remote
17
+ * worker daemon — where the live viewport actually exists. The instance's
18
+ * getTerminalScreenSnapshot() is gated on isMeshWorkerSession() (returns null for
19
+ * a non-mesh session), which the MCP layer complements with a mesh/session/node
20
+ * ownership cross-check. SECURITY: the raw viewport can contain tokens / args /
21
+ * env / user data — never logged here (only its byte size / truncation flag are).
22
+ */
23
+ export declare function handleReadTerminal(h: CommandHelpers, args: any): CommandResult;
24
+ /**
25
+ * MESH-SEND-KEYS (feature 3: key injection). Inject a structured key sequence into
26
+ * a specific mesh worker session's PTY for the mesh_send_keys tool.
27
+ *
28
+ * Daemon-side `send_keys` verb. Like read_terminal it runs on the coordinator for
29
+ * a local worker and, after router forwarding (MESH_FORWARDABLE_SESSION_COMMANDS +
30
+ * _meshDirectDispatch), on the OWNING remote worker daemon. The instance's
31
+ * injectKeys() is gated on isMeshWorkerSession(); the MCP layer complements it with
32
+ * mesh/session/node ownership + the destructive-key double gate (confirm_destructive
33
+ * + mesh policy) + audit ledger.
34
+ *
35
+ * Defense-in-depth here: even though the MCP layer gates destructive keys, the
36
+ * daemon re-enforces confirm_destructive so a direct/forwarded send_keys that
37
+ * contains CTRL_C/ESC without confirm is refused at the boundary too.
38
+ * SECURITY: never logs the literal text body (only key enums / byte counts).
39
+ */
40
+ export declare function handleSendKeys(h: CommandHelpers, args: any): Promise<CommandResult>;
10
41
  export declare function handleGetProviderSettings(h: CommandHelpers, args: any): CommandResult;
11
42
  export declare function handleSetProviderSetting(h: CommandHelpers, args: any): Promise<CommandResult>;
12
43
  export declare function handleGetProviderSourceConfig(h: CommandHelpers, _args: any): CommandResult;
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ export type { SessionEntry, CompactSessionEntry, CompactDaemonEntry, CloudDaemon
8
8
  export type { InteractivePrompt, InteractiveQuestion, InteractiveOption, InteractivePromptResponse, InteractiveAnswer, } from './providers/types/interactive-prompt.js';
9
9
  export { normalizeInteractivePrompt, normalizeInteractivePromptResponse, buildClaudeInteractiveToolResult, interactivePromptFromClaudeAskUserQuestion, detectClaudeAskUserQuestionPromptFromJson, } from './providers/types/interactive-prompt.js';
10
10
  export type { RepoMesh, RepoMeshDaemonRole, RepoMeshHostMetadata, RepoMeshHostPairingMetadata, RepoMeshHostStatus, RepoMeshNode, RepoMeshNodeHealth, RepoMeshPolicy, RepoMeshMagiSessionCleanupMode, RepoMeshNodePolicy, RepoMeshRelatedRepo, RepoMeshNodeCapabilities, DetectedCommand, ProjectContextSnapshot, ProjectContextSource, RepoMeshCoordinatorConfig, LocalMeshConfig, LocalMeshEntry, LocalMeshNodeEntry, RepoMeshStatus, RepoMeshNodeStatus, RepoMeshPeerConnectionStatus, RepoMeshPeerConnectionState, RepoMeshPeerConnectionTransport, RepoMeshSessionStatus, RepoMeshQueueTask, RepoMeshQueueTaskStatus, RepoMeshQueueSummary, RepoMeshQueueStatus, RepoMeshLedgerEntryStatus, RepoMeshLedgerSummaryStatus, RepoMeshLedgerStatus, MeshAsyncJobLifecycle, RepoMeshSchedulingStrategy, RepoMeshSchedulingStatus, RepoMeshNodeSchedulingStatus, RepoMeshNodeProviderSchedulingStatus, } from './repo-mesh-types.js';
11
- export { DEFAULT_MESH_POLICY, resolveDelegatedWorkerAutoApprove, resolveMagiSessionCleanupMode, magiAutoLaunchedSessionCleanupDecision, MESH_SCHEDULING_STRATEGIES, DEFAULT_MESH_SCHEDULING_STRATEGY, normalizeMeshSchedulingStrategy, resolveNodeSchedulingPriority, resolveProviderMaxParallel, mergeAndNormalizePolicy, normalizeAutoFastForwardPolicy, resolveMaxParallelTasks, MESH_MAX_PARALLEL_TASKS_MIN, MESH_MAX_PARALLEL_TASKS_MAX, MESH_CONVERGE_REFINE_TAG, MESH_CONVERGE_FAST_FORWARD_TAG, resolveAutoConvergeCodeChange, } from './repo-mesh-types.js';
11
+ export { DEFAULT_MESH_POLICY, resolveDelegatedWorkerAutoApprove, resolveAllowSendKeysDestructive, resolveMagiSessionCleanupMode, magiAutoLaunchedSessionCleanupDecision, MESH_SCHEDULING_STRATEGIES, DEFAULT_MESH_SCHEDULING_STRATEGY, normalizeMeshSchedulingStrategy, resolveNodeSchedulingPriority, resolveProviderMaxParallel, mergeAndNormalizePolicy, normalizeAutoFastForwardPolicy, resolveMaxParallelTasks, MESH_MAX_PARALLEL_TASKS_MIN, MESH_MAX_PARALLEL_TASKS_MAX, MESH_CONVERGE_REFINE_TAG, MESH_CONVERGE_FAST_FORWARD_TAG, resolveAutoConvergeCodeChange, } from './repo-mesh-types.js';
12
12
  export * from './git/index.js';
13
13
  import type { RuntimeWriteOwner as _RuntimeWriteOwner } from './shared-types-extra.js';
14
14
  import type { RuntimeAttachedClient as _RuntimeAttachedClient } from './shared-types-extra.js';