@adhdev/daemon-core 0.9.32 → 0.9.34
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/commands/upgrade-helper.d.ts +1 -0
- package/dist/index.js +200 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +200 -20
- package/dist/index.mjs.map +1 -1
- package/dist/providers/cli-provider-instance.d.ts +2 -1
- package/dist/providers/provider-instance-manager.d.ts +2 -1
- package/dist/providers/provider-instance.d.ts +17 -0
- package/dist/providers/provider-loader.d.ts +1 -0
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/cli-adapters/provider-cli-adapter.ts +46 -3
- package/src/cli-adapters/provider-cli-parse.ts +3 -2
- package/src/commands/chat-commands.ts +54 -0
- package/src/commands/upgrade-helper.ts +48 -16
- package/src/providers/cli-provider-instance.ts +25 -1
- package/src/providers/provider-instance-manager.ts +43 -1
- package/src/providers/provider-instance.ts +19 -0
- package/src/providers/provider-loader.ts +18 -2
|
@@ -27,5 +27,6 @@ export declare function buildPinnedGlobalInstallCommand(options: {
|
|
|
27
27
|
currentCliPath?: string;
|
|
28
28
|
nodeExecutable?: string;
|
|
29
29
|
}): PinnedGlobalInstallCommand;
|
|
30
|
+
export declare function stopSessionHostProcesses(appName: string): void;
|
|
30
31
|
export declare function spawnDetachedDaemonUpgradeHelper(payload: DaemonUpgradeHelperPayload): void;
|
|
31
32
|
export declare function maybeRunDaemonUpgradeHelperFromEnv(): Promise<boolean>;
|
package/dist/index.js
CHANGED
|
@@ -1690,13 +1690,14 @@ function sliceFromOffset(text, start) {
|
|
|
1690
1690
|
function hydrateCliParsedMessages(parsedMessages, options) {
|
|
1691
1691
|
const { committedMessages, scope, lastOutputAt } = options;
|
|
1692
1692
|
const referenceMessages = [...committedMessages];
|
|
1693
|
+
const referenceComparables = referenceMessages.map((message) => normalizeComparableMessageContent(message?.content || ""));
|
|
1693
1694
|
const usedReferenceIndexes = /* @__PURE__ */ new Set();
|
|
1694
1695
|
const now = options.now ?? Date.now();
|
|
1695
1696
|
const findReferenceTimestamp = (role, content, parsedIndex) => {
|
|
1696
1697
|
const normalizedContent = normalizeComparableMessageContent(content);
|
|
1697
1698
|
if (!normalizedContent) return void 0;
|
|
1698
1699
|
const sameIndex = referenceMessages[parsedIndex];
|
|
1699
|
-
if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role &&
|
|
1700
|
+
if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && referenceComparables[parsedIndex] === normalizedContent && typeof sameIndex.timestamp === "number" && Number.isFinite(sameIndex.timestamp)) {
|
|
1700
1701
|
usedReferenceIndexes.add(parsedIndex);
|
|
1701
1702
|
return sameIndex.timestamp;
|
|
1702
1703
|
}
|
|
@@ -1704,7 +1705,7 @@ function hydrateCliParsedMessages(parsedMessages, options) {
|
|
|
1704
1705
|
if (usedReferenceIndexes.has(i)) continue;
|
|
1705
1706
|
const candidate = referenceMessages[i];
|
|
1706
1707
|
if (!candidate || candidate.role !== role) continue;
|
|
1707
|
-
const candidateContent =
|
|
1708
|
+
const candidateContent = referenceComparables[i];
|
|
1708
1709
|
if (!candidateContent) continue;
|
|
1709
1710
|
const exactMatch = candidateContent === normalizedContent;
|
|
1710
1711
|
const fuzzyMatch = candidateContent.includes(normalizedContent) || normalizedContent.includes(candidateContent);
|
|
@@ -2796,7 +2797,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
2796
2797
|
return;
|
|
2797
2798
|
}
|
|
2798
2799
|
if (this.currentTurnScope && !lastParsedAssistant) {
|
|
2799
|
-
LOG.
|
|
2800
|
+
LOG.debug(
|
|
2800
2801
|
"CLI",
|
|
2801
2802
|
`[${this.cliType}] Settled without assistant: prompt=${JSON.stringify(this.currentTurnScope.prompt).slice(0, 140)} responseBuffer=${JSON.stringify(summarizeCliTraceText(this.responseBuffer, 220)).slice(0, 260)} screen=${JSON.stringify(summarizeCliTraceText(screenText, 220)).slice(0, 260)} providerDir=${this.providerResolutionMeta.providerDir || "-"} scriptDir=${this.providerResolutionMeta.scriptDir || "-"}`
|
|
2802
2803
|
);
|
|
@@ -3612,9 +3613,43 @@ var init_provider_cli_adapter = __esm({
|
|
|
3612
3613
|
}
|
|
3613
3614
|
armResponseTimeout() {
|
|
3614
3615
|
if (this.responseTimeout) clearTimeout(this.responseTimeout);
|
|
3616
|
+
const timeoutMs = this.timeouts.maxResponse;
|
|
3617
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
3618
|
+
this.responseTimeout = null;
|
|
3619
|
+
return;
|
|
3620
|
+
}
|
|
3615
3621
|
this.responseTimeout = setTimeout(() => {
|
|
3616
|
-
|
|
3617
|
-
|
|
3622
|
+
this.responseTimeout = null;
|
|
3623
|
+
if (!this.isWaitingForResponse) return;
|
|
3624
|
+
const detectedStatusBeforeEval = this.runDetectStatus(this.recentOutputBuffer);
|
|
3625
|
+
this.recordTrace("response_timeout_check", {
|
|
3626
|
+
timeoutMs,
|
|
3627
|
+
detectedStatus: detectedStatusBeforeEval,
|
|
3628
|
+
currentStatus: this.currentStatus,
|
|
3629
|
+
isWaitingForResponse: this.isWaitingForResponse,
|
|
3630
|
+
hasActionableApproval: this.hasActionableApproval(),
|
|
3631
|
+
...buildCliTraceParseSnapshot({
|
|
3632
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
3633
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
3634
|
+
responseBuffer: this.responseBuffer,
|
|
3635
|
+
partialResponse: this.responseBuffer,
|
|
3636
|
+
scope: this.currentTurnScope
|
|
3637
|
+
})
|
|
3638
|
+
});
|
|
3639
|
+
this.settledBuffer = this.recentOutputBuffer;
|
|
3640
|
+
this.evaluateSettled();
|
|
3641
|
+
if (this.isWaitingForResponse && !this.hasActionableApproval()) {
|
|
3642
|
+
const detectedStatusAfterEval = this.runDetectStatus(this.recentOutputBuffer);
|
|
3643
|
+
this.recordTrace("response_timeout_kept_open", {
|
|
3644
|
+
timeoutMs,
|
|
3645
|
+
detectedStatusBeforeEval,
|
|
3646
|
+
detectedStatusAfterEval,
|
|
3647
|
+
currentStatus: this.currentStatus,
|
|
3648
|
+
isWaitingForResponse: this.isWaitingForResponse
|
|
3649
|
+
});
|
|
3650
|
+
this.armResponseTimeout();
|
|
3651
|
+
}
|
|
3652
|
+
}, timeoutMs);
|
|
3618
3653
|
}
|
|
3619
3654
|
writeSubmitKeyForRetry(mode) {
|
|
3620
3655
|
void this.writeToPty(this.sendKey).catch((error) => {
|
|
@@ -10509,6 +10544,26 @@ function toHistoryPersistedMessages(messages) {
|
|
|
10509
10544
|
historyDedupKey: deriveHistoryDedupKey(message)
|
|
10510
10545
|
}));
|
|
10511
10546
|
}
|
|
10547
|
+
function findLastMessageIndexBySignature(messages, signature) {
|
|
10548
|
+
if (!signature) return -1;
|
|
10549
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
10550
|
+
if (getChatMessageSignature(messages[index]) === signature) {
|
|
10551
|
+
return index;
|
|
10552
|
+
}
|
|
10553
|
+
}
|
|
10554
|
+
return -1;
|
|
10555
|
+
}
|
|
10556
|
+
function buildBoundedTailSync(messages, cursor) {
|
|
10557
|
+
const totalMessages = messages.length;
|
|
10558
|
+
const tailMessages = cursor.tailLimit > 0 && totalMessages > cursor.tailLimit ? messages.slice(-cursor.tailLimit) : messages;
|
|
10559
|
+
return {
|
|
10560
|
+
syncMode: "full",
|
|
10561
|
+
replaceFrom: 0,
|
|
10562
|
+
messages: tailMessages,
|
|
10563
|
+
totalMessages,
|
|
10564
|
+
lastMessageSignature: getChatMessageSignature(messages[totalMessages - 1])
|
|
10565
|
+
};
|
|
10566
|
+
}
|
|
10512
10567
|
function computeReadChatSync(messages, cursor) {
|
|
10513
10568
|
const totalMessages = messages.length;
|
|
10514
10569
|
const lastMessageSignature = getChatMessageSignature(messages[totalMessages - 1]);
|
|
@@ -10540,6 +10595,15 @@ function computeReadChatSync(messages, cursor) {
|
|
|
10540
10595
|
lastMessageSignature
|
|
10541
10596
|
};
|
|
10542
10597
|
}
|
|
10598
|
+
if (cursor.tailLimit > 0 && knownSignature === lastMessageSignature) {
|
|
10599
|
+
return {
|
|
10600
|
+
syncMode: "noop",
|
|
10601
|
+
replaceFrom: totalMessages,
|
|
10602
|
+
messages: [],
|
|
10603
|
+
totalMessages,
|
|
10604
|
+
lastMessageSignature
|
|
10605
|
+
};
|
|
10606
|
+
}
|
|
10543
10607
|
if (knownMessageCount < totalMessages) {
|
|
10544
10608
|
const anchorSignature = getChatMessageSignature(messages[knownMessageCount - 1]);
|
|
10545
10609
|
if (anchorSignature === knownSignature) {
|
|
@@ -10551,6 +10615,19 @@ function computeReadChatSync(messages, cursor) {
|
|
|
10551
10615
|
lastMessageSignature
|
|
10552
10616
|
};
|
|
10553
10617
|
}
|
|
10618
|
+
if (cursor.tailLimit > 0) {
|
|
10619
|
+
const signatureIndex = findLastMessageIndexBySignature(messages, knownSignature);
|
|
10620
|
+
if (signatureIndex >= 0) {
|
|
10621
|
+
return {
|
|
10622
|
+
syncMode: "append",
|
|
10623
|
+
replaceFrom: knownMessageCount,
|
|
10624
|
+
messages: messages.slice(signatureIndex + 1),
|
|
10625
|
+
totalMessages,
|
|
10626
|
+
lastMessageSignature
|
|
10627
|
+
};
|
|
10628
|
+
}
|
|
10629
|
+
return buildBoundedTailSync(messages, cursor);
|
|
10630
|
+
}
|
|
10554
10631
|
}
|
|
10555
10632
|
const replaceFrom = Math.max(0, Math.min(knownMessageCount - 1, totalMessages));
|
|
10556
10633
|
return {
|
|
@@ -13361,6 +13438,20 @@ var CliProviderInstance = class {
|
|
|
13361
13438
|
getPresentationMode() {
|
|
13362
13439
|
return this.presentationMode;
|
|
13363
13440
|
}
|
|
13441
|
+
getHotChatSessionState() {
|
|
13442
|
+
const adapterStatus = this.adapter.getStatus();
|
|
13443
|
+
const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
|
|
13444
|
+
const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
|
|
13445
|
+
const runtime = this.adapter.getRuntimeMetadata();
|
|
13446
|
+
return {
|
|
13447
|
+
id: this.instanceId,
|
|
13448
|
+
status: visibleStatus,
|
|
13449
|
+
runtimeLifecycle: runtime?.lifecycle ?? null,
|
|
13450
|
+
runtimeSurfaceKind: runtime?.surfaceKind,
|
|
13451
|
+
runtimeRestoredFromStorage: runtime?.restoredFromStorage === true,
|
|
13452
|
+
runtimeRecoveryState: runtime?.recoveryState ?? null
|
|
13453
|
+
};
|
|
13454
|
+
}
|
|
13364
13455
|
updateSettings(newSettings) {
|
|
13365
13456
|
this.settings = { ...newSettings };
|
|
13366
13457
|
this.adapter.updateRuntimeSettings?.(this.settings);
|
|
@@ -13516,6 +13607,15 @@ var CliProviderInstance = class {
|
|
|
13516
13607
|
this.completedDebouncePending = { chatTitle, duration, timestamp: now };
|
|
13517
13608
|
this.completedDebounceTimer = setTimeout(() => {
|
|
13518
13609
|
if (this.completedDebouncePending) {
|
|
13610
|
+
const latestStatus = this.adapter.getStatus();
|
|
13611
|
+
const latestAutoApproveActive = latestStatus.status === "waiting_approval" && this.shouldAutoApprove();
|
|
13612
|
+
const latestVisibleStatus = latestAutoApproveActive ? "generating" : latestStatus.status;
|
|
13613
|
+
if (latestVisibleStatus !== "idle") {
|
|
13614
|
+
LOG.info("CLI", `[${this.type}] cancelled pending completed (resumed ${latestVisibleStatus})`);
|
|
13615
|
+
this.completedDebouncePending = null;
|
|
13616
|
+
this.completedDebounceTimer = null;
|
|
13617
|
+
return;
|
|
13618
|
+
}
|
|
13519
13619
|
LOG.info("CLI", `[${this.type}] completed in ${this.completedDebouncePending.duration}s`);
|
|
13520
13620
|
this.pushEvent({ event: "agent:generating_completed", ...this.completedDebouncePending });
|
|
13521
13621
|
this.completedDebouncePending = null;
|
|
@@ -16551,10 +16651,22 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
16551
16651
|
setMachineProviderEnabled(type, enabled) {
|
|
16552
16652
|
return this.setMachineProviderConfig(type, { enabled });
|
|
16553
16653
|
}
|
|
16654
|
+
getEffectiveProviderAvailability(type) {
|
|
16655
|
+
const providerType = this.resolveAlias(type);
|
|
16656
|
+
const availability = this.providerAvailability.get(providerType);
|
|
16657
|
+
if (availability) return availability;
|
|
16658
|
+
const machineConfig = this.getMachineProviderConfig(providerType);
|
|
16659
|
+
const lastDetection = machineConfig.lastDetection;
|
|
16660
|
+
if (!lastDetection) return void 0;
|
|
16661
|
+
return {
|
|
16662
|
+
installed: lastDetection.ok === true,
|
|
16663
|
+
detectedPath: typeof lastDetection.path === "string" && lastDetection.path.trim() ? lastDetection.path.trim() : null
|
|
16664
|
+
};
|
|
16665
|
+
}
|
|
16554
16666
|
getMachineProviderStatus(type) {
|
|
16555
16667
|
const providerType = this.resolveAlias(type);
|
|
16556
16668
|
if (!this.isMachineProviderEnabled(providerType)) return "disabled";
|
|
16557
|
-
const availability = this.
|
|
16669
|
+
const availability = this.getEffectiveProviderAvailability(providerType);
|
|
16558
16670
|
if (!availability) return "enabled_unchecked";
|
|
16559
16671
|
return availability.installed ? "detected" : "not_detected";
|
|
16560
16672
|
}
|
|
@@ -16682,7 +16794,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
16682
16794
|
}
|
|
16683
16795
|
getAvailableProviderInfos() {
|
|
16684
16796
|
return this.getAll().map((provider) => {
|
|
16685
|
-
const availability = this.
|
|
16797
|
+
const availability = this.getEffectiveProviderAvailability(provider.type);
|
|
16686
16798
|
const enabled = this.isMachineProviderEnabled(provider.type);
|
|
16687
16799
|
const machineConfig = this.getMachineProviderConfig(provider.type);
|
|
16688
16800
|
return {
|
|
@@ -18510,6 +18622,51 @@ function killPid(pid) {
|
|
|
18510
18622
|
return false;
|
|
18511
18623
|
}
|
|
18512
18624
|
}
|
|
18625
|
+
function getWindowsProcessCommandLine(pid) {
|
|
18626
|
+
const pidFilter = `ProcessId=${pid}`;
|
|
18627
|
+
try {
|
|
18628
|
+
const psOut = (0, import_child_process8.execFileSync)("powershell.exe", [
|
|
18629
|
+
"-NoProfile",
|
|
18630
|
+
"-NonInteractive",
|
|
18631
|
+
"-ExecutionPolicy",
|
|
18632
|
+
"Bypass",
|
|
18633
|
+
"-Command",
|
|
18634
|
+
`(Get-CimInstance Win32_Process -Filter "${pidFilter}").CommandLine`
|
|
18635
|
+
], { encoding: "utf8", timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
18636
|
+
if (psOut) return psOut;
|
|
18637
|
+
} catch {
|
|
18638
|
+
}
|
|
18639
|
+
try {
|
|
18640
|
+
const wmicOut = (0, import_child_process8.execFileSync)("wmic", [
|
|
18641
|
+
"process",
|
|
18642
|
+
"where",
|
|
18643
|
+
pidFilter,
|
|
18644
|
+
"get",
|
|
18645
|
+
"CommandLine"
|
|
18646
|
+
], { encoding: "utf8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
18647
|
+
if (wmicOut) return wmicOut;
|
|
18648
|
+
} catch {
|
|
18649
|
+
}
|
|
18650
|
+
return null;
|
|
18651
|
+
}
|
|
18652
|
+
function getProcessCommandLine(pid) {
|
|
18653
|
+
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
18654
|
+
if (process.platform === "win32") return getWindowsProcessCommandLine(pid);
|
|
18655
|
+
try {
|
|
18656
|
+
const text = (0, import_child_process8.execFileSync)("ps", ["-o", "command=", "-p", String(pid)], {
|
|
18657
|
+
encoding: "utf8",
|
|
18658
|
+
timeout: 3e3,
|
|
18659
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
18660
|
+
}).trim();
|
|
18661
|
+
return text || null;
|
|
18662
|
+
} catch {
|
|
18663
|
+
return null;
|
|
18664
|
+
}
|
|
18665
|
+
}
|
|
18666
|
+
function isManagedSessionHostPid(pid) {
|
|
18667
|
+
const commandLine = getProcessCommandLine(pid);
|
|
18668
|
+
return !!commandLine && /session-host-daemon/i.test(commandLine);
|
|
18669
|
+
}
|
|
18513
18670
|
async function waitForPidExit(pid, timeoutMs) {
|
|
18514
18671
|
const start = Date.now();
|
|
18515
18672
|
while (Date.now() - start < timeoutMs) {
|
|
@@ -18526,7 +18683,7 @@ function stopSessionHostProcesses(appName) {
|
|
|
18526
18683
|
try {
|
|
18527
18684
|
if (fs8.existsSync(pidFile)) {
|
|
18528
18685
|
const pid = Number.parseInt(fs8.readFileSync(pidFile, "utf8").trim(), 10);
|
|
18529
|
-
if (Number.isFinite(pid)) {
|
|
18686
|
+
if (Number.isFinite(pid) && pid !== process.pid && isManagedSessionHostPid(pid)) {
|
|
18530
18687
|
killPid(pid);
|
|
18531
18688
|
}
|
|
18532
18689
|
}
|
|
@@ -18537,18 +18694,6 @@ function stopSessionHostProcesses(appName) {
|
|
|
18537
18694
|
} catch {
|
|
18538
18695
|
}
|
|
18539
18696
|
}
|
|
18540
|
-
if (process.platform !== "win32") {
|
|
18541
|
-
try {
|
|
18542
|
-
const raw = (0, import_child_process8.execFileSync)("pgrep", ["-f", "session-host-daemon"], { encoding: "utf8" }).trim();
|
|
18543
|
-
for (const line of raw.split("\n")) {
|
|
18544
|
-
const pid = Number.parseInt(line.trim(), 10);
|
|
18545
|
-
if (Number.isFinite(pid)) {
|
|
18546
|
-
killPid(pid);
|
|
18547
|
-
}
|
|
18548
|
-
}
|
|
18549
|
-
} catch {
|
|
18550
|
-
}
|
|
18551
|
-
}
|
|
18552
18697
|
}
|
|
18553
18698
|
function removeDaemonPidFile() {
|
|
18554
18699
|
const pidFile = path16.join(os17.homedir(), ".adhdev", "daemon.pid");
|
|
@@ -20783,6 +20928,20 @@ function forwardAgentStreamsToIdeInstance(instanceManager, ideType, streams) {
|
|
|
20783
20928
|
|
|
20784
20929
|
// src/providers/provider-instance-manager.ts
|
|
20785
20930
|
init_logger();
|
|
20931
|
+
function projectHotChatSessionStatesFromProviderState(state) {
|
|
20932
|
+
const project = (item) => ({
|
|
20933
|
+
id: item.instanceId,
|
|
20934
|
+
status: item.activeChat?.status || item.status,
|
|
20935
|
+
runtimeLifecycle: item.runtime?.lifecycle ?? null,
|
|
20936
|
+
runtimeSurfaceKind: item.runtime?.surfaceKind,
|
|
20937
|
+
runtimeRestoredFromStorage: item.runtime?.restoredFromStorage === true,
|
|
20938
|
+
runtimeRecoveryState: item.runtime?.recoveryState ?? null
|
|
20939
|
+
});
|
|
20940
|
+
if (state.category === "ide") {
|
|
20941
|
+
return [project(state), ...state.extensions.map(project)];
|
|
20942
|
+
}
|
|
20943
|
+
return [project(state)];
|
|
20944
|
+
}
|
|
20786
20945
|
var ProviderInstanceManager = class {
|
|
20787
20946
|
instances = /* @__PURE__ */ new Map();
|
|
20788
20947
|
tickTimer = null;
|
|
@@ -20878,6 +21037,27 @@ var ProviderInstanceManager = class {
|
|
|
20878
21037
|
}
|
|
20879
21038
|
return states;
|
|
20880
21039
|
}
|
|
21040
|
+
collectHotChatSessionStates() {
|
|
21041
|
+
const sessions = [];
|
|
21042
|
+
for (const [id, instance] of this.instances) {
|
|
21043
|
+
try {
|
|
21044
|
+
const projected = instance.getHotChatSessionState?.();
|
|
21045
|
+
if (Array.isArray(projected)) {
|
|
21046
|
+
sessions.push(...projected.filter((session) => !!session?.id));
|
|
21047
|
+
continue;
|
|
21048
|
+
}
|
|
21049
|
+
if (projected?.id) {
|
|
21050
|
+
sessions.push(projected);
|
|
21051
|
+
continue;
|
|
21052
|
+
}
|
|
21053
|
+
const state = instance.getState();
|
|
21054
|
+
sessions.push(...projectHotChatSessionStatesFromProviderState(state));
|
|
21055
|
+
} catch (e) {
|
|
21056
|
+
LOG.warn("InstanceMgr", `[InstanceManager] Failed to collect hot chat metadata from ${id}: ${e.message}`);
|
|
21057
|
+
}
|
|
21058
|
+
}
|
|
21059
|
+
return sessions;
|
|
21060
|
+
}
|
|
20881
21061
|
/**
|
|
20882
21062
|
* Per-category status collect
|
|
20883
21063
|
*/
|