@adhdev/daemon-core 0.9.82-rc.26 → 0.9.82-rc.261
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.
- package/dist/boot/daemon-lifecycle.d.ts +4 -0
- package/dist/boot/process-hardening.d.ts +50 -0
- package/dist/chat/source-machine.d.ts +166 -0
- package/dist/chat/source-resolver.d.ts +104 -0
- package/dist/chat/subscription-updates.d.ts +1 -0
- package/dist/cli-adapter-types.d.ts +23 -2
- package/dist/cli-adapters/cli-script-runner.d.ts +117 -0
- package/dist/cli-adapters/cli-state-engine.d.ts +198 -0
- package/dist/cli-adapters/provider-cli-adapter.d.ts +106 -63
- package/dist/cli-adapters/provider-cli-parse.d.ts +4 -0
- package/dist/cli-adapters/provider-cli-shared.d.ts +38 -0
- package/dist/cli-adapters/raw-terminal-io.d.ts +37 -0
- package/dist/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +3 -3
- package/dist/cli-adapters/terminal-backends/types.d.ts +1 -2
- package/dist/cli-adapters/terminal-screen.d.ts +2 -11
- package/dist/commands/cli-manager.d.ts +2 -1
- package/dist/commands/handler.d.ts +110 -0
- package/dist/commands/mesh-coordinator.d.ts +85 -1
- package/dist/commands/router.d.ts +44 -1
- package/dist/config/chat-history.d.ts +9 -0
- package/dist/config/config.d.ts +5 -0
- package/dist/config/mesh-config.d.ts +72 -1
- package/dist/git/git-commands.d.ts +9 -1
- package/dist/git/git-diff.d.ts +6 -0
- package/dist/git/git-types.d.ts +2 -0
- package/dist/index.d.ts +47 -11
- package/dist/index.js +31114 -11255
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +31615 -11852
- package/dist/index.mjs.map +1 -1
- package/dist/installer.d.ts +1 -4
- package/dist/ipc/local-ipc-server.d.ts +91 -0
- package/dist/launch.d.ts +1 -1
- package/dist/logging/async-batch-writer.d.ts +10 -0
- package/dist/mesh/contracts.d.ts +164 -0
- package/dist/mesh/coordinator-prompt.d.ts +36 -0
- package/dist/mesh/coordinator-registry.d.ts +59 -0
- package/dist/mesh/mesh-active-work.d.ts +90 -0
- package/dist/mesh/mesh-delivery-policy.d.ts +131 -0
- package/dist/mesh/mesh-events-coordinator.d.ts +152 -0
- package/dist/mesh/mesh-events-pending.d.ts +40 -0
- package/dist/mesh/mesh-events-stale.d.ts +40 -0
- package/dist/mesh/mesh-events-utils.d.ts +16 -0
- package/dist/mesh/mesh-events.d.ts +5 -49
- package/dist/mesh/mesh-fast-forward.d.ts +41 -0
- package/dist/mesh/mesh-host-ownership.d.ts +9 -0
- package/dist/mesh/mesh-ledger-reconciliation.d.ts +23 -3
- package/dist/mesh/mesh-ledger.d.ts +77 -1
- package/dist/mesh/mesh-missions.d.ts +58 -0
- package/dist/mesh/mesh-refine-batch.d.ts +68 -0
- package/dist/mesh/mesh-refine-status.d.ts +62 -0
- package/dist/mesh/mesh-review-inbox.d.ts +90 -0
- package/dist/mesh/mesh-routing.d.ts +70 -0
- package/dist/mesh/mesh-runtime-store.d.ts +327 -0
- package/dist/mesh/mesh-task-stats.d.ts +49 -0
- package/dist/mesh/mesh-work-queue.d.ts +160 -5
- package/dist/mesh/preview-freshness.d.ts +18 -0
- package/dist/mesh/refine-config.d.ts +215 -0
- package/dist/mesh/worktree-bootstrap-config.d.ts +135 -0
- package/dist/providers/acp-provider-instance.d.ts +2 -0
- package/dist/providers/approval-utils.d.ts +13 -0
- package/dist/providers/cli-provider-instance.d.ts +37 -3
- package/dist/providers/contracts.d.ts +130 -6
- package/dist/providers/external-sources.d.ts +71 -0
- package/dist/providers/native-history/antigravity-cli-transcript.d.ts +100 -0
- package/dist/providers/native-history/claude-cli-transcript.d.ts +70 -0
- package/dist/providers/native-history/codex-cli-transcript.d.ts +73 -0
- package/dist/providers/native-history/dispatcher.d.ts +27 -0
- package/dist/providers/native-history/hermes-cli-transcript.d.ts +30 -0
- package/dist/providers/native-history/index.d.ts +13 -0
- package/dist/providers/provider-instance-manager.d.ts +13 -0
- package/dist/providers/provider-instance.d.ts +13 -1
- package/dist/providers/provider-loader.d.ts +26 -4
- package/dist/providers/provider-trust.d.ts +31 -0
- package/dist/providers/read-chat-contract.d.ts +29 -0
- package/dist/providers/sdk/v1/builders/acp/detect-status.d.ts +68 -0
- package/dist/providers/sdk/v1/builders/cli/detect-status.d.ts +85 -0
- package/dist/providers/sdk/v1/builders/cli/parse-approval-squash.d.ts +59 -0
- package/dist/providers/sdk/v1/builders/cli/parse-approval.d.ts +65 -0
- package/dist/providers/sdk/v1/builders/cli/parse-session.d.ts +91 -0
- package/dist/providers/sdk/v1/builders/cli/visible-region.d.ts +42 -0
- package/dist/providers/sdk/v1/fixture-tooling/format.d.ts +126 -0
- package/dist/providers/sdk/v1/fixture-tooling/index.d.ts +8 -0
- package/dist/providers/sdk/v1/fixture-tooling/replay.d.ts +38 -0
- package/dist/providers/sdk/v1/index.d.ts +30 -0
- package/dist/providers/sdk/v1/sandbox/README-design.d.ts +193 -0
- package/dist/providers/sdk/v1/sandbox/require-whitelist.d.ts +74 -0
- package/dist/providers/sdk/v1/sandbox/script-runner.d.ts +98 -0
- package/dist/providers/sdk/v1/types/cli/index.d.ts +277 -0
- package/dist/providers/sdk/v1/types/common/index.d.ts +203 -0
- package/dist/providers/sdk/v1/validators/index.d.ts +5 -0
- package/dist/providers/sdk/v1/validators/manifest.d.ts +40 -0
- package/dist/providers/sdk/v1/validators/taint.d.ts +52 -0
- package/dist/providers/spec/adapter.d.ts +52 -0
- package/dist/providers/spec/cli-adapter.d.ts +140 -0
- package/dist/providers/spec/evaluator.d.ts +23 -0
- package/dist/providers/spec/fsm-driver.d.ts +273 -0
- package/dist/providers/spec/fsm-evaluator.d.ts +72 -0
- package/dist/providers/spec/fsm-loader.d.ts +14 -0
- package/dist/providers/spec/fsm-types.d.ts +91 -0
- package/dist/providers/spec/native-history-executor.d.ts +41 -0
- package/dist/providers/spec/route.d.ts +4 -0
- package/dist/providers/spec/types.d.ts +129 -0
- package/dist/providers/transcript-v2.d.ts +176 -0
- package/dist/providers/types/interactive-prompt.d.ts +48 -0
- package/dist/repo-mesh-types.d.ts +126 -1
- package/dist/sessions/registry.d.ts +6 -0
- package/dist/shared-types-extra.d.ts +2 -4
- package/dist/shared-types.d.ts +42 -1
- package/dist/status/normalize.d.ts +1 -1
- package/dist/status/normalize.js +1 -0
- package/dist/status/normalize.js.map +1 -1
- package/dist/status/normalize.mjs +1 -0
- package/dist/status/normalize.mjs.map +1 -1
- package/dist/status/reporter.d.ts +2 -0
- package/dist/status/snapshot.d.ts +1 -0
- package/dist/types.d.ts +5 -0
- package/package.json +6 -3
- package/src/agent-stream/poller.ts +2 -3
- package/src/boot/daemon-lifecycle.ts +30 -10
- package/src/boot/process-hardening.ts +89 -0
- package/src/chat/source-machine.ts +534 -0
- package/src/chat/source-resolver.ts +0 -0
- package/src/chat/subscription-updates.ts +20 -1
- package/src/cli-adapter-types.d.ts +1 -0
- package/src/cli-adapter-types.ts +22 -2
- package/src/cli-adapters/cli-script-runner.ts +421 -0
- package/src/cli-adapters/cli-state-engine.ts +1215 -0
- package/src/cli-adapters/provider-cli-adapter.d.ts +1 -1
- package/src/cli-adapters/provider-cli-adapter.ts +674 -1139
- package/src/cli-adapters/provider-cli-parse.d.ts +1 -0
- package/src/cli-adapters/provider-cli-parse.ts +13 -0
- package/src/cli-adapters/provider-cli-runtime.ts +3 -1
- package/src/cli-adapters/provider-cli-shared.d.ts +2 -0
- package/src/cli-adapters/provider-cli-shared.ts +68 -11
- package/src/cli-adapters/raw-terminal-io.ts +252 -0
- package/src/cli-adapters/terminal-backends/ghostty-vt-backend.ts +35 -29
- package/src/cli-adapters/terminal-backends/types.ts +1 -3
- package/src/cli-adapters/terminal-screen.ts +11 -81
- package/src/commands/chat-commands.ts +1806 -60
- package/src/commands/cli-manager.ts +286 -14
- package/src/commands/handler.ts +809 -2
- package/src/commands/mesh-coordinator.ts +332 -122
- package/src/commands/router.ts +4890 -489
- package/src/config/chat-history.ts +95 -24
- package/src/config/config.ts +12 -0
- package/src/config/mesh-config.ts +303 -3
- package/src/config/recent-activity.ts +8 -2
- package/src/daemon/dev-auto-implement.ts +3 -2
- package/src/daemon/dev-cli-debug.ts +10 -1
- package/src/detection/ide-detector.ts +26 -16
- package/src/git/git-commands.ts +42 -12
- package/src/git/git-diff.ts +53 -0
- package/src/git/git-status.ts +35 -6
- package/src/git/git-types.ts +2 -0
- package/src/git/git-worktree.ts +8 -1
- package/src/index.ts +127 -10
- package/src/installer.d.ts +1 -1
- package/src/installer.ts +8 -6
- package/src/ipc/local-ipc-server.ts +278 -0
- package/src/launch.d.ts +1 -1
- package/src/launch.ts +37 -28
- package/src/logging/async-batch-writer.ts +55 -0
- package/src/logging/logger.ts +2 -1
- package/src/mesh/contracts.ts +329 -0
- package/src/mesh/coordinator-prompt.ts +219 -31
- package/src/mesh/coordinator-registry.ts +121 -0
- package/src/mesh/mesh-active-work.ts +437 -0
- package/src/mesh/mesh-delivery-policy.ts +315 -0
- package/src/mesh/mesh-events-coordinator.ts +1625 -0
- package/src/mesh/mesh-events-pending.ts +439 -0
- package/src/mesh/mesh-events-stale.ts +283 -0
- package/src/mesh/mesh-events-utils.ts +195 -0
- package/src/mesh/mesh-events.ts +26 -1035
- package/src/mesh/mesh-fast-forward.ts +438 -0
- package/src/mesh/mesh-host-ownership.ts +73 -0
- package/src/mesh/mesh-ledger-reconciliation.ts +12 -5
- package/src/mesh/mesh-ledger.ts +588 -102
- package/src/mesh/mesh-missions.ts +151 -0
- package/src/mesh/mesh-refine-batch.ts +197 -0
- package/src/mesh/mesh-refine-status.ts +231 -0
- package/src/mesh/mesh-review-inbox.ts +307 -0
- package/src/mesh/mesh-routing.ts +272 -0
- package/src/mesh/mesh-runtime-store.ts +1342 -0
- package/src/mesh/mesh-task-stats.ts +154 -0
- package/src/mesh/mesh-work-queue.ts +573 -145
- package/src/mesh/preview-freshness.ts +118 -0
- package/src/mesh/refine-config.ts +403 -0
- package/src/mesh/worktree-bootstrap-config.ts +326 -0
- package/src/providers/acp-provider-instance.ts +15 -1
- package/src/providers/approval-utils.d.ts +4 -0
- package/src/providers/approval-utils.ts +47 -5
- package/src/providers/chat-message-normalization.ts +4 -11
- package/src/providers/cli-provider-instance.ts +806 -72
- package/src/providers/contracts.d.ts +55 -0
- package/src/providers/contracts.ts +141 -6
- package/src/providers/external-sources.ts +218 -0
- package/src/providers/ide-provider-instance.ts +19 -5
- package/src/providers/native-history/antigravity-cli-transcript.ts +643 -0
- package/src/providers/native-history/claude-cli-transcript.ts +396 -0
- package/src/providers/native-history/codex-cli-transcript.ts +479 -0
- package/src/providers/native-history/dispatcher.ts +340 -0
- package/src/providers/native-history/hermes-cli-transcript.ts +230 -0
- package/src/providers/native-history/index.ts +30 -0
- package/src/providers/provider-instance-manager.ts +30 -0
- package/src/providers/provider-instance.ts +10 -1
- package/src/providers/provider-loader.ts +584 -50
- package/src/providers/provider-schema.ts +87 -14
- package/src/providers/provider-trust.ts +114 -0
- package/src/providers/read-chat-contract.ts +76 -16
- package/src/providers/sdk/README.md +49 -0
- package/src/providers/sdk/v1/builders/acp/detect-status.ts +144 -0
- package/src/providers/sdk/v1/builders/cli/detect-status.ts +262 -0
- package/src/providers/sdk/v1/builders/cli/parse-approval-squash.ts +158 -0
- package/src/providers/sdk/v1/builders/cli/parse-approval.ts +250 -0
- package/src/providers/sdk/v1/builders/cli/parse-session.ts +276 -0
- package/src/providers/sdk/v1/builders/cli/visible-region.ts +143 -0
- package/src/providers/sdk/v1/fixture-tooling/format.ts +130 -0
- package/src/providers/sdk/v1/fixture-tooling/index.ts +22 -0
- package/src/providers/sdk/v1/fixture-tooling/replay.ts +352 -0
- package/src/providers/sdk/v1/index.ts +152 -0
- package/src/providers/sdk/v1/sandbox/README-design.ts +195 -0
- package/src/providers/sdk/v1/sandbox/require-whitelist.ts +472 -0
- package/src/providers/sdk/v1/sandbox/script-runner.ts +150 -0
- package/src/providers/sdk/v1/schemas/cli/provider.schema.json +504 -0
- package/src/providers/sdk/v1/schemas/primitives/acp-session-protocol-v1.json +131 -0
- package/src/providers/sdk/v1/schemas/primitives/native-history-codex-rollout-v1.json +66 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-approval-squash-v1.json +91 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-assistant-block-v1.json +91 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-cue-ordering-v1.json +47 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-dispatch-order-v1.json +32 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-footer-chrome-v1.json +42 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-index-finder-v1.json +27 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-modal-v1.json +125 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-prompt-marker-v1.json +45 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-session-id-extraction-v1.json +46 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-settled-prompt-v1.json +71 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-spinner-v1.json +83 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-transcript-pty-v1.json +83 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-visible-region-v1.json +57 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-welcome-screen-v1.json +35 -0
- package/src/providers/sdk/v1/types/cli/index.ts +365 -0
- package/src/providers/sdk/v1/types/common/index.ts +229 -0
- package/src/providers/sdk/v1/validators/index.ts +19 -0
- package/src/providers/sdk/v1/validators/manifest.ts +110 -0
- package/src/providers/sdk/v1/validators/taint.ts +309 -0
- package/src/providers/spec/adapter.ts +145 -0
- package/src/providers/spec/cli-adapter.ts +730 -0
- package/src/providers/spec/evaluator.ts +321 -0
- package/src/providers/spec/fsm-driver.ts +811 -0
- package/src/providers/spec/fsm-evaluator.ts +255 -0
- package/src/providers/spec/fsm-loader.ts +102 -0
- package/src/providers/spec/fsm-types.ts +184 -0
- package/src/providers/spec/native-history-executor.ts +943 -0
- package/src/providers/spec/route.ts +51 -0
- package/src/providers/spec/types.ts +173 -0
- package/src/providers/transcript-v2.ts +567 -0
- package/src/providers/types/interactive-prompt.ts +425 -0
- package/src/providers/version-archive.ts +38 -20
- package/src/repo-mesh-types.ts +138 -1
- package/src/sessions/registry.ts +6 -0
- package/src/shared-types-extra.ts +2 -4
- package/src/shared-types.ts +45 -1
- package/src/status/builders.ts +26 -6
- package/src/status/normalize.ts +2 -0
- package/src/status/reporter.ts +15 -0
- package/src/status/snapshot.ts +84 -25
- package/src/system/host-memory.ts +29 -12
- package/src/types.ts +5 -0
- package/dist/cli-adapters/terminal-backends/xterm-backend.d.ts +0 -17
- package/dist/mesh/mesh-sync.d.ts +0 -53
- package/src/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +0 -16
- package/src/cli-adapters/terminal-backends/xterm-backend.ts +0 -97
- package/src/mesh/mesh-sync.ts +0 -111
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import type { CliAdapter, CliAdapterStatus } from '../../cli-adapter-types.js';
|
|
2
|
+
import type { PtyTransportFactory } from '../../cli-adapters/pty-transport.js';
|
|
3
|
+
import { type InteractivePromptResponse } from '../types/interactive-prompt.js';
|
|
4
|
+
export declare class SpecCliAdapter implements CliAdapter {
|
|
5
|
+
readonly cliType: string;
|
|
6
|
+
readonly cliName: string;
|
|
7
|
+
readonly workingDir: string;
|
|
8
|
+
/**
|
|
9
|
+
* Marker the daemon's finalization gate checks: `getStatus()` returns
|
|
10
|
+
* `messages: []` by design here (chat history lives in the daemon's
|
|
11
|
+
* native-history pipeline, not the adapter). Without this flag,
|
|
12
|
+
* cli-provider-instance's `missing_final_assistant` gate would stall
|
|
13
|
+
* every turn until the 30s safety timeout because it expects the
|
|
14
|
+
* adapter to surface the final assistant message.
|
|
15
|
+
*/
|
|
16
|
+
readonly chatMessagesOwnedExternally: true;
|
|
17
|
+
private driver;
|
|
18
|
+
/** Common spec fields the adapter reads, present in both v3 and v4. */
|
|
19
|
+
private spec;
|
|
20
|
+
private lastEvent;
|
|
21
|
+
private latestState;
|
|
22
|
+
private latestModal;
|
|
23
|
+
private statusCallback;
|
|
24
|
+
private ptyDataCallback;
|
|
25
|
+
private partialResponse;
|
|
26
|
+
private activeInteractivePrompt;
|
|
27
|
+
private interactivePromptTransport;
|
|
28
|
+
private claudeTuiPromptCaptureInFlight;
|
|
29
|
+
/**
|
|
30
|
+
* Wall clock of the first frame on which a held interactive prompt was
|
|
31
|
+
* observed to have left the screen. Mirrors the approval FSM's
|
|
32
|
+
* `modalLostAt` hysteresis (see cli-state-engine.ts): claude-cli's TUI
|
|
33
|
+
* repaints the choice picker as several PTY chunks, so a single frame
|
|
34
|
+
* with no "Enter to select" footer is not proof the prompt is gone — it
|
|
35
|
+
* may just be mid-repaint. We only clear the held prompt once it has
|
|
36
|
+
* been absent across a short grace window. Reset to null the moment the
|
|
37
|
+
* prompt footer reappears.
|
|
38
|
+
*
|
|
39
|
+
* Without this, a choice prompt resolved *directly in the terminal* (the
|
|
40
|
+
* user picked an option without going through ADHDev's
|
|
41
|
+
* setInteractivePromptResponse) was never cleared from
|
|
42
|
+
* `activeInteractivePrompt`, so getStatus() re-emitted the same prompt
|
|
43
|
+
* forever — the choice-resolve-stuck bug.
|
|
44
|
+
*/
|
|
45
|
+
private interactivePromptLostAt;
|
|
46
|
+
private jsonLineTail;
|
|
47
|
+
private exited;
|
|
48
|
+
private spawned;
|
|
49
|
+
private providerSessionId;
|
|
50
|
+
/** Wall clock at the moment spawn() ran. Used as the cutoff for
|
|
51
|
+
* native-history file selection so a prior session's transcript
|
|
52
|
+
* can't leak into this session before the agent has written its
|
|
53
|
+
* own records. */
|
|
54
|
+
private spawnedAtMs;
|
|
55
|
+
/** Env vars the daemon set on the spawned child. Mesh coordinator
|
|
56
|
+
* points hermes at a per-coordinator HERMES_HOME so the dashboard's
|
|
57
|
+
* native-history reader needs that override to find the right
|
|
58
|
+
* state.db; without it the reader sees ~/.hermes/state.db which
|
|
59
|
+
* the coordinator-launched hermes never writes to. The choice to
|
|
60
|
+
* redirect HERMES_HOME is a workaround for an unresolved hermes
|
|
61
|
+
* upstream feature gap (see hermes-agent#23130 — runtime-supplied
|
|
62
|
+
* MCP config), so this routing keeps the dashboard honest until
|
|
63
|
+
* hermes ships a runtime MCP override. */
|
|
64
|
+
private spawnedEnv;
|
|
65
|
+
constructor(specPath: string, workingDir: string, cliArgs: string[], extraEnv: Record<string, string>, transportFactory?: PtyTransportFactory);
|
|
66
|
+
spawn(): Promise<void>;
|
|
67
|
+
sendMessage(text: string): Promise<void>;
|
|
68
|
+
getStatus(): CliAdapterStatus;
|
|
69
|
+
private maybeRefreshNativeHistory;
|
|
70
|
+
getScriptParsedStatus(): unknown;
|
|
71
|
+
getPartialResponse(): string;
|
|
72
|
+
shutdown(): void;
|
|
73
|
+
cancel(): void;
|
|
74
|
+
isProcessing(): boolean;
|
|
75
|
+
isReady(): boolean;
|
|
76
|
+
setOnStatusChange(cb: () => void): void;
|
|
77
|
+
setOnPtyData(cb: (data: string) => void): void;
|
|
78
|
+
writeRaw(data: string): void;
|
|
79
|
+
resize(cols: number, rows: number): void;
|
|
80
|
+
resolveModal(buttonIndex: number): void;
|
|
81
|
+
resolveAction(data: unknown): Promise<void>;
|
|
82
|
+
setInteractivePromptResponse(response: InteractivePromptResponse): Promise<void>;
|
|
83
|
+
isApprovalRecentlyResolved(): boolean;
|
|
84
|
+
clearHistory(): void;
|
|
85
|
+
updateRuntimeSettings(): void;
|
|
86
|
+
setServerConn(): void;
|
|
87
|
+
/**
|
|
88
|
+
* Map an invokeScript(name, args) call onto a control_bar entry.
|
|
89
|
+
*
|
|
90
|
+
* scriptName is matched against control.id. The control's action.type
|
|
91
|
+
* drives the dispatch:
|
|
92
|
+
*
|
|
93
|
+
* send_keys → click_control (e.g. stop)
|
|
94
|
+
* open_picker → click_control then resolve when extract_choices
|
|
95
|
+
* surface; choice index comes from args.choiceIndex
|
|
96
|
+
* or args.choice (string label match), defaulting to 0
|
|
97
|
+
* attach_image → attach_image dispatch; expects args.blob (data url
|
|
98
|
+
* or base64) and args.mime
|
|
99
|
+
*
|
|
100
|
+
* Callers that pass an unknown control id get a { not_found } response.
|
|
101
|
+
* No control matched, no driver call — keeps the surface honest.
|
|
102
|
+
*/
|
|
103
|
+
invokeScript(scriptName: string, args?: Record<string, unknown>): Promise<unknown>;
|
|
104
|
+
getDebugSnapshot(): unknown;
|
|
105
|
+
getRuntimeMetadata(): unknown;
|
|
106
|
+
updateRuntimeMeta(meta?: Record<string, unknown>): void;
|
|
107
|
+
refreshProviderDefinition(): void;
|
|
108
|
+
private handleEvent;
|
|
109
|
+
private detectInteractivePromptFromPtyChunk;
|
|
110
|
+
private readCurrentScreenSections;
|
|
111
|
+
private extractProviderSessionIdFromScreen;
|
|
112
|
+
private readClaudeScreenAssistantMessages;
|
|
113
|
+
/**
|
|
114
|
+
* Grace window a held interactive prompt must be absent from the screen
|
|
115
|
+
* before we treat it as resolved-in-terminal and clear it. claude-cli
|
|
116
|
+
* repaints the picker across multiple PTY chunks, so a single
|
|
117
|
+
* footer-less frame is not proof the prompt is gone. Sized in the same
|
|
118
|
+
* spirit as the approval FSM's `approvalCooldown` modal-lost hysteresis.
|
|
119
|
+
*/
|
|
120
|
+
private static readonly INTERACTIVE_PROMPT_LOST_GRACE_MS;
|
|
121
|
+
/**
|
|
122
|
+
* Clear a held interactive prompt once the user has resolved it directly
|
|
123
|
+
* in the terminal (the choice picker leaves the screen without going
|
|
124
|
+
* through setInteractivePromptResponse). The approval path already does
|
|
125
|
+
* this via the FSM's modal-lost hysteresis; the interactive-prompt path
|
|
126
|
+
* had no equivalent, so a terminal-side answer left activeInteractivePrompt
|
|
127
|
+
* set and getStatus() re-emitted the same choice modal forever.
|
|
128
|
+
*
|
|
129
|
+
* Detection mirrors capture: the claude TUI picker is on-screen exactly
|
|
130
|
+
* while its "Enter to select" footer is rendered. When the footer is gone
|
|
131
|
+
* for INTERACTIVE_PROMPT_LOST_GRACE_MS the prompt is genuinely resolved.
|
|
132
|
+
*/
|
|
133
|
+
private maybeClearResolvedClaudeTuiPrompt;
|
|
134
|
+
private maybeCaptureClaudeTuiPrompt;
|
|
135
|
+
private readClaudeTuiHeaders;
|
|
136
|
+
private captureClaudeTuiPrompt;
|
|
137
|
+
getDebugState(): Record<string, any>;
|
|
138
|
+
getTraceState(limit?: number): Record<string, any>;
|
|
139
|
+
getProviderResolutionMeta(): Record<string, any>;
|
|
140
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { SectionDef, Condition, ExtractTitle, ExtractButtons } from './types.js';
|
|
2
|
+
export interface ResolvedSection {
|
|
3
|
+
id: string;
|
|
4
|
+
fromLine: number;
|
|
5
|
+
toLine: number;
|
|
6
|
+
text: string;
|
|
7
|
+
}
|
|
8
|
+
export interface TraceEntry {
|
|
9
|
+
kind: 'section' | 'state_match' | 'state_skip' | 'modal' | 'control' | 'notification' | 'delegate';
|
|
10
|
+
text: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function resolveSections(sectionsObj: Record<string, SectionDef>, lines: string[]): ResolvedSection[];
|
|
13
|
+
export declare function sectionText(sections: ResolvedSection[], sectionId: string | undefined, fullScreen: string): string;
|
|
14
|
+
export declare function evaluateCondition(cond: Condition, sections: ResolvedSection[], fullScreen: string, cursor: {
|
|
15
|
+
row: number;
|
|
16
|
+
col: number;
|
|
17
|
+
} | undefined, prevLines: string[] | undefined, trace: TraceEntry[], stateId: string): boolean;
|
|
18
|
+
export declare function extractTitle(rule: ExtractTitle, sections: ResolvedSection[], fullScreen: string): string | null;
|
|
19
|
+
export declare function extractButtonsFromRule(rule: ExtractButtons, hay: string): {
|
|
20
|
+
index: number;
|
|
21
|
+
label: string;
|
|
22
|
+
key: string;
|
|
23
|
+
}[];
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import type { PtyTransportFactory } from '../../cli-adapters/pty-transport.js';
|
|
2
|
+
import { type TraceEntry } from './evaluator.js';
|
|
3
|
+
import { type TransitionEval } from './fsm-evaluator.js';
|
|
4
|
+
export type DashboardEvent = {
|
|
5
|
+
kind: 'pty_data';
|
|
6
|
+
chunk: string;
|
|
7
|
+
} | {
|
|
8
|
+
kind: 'state_changed';
|
|
9
|
+
state: {
|
|
10
|
+
id: string;
|
|
11
|
+
label: string;
|
|
12
|
+
title: string | null;
|
|
13
|
+
status: 'idle' | 'generating' | 'approval';
|
|
14
|
+
};
|
|
15
|
+
modal: {
|
|
16
|
+
title: string | null;
|
|
17
|
+
buttons: {
|
|
18
|
+
index: number;
|
|
19
|
+
label: string;
|
|
20
|
+
}[];
|
|
21
|
+
} | null;
|
|
22
|
+
controls: {
|
|
23
|
+
id: string;
|
|
24
|
+
label: string;
|
|
25
|
+
action_type: string;
|
|
26
|
+
}[];
|
|
27
|
+
} | {
|
|
28
|
+
kind: 'notification';
|
|
29
|
+
id: string;
|
|
30
|
+
title: string;
|
|
31
|
+
body: string;
|
|
32
|
+
} | {
|
|
33
|
+
kind: 'delegate';
|
|
34
|
+
id: string;
|
|
35
|
+
task: string;
|
|
36
|
+
} | {
|
|
37
|
+
kind: 'spec_trace';
|
|
38
|
+
entries: TraceEntry[];
|
|
39
|
+
} | {
|
|
40
|
+
kind: 'exit';
|
|
41
|
+
exit_code: number;
|
|
42
|
+
} | {
|
|
43
|
+
kind: 'spec_error';
|
|
44
|
+
errors: string[];
|
|
45
|
+
};
|
|
46
|
+
export type DashboardCommand = {
|
|
47
|
+
kind: 'send_message';
|
|
48
|
+
text: string;
|
|
49
|
+
} | {
|
|
50
|
+
kind: 'pty_write';
|
|
51
|
+
data: string;
|
|
52
|
+
} | {
|
|
53
|
+
kind: 'click_control';
|
|
54
|
+
control_id: string;
|
|
55
|
+
payload?: unknown;
|
|
56
|
+
} | {
|
|
57
|
+
kind: 'click_modal_button';
|
|
58
|
+
index: number;
|
|
59
|
+
} | {
|
|
60
|
+
kind: 'attach_image';
|
|
61
|
+
blob: string;
|
|
62
|
+
mime: string;
|
|
63
|
+
} | {
|
|
64
|
+
kind: 'resize';
|
|
65
|
+
cols: number;
|
|
66
|
+
rows: number;
|
|
67
|
+
} | {
|
|
68
|
+
kind: 'cancel';
|
|
69
|
+
} | {
|
|
70
|
+
kind: 'shutdown';
|
|
71
|
+
};
|
|
72
|
+
export interface DriverHistoryEntry {
|
|
73
|
+
stateId: string;
|
|
74
|
+
label: string;
|
|
75
|
+
at: number;
|
|
76
|
+
durationMs: number;
|
|
77
|
+
reason: string;
|
|
78
|
+
matchedStateId?: string;
|
|
79
|
+
matchedRules?: string[];
|
|
80
|
+
debounceKind?: string;
|
|
81
|
+
idleHoldMs?: number;
|
|
82
|
+
busyHoldMs?: number;
|
|
83
|
+
via?: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* A frozen snapshot of the FULL FSM evaluation captured at the instant a
|
|
87
|
+
* transition fired — the rich `transitions[]` table (per-transition eligible /
|
|
88
|
+
* hold countdown / per-condition CondResult + remainingMs) that `getFsmDebug()`
|
|
89
|
+
* otherwise only computes live for the current instant. Kept in a separate ring
|
|
90
|
+
* buffer from `stateHistory` (which stays intentionally lightweight) so the
|
|
91
|
+
* "why did this rule fire just before the transition" question is answerable
|
|
92
|
+
* after the fact. before-only: this is the evaluation that PRODUCED the
|
|
93
|
+
* transition, not the post-transition state.
|
|
94
|
+
*/
|
|
95
|
+
export interface FsmSnapshotEntry {
|
|
96
|
+
/** State we transitioned out of. */
|
|
97
|
+
stateFrom: string;
|
|
98
|
+
/** State we transitioned into (the fired transition's destination). */
|
|
99
|
+
stateTo: string;
|
|
100
|
+
/** Wall-clock time the transition committed (ms). */
|
|
101
|
+
at: number;
|
|
102
|
+
/** The fired transition's destination state id (== stateTo; kept explicit
|
|
103
|
+
* to mirror the rule that fired). */
|
|
104
|
+
firedTo: string;
|
|
105
|
+
/** Human label of the fired transition (e.g. "approval→busy"). */
|
|
106
|
+
firedLabel: string;
|
|
107
|
+
/** Why-it-fired summary, same shape produced for stateHistory.matchedRules. */
|
|
108
|
+
reason: string[];
|
|
109
|
+
/** Every outgoing transition from `stateFrom` as evaluated at `at`, each
|
|
110
|
+
* with its eligible / hold / per-condition CondResult + remainingMs. This
|
|
111
|
+
* is the full pre-transition evaluation table — the whole point of the
|
|
112
|
+
* snapshot. */
|
|
113
|
+
transitions: TransitionEval[];
|
|
114
|
+
}
|
|
115
|
+
export interface ISpecDriver {
|
|
116
|
+
subscribe(listener: (ev: DashboardEvent) => void): () => void;
|
|
117
|
+
start(): void;
|
|
118
|
+
dispatch(cmd: DashboardCommand): void;
|
|
119
|
+
snapshot(): string;
|
|
120
|
+
getCursorPosition(): {
|
|
121
|
+
row: number;
|
|
122
|
+
col: number;
|
|
123
|
+
};
|
|
124
|
+
getScreen(): string;
|
|
125
|
+
getSpecPath(): string;
|
|
126
|
+
shutdown(): void;
|
|
127
|
+
getStateHistory(): ReadonlyArray<DriverHistoryEntry>;
|
|
128
|
+
getSections(): Array<{
|
|
129
|
+
id: string;
|
|
130
|
+
text: string;
|
|
131
|
+
}> | null;
|
|
132
|
+
getLastBusyAt(): number;
|
|
133
|
+
hasIdleHoldPending(): boolean;
|
|
134
|
+
getCompletionIdleDebounceState(): {
|
|
135
|
+
active: boolean;
|
|
136
|
+
ageMs: number;
|
|
137
|
+
holdMs: number;
|
|
138
|
+
forceAfterMs: number;
|
|
139
|
+
} | null;
|
|
140
|
+
getFsmDebug?(): unknown;
|
|
141
|
+
getFsmSnapshotHistory?(): ReadonlyArray<FsmSnapshotEntry>;
|
|
142
|
+
}
|
|
143
|
+
export interface SpecDriverOpts {
|
|
144
|
+
specPath: string;
|
|
145
|
+
workingDir: string;
|
|
146
|
+
extraEnv?: Record<string, string>;
|
|
147
|
+
cols?: number;
|
|
148
|
+
rows?: number;
|
|
149
|
+
hotReload?: boolean;
|
|
150
|
+
emitTrace?: boolean;
|
|
151
|
+
transportFactory?: PtyTransportFactory;
|
|
152
|
+
extraCliArgs?: string[];
|
|
153
|
+
}
|
|
154
|
+
export declare function resolveSubmitDelayMs(specBeforeSubmit: number | undefined, text: string): number;
|
|
155
|
+
export declare function guessExt(mime: string): string;
|
|
156
|
+
type HistoryEntry = DriverHistoryEntry;
|
|
157
|
+
export declare class FsmDriver implements ISpecDriver {
|
|
158
|
+
private readonly opts;
|
|
159
|
+
private spec;
|
|
160
|
+
private adapter;
|
|
161
|
+
private listeners;
|
|
162
|
+
private currentStateId;
|
|
163
|
+
private stateEnteredAt;
|
|
164
|
+
private startedAtMs;
|
|
165
|
+
private prevScreenLines;
|
|
166
|
+
/** Per cursor_above region (key: cursor_above, -1 = whole screen) → last
|
|
167
|
+
* time that region's content changed. Drives stable_ms conditions. */
|
|
168
|
+
private regionLastChangedAt;
|
|
169
|
+
/** Timer that re-runs evaluate() when a time-condition would flip true
|
|
170
|
+
* with no PTY frame to trigger it. */
|
|
171
|
+
private wakeTimer;
|
|
172
|
+
private currentEval;
|
|
173
|
+
private stateHistory;
|
|
174
|
+
private prevStateAt;
|
|
175
|
+
private readySeenOnce;
|
|
176
|
+
private pendingSends;
|
|
177
|
+
private pickerInProgress;
|
|
178
|
+
private delegateTimers;
|
|
179
|
+
private specWatcher;
|
|
180
|
+
/** Last full FSM evaluation, kept for the debugger. */
|
|
181
|
+
private lastFsmEval;
|
|
182
|
+
/** Ring buffer (max 20) of the full FSM evaluation captured at each
|
|
183
|
+
* transition — the rich pre-transition table that lastFsmEval only keeps
|
|
184
|
+
* for the single most recent evaluation. Separate from stateHistory. */
|
|
185
|
+
private fsmSnapshotHistory;
|
|
186
|
+
constructor(opts: SpecDriverOpts);
|
|
187
|
+
subscribe(listener: (ev: DashboardEvent) => void): () => void;
|
|
188
|
+
start(): void;
|
|
189
|
+
dispatch(cmd: DashboardCommand): void;
|
|
190
|
+
snapshot(): string;
|
|
191
|
+
getCursorPosition(): {
|
|
192
|
+
row: number;
|
|
193
|
+
col: number;
|
|
194
|
+
};
|
|
195
|
+
getScreen(): string;
|
|
196
|
+
getSpecPath(): string;
|
|
197
|
+
shutdown(): void;
|
|
198
|
+
getFsmDebug(): {
|
|
199
|
+
currentState: string;
|
|
200
|
+
label: string;
|
|
201
|
+
stateAgeMs: number;
|
|
202
|
+
status: string;
|
|
203
|
+
cursor: {
|
|
204
|
+
row: number;
|
|
205
|
+
col: number;
|
|
206
|
+
};
|
|
207
|
+
transitions: TransitionEval[];
|
|
208
|
+
};
|
|
209
|
+
getStateHistory(): ReadonlyArray<HistoryEntry>;
|
|
210
|
+
getFsmSnapshotHistory(): ReadonlyArray<FsmSnapshotEntry>;
|
|
211
|
+
getSections(): Array<{
|
|
212
|
+
id: string;
|
|
213
|
+
text: string;
|
|
214
|
+
}> | null;
|
|
215
|
+
/** v3-compat shims so the cli-adapter's existing debug snapshot keeps
|
|
216
|
+
* working without branching on driver type. */
|
|
217
|
+
getLastBusyAt(): number;
|
|
218
|
+
hasIdleHoldPending(): boolean;
|
|
219
|
+
getCompletionIdleDebounceState(): {
|
|
220
|
+
active: boolean;
|
|
221
|
+
ageMs: number;
|
|
222
|
+
holdMs: number;
|
|
223
|
+
forceAfterMs: number;
|
|
224
|
+
} | null;
|
|
225
|
+
private loadSpecOrThrow;
|
|
226
|
+
private buildAdapterOpts;
|
|
227
|
+
private armSpecWatcher;
|
|
228
|
+
private emitInitialState;
|
|
229
|
+
private buildClock;
|
|
230
|
+
private evalFsmNow;
|
|
231
|
+
private reevaluate;
|
|
232
|
+
private commitTransition;
|
|
233
|
+
/** Snapshot the full FSM evaluation that produced a transition into the
|
|
234
|
+
* separate fsmSnapshotHistory ring buffer (max 20). The transitions[]
|
|
235
|
+
* table is captured by reference — it is freshly built per evaluation in
|
|
236
|
+
* evaluateFsm and never mutated after, so no clone is needed. */
|
|
237
|
+
private pushFsmSnapshot;
|
|
238
|
+
/** Re-derive the visible modal + controls for the current state and emit a
|
|
239
|
+
* state_changed if anything differs from the last emit. */
|
|
240
|
+
private emitStateChanged;
|
|
241
|
+
private deriveModal;
|
|
242
|
+
private deriveTitle;
|
|
243
|
+
private deriveControls;
|
|
244
|
+
/** Track which cursor_above regions changed since the previous frame so
|
|
245
|
+
* stable_ms conditions can measure quiet time. We record every region
|
|
246
|
+
* size referenced by a stable_ms condition in the spec, plus the whole
|
|
247
|
+
* screen (-1). */
|
|
248
|
+
private trackRegionChanges;
|
|
249
|
+
/** All cursor_above region sizes referenced by stable_ms conditions in the
|
|
250
|
+
* current state's outgoing transitions, plus whole-screen. Cached lazily
|
|
251
|
+
* per spec load would be nicer but the set is tiny. */
|
|
252
|
+
private stableRegionSizes;
|
|
253
|
+
/** Schedule a re-evaluation for the soonest pending time-condition on any
|
|
254
|
+
* outgoing transition (elapsed_ms / stable_ms / min_hold_ms). Without
|
|
255
|
+
* this, a state whose only exit is time-based would never leave once the
|
|
256
|
+
* PTY goes quiet. */
|
|
257
|
+
private scheduleWakeForState;
|
|
258
|
+
private maybeMarkReady;
|
|
259
|
+
private fireNotifications;
|
|
260
|
+
private armOrCancelDelegateTimers;
|
|
261
|
+
private fireDelegate;
|
|
262
|
+
private handleSendMessage;
|
|
263
|
+
private actuallySendMessage;
|
|
264
|
+
private handleClickControl;
|
|
265
|
+
private handleClickModalButton;
|
|
266
|
+
private handleAttachImage;
|
|
267
|
+
private tryAdvancePicker;
|
|
268
|
+
private handleExit;
|
|
269
|
+
private pushHistory;
|
|
270
|
+
private specTag;
|
|
271
|
+
private emit;
|
|
272
|
+
}
|
|
273
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { SectionDef } from './types.js';
|
|
2
|
+
import { type ResolvedSection, type TraceEntry } from './evaluator.js';
|
|
3
|
+
import { type CliSpecV4, type FsmCondition } from './fsm-types.js';
|
|
4
|
+
export interface FsmClock {
|
|
5
|
+
/** Wall-clock now (ms). Passed in so the evaluator stays pure. */
|
|
6
|
+
now: number;
|
|
7
|
+
/** When the current state was entered (ms). */
|
|
8
|
+
stateEnteredAt: number;
|
|
9
|
+
/** Last-changed timestamp per cursor_above region. Key = cursor_above
|
|
10
|
+
* value (0 / undefined → whole-screen, keyed as -1). Missing key means
|
|
11
|
+
* "never observed changing" → treated as stable since stateEnteredAt. */
|
|
12
|
+
regionLastChangedAt: Map<number, number>;
|
|
13
|
+
}
|
|
14
|
+
/** Per-condition evaluation detail — the debugging payload. */
|
|
15
|
+
export interface CondResult {
|
|
16
|
+
kind: 'regex' | 'changed' | 'elapsed' | 'stable' | 'all' | 'any' | 'not';
|
|
17
|
+
result: boolean;
|
|
18
|
+
detail: string;
|
|
19
|
+
/** Remaining ms until a time-based condition would flip to true. 0 if
|
|
20
|
+
* already true or not applicable. Lets the UI show a countdown. */
|
|
21
|
+
remainingMs?: number;
|
|
22
|
+
children?: CondResult[];
|
|
23
|
+
}
|
|
24
|
+
/** One evaluated transition with its full reasoning. */
|
|
25
|
+
export interface TransitionEval {
|
|
26
|
+
to: string;
|
|
27
|
+
label: string;
|
|
28
|
+
/** Did the `from` clause include the current state? (Always true for the
|
|
29
|
+
* transitions we return — kept for completeness.) */
|
|
30
|
+
eligible: boolean;
|
|
31
|
+
/** min_hold_ms guard satisfied? */
|
|
32
|
+
holdSatisfied: boolean;
|
|
33
|
+
holdRemainingMs: number;
|
|
34
|
+
/** Guard condition result (true if no `when`). */
|
|
35
|
+
condResult: boolean;
|
|
36
|
+
cond?: CondResult;
|
|
37
|
+
/** Overall: would this transition fire? */
|
|
38
|
+
fires: boolean;
|
|
39
|
+
priority: number;
|
|
40
|
+
}
|
|
41
|
+
export interface FsmEvaluation {
|
|
42
|
+
/** Sections resolved from the screen (shared with v3 shape). */
|
|
43
|
+
sections: ResolvedSection[];
|
|
44
|
+
/** Every outgoing transition from the current state, priority-ordered,
|
|
45
|
+
* each annotated with why it fired or didn't. */
|
|
46
|
+
transitions: TransitionEval[];
|
|
47
|
+
/** The transition that fires (first in priority order with fires===true),
|
|
48
|
+
* or null to stay in the current state. */
|
|
49
|
+
fired: TransitionEval | null;
|
|
50
|
+
/** v3-compatible trace lines for the legacy inspector. */
|
|
51
|
+
trace: TraceEntry[];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Evaluate the FSM: given the current state id and screen, return every
|
|
55
|
+
* outgoing transition annotated with why it fires/doesn't, plus the one that
|
|
56
|
+
* fires (if any).
|
|
57
|
+
*/
|
|
58
|
+
export declare function evaluateFsm(spec: CliSpecV4, currentStateId: string, screenText: string, cursor: {
|
|
59
|
+
row: number;
|
|
60
|
+
col: number;
|
|
61
|
+
} | undefined, prevLines: string[] | undefined, clock: FsmClock): FsmEvaluation;
|
|
62
|
+
/**
|
|
63
|
+
* Evaluate a single condition against a screen + section map — for the spec
|
|
64
|
+
* editor's live preview ("does this regex match the current screen right
|
|
65
|
+
* now?"). Time leaves (elapsed_ms/stable_ms) are evaluated against a synthetic
|
|
66
|
+
* clock where the state was just entered, so they report their countdown
|
|
67
|
+
* rather than firing; the preview is about screen-content match, not timing.
|
|
68
|
+
*/
|
|
69
|
+
export declare function evaluateConditionPreview(cond: FsmCondition, sections: Record<string, SectionDef> | undefined, screenText: string, cursor?: {
|
|
70
|
+
row: number;
|
|
71
|
+
col: number;
|
|
72
|
+
}): CondResult;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type CliSpecV4 } from './fsm-types.js';
|
|
2
|
+
export interface FsmLoadOk {
|
|
3
|
+
ok: true;
|
|
4
|
+
spec: CliSpecV4;
|
|
5
|
+
sourcePath: string;
|
|
6
|
+
}
|
|
7
|
+
export interface FsmLoadErr {
|
|
8
|
+
ok: false;
|
|
9
|
+
errors: string[];
|
|
10
|
+
sourcePath: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function loadFsmSpec(sourcePath: string): FsmLoadOk | FsmLoadErr;
|
|
13
|
+
/** Pure validator — usable from a "validate before save" API in the panel. */
|
|
14
|
+
export declare function validateFsmSpec(raw: unknown): string[];
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { RegexCondition, ChangedCondition, Control, NotificationRule, DelegateTrigger, NativeHistoryConfig, SectionDef, ExtractTitle, ExtractButtons } from './types.js';
|
|
2
|
+
/** True once `ms` have elapsed since the current state was entered. */
|
|
3
|
+
export interface ElapsedCondition {
|
|
4
|
+
elapsed_ms: number;
|
|
5
|
+
}
|
|
6
|
+
/** True once the region `cursor_above` lines above the cursor has been
|
|
7
|
+
* unchanged for `ms`. A stability gate — the inverse of a busy signal. */
|
|
8
|
+
export interface StableCondition {
|
|
9
|
+
stable_ms: number;
|
|
10
|
+
/** Lines above the cursor that must be stable. Default: whole screen. */
|
|
11
|
+
cursor_above?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface FsmAllCondition {
|
|
14
|
+
all: FsmCondition[];
|
|
15
|
+
}
|
|
16
|
+
export interface FsmAnyCondition {
|
|
17
|
+
any: FsmCondition[];
|
|
18
|
+
}
|
|
19
|
+
/** Negation — true when the inner condition is false. Lets a transition say
|
|
20
|
+
* "go busy unless the completion marker is present", etc. */
|
|
21
|
+
export interface FsmNotCondition {
|
|
22
|
+
not: FsmCondition;
|
|
23
|
+
}
|
|
24
|
+
export type FsmCondition = RegexCondition | ChangedCondition | ElapsedCondition | StableCondition | FsmAllCondition | FsmAnyCondition | FsmNotCondition;
|
|
25
|
+
export interface FsmState {
|
|
26
|
+
id: string;
|
|
27
|
+
label: string;
|
|
28
|
+
/** Exactly one state must be `initial: true` — the state at spawn. */
|
|
29
|
+
initial?: boolean;
|
|
30
|
+
/** Modal states (approval/picker) expose modal buttons in the UI and are
|
|
31
|
+
* treated as "interesting" — the dashboard surfaces them distinctly. */
|
|
32
|
+
modal?: boolean;
|
|
33
|
+
/** Status this state maps to for the dashboard/cli-adapter status field.
|
|
34
|
+
* One of: idle | generating | approval. Defaults: modal→approval,
|
|
35
|
+
* initial→idle, id==='busy'→generating, else idle. Explicit wins. */
|
|
36
|
+
status?: 'idle' | 'generating' | 'approval';
|
|
37
|
+
/** Optional extraction run whenever this state is the committed state —
|
|
38
|
+
* used by modal states to surface a title + buttons. */
|
|
39
|
+
extract?: {
|
|
40
|
+
title?: ExtractTitle;
|
|
41
|
+
buttons?: ExtractButtons;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export interface FsmTransition {
|
|
45
|
+
/** Source state id, or list of source ids, or "*" for any state. */
|
|
46
|
+
from: string | string[];
|
|
47
|
+
/** Destination state id. */
|
|
48
|
+
to: string;
|
|
49
|
+
/** Guard condition. Omitted → always eligible (only gated by `from` +
|
|
50
|
+
* min_hold_ms). Evaluated against the current screen + clock. */
|
|
51
|
+
when?: FsmCondition;
|
|
52
|
+
/** Minimum time the machine must have been in `from` before this edge can
|
|
53
|
+
* fire. Replaces busy_hold_ms / idle_hold_ms (per-edge, not global). */
|
|
54
|
+
min_hold_ms?: number;
|
|
55
|
+
/** Higher priority transitions are evaluated first. Default 0. Ties broken
|
|
56
|
+
* by declaration order. */
|
|
57
|
+
priority?: number;
|
|
58
|
+
/** Human label for the debugger. */
|
|
59
|
+
label?: string;
|
|
60
|
+
}
|
|
61
|
+
export interface CliSpecV4 {
|
|
62
|
+
$schema: 'adhdev:cli/spec@4';
|
|
63
|
+
id: string;
|
|
64
|
+
name: string;
|
|
65
|
+
binary: string;
|
|
66
|
+
spawn_args?: string[];
|
|
67
|
+
env?: Record<string, string>;
|
|
68
|
+
cli_version_range?: string;
|
|
69
|
+
send_message: {
|
|
70
|
+
submit_key: string;
|
|
71
|
+
delay_ms_before_submit?: number;
|
|
72
|
+
delay_ms_per_char?: number;
|
|
73
|
+
};
|
|
74
|
+
sections: Record<string, SectionDef>;
|
|
75
|
+
states: FsmState[];
|
|
76
|
+
transitions: FsmTransition[];
|
|
77
|
+
control_bar?: Control[];
|
|
78
|
+
notifications?: NotificationRule[];
|
|
79
|
+
delegate?: DelegateTrigger[];
|
|
80
|
+
native_history?: NativeHistoryConfig;
|
|
81
|
+
requiresFinalAssistantBeforeIdle?: boolean;
|
|
82
|
+
}
|
|
83
|
+
export declare function isV4Spec(raw: unknown): raw is CliSpecV4;
|
|
84
|
+
export declare function initialState(spec: CliSpecV4): FsmState;
|
|
85
|
+
export declare function stateById(spec: CliSpecV4, id: string): FsmState | undefined;
|
|
86
|
+
/** Outgoing transitions from `stateId`, highest priority first, declaration
|
|
87
|
+
* order as tiebreak. Includes wildcard ("*") and list-membership sources. */
|
|
88
|
+
export declare function outgoingTransitions(spec: CliSpecV4, stateId: string): FsmTransition[];
|
|
89
|
+
/** Map a state to the dashboard status string, applying the documented
|
|
90
|
+
* defaults when `status` is not explicit. */
|
|
91
|
+
export declare function statusForState(state: FsmState): 'idle' | 'generating' | 'approval';
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { NativeHistoryConfig } from './types.js';
|
|
2
|
+
export interface NativeHistoryInput {
|
|
3
|
+
agentType?: string;
|
|
4
|
+
sessionId?: string;
|
|
5
|
+
providerSessionId?: string;
|
|
6
|
+
historySessionId?: string;
|
|
7
|
+
workspace?: string;
|
|
8
|
+
/** Daemon-side wall clock at the moment the session was registered.
|
|
9
|
+
* Native-history file lookups use this as the lower bound: any file
|
|
10
|
+
* whose mtime is before the current session started can't be from
|
|
11
|
+
* this session, so it's excluded from newest-recent matching. The
|
|
12
|
+
* caller (chat-history pipeline) populates this from the session
|
|
13
|
+
* registry; specs/executor never need to know how it's sourced. */
|
|
14
|
+
sessionStartedAtMs?: number;
|
|
15
|
+
/** Env overrides the daemon set on the spawned CLI. The mesh
|
|
16
|
+
* coordinator points hermes at a per-coordinator HERMES_HOME so
|
|
17
|
+
* the hermes process writes its state.db into a tmp directory
|
|
18
|
+
* instead of ~/.hermes. expandPath consults this map before
|
|
19
|
+
* process.env so the native-history reader follows the spawned
|
|
20
|
+
* child's view of HERMES_HOME / similar overrides; without it
|
|
21
|
+
* the reader would always look at ~/.hermes and miss every
|
|
22
|
+
* coordinator-session transcript. */
|
|
23
|
+
envOverrides?: Record<string, string>;
|
|
24
|
+
args?: Record<string, unknown>;
|
|
25
|
+
}
|
|
26
|
+
export interface NativeHistoryMessage {
|
|
27
|
+
role: 'user' | 'assistant' | 'system';
|
|
28
|
+
content: string;
|
|
29
|
+
receivedAt: number;
|
|
30
|
+
kind?: string;
|
|
31
|
+
workspace?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface NativeHistoryResult {
|
|
34
|
+
messages: NativeHistoryMessage[];
|
|
35
|
+
providerSessionId?: string;
|
|
36
|
+
sourcePath: string;
|
|
37
|
+
sourceMtimeMs: number;
|
|
38
|
+
nativeHistoryCoverage?: 'full' | 'partial' | 'best-effort';
|
|
39
|
+
workspace?: string;
|
|
40
|
+
}
|
|
41
|
+
export declare function executeNativeHistory(cfg: NativeHistoryConfig, input: NativeHistoryInput): NativeHistoryResult | null;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CliProviderModule } from '../../cli-adapters/provider-cli-adapter.js';
|
|
2
|
+
import type { PtyTransportFactory } from '../../cli-adapters/pty-transport.js';
|
|
3
|
+
import type { CliAdapter } from '../../cli-adapter-types.js';
|
|
4
|
+
export declare function createCliAdapter(provider: CliProviderModule, workingDir: string, cliArgs: string[], extraEnv: Record<string, string>, transportFactory?: PtyTransportFactory): CliAdapter;
|