@adhdev/daemon-core 0.8.33 → 0.8.35
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/index.d.ts +1 -1
- package/dist/index.js +127 -102
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +127 -102
- package/dist/index.mjs.map +1 -1
- package/dist/shared-types.d.ts +38 -0
- package/dist/status/reporter.d.ts +3 -0
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/agent-stream/forward.d.ts +8 -0
- package/src/agent-stream/index.d.ts +6 -0
- package/src/agent-stream/manager.d.ts +60 -0
- package/src/agent-stream/poller.d.ts +41 -0
- package/src/agent-stream/provider-adapter.d.ts +36 -0
- package/src/agent-stream/types.d.ts +68 -0
- package/src/boot/daemon-lifecycle.d.ts +100 -0
- package/src/cdp/devtools.d.ts +51 -0
- package/src/cdp/initializer.d.ts +50 -0
- package/src/cdp/manager.d.ts +147 -0
- package/src/cdp/scanner.d.ts +58 -0
- package/src/cdp/setup.d.ts +58 -0
- package/src/cli-adapter-types.d.ts +57 -0
- package/src/cli-adapters/provider-cli-adapter.d.ts +177 -0
- package/src/cli-adapters/provider-cli-adapter.ts +115 -91
- package/src/cli-adapters/provider-cli-config.d.ts +30 -0
- package/src/cli-adapters/provider-cli-parse.d.ts +42 -0
- package/src/cli-adapters/provider-cli-runtime.d.ts +29 -0
- package/src/cli-adapters/provider-cli-shared.d.ts +158 -0
- package/src/cli-adapters/pty-transport.d.ts +48 -0
- package/src/cli-adapters/session-host-transport.d.ts +20 -0
- package/src/cli-adapters/spawn-env.d.ts +8 -0
- package/src/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +16 -0
- package/src/cli-adapters/terminal-backends/types.d.ts +18 -0
- package/src/cli-adapters/terminal-backends/xterm-backend.d.ts +17 -0
- package/src/cli-adapters/terminal-screen.d.ts +33 -0
- package/src/commands/cdp-commands.d.ts +15 -0
- package/src/commands/chat-commands.d.ts +15 -0
- package/src/commands/cli-manager.d.ts +94 -0
- package/src/commands/handler.d.ts +103 -0
- package/src/commands/router.d.ts +98 -0
- package/src/commands/stream-commands.d.ts +14 -0
- package/src/commands/upgrade-helper.d.ts +10 -0
- package/src/commands/workspace-commands.d.ts +11 -0
- package/src/config/chat-history.d.ts +99 -0
- package/src/config/config.d.ts +14 -0
- package/src/config/recent-activity.d.ts +29 -0
- package/src/config/saved-sessions.d.ts +22 -0
- package/src/config/state-store.d.ts +32 -0
- package/src/config/workspaces.d.ts +0 -1
- package/src/daemon/dev-auto-implement.d.ts +43 -0
- package/src/daemon/dev-cdp-handlers.d.ts +22 -0
- package/src/daemon/dev-cli-debug.d.ts +106 -0
- package/src/daemon/dev-server-types.d.ts +43 -0
- package/src/daemon/dev-server.d.ts +140 -0
- package/src/daemon/scaffold-template.d.ts +32 -0
- package/src/daemon-core.d.ts +36 -0
- package/src/detection/cli-detector.d.ts +31 -0
- package/src/detection/ide-detector.d.ts +35 -0
- package/src/index.d.ts +83 -0
- package/src/index.ts +2 -0
- package/src/installer.d.ts +50 -0
- package/src/ipc-protocol.d.ts +111 -0
- package/src/launch.d.ts +46 -0
- package/src/logging/command-log.d.ts +31 -0
- package/src/logging/logger.d.ts +89 -0
- package/src/providers/acp-provider-instance.d.ts +102 -0
- package/src/providers/approval-utils.d.ts +7 -0
- package/src/providers/cli-provider-instance.d.ts +86 -0
- package/src/providers/contracts.d.ts +193 -1
- package/src/providers/control-effects.d.ts +4 -0
- package/src/providers/extension-provider-instance.d.ts +61 -0
- package/src/providers/ide-provider-instance.d.ts +70 -0
- package/src/providers/provider-instance-manager.d.ts +84 -0
- package/src/providers/provider-instance.d.ts +7 -1
- package/src/providers/provider-loader.d.ts +299 -0
- package/src/providers/status-monitor.d.ts +48 -0
- package/src/providers/version-archive.d.ts +52 -0
- package/src/session-host/runtime-support.d.ts +8 -0
- package/src/sessions/reconcile.d.ts +22 -0
- package/src/sessions/registry.d.ts +24 -0
- package/src/shared-types-extra.d.ts +29 -0
- package/src/shared-types.d.ts +79 -22
- package/src/shared-types.ts +40 -0
- package/src/status/builders.d.ts +33 -0
- package/src/status/reporter.d.ts +69 -0
- package/src/status/reporter.ts +16 -13
- package/src/status/snapshot.d.ts +58 -0
- package/src/system/host-memory.d.ts +19 -0
- package/src/types.d.ts +3 -7
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DaemonCdpScanner — Periodic CDP port scanning & auto-connect
|
|
3
|
+
*
|
|
4
|
+
* Periodic CDP port scanning and auto-connect for IDE discovery.
|
|
5
|
+
* Provides a unified approach to:
|
|
6
|
+
* 1. Initial CDP port discovery
|
|
7
|
+
* 2. Periodic scanning for newly launched IDEs
|
|
8
|
+
* 3. Multi-window support (multiple pages on same port)
|
|
9
|
+
*/
|
|
10
|
+
import { DaemonCdpManager } from './manager.js';
|
|
11
|
+
import { type CdpSetupContext } from './setup.js';
|
|
12
|
+
export interface CdpScannerOptions {
|
|
13
|
+
/** Context for setup operations */
|
|
14
|
+
ctx: CdpSetupContext;
|
|
15
|
+
/** Log function for per-IDE CDP logs */
|
|
16
|
+
logFn?: (ideType: string) => (msg: string) => void;
|
|
17
|
+
/** Whether to support multi-window (multiple pages per port) */
|
|
18
|
+
multiWindow?: boolean;
|
|
19
|
+
/** Scan interval in ms (default: 30000) */
|
|
20
|
+
scanIntervalMs?: number;
|
|
21
|
+
/** Callback when a new CDP connection is established */
|
|
22
|
+
onConnected?: (ideType: string, managerKey: string, manager: DaemonCdpManager) => void;
|
|
23
|
+
}
|
|
24
|
+
export declare class DaemonCdpScanner {
|
|
25
|
+
private ctx;
|
|
26
|
+
private opts;
|
|
27
|
+
private scanTimer;
|
|
28
|
+
private discoveryTimer;
|
|
29
|
+
constructor(opts: CdpScannerOptions);
|
|
30
|
+
/**
|
|
31
|
+
* Initial CDP discovery — connect to all available IDEs.
|
|
32
|
+
* Supports both single-window and multi-window modes.
|
|
33
|
+
*/
|
|
34
|
+
initialScan(enabledIdes?: string[]): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Start periodic scanning for newly launched IDEs.
|
|
37
|
+
*/
|
|
38
|
+
startPeriodicScan(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Start periodic agent webview discovery on all connected CDPs.
|
|
41
|
+
*/
|
|
42
|
+
startWebviewDiscovery(intervalMs?: number): void;
|
|
43
|
+
/**
|
|
44
|
+
* Stop all timers.
|
|
45
|
+
*/
|
|
46
|
+
stop(): void;
|
|
47
|
+
private getLogFn;
|
|
48
|
+
/**
|
|
49
|
+
* Single-window connection (standalone mode).
|
|
50
|
+
* One CDP manager per IDE, first working port wins.
|
|
51
|
+
*/
|
|
52
|
+
private connectSingleWindow;
|
|
53
|
+
/**
|
|
54
|
+
* Multi-window connection.
|
|
55
|
+
* Multiple CDP managers per IDE — one per workbench page.
|
|
56
|
+
*/
|
|
57
|
+
private connectMultiWindow;
|
|
58
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DaemonCdpSetup — Shared CDP initialization helpers
|
|
3
|
+
*
|
|
4
|
+
* Common CDP setup logic for consistent
|
|
5
|
+
* CDP → ProviderInstance registration.
|
|
6
|
+
*/
|
|
7
|
+
import { DaemonCdpManager } from './manager.js';
|
|
8
|
+
import { ProviderLoader } from '../providers/provider-loader.js';
|
|
9
|
+
import { ProviderInstanceManager } from '../providers/provider-instance-manager.js';
|
|
10
|
+
import { IdeProviderInstance } from '../providers/ide-provider-instance.js';
|
|
11
|
+
import { SessionRegistry } from '../sessions/registry.js';
|
|
12
|
+
export interface CdpSetupContext {
|
|
13
|
+
providerLoader: ProviderLoader;
|
|
14
|
+
instanceManager: ProviderInstanceManager;
|
|
15
|
+
cdpManagers: Map<string, DaemonCdpManager>;
|
|
16
|
+
sessionRegistry: SessionRegistry;
|
|
17
|
+
/** Server connection (optional) */
|
|
18
|
+
serverConn?: any;
|
|
19
|
+
}
|
|
20
|
+
export interface SetupIdeInstanceOptions {
|
|
21
|
+
/** Provider-based IDE type (e.g., 'antigravity', 'cursor') */
|
|
22
|
+
ideType: string;
|
|
23
|
+
/** Connected CDP manager */
|
|
24
|
+
manager: DaemonCdpManager;
|
|
25
|
+
/** CDP manager key (for multi-window: 'antigravity_remote_vs', single: 'antigravity') */
|
|
26
|
+
managerKey?: string;
|
|
27
|
+
/** Provider settings override */
|
|
28
|
+
settings?: Record<string, any>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Register extension providers on a CDP manager.
|
|
32
|
+
* Common pattern used during CDP init and periodic scans.
|
|
33
|
+
*/
|
|
34
|
+
export declare function registerExtensionProviders(providerLoader: ProviderLoader, manager: DaemonCdpManager, ideType: string): void;
|
|
35
|
+
/**
|
|
36
|
+
* Setup a CDP-connected IDE as a ProviderInstance.
|
|
37
|
+
*
|
|
38
|
+
* Performs:
|
|
39
|
+
* 1. providerLoader.resolve() to get scripts
|
|
40
|
+
* 2. Create IdeProviderInstance
|
|
41
|
+
* 3. Register in InstanceManager
|
|
42
|
+
* 4. Register enabled extensions
|
|
43
|
+
* 5. Register runtime sessions (workspace + extension children)
|
|
44
|
+
*
|
|
45
|
+
* @returns The created IdeProviderInstance, or null if provider not found
|
|
46
|
+
*/
|
|
47
|
+
export declare function setupIdeInstance(ctx: CdpSetupContext, opts: SetupIdeInstanceOptions): Promise<IdeProviderInstance | null>;
|
|
48
|
+
/**
|
|
49
|
+
* Create and connect a DaemonCdpManager for a given port.
|
|
50
|
+
*
|
|
51
|
+
* @returns Connected manager or null if connection failed
|
|
52
|
+
*/
|
|
53
|
+
export declare function connectCdpManager(port: number, ideType: string, logFn: (msg: string) => void, providerLoader: ProviderLoader, targetId?: string): Promise<DaemonCdpManager | null>;
|
|
54
|
+
/**
|
|
55
|
+
* Probe a CDP port to check if it's listening.
|
|
56
|
+
* @returns true if CDP is available on this port
|
|
57
|
+
*/
|
|
58
|
+
export declare function probeCdpPort(port: number, timeoutMs?: number): Promise<boolean>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CliAdapter — common interface for CLI agents
|
|
3
|
+
*
|
|
4
|
+
* Contract implemented by all CLI adapters (ProviderCliAdapter etc).
|
|
5
|
+
*/
|
|
6
|
+
import type { ChatMessage } from './types.js';
|
|
7
|
+
export interface CliAdapterStatus {
|
|
8
|
+
status?: string;
|
|
9
|
+
messages?: ChatMessage[];
|
|
10
|
+
activeModal?: {
|
|
11
|
+
message: string;
|
|
12
|
+
buttons: string[];
|
|
13
|
+
} | null;
|
|
14
|
+
}
|
|
15
|
+
export interface AcpAdapterHandle {
|
|
16
|
+
onEvent(event: string, data?: unknown): void;
|
|
17
|
+
getState(): {
|
|
18
|
+
status: string;
|
|
19
|
+
activeChat?: {
|
|
20
|
+
messages?: ChatMessage[];
|
|
21
|
+
activeModal?: {
|
|
22
|
+
message: string;
|
|
23
|
+
buttons: string[];
|
|
24
|
+
} | null;
|
|
25
|
+
} | null;
|
|
26
|
+
};
|
|
27
|
+
setMode?(mode: string): Promise<void>;
|
|
28
|
+
setConfigOption?(configId: string, value: string): Promise<void>;
|
|
29
|
+
resolvePermission?(approved: boolean): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
export interface CliAdapter {
|
|
32
|
+
cliType: string;
|
|
33
|
+
cliName: string;
|
|
34
|
+
workingDir: string;
|
|
35
|
+
_acpInstance?: AcpAdapterHandle;
|
|
36
|
+
spawn(): Promise<void>;
|
|
37
|
+
sendMessage(text: string): Promise<void>;
|
|
38
|
+
getStatus(): CliAdapterStatus;
|
|
39
|
+
getScriptParsedStatus?(): unknown;
|
|
40
|
+
invokeScript?(scriptName: string, args?: Record<string, unknown>): Promise<unknown>;
|
|
41
|
+
getPartialResponse(): string;
|
|
42
|
+
saveAndStop?(): Promise<void>;
|
|
43
|
+
shutdown(): void;
|
|
44
|
+
detach?(): void;
|
|
45
|
+
cancel(): void;
|
|
46
|
+
isProcessing(): boolean;
|
|
47
|
+
isReady(): boolean;
|
|
48
|
+
setOnStatusChange(callback: () => void): void;
|
|
49
|
+
updateRuntimeSettings?(settings: Record<string, unknown>): void;
|
|
50
|
+
setServerConn?(serverConn: unknown): void;
|
|
51
|
+
clearHistory?(): void;
|
|
52
|
+
resolveAction?(data: unknown): Promise<void>;
|
|
53
|
+
resolveModal?(buttonIndex: number): void;
|
|
54
|
+
setOnPtyData?(callback: (data: string) => void): void;
|
|
55
|
+
writeRaw?(data: string): void;
|
|
56
|
+
resize?(cols: number, rows: number): void;
|
|
57
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProviderCliAdapter — Script-based CLI Adapter
|
|
3
|
+
*
|
|
4
|
+
* All CLI providers use versioned scripts (like IDE providers).
|
|
5
|
+
* Scripts are Node.js functions that receive PTY buffer data and return structured results.
|
|
6
|
+
*
|
|
7
|
+
* Required scripts in scripts/{version}/scripts.js:
|
|
8
|
+
* - detectStatus(input) → AgentStatus string ('idle' | 'generating' | 'waiting_approval')
|
|
9
|
+
* - parseOutput(input) → ReadChatResult { messages, status, activeModal, ... }
|
|
10
|
+
* - parseApproval(input) → ModalInfo | null
|
|
11
|
+
*
|
|
12
|
+
* provider.json contract:
|
|
13
|
+
* type, name, category: 'cli', binary, spawn, approvalKeys
|
|
14
|
+
* compatibility: [{ ideVersion, scriptDir }] ← versioned scripts
|
|
15
|
+
*/
|
|
16
|
+
import type { CliAdapter } from '../cli-adapter-types.js';
|
|
17
|
+
import { type PtyRuntimeMetadata, type PtyTransportFactory } from './pty-transport.js';
|
|
18
|
+
import { type CliChatMessage, type CliProviderModule, type CliScripts, type CliSessionStatus } from './provider-cli-shared.js';
|
|
19
|
+
import { type ProviderResolutionMeta } from './provider-cli-config.js';
|
|
20
|
+
export { normalizeCliProviderForRuntime, type CliApprovalInput, type CliChatMessage, type CliProviderModule, type CliScreenLine, type CliScreenSnapshot, type CliScriptInput, type CliScripts, type CliSessionStatus, type CliStatusInput, type CliTraceEntry, } from './provider-cli-shared.js';
|
|
21
|
+
type SeedCliChatMessage = Omit<Partial<CliChatMessage>, 'role'> & {
|
|
22
|
+
role?: string;
|
|
23
|
+
content?: string;
|
|
24
|
+
};
|
|
25
|
+
export declare class ProviderCliAdapter implements CliAdapter {
|
|
26
|
+
private extraArgs;
|
|
27
|
+
readonly cliType: string;
|
|
28
|
+
readonly cliName: string;
|
|
29
|
+
workingDir: string;
|
|
30
|
+
private provider;
|
|
31
|
+
private ptyProcess;
|
|
32
|
+
private transportFactory;
|
|
33
|
+
private messages;
|
|
34
|
+
private committedMessages;
|
|
35
|
+
private structuredMessages;
|
|
36
|
+
private currentStatus;
|
|
37
|
+
private onStatusChange;
|
|
38
|
+
private responseBuffer;
|
|
39
|
+
private recentOutputBuffer;
|
|
40
|
+
private isWaitingForResponse;
|
|
41
|
+
private activeModal;
|
|
42
|
+
private responseTimeout;
|
|
43
|
+
private idleTimeout;
|
|
44
|
+
private ready;
|
|
45
|
+
private startupBuffer;
|
|
46
|
+
private startupParseGate;
|
|
47
|
+
private startupSettleTimer;
|
|
48
|
+
private spawnAt;
|
|
49
|
+
private startupFirstOutputAt;
|
|
50
|
+
private onPtyDataCallback;
|
|
51
|
+
private pendingOutputParseBuffer;
|
|
52
|
+
private pendingOutputParseTimer;
|
|
53
|
+
private ptyOutputBuffer;
|
|
54
|
+
private ptyOutputFlushTimer;
|
|
55
|
+
private pendingTerminalQueryTail;
|
|
56
|
+
private lastOutputAt;
|
|
57
|
+
private lastNonEmptyOutputAt;
|
|
58
|
+
private lastScreenChangeAt;
|
|
59
|
+
private lastScreenSnapshot;
|
|
60
|
+
private serverConn;
|
|
61
|
+
private logBuffer;
|
|
62
|
+
private lastApprovalResolvedAt;
|
|
63
|
+
private approvalTransitionBuffer;
|
|
64
|
+
private approvalExitTimeout;
|
|
65
|
+
private pendingScriptStatus;
|
|
66
|
+
private pendingScriptStatusSince;
|
|
67
|
+
private pendingScriptStatusTimer;
|
|
68
|
+
private settleTimer;
|
|
69
|
+
private settledBuffer;
|
|
70
|
+
private submitPendingUntil;
|
|
71
|
+
private responseSettleIgnoreUntil;
|
|
72
|
+
private responseEpoch;
|
|
73
|
+
private submitRetryTimer;
|
|
74
|
+
private submitRetryUsed;
|
|
75
|
+
private submitRetryPromptSnippet;
|
|
76
|
+
private idleFinishCandidate;
|
|
77
|
+
private finishRetryTimer;
|
|
78
|
+
private finishRetryCount;
|
|
79
|
+
private resizeSuppressUntil;
|
|
80
|
+
private statusHistory;
|
|
81
|
+
private cliScripts;
|
|
82
|
+
private runtimeSettings;
|
|
83
|
+
/** Full accumulated ANSI-stripped PTY output */
|
|
84
|
+
private accumulatedBuffer;
|
|
85
|
+
/** Full accumulated raw PTY output (with ANSI) */
|
|
86
|
+
private accumulatedRawBuffer;
|
|
87
|
+
/** Current visible terminal screen snapshot */
|
|
88
|
+
private terminalScreen;
|
|
89
|
+
/** Max accumulated buffer size (last 50KB) */
|
|
90
|
+
private static readonly MAX_ACCUMULATED_BUFFER;
|
|
91
|
+
private currentTurnScope;
|
|
92
|
+
private traceEntries;
|
|
93
|
+
private traceSeq;
|
|
94
|
+
private traceSessionId;
|
|
95
|
+
private static readonly MAX_TRACE_ENTRIES;
|
|
96
|
+
private readonly providerResolutionMeta;
|
|
97
|
+
private static readonly IDLE_FINISH_CONFIRM_MS;
|
|
98
|
+
private static readonly STATUS_ACTIVITY_HOLD_MS;
|
|
99
|
+
private static readonly FINISH_RETRY_DELAY_MS;
|
|
100
|
+
private static readonly MAX_FINISH_RETRIES;
|
|
101
|
+
private syncMessageViews;
|
|
102
|
+
private setStatus;
|
|
103
|
+
private clearIdleFinishCandidate;
|
|
104
|
+
private armIdleFinishCandidate;
|
|
105
|
+
private recordTrace;
|
|
106
|
+
private resetTraceSession;
|
|
107
|
+
private readonly timeouts;
|
|
108
|
+
private readonly approvalKeys;
|
|
109
|
+
private readonly sendDelayMs;
|
|
110
|
+
private readonly sendKey;
|
|
111
|
+
private readonly submitStrategy;
|
|
112
|
+
private static readonly SCRIPT_STATUS_DEBOUNCE_MS;
|
|
113
|
+
constructor(provider: CliProviderModule, workingDir: string, extraArgs?: string[], transportFactory?: PtyTransportFactory);
|
|
114
|
+
/** Inject CLI scripts after construction (e.g. when resolved by ProviderLoader) */
|
|
115
|
+
setCliScripts(scripts: CliScripts): void;
|
|
116
|
+
updateRuntimeSettings(settings: Record<string, any>): void;
|
|
117
|
+
setServerConn(serverConn: any): void;
|
|
118
|
+
setOnStatusChange(callback: () => void): void;
|
|
119
|
+
setOnPtyData(callback: (data: string) => void): void;
|
|
120
|
+
private flushPendingOutputParse;
|
|
121
|
+
spawn(): Promise<void>;
|
|
122
|
+
private handleOutput;
|
|
123
|
+
private resolveStartupState;
|
|
124
|
+
private scheduleStartupSettleCheck;
|
|
125
|
+
private scheduleSettle;
|
|
126
|
+
private armApprovalExitTimeout;
|
|
127
|
+
private looksLikeVisibleIdlePrompt;
|
|
128
|
+
private findLastMatchingLineIndex;
|
|
129
|
+
private looksLikeClaudeGeneratingLine;
|
|
130
|
+
private detectClaudeGeneratingOverride;
|
|
131
|
+
private refineDetectedStatus;
|
|
132
|
+
private looksLikeVisibleAssistantCandidate;
|
|
133
|
+
private shouldRetryFinishResponse;
|
|
134
|
+
private hasRecentInteractiveActivity;
|
|
135
|
+
private getStartupConfirmationModal;
|
|
136
|
+
private shouldResolveModalWithEnter;
|
|
137
|
+
private waitForInteractivePrompt;
|
|
138
|
+
private evaluateSettled;
|
|
139
|
+
private finishResponse;
|
|
140
|
+
private commitCurrentTranscript;
|
|
141
|
+
private runDetectStatus;
|
|
142
|
+
private runParseApproval;
|
|
143
|
+
getStatus(): CliSessionStatus;
|
|
144
|
+
seedCommittedMessages(messages: SeedCliChatMessage[]): void;
|
|
145
|
+
/**
|
|
146
|
+
* Script-based full parse — returns ReadChatResult.
|
|
147
|
+
* Called by command handler / dashboard for rich content rendering.
|
|
148
|
+
*/
|
|
149
|
+
getScriptParsedStatus(): any;
|
|
150
|
+
invokeScript(scriptName: string, args?: Record<string, any>): Promise<any>;
|
|
151
|
+
private parseCurrentTranscript;
|
|
152
|
+
/** Whether this adapter has CLI scripts loaded */
|
|
153
|
+
hasCliScripts(): boolean;
|
|
154
|
+
/**
|
|
155
|
+
* Resolves an action (like 'fix' lint error) from the dashboard.
|
|
156
|
+
* Uses resolveAction script if available, otherwise falls back to standard text.
|
|
157
|
+
*/
|
|
158
|
+
resolveAction(data: any): Promise<void>;
|
|
159
|
+
sendMessage(text: string): Promise<void>;
|
|
160
|
+
getPartialResponse(): string;
|
|
161
|
+
getRuntimeMetadata(): PtyRuntimeMetadata | null;
|
|
162
|
+
updateRuntimeMeta(meta: Record<string, unknown>, replace?: boolean): void;
|
|
163
|
+
cancel(): void;
|
|
164
|
+
saveAndStop(): Promise<void>;
|
|
165
|
+
private waitForStopped;
|
|
166
|
+
shutdown(): void;
|
|
167
|
+
detach(): void;
|
|
168
|
+
clearHistory(): void;
|
|
169
|
+
isProcessing(): boolean;
|
|
170
|
+
isReady(): boolean;
|
|
171
|
+
writeRaw(data: string): void;
|
|
172
|
+
resolveModal(buttonIndex: number): void;
|
|
173
|
+
resize(cols: number, rows: number): void;
|
|
174
|
+
getDebugState(): Record<string, any>;
|
|
175
|
+
getTraceState(limit?: number): Record<string, any>;
|
|
176
|
+
getProviderResolutionMeta(): ProviderResolutionMeta;
|
|
177
|
+
}
|
|
@@ -1428,8 +1428,6 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1428
1428
|
throw new Error(`${this.cliName} is awaiting confirmation before it can accept a prompt`);
|
|
1429
1429
|
}
|
|
1430
1430
|
|
|
1431
|
-
this.committedMessages.push({ role: 'user', content: text, timestamp: Date.now() });
|
|
1432
|
-
this.syncMessageViews();
|
|
1433
1431
|
this.isWaitingForResponse = true;
|
|
1434
1432
|
this.responseBuffer = '';
|
|
1435
1433
|
this.finishRetryCount = 0;
|
|
@@ -1458,6 +1456,13 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1458
1456
|
const submitDelayMs = this.sendDelayMs + Math.min(2000, Math.max(0, estimatedLines - 1) * 350);
|
|
1459
1457
|
const maxEchoWaitMs = submitDelayMs + Math.max(1500, Math.min(5000, estimatedLines * 500));
|
|
1460
1458
|
const retryDelayMs = Math.max(350, Math.min(1500, Math.max(this.sendDelayMs, submitDelayMs)));
|
|
1459
|
+
let didCommitUserTurn = false;
|
|
1460
|
+
const commitUserTurn = () => {
|
|
1461
|
+
if (didCommitUserTurn) return;
|
|
1462
|
+
didCommitUserTurn = true;
|
|
1463
|
+
this.committedMessages.push({ role: 'user', content: text, timestamp: Date.now() });
|
|
1464
|
+
this.syncMessageViews();
|
|
1465
|
+
};
|
|
1461
1466
|
if (this.settleTimer) {
|
|
1462
1467
|
clearTimeout(this.settleTimer);
|
|
1463
1468
|
this.settleTimer = null;
|
|
@@ -1470,115 +1475,134 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1470
1475
|
if (this.isWaitingForResponse) this.finishResponse();
|
|
1471
1476
|
}, this.timeouts.maxResponse);
|
|
1472
1477
|
};
|
|
1478
|
+
await new Promise<void>((resolve) => {
|
|
1479
|
+
let resolved = false;
|
|
1480
|
+
const resolveOnce = () => {
|
|
1481
|
+
if (resolved) return;
|
|
1482
|
+
resolved = true;
|
|
1483
|
+
resolve();
|
|
1484
|
+
};
|
|
1473
1485
|
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
});
|
|
1482
|
-
this.ptyProcess.write(this.sendKey);
|
|
1483
|
-
const retrySubmitIfStuck = (attempt: number) => {
|
|
1484
|
-
this.submitRetryTimer = null;
|
|
1485
|
-
if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
|
|
1486
|
-
if (this.currentStatus === 'waiting_approval') return;
|
|
1487
|
-
if ((this.responseBuffer || '').trim()) return;
|
|
1486
|
+
const submit = () => {
|
|
1487
|
+
if (!this.ptyProcess) {
|
|
1488
|
+
resolveOnce();
|
|
1489
|
+
return;
|
|
1490
|
+
}
|
|
1491
|
+
commitUserTurn();
|
|
1492
|
+
this.submitPendingUntil = 0;
|
|
1488
1493
|
const screenText = this.terminalScreen.getText();
|
|
1489
|
-
if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
|
|
1490
|
-
if (/Esc to interrupt|Do you want to proceed|This command requires approval|Allow Codex to|Approve and run now|Always approve this session|Running…|Running\.\.\./i.test(screenText)) return;
|
|
1491
|
-
this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
|
|
1492
|
-
LOG.info('CLI', `[${this.cliType}] Retrying submit key for stuck prompt (attempt ${attempt})`);
|
|
1493
1494
|
this.recordTrace('submit_write', {
|
|
1494
|
-
mode: '
|
|
1495
|
-
attempt,
|
|
1495
|
+
mode: 'submit_key',
|
|
1496
1496
|
sendKey: this.sendKey,
|
|
1497
1497
|
screenText: summarizeCliTraceText(screenText, 500),
|
|
1498
1498
|
});
|
|
1499
|
-
this.ptyProcess
|
|
1500
|
-
|
|
1501
|
-
this.
|
|
1502
|
-
return;
|
|
1503
|
-
|
|
1504
|
-
|
|
1499
|
+
this.ptyProcess!.write(this.sendKey);
|
|
1500
|
+
const retrySubmitIfStuck = (attempt: number) => {
|
|
1501
|
+
this.submitRetryTimer = null;
|
|
1502
|
+
if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
|
|
1503
|
+
if (this.currentStatus === 'waiting_approval') return;
|
|
1504
|
+
if ((this.responseBuffer || '').trim()) return;
|
|
1505
|
+
const screenText = this.terminalScreen.getText();
|
|
1506
|
+
if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
|
|
1507
|
+
if (/Esc to interrupt|Do you want to proceed|This command requires approval|Allow Codex to|Approve and run now|Always approve this session|Running…|Running\.\.\./i.test(screenText)) return;
|
|
1508
|
+
this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
|
|
1509
|
+
LOG.info('CLI', `[${this.cliType}] Retrying submit key for stuck prompt (attempt ${attempt})`);
|
|
1510
|
+
this.recordTrace('submit_write', {
|
|
1511
|
+
mode: 'submit_retry',
|
|
1512
|
+
attempt,
|
|
1513
|
+
sendKey: this.sendKey,
|
|
1514
|
+
screenText: summarizeCliTraceText(screenText, 500),
|
|
1515
|
+
});
|
|
1516
|
+
this.ptyProcess.write(this.sendKey);
|
|
1517
|
+
if (attempt >= 3) {
|
|
1518
|
+
this.submitRetryUsed = true;
|
|
1519
|
+
return;
|
|
1520
|
+
}
|
|
1521
|
+
this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(attempt + 1), retryDelayMs);
|
|
1522
|
+
};
|
|
1523
|
+
this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(1), retryDelayMs);
|
|
1524
|
+
startResponseTimeout();
|
|
1525
|
+
resolveOnce();
|
|
1505
1526
|
};
|
|
1506
|
-
this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(1), retryDelayMs);
|
|
1507
|
-
startResponseTimeout();
|
|
1508
|
-
};
|
|
1509
1527
|
|
|
1510
|
-
|
|
1511
|
-
|
|
1528
|
+
if (this.submitStrategy === 'immediate') {
|
|
1529
|
+
commitUserTurn();
|
|
1530
|
+
this.submitPendingUntil = 0;
|
|
1531
|
+
this.recordTrace('submit_write', {
|
|
1532
|
+
mode: 'immediate',
|
|
1533
|
+
text: summarizeCliTraceText(text, 500),
|
|
1534
|
+
sendKey: this.sendKey,
|
|
1535
|
+
screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500),
|
|
1536
|
+
});
|
|
1537
|
+
this.ptyProcess!.write(text + this.sendKey);
|
|
1538
|
+
this.submitRetryTimer = setTimeout(() => {
|
|
1539
|
+
this.submitRetryTimer = null;
|
|
1540
|
+
if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
|
|
1541
|
+
if (this.currentStatus === 'waiting_approval') return;
|
|
1542
|
+
if ((this.responseBuffer || '').trim()) return;
|
|
1543
|
+
const screenText = this.terminalScreen.getText();
|
|
1544
|
+
if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
|
|
1545
|
+
LOG.info('CLI', `[${this.cliType}] Retrying submit key for stuck prompt (attempt 1)`);
|
|
1546
|
+
this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
|
|
1547
|
+
this.recordTrace('submit_write', {
|
|
1548
|
+
mode: 'immediate_retry',
|
|
1549
|
+
attempt: 1,
|
|
1550
|
+
sendKey: this.sendKey,
|
|
1551
|
+
screenText: summarizeCliTraceText(screenText, 500),
|
|
1552
|
+
});
|
|
1553
|
+
this.ptyProcess.write(this.sendKey);
|
|
1554
|
+
this.submitRetryUsed = true;
|
|
1555
|
+
}, retryDelayMs);
|
|
1556
|
+
startResponseTimeout();
|
|
1557
|
+
resolveOnce();
|
|
1558
|
+
return;
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
if (submitDelayMs > 0) {
|
|
1562
|
+
this.submitPendingUntil = Date.now() + submitDelayMs;
|
|
1563
|
+
}
|
|
1564
|
+
this.ptyProcess!.write(text);
|
|
1512
1565
|
this.recordTrace('submit_write', {
|
|
1513
|
-
mode: '
|
|
1566
|
+
mode: 'type_then_submit',
|
|
1514
1567
|
text: summarizeCliTraceText(text, 500),
|
|
1515
1568
|
sendKey: this.sendKey,
|
|
1516
1569
|
screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500),
|
|
1517
1570
|
});
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
if (this.
|
|
1523
|
-
|
|
1571
|
+
const submitStartedAt = Date.now();
|
|
1572
|
+
let lastNormalizedScreen = '';
|
|
1573
|
+
let lastScreenChangeAt = submitStartedAt;
|
|
1574
|
+
const waitForEchoAndSubmit = () => {
|
|
1575
|
+
if (!this.ptyProcess) {
|
|
1576
|
+
resolveOnce();
|
|
1577
|
+
return;
|
|
1578
|
+
}
|
|
1579
|
+
const now = Date.now();
|
|
1580
|
+
const elapsed = now - submitStartedAt;
|
|
1524
1581
|
const screenText = this.terminalScreen.getText();
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
sendKey: this.sendKey,
|
|
1532
|
-
screenText: summarizeCliTraceText(screenText, 500),
|
|
1533
|
-
});
|
|
1534
|
-
this.ptyProcess.write(this.sendKey);
|
|
1535
|
-
this.submitRetryUsed = true;
|
|
1536
|
-
}, retryDelayMs);
|
|
1537
|
-
startResponseTimeout();
|
|
1538
|
-
return;
|
|
1539
|
-
}
|
|
1582
|
+
const normalizedScreen = normalizePromptText(screenText);
|
|
1583
|
+
if (normalizedScreen !== lastNormalizedScreen) {
|
|
1584
|
+
lastNormalizedScreen = normalizedScreen;
|
|
1585
|
+
lastScreenChangeAt = now;
|
|
1586
|
+
}
|
|
1587
|
+
const echoVisible = !normalizedPromptSnippet || promptLikelyVisible(screenText, normalizedPromptSnippet);
|
|
1540
1588
|
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
sendKey: this.sendKey,
|
|
1549
|
-
screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500),
|
|
1550
|
-
});
|
|
1551
|
-
const submitStartedAt = Date.now();
|
|
1552
|
-
let lastNormalizedScreen = '';
|
|
1553
|
-
let lastScreenChangeAt = submitStartedAt;
|
|
1554
|
-
const waitForEchoAndSubmit = () => {
|
|
1555
|
-
if (!this.ptyProcess) return;
|
|
1556
|
-
const now = Date.now();
|
|
1557
|
-
const elapsed = now - submitStartedAt;
|
|
1558
|
-
const screenText = this.terminalScreen.getText();
|
|
1559
|
-
const normalizedScreen = normalizePromptText(screenText);
|
|
1560
|
-
if (normalizedScreen !== lastNormalizedScreen) {
|
|
1561
|
-
lastNormalizedScreen = normalizedScreen;
|
|
1562
|
-
lastScreenChangeAt = now;
|
|
1563
|
-
}
|
|
1564
|
-
const echoVisible = !normalizedPromptSnippet || promptLikelyVisible(screenText, normalizedPromptSnippet);
|
|
1589
|
+
if (echoVisible) {
|
|
1590
|
+
const screenSettled = (now - lastScreenChangeAt) >= 500;
|
|
1591
|
+
if (elapsed >= submitDelayMs && screenSettled) {
|
|
1592
|
+
submit();
|
|
1593
|
+
return;
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1565
1596
|
|
|
1566
|
-
|
|
1567
|
-
const screenSettled = (now - lastScreenChangeAt) >= 500;
|
|
1568
|
-
if (elapsed >= submitDelayMs && screenSettled) {
|
|
1597
|
+
if (elapsed >= maxEchoWaitMs) {
|
|
1569
1598
|
submit();
|
|
1570
1599
|
return;
|
|
1571
1600
|
}
|
|
1572
|
-
}
|
|
1573
1601
|
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
setTimeout(waitForEchoAndSubmit, 50);
|
|
1580
|
-
};
|
|
1581
|
-
waitForEchoAndSubmit();
|
|
1602
|
+
setTimeout(waitForEchoAndSubmit, 50);
|
|
1603
|
+
};
|
|
1604
|
+
waitForEchoAndSubmit();
|
|
1605
|
+
});
|
|
1582
1606
|
}
|
|
1583
1607
|
|
|
1584
1608
|
getPartialResponse(): string {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { CliProviderModule } from './provider-cli-shared.js';
|
|
2
|
+
export interface ProviderResolutionMeta {
|
|
3
|
+
type: string;
|
|
4
|
+
name: string;
|
|
5
|
+
resolvedVersion: string | null;
|
|
6
|
+
resolvedOs: string | null;
|
|
7
|
+
providerDir: string | null;
|
|
8
|
+
scriptDir: string | null;
|
|
9
|
+
scriptsPath: string | null;
|
|
10
|
+
scriptsSource: string | null;
|
|
11
|
+
versionWarning: string | null;
|
|
12
|
+
}
|
|
13
|
+
export interface ResolvedCliAdapterConfig {
|
|
14
|
+
timeouts: {
|
|
15
|
+
ptyFlush: number;
|
|
16
|
+
dialogAccept: number;
|
|
17
|
+
approvalCooldown: number;
|
|
18
|
+
generatingIdle: number;
|
|
19
|
+
idleFinish: number;
|
|
20
|
+
maxResponse: number;
|
|
21
|
+
shutdownGrace: number;
|
|
22
|
+
outputSettle: number;
|
|
23
|
+
};
|
|
24
|
+
approvalKeys: Record<number, string>;
|
|
25
|
+
sendDelayMs: number;
|
|
26
|
+
sendKey: string;
|
|
27
|
+
submitStrategy: 'wait_for_echo' | 'immediate';
|
|
28
|
+
providerResolutionMeta: ProviderResolutionMeta;
|
|
29
|
+
}
|
|
30
|
+
export declare function resolveCliAdapterConfig(provider: CliProviderModule): ResolvedCliAdapterConfig;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type CliChatMessage, type CliScriptInput } from './provider-cli-shared.js';
|
|
2
|
+
export interface TurnParseScope {
|
|
3
|
+
prompt: string;
|
|
4
|
+
startedAt: number;
|
|
5
|
+
bufferStart: number;
|
|
6
|
+
rawBufferStart: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function hydrateCliParsedMessages(parsedMessages: any[], options: {
|
|
9
|
+
committedMessages: CliChatMessage[];
|
|
10
|
+
scope?: TurnParseScope | null;
|
|
11
|
+
lastOutputAt: number;
|
|
12
|
+
now?: number;
|
|
13
|
+
}): any[];
|
|
14
|
+
export declare function normalizeCliParsedMessages(parsedMessages: any[], options: {
|
|
15
|
+
committedMessages: CliChatMessage[];
|
|
16
|
+
scope?: TurnParseScope | null;
|
|
17
|
+
lastOutputAt: number;
|
|
18
|
+
now?: number;
|
|
19
|
+
}): CliChatMessage[];
|
|
20
|
+
export declare function buildCliParseInput(options: {
|
|
21
|
+
accumulatedBuffer: string;
|
|
22
|
+
accumulatedRawBuffer: string;
|
|
23
|
+
recentOutputBuffer: string;
|
|
24
|
+
terminalScreenText: string;
|
|
25
|
+
baseMessages: CliChatMessage[];
|
|
26
|
+
partialResponse: string;
|
|
27
|
+
scope?: TurnParseScope | null;
|
|
28
|
+
runtimeSettings: Record<string, any>;
|
|
29
|
+
}): CliScriptInput;
|
|
30
|
+
export declare function summarizeCliTraceText(text: string, max?: number): string;
|
|
31
|
+
export declare function summarizeCliTraceMessages(messages: CliChatMessage[], limit?: number): {
|
|
32
|
+
role: string;
|
|
33
|
+
content: string;
|
|
34
|
+
timestamp?: number;
|
|
35
|
+
}[];
|
|
36
|
+
export declare function buildCliTraceParseSnapshot(options: {
|
|
37
|
+
accumulatedBuffer: string;
|
|
38
|
+
accumulatedRawBuffer: string;
|
|
39
|
+
responseBuffer: string;
|
|
40
|
+
partialResponse?: string;
|
|
41
|
+
scope?: TurnParseScope | null;
|
|
42
|
+
}): Record<string, any>;
|