@adhdev/daemon-core 0.9.12 → 0.9.14
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/cli-adapters/provider-cli-adapter.d.ts +3 -1
- package/dist/cli-adapters/pty-transport.d.ts +1 -1
- package/dist/commands/stream-commands.d.ts +1 -1
- package/dist/index.js +86 -45
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +86 -45
- package/dist/index.mjs.map +1 -1
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/cli-adapters/provider-cli-adapter.d.ts +3 -1
- package/src/cli-adapters/provider-cli-adapter.ts +65 -37
- package/src/cli-adapters/pty-transport.d.ts +1 -1
- package/src/cli-adapters/pty-transport.ts +1 -1
- package/src/cli-adapters/session-host-transport.ts +8 -7
- package/src/commands/router.ts +7 -1
- package/src/commands/stream-commands.d.ts +1 -1
- package/src/commands/stream-commands.ts +3 -3
- package/src/daemon/dev-cli-debug.ts +1 -1
- package/src/providers/cli-provider-instance.ts +1 -1
package/package.json
CHANGED
|
@@ -156,6 +156,8 @@ export declare class ProviderCliAdapter implements CliAdapter {
|
|
|
156
156
|
* Uses resolveAction script if available, otherwise falls back to standard text.
|
|
157
157
|
*/
|
|
158
158
|
resolveAction(data: any): Promise<void>;
|
|
159
|
+
private writeToPty;
|
|
160
|
+
private resetPendingSendState;
|
|
159
161
|
sendMessage(text: string): Promise<void>;
|
|
160
162
|
getPartialResponse(): string;
|
|
161
163
|
getRuntimeMetadata(): PtyRuntimeMetadata | null;
|
|
@@ -168,7 +170,7 @@ export declare class ProviderCliAdapter implements CliAdapter {
|
|
|
168
170
|
clearHistory(): void;
|
|
169
171
|
isProcessing(): boolean;
|
|
170
172
|
isReady(): boolean;
|
|
171
|
-
writeRaw(data: string): void
|
|
173
|
+
writeRaw(data: string): Promise<void>;
|
|
172
174
|
resolveModal(buttonIndex: number): void;
|
|
173
175
|
resize(cols: number, rows: number): void;
|
|
174
176
|
getDebugState(): Record<string, any>;
|
|
@@ -1779,6 +1779,22 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1779
1779
|
await this.sendMessage(promptText);
|
|
1780
1780
|
}
|
|
1781
1781
|
|
|
1782
|
+
private async writeToPty(data: string): Promise<void> {
|
|
1783
|
+
if (!this.ptyProcess) throw new Error(`${this.cliName} is not running`);
|
|
1784
|
+
await this.ptyProcess.write(data);
|
|
1785
|
+
}
|
|
1786
|
+
|
|
1787
|
+
private resetPendingSendState(reason: string): void {
|
|
1788
|
+
this.isWaitingForResponse = false;
|
|
1789
|
+
this.responseBuffer = '';
|
|
1790
|
+
this.currentTurnScope = null;
|
|
1791
|
+
this.submitPendingUntil = 0;
|
|
1792
|
+
this.clearIdleFinishCandidate(reason);
|
|
1793
|
+
if (this.responseTimeout) { clearTimeout(this.responseTimeout); this.responseTimeout = null; }
|
|
1794
|
+
if (this.submitRetryTimer) { clearTimeout(this.submitRetryTimer); this.submitRetryTimer = null; }
|
|
1795
|
+
if (this.finishRetryTimer) { clearTimeout(this.finishRetryTimer); this.finishRetryTimer = null; }
|
|
1796
|
+
}
|
|
1797
|
+
|
|
1782
1798
|
async sendMessage(text: string): Promise<void> {
|
|
1783
1799
|
if (!this.ptyProcess) throw new Error(`${this.cliName} is not running`);
|
|
1784
1800
|
const allowInputDuringGeneration = this.provider.allowInputDuringGeneration === true;
|
|
@@ -1881,20 +1897,30 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1881
1897
|
if (this.isWaitingForResponse) this.finishResponse();
|
|
1882
1898
|
}, this.timeouts.maxResponse);
|
|
1883
1899
|
};
|
|
1884
|
-
await new Promise<void>((resolve) => {
|
|
1900
|
+
await new Promise<void>((resolve, reject) => {
|
|
1885
1901
|
let resolved = false;
|
|
1886
1902
|
const resolveOnce = () => {
|
|
1887
1903
|
if (resolved) return;
|
|
1888
1904
|
resolved = true;
|
|
1889
1905
|
resolve();
|
|
1890
1906
|
};
|
|
1907
|
+
const rejectOnce = (error: unknown) => {
|
|
1908
|
+
if (resolved) return;
|
|
1909
|
+
this.resetPendingSendState('send_write_failed');
|
|
1910
|
+
resolved = true;
|
|
1911
|
+
reject(error);
|
|
1912
|
+
};
|
|
1913
|
+
const writeRetryKey = (mode: string) => {
|
|
1914
|
+
void this.writeToPty(this.sendKey).catch((error) => {
|
|
1915
|
+
LOG.warn('CLI', `[${this.cliType}] ${mode} write failed: ${error?.message || error}`);
|
|
1916
|
+
});
|
|
1917
|
+
};
|
|
1891
1918
|
|
|
1892
1919
|
const submit = () => {
|
|
1893
1920
|
if (!this.ptyProcess) {
|
|
1894
1921
|
resolveOnce();
|
|
1895
1922
|
return;
|
|
1896
1923
|
}
|
|
1897
|
-
commitUserTurn();
|
|
1898
1924
|
this.submitPendingUntil = 0;
|
|
1899
1925
|
const screenText = this.terminalScreen.getText();
|
|
1900
1926
|
this.recordTrace('submit_write', {
|
|
@@ -1902,7 +1928,6 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1902
1928
|
sendKey: this.sendKey,
|
|
1903
1929
|
screenText: summarizeCliTraceText(screenText, 500),
|
|
1904
1930
|
});
|
|
1905
|
-
this.ptyProcess!.write(this.sendKey);
|
|
1906
1931
|
const retrySubmitIfStuck = (attempt: number) => {
|
|
1907
1932
|
this.submitRetryTimer = null;
|
|
1908
1933
|
if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
|
|
@@ -1922,20 +1947,22 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1922
1947
|
sendKey: this.sendKey,
|
|
1923
1948
|
screenText: summarizeCliTraceText(screenText, 500),
|
|
1924
1949
|
});
|
|
1925
|
-
|
|
1950
|
+
writeRetryKey('submit_retry');
|
|
1926
1951
|
if (attempt >= 3) {
|
|
1927
1952
|
this.submitRetryUsed = true;
|
|
1928
1953
|
return;
|
|
1929
1954
|
}
|
|
1930
1955
|
this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(attempt + 1), retryDelayMs);
|
|
1931
1956
|
};
|
|
1932
|
-
this.
|
|
1933
|
-
|
|
1934
|
-
|
|
1957
|
+
void this.writeToPty(this.sendKey).then(() => {
|
|
1958
|
+
commitUserTurn();
|
|
1959
|
+
this.submitRetryTimer = setTimeout(() => retrySubmitIfStuck(1), retryDelayMs);
|
|
1960
|
+
startResponseTimeout();
|
|
1961
|
+
resolveOnce();
|
|
1962
|
+
}, rejectOnce);
|
|
1935
1963
|
};
|
|
1936
1964
|
|
|
1937
1965
|
if (this.submitStrategy === 'immediate') {
|
|
1938
|
-
commitUserTurn();
|
|
1939
1966
|
this.submitPendingUntil = 0;
|
|
1940
1967
|
this.recordTrace('submit_write', {
|
|
1941
1968
|
mode: 'immediate',
|
|
@@ -1943,38 +1970,39 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1943
1970
|
sendKey: this.sendKey,
|
|
1944
1971
|
screenText: summarizeCliTraceText(this.terminalScreen.getText(), 500),
|
|
1945
1972
|
});
|
|
1946
|
-
this.
|
|
1947
|
-
|
|
1948
|
-
this.submitRetryTimer =
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1973
|
+
void this.writeToPty(text + this.sendKey).then(() => {
|
|
1974
|
+
commitUserTurn();
|
|
1975
|
+
this.submitRetryTimer = setTimeout(() => {
|
|
1976
|
+
this.submitRetryTimer = null;
|
|
1977
|
+
if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
|
|
1978
|
+
if (this.currentStatus === 'waiting_approval') return;
|
|
1979
|
+
if (this.hasMeaningfulResponseBuffer(normalizedPromptSnippet)) return;
|
|
1980
|
+
const screenText = this.terminalScreen.getText();
|
|
1981
|
+
if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
|
|
1982
|
+
const liveApproval = this.runParseApproval(screenText) || this.runParseApproval(this.recentOutputBuffer);
|
|
1983
|
+
if (liveApproval) return;
|
|
1984
|
+
const liveStatus = this.runDetectStatus(screenText) || this.runDetectStatus(this.recentOutputBuffer);
|
|
1985
|
+
if (liveStatus === 'generating' || liveStatus === 'waiting_approval') return;
|
|
1986
|
+
LOG.info('CLI', `[${this.cliType}] Retrying submit key for stuck prompt (attempt 1)`);
|
|
1987
|
+
this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
|
|
1988
|
+
this.recordTrace('submit_write', {
|
|
1989
|
+
mode: 'immediate_retry',
|
|
1990
|
+
attempt: 1,
|
|
1991
|
+
sendKey: this.sendKey,
|
|
1992
|
+
screenText: summarizeCliTraceText(screenText, 500),
|
|
1993
|
+
});
|
|
1994
|
+
writeRetryKey('immediate_retry');
|
|
1995
|
+
this.submitRetryUsed = true;
|
|
1996
|
+
}, retryDelayMs);
|
|
1997
|
+
startResponseTimeout();
|
|
1998
|
+
resolveOnce();
|
|
1999
|
+
}, rejectOnce);
|
|
1971
2000
|
return;
|
|
1972
2001
|
}
|
|
1973
2002
|
|
|
1974
2003
|
if (submitDelayMs > 0) {
|
|
1975
2004
|
this.submitPendingUntil = Date.now() + submitDelayMs;
|
|
1976
2005
|
}
|
|
1977
|
-
this.ptyProcess!.write(text);
|
|
1978
2006
|
this.recordTrace('submit_write', {
|
|
1979
2007
|
mode: 'type_then_submit',
|
|
1980
2008
|
text: summarizeCliTraceText(text, 500),
|
|
@@ -2014,7 +2042,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
2014
2042
|
|
|
2015
2043
|
setTimeout(waitForEchoAndSubmit, 50);
|
|
2016
2044
|
};
|
|
2017
|
-
waitForEchoAndSubmit();
|
|
2045
|
+
void this.writeToPty(text).then(() => waitForEchoAndSubmit(), rejectOnce);
|
|
2018
2046
|
});
|
|
2019
2047
|
}
|
|
2020
2048
|
|
|
@@ -2168,12 +2196,12 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
2168
2196
|
isProcessing(): boolean { return this.isWaitingForResponse; }
|
|
2169
2197
|
isReady(): boolean { return this.ready; }
|
|
2170
2198
|
|
|
2171
|
-
writeRaw(data: string): void {
|
|
2199
|
+
async writeRaw(data: string): Promise<void> {
|
|
2172
2200
|
this.recordTrace('write_raw', {
|
|
2173
2201
|
keys: JSON.stringify(data),
|
|
2174
2202
|
length: data.length,
|
|
2175
2203
|
});
|
|
2176
|
-
this.
|
|
2204
|
+
await this.writeToPty(data);
|
|
2177
2205
|
}
|
|
2178
2206
|
|
|
2179
2207
|
resolveModal(buttonIndex: number): void {
|
|
@@ -28,7 +28,7 @@ export interface PtyRuntimeTransport {
|
|
|
28
28
|
readonly pid: number;
|
|
29
29
|
readonly ready: Promise<void>;
|
|
30
30
|
readonly terminalQueriesHandled?: boolean;
|
|
31
|
-
write(data: string): void
|
|
31
|
+
write(data: string): void | Promise<void>;
|
|
32
32
|
resize(cols: number, rows: number): void;
|
|
33
33
|
kill(): void;
|
|
34
34
|
clearBuffer?(): void;
|
|
@@ -53,7 +53,7 @@ export interface PtyRuntimeTransport {
|
|
|
53
53
|
readonly pid: number;
|
|
54
54
|
readonly ready: Promise<void>;
|
|
55
55
|
readonly terminalQueriesHandled?: boolean;
|
|
56
|
-
write(data: string): void
|
|
56
|
+
write(data: string): void | Promise<void>;
|
|
57
57
|
resize(cols: number, rows: number): void;
|
|
58
58
|
kill(): void;
|
|
59
59
|
clearBuffer?(): void;
|
|
@@ -82,8 +82,8 @@ class SessionHostRuntimeTransport implements PtyRuntimeTransport {
|
|
|
82
82
|
this.exitCallbacks.add(callback);
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
write(data: string): void {
|
|
86
|
-
this.enqueue(async () => {
|
|
85
|
+
write(data: string): Promise<void> {
|
|
86
|
+
return this.enqueue(async () => {
|
|
87
87
|
let response = await this.client.request({
|
|
88
88
|
type: 'send_input',
|
|
89
89
|
payload: {
|
|
@@ -404,13 +404,14 @@ class SessionHostRuntimeTransport implements PtyRuntimeTransport {
|
|
|
404
404
|
};
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
-
private enqueue(action: () => Promise<void>): void {
|
|
408
|
-
|
|
407
|
+
private enqueue(action: () => Promise<void>): Promise<void> {
|
|
408
|
+
const operation = this.operationChain
|
|
409
409
|
.then(() => this.ready)
|
|
410
410
|
.then(action)
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
411
|
+
this.operationChain = operation.catch((error) => {
|
|
412
|
+
LOG.warn('CLI', `[session-host:${this.options.runtimeId}] ${error?.message || error}`);
|
|
413
|
+
});
|
|
414
|
+
return operation;
|
|
414
415
|
}
|
|
415
416
|
|
|
416
417
|
private async closeClient(destroy = false): Promise<void> {
|
package/src/commands/router.ts
CHANGED
|
@@ -818,10 +818,16 @@ export class DaemonCommandRouter {
|
|
|
818
818
|
// ignore ls failures; upgrade can still proceed
|
|
819
819
|
}
|
|
820
820
|
|
|
821
|
-
|
|
821
|
+
const runningVersion = typeof this.deps.statusVersion === 'string'
|
|
822
|
+
? this.deps.statusVersion.trim().replace(/^v/, '')
|
|
823
|
+
: null;
|
|
824
|
+
if (currentInstalled === latest && runningVersion === latest) {
|
|
822
825
|
LOG.info('Upgrade', `Already on latest version v${latest}; skipping install`);
|
|
823
826
|
return { success: true, upgraded: false, alreadyLatest: true, version: latest };
|
|
824
827
|
}
|
|
828
|
+
if (currentInstalled === latest && runningVersion && runningVersion !== latest) {
|
|
829
|
+
LOG.info('Upgrade', `Installed package is v${latest}, but running daemon is v${runningVersion}; scheduling restart`);
|
|
830
|
+
}
|
|
825
831
|
|
|
826
832
|
spawnDetachedDaemonUpgradeHelper({
|
|
827
833
|
packageName: pkgName,
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import type { CommandResult, CommandHelpers } from './handler.js';
|
|
6
6
|
export declare function handleSelectSession(h: CommandHelpers, args: any): Promise<CommandResult>;
|
|
7
7
|
export declare function handleOpenPanel(h: CommandHelpers, args: any): Promise<CommandResult>;
|
|
8
|
-
export declare function handlePtyInput(h: CommandHelpers, args: any): CommandResult
|
|
8
|
+
export declare function handlePtyInput(h: CommandHelpers, args: any): Promise<CommandResult>;
|
|
9
9
|
export declare function handlePtyResize(h: CommandHelpers, args: any): CommandResult;
|
|
10
10
|
export declare function handleGetProviderSettings(h: CommandHelpers, args: any): CommandResult;
|
|
11
11
|
export declare function handleSetProviderSetting(h: CommandHelpers, args: any): Promise<CommandResult>;
|
|
@@ -110,14 +110,14 @@ export async function handleOpenPanel(h: CommandHelpers, args: any): Promise<Com
|
|
|
110
110
|
|
|
111
111
|
// ─── PTY Raw I/O ──────────────────────────────────
|
|
112
112
|
|
|
113
|
-
export function handlePtyInput(h: CommandHelpers, args: any): CommandResult {
|
|
113
|
+
export async function handlePtyInput(h: CommandHelpers, args: any): Promise<CommandResult> {
|
|
114
114
|
const { cliType, data, targetSessionId } = args || {};
|
|
115
115
|
if (!data) return { success: false, error: 'data required' };
|
|
116
116
|
const adapter = h.getCliAdapter(targetSessionId || cliType);
|
|
117
117
|
if (!adapter || typeof adapter.writeRaw !== 'function') {
|
|
118
118
|
return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || 'unknown'}` };
|
|
119
119
|
}
|
|
120
|
-
adapter.writeRaw(data);
|
|
120
|
+
await adapter.writeRaw(data);
|
|
121
121
|
return { success: true };
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -343,7 +343,7 @@ async function executeProviderScript(h: CommandHelpers, args: any, scriptName: s
|
|
|
343
343
|
if (cliCommand?.type === 'send_message' && cliCommand.text) {
|
|
344
344
|
await adapter.sendMessage(cliCommand.text);
|
|
345
345
|
} else if (cliCommand?.type === 'pty_write' && cliCommand.text && adapter.writeRaw) {
|
|
346
|
-
adapter.writeRaw(cliCommand.text + '\r');
|
|
346
|
+
await adapter.writeRaw(cliCommand.text + '\r');
|
|
347
347
|
}
|
|
348
348
|
applyProviderPatch(h, args, parsed.payload);
|
|
349
349
|
return {
|
|
@@ -1195,7 +1195,7 @@ export async function handleCliRaw(ctx: DevServerContext, req: http.IncomingMess
|
|
|
1195
1195
|
|
|
1196
1196
|
try {
|
|
1197
1197
|
if (typeof adapter.writeRaw === 'function') {
|
|
1198
|
-
adapter.writeRaw(keys);
|
|
1198
|
+
await adapter.writeRaw(keys);
|
|
1199
1199
|
ctx.json(res, 200, { sent: true, type: target.type, instanceId: target.instanceId, keysLength: keys.length });
|
|
1200
1200
|
} else {
|
|
1201
1201
|
ctx.json(res, 400, { error: 'writeRaw not available on this adapter' });
|
|
@@ -526,7 +526,7 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
526
526
|
if (cliCommand?.type === 'send_message' && cliCommand.text) {
|
|
527
527
|
await this.adapter.sendMessage(cliCommand.text);
|
|
528
528
|
} else if (cliCommand?.type === 'pty_write' && cliCommand.text) {
|
|
529
|
-
this.adapter.writeRaw(cliCommand.text + '\r');
|
|
529
|
+
await this.adapter.writeRaw(cliCommand.text + '\r');
|
|
530
530
|
}
|
|
531
531
|
|
|
532
532
|
this.applyProviderResponse(parsed.payload, { phase: 'immediate' });
|