@adhdev/daemon-core 0.9.82-rc.22 → 0.9.82-rc.220
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 +1 -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 +178 -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 +29 -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 +32 -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 +46 -11
- package/dist/index.js +36322 -15614
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +36182 -15568
- 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 +151 -0
- package/dist/mesh/mesh-events-pending.d.ts +33 -0
- package/dist/mesh/mesh-events-stale.d.ts +40 -0
- package/dist/mesh/mesh-events-utils.d.ts +14 -0
- package/dist/mesh/mesh-events.d.ts +5 -40
- 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-status.d.ts +26 -0
- package/dist/mesh/mesh-review-inbox.d.ts +90 -0
- package/dist/mesh/mesh-runtime-store.d.ts +324 -0
- package/dist/mesh/mesh-task-stats.d.ts +49 -0
- package/dist/mesh/mesh-work-queue.d.ts +137 -6
- 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 +39 -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 +12 -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 +102 -0
- package/dist/providers/spec/driver.d.ts +287 -0
- package/dist/providers/spec/evaluator.d.ts +70 -0
- package/dist/providers/spec/fsm-driver.d.ts +110 -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/loader.d.ts +15 -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/schema.gen.d.ts +2039 -0
- package/dist/providers/spec/types.d.ts +311 -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 +3 -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 +22 -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 +1162 -0
- package/src/cli-adapters/provider-cli-adapter.d.ts +1 -1
- package/src/cli-adapters/provider-cli-adapter.ts +673 -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 +59 -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 +1787 -60
- package/src/commands/cli-manager.ts +283 -14
- package/src/commands/handler.ts +809 -2
- package/src/commands/mesh-coordinator.ts +332 -122
- package/src/commands/router.ts +4369 -558
- 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 +126 -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 +218 -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 +1447 -0
- package/src/mesh/mesh-events-pending.ts +371 -0
- package/src/mesh/mesh-events-stale.ts +283 -0
- package/src/mesh/mesh-events-utils.ts +166 -0
- package/src/mesh/mesh-events.ts +24 -908
- 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 +587 -102
- package/src/mesh/mesh-missions.ts +151 -0
- package/src/mesh/mesh-refine-status.ts +144 -0
- package/src/mesh/mesh-review-inbox.ts +307 -0
- package/src/mesh/mesh-runtime-store.ts +1305 -0
- package/src/mesh/mesh-task-stats.ts +154 -0
- package/src/mesh/mesh-work-queue.ts +490 -166
- 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 +834 -64
- 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 +592 -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 +138 -0
- package/src/providers/spec/cli-adapter.ts +674 -0
- package/src/providers/spec/driver.ts +1082 -0
- package/src/providers/spec/evaluator.ts +604 -0
- package/src/providers/spec/fsm-driver.ts +663 -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/loader.ts +325 -0
- package/src/providers/spec/native-history-executor.ts +939 -0
- package/src/providers/spec/route.ts +51 -0
- package/src/providers/spec/schema.gen.ts +693 -0
- package/src/providers/spec/schema.json +342 -0
- package/src/providers/spec/types.ts +365 -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 +3 -0
- package/src/shared-types-extra.ts +2 -4
- package/src/shared-types.ts +45 -1
- package/src/status/builders.ts +24 -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,287 @@
|
|
|
1
|
+
import type { PtyTransportFactory } from '../../cli-adapters/pty-transport.js';
|
|
2
|
+
import { type SpecEvaluation, type TraceEntry } from './evaluator.js';
|
|
3
|
+
import type { CliSpec } from './types.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
|
+
};
|
|
14
|
+
modal: {
|
|
15
|
+
title: string | null;
|
|
16
|
+
buttons: {
|
|
17
|
+
index: number;
|
|
18
|
+
label: string;
|
|
19
|
+
}[];
|
|
20
|
+
} | null;
|
|
21
|
+
controls: {
|
|
22
|
+
id: string;
|
|
23
|
+
label: string;
|
|
24
|
+
action_type: string;
|
|
25
|
+
}[];
|
|
26
|
+
} | {
|
|
27
|
+
kind: 'notification';
|
|
28
|
+
id: string;
|
|
29
|
+
title: string;
|
|
30
|
+
body: string;
|
|
31
|
+
} | {
|
|
32
|
+
kind: 'delegate';
|
|
33
|
+
id: string;
|
|
34
|
+
task: string;
|
|
35
|
+
} | {
|
|
36
|
+
kind: 'spec_trace';
|
|
37
|
+
entries: TraceEntry[];
|
|
38
|
+
} | {
|
|
39
|
+
kind: 'exit';
|
|
40
|
+
exit_code: number;
|
|
41
|
+
} | {
|
|
42
|
+
kind: 'spec_error';
|
|
43
|
+
errors: string[];
|
|
44
|
+
};
|
|
45
|
+
export type DashboardCommand = {
|
|
46
|
+
kind: 'send_message';
|
|
47
|
+
text: string;
|
|
48
|
+
} | {
|
|
49
|
+
kind: 'pty_write';
|
|
50
|
+
data: string;
|
|
51
|
+
} | {
|
|
52
|
+
kind: 'click_control';
|
|
53
|
+
control_id: string;
|
|
54
|
+
payload?: unknown;
|
|
55
|
+
} | {
|
|
56
|
+
kind: 'click_modal_button';
|
|
57
|
+
index: number;
|
|
58
|
+
} | {
|
|
59
|
+
kind: 'attach_image';
|
|
60
|
+
blob: string;
|
|
61
|
+
mime: string;
|
|
62
|
+
} | {
|
|
63
|
+
kind: 'resize';
|
|
64
|
+
cols: number;
|
|
65
|
+
rows: number;
|
|
66
|
+
} | {
|
|
67
|
+
kind: 'cancel';
|
|
68
|
+
} | {
|
|
69
|
+
kind: 'shutdown';
|
|
70
|
+
};
|
|
71
|
+
/** One state-history entry — the union of fields produced by the v3 SpecDriver
|
|
72
|
+
* (debounce-based) and the v4 FsmDriver (transition-based). The cli-adapter
|
|
73
|
+
* and debug panel read this shape from either driver. */
|
|
74
|
+
export interface DriverHistoryEntry {
|
|
75
|
+
stateId: string;
|
|
76
|
+
label: string;
|
|
77
|
+
at: number;
|
|
78
|
+
durationMs: number;
|
|
79
|
+
reason: string;
|
|
80
|
+
matchedStateId?: string;
|
|
81
|
+
matchedRules?: string[];
|
|
82
|
+
debounceKind?: string;
|
|
83
|
+
idleHoldMs?: number;
|
|
84
|
+
busyHoldMs?: number;
|
|
85
|
+
/** v4: the transition that fired, e.g. "idle→busy". */
|
|
86
|
+
via?: string;
|
|
87
|
+
}
|
|
88
|
+
/** The surface the cli-adapter drives. Implemented by both SpecDriver (v3,
|
|
89
|
+
* debounce) and FsmDriver (v4, FSM). Lets the adapter hold either without
|
|
90
|
+
* branching on the concrete type. */
|
|
91
|
+
export interface ISpecDriver {
|
|
92
|
+
subscribe(listener: (ev: DashboardEvent) => void): () => void;
|
|
93
|
+
start(): void;
|
|
94
|
+
dispatch(cmd: DashboardCommand): void;
|
|
95
|
+
snapshot(): string;
|
|
96
|
+
getCursorPosition(): {
|
|
97
|
+
row: number;
|
|
98
|
+
col: number;
|
|
99
|
+
};
|
|
100
|
+
getScreen(): string;
|
|
101
|
+
getSpecPath(): string;
|
|
102
|
+
shutdown(): void;
|
|
103
|
+
getStateHistory(): ReadonlyArray<DriverHistoryEntry>;
|
|
104
|
+
getSections(): Array<{
|
|
105
|
+
id: string;
|
|
106
|
+
text: string;
|
|
107
|
+
}> | null;
|
|
108
|
+
getLastBusyAt(): number;
|
|
109
|
+
hasIdleHoldPending(): boolean;
|
|
110
|
+
getCompletionIdleDebounceState(): {
|
|
111
|
+
active: boolean;
|
|
112
|
+
ageMs: number;
|
|
113
|
+
holdMs: number;
|
|
114
|
+
forceAfterMs: number;
|
|
115
|
+
} | null;
|
|
116
|
+
/** v4 only — present on FsmDriver. Returns the live transition table. */
|
|
117
|
+
getFsmDebug?(): unknown;
|
|
118
|
+
}
|
|
119
|
+
export interface SpecDriverOpts {
|
|
120
|
+
specPath: string;
|
|
121
|
+
workingDir: string;
|
|
122
|
+
extraEnv?: Record<string, string>;
|
|
123
|
+
cols?: number;
|
|
124
|
+
rows?: number;
|
|
125
|
+
/** Set false to skip the spec.json fs.watch. */
|
|
126
|
+
hotReload?: boolean;
|
|
127
|
+
/** Set true to forward trace entries on every state_changed. */
|
|
128
|
+
emitTrace?: boolean;
|
|
129
|
+
/** Inject the daemon's PTY transport (typically SessionHostPtyTransportFactory). */
|
|
130
|
+
transportFactory?: PtyTransportFactory;
|
|
131
|
+
/**
|
|
132
|
+
* Extra CLI args appended to spec.spawn_args. Used by the daemon to
|
|
133
|
+
* pass per-launch arguments like `--session-id <uuid>` so the agent
|
|
134
|
+
* uses the daemon's providerSessionId instead of generating its own.
|
|
135
|
+
*/
|
|
136
|
+
extraCliArgs?: string[];
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Pick the effective delay (ms) to wait between writing the prompt body and
|
|
140
|
+
* writing the submit_key. Exported for tests; production callers go through
|
|
141
|
+
* actuallySendMessage. Floors to SUBMIT_DELAY_FLOOR_MS so specs that omit
|
|
142
|
+
* delay_ms_before_submit (e.g. claude, antigravity) still get baseline
|
|
143
|
+
* protection against the paste→submit race. Adds line-count bonus so
|
|
144
|
+
* multi-line prompts get more settling time on TUIs that re-render per
|
|
145
|
+
* embedded `\n`.
|
|
146
|
+
*/
|
|
147
|
+
export declare function resolveSubmitDelayMs(specBeforeSubmit: number | undefined, text: string): number;
|
|
148
|
+
export declare function matchesCompletionIdleRule(spec: CliSpec, ev: SpecEvaluation, screen: string): string | null;
|
|
149
|
+
export declare function matchesCompletionIdleTargetState(spec: CliSpec, ev: SpecEvaluation, screen: string, cursor?: {
|
|
150
|
+
row: number;
|
|
151
|
+
col: number;
|
|
152
|
+
}): boolean;
|
|
153
|
+
export declare class SpecDriver implements ISpecDriver {
|
|
154
|
+
private readonly opts;
|
|
155
|
+
private spec;
|
|
156
|
+
private adapter;
|
|
157
|
+
private listeners;
|
|
158
|
+
private currentStateId;
|
|
159
|
+
/** Have we ever seen the spec's idle state *after* the startup grace
|
|
160
|
+
* window? Until we do, the agent's startup banner may still be
|
|
161
|
+
* painting and any send_message we forward to the PTY will be wiped
|
|
162
|
+
* when the banner clears the screen. Queue + drain on first valid
|
|
163
|
+
* idle. */
|
|
164
|
+
private idleSeenOnce;
|
|
165
|
+
private startedAtMs;
|
|
166
|
+
private pendingSends;
|
|
167
|
+
private currentEval;
|
|
168
|
+
private pickerInProgress;
|
|
169
|
+
private delegateTimers;
|
|
170
|
+
/** Timestamp of the last time the evaluator returned busy. Used to debounce
|
|
171
|
+
* the busy → idle transition (see reevaluate). */
|
|
172
|
+
private lastBusyAt;
|
|
173
|
+
/** The exact busy state object we last saw — held alongside lastBusyAt so
|
|
174
|
+
* the hold can re-emit the same { id: 'busy', label, title } payload the
|
|
175
|
+
* dashboard already learned about. currentEval can't fill this role
|
|
176
|
+
* because the evaluator already moved past busy by the time the hold
|
|
177
|
+
* kicks in. */
|
|
178
|
+
private lastBusyState;
|
|
179
|
+
/** Timestamp of the last time we entered a modal state (approval/picker or
|
|
180
|
+
* any non-busy non-idle state). Used to suppress brief busy blips that
|
|
181
|
+
* appear while the modal is still on screen — Claude Code streams body
|
|
182
|
+
* text that transiently shows a spinner even while an approval modal is
|
|
183
|
+
* visible, causing rapid approval→busy→approval flicker on the dashboard. */
|
|
184
|
+
private lastModalAt;
|
|
185
|
+
/** The modal state snapshot held across busy blips. */
|
|
186
|
+
private lastModalState;
|
|
187
|
+
/** Timestamp of when we last *exited* a modal state (approval/picker → idle
|
|
188
|
+
* or directly via completion_idle_after). Used to suppress completion_idle_after
|
|
189
|
+
* firings that were queued before the modal appeared and expire immediately
|
|
190
|
+
* after the modal is dismissed — without this the agent appears idle even
|
|
191
|
+
* though it is still generating. */
|
|
192
|
+
private lastModalExitAt;
|
|
193
|
+
private completionIdleFirstSeenAt;
|
|
194
|
+
private completionIdleKey;
|
|
195
|
+
/** Previous screen lines — passed to evaluate() for `changed` condition detection. */
|
|
196
|
+
private prevScreenLines;
|
|
197
|
+
/** Timestamp when idle was last committed (either direct or via idle_hold_ms).
|
|
198
|
+
* Used to suppress immediate idle → busy re-entry from transient `changed`
|
|
199
|
+
* condition blips (e.g. completion-marker counter "Completed for Xs" updating
|
|
200
|
+
* every second, which triggers cursor_above:changed and bounces back to busy
|
|
201
|
+
* right after an idle commit). */
|
|
202
|
+
private lastIdleCommittedAt;
|
|
203
|
+
/** Timestamp of the last PTY frame that changed the screen content.
|
|
204
|
+
* Used by screen_active_hold_ms to suppress idle downshifts while
|
|
205
|
+
* the terminal is still actively updating. */
|
|
206
|
+
private lastScreenChangedAt;
|
|
207
|
+
/** Per-cursor_above region last-changed timestamps for stable_ms tracking.
|
|
208
|
+
* Key: cursor_above value. Value: last time that region changed. */
|
|
209
|
+
private regionLastChangedAt;
|
|
210
|
+
/** Timer that re-runs evaluate() once the hold window expires. Needed
|
|
211
|
+
* because the PTY stops emitting once the agent finishes; without an
|
|
212
|
+
* explicit wake-up there's nothing to trigger the busy → idle
|
|
213
|
+
* downshift. */
|
|
214
|
+
private busyExpiryTimer;
|
|
215
|
+
/** Set true while reevaluate() is invoked from busyExpiryTimer callback. */
|
|
216
|
+
private busyExpiryFired;
|
|
217
|
+
/** Pending idle-commit timer. Armed when the evaluator first returns idle;
|
|
218
|
+
* fires after idle_hold_ms if no non-idle reading has cancelled it. */
|
|
219
|
+
private idleHoldTimer;
|
|
220
|
+
/** State snapshot captured when the idle hold was armed — emitted on commit. */
|
|
221
|
+
private pendingIdleState;
|
|
222
|
+
private specWatcher;
|
|
223
|
+
/** Ring buffer of committed state transitions (max 50). */
|
|
224
|
+
private stateHistory;
|
|
225
|
+
private prevStateAt;
|
|
226
|
+
constructor(opts: SpecDriverOpts);
|
|
227
|
+
/** Subscribe to outbound events. Returns an unsubscribe fn. */
|
|
228
|
+
subscribe(listener: (ev: DashboardEvent) => void): () => void;
|
|
229
|
+
start(): void;
|
|
230
|
+
dispatch(cmd: DashboardCommand): void;
|
|
231
|
+
snapshot(): string;
|
|
232
|
+
getCursorPosition(): {
|
|
233
|
+
row: number;
|
|
234
|
+
col: number;
|
|
235
|
+
};
|
|
236
|
+
shutdown(): void;
|
|
237
|
+
private cancelIdleHold;
|
|
238
|
+
private pushHistory;
|
|
239
|
+
getStateHistory(): ReadonlyArray<{
|
|
240
|
+
stateId: string;
|
|
241
|
+
label: string;
|
|
242
|
+
at: number;
|
|
243
|
+
durationMs: number;
|
|
244
|
+
reason: string;
|
|
245
|
+
matchedStateId?: string;
|
|
246
|
+
matchedRules?: string[];
|
|
247
|
+
debounceKind?: string;
|
|
248
|
+
idleHoldMs?: number;
|
|
249
|
+
busyHoldMs?: number;
|
|
250
|
+
}>;
|
|
251
|
+
getLastBusyAt(): number;
|
|
252
|
+
hasIdleHoldPending(): boolean;
|
|
253
|
+
getSpecPath(): string;
|
|
254
|
+
getCompletionIdleDebounceState(): {
|
|
255
|
+
active: boolean;
|
|
256
|
+
ageMs: number;
|
|
257
|
+
holdMs: number;
|
|
258
|
+
forceAfterMs: number;
|
|
259
|
+
} | null;
|
|
260
|
+
getScreen(): string;
|
|
261
|
+
getSections(): Array<{
|
|
262
|
+
id: string;
|
|
263
|
+
text: string;
|
|
264
|
+
}> | null;
|
|
265
|
+
private loadSpecOrThrow;
|
|
266
|
+
private buildAdapterOpts;
|
|
267
|
+
private armSpecWatcher;
|
|
268
|
+
private emitInitialState;
|
|
269
|
+
/** Re-arm the timer that wakes the driver up after BUSY_HOLD_MS so it
|
|
270
|
+
* can decide whether to downshift to idle. Always uses the most recent
|
|
271
|
+
* hold value so a spec hot-reload that shortens the hold takes effect
|
|
272
|
+
* on the next busy entry. Safe to call repeatedly; only the last call
|
|
273
|
+
* fires. */
|
|
274
|
+
private scheduleBusyExpiry;
|
|
275
|
+
private reevaluate;
|
|
276
|
+
private armOrCancelDelegateTimers;
|
|
277
|
+
private fireDelegate;
|
|
278
|
+
private handleSendMessage;
|
|
279
|
+
private actuallySendMessage;
|
|
280
|
+
private handleClickControl;
|
|
281
|
+
private handleClickModalButton;
|
|
282
|
+
private handleAttachImage;
|
|
283
|
+
private tryAdvancePicker;
|
|
284
|
+
private handleExit;
|
|
285
|
+
private emit;
|
|
286
|
+
}
|
|
287
|
+
export declare function guessExt(mime: string): string;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { CliSpec, 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 ModalSnapshot {
|
|
9
|
+
title: string | null;
|
|
10
|
+
buttons: {
|
|
11
|
+
index: number;
|
|
12
|
+
label: string;
|
|
13
|
+
key: string;
|
|
14
|
+
}[];
|
|
15
|
+
}
|
|
16
|
+
export interface VisibleControl {
|
|
17
|
+
id: string;
|
|
18
|
+
label: string;
|
|
19
|
+
actionType: 'send_keys' | 'open_picker' | 'attach_image';
|
|
20
|
+
}
|
|
21
|
+
export interface FiredNotification {
|
|
22
|
+
id: string;
|
|
23
|
+
title: string;
|
|
24
|
+
body: string;
|
|
25
|
+
}
|
|
26
|
+
export interface FiredDelegate {
|
|
27
|
+
id: string;
|
|
28
|
+
task: string;
|
|
29
|
+
}
|
|
30
|
+
export interface TraceEntry {
|
|
31
|
+
kind: 'section' | 'state_match' | 'state_skip' | 'modal' | 'control' | 'notification' | 'delegate';
|
|
32
|
+
text: string;
|
|
33
|
+
}
|
|
34
|
+
export interface SpecEvaluation {
|
|
35
|
+
state: {
|
|
36
|
+
id: string;
|
|
37
|
+
label: string;
|
|
38
|
+
title: string | null;
|
|
39
|
+
};
|
|
40
|
+
modal: ModalSnapshot | null;
|
|
41
|
+
controls: VisibleControl[];
|
|
42
|
+
notifications: FiredNotification[];
|
|
43
|
+
delegates: FiredDelegate[];
|
|
44
|
+
sections: ResolvedSection[];
|
|
45
|
+
trace: TraceEntry[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Resolve v3 sections{} object into an ordered array of ResolvedSection.
|
|
49
|
+
* Two-pass: first anchor/positional, then apply `until` cross-references.
|
|
50
|
+
*/
|
|
51
|
+
export declare function resolveSections(sectionsObj: Record<string, SectionDef>, lines: string[]): ResolvedSection[];
|
|
52
|
+
export declare function sectionText(sections: ResolvedSection[], sectionId: string | undefined, fullScreen: string): string;
|
|
53
|
+
export declare function evaluateCondition(cond: Condition, sections: ResolvedSection[], fullScreen: string, cursor: {
|
|
54
|
+
row: number;
|
|
55
|
+
col: number;
|
|
56
|
+
} | undefined, prevLines: string[] | undefined, trace: TraceEntry[], stateId: string): boolean;
|
|
57
|
+
export declare function extractTitle(rule: ExtractTitle, sections: ResolvedSection[], fullScreen: string): string | null;
|
|
58
|
+
export declare function extractButtonsFromRule(rule: ExtractButtons, hay: string): {
|
|
59
|
+
index: number;
|
|
60
|
+
label: string;
|
|
61
|
+
key: string;
|
|
62
|
+
}[];
|
|
63
|
+
export declare function evaluate(spec: CliSpec, screenText: string,
|
|
64
|
+
/** Optional cursor position (0-based row and col). */
|
|
65
|
+
cursor?: {
|
|
66
|
+
row: number;
|
|
67
|
+
col: number;
|
|
68
|
+
},
|
|
69
|
+
/** Optional previous screen lines for `changed` condition detection. */
|
|
70
|
+
prevLines?: string[]): SpecEvaluation;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { type TransitionEval } from './fsm-evaluator.js';
|
|
2
|
+
import { type DashboardEvent, type DashboardCommand, type SpecDriverOpts, type ISpecDriver, type DriverHistoryEntry } from './driver.js';
|
|
3
|
+
type HistoryEntry = DriverHistoryEntry;
|
|
4
|
+
export declare class FsmDriver implements ISpecDriver {
|
|
5
|
+
private readonly opts;
|
|
6
|
+
private spec;
|
|
7
|
+
private adapter;
|
|
8
|
+
private listeners;
|
|
9
|
+
private currentStateId;
|
|
10
|
+
private stateEnteredAt;
|
|
11
|
+
private startedAtMs;
|
|
12
|
+
private prevScreenLines;
|
|
13
|
+
/** Per cursor_above region (key: cursor_above, -1 = whole screen) → last
|
|
14
|
+
* time that region's content changed. Drives stable_ms conditions. */
|
|
15
|
+
private regionLastChangedAt;
|
|
16
|
+
/** Timer that re-runs evaluate() when a time-condition would flip true
|
|
17
|
+
* with no PTY frame to trigger it. */
|
|
18
|
+
private wakeTimer;
|
|
19
|
+
private currentEval;
|
|
20
|
+
private stateHistory;
|
|
21
|
+
private prevStateAt;
|
|
22
|
+
private readySeenOnce;
|
|
23
|
+
private pendingSends;
|
|
24
|
+
private pickerInProgress;
|
|
25
|
+
private delegateTimers;
|
|
26
|
+
private specWatcher;
|
|
27
|
+
/** Last full FSM evaluation, kept for the debugger. */
|
|
28
|
+
private lastFsmEval;
|
|
29
|
+
constructor(opts: SpecDriverOpts);
|
|
30
|
+
subscribe(listener: (ev: DashboardEvent) => void): () => void;
|
|
31
|
+
start(): void;
|
|
32
|
+
dispatch(cmd: DashboardCommand): void;
|
|
33
|
+
snapshot(): string;
|
|
34
|
+
getCursorPosition(): {
|
|
35
|
+
row: number;
|
|
36
|
+
col: number;
|
|
37
|
+
};
|
|
38
|
+
getScreen(): string;
|
|
39
|
+
getSpecPath(): string;
|
|
40
|
+
shutdown(): void;
|
|
41
|
+
getFsmDebug(): {
|
|
42
|
+
currentState: string;
|
|
43
|
+
label: string;
|
|
44
|
+
stateAgeMs: number;
|
|
45
|
+
status: string;
|
|
46
|
+
cursor: {
|
|
47
|
+
row: number;
|
|
48
|
+
col: number;
|
|
49
|
+
};
|
|
50
|
+
transitions: TransitionEval[];
|
|
51
|
+
};
|
|
52
|
+
getStateHistory(): ReadonlyArray<HistoryEntry>;
|
|
53
|
+
getSections(): Array<{
|
|
54
|
+
id: string;
|
|
55
|
+
text: string;
|
|
56
|
+
}> | null;
|
|
57
|
+
/** v3-compat shims so the cli-adapter's existing debug snapshot keeps
|
|
58
|
+
* working without branching on driver type. */
|
|
59
|
+
getLastBusyAt(): number;
|
|
60
|
+
hasIdleHoldPending(): boolean;
|
|
61
|
+
getCompletionIdleDebounceState(): {
|
|
62
|
+
active: boolean;
|
|
63
|
+
ageMs: number;
|
|
64
|
+
holdMs: number;
|
|
65
|
+
forceAfterMs: number;
|
|
66
|
+
} | null;
|
|
67
|
+
private loadSpecOrThrow;
|
|
68
|
+
private buildAdapterOpts;
|
|
69
|
+
private armSpecWatcher;
|
|
70
|
+
private emitInitialState;
|
|
71
|
+
private buildClock;
|
|
72
|
+
private evalFsmNow;
|
|
73
|
+
private reevaluate;
|
|
74
|
+
private commitTransition;
|
|
75
|
+
/** Re-derive the visible modal + controls for the current state and emit a
|
|
76
|
+
* state_changed if anything differs from the last emit. */
|
|
77
|
+
private emitStateChanged;
|
|
78
|
+
private deriveModal;
|
|
79
|
+
private deriveTitle;
|
|
80
|
+
private deriveControls;
|
|
81
|
+
/** Track which cursor_above regions changed since the previous frame so
|
|
82
|
+
* stable_ms conditions can measure quiet time. We record every region
|
|
83
|
+
* size referenced by a stable_ms condition in the spec, plus the whole
|
|
84
|
+
* screen (-1). */
|
|
85
|
+
private trackRegionChanges;
|
|
86
|
+
/** All cursor_above region sizes referenced by stable_ms conditions in the
|
|
87
|
+
* current state's outgoing transitions, plus whole-screen. Cached lazily
|
|
88
|
+
* per spec load would be nicer but the set is tiny. */
|
|
89
|
+
private stableRegionSizes;
|
|
90
|
+
/** Schedule a re-evaluation for the soonest pending time-condition on any
|
|
91
|
+
* outgoing transition (elapsed_ms / stable_ms / min_hold_ms). Without
|
|
92
|
+
* this, a state whose only exit is time-based would never leave once the
|
|
93
|
+
* PTY goes quiet. */
|
|
94
|
+
private scheduleWakeForState;
|
|
95
|
+
private maybeMarkReady;
|
|
96
|
+
private fireNotifications;
|
|
97
|
+
private armOrCancelDelegateTimers;
|
|
98
|
+
private fireDelegate;
|
|
99
|
+
private handleSendMessage;
|
|
100
|
+
private actuallySendMessage;
|
|
101
|
+
private handleClickControl;
|
|
102
|
+
private handleClickModalButton;
|
|
103
|
+
private handleAttachImage;
|
|
104
|
+
private tryAdvancePicker;
|
|
105
|
+
private handleExit;
|
|
106
|
+
private pushHistory;
|
|
107
|
+
private specTag;
|
|
108
|
+
private emit;
|
|
109
|
+
}
|
|
110
|
+
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,15 @@
|
|
|
1
|
+
import type { CliSpec } from './types.js';
|
|
2
|
+
export interface SpecLoadResult {
|
|
3
|
+
ok: true;
|
|
4
|
+
spec: CliSpec;
|
|
5
|
+
sourcePath: string;
|
|
6
|
+
}
|
|
7
|
+
export interface SpecLoadError {
|
|
8
|
+
ok: false;
|
|
9
|
+
errors: string[];
|
|
10
|
+
sourcePath: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function loadSpec(sourcePath: string): SpecLoadResult | SpecLoadError;
|
|
13
|
+
export declare function migrateV1toV3(raw: any): any;
|
|
14
|
+
/** Convenience: look up a provider's spec.json next to its provider dir. */
|
|
15
|
+
export declare function resolveSpecPath(providerDir: string): string;
|