@adhdev/daemon-core 0.8.57 → 0.8.59
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/agent-stream/types.d.ts +3 -4
- package/dist/boot/daemon-lifecycle.d.ts +1 -0
- package/dist/commands/handler.d.ts +1 -0
- package/dist/commands/router.d.ts +1 -0
- package/dist/commands/stream-commands.d.ts +3 -0
- package/dist/config/chat-history.d.ts +3 -0
- package/dist/config/config.d.ts +3 -0
- package/dist/config/provider-source-config.d.ts +23 -0
- package/dist/config/recent-activity.d.ts +2 -1
- package/dist/config/saved-sessions.d.ts +2 -1
- package/dist/daemon/dev-server-types.d.ts +1 -0
- package/dist/daemon/dev-server.d.ts +4 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +876 -337
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +875 -337
- package/dist/index.mjs.map +1 -1
- package/dist/providers/acp-provider-instance.d.ts +8 -2
- package/dist/providers/cli-provider-instance.d.ts +10 -0
- package/dist/providers/contracts.d.ts +4 -2
- package/dist/providers/extension-provider-instance.d.ts +1 -2
- package/dist/providers/provider-instance.d.ts +3 -4
- package/dist/providers/provider-loader.d.ts +14 -1
- package/dist/providers/provider-patch-state.d.ts +23 -0
- package/dist/providers/summary-metadata.d.ts +22 -0
- package/dist/shared-types.d.ts +15 -9
- package/dist/status/snapshot.d.ts +16 -1
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/agent-stream/forward.ts +1 -2
- package/src/agent-stream/manager.ts +2 -1
- package/src/agent-stream/provider-adapter.ts +7 -3
- package/src/agent-stream/types.d.ts +3 -4
- package/src/agent-stream/types.ts +3 -4
- package/src/boot/daemon-lifecycle.ts +13 -3
- package/src/commands/cli-manager.ts +10 -5
- package/src/commands/handler.ts +3 -0
- package/src/commands/router.ts +160 -26
- package/src/commands/stream-commands.ts +60 -2
- package/src/config/chat-history.ts +39 -0
- package/src/config/config.d.ts +3 -0
- package/src/config/config.ts +19 -3
- package/src/config/provider-source-config.ts +42 -0
- package/src/config/recent-activity.d.ts +2 -1
- package/src/config/recent-activity.ts +12 -1
- package/src/config/saved-sessions.d.ts +2 -1
- package/src/config/saved-sessions.ts +12 -2
- package/src/daemon/dev-auto-implement.ts +1 -14
- package/src/daemon/dev-cli-debug.ts +0 -1
- package/src/daemon/dev-server-types.ts +1 -0
- package/src/daemon/dev-server.ts +46 -21
- package/src/daemon/scaffold-template.ts +8 -1
- package/src/index.d.ts +1 -1
- package/src/index.ts +4 -0
- package/src/providers/acp-provider-instance.d.ts +8 -2
- package/src/providers/acp-provider-instance.ts +80 -23
- package/src/providers/cli-provider-instance.ts +42 -22
- package/src/providers/contracts.d.ts +3 -2
- package/src/providers/contracts.ts +7 -4
- package/src/providers/control-effects.ts +3 -4
- package/src/providers/extension-provider-instance.d.ts +1 -2
- package/src/providers/extension-provider-instance.ts +26 -14
- package/src/providers/ide-provider-instance.ts +28 -15
- package/src/providers/provider-instance.d.ts +3 -4
- package/src/providers/provider-instance.ts +6 -7
- package/src/providers/provider-loader.d.ts +4 -1
- package/src/providers/provider-loader.ts +61 -23
- package/src/providers/provider-patch-state.ts +91 -0
- package/src/providers/provider-schema.ts +3 -0
- package/src/providers/summary-metadata.ts +118 -0
- package/src/shared-types.d.ts +15 -9
- package/src/shared-types.ts +17 -9
- package/src/status/builders.ts +18 -13
- package/src/status/reporter.ts +2 -4
- package/src/status/snapshot.ts +60 -2
package/dist/index.mjs
CHANGED
|
@@ -35,6 +35,7 @@ __export(config_exports, {
|
|
|
35
35
|
loadConfig: () => loadConfig,
|
|
36
36
|
markSetupComplete: () => markSetupComplete,
|
|
37
37
|
resetConfig: () => resetConfig,
|
|
38
|
+
resolveProviderSourceMode: () => resolveProviderSourceMode,
|
|
38
39
|
saveConfig: () => saveConfig,
|
|
39
40
|
updateConfig: () => updateConfig
|
|
40
41
|
});
|
|
@@ -42,6 +43,12 @@ import { homedir } from "os";
|
|
|
42
43
|
import { join } from "path";
|
|
43
44
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync } from "fs";
|
|
44
45
|
import { randomUUID } from "crypto";
|
|
46
|
+
function resolveProviderSourceMode(providerSourceMode, legacyDisableUpstream) {
|
|
47
|
+
if (providerSourceMode === "normal" || providerSourceMode === "no-upstream") {
|
|
48
|
+
return providerSourceMode;
|
|
49
|
+
}
|
|
50
|
+
return legacyDisableUpstream === true ? "no-upstream" : "normal";
|
|
51
|
+
}
|
|
45
52
|
function isPlainObject(value) {
|
|
46
53
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
47
54
|
}
|
|
@@ -79,7 +86,7 @@ function normalizeConfig(raw) {
|
|
|
79
86
|
registeredMachineId: asOptionalString(parsed.registeredMachineId),
|
|
80
87
|
providerSettings: isPlainObject(parsed.providerSettings) ? parsed.providerSettings : {},
|
|
81
88
|
ideSettings: isPlainObject(parsed.ideSettings) ? parsed.ideSettings : {},
|
|
82
|
-
|
|
89
|
+
providerSourceMode: resolveProviderSourceMode(parsed.providerSourceMode, parsed.disableUpstream),
|
|
83
90
|
providerDir: asOptionalString(parsed.providerDir),
|
|
84
91
|
terminalSizingMode: parsed.terminalSizingMode === "fit" ? "fit" : "measured"
|
|
85
92
|
};
|
|
@@ -224,7 +231,7 @@ var init_config = __esm({
|
|
|
224
231
|
registeredMachineId: void 0,
|
|
225
232
|
providerSettings: {},
|
|
226
233
|
ideSettings: {},
|
|
227
|
-
|
|
234
|
+
providerSourceMode: "normal",
|
|
228
235
|
terminalSizingMode: "measured"
|
|
229
236
|
};
|
|
230
237
|
MACHINE_ID_PREFIX = "mach_";
|
|
@@ -1894,7 +1901,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
1894
1901
|
`[${this.cliType}] Waiting for interactive prompt: hasPrompt=${hasPrompt} stableMs=${stableMs} recentOutputMs=${recentlyOutput} status=${status} startup=${startupLikelyActive} screen=${JSON.stringify(summarizeCliTraceText(screenText, 220)).slice(0, 260)}`
|
|
1895
1902
|
);
|
|
1896
1903
|
}
|
|
1897
|
-
await new Promise((
|
|
1904
|
+
await new Promise((resolve11) => setTimeout(resolve11, 50));
|
|
1898
1905
|
}
|
|
1899
1906
|
const finalScreenText = this.terminalScreen.getText() || "";
|
|
1900
1907
|
LOG.warn(
|
|
@@ -2467,7 +2474,7 @@ ${data.message || ""}`.trim();
|
|
|
2467
2474
|
const deadline = Date.now() + 1e4;
|
|
2468
2475
|
while (this.startupParseGate && Date.now() < deadline) {
|
|
2469
2476
|
this.resolveStartupState("send_wait");
|
|
2470
|
-
await new Promise((
|
|
2477
|
+
await new Promise((resolve11) => setTimeout(resolve11, 50));
|
|
2471
2478
|
}
|
|
2472
2479
|
}
|
|
2473
2480
|
await this.waitForInteractivePrompt();
|
|
@@ -2537,12 +2544,12 @@ ${data.message || ""}`.trim();
|
|
|
2537
2544
|
if (this.isWaitingForResponse) this.finishResponse();
|
|
2538
2545
|
}, this.timeouts.maxResponse);
|
|
2539
2546
|
};
|
|
2540
|
-
await new Promise((
|
|
2547
|
+
await new Promise((resolve11) => {
|
|
2541
2548
|
let resolved = false;
|
|
2542
2549
|
const resolveOnce = () => {
|
|
2543
2550
|
if (resolved) return;
|
|
2544
2551
|
resolved = true;
|
|
2545
|
-
|
|
2552
|
+
resolve11();
|
|
2546
2553
|
};
|
|
2547
2554
|
const submit = () => {
|
|
2548
2555
|
if (!this.ptyProcess) {
|
|
@@ -2716,17 +2723,17 @@ ${data.message || ""}`.trim();
|
|
|
2716
2723
|
}
|
|
2717
2724
|
}
|
|
2718
2725
|
waitForStopped(timeoutMs) {
|
|
2719
|
-
return new Promise((
|
|
2726
|
+
return new Promise((resolve11) => {
|
|
2720
2727
|
const startedAt = Date.now();
|
|
2721
2728
|
const timer = setInterval(() => {
|
|
2722
2729
|
if (!this.ptyProcess || this.currentStatus === "stopped") {
|
|
2723
2730
|
clearInterval(timer);
|
|
2724
|
-
|
|
2731
|
+
resolve11(true);
|
|
2725
2732
|
return;
|
|
2726
2733
|
}
|
|
2727
2734
|
if (Date.now() - startedAt >= timeoutMs) {
|
|
2728
2735
|
clearInterval(timer);
|
|
2729
|
-
|
|
2736
|
+
resolve11(false);
|
|
2730
2737
|
}
|
|
2731
2738
|
}, 100);
|
|
2732
2739
|
});
|
|
@@ -3168,6 +3175,70 @@ function setDefaultWorkspaceId(config, id) {
|
|
|
3168
3175
|
|
|
3169
3176
|
// src/config/recent-activity.ts
|
|
3170
3177
|
import * as path2 from "path";
|
|
3178
|
+
|
|
3179
|
+
// src/providers/summary-metadata.ts
|
|
3180
|
+
function normalizeSummaryItem(item) {
|
|
3181
|
+
if (!item || typeof item !== "object") return null;
|
|
3182
|
+
const id = String(item.id || "").trim();
|
|
3183
|
+
const value = String(item.value || "").trim();
|
|
3184
|
+
if (!id || !value) return null;
|
|
3185
|
+
const normalized = {
|
|
3186
|
+
id,
|
|
3187
|
+
value
|
|
3188
|
+
};
|
|
3189
|
+
if (typeof item.label === "string" && item.label.trim()) normalized.label = item.label.trim();
|
|
3190
|
+
if (typeof item.shortValue === "string" && item.shortValue.trim()) normalized.shortValue = item.shortValue.trim();
|
|
3191
|
+
if (typeof item.icon === "string" && item.icon.trim()) normalized.icon = item.icon.trim();
|
|
3192
|
+
if (typeof item.order === "number" && Number.isFinite(item.order)) normalized.order = item.order;
|
|
3193
|
+
return normalized;
|
|
3194
|
+
}
|
|
3195
|
+
function normalizeProviderSummaryMetadata(summary) {
|
|
3196
|
+
if (!summary || !Array.isArray(summary.items)) return void 0;
|
|
3197
|
+
const items = summary.items.map((item) => normalizeSummaryItem(item)).filter((item) => !!item).sort((left, right) => {
|
|
3198
|
+
const orderDiff = (left.order ?? Number.MAX_SAFE_INTEGER) - (right.order ?? Number.MAX_SAFE_INTEGER);
|
|
3199
|
+
if (orderDiff !== 0) return orderDiff;
|
|
3200
|
+
return left.id.localeCompare(right.id);
|
|
3201
|
+
});
|
|
3202
|
+
return items.length > 0 ? { items } : void 0;
|
|
3203
|
+
}
|
|
3204
|
+
function buildProviderSummaryMetadata(items) {
|
|
3205
|
+
return normalizeProviderSummaryMetadata({ items: items.filter(Boolean) });
|
|
3206
|
+
}
|
|
3207
|
+
function buildLegacyModelModeSummaryMetadata(params) {
|
|
3208
|
+
return buildProviderSummaryMetadata([
|
|
3209
|
+
params.model ? {
|
|
3210
|
+
id: "model",
|
|
3211
|
+
label: "Model",
|
|
3212
|
+
value: String(params.modelLabel || params.model).trim(),
|
|
3213
|
+
shortValue: String(params.model).trim(),
|
|
3214
|
+
order: 10
|
|
3215
|
+
} : null,
|
|
3216
|
+
params.mode ? {
|
|
3217
|
+
id: "mode",
|
|
3218
|
+
label: "Mode",
|
|
3219
|
+
value: String(params.modeLabel || params.mode).trim(),
|
|
3220
|
+
shortValue: String(params.mode).trim(),
|
|
3221
|
+
order: 20
|
|
3222
|
+
} : null
|
|
3223
|
+
]);
|
|
3224
|
+
}
|
|
3225
|
+
function resolveProviderStateSummaryMetadata(params) {
|
|
3226
|
+
const explicit = normalizeProviderSummaryMetadata(params.summaryMetadata);
|
|
3227
|
+
if (explicit) return explicit;
|
|
3228
|
+
const model = typeof params.controlValues?.model === "string" ? params.controlValues.model : void 0;
|
|
3229
|
+
const mode = typeof params.controlValues?.mode === "string" ? params.controlValues.mode : void 0;
|
|
3230
|
+
return buildLegacyModelModeSummaryMetadata({
|
|
3231
|
+
model,
|
|
3232
|
+
mode,
|
|
3233
|
+
modelLabel: params.modelLabel,
|
|
3234
|
+
modeLabel: params.modeLabel
|
|
3235
|
+
});
|
|
3236
|
+
}
|
|
3237
|
+
function normalizePersistedSummaryMetadata(params) {
|
|
3238
|
+
return normalizeProviderSummaryMetadata(params.summaryMetadata);
|
|
3239
|
+
}
|
|
3240
|
+
|
|
3241
|
+
// src/config/recent-activity.ts
|
|
3171
3242
|
var MAX_ACTIVITY = 30;
|
|
3172
3243
|
function normalizeWorkspace(workspace) {
|
|
3173
3244
|
if (!workspace) return "";
|
|
@@ -3191,6 +3262,9 @@ function appendRecentActivity(state, entry) {
|
|
|
3191
3262
|
const nextEntry = {
|
|
3192
3263
|
...entry,
|
|
3193
3264
|
workspace: entry.workspace ? normalizeWorkspace(entry.workspace) : void 0,
|
|
3265
|
+
summaryMetadata: normalizePersistedSummaryMetadata({
|
|
3266
|
+
summaryMetadata: entry.summaryMetadata
|
|
3267
|
+
}),
|
|
3194
3268
|
id: buildRecentActivityKeyForEntry(entry),
|
|
3195
3269
|
lastUsedAt: entry.lastUsedAt || Date.now()
|
|
3196
3270
|
};
|
|
@@ -3201,7 +3275,12 @@ function appendRecentActivity(state, entry) {
|
|
|
3201
3275
|
};
|
|
3202
3276
|
}
|
|
3203
3277
|
function getRecentActivity(state, limit = 20) {
|
|
3204
|
-
return [...state.recentActivity || []].
|
|
3278
|
+
return [...state.recentActivity || []].map((entry) => ({
|
|
3279
|
+
...entry,
|
|
3280
|
+
summaryMetadata: normalizePersistedSummaryMetadata({
|
|
3281
|
+
summaryMetadata: entry.summaryMetadata
|
|
3282
|
+
})
|
|
3283
|
+
})).sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, limit);
|
|
3205
3284
|
}
|
|
3206
3285
|
function getSessionSeenAt(state, sessionId) {
|
|
3207
3286
|
return state.sessionReads?.[sessionId] || 0;
|
|
@@ -3253,7 +3332,9 @@ function upsertSavedProviderSession(state, entry) {
|
|
|
3253
3332
|
providerName: entry.providerName,
|
|
3254
3333
|
providerSessionId,
|
|
3255
3334
|
workspace: entry.workspace ? normalizeWorkspace2(entry.workspace) : void 0,
|
|
3256
|
-
|
|
3335
|
+
summaryMetadata: normalizePersistedSummaryMetadata({
|
|
3336
|
+
summaryMetadata: entry.summaryMetadata
|
|
3337
|
+
}),
|
|
3257
3338
|
title: entry.title,
|
|
3258
3339
|
createdAt: existing?.createdAt || entry.createdAt || Date.now(),
|
|
3259
3340
|
lastUsedAt: entry.lastUsedAt || Date.now()
|
|
@@ -3269,7 +3350,12 @@ function getSavedProviderSessions(state, filters) {
|
|
|
3269
3350
|
if (filters?.providerType && entry.providerType !== filters.providerType) return false;
|
|
3270
3351
|
if (filters?.kind && entry.kind !== filters.kind) return false;
|
|
3271
3352
|
return true;
|
|
3272
|
-
}).
|
|
3353
|
+
}).map((entry) => ({
|
|
3354
|
+
...entry,
|
|
3355
|
+
summaryMetadata: normalizePersistedSummaryMetadata({
|
|
3356
|
+
summaryMetadata: entry.summaryMetadata
|
|
3357
|
+
})
|
|
3358
|
+
})).sort((a, b) => b.lastUsedAt - a.lastUsedAt);
|
|
3273
3359
|
}
|
|
3274
3360
|
|
|
3275
3361
|
// src/config/state-store.ts
|
|
@@ -3465,15 +3551,15 @@ function resolveCommandPath(command) {
|
|
|
3465
3551
|
return null;
|
|
3466
3552
|
}
|
|
3467
3553
|
function execAsync(cmd, timeoutMs = 5e3) {
|
|
3468
|
-
return new Promise((
|
|
3554
|
+
return new Promise((resolve11) => {
|
|
3469
3555
|
const child = exec(cmd, { encoding: "utf-8", timeout: timeoutMs }, (err, stdout) => {
|
|
3470
3556
|
if (err || !stdout?.trim()) {
|
|
3471
|
-
|
|
3557
|
+
resolve11(null);
|
|
3472
3558
|
} else {
|
|
3473
|
-
|
|
3559
|
+
resolve11(stdout.trim());
|
|
3474
3560
|
}
|
|
3475
3561
|
});
|
|
3476
|
-
child.on("error", () =>
|
|
3562
|
+
child.on("error", () => resolve11(null));
|
|
3477
3563
|
});
|
|
3478
3564
|
}
|
|
3479
3565
|
async function detectCLIs(providerLoader, options) {
|
|
@@ -3684,7 +3770,7 @@ var DaemonCdpManager = class {
|
|
|
3684
3770
|
* Returns multiple entries if multiple IDE windows are open on same port
|
|
3685
3771
|
*/
|
|
3686
3772
|
static listAllTargets(port) {
|
|
3687
|
-
return new Promise((
|
|
3773
|
+
return new Promise((resolve11) => {
|
|
3688
3774
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
3689
3775
|
let data = "";
|
|
3690
3776
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -3700,16 +3786,16 @@ var DaemonCdpManager = class {
|
|
|
3700
3786
|
(t) => !isNonMain(t.title || "") && t.url?.includes("workbench.html") && !t.url?.includes("agent")
|
|
3701
3787
|
);
|
|
3702
3788
|
const fallbackPages = pages.filter((t) => !isNonMain(t.title || ""));
|
|
3703
|
-
|
|
3789
|
+
resolve11(mainPages.length > 0 ? mainPages : fallbackPages);
|
|
3704
3790
|
} catch {
|
|
3705
|
-
|
|
3791
|
+
resolve11([]);
|
|
3706
3792
|
}
|
|
3707
3793
|
});
|
|
3708
3794
|
});
|
|
3709
|
-
req.on("error", () =>
|
|
3795
|
+
req.on("error", () => resolve11([]));
|
|
3710
3796
|
req.setTimeout(2e3, () => {
|
|
3711
3797
|
req.destroy();
|
|
3712
|
-
|
|
3798
|
+
resolve11([]);
|
|
3713
3799
|
});
|
|
3714
3800
|
});
|
|
3715
3801
|
}
|
|
@@ -3749,7 +3835,7 @@ var DaemonCdpManager = class {
|
|
|
3749
3835
|
}
|
|
3750
3836
|
}
|
|
3751
3837
|
findTargetOnPort(port) {
|
|
3752
|
-
return new Promise((
|
|
3838
|
+
return new Promise((resolve11) => {
|
|
3753
3839
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
3754
3840
|
let data = "";
|
|
3755
3841
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -3760,7 +3846,7 @@ var DaemonCdpManager = class {
|
|
|
3760
3846
|
(t) => (t.type === "page" || t.type === "browser" || t.type === "Page") && t.webSocketDebuggerUrl
|
|
3761
3847
|
);
|
|
3762
3848
|
if (pages.length === 0) {
|
|
3763
|
-
|
|
3849
|
+
resolve11(targets.find((t) => t.webSocketDebuggerUrl) || null);
|
|
3764
3850
|
return;
|
|
3765
3851
|
}
|
|
3766
3852
|
const mainPages = pages.filter((t) => !this.isNonMainTitle(t.title || ""));
|
|
@@ -3770,24 +3856,24 @@ var DaemonCdpManager = class {
|
|
|
3770
3856
|
const specific = list.find((t) => t.id === this._targetId);
|
|
3771
3857
|
if (specific) {
|
|
3772
3858
|
this._pageTitle = specific.title || "";
|
|
3773
|
-
|
|
3859
|
+
resolve11(specific);
|
|
3774
3860
|
} else {
|
|
3775
3861
|
this.log(`[CDP] Target ${this._targetId} not found in page list`);
|
|
3776
|
-
|
|
3862
|
+
resolve11(null);
|
|
3777
3863
|
}
|
|
3778
3864
|
return;
|
|
3779
3865
|
}
|
|
3780
3866
|
this._pageTitle = list[0]?.title || "";
|
|
3781
|
-
|
|
3867
|
+
resolve11(list[0]);
|
|
3782
3868
|
} catch {
|
|
3783
|
-
|
|
3869
|
+
resolve11(null);
|
|
3784
3870
|
}
|
|
3785
3871
|
});
|
|
3786
3872
|
});
|
|
3787
|
-
req.on("error", () =>
|
|
3873
|
+
req.on("error", () => resolve11(null));
|
|
3788
3874
|
req.setTimeout(2e3, () => {
|
|
3789
3875
|
req.destroy();
|
|
3790
|
-
|
|
3876
|
+
resolve11(null);
|
|
3791
3877
|
});
|
|
3792
3878
|
});
|
|
3793
3879
|
}
|
|
@@ -3798,7 +3884,7 @@ var DaemonCdpManager = class {
|
|
|
3798
3884
|
this.extensionProviders = providers;
|
|
3799
3885
|
}
|
|
3800
3886
|
connectToTarget(wsUrl) {
|
|
3801
|
-
return new Promise((
|
|
3887
|
+
return new Promise((resolve11) => {
|
|
3802
3888
|
this.ws = new WebSocket(wsUrl);
|
|
3803
3889
|
this.ws.on("open", async () => {
|
|
3804
3890
|
this._connected = true;
|
|
@@ -3808,17 +3894,17 @@ var DaemonCdpManager = class {
|
|
|
3808
3894
|
}
|
|
3809
3895
|
this.connectBrowserWs().catch(() => {
|
|
3810
3896
|
});
|
|
3811
|
-
|
|
3897
|
+
resolve11(true);
|
|
3812
3898
|
});
|
|
3813
3899
|
this.ws.on("message", (data) => {
|
|
3814
3900
|
try {
|
|
3815
3901
|
const msg = JSON.parse(data.toString());
|
|
3816
3902
|
if (msg.id && this.pending.has(msg.id)) {
|
|
3817
|
-
const { resolve:
|
|
3903
|
+
const { resolve: resolve12, reject } = this.pending.get(msg.id);
|
|
3818
3904
|
this.pending.delete(msg.id);
|
|
3819
3905
|
this.failureCount = 0;
|
|
3820
3906
|
if (msg.error) reject(new Error(msg.error.message));
|
|
3821
|
-
else
|
|
3907
|
+
else resolve12(msg.result);
|
|
3822
3908
|
} else if (msg.method === "Runtime.executionContextCreated") {
|
|
3823
3909
|
this.contexts.add(msg.params.context.id);
|
|
3824
3910
|
} else if (msg.method === "Runtime.executionContextDestroyed") {
|
|
@@ -3841,7 +3927,7 @@ var DaemonCdpManager = class {
|
|
|
3841
3927
|
this.ws.on("error", (err) => {
|
|
3842
3928
|
this.log(`[CDP] WebSocket error: ${err.message}`);
|
|
3843
3929
|
this._connected = false;
|
|
3844
|
-
|
|
3930
|
+
resolve11(false);
|
|
3845
3931
|
});
|
|
3846
3932
|
});
|
|
3847
3933
|
}
|
|
@@ -3855,7 +3941,7 @@ var DaemonCdpManager = class {
|
|
|
3855
3941
|
return;
|
|
3856
3942
|
}
|
|
3857
3943
|
this.log(`[CDP] Connecting browser WS for target discovery...`);
|
|
3858
|
-
await new Promise((
|
|
3944
|
+
await new Promise((resolve11, reject) => {
|
|
3859
3945
|
this.browserWs = new WebSocket(browserWsUrl);
|
|
3860
3946
|
this.browserWs.on("open", async () => {
|
|
3861
3947
|
this._browserConnected = true;
|
|
@@ -3865,16 +3951,16 @@ var DaemonCdpManager = class {
|
|
|
3865
3951
|
} catch (e) {
|
|
3866
3952
|
this.log(`[CDP] setDiscoverTargets failed: ${e.message}`);
|
|
3867
3953
|
}
|
|
3868
|
-
|
|
3954
|
+
resolve11();
|
|
3869
3955
|
});
|
|
3870
3956
|
this.browserWs.on("message", (data) => {
|
|
3871
3957
|
try {
|
|
3872
3958
|
const msg = JSON.parse(data.toString());
|
|
3873
3959
|
if (msg.id && this.browserPending.has(msg.id)) {
|
|
3874
|
-
const { resolve:
|
|
3960
|
+
const { resolve: resolve12, reject: reject2 } = this.browserPending.get(msg.id);
|
|
3875
3961
|
this.browserPending.delete(msg.id);
|
|
3876
3962
|
if (msg.error) reject2(new Error(msg.error.message));
|
|
3877
|
-
else
|
|
3963
|
+
else resolve12(msg.result);
|
|
3878
3964
|
}
|
|
3879
3965
|
} catch {
|
|
3880
3966
|
}
|
|
@@ -3894,31 +3980,31 @@ var DaemonCdpManager = class {
|
|
|
3894
3980
|
}
|
|
3895
3981
|
}
|
|
3896
3982
|
getBrowserWsUrl() {
|
|
3897
|
-
return new Promise((
|
|
3983
|
+
return new Promise((resolve11) => {
|
|
3898
3984
|
const req = http.get(`http://127.0.0.1:${this.port}/json/version`, (res) => {
|
|
3899
3985
|
let data = "";
|
|
3900
3986
|
res.on("data", (chunk) => data += chunk.toString());
|
|
3901
3987
|
res.on("end", () => {
|
|
3902
3988
|
try {
|
|
3903
3989
|
const info = JSON.parse(data);
|
|
3904
|
-
|
|
3990
|
+
resolve11(info.webSocketDebuggerUrl || null);
|
|
3905
3991
|
} catch {
|
|
3906
|
-
|
|
3992
|
+
resolve11(null);
|
|
3907
3993
|
}
|
|
3908
3994
|
});
|
|
3909
3995
|
});
|
|
3910
|
-
req.on("error", () =>
|
|
3996
|
+
req.on("error", () => resolve11(null));
|
|
3911
3997
|
req.setTimeout(3e3, () => {
|
|
3912
3998
|
req.destroy();
|
|
3913
|
-
|
|
3999
|
+
resolve11(null);
|
|
3914
4000
|
});
|
|
3915
4001
|
});
|
|
3916
4002
|
}
|
|
3917
4003
|
sendBrowser(method, params = {}, timeoutMs = 15e3) {
|
|
3918
|
-
return new Promise((
|
|
4004
|
+
return new Promise((resolve11, reject) => {
|
|
3919
4005
|
if (!this.browserWs || !this._browserConnected) return reject(new Error("Browser WS not connected"));
|
|
3920
4006
|
const id = this.browserMsgId++;
|
|
3921
|
-
this.browserPending.set(id, { resolve:
|
|
4007
|
+
this.browserPending.set(id, { resolve: resolve11, reject });
|
|
3922
4008
|
this.browserWs.send(JSON.stringify({ id, method, params }));
|
|
3923
4009
|
setTimeout(() => {
|
|
3924
4010
|
if (this.browserPending.has(id)) {
|
|
@@ -3958,11 +4044,11 @@ var DaemonCdpManager = class {
|
|
|
3958
4044
|
}
|
|
3959
4045
|
// ─── CDP Protocol ────────────────────────────────────────
|
|
3960
4046
|
sendInternal(method, params = {}, timeoutMs = 15e3) {
|
|
3961
|
-
return new Promise((
|
|
4047
|
+
return new Promise((resolve11, reject) => {
|
|
3962
4048
|
if (!this.ws || !this._connected) return reject(new Error("CDP not connected"));
|
|
3963
4049
|
if (this.ws.readyState !== WebSocket.OPEN) return reject(new Error("WebSocket not open"));
|
|
3964
4050
|
const id = this.msgId++;
|
|
3965
|
-
this.pending.set(id, { resolve:
|
|
4051
|
+
this.pending.set(id, { resolve: resolve11, reject });
|
|
3966
4052
|
this.ws.send(JSON.stringify({ id, method, params }));
|
|
3967
4053
|
setTimeout(() => {
|
|
3968
4054
|
if (this.pending.has(id)) {
|
|
@@ -4211,7 +4297,7 @@ var DaemonCdpManager = class {
|
|
|
4211
4297
|
const browserWs = this.browserWs;
|
|
4212
4298
|
let msgId = this.browserMsgId;
|
|
4213
4299
|
const sendWs = (method, params = {}, sessionId) => {
|
|
4214
|
-
return new Promise((
|
|
4300
|
+
return new Promise((resolve11, reject) => {
|
|
4215
4301
|
const mid = msgId++;
|
|
4216
4302
|
this.browserMsgId = msgId;
|
|
4217
4303
|
const handler = (raw) => {
|
|
@@ -4220,7 +4306,7 @@ var DaemonCdpManager = class {
|
|
|
4220
4306
|
if (msg.id === mid) {
|
|
4221
4307
|
browserWs.removeListener("message", handler);
|
|
4222
4308
|
if (msg.error) reject(new Error(msg.error.message || JSON.stringify(msg.error)));
|
|
4223
|
-
else
|
|
4309
|
+
else resolve11(msg.result);
|
|
4224
4310
|
}
|
|
4225
4311
|
} catch {
|
|
4226
4312
|
}
|
|
@@ -4421,14 +4507,14 @@ var DaemonCdpManager = class {
|
|
|
4421
4507
|
if (!ws || ws.readyState !== WebSocket.OPEN) {
|
|
4422
4508
|
throw new Error("CDP not connected");
|
|
4423
4509
|
}
|
|
4424
|
-
return new Promise((
|
|
4510
|
+
return new Promise((resolve11, reject) => {
|
|
4425
4511
|
const id = getNextId();
|
|
4426
4512
|
pendingMap.set(id, {
|
|
4427
4513
|
resolve: (result) => {
|
|
4428
4514
|
if (result?.result?.subtype === "error") {
|
|
4429
4515
|
reject(new Error(result.result.description));
|
|
4430
4516
|
} else {
|
|
4431
|
-
|
|
4517
|
+
resolve11(result?.result?.value);
|
|
4432
4518
|
}
|
|
4433
4519
|
},
|
|
4434
4520
|
reject
|
|
@@ -4460,10 +4546,10 @@ var DaemonCdpManager = class {
|
|
|
4460
4546
|
throw new Error("CDP not connected");
|
|
4461
4547
|
}
|
|
4462
4548
|
const sendViaSession = (method, params = {}) => {
|
|
4463
|
-
return new Promise((
|
|
4549
|
+
return new Promise((resolve11, reject) => {
|
|
4464
4550
|
const pendingMap = this._browserConnected ? this.browserPending : this.pending;
|
|
4465
4551
|
const id = this._browserConnected ? this.browserMsgId++ : this.msgId++;
|
|
4466
|
-
pendingMap.set(id, { resolve:
|
|
4552
|
+
pendingMap.set(id, { resolve: resolve11, reject });
|
|
4467
4553
|
ws.send(JSON.stringify({ id, sessionId, method, params }));
|
|
4468
4554
|
setTimeout(() => {
|
|
4469
4555
|
if (pendingMap.has(id)) {
|
|
@@ -5026,8 +5112,6 @@ function extractProviderControlValues(controls, data) {
|
|
|
5026
5112
|
if (rawValue === void 0 || rawValue === null) continue;
|
|
5027
5113
|
values[ctrl.id] = normalizeControlValue(rawValue);
|
|
5028
5114
|
}
|
|
5029
|
-
if (data.model !== void 0 && values.model === void 0) values.model = normalizeControlValue(data.model);
|
|
5030
|
-
if (data.mode !== void 0 && values.mode === void 0) values.mode = normalizeControlValue(data.mode);
|
|
5031
5115
|
return Object.keys(values).length > 0 ? values : void 0;
|
|
5032
5116
|
}
|
|
5033
5117
|
function normalizeProviderEffects(data) {
|
|
@@ -5129,7 +5213,7 @@ function normalizeControlOption(option) {
|
|
|
5129
5213
|
}
|
|
5130
5214
|
if (!option || typeof option !== "object") return null;
|
|
5131
5215
|
const record = option;
|
|
5132
|
-
const value = typeof record.value === "string" ? record.value : typeof record.id === "string" ? record.id : null;
|
|
5216
|
+
const value = typeof record.value === "string" ? record.value : typeof record.id === "string" ? record.id : typeof record.name === "string" ? record.name : null;
|
|
5133
5217
|
if (!value) return null;
|
|
5134
5218
|
const label = typeof record.label === "string" ? record.label : typeof record.name === "string" ? record.name : value;
|
|
5135
5219
|
const normalized = { value, label };
|
|
@@ -5373,6 +5457,30 @@ var ChatHistoryWriter = class {
|
|
|
5373
5457
|
options.historySessionId
|
|
5374
5458
|
);
|
|
5375
5459
|
}
|
|
5460
|
+
writeSessionStart(agentType, historySessionId, workspace, instanceId) {
|
|
5461
|
+
const id = String(historySessionId || "").trim();
|
|
5462
|
+
const ws = String(workspace || "").trim();
|
|
5463
|
+
if (!id || !ws) return;
|
|
5464
|
+
try {
|
|
5465
|
+
const dir = path7.join(HISTORY_DIR, this.sanitize(agentType));
|
|
5466
|
+
fs3.mkdirSync(dir, { recursive: true });
|
|
5467
|
+
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
5468
|
+
const filePath = path7.join(dir, `${this.sanitize(id)}_${date}.jsonl`);
|
|
5469
|
+
const record = {
|
|
5470
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5471
|
+
receivedAt: Date.now(),
|
|
5472
|
+
role: "system",
|
|
5473
|
+
kind: "session_start",
|
|
5474
|
+
content: ws,
|
|
5475
|
+
agent: agentType,
|
|
5476
|
+
instanceId,
|
|
5477
|
+
historySessionId: id,
|
|
5478
|
+
workspace: ws
|
|
5479
|
+
};
|
|
5480
|
+
fs3.appendFileSync(filePath, JSON.stringify(record) + "\n", "utf-8");
|
|
5481
|
+
} catch {
|
|
5482
|
+
}
|
|
5483
|
+
}
|
|
5376
5484
|
promoteHistorySession(agentType, previousHistorySessionId, nextHistorySessionId) {
|
|
5377
5485
|
const fromId = String(previousHistorySessionId || "").trim();
|
|
5378
5486
|
const toId = String(nextHistorySessionId || "").trim();
|
|
@@ -5592,6 +5700,7 @@ function listSavedHistorySessions(agentType, options = {}) {
|
|
|
5592
5700
|
let lastMessageAt = 0;
|
|
5593
5701
|
let sessionTitle = "";
|
|
5594
5702
|
let preview = "";
|
|
5703
|
+
let workspace = "";
|
|
5595
5704
|
for (const file of files.sort()) {
|
|
5596
5705
|
const filePath = path7.join(dir, file);
|
|
5597
5706
|
const content = fs3.readFileSync(filePath, "utf-8");
|
|
@@ -5604,6 +5713,10 @@ function listSavedHistorySessions(agentType, options = {}) {
|
|
|
5604
5713
|
parsed = null;
|
|
5605
5714
|
}
|
|
5606
5715
|
if (!parsed || parsed.historySessionId !== historySessionId) continue;
|
|
5716
|
+
if (parsed.kind === "session_start") {
|
|
5717
|
+
if (!workspace && parsed.workspace) workspace = parsed.workspace;
|
|
5718
|
+
continue;
|
|
5719
|
+
}
|
|
5607
5720
|
messageCount += 1;
|
|
5608
5721
|
if (!firstMessageAt || parsed.receivedAt < firstMessageAt) firstMessageAt = parsed.receivedAt;
|
|
5609
5722
|
if (!lastMessageAt || parsed.receivedAt > lastMessageAt) lastMessageAt = parsed.receivedAt;
|
|
@@ -5618,7 +5731,8 @@ function listSavedHistorySessions(agentType, options = {}) {
|
|
|
5618
5731
|
messageCount,
|
|
5619
5732
|
firstMessageAt,
|
|
5620
5733
|
lastMessageAt,
|
|
5621
|
-
preview: preview || void 0
|
|
5734
|
+
preview: preview || void 0,
|
|
5735
|
+
workspace: workspace || void 0
|
|
5622
5736
|
});
|
|
5623
5737
|
}
|
|
5624
5738
|
summaries.sort((a, b) => b.lastMessageAt - a.lastMessageAt);
|
|
@@ -5634,6 +5748,61 @@ function listSavedHistorySessions(agentType, options = {}) {
|
|
|
5634
5748
|
}
|
|
5635
5749
|
}
|
|
5636
5750
|
|
|
5751
|
+
// src/providers/provider-patch-state.ts
|
|
5752
|
+
function isControlValue(value) {
|
|
5753
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
5754
|
+
}
|
|
5755
|
+
function asControlValueMap(value) {
|
|
5756
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
5757
|
+
const result = {};
|
|
5758
|
+
for (const [entryKey, entryValue] of Object.entries(value)) {
|
|
5759
|
+
if (isControlValue(entryValue)) result[entryKey] = entryValue;
|
|
5760
|
+
}
|
|
5761
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
5762
|
+
}
|
|
5763
|
+
function getLegacyModelModeValues(data) {
|
|
5764
|
+
if (!data || typeof data !== "object") return void 0;
|
|
5765
|
+
const legacy = {};
|
|
5766
|
+
if (typeof data.model === "string" && data.model.trim()) legacy.model = data.model.trim();
|
|
5767
|
+
if (typeof data.mode === "string" && data.mode.trim()) legacy.mode = data.mode.trim();
|
|
5768
|
+
return Object.keys(legacy).length > 0 ? legacy : void 0;
|
|
5769
|
+
}
|
|
5770
|
+
function mergeProviderPatchState(params) {
|
|
5771
|
+
const {
|
|
5772
|
+
providerControls,
|
|
5773
|
+
data,
|
|
5774
|
+
currentControlValues,
|
|
5775
|
+
currentSummaryMetadata,
|
|
5776
|
+
mergeWithCurrent = true
|
|
5777
|
+
} = params;
|
|
5778
|
+
const sources = [
|
|
5779
|
+
mergeWithCurrent ? asControlValueMap(currentControlValues) : void 0,
|
|
5780
|
+
asControlValueMap(data?.controlValues),
|
|
5781
|
+
asControlValueMap(extractProviderControlValues(providerControls, data)),
|
|
5782
|
+
getLegacyModelModeValues(data)
|
|
5783
|
+
];
|
|
5784
|
+
const controlValues = Object.assign({}, ...sources.filter(Boolean));
|
|
5785
|
+
return {
|
|
5786
|
+
controlValues,
|
|
5787
|
+
summaryMetadata: data?.summaryMetadata !== void 0 ? data.summaryMetadata : currentSummaryMetadata
|
|
5788
|
+
};
|
|
5789
|
+
}
|
|
5790
|
+
function normalizeProviderStateControlValues(controlValues) {
|
|
5791
|
+
return controlValues && Object.keys(controlValues).length > 0 ? controlValues : void 0;
|
|
5792
|
+
}
|
|
5793
|
+
function resolveProviderStateSurface(params) {
|
|
5794
|
+
const controlValues = normalizeProviderStateControlValues(params.controlValues);
|
|
5795
|
+
return {
|
|
5796
|
+
controlValues,
|
|
5797
|
+
summaryMetadata: resolveProviderStateSummaryMetadata({
|
|
5798
|
+
summaryMetadata: params.summaryMetadata,
|
|
5799
|
+
controlValues,
|
|
5800
|
+
modelLabel: params.modelLabel,
|
|
5801
|
+
modeLabel: params.modeLabel
|
|
5802
|
+
})
|
|
5803
|
+
};
|
|
5804
|
+
}
|
|
5805
|
+
|
|
5637
5806
|
// src/providers/extension-provider-instance.ts
|
|
5638
5807
|
var ExtensionProviderInstance = class {
|
|
5639
5808
|
type;
|
|
@@ -5648,9 +5817,8 @@ var ExtensionProviderInstance = class {
|
|
|
5648
5817
|
messages = [];
|
|
5649
5818
|
prevMessageHashes = /* @__PURE__ */ new Map();
|
|
5650
5819
|
activeModal = null;
|
|
5651
|
-
currentModel = "";
|
|
5652
|
-
currentMode = "";
|
|
5653
5820
|
controlValues = {};
|
|
5821
|
+
summaryMetadata = void 0;
|
|
5654
5822
|
appliedEffectKeys = /* @__PURE__ */ new Set();
|
|
5655
5823
|
runtimeMessages = [];
|
|
5656
5824
|
lastAgentStatus = "idle";
|
|
@@ -5685,6 +5853,10 @@ var ExtensionProviderInstance = class {
|
|
|
5685
5853
|
if (!this.context?.cdp?.isConnected) return;
|
|
5686
5854
|
}
|
|
5687
5855
|
getState() {
|
|
5856
|
+
const surface = resolveProviderStateSurface({
|
|
5857
|
+
summaryMetadata: this.summaryMetadata,
|
|
5858
|
+
controlValues: this.controlValues
|
|
5859
|
+
});
|
|
5688
5860
|
return {
|
|
5689
5861
|
type: this.type,
|
|
5690
5862
|
name: this.provider.name,
|
|
@@ -5698,10 +5870,9 @@ var ExtensionProviderInstance = class {
|
|
|
5698
5870
|
activeModal: this.activeModal,
|
|
5699
5871
|
inputContent: ""
|
|
5700
5872
|
} : null,
|
|
5701
|
-
|
|
5702
|
-
currentPlan: this.currentMode || void 0,
|
|
5703
|
-
controlValues: this.controlValues,
|
|
5873
|
+
controlValues: surface.controlValues,
|
|
5704
5874
|
providerControls: this.provider.controls,
|
|
5875
|
+
summaryMetadata: surface.summaryMetadata,
|
|
5705
5876
|
agentStreams: this.agentStreams,
|
|
5706
5877
|
instanceId: this.instanceId,
|
|
5707
5878
|
lastUpdated: Date.now(),
|
|
@@ -5714,10 +5885,14 @@ var ExtensionProviderInstance = class {
|
|
|
5714
5885
|
if (data?.streams) this.agentStreams = data.streams;
|
|
5715
5886
|
if (data?.messages) this.messages = this.assignReceivedAt(data.messages);
|
|
5716
5887
|
if (data?.activeModal !== void 0) this.activeModal = data.activeModal;
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5888
|
+
const patchedState = mergeProviderPatchState({
|
|
5889
|
+
providerControls: this.provider.controls,
|
|
5890
|
+
data,
|
|
5891
|
+
currentControlValues: this.controlValues,
|
|
5892
|
+
currentSummaryMetadata: this.summaryMetadata
|
|
5893
|
+
});
|
|
5894
|
+
this.controlValues = patchedState.controlValues;
|
|
5895
|
+
this.summaryMetadata = patchedState.summaryMetadata;
|
|
5721
5896
|
if (typeof data?.sessionId === "string" && data.sessionId.trim()) this.chatId = data.sessionId;
|
|
5722
5897
|
if (typeof data?.title === "string" && data.title.trim()) this.chatTitle = data.title;
|
|
5723
5898
|
if (typeof data?.agentName === "string" && data.agentName.trim()) this.agentName = data.agentName;
|
|
@@ -5818,8 +5993,14 @@ var ExtensionProviderInstance = class {
|
|
|
5818
5993
|
}
|
|
5819
5994
|
applyProviderResponse(data, options) {
|
|
5820
5995
|
if (!data || typeof data !== "object") return;
|
|
5821
|
-
const
|
|
5822
|
-
|
|
5996
|
+
const patchedState = mergeProviderPatchState({
|
|
5997
|
+
providerControls: this.provider.controls,
|
|
5998
|
+
data,
|
|
5999
|
+
currentControlValues: this.controlValues,
|
|
6000
|
+
currentSummaryMetadata: this.summaryMetadata
|
|
6001
|
+
});
|
|
6002
|
+
this.controlValues = patchedState.controlValues;
|
|
6003
|
+
this.summaryMetadata = patchedState.summaryMetadata;
|
|
5823
6004
|
const effects = normalizeProviderEffects(data);
|
|
5824
6005
|
for (const effect of effects) {
|
|
5825
6006
|
const effectWhen = effect.when || "immediate";
|
|
@@ -5969,8 +6150,6 @@ ${effect.notification.body || ""}`.trim();
|
|
|
5969
6150
|
this.messages = [];
|
|
5970
6151
|
this.prevMessageHashes.clear();
|
|
5971
6152
|
this.activeModal = null;
|
|
5972
|
-
this.currentModel = "";
|
|
5973
|
-
this.currentMode = "";
|
|
5974
6153
|
this.controlValues = {};
|
|
5975
6154
|
this.currentStatus = "idle";
|
|
5976
6155
|
this.chatId = null;
|
|
@@ -6106,6 +6285,10 @@ var IdeProviderInstance = class {
|
|
|
6106
6285
|
for (const ext of this.extensions.values()) {
|
|
6107
6286
|
extensionStates.push(ext.getState());
|
|
6108
6287
|
}
|
|
6288
|
+
const surface = resolveProviderStateSurface({
|
|
6289
|
+
summaryMetadata: this.cachedChat?.summaryMetadata,
|
|
6290
|
+
controlValues: this.cachedChat?.controlValues
|
|
6291
|
+
});
|
|
6109
6292
|
return {
|
|
6110
6293
|
type: this.type,
|
|
6111
6294
|
name: this.provider.name,
|
|
@@ -6122,11 +6305,9 @@ var IdeProviderInstance = class {
|
|
|
6122
6305
|
workspace: this.workspace || null,
|
|
6123
6306
|
extensions: extensionStates,
|
|
6124
6307
|
cdpConnected: cdp?.isConnected || false,
|
|
6125
|
-
|
|
6126
|
-
currentPlan: this.cachedChat?.mode || void 0,
|
|
6127
|
-
currentAutoApprove: this.cachedChat?.autoApprove || void 0,
|
|
6128
|
-
controlValues: this.cachedChat?.controlValues || void 0,
|
|
6308
|
+
controlValues: surface.controlValues,
|
|
6129
6309
|
providerControls: this.provider.controls,
|
|
6310
|
+
summaryMetadata: surface.summaryMetadata,
|
|
6130
6311
|
instanceId: this.instanceId,
|
|
6131
6312
|
lastUpdated: Date.now(),
|
|
6132
6313
|
settings: this.settings,
|
|
@@ -6298,8 +6479,13 @@ var IdeProviderInstance = class {
|
|
|
6298
6479
|
chat.messages = messages.filter((m) => !hiddenKinds.has(m.kind || ""));
|
|
6299
6480
|
}
|
|
6300
6481
|
}
|
|
6301
|
-
const
|
|
6302
|
-
|
|
6482
|
+
const patchedState = mergeProviderPatchState({
|
|
6483
|
+
providerControls: this.provider.controls,
|
|
6484
|
+
data: chat,
|
|
6485
|
+
mergeWithCurrent: false
|
|
6486
|
+
});
|
|
6487
|
+
chat.controlValues = Object.keys(patchedState.controlValues).length > 0 ? patchedState.controlValues : void 0;
|
|
6488
|
+
chat.summaryMetadata = patchedState.summaryMetadata;
|
|
6303
6489
|
this.cachedChat = { ...chat, activeModal };
|
|
6304
6490
|
this.detectAgentTransitions(chat, now);
|
|
6305
6491
|
const persistedMessages = chat.messages || messages;
|
|
@@ -6386,14 +6572,18 @@ var IdeProviderInstance = class {
|
|
|
6386
6572
|
}
|
|
6387
6573
|
applyProviderResponse(data, options) {
|
|
6388
6574
|
if (!data || typeof data !== "object") return;
|
|
6389
|
-
const
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6575
|
+
const patchedState = mergeProviderPatchState({
|
|
6576
|
+
providerControls: this.provider.controls,
|
|
6577
|
+
data,
|
|
6578
|
+
currentControlValues: this.cachedChat?.controlValues,
|
|
6579
|
+
currentSummaryMetadata: this.cachedChat?.summaryMetadata
|
|
6580
|
+
});
|
|
6581
|
+
this.cachedChat = {
|
|
6582
|
+
...this.cachedChat || {},
|
|
6583
|
+
...data,
|
|
6584
|
+
controlValues: Object.keys(patchedState.controlValues).length > 0 ? patchedState.controlValues : void 0,
|
|
6585
|
+
summaryMetadata: patchedState.summaryMetadata
|
|
6586
|
+
};
|
|
6397
6587
|
const effects = normalizeProviderEffects(data);
|
|
6398
6588
|
for (const effect of effects) {
|
|
6399
6589
|
const effectWhen = effect.when || "immediate";
|
|
@@ -7176,6 +7366,8 @@ var ACP_SESSION_CAPABILITIES = [
|
|
|
7176
7366
|
function buildIdeWorkspaceSession(state, cdpManagers, options) {
|
|
7177
7367
|
const profile = options.profile || "full";
|
|
7178
7368
|
const activeChat = normalizeActiveChatData(state.activeChat, getActiveChatOptions(profile));
|
|
7369
|
+
const summaryMetadata = normalizeProviderSummaryMetadata(state.summaryMetadata);
|
|
7370
|
+
const controlValues = normalizeProviderStateControlValues(state.controlValues);
|
|
7179
7371
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
7180
7372
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
7181
7373
|
const title = activeChat?.title || state.name;
|
|
@@ -7192,13 +7384,11 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
|
|
|
7192
7384
|
title,
|
|
7193
7385
|
...includeSessionMetadata && { workspace: state.workspace || null },
|
|
7194
7386
|
activeChat,
|
|
7387
|
+
...summaryMetadata && { summaryMetadata },
|
|
7195
7388
|
...includeSessionMetadata && { capabilities: IDE_SESSION_CAPABILITIES },
|
|
7196
7389
|
cdpConnected: state.cdpConnected ?? isCdpConnected(cdpManagers, state.type),
|
|
7197
|
-
currentModel: state.currentModel,
|
|
7198
|
-
currentPlan: state.currentPlan,
|
|
7199
|
-
currentAutoApprove: state.currentAutoApprove,
|
|
7200
7390
|
...includeSessionControls && {
|
|
7201
|
-
controlValues
|
|
7391
|
+
...controlValues && { controlValues },
|
|
7202
7392
|
providerControls: state.providerControls
|
|
7203
7393
|
},
|
|
7204
7394
|
errorMessage: state.errorMessage,
|
|
@@ -7209,6 +7399,8 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
|
|
|
7209
7399
|
function buildExtensionAgentSession(parent, ext, options) {
|
|
7210
7400
|
const profile = options.profile || "full";
|
|
7211
7401
|
const activeChat = normalizeActiveChatData(ext.activeChat, getActiveChatOptions(profile));
|
|
7402
|
+
const summaryMetadata = normalizeProviderSummaryMetadata(ext.summaryMetadata);
|
|
7403
|
+
const controlValues = normalizeProviderStateControlValues(ext.controlValues);
|
|
7212
7404
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
7213
7405
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
7214
7406
|
return {
|
|
@@ -7224,11 +7416,10 @@ function buildExtensionAgentSession(parent, ext, options) {
|
|
|
7224
7416
|
title: activeChat?.title || ext.name,
|
|
7225
7417
|
...includeSessionMetadata && { workspace: parent.workspace || null },
|
|
7226
7418
|
activeChat,
|
|
7419
|
+
...summaryMetadata && { summaryMetadata },
|
|
7227
7420
|
...includeSessionMetadata && { capabilities: EXTENSION_SESSION_CAPABILITIES },
|
|
7228
|
-
currentModel: ext.currentModel,
|
|
7229
|
-
currentPlan: ext.currentPlan,
|
|
7230
7421
|
...includeSessionControls && {
|
|
7231
|
-
controlValues
|
|
7422
|
+
...controlValues && { controlValues },
|
|
7232
7423
|
providerControls: ext.providerControls
|
|
7233
7424
|
},
|
|
7234
7425
|
errorMessage: ext.errorMessage,
|
|
@@ -7239,6 +7430,8 @@ function buildExtensionAgentSession(parent, ext, options) {
|
|
|
7239
7430
|
function buildCliSession(state, options) {
|
|
7240
7431
|
const profile = options.profile || "full";
|
|
7241
7432
|
const activeChat = normalizeActiveChatData(state.activeChat, getActiveChatOptions(profile));
|
|
7433
|
+
const summaryMetadata = normalizeProviderSummaryMetadata(state.summaryMetadata);
|
|
7434
|
+
const controlValues = normalizeProviderStateControlValues(state.controlValues);
|
|
7242
7435
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
7243
7436
|
const includeRuntimeMetadata = shouldIncludeRuntimeMetadata(profile);
|
|
7244
7437
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
@@ -7265,11 +7458,12 @@ function buildCliSession(state, options) {
|
|
|
7265
7458
|
mode: state.mode,
|
|
7266
7459
|
resume: state.resume,
|
|
7267
7460
|
activeChat,
|
|
7461
|
+
...summaryMetadata && { summaryMetadata },
|
|
7268
7462
|
...includeSessionMetadata && {
|
|
7269
7463
|
capabilities: state.mode === "terminal" ? PTY_SESSION_CAPABILITIES : CLI_CHAT_SESSION_CAPABILITIES
|
|
7270
7464
|
},
|
|
7271
7465
|
...includeSessionControls && {
|
|
7272
|
-
controlValues
|
|
7466
|
+
...controlValues && { controlValues },
|
|
7273
7467
|
providerControls: state.providerControls
|
|
7274
7468
|
},
|
|
7275
7469
|
errorMessage: state.errorMessage,
|
|
@@ -7280,6 +7474,8 @@ function buildCliSession(state, options) {
|
|
|
7280
7474
|
function buildAcpSession(state, options) {
|
|
7281
7475
|
const profile = options.profile || "full";
|
|
7282
7476
|
const activeChat = normalizeActiveChatData(state.activeChat, getActiveChatOptions(profile));
|
|
7477
|
+
const summaryMetadata = normalizeProviderSummaryMetadata(state.summaryMetadata);
|
|
7478
|
+
const controlValues = normalizeProviderStateControlValues(state.controlValues);
|
|
7283
7479
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
7284
7480
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
7285
7481
|
return {
|
|
@@ -7295,13 +7491,10 @@ function buildAcpSession(state, options) {
|
|
|
7295
7491
|
title: activeChat?.title || state.name,
|
|
7296
7492
|
...includeSessionMetadata && { workspace: state.workspace || null },
|
|
7297
7493
|
activeChat,
|
|
7494
|
+
...summaryMetadata && { summaryMetadata },
|
|
7298
7495
|
...includeSessionMetadata && { capabilities: ACP_SESSION_CAPABILITIES },
|
|
7299
|
-
currentModel: state.currentModel,
|
|
7300
|
-
currentPlan: state.currentPlan,
|
|
7301
7496
|
...includeSessionControls && {
|
|
7302
|
-
|
|
7303
|
-
acpModes: state.acpModes,
|
|
7304
|
-
controlValues: state.controlValues,
|
|
7497
|
+
...controlValues && { controlValues },
|
|
7305
7498
|
providerControls: state.providerControls
|
|
7306
7499
|
},
|
|
7307
7500
|
errorMessage: state.errorMessage,
|
|
@@ -7993,7 +8186,7 @@ function getStateLastSignature(state) {
|
|
|
7993
8186
|
async function getStableExtensionBaseline(h) {
|
|
7994
8187
|
const first = await readExtensionChatState(h);
|
|
7995
8188
|
if (getStateMessageCount(first) > 0 || getStateLastSignature(first)) return first;
|
|
7996
|
-
await new Promise((
|
|
8189
|
+
await new Promise((resolve11) => setTimeout(resolve11, 150));
|
|
7997
8190
|
const second = await readExtensionChatState(h);
|
|
7998
8191
|
return getStateMessageCount(second) >= getStateMessageCount(first) ? second : first;
|
|
7999
8192
|
}
|
|
@@ -8001,7 +8194,7 @@ async function verifyExtensionSendObserved(h, before) {
|
|
|
8001
8194
|
const beforeCount = getStateMessageCount(before);
|
|
8002
8195
|
const beforeSignature = getStateLastSignature(before);
|
|
8003
8196
|
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
8004
|
-
await new Promise((
|
|
8197
|
+
await new Promise((resolve11) => setTimeout(resolve11, 250));
|
|
8005
8198
|
const state = await readExtensionChatState(h);
|
|
8006
8199
|
if (state?.status === "waiting_approval") return true;
|
|
8007
8200
|
const afterCount = getStateMessageCount(state);
|
|
@@ -9193,6 +9386,30 @@ async function handleFileListBrowse(h, args) {
|
|
|
9193
9386
|
}
|
|
9194
9387
|
}
|
|
9195
9388
|
|
|
9389
|
+
// src/commands/stream-commands.ts
|
|
9390
|
+
init_config();
|
|
9391
|
+
|
|
9392
|
+
// src/config/provider-source-config.ts
|
|
9393
|
+
function normalizeProviderDir(value) {
|
|
9394
|
+
if (typeof value !== "string") return void 0;
|
|
9395
|
+
const trimmed = value.trim();
|
|
9396
|
+
return trimmed ? trimmed : void 0;
|
|
9397
|
+
}
|
|
9398
|
+
function parseProviderSourceConfigUpdate(input) {
|
|
9399
|
+
const updates = {};
|
|
9400
|
+
if (Object.prototype.hasOwnProperty.call(input, "providerSourceMode")) {
|
|
9401
|
+
const { providerSourceMode } = input;
|
|
9402
|
+
if (providerSourceMode !== "normal" && providerSourceMode !== "no-upstream") {
|
|
9403
|
+
return { ok: false, error: "providerSourceMode must be 'normal' or 'no-upstream'" };
|
|
9404
|
+
}
|
|
9405
|
+
updates.providerSourceMode = providerSourceMode;
|
|
9406
|
+
}
|
|
9407
|
+
if (Object.prototype.hasOwnProperty.call(input, "providerDir")) {
|
|
9408
|
+
updates.providerDir = normalizeProviderDir(input.providerDir);
|
|
9409
|
+
}
|
|
9410
|
+
return { ok: true, updates };
|
|
9411
|
+
}
|
|
9412
|
+
|
|
9196
9413
|
// src/providers/cli-script-results.ts
|
|
9197
9414
|
function parseCliScriptResult(result) {
|
|
9198
9415
|
if (typeof result === "string") {
|
|
@@ -9305,8 +9522,49 @@ async function handleSetProviderSetting(h, args) {
|
|
|
9305
9522
|
}
|
|
9306
9523
|
return { success: false, error: `Failed to set ${providerType}.${key} \u2014 invalid key, value, or not a public setting` };
|
|
9307
9524
|
}
|
|
9308
|
-
function
|
|
9525
|
+
function handleGetProviderSourceConfig(h, _args) {
|
|
9526
|
+
const loader = h.ctx.providerLoader;
|
|
9527
|
+
if (!loader) return { success: false, error: "providerLoader not available" };
|
|
9528
|
+
return { success: true, ...loader.getSourceConfig() };
|
|
9529
|
+
}
|
|
9530
|
+
async function handleSetProviderSourceConfig(h, args) {
|
|
9531
|
+
const loader = h.ctx.providerLoader;
|
|
9532
|
+
if (!loader) return { success: false, error: "providerLoader not available" };
|
|
9533
|
+
const parsed = parseProviderSourceConfigUpdate(args || {});
|
|
9534
|
+
if ("error" in parsed) {
|
|
9535
|
+
return { success: false, error: parsed.error };
|
|
9536
|
+
}
|
|
9537
|
+
const currentConfig2 = loadConfig();
|
|
9538
|
+
const nextConfig = {
|
|
9539
|
+
...currentConfig2,
|
|
9540
|
+
...parsed.updates.providerSourceMode ? { providerSourceMode: parsed.updates.providerSourceMode } : {},
|
|
9541
|
+
...Object.prototype.hasOwnProperty.call(parsed.updates, "providerDir") ? { providerDir: parsed.updates.providerDir } : {}
|
|
9542
|
+
};
|
|
9543
|
+
saveConfig(nextConfig);
|
|
9544
|
+
const sourceConfig = loader.applySourceConfig({
|
|
9545
|
+
sourceMode: nextConfig.providerSourceMode,
|
|
9546
|
+
userDir: Object.prototype.hasOwnProperty.call(parsed.updates, "providerDir") ? parsed.updates.providerDir : loader.getSourceConfig().explicitProviderDir || void 0
|
|
9547
|
+
});
|
|
9548
|
+
loader.reload();
|
|
9549
|
+
loader.registerToDetector();
|
|
9550
|
+
await h.ctx.onProviderSourceConfigChanged?.();
|
|
9551
|
+
LOG.info(
|
|
9552
|
+
"Command",
|
|
9553
|
+
`[set_provider_source_config] mode=${sourceConfig.sourceMode} explicitProviderDir=${sourceConfig.explicitProviderDir || "-"} userDir=${sourceConfig.userDir}`
|
|
9554
|
+
);
|
|
9555
|
+
return { success: true, reloaded: true, ...sourceConfig };
|
|
9556
|
+
}
|
|
9557
|
+
function normalizeProviderScriptArgs(args, scriptName) {
|
|
9309
9558
|
const normalizedArgs = { ...args || {} };
|
|
9559
|
+
const normalizedScriptName = String(scriptName || "").toLowerCase();
|
|
9560
|
+
if (Object.prototype.hasOwnProperty.call(normalizedArgs, "value")) {
|
|
9561
|
+
if (normalizedArgs.model === void 0 && (normalizedScriptName === "setmodel" || normalizedScriptName === "setmodelgui" || normalizedScriptName === "webviewsetmodel")) {
|
|
9562
|
+
normalizedArgs.model = normalizedArgs.value;
|
|
9563
|
+
}
|
|
9564
|
+
if (normalizedArgs.mode === void 0 && (normalizedScriptName === "setmode" || normalizedScriptName === "webviewsetmode")) {
|
|
9565
|
+
normalizedArgs.mode = normalizedArgs.value;
|
|
9566
|
+
}
|
|
9567
|
+
}
|
|
9310
9568
|
for (const key of ["mode", "model", "message", "action", "button", "text", "sessionId", "value"]) {
|
|
9311
9569
|
if (key in normalizedArgs && !(key.toUpperCase() in normalizedArgs)) {
|
|
9312
9570
|
normalizedArgs[key.toUpperCase()] = normalizedArgs[key];
|
|
@@ -9352,7 +9610,7 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
9352
9610
|
if (!provider.scripts?.[actualScriptName]) {
|
|
9353
9611
|
return { success: false, error: `Script '${actualScriptName}' not available for ${resolvedProviderType}` };
|
|
9354
9612
|
}
|
|
9355
|
-
const normalizedArgs = normalizeProviderScriptArgs(args);
|
|
9613
|
+
const normalizedArgs = normalizeProviderScriptArgs(args, actualScriptName);
|
|
9356
9614
|
if (provider.category === "cli") {
|
|
9357
9615
|
const adapter = h.getCliAdapter(args?.targetSessionId || resolvedProviderType);
|
|
9358
9616
|
if (!adapter?.invokeScript) {
|
|
@@ -9998,6 +10256,10 @@ var DaemonCommandHandler = class {
|
|
|
9998
10256
|
return handleGetProviderSettings(this, args);
|
|
9999
10257
|
case "set_provider_setting":
|
|
10000
10258
|
return handleSetProviderSetting(this, args);
|
|
10259
|
+
case "get_provider_source_config":
|
|
10260
|
+
return handleGetProviderSourceConfig(this, args);
|
|
10261
|
+
case "set_provider_source_config":
|
|
10262
|
+
return handleSetProviderSourceConfig(this, args);
|
|
10001
10263
|
// ─── IDE Extension Settings (stream-commands.ts) ──────────
|
|
10002
10264
|
case "get_ide_extensions":
|
|
10003
10265
|
return handleGetIdeExtensions(this, args);
|
|
@@ -10037,7 +10299,7 @@ var DaemonCommandHandler = class {
|
|
|
10037
10299
|
try {
|
|
10038
10300
|
const http3 = await import("http");
|
|
10039
10301
|
const postData = JSON.stringify(body);
|
|
10040
|
-
const result = await new Promise((
|
|
10302
|
+
const result = await new Promise((resolve11, reject) => {
|
|
10041
10303
|
const req = http3.request({
|
|
10042
10304
|
hostname: "127.0.0.1",
|
|
10043
10305
|
port: 19280,
|
|
@@ -10049,9 +10311,9 @@ var DaemonCommandHandler = class {
|
|
|
10049
10311
|
res.on("data", (chunk) => data += chunk);
|
|
10050
10312
|
res.on("end", () => {
|
|
10051
10313
|
try {
|
|
10052
|
-
|
|
10314
|
+
resolve11(JSON.parse(data));
|
|
10053
10315
|
} catch {
|
|
10054
|
-
|
|
10316
|
+
resolve11({ raw: data });
|
|
10055
10317
|
}
|
|
10056
10318
|
});
|
|
10057
10319
|
});
|
|
@@ -10069,15 +10331,15 @@ var DaemonCommandHandler = class {
|
|
|
10069
10331
|
if (!providerType) return { success: false, error: "providerType required" };
|
|
10070
10332
|
try {
|
|
10071
10333
|
const http3 = await import("http");
|
|
10072
|
-
const result = await new Promise((
|
|
10334
|
+
const result = await new Promise((resolve11, reject) => {
|
|
10073
10335
|
http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
|
|
10074
10336
|
let data = "";
|
|
10075
10337
|
res.on("data", (chunk) => data += chunk);
|
|
10076
10338
|
res.on("end", () => {
|
|
10077
10339
|
try {
|
|
10078
|
-
|
|
10340
|
+
resolve11(JSON.parse(data));
|
|
10079
10341
|
} catch {
|
|
10080
|
-
|
|
10342
|
+
resolve11({ raw: data });
|
|
10081
10343
|
}
|
|
10082
10344
|
});
|
|
10083
10345
|
}).on("error", reject);
|
|
@@ -10091,7 +10353,7 @@ var DaemonCommandHandler = class {
|
|
|
10091
10353
|
try {
|
|
10092
10354
|
const http3 = await import("http");
|
|
10093
10355
|
const postData = JSON.stringify(args || {});
|
|
10094
|
-
const result = await new Promise((
|
|
10356
|
+
const result = await new Promise((resolve11, reject) => {
|
|
10095
10357
|
const req = http3.request({
|
|
10096
10358
|
hostname: "127.0.0.1",
|
|
10097
10359
|
port: 19280,
|
|
@@ -10103,9 +10365,9 @@ var DaemonCommandHandler = class {
|
|
|
10103
10365
|
res.on("data", (chunk) => data += chunk);
|
|
10104
10366
|
res.on("end", () => {
|
|
10105
10367
|
try {
|
|
10106
|
-
|
|
10368
|
+
resolve11(JSON.parse(data));
|
|
10107
10369
|
} catch {
|
|
10108
|
-
|
|
10370
|
+
resolve11({ raw: data });
|
|
10109
10371
|
}
|
|
10110
10372
|
});
|
|
10111
10373
|
});
|
|
@@ -10155,6 +10417,9 @@ function getForcedNewSessionScriptName(provider, launchMode) {
|
|
|
10155
10417
|
const controls = Array.isArray(provider.controls) ? provider.controls : [];
|
|
10156
10418
|
for (const control of controls) {
|
|
10157
10419
|
if (control?.type !== "action") continue;
|
|
10420
|
+
if (typeof control?.confirmTitle === "string" && control.confirmTitle.trim()) continue;
|
|
10421
|
+
if (typeof control?.confirmMessage === "string" && control.confirmMessage.trim()) continue;
|
|
10422
|
+
if (typeof control?.confirmLabel === "string" && control.confirmLabel.trim()) continue;
|
|
10158
10423
|
const invokeScript = typeof control?.invokeScript === "string" ? control.invokeScript.trim() : "";
|
|
10159
10424
|
if (!invokeScript) continue;
|
|
10160
10425
|
const controlId = typeof control?.id === "string" ? control.id.trim() : "";
|
|
@@ -10164,6 +10429,20 @@ function getForcedNewSessionScriptName(provider, launchMode) {
|
|
|
10164
10429
|
}
|
|
10165
10430
|
return null;
|
|
10166
10431
|
}
|
|
10432
|
+
async function waitForCliAdapterReady(adapter, options) {
|
|
10433
|
+
const timeoutMs = Math.max(100, options?.timeoutMs ?? 15e3);
|
|
10434
|
+
const pollMs = Math.max(10, options?.pollMs ?? 50);
|
|
10435
|
+
const deadline = Date.now() + timeoutMs;
|
|
10436
|
+
while (Date.now() < deadline) {
|
|
10437
|
+
if (adapter?.isReady?.()) return;
|
|
10438
|
+
const status = adapter?.getStatus?.()?.status;
|
|
10439
|
+
if (status === "stopped") {
|
|
10440
|
+
throw new Error("CLI runtime stopped before it became ready");
|
|
10441
|
+
}
|
|
10442
|
+
await new Promise((resolve11) => setTimeout(resolve11, pollMs));
|
|
10443
|
+
}
|
|
10444
|
+
throw new Error(`CLI runtime did not become ready within ${timeoutMs}ms`);
|
|
10445
|
+
}
|
|
10167
10446
|
var CliProviderInstance = class {
|
|
10168
10447
|
constructor(provider, workingDir, cliArgs = [], instanceId, transportFactory, options) {
|
|
10169
10448
|
this.provider = provider;
|
|
@@ -10192,6 +10471,7 @@ var CliProviderInstance = class {
|
|
|
10192
10471
|
generatingDebouncePending = null;
|
|
10193
10472
|
lastApprovalEventAt = 0;
|
|
10194
10473
|
controlValues = {};
|
|
10474
|
+
summaryMetadata = void 0;
|
|
10195
10475
|
appliedEffectKeys = /* @__PURE__ */ new Set();
|
|
10196
10476
|
historyWriter;
|
|
10197
10477
|
runtimeMessages = [];
|
|
@@ -10334,13 +10614,7 @@ var CliProviderInstance = class {
|
|
|
10334
10614
|
if (historyMessageCount !== null) {
|
|
10335
10615
|
parsedMessages = historyMessageCount > 0 ? parsedMessages.slice(-historyMessageCount) : [];
|
|
10336
10616
|
}
|
|
10337
|
-
const controlValues = extractProviderControlValues(this.provider.controls, parsedStatus);
|
|
10338
|
-
if (controlValues) {
|
|
10339
|
-
this.controlValues = { ...this.controlValues, ...controlValues };
|
|
10340
|
-
}
|
|
10341
10617
|
const mergedMessages = this.mergeConversationMessages(parsedMessages);
|
|
10342
|
-
const currentModel = typeof parsedStatus?.model === "string" && parsedStatus.model.trim() ? parsedStatus.model.trim() : typeof this.controlValues.model === "string" && this.controlValues.model.trim() ? this.controlValues.model.trim() : void 0;
|
|
10343
|
-
const currentPlan = typeof parsedStatus?.mode === "string" && parsedStatus.mode.trim() ? parsedStatus.mode.trim() : typeof this.controlValues.mode === "string" && this.controlValues.mode.trim() ? this.controlValues.mode.trim() : void 0;
|
|
10344
10618
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
10345
10619
|
if (parsedMessages.length > 0) {
|
|
10346
10620
|
const shouldSkipReplayPersist = this.suppressIdleHistoryReplay && adapterStatus.status === "idle" && parsedStatus?.status === "idle";
|
|
@@ -10362,6 +10636,10 @@ var CliProviderInstance = class {
|
|
|
10362
10636
|
}
|
|
10363
10637
|
}
|
|
10364
10638
|
this.applyProviderResponse(parsedStatus, { phase: "immediate" });
|
|
10639
|
+
const surface = resolveProviderStateSurface({
|
|
10640
|
+
summaryMetadata: this.summaryMetadata,
|
|
10641
|
+
controlValues: this.controlValues
|
|
10642
|
+
});
|
|
10365
10643
|
return {
|
|
10366
10644
|
type: this.type,
|
|
10367
10645
|
name: this.provider.name,
|
|
@@ -10377,8 +10655,6 @@ var CliProviderInstance = class {
|
|
|
10377
10655
|
inputContent: ""
|
|
10378
10656
|
},
|
|
10379
10657
|
workspace: this.workingDir,
|
|
10380
|
-
currentModel,
|
|
10381
|
-
currentPlan,
|
|
10382
10658
|
instanceId: this.instanceId,
|
|
10383
10659
|
providerSessionId: this.providerSessionId,
|
|
10384
10660
|
lastUpdated: Date.now(),
|
|
@@ -10393,8 +10669,9 @@ var CliProviderInstance = class {
|
|
|
10393
10669
|
attachedClients: runtime.attachedClients || []
|
|
10394
10670
|
} : void 0,
|
|
10395
10671
|
resume: this.provider.resume,
|
|
10396
|
-
controlValues:
|
|
10397
|
-
providerControls: this.provider.controls
|
|
10672
|
+
controlValues: surface.controlValues,
|
|
10673
|
+
providerControls: this.provider.controls,
|
|
10674
|
+
summaryMetadata: surface.summaryMetadata
|
|
10398
10675
|
};
|
|
10399
10676
|
}
|
|
10400
10677
|
setPresentationMode(mode) {
|
|
@@ -10442,6 +10719,7 @@ var CliProviderInstance = class {
|
|
|
10442
10719
|
const scriptName = getForcedNewSessionScriptName(this.provider, this.launchMode);
|
|
10443
10720
|
if (!scriptName) return;
|
|
10444
10721
|
LOG.info("CLI", `[${this.type}] forcing fresh session launch via script: ${scriptName}`);
|
|
10722
|
+
await waitForCliAdapterReady(this.adapter);
|
|
10445
10723
|
const raw = await this.adapter.invokeScript(scriptName, {});
|
|
10446
10724
|
const parsed = parseCliScriptResult(raw);
|
|
10447
10725
|
if (!parsed.success) {
|
|
@@ -10597,10 +10875,14 @@ var CliProviderInstance = class {
|
|
|
10597
10875
|
this.suppressIdleHistoryReplay = false;
|
|
10598
10876
|
this.adapter.clearHistory();
|
|
10599
10877
|
}
|
|
10600
|
-
const
|
|
10601
|
-
|
|
10602
|
-
|
|
10603
|
-
|
|
10878
|
+
const patchedState = mergeProviderPatchState({
|
|
10879
|
+
providerControls: this.provider.controls,
|
|
10880
|
+
data,
|
|
10881
|
+
currentControlValues: this.controlValues,
|
|
10882
|
+
currentSummaryMetadata: this.summaryMetadata
|
|
10883
|
+
});
|
|
10884
|
+
this.controlValues = patchedState.controlValues;
|
|
10885
|
+
this.summaryMetadata = patchedState.summaryMetadata;
|
|
10604
10886
|
const effects = normalizeProviderEffects(data);
|
|
10605
10887
|
for (const effect of effects) {
|
|
10606
10888
|
const effectWhen = effect.when || "immediate";
|
|
@@ -10791,6 +11073,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
10791
11073
|
const previousProviderSessionId = this.providerSessionId;
|
|
10792
11074
|
this.providerSessionId = nextSessionId;
|
|
10793
11075
|
this.historyWriter.promoteHistorySession(this.type, previousHistorySessionId, nextSessionId);
|
|
11076
|
+
this.historyWriter.writeSessionStart(this.type, nextSessionId, this.workingDir, this.instanceId);
|
|
10794
11077
|
this.adapter.updateRuntimeMeta({ providerSessionId: nextSessionId });
|
|
10795
11078
|
this.onProviderSessionResolved?.({
|
|
10796
11079
|
instanceId: this.instanceId,
|
|
@@ -10970,8 +11253,7 @@ var AcpProviderInstance = class {
|
|
|
10970
11253
|
lastStatus = "starting";
|
|
10971
11254
|
generatingStartedAt = 0;
|
|
10972
11255
|
agentCapabilities = {};
|
|
10973
|
-
|
|
10974
|
-
currentMode;
|
|
11256
|
+
currentSelections = {};
|
|
10975
11257
|
activeToolCalls = [];
|
|
10976
11258
|
stopReason = null;
|
|
10977
11259
|
partialContent = "";
|
|
@@ -11051,8 +11333,6 @@ var AcpProviderInstance = class {
|
|
|
11051
11333
|
inputContent: ""
|
|
11052
11334
|
},
|
|
11053
11335
|
workspace: this.workingDir,
|
|
11054
|
-
currentModel: this.currentModel,
|
|
11055
|
-
currentPlan: this.currentMode,
|
|
11056
11336
|
instanceId: this.instanceId,
|
|
11057
11337
|
lastUpdated: Date.now(),
|
|
11058
11338
|
settings: this.settings,
|
|
@@ -11063,11 +11343,9 @@ var AcpProviderInstance = class {
|
|
|
11063
11343
|
// Error details for dashboard display
|
|
11064
11344
|
errorMessage: this.errorMessage || void 0,
|
|
11065
11345
|
errorReason: this.errorReason || void 0,
|
|
11066
|
-
controlValues:
|
|
11067
|
-
|
|
11068
|
-
|
|
11069
|
-
},
|
|
11070
|
-
providerControls: this.provider.controls
|
|
11346
|
+
controlValues: this.getSelectionControlValues(),
|
|
11347
|
+
providerControls: this.provider.controls,
|
|
11348
|
+
summaryMetadata: this.buildSelectionSummaryMetadata()
|
|
11071
11349
|
};
|
|
11072
11350
|
}
|
|
11073
11351
|
onEvent(event, data) {
|
|
@@ -11101,6 +11379,54 @@ var AcpProviderInstance = class {
|
|
|
11101
11379
|
getInstanceId() {
|
|
11102
11380
|
return this.instanceId;
|
|
11103
11381
|
}
|
|
11382
|
+
resolveConfigOptionLabel(category, value) {
|
|
11383
|
+
if (!value) return void 0;
|
|
11384
|
+
const option = this.configOptions.find((entry) => entry.category === category);
|
|
11385
|
+
return option?.options.find((candidate) => candidate.value === value)?.name || value;
|
|
11386
|
+
}
|
|
11387
|
+
resolveModeLabel(modeId) {
|
|
11388
|
+
if (!modeId) return void 0;
|
|
11389
|
+
return this.availableModes.find((mode) => mode.id === modeId)?.name || modeId;
|
|
11390
|
+
}
|
|
11391
|
+
getCurrentSelection(category) {
|
|
11392
|
+
return this.currentSelections[category];
|
|
11393
|
+
}
|
|
11394
|
+
setCurrentSelection(category, value) {
|
|
11395
|
+
const normalized = typeof value === "string" ? value.trim() : "";
|
|
11396
|
+
if (normalized) {
|
|
11397
|
+
this.currentSelections[category] = normalized;
|
|
11398
|
+
return;
|
|
11399
|
+
}
|
|
11400
|
+
delete this.currentSelections[category];
|
|
11401
|
+
}
|
|
11402
|
+
getSelectionControlValues() {
|
|
11403
|
+
const model = this.getCurrentSelection("model");
|
|
11404
|
+
const mode = this.getCurrentSelection("mode");
|
|
11405
|
+
return {
|
|
11406
|
+
...model ? { model } : {},
|
|
11407
|
+
...mode ? { mode } : {}
|
|
11408
|
+
};
|
|
11409
|
+
}
|
|
11410
|
+
resolveSelectionLabel(category, value) {
|
|
11411
|
+
if (!value) return void 0;
|
|
11412
|
+
const configLabel = this.resolveConfigOptionLabel(category, value);
|
|
11413
|
+
if (configLabel && configLabel !== value) return configLabel;
|
|
11414
|
+
if (category === "mode") {
|
|
11415
|
+
const modeLabel = this.resolveModeLabel(value);
|
|
11416
|
+
if (modeLabel) return modeLabel;
|
|
11417
|
+
}
|
|
11418
|
+
return configLabel || value;
|
|
11419
|
+
}
|
|
11420
|
+
buildSelectionSummaryMetadata() {
|
|
11421
|
+
const model = this.getCurrentSelection("model");
|
|
11422
|
+
const mode = this.getCurrentSelection("mode");
|
|
11423
|
+
return buildLegacyModelModeSummaryMetadata({
|
|
11424
|
+
model,
|
|
11425
|
+
mode,
|
|
11426
|
+
modelLabel: this.resolveSelectionLabel("model", model),
|
|
11427
|
+
modeLabel: this.resolveSelectionLabel("mode", mode)
|
|
11428
|
+
});
|
|
11429
|
+
}
|
|
11104
11430
|
// ─── ACP Config Options & Modes ─────────────────────
|
|
11105
11431
|
parseConfigOptions(raw) {
|
|
11106
11432
|
if (!Array.isArray(raw)) return;
|
|
@@ -11132,12 +11458,14 @@ var AcpProviderInstance = class {
|
|
|
11132
11458
|
}
|
|
11133
11459
|
}
|
|
11134
11460
|
this.configOptions.push({ category, configId, currentValue, options: flatOptions });
|
|
11135
|
-
if (category === "model"
|
|
11461
|
+
if (category === "model" || category === "mode") {
|
|
11462
|
+
this.setCurrentSelection(category, currentValue);
|
|
11463
|
+
}
|
|
11136
11464
|
}
|
|
11137
11465
|
}
|
|
11138
11466
|
parseModes(raw) {
|
|
11139
11467
|
if (!raw) return;
|
|
11140
|
-
|
|
11468
|
+
this.setCurrentSelection("mode", raw.currentModeId);
|
|
11141
11469
|
if (Array.isArray(raw.availableModes)) {
|
|
11142
11470
|
this.availableModes = raw.availableModes.map((m) => ({
|
|
11143
11471
|
id: m.id,
|
|
@@ -11156,8 +11484,7 @@ var AcpProviderInstance = class {
|
|
|
11156
11484
|
if (this.useStaticConfig) {
|
|
11157
11485
|
opt.currentValue = value;
|
|
11158
11486
|
this.selectedConfig[opt.configId] = value;
|
|
11159
|
-
if (category === "model") this.
|
|
11160
|
-
if (category === "mode") this.currentMode = value;
|
|
11487
|
+
if (category === "model" || category === "mode") this.setCurrentSelection(category, value);
|
|
11161
11488
|
this.log.info(`[${this.type}] Static config ${category} set to: ${value} \u2014 restarting agent`);
|
|
11162
11489
|
await this.restartWithNewConfig();
|
|
11163
11490
|
return;
|
|
@@ -11175,7 +11502,7 @@ var AcpProviderInstance = class {
|
|
|
11175
11502
|
value
|
|
11176
11503
|
});
|
|
11177
11504
|
opt.currentValue = value;
|
|
11178
|
-
if (category === "model") this.
|
|
11505
|
+
if (category === "model" || category === "mode") this.setCurrentSelection(category, value);
|
|
11179
11506
|
if (result?.configOptions) this.parseConfigOptions(result.configOptions);
|
|
11180
11507
|
this.log.info(`[${this.type}] Config ${category} set to: ${value} | response: ${JSON.stringify(result)?.slice(0, 300)}`);
|
|
11181
11508
|
} catch (e) {
|
|
@@ -11191,7 +11518,7 @@ var AcpProviderInstance = class {
|
|
|
11191
11518
|
opt.currentValue = modeId;
|
|
11192
11519
|
this.selectedConfig[opt.configId] = modeId;
|
|
11193
11520
|
}
|
|
11194
|
-
this.
|
|
11521
|
+
this.setCurrentSelection("mode", modeId);
|
|
11195
11522
|
this.log.info(`[${this.type}] Static mode set to: ${modeId} \u2014 restarting agent`);
|
|
11196
11523
|
await this.restartWithNewConfig();
|
|
11197
11524
|
return;
|
|
@@ -11206,7 +11533,7 @@ var AcpProviderInstance = class {
|
|
|
11206
11533
|
sessionId: this.sessionId,
|
|
11207
11534
|
modeId
|
|
11208
11535
|
});
|
|
11209
|
-
this.
|
|
11536
|
+
this.setCurrentSelection("mode", modeId);
|
|
11210
11537
|
this.log.info(`[${this.type}] Mode set to: ${modeId}`);
|
|
11211
11538
|
} catch (e) {
|
|
11212
11539
|
const message = e?.message || "Unknown ACP mode error";
|
|
@@ -11377,13 +11704,13 @@ var AcpProviderInstance = class {
|
|
|
11377
11704
|
}
|
|
11378
11705
|
this.currentStatus = "waiting_approval";
|
|
11379
11706
|
this.detectStatusTransition();
|
|
11380
|
-
const approved = await new Promise((
|
|
11381
|
-
this.permissionResolvers.push(
|
|
11707
|
+
const approved = await new Promise((resolve11) => {
|
|
11708
|
+
this.permissionResolvers.push(resolve11);
|
|
11382
11709
|
setTimeout(() => {
|
|
11383
|
-
const idx = this.permissionResolvers.indexOf(
|
|
11710
|
+
const idx = this.permissionResolvers.indexOf(resolve11);
|
|
11384
11711
|
if (idx >= 0) {
|
|
11385
11712
|
this.permissionResolvers.splice(idx, 1);
|
|
11386
|
-
|
|
11713
|
+
resolve11(false);
|
|
11387
11714
|
}
|
|
11388
11715
|
}, 3e5);
|
|
11389
11716
|
});
|
|
@@ -11464,8 +11791,8 @@ var AcpProviderInstance = class {
|
|
|
11464
11791
|
if (result?.modes) this.log.debug(`[${this.type}] modes: ${JSON.stringify(result.modes).slice(0, 300)}`);
|
|
11465
11792
|
this.parseConfigOptions(result?.configOptions);
|
|
11466
11793
|
this.parseModes(result?.modes);
|
|
11467
|
-
if (!this.
|
|
11468
|
-
this.
|
|
11794
|
+
if (!this.getCurrentSelection("model") && result?.models?.currentModelId) {
|
|
11795
|
+
this.setCurrentSelection("model", result.models.currentModelId);
|
|
11469
11796
|
}
|
|
11470
11797
|
if (this.configOptions.length === 0 && this.provider.staticConfigOptions?.length) {
|
|
11471
11798
|
this.useStaticConfig = true;
|
|
@@ -11479,13 +11806,16 @@ var AcpProviderInstance = class {
|
|
|
11479
11806
|
});
|
|
11480
11807
|
if (defaultVal) {
|
|
11481
11808
|
this.selectedConfig[sc.configId] = defaultVal;
|
|
11482
|
-
if (sc.category === "model"
|
|
11483
|
-
|
|
11809
|
+
if (sc.category === "model" || sc.category === "mode") {
|
|
11810
|
+
this.setCurrentSelection(sc.category, defaultVal);
|
|
11811
|
+
}
|
|
11484
11812
|
}
|
|
11485
11813
|
}
|
|
11486
11814
|
this.log.info(`[${this.type}] Using static configOptions (${this.configOptions.length} options)`);
|
|
11487
11815
|
}
|
|
11488
|
-
|
|
11816
|
+
const currentModel = this.getCurrentSelection("model");
|
|
11817
|
+
const currentMode = this.getCurrentSelection("mode");
|
|
11818
|
+
this.log.info(`[${this.type}] Session created: ${this.sessionId}${currentModel ? ` (model: ${currentModel})` : ""}${currentMode ? ` (mode: ${currentMode})` : ""}`);
|
|
11489
11819
|
if (this.configOptions.length > 0) {
|
|
11490
11820
|
this.log.info(`[${this.type}] Config options: ${this.configOptions.map((c) => `${c.category}(${c.options.length})`).join(", ")}`);
|
|
11491
11821
|
}
|
|
@@ -11660,7 +11990,7 @@ var AcpProviderInstance = class {
|
|
|
11660
11990
|
break;
|
|
11661
11991
|
}
|
|
11662
11992
|
case "current_mode_update": {
|
|
11663
|
-
this.
|
|
11993
|
+
this.setCurrentSelection("mode", update.currentModeId);
|
|
11664
11994
|
break;
|
|
11665
11995
|
}
|
|
11666
11996
|
case "config_option_update": {
|
|
@@ -11733,7 +12063,7 @@ var AcpProviderInstance = class {
|
|
|
11733
12063
|
this.detectStatusTransition();
|
|
11734
12064
|
}
|
|
11735
12065
|
if (params.model) {
|
|
11736
|
-
this.
|
|
12066
|
+
this.setCurrentSelection("model", params.model);
|
|
11737
12067
|
}
|
|
11738
12068
|
}
|
|
11739
12069
|
/** Map SDK ToolCallStatus to internal status */
|
|
@@ -12022,7 +12352,11 @@ var DaemonCliManager = class {
|
|
|
12022
12352
|
}
|
|
12023
12353
|
persistRecentActivity(entry) {
|
|
12024
12354
|
try {
|
|
12025
|
-
|
|
12355
|
+
const summaryMetadata = normalizeProviderSummaryMetadata(entry.summaryMetadata);
|
|
12356
|
+
let nextState = appendRecentActivity(loadState(), {
|
|
12357
|
+
...entry,
|
|
12358
|
+
summaryMetadata
|
|
12359
|
+
});
|
|
12026
12360
|
if (entry.providerSessionId && (entry.kind === "cli" || entry.kind === "acp")) {
|
|
12027
12361
|
nextState = upsertSavedProviderSession(nextState, {
|
|
12028
12362
|
kind: entry.kind,
|
|
@@ -12030,7 +12364,7 @@ var DaemonCliManager = class {
|
|
|
12030
12364
|
providerName: entry.providerName,
|
|
12031
12365
|
providerSessionId: entry.providerSessionId,
|
|
12032
12366
|
workspace: entry.workspace,
|
|
12033
|
-
|
|
12367
|
+
summaryMetadata,
|
|
12034
12368
|
title: entry.title
|
|
12035
12369
|
});
|
|
12036
12370
|
}
|
|
@@ -12220,7 +12554,7 @@ ${installInfo}`
|
|
|
12220
12554
|
providerType: normalizedType,
|
|
12221
12555
|
providerName: provider.displayName || provider.name || normalizedType,
|
|
12222
12556
|
workspace: resolvedDir,
|
|
12223
|
-
|
|
12557
|
+
summaryMetadata: buildLegacyModelModeSummaryMetadata({ model: initialModel }),
|
|
12224
12558
|
sessionId,
|
|
12225
12559
|
title: provider.displayName || provider.name || normalizedType
|
|
12226
12560
|
});
|
|
@@ -12322,7 +12656,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
12322
12656
|
providerName: provider?.displayName || provider?.name || normalizedType,
|
|
12323
12657
|
providerSessionId: sessionBinding.providerSessionId,
|
|
12324
12658
|
workspace: resolvedDir,
|
|
12325
|
-
|
|
12659
|
+
summaryMetadata: buildLegacyModelModeSummaryMetadata({ model: initialModel }),
|
|
12326
12660
|
sessionId: key,
|
|
12327
12661
|
title: provider?.displayName || provider?.name || normalizedType
|
|
12328
12662
|
});
|
|
@@ -12699,6 +13033,9 @@ function validateProviderDefinition(raw) {
|
|
|
12699
13033
|
warnings.push(`Unknown provider field: ${key}`);
|
|
12700
13034
|
}
|
|
12701
13035
|
}
|
|
13036
|
+
if (provider.disableUpstream !== void 0) {
|
|
13037
|
+
warnings.push("disableUpstream is deprecated in provider definitions; use machine-level provider source policy instead");
|
|
13038
|
+
}
|
|
12702
13039
|
const category = provider.category;
|
|
12703
13040
|
if (category === "cli" || category === "acp") {
|
|
12704
13041
|
const spawn4 = provider.spawn;
|
|
@@ -12758,8 +13095,11 @@ function validateControl(control, errors) {
|
|
|
12758
13095
|
var ProviderLoader = class _ProviderLoader {
|
|
12759
13096
|
providers = /* @__PURE__ */ new Map();
|
|
12760
13097
|
providerAvailability = /* @__PURE__ */ new Map();
|
|
13098
|
+
defaultProvidersDir;
|
|
13099
|
+
explicitProviderDir = null;
|
|
12761
13100
|
userDir;
|
|
12762
13101
|
upstreamDir;
|
|
13102
|
+
sourceMode = "normal";
|
|
12763
13103
|
disableUpstream;
|
|
12764
13104
|
watchers = [];
|
|
12765
13105
|
logFn;
|
|
@@ -12773,22 +13113,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12773
13113
|
static META_FILE = ".meta.json";
|
|
12774
13114
|
constructor(options) {
|
|
12775
13115
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
12776
|
-
|
|
12777
|
-
|
|
12778
|
-
|
|
12779
|
-
|
|
12780
|
-
|
|
12781
|
-
|
|
12782
|
-
|
|
12783
|
-
|
|
12784
|
-
|
|
12785
|
-
} else {
|
|
12786
|
-
this.userDir = defaultProvidersDir;
|
|
12787
|
-
this.log(`Using default user providers directory: ${this.userDir}`);
|
|
12788
|
-
}
|
|
12789
|
-
}
|
|
12790
|
-
this.upstreamDir = path14.join(defaultProvidersDir, ".upstream");
|
|
12791
|
-
this.disableUpstream = options?.disableUpstream ?? false;
|
|
13116
|
+
this.defaultProvidersDir = path14.join(os13.homedir(), ".adhdev", "providers");
|
|
13117
|
+
this.userDir = this.defaultProvidersDir;
|
|
13118
|
+
this.upstreamDir = path14.join(this.defaultProvidersDir, ".upstream");
|
|
13119
|
+
this.disableUpstream = false;
|
|
13120
|
+
this.applySourceConfig({
|
|
13121
|
+
userDir: options?.userDir,
|
|
13122
|
+
sourceMode: options?.sourceMode,
|
|
13123
|
+
disableUpstream: options?.disableUpstream
|
|
13124
|
+
});
|
|
12792
13125
|
}
|
|
12793
13126
|
log(msg) {
|
|
12794
13127
|
this.logFn(`[ProviderLoader] ${msg}`);
|
|
@@ -12813,6 +13146,33 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12813
13146
|
getProviderRoots() {
|
|
12814
13147
|
return [this.userDir, this.upstreamDir];
|
|
12815
13148
|
}
|
|
13149
|
+
getSourceConfig() {
|
|
13150
|
+
return {
|
|
13151
|
+
sourceMode: this.sourceMode,
|
|
13152
|
+
disableUpstream: this.disableUpstream,
|
|
13153
|
+
explicitProviderDir: this.explicitProviderDir,
|
|
13154
|
+
userDir: this.userDir,
|
|
13155
|
+
upstreamDir: this.upstreamDir,
|
|
13156
|
+
providerRoots: this.getProviderRoots()
|
|
13157
|
+
};
|
|
13158
|
+
}
|
|
13159
|
+
applySourceConfig(options) {
|
|
13160
|
+
const nextSourceMode = options?.sourceMode === "no-upstream" ? "no-upstream" : options?.sourceMode === "normal" ? "normal" : options?.disableUpstream ? "no-upstream" : this.sourceMode || "normal";
|
|
13161
|
+
if (options && Object.prototype.hasOwnProperty.call(options, "userDir")) {
|
|
13162
|
+
this.explicitProviderDir = options.userDir?.trim() ? options.userDir : null;
|
|
13163
|
+
}
|
|
13164
|
+
this.sourceMode = nextSourceMode;
|
|
13165
|
+
this.userDir = this.explicitProviderDir || this.defaultProvidersDir;
|
|
13166
|
+
this.upstreamDir = path14.join(this.defaultProvidersDir, ".upstream");
|
|
13167
|
+
this.disableUpstream = this.sourceMode === "no-upstream";
|
|
13168
|
+
if (this.explicitProviderDir) {
|
|
13169
|
+
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
13170
|
+
} else {
|
|
13171
|
+
this.log(`Using default user providers directory: ${this.userDir}`);
|
|
13172
|
+
}
|
|
13173
|
+
this.log(`Provider source config: mode=${this.sourceMode} explicitProviderDir=${this.explicitProviderDir || "-"} userDir=${this.userDir} upstreamDir=${this.upstreamDir}`);
|
|
13174
|
+
return this.getSourceConfig();
|
|
13175
|
+
}
|
|
12816
13176
|
/**
|
|
12817
13177
|
* Canonical provider directory shape for a given root.
|
|
12818
13178
|
*/
|
|
@@ -12863,7 +13223,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12863
13223
|
this.log(`Loaded ${upstreamCount} upstream providers (auto-updated)`);
|
|
12864
13224
|
}
|
|
12865
13225
|
} else if (this.disableUpstream) {
|
|
12866
|
-
this.log("Upstream loading disabled (
|
|
13226
|
+
this.log("Upstream loading disabled (sourceMode=no-upstream)");
|
|
12867
13227
|
}
|
|
12868
13228
|
if (fs6.existsSync(this.userDir)) {
|
|
12869
13229
|
const userCount = this.loadDir(this.userDir, [".upstream"]);
|
|
@@ -13374,7 +13734,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13374
13734
|
*/
|
|
13375
13735
|
async fetchLatest() {
|
|
13376
13736
|
if (this.disableUpstream) {
|
|
13377
|
-
this.log("Upstream fetch skipped (
|
|
13737
|
+
this.log("Upstream fetch skipped (sourceMode=no-upstream)");
|
|
13378
13738
|
return { updated: false };
|
|
13379
13739
|
}
|
|
13380
13740
|
const https = __require("https");
|
|
@@ -13396,7 +13756,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13396
13756
|
return { updated: false };
|
|
13397
13757
|
}
|
|
13398
13758
|
try {
|
|
13399
|
-
const etag = await new Promise((
|
|
13759
|
+
const etag = await new Promise((resolve11, reject) => {
|
|
13400
13760
|
const options = {
|
|
13401
13761
|
method: "HEAD",
|
|
13402
13762
|
hostname: "github.com",
|
|
@@ -13414,7 +13774,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13414
13774
|
headers: { "User-Agent": "adhdev-launcher" },
|
|
13415
13775
|
timeout: 1e4
|
|
13416
13776
|
}, (res2) => {
|
|
13417
|
-
|
|
13777
|
+
resolve11(res2.headers.etag || res2.headers["last-modified"] || "");
|
|
13418
13778
|
});
|
|
13419
13779
|
req2.on("error", reject);
|
|
13420
13780
|
req2.on("timeout", () => {
|
|
@@ -13423,7 +13783,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13423
13783
|
});
|
|
13424
13784
|
req2.end();
|
|
13425
13785
|
} else {
|
|
13426
|
-
|
|
13786
|
+
resolve11(res.headers.etag || res.headers["last-modified"] || "");
|
|
13427
13787
|
}
|
|
13428
13788
|
});
|
|
13429
13789
|
req.on("error", reject);
|
|
@@ -13487,7 +13847,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13487
13847
|
downloadFile(url, destPath) {
|
|
13488
13848
|
const https = __require("https");
|
|
13489
13849
|
const http3 = __require("http");
|
|
13490
|
-
return new Promise((
|
|
13850
|
+
return new Promise((resolve11, reject) => {
|
|
13491
13851
|
const doRequest = (reqUrl, redirectCount = 0) => {
|
|
13492
13852
|
if (redirectCount > 5) {
|
|
13493
13853
|
reject(new Error("Too many redirects"));
|
|
@@ -13507,7 +13867,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13507
13867
|
res.pipe(ws);
|
|
13508
13868
|
ws.on("finish", () => {
|
|
13509
13869
|
ws.close();
|
|
13510
|
-
|
|
13870
|
+
resolve11();
|
|
13511
13871
|
});
|
|
13512
13872
|
ws.on("error", reject);
|
|
13513
13873
|
});
|
|
@@ -13982,17 +14342,17 @@ async function findFreePort(ports) {
|
|
|
13982
14342
|
throw new Error("No free port found");
|
|
13983
14343
|
}
|
|
13984
14344
|
function checkPortFree(port) {
|
|
13985
|
-
return new Promise((
|
|
14345
|
+
return new Promise((resolve11) => {
|
|
13986
14346
|
const server = net.createServer();
|
|
13987
14347
|
server.unref();
|
|
13988
|
-
server.on("error", () =>
|
|
14348
|
+
server.on("error", () => resolve11(false));
|
|
13989
14349
|
server.listen(port, "127.0.0.1", () => {
|
|
13990
|
-
server.close(() =>
|
|
14350
|
+
server.close(() => resolve11(true));
|
|
13991
14351
|
});
|
|
13992
14352
|
});
|
|
13993
14353
|
}
|
|
13994
14354
|
async function isCdpActive(port) {
|
|
13995
|
-
return new Promise((
|
|
14355
|
+
return new Promise((resolve11) => {
|
|
13996
14356
|
const req = __require("http").get(`http://127.0.0.1:${port}/json/version`, {
|
|
13997
14357
|
timeout: 2e3
|
|
13998
14358
|
}, (res) => {
|
|
@@ -14001,16 +14361,16 @@ async function isCdpActive(port) {
|
|
|
14001
14361
|
res.on("end", () => {
|
|
14002
14362
|
try {
|
|
14003
14363
|
const info = JSON.parse(data);
|
|
14004
|
-
|
|
14364
|
+
resolve11(!!info["WebKit-Version"] || !!info["Browser"]);
|
|
14005
14365
|
} catch {
|
|
14006
|
-
|
|
14366
|
+
resolve11(false);
|
|
14007
14367
|
}
|
|
14008
14368
|
});
|
|
14009
14369
|
});
|
|
14010
|
-
req.on("error", () =>
|
|
14370
|
+
req.on("error", () => resolve11(false));
|
|
14011
14371
|
req.on("timeout", () => {
|
|
14012
14372
|
req.destroy();
|
|
14013
|
-
|
|
14373
|
+
resolve11(false);
|
|
14014
14374
|
});
|
|
14015
14375
|
});
|
|
14016
14376
|
}
|
|
@@ -14461,12 +14821,90 @@ cleanOldFiles();
|
|
|
14461
14821
|
// src/commands/router.ts
|
|
14462
14822
|
init_logger();
|
|
14463
14823
|
|
|
14824
|
+
// src/session-host/runtime-surface.ts
|
|
14825
|
+
var LIVE_LIFECYCLES = /* @__PURE__ */ new Set(["starting", "running", "stopping", "interrupted"]);
|
|
14826
|
+
function isSessionHostLiveRuntime(record) {
|
|
14827
|
+
const lifecycle = String(record?.lifecycle || "").trim();
|
|
14828
|
+
return LIVE_LIFECYCLES.has(lifecycle);
|
|
14829
|
+
}
|
|
14830
|
+
function getSessionHostRecoveryLabel(meta) {
|
|
14831
|
+
const recoveryState = typeof meta?.runtimeRecoveryState === "string" ? String(meta.runtimeRecoveryState).trim() : "";
|
|
14832
|
+
if (!recoveryState) return null;
|
|
14833
|
+
if (recoveryState === "auto_resumed") return "restored after restart";
|
|
14834
|
+
if (recoveryState === "resume_failed") return "restore failed";
|
|
14835
|
+
if (recoveryState === "host_restart_interrupted") return "host restart interrupted";
|
|
14836
|
+
if (recoveryState === "orphan_snapshot") return "snapshot recovered";
|
|
14837
|
+
return recoveryState.replace(/_/g, " ");
|
|
14838
|
+
}
|
|
14839
|
+
function isSessionHostRecoverySnapshot(record) {
|
|
14840
|
+
if (!record) return false;
|
|
14841
|
+
if (isSessionHostLiveRuntime(record)) return false;
|
|
14842
|
+
const lifecycle = String(record.lifecycle || "").trim();
|
|
14843
|
+
if (lifecycle && lifecycle !== "stopped" && lifecycle !== "failed") {
|
|
14844
|
+
return false;
|
|
14845
|
+
}
|
|
14846
|
+
const meta = record.meta || void 0;
|
|
14847
|
+
if (meta?.restoredFromStorage === true) return true;
|
|
14848
|
+
return getSessionHostRecoveryLabel(meta) !== null;
|
|
14849
|
+
}
|
|
14850
|
+
function getSessionHostSurfaceKind(record) {
|
|
14851
|
+
if (isSessionHostLiveRuntime(record)) return "live_runtime";
|
|
14852
|
+
if (isSessionHostRecoverySnapshot(record)) return "recovery_snapshot";
|
|
14853
|
+
return "inactive_record";
|
|
14854
|
+
}
|
|
14855
|
+
function partitionSessionHostRecords(records) {
|
|
14856
|
+
const liveRuntimes = [];
|
|
14857
|
+
const recoverySnapshots = [];
|
|
14858
|
+
const inactiveRecords = [];
|
|
14859
|
+
for (const record of records) {
|
|
14860
|
+
const kind = getSessionHostSurfaceKind(record);
|
|
14861
|
+
if (kind === "live_runtime") {
|
|
14862
|
+
liveRuntimes.push(record);
|
|
14863
|
+
} else if (kind === "recovery_snapshot") {
|
|
14864
|
+
recoverySnapshots.push(record);
|
|
14865
|
+
} else {
|
|
14866
|
+
inactiveRecords.push(record);
|
|
14867
|
+
}
|
|
14868
|
+
}
|
|
14869
|
+
return {
|
|
14870
|
+
liveRuntimes,
|
|
14871
|
+
recoverySnapshots,
|
|
14872
|
+
inactiveRecords
|
|
14873
|
+
};
|
|
14874
|
+
}
|
|
14875
|
+
function partitionSessionHostDiagnosticsSessions(records) {
|
|
14876
|
+
return partitionSessionHostRecords(records || []);
|
|
14877
|
+
}
|
|
14878
|
+
|
|
14464
14879
|
// src/status/snapshot.ts
|
|
14465
14880
|
init_config();
|
|
14466
14881
|
import * as os16 from "os";
|
|
14467
14882
|
init_terminal_screen();
|
|
14468
14883
|
init_logger();
|
|
14469
14884
|
var READ_DEBUG_ENABLED = process.argv.includes("--dev") || process.env.ADHDEV_READ_DEBUG === "1";
|
|
14885
|
+
var recentReadDebugSignatureBySession = /* @__PURE__ */ new Map();
|
|
14886
|
+
function buildRecentReadDebugSignature(snapshot) {
|
|
14887
|
+
return [
|
|
14888
|
+
snapshot.providerType,
|
|
14889
|
+
snapshot.status,
|
|
14890
|
+
snapshot.inboxBucket,
|
|
14891
|
+
snapshot.unread ? "1" : "0",
|
|
14892
|
+
String(snapshot.lastSeenAt),
|
|
14893
|
+
snapshot.completionMarker,
|
|
14894
|
+
snapshot.seenCompletionMarker,
|
|
14895
|
+
String(snapshot.lastUpdated),
|
|
14896
|
+
String(snapshot.lastUsedAt),
|
|
14897
|
+
snapshot.lastRole,
|
|
14898
|
+
String(snapshot.messageUpdatedAt)
|
|
14899
|
+
].join("|");
|
|
14900
|
+
}
|
|
14901
|
+
function shouldEmitRecentReadDebugLog(cache, snapshot) {
|
|
14902
|
+
const nextSignature = buildRecentReadDebugSignature(snapshot);
|
|
14903
|
+
const previousSignature = cache.get(snapshot.sessionId);
|
|
14904
|
+
if (previousSignature === nextSignature) return false;
|
|
14905
|
+
cache.set(snapshot.sessionId, nextSignature);
|
|
14906
|
+
return true;
|
|
14907
|
+
}
|
|
14470
14908
|
function buildDetectedIdeInfos(detectedIdes, cdpManagers) {
|
|
14471
14909
|
return detectedIdes.filter((ide) => ide.installed !== false).map((ide) => ({
|
|
14472
14910
|
id: ide.id,
|
|
@@ -14618,7 +15056,7 @@ function buildRecentLaunches(recentActivity) {
|
|
|
14618
15056
|
providerSessionId: item.providerSessionId,
|
|
14619
15057
|
title: item.title || item.providerName,
|
|
14620
15058
|
workspace: item.workspace,
|
|
14621
|
-
|
|
15059
|
+
summaryMetadata: item.summaryMetadata,
|
|
14622
15060
|
lastLaunchedAt: item.lastUsedAt
|
|
14623
15061
|
})).sort((a, b) => b.lastLaunchedAt - a.lastLaunchedAt).slice(0, 12);
|
|
14624
15062
|
}
|
|
@@ -14659,9 +15097,24 @@ function buildStatusSnapshot(options) {
|
|
|
14659
15097
|
session.unread = unread;
|
|
14660
15098
|
session.inboxBucket = inboxBucket;
|
|
14661
15099
|
if (READ_DEBUG_ENABLED && (session.unread || session.inboxBucket !== "idle" || session.providerType.includes("codex"))) {
|
|
15100
|
+
const recentReadSnapshot = {
|
|
15101
|
+
sessionId: session.id,
|
|
15102
|
+
providerType: session.providerType,
|
|
15103
|
+
status: String(session.status || ""),
|
|
15104
|
+
inboxBucket,
|
|
15105
|
+
unread,
|
|
15106
|
+
lastSeenAt,
|
|
15107
|
+
completionMarker: completionMarker || "-",
|
|
15108
|
+
seenCompletionMarker: seenCompletionMarker || "-",
|
|
15109
|
+
lastUpdated: Number(session.lastUpdated || 0),
|
|
15110
|
+
lastUsedAt,
|
|
15111
|
+
lastRole: getLastMessageRole(sourceSession),
|
|
15112
|
+
messageUpdatedAt: getSessionMessageUpdatedAt(sourceSession)
|
|
15113
|
+
};
|
|
15114
|
+
if (!shouldEmitRecentReadDebugLog(recentReadDebugSignatureBySession, recentReadSnapshot)) continue;
|
|
14662
15115
|
LOG.info(
|
|
14663
15116
|
"RecentRead",
|
|
14664
|
-
`snapshot session id=${
|
|
15117
|
+
`snapshot session id=${recentReadSnapshot.sessionId} provider=${recentReadSnapshot.providerType} status=${recentReadSnapshot.status} bucket=${recentReadSnapshot.inboxBucket} unread=${String(recentReadSnapshot.unread)} lastSeenAt=${recentReadSnapshot.lastSeenAt} completionMarker=${recentReadSnapshot.completionMarker} seenMarker=${recentReadSnapshot.seenCompletionMarker} lastUpdated=${String(recentReadSnapshot.lastUpdated)} lastUsedAt=${recentReadSnapshot.lastUsedAt} lastRole=${recentReadSnapshot.lastRole} msgUpdatedAt=${recentReadSnapshot.messageUpdatedAt}`
|
|
14665
15118
|
);
|
|
14666
15119
|
}
|
|
14667
15120
|
const lastDisplayMessage = getLastDisplayMessage(sourceSession);
|
|
@@ -14739,7 +15192,7 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
14739
15192
|
while (Date.now() - start < timeoutMs) {
|
|
14740
15193
|
try {
|
|
14741
15194
|
process.kill(pid, 0);
|
|
14742
|
-
await new Promise((
|
|
15195
|
+
await new Promise((resolve11) => setTimeout(resolve11, 250));
|
|
14743
15196
|
} catch {
|
|
14744
15197
|
return;
|
|
14745
15198
|
}
|
|
@@ -14854,7 +15307,7 @@ async function runDaemonUpgradeHelper(payload) {
|
|
|
14854
15307
|
appendUpgradeLog(installOutput.trim());
|
|
14855
15308
|
}
|
|
14856
15309
|
if (process.platform === "win32") {
|
|
14857
|
-
await new Promise((
|
|
15310
|
+
await new Promise((resolve11) => setTimeout(resolve11, 500));
|
|
14858
15311
|
cleanupStaleGlobalInstallDirs(payload.packageName);
|
|
14859
15312
|
appendUpgradeLog("Post-install staging cleanup complete");
|
|
14860
15313
|
}
|
|
@@ -14936,11 +15389,104 @@ function toHostedCliRuntimeDescriptor(record) {
|
|
|
14936
15389
|
providerSessionId: typeof record.meta?.providerSessionId === "string" ? String(record.meta.providerSessionId) : void 0
|
|
14937
15390
|
};
|
|
14938
15391
|
}
|
|
15392
|
+
function getWriteConflictOwnerClientId(error) {
|
|
15393
|
+
const message = typeof error === "string" ? error : error instanceof Error ? error.message : "";
|
|
15394
|
+
const match = /^Write owned by\s+(.+)$/.exec(message.trim());
|
|
15395
|
+
return match?.[1]?.trim() || void 0;
|
|
15396
|
+
}
|
|
15397
|
+
function summarizeSessionHostRecord(result) {
|
|
15398
|
+
if (!result || typeof result !== "object") return {};
|
|
15399
|
+
const record = result;
|
|
15400
|
+
return {
|
|
15401
|
+
runtimeKey: typeof record.runtimeKey === "string" ? record.runtimeKey : void 0,
|
|
15402
|
+
lifecycle: typeof record.lifecycle === "string" ? record.lifecycle : void 0,
|
|
15403
|
+
surfaceKind: getSessionHostSurfaceKind(record),
|
|
15404
|
+
attachedClientCount: Array.isArray(record.attachedClients) ? record.attachedClients.length : void 0,
|
|
15405
|
+
hasWriteOwner: !!record.writeOwner,
|
|
15406
|
+
writeOwnerClientId: typeof record.writeOwner?.clientId === "string" ? record.writeOwner.clientId : void 0
|
|
15407
|
+
};
|
|
15408
|
+
}
|
|
15409
|
+
function summarizeSessionHostRecords(result) {
|
|
15410
|
+
const records = Array.isArray(result) ? result : [];
|
|
15411
|
+
const groups = partitionSessionHostRecords(records);
|
|
15412
|
+
return {
|
|
15413
|
+
sessionCount: records.length,
|
|
15414
|
+
liveRuntimeCount: groups.liveRuntimes.length,
|
|
15415
|
+
recoverySnapshotCount: groups.recoverySnapshots.length,
|
|
15416
|
+
inactiveRecordCount: groups.inactiveRecords.length
|
|
15417
|
+
};
|
|
15418
|
+
}
|
|
15419
|
+
function summarizeSessionHostDiagnostics(result) {
|
|
15420
|
+
const diagnostics = result && typeof result === "object" ? result : {};
|
|
15421
|
+
const sessions = Array.isArray(diagnostics.sessions) ? diagnostics.sessions : [];
|
|
15422
|
+
return {
|
|
15423
|
+
runtimeCount: typeof diagnostics.runtimeCount === "number" ? diagnostics.runtimeCount : void 0,
|
|
15424
|
+
...summarizeSessionHostRecords(sessions)
|
|
15425
|
+
};
|
|
15426
|
+
}
|
|
15427
|
+
function summarizeSessionHostPruneResult(result) {
|
|
15428
|
+
const value = result && typeof result === "object" ? result : {};
|
|
15429
|
+
return {
|
|
15430
|
+
duplicateGroupCount: typeof value.duplicateGroupCount === "number" ? value.duplicateGroupCount : void 0,
|
|
15431
|
+
prunedCount: Array.isArray(value.prunedSessionIds) ? value.prunedSessionIds.length : void 0,
|
|
15432
|
+
keptCount: Array.isArray(value.keptSessionIds) ? value.keptSessionIds.length : void 0
|
|
15433
|
+
};
|
|
15434
|
+
}
|
|
14939
15435
|
var DaemonCommandRouter = class {
|
|
14940
15436
|
deps;
|
|
14941
15437
|
constructor(deps) {
|
|
14942
15438
|
this.deps = deps;
|
|
14943
15439
|
}
|
|
15440
|
+
async traceSessionHostAction(action, args, run, summarizeResult) {
|
|
15441
|
+
const interactionId = typeof args?._interactionId === "string" ? args._interactionId : void 0;
|
|
15442
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : void 0;
|
|
15443
|
+
const requestedPayload = { action };
|
|
15444
|
+
if (sessionId) requestedPayload.sessionId = sessionId;
|
|
15445
|
+
if (typeof args?.clientId === "string") requestedPayload.clientId = args.clientId;
|
|
15446
|
+
if (typeof args?.signal === "string") requestedPayload.signal = args.signal;
|
|
15447
|
+
if (typeof args?.providerType === "string") requestedPayload.providerType = args.providerType;
|
|
15448
|
+
if (typeof args?.workspace === "string") requestedPayload.workspace = args.workspace;
|
|
15449
|
+
if (typeof args?.dryRun === "boolean") requestedPayload.dryRun = args.dryRun;
|
|
15450
|
+
recordDebugTrace({
|
|
15451
|
+
interactionId,
|
|
15452
|
+
category: "session_host",
|
|
15453
|
+
stage: "action_requested",
|
|
15454
|
+
level: "info",
|
|
15455
|
+
sessionId,
|
|
15456
|
+
payload: requestedPayload
|
|
15457
|
+
});
|
|
15458
|
+
try {
|
|
15459
|
+
const result = await run();
|
|
15460
|
+
recordDebugTrace({
|
|
15461
|
+
interactionId,
|
|
15462
|
+
category: "session_host",
|
|
15463
|
+
stage: "action_result",
|
|
15464
|
+
level: "info",
|
|
15465
|
+
sessionId,
|
|
15466
|
+
payload: {
|
|
15467
|
+
...requestedPayload,
|
|
15468
|
+
success: true,
|
|
15469
|
+
...summarizeResult ? summarizeResult(result) : {}
|
|
15470
|
+
}
|
|
15471
|
+
});
|
|
15472
|
+
return result;
|
|
15473
|
+
} catch (error) {
|
|
15474
|
+
recordDebugTrace({
|
|
15475
|
+
interactionId,
|
|
15476
|
+
category: "session_host",
|
|
15477
|
+
stage: "action_failed",
|
|
15478
|
+
level: "error",
|
|
15479
|
+
sessionId,
|
|
15480
|
+
payload: {
|
|
15481
|
+
...requestedPayload,
|
|
15482
|
+
error: error?.message || String(error),
|
|
15483
|
+
failureKind: getWriteConflictOwnerClientId(error) ? "write_conflict" : "request_failed",
|
|
15484
|
+
conflictOwnerClientId: getWriteConflictOwnerClientId(error)
|
|
15485
|
+
}
|
|
15486
|
+
});
|
|
15487
|
+
throw error;
|
|
15488
|
+
}
|
|
15489
|
+
}
|
|
14944
15490
|
/**
|
|
14945
15491
|
* Unified command routing.
|
|
14946
15492
|
* Returns result for all commands:
|
|
@@ -15050,44 +15596,60 @@ var DaemonCommandRouter = class {
|
|
|
15050
15596
|
}
|
|
15051
15597
|
case "session_host_get_diagnostics": {
|
|
15052
15598
|
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
15053
|
-
const diagnostics = await this.deps.sessionHostControl.getDiagnostics({
|
|
15599
|
+
const diagnostics = await this.traceSessionHostAction("session_host_get_diagnostics", args, () => this.deps.sessionHostControl.getDiagnostics({
|
|
15054
15600
|
includeSessions: args?.includeSessions !== false,
|
|
15055
15601
|
limit: Number(args?.limit) || void 0
|
|
15056
|
-
})
|
|
15602
|
+
}), (result) => ({
|
|
15603
|
+
includeSessions: args?.includeSessions !== false,
|
|
15604
|
+
limit: Number(args?.limit) || void 0,
|
|
15605
|
+
...summarizeSessionHostDiagnostics(result)
|
|
15606
|
+
}));
|
|
15057
15607
|
return { success: true, diagnostics };
|
|
15058
15608
|
}
|
|
15059
15609
|
case "session_host_list_sessions": {
|
|
15060
15610
|
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
15061
|
-
const sessions = await this.deps.sessionHostControl.listSessions();
|
|
15611
|
+
const sessions = await this.traceSessionHostAction("session_host_list_sessions", args, () => this.deps.sessionHostControl.listSessions(), (records) => summarizeSessionHostRecords(records));
|
|
15062
15612
|
return { success: true, sessions };
|
|
15063
15613
|
}
|
|
15064
15614
|
case "session_host_stop_session": {
|
|
15065
15615
|
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
15066
15616
|
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
15067
15617
|
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
15068
|
-
const record = await this.deps.sessionHostControl.stopSession(sessionId);
|
|
15618
|
+
const record = await this.traceSessionHostAction("session_host_stop_session", args, () => this.deps.sessionHostControl.stopSession(sessionId), (result) => summarizeSessionHostRecord(result));
|
|
15069
15619
|
return { success: true, record };
|
|
15070
15620
|
}
|
|
15071
15621
|
case "session_host_resume_session": {
|
|
15072
15622
|
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
15073
15623
|
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
15074
15624
|
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
15075
|
-
const record = await this.
|
|
15076
|
-
|
|
15077
|
-
|
|
15078
|
-
|
|
15079
|
-
|
|
15625
|
+
const record = await this.traceSessionHostAction("session_host_resume_session", args, async () => {
|
|
15626
|
+
const nextRecord = await this.deps.sessionHostControl.resumeSession(sessionId);
|
|
15627
|
+
const hosted = toHostedCliRuntimeDescriptor(nextRecord);
|
|
15628
|
+
if (hosted) {
|
|
15629
|
+
await this.deps.cliManager.restoreHostedSessions([hosted]);
|
|
15630
|
+
}
|
|
15631
|
+
return nextRecord;
|
|
15632
|
+
}, (result) => ({
|
|
15633
|
+
...summarizeSessionHostRecord(result),
|
|
15634
|
+
restoredHostedSession: !!toHostedCliRuntimeDescriptor(result)
|
|
15635
|
+
}));
|
|
15080
15636
|
return { success: true, record };
|
|
15081
15637
|
}
|
|
15082
15638
|
case "session_host_restart_session": {
|
|
15083
15639
|
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
15084
15640
|
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
15085
15641
|
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
15086
|
-
const record = await this.
|
|
15087
|
-
|
|
15088
|
-
|
|
15089
|
-
|
|
15090
|
-
|
|
15642
|
+
const record = await this.traceSessionHostAction("session_host_restart_session", args, async () => {
|
|
15643
|
+
const nextRecord = await this.deps.sessionHostControl.restartSession(sessionId);
|
|
15644
|
+
const hosted = toHostedCliRuntimeDescriptor(nextRecord);
|
|
15645
|
+
if (hosted) {
|
|
15646
|
+
await this.deps.cliManager.restoreHostedSessions([hosted]);
|
|
15647
|
+
}
|
|
15648
|
+
return nextRecord;
|
|
15649
|
+
}, (result) => ({
|
|
15650
|
+
...summarizeSessionHostRecord(result),
|
|
15651
|
+
restoredHostedSession: !!toHostedCliRuntimeDescriptor(result)
|
|
15652
|
+
}));
|
|
15091
15653
|
return { success: true, record };
|
|
15092
15654
|
}
|
|
15093
15655
|
case "session_host_send_signal": {
|
|
@@ -15096,7 +15658,7 @@ var DaemonCommandRouter = class {
|
|
|
15096
15658
|
const signal = typeof args?.signal === "string" ? args.signal : "";
|
|
15097
15659
|
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
15098
15660
|
if (!signal) return { success: false, error: "signal required" };
|
|
15099
|
-
const record = await this.deps.sessionHostControl.sendSignal(sessionId, signal);
|
|
15661
|
+
const record = await this.traceSessionHostAction("session_host_send_signal", args, () => this.deps.sessionHostControl.sendSignal(sessionId, signal), (result) => summarizeSessionHostRecord(result));
|
|
15100
15662
|
return { success: true, record };
|
|
15101
15663
|
}
|
|
15102
15664
|
case "session_host_force_detach_client": {
|
|
@@ -15105,16 +15667,16 @@ var DaemonCommandRouter = class {
|
|
|
15105
15667
|
const clientId = typeof args?.clientId === "string" ? args.clientId : "";
|
|
15106
15668
|
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
15107
15669
|
if (!clientId) return { success: false, error: "clientId required" };
|
|
15108
|
-
const record = await this.deps.sessionHostControl.forceDetachClient(sessionId, clientId);
|
|
15670
|
+
const record = await this.traceSessionHostAction("session_host_force_detach_client", args, () => this.deps.sessionHostControl.forceDetachClient(sessionId, clientId), (result) => summarizeSessionHostRecord(result));
|
|
15109
15671
|
return { success: true, record };
|
|
15110
15672
|
}
|
|
15111
15673
|
case "session_host_prune_duplicate_sessions": {
|
|
15112
15674
|
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
15113
|
-
const result = await this.deps.sessionHostControl.pruneDuplicateSessions({
|
|
15675
|
+
const result = await this.traceSessionHostAction("session_host_prune_duplicate_sessions", args, () => this.deps.sessionHostControl.pruneDuplicateSessions({
|
|
15114
15676
|
providerType: typeof args?.providerType === "string" ? args.providerType : void 0,
|
|
15115
15677
|
workspace: typeof args?.workspace === "string" ? args.workspace : void 0,
|
|
15116
15678
|
dryRun: args?.dryRun === true
|
|
15117
|
-
});
|
|
15679
|
+
}), (value) => summarizeSessionHostPruneResult(value));
|
|
15118
15680
|
return { success: true, result };
|
|
15119
15681
|
}
|
|
15120
15682
|
case "session_host_acquire_write": {
|
|
@@ -15124,12 +15686,15 @@ var DaemonCommandRouter = class {
|
|
|
15124
15686
|
const ownerType = args?.ownerType === "agent" ? "agent" : "user";
|
|
15125
15687
|
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
15126
15688
|
if (!clientId) return { success: false, error: "clientId required" };
|
|
15127
|
-
const record = await this.deps.sessionHostControl.acquireWrite({
|
|
15689
|
+
const record = await this.traceSessionHostAction("session_host_acquire_write", args, () => this.deps.sessionHostControl.acquireWrite({
|
|
15128
15690
|
sessionId,
|
|
15129
15691
|
clientId,
|
|
15130
15692
|
ownerType,
|
|
15131
15693
|
force: args?.force !== false
|
|
15132
|
-
})
|
|
15694
|
+
}), (result) => ({
|
|
15695
|
+
...summarizeSessionHostRecord(result),
|
|
15696
|
+
ownerType
|
|
15697
|
+
}));
|
|
15133
15698
|
return { success: true, record };
|
|
15134
15699
|
}
|
|
15135
15700
|
case "session_host_release_write": {
|
|
@@ -15138,7 +15703,10 @@ var DaemonCommandRouter = class {
|
|
|
15138
15703
|
const clientId = typeof args?.clientId === "string" ? args.clientId : "";
|
|
15139
15704
|
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
15140
15705
|
if (!clientId) return { success: false, error: "clientId required" };
|
|
15141
|
-
const record = await this.deps.sessionHostControl.releaseWrite({
|
|
15706
|
+
const record = await this.traceSessionHostAction("session_host_release_write", args, () => this.deps.sessionHostControl.releaseWrite({
|
|
15707
|
+
sessionId,
|
|
15708
|
+
clientId
|
|
15709
|
+
}), (result) => summarizeSessionHostRecord(result));
|
|
15142
15710
|
return { success: true, record };
|
|
15143
15711
|
}
|
|
15144
15712
|
case "list_saved_sessions": {
|
|
@@ -15147,8 +15715,9 @@ var DaemonCommandRouter = class {
|
|
|
15147
15715
|
if (!providerType) {
|
|
15148
15716
|
return { success: false, error: "providerType required" };
|
|
15149
15717
|
}
|
|
15150
|
-
const
|
|
15151
|
-
const
|
|
15718
|
+
const wantsAll = args?.all === true;
|
|
15719
|
+
const offset = wantsAll ? 0 : Math.max(0, Number(args?.offset) || 0);
|
|
15720
|
+
const limit = wantsAll ? Number.MAX_SAFE_INTEGER : Math.max(1, Math.min(100, Number(args?.limit) || 30));
|
|
15152
15721
|
const { sessions: historySessions, hasMore } = listSavedHistorySessions(providerType, { offset, limit });
|
|
15153
15722
|
const state = loadState();
|
|
15154
15723
|
const savedSessions = getSavedProviderSessions(state, { providerType, kind });
|
|
@@ -15169,13 +15738,13 @@ var DaemonCommandRouter = class {
|
|
|
15169
15738
|
providerName: saved?.providerName || recent?.providerName || providerType,
|
|
15170
15739
|
kind: saved?.kind || recent?.kind || kind,
|
|
15171
15740
|
title: saved?.title || recent?.title || session.sessionTitle || session.preview || providerType,
|
|
15172
|
-
workspace: saved?.workspace || recent?.workspace,
|
|
15173
|
-
|
|
15741
|
+
workspace: saved?.workspace || recent?.workspace || session.workspace,
|
|
15742
|
+
summaryMetadata: saved?.summaryMetadata || recent?.summaryMetadata,
|
|
15174
15743
|
preview: session.preview,
|
|
15175
15744
|
messageCount: session.messageCount,
|
|
15176
15745
|
firstMessageAt: session.firstMessageAt,
|
|
15177
15746
|
lastMessageAt: session.lastMessageAt,
|
|
15178
|
-
canResume: !!(saved?.workspace || recent?.workspace) && canResumeById
|
|
15747
|
+
canResume: !!(saved?.workspace || recent?.workspace || session.workspace) && canResumeById
|
|
15179
15748
|
};
|
|
15180
15749
|
}),
|
|
15181
15750
|
hasMore
|
|
@@ -15609,7 +16178,7 @@ var DaemonStatusReporter = class {
|
|
|
15609
16178
|
const ideSummary = ideStates.map((s) => {
|
|
15610
16179
|
const msgs = s.activeChat?.messages?.length || 0;
|
|
15611
16180
|
const exts = s.extensions.length;
|
|
15612
|
-
return `${s.type}(${s.status},${msgs}msg,${exts}ext
|
|
16181
|
+
return `${s.type}(${s.status},${msgs}msg,${exts}ext)`;
|
|
15613
16182
|
}).join(", ");
|
|
15614
16183
|
const cliSummary = cliStates.map((s) => `${s.type}(${s.status})`).join(", ");
|
|
15615
16184
|
const acpSummary = acpStates.map((s) => `${s.type}(${s.status})`).join(", ");
|
|
@@ -15671,9 +16240,7 @@ var DaemonStatusReporter = class {
|
|
|
15671
16240
|
workspace: session.workspace ?? null,
|
|
15672
16241
|
title: session.title,
|
|
15673
16242
|
cdpConnected: session.cdpConnected,
|
|
15674
|
-
|
|
15675
|
-
currentPlan: session.currentPlan,
|
|
15676
|
-
currentAutoApprove: session.currentAutoApprove
|
|
16243
|
+
summaryMetadata: session.summaryMetadata
|
|
15677
16244
|
})),
|
|
15678
16245
|
p2p: payload.p2p,
|
|
15679
16246
|
timestamp: now
|
|
@@ -15792,7 +16359,7 @@ var ProviderStreamAdapter = class {
|
|
|
15792
16359
|
const beforeCount = this.messageCount(before);
|
|
15793
16360
|
const beforeSignature = this.lastMessageSignature(before);
|
|
15794
16361
|
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
15795
|
-
await new Promise((
|
|
16362
|
+
await new Promise((resolve11) => setTimeout(resolve11, 250));
|
|
15796
16363
|
let state;
|
|
15797
16364
|
try {
|
|
15798
16365
|
state = await this.readChat(evaluate);
|
|
@@ -15814,7 +16381,7 @@ var ProviderStreamAdapter = class {
|
|
|
15814
16381
|
if (this.messageCount(first) > 0 || this.lastMessageSignature(first)) {
|
|
15815
16382
|
return first;
|
|
15816
16383
|
}
|
|
15817
|
-
await new Promise((
|
|
16384
|
+
await new Promise((resolve11) => setTimeout(resolve11, 150));
|
|
15818
16385
|
const second = await this.readChat(evaluate);
|
|
15819
16386
|
return this.messageCount(second) >= this.messageCount(first) ? second : first;
|
|
15820
16387
|
}
|
|
@@ -15839,15 +16406,18 @@ var ProviderStreamAdapter = class {
|
|
|
15839
16406
|
status: data.status || "idle",
|
|
15840
16407
|
messages: data.messages || [],
|
|
15841
16408
|
inputContent: data.inputContent || "",
|
|
15842
|
-
model: data.model,
|
|
15843
|
-
mode: data.mode,
|
|
15844
16409
|
activeModal: data.activeModal
|
|
15845
16410
|
};
|
|
15846
16411
|
if (typeof data.title === "string" && data.title.trim()) {
|
|
15847
16412
|
state.title = data.title.trim();
|
|
15848
16413
|
}
|
|
15849
16414
|
const controlValues = extractProviderControlValues(this.provider.controls, data);
|
|
15850
|
-
|
|
16415
|
+
const surface = resolveProviderStateSurface({
|
|
16416
|
+
controlValues,
|
|
16417
|
+
summaryMetadata: data.summaryMetadata
|
|
16418
|
+
});
|
|
16419
|
+
if (surface.controlValues) state.controlValues = surface.controlValues;
|
|
16420
|
+
if (surface.summaryMetadata) state.summaryMetadata = surface.summaryMetadata;
|
|
15851
16421
|
const effects = normalizeProviderEffects(data);
|
|
15852
16422
|
if (effects.length > 0) state.effects = effects;
|
|
15853
16423
|
if (state.messages.length > 0) {
|
|
@@ -15954,7 +16524,7 @@ var ProviderStreamAdapter = class {
|
|
|
15954
16524
|
if (typeof data.error === "string" && data.error.trim()) return false;
|
|
15955
16525
|
}
|
|
15956
16526
|
for (let attempt = 0; attempt < 6; attempt += 1) {
|
|
15957
|
-
await new Promise((
|
|
16527
|
+
await new Promise((resolve11) => setTimeout(resolve11, 250));
|
|
15958
16528
|
const state = await this.readChat(evaluate);
|
|
15959
16529
|
const title = this.getStateTitle(state);
|
|
15960
16530
|
if (this.titlesMatch(title, sessionId)) return true;
|
|
@@ -16121,7 +16691,8 @@ var DaemonAgentStreamManager = class {
|
|
|
16121
16691
|
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
|
|
16122
16692
|
const state = await agent.adapter.readChat(evaluate);
|
|
16123
16693
|
const stateError = this.getStateError(state);
|
|
16124
|
-
|
|
16694
|
+
const selectedModelValue = typeof state.controlValues?.model === "string" ? state.controlValues.model : "";
|
|
16695
|
+
LOG.debug("AgentStream", `[AgentStream] readChat(${type}) result: status=${state.status} msgs=${state.messages?.length || 0} model=${selectedModelValue}${state.status === "error" ? " error=" + JSON.stringify(stateError) : ""}`);
|
|
16125
16696
|
if (state.status === "error" && this.isRecoverableSessionError(stateError)) {
|
|
16126
16697
|
throw new Error(stateError);
|
|
16127
16698
|
}
|
|
@@ -16469,9 +17040,8 @@ function forwardAgentStreamsToIdeInstance(instanceManager, ideType, streams) {
|
|
|
16469
17040
|
messages: stream.messages || [],
|
|
16470
17041
|
status: stream.status || "idle",
|
|
16471
17042
|
activeModal: stream.activeModal || null,
|
|
16472
|
-
model: stream.model || void 0,
|
|
16473
|
-
mode: stream.mode || void 0,
|
|
16474
17043
|
controlValues: stream.controlValues || void 0,
|
|
17044
|
+
summaryMetadata: stream.summaryMetadata || void 0,
|
|
16475
17045
|
effects: stream.effects || void 0,
|
|
16476
17046
|
sessionId: stream.sessionId || stream.instanceId || void 0,
|
|
16477
17047
|
title: stream.title || stream.agentName || void 0,
|
|
@@ -16876,6 +17446,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
16876
17446
|
import * as http2 from "http";
|
|
16877
17447
|
import * as fs14 from "fs";
|
|
16878
17448
|
import * as path22 from "path";
|
|
17449
|
+
init_config();
|
|
16879
17450
|
|
|
16880
17451
|
// src/daemon/scaffold-template.ts
|
|
16881
17452
|
function generateFiles(type, name, category, opts = {}) {
|
|
@@ -17006,7 +17577,11 @@ module.exports.setMode = (params) => {
|
|
|
17006
17577
|
* 5. Approval dialog detection (buttons, modal)
|
|
17007
17578
|
* 6. Input field selector
|
|
17008
17579
|
*
|
|
17009
|
-
*
|
|
17580
|
+
* Preferred live-state surface:
|
|
17581
|
+
* - controlValues: explicit current control selections (model/mode/etc.)
|
|
17582
|
+
* - summaryMetadata: compact always-visible metadata for dashboard/recent views
|
|
17583
|
+
* Legacy top-level model/mode output is no longer the preferred shape.
|
|
17584
|
+
* \u2192 { id, status, title, messages[], inputContent, activeModal, controlValues?, summaryMetadata? }
|
|
17010
17585
|
*/
|
|
17011
17586
|
(() => {
|
|
17012
17587
|
try {
|
|
@@ -17034,6 +17609,9 @@ module.exports.setMode = (params) => {
|
|
|
17034
17609
|
messages,
|
|
17035
17610
|
inputContent,
|
|
17036
17611
|
activeModal,
|
|
17612
|
+
// TODO: Return explicit selections when available, e.g.
|
|
17613
|
+
// controlValues: { model: selectedModel, mode: selectedMode },
|
|
17614
|
+
// summaryMetadata: { items: [{ id: 'model', value: selectedModelLabel || selectedModel, shortValue: selectedModel, order: 10 }] },
|
|
17037
17615
|
});
|
|
17038
17616
|
} catch(e) {
|
|
17039
17617
|
return JSON.stringify({ id: '', status: 'error', messages: [], error: e.message });
|
|
@@ -18412,7 +18990,7 @@ function getCliTargetBundle(ctx, type, instanceId) {
|
|
|
18412
18990
|
return { target, instance, adapter };
|
|
18413
18991
|
}
|
|
18414
18992
|
function sleep(ms) {
|
|
18415
|
-
return new Promise((
|
|
18993
|
+
return new Promise((resolve11) => setTimeout(resolve11, ms));
|
|
18416
18994
|
}
|
|
18417
18995
|
async function waitForCliReady(ctx, type, instanceId, timeoutMs) {
|
|
18418
18996
|
const startedAt = Date.now();
|
|
@@ -18774,7 +19352,6 @@ async function handleCliStatus(ctx, _req, res) {
|
|
|
18774
19352
|
lastMessage: s.activeChat?.messages?.slice(-1)[0] || null,
|
|
18775
19353
|
activeModal: s.activeChat?.activeModal || null,
|
|
18776
19354
|
pendingEvents: s.pendingEvents || [],
|
|
18777
|
-
currentModel: s.currentModel,
|
|
18778
19355
|
settings: s.settings
|
|
18779
19356
|
}));
|
|
18780
19357
|
ctx.json(res, 200, { instances: result, count: result.length });
|
|
@@ -19259,18 +19836,6 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
19259
19836
|
if (!fs13.existsSync(providerJson)) {
|
|
19260
19837
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
19261
19838
|
}
|
|
19262
|
-
try {
|
|
19263
|
-
const providerData = JSON.parse(fs13.readFileSync(providerJson, "utf-8"));
|
|
19264
|
-
if (providerData.disableUpstream !== true) {
|
|
19265
|
-
providerData.disableUpstream = true;
|
|
19266
|
-
fs13.writeFileSync(providerJson, JSON.stringify(providerData, null, 2));
|
|
19267
|
-
}
|
|
19268
|
-
} catch (error) {
|
|
19269
|
-
return {
|
|
19270
|
-
dir: null,
|
|
19271
|
-
reason: `Failed to update provider.json in writable provider directory: ${error.message}`
|
|
19272
|
-
};
|
|
19273
|
-
}
|
|
19274
19839
|
return { dir: desiredDir };
|
|
19275
19840
|
}
|
|
19276
19841
|
function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
@@ -19943,7 +20508,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
19943
20508
|
lines.push("## Required Return Format");
|
|
19944
20509
|
lines.push("| Function | Return JSON |");
|
|
19945
20510
|
lines.push("|---|---|");
|
|
19946
|
-
lines.push("| readChat | `{ id, status, title, messages: [{role, content, index, kind?, meta?}], inputContent, activeModal }` \u2014 optional `kind`: standard, thought, tool, terminal;
|
|
20511
|
+
lines.push("| readChat | `{ id, status, title, messages: [{role, content, index, kind?, meta?}], inputContent, activeModal, controlValues?, summaryMetadata? }` \u2014 optional `kind`: standard, thought, tool, terminal; prefer explicit `controlValues` for current selections and `summaryMetadata` for compact always-visible UI metadata |");
|
|
19947
20512
|
lines.push("| sendMessage | `{ sent: false, needsTypeAndSend: true, selector }` |");
|
|
19948
20513
|
lines.push("| resolveAction | `{ resolved: true/false, clicked? }` |");
|
|
19949
20514
|
lines.push("| listSessions | `{ sessions: [{ id, title, active, index }] }` |");
|
|
@@ -20557,6 +21122,7 @@ var DevServer = class _DevServer {
|
|
|
20557
21122
|
cdpManagers;
|
|
20558
21123
|
instanceManager;
|
|
20559
21124
|
cliManager;
|
|
21125
|
+
onProviderSourceConfigChanged;
|
|
20560
21126
|
logFn;
|
|
20561
21127
|
sseClients = [];
|
|
20562
21128
|
watchScriptPath = null;
|
|
@@ -20573,6 +21139,7 @@ var DevServer = class _DevServer {
|
|
|
20573
21139
|
this.cdpManagers = options.cdpManagers;
|
|
20574
21140
|
this.instanceManager = options.instanceManager || null;
|
|
20575
21141
|
this.cliManager = options.cliManager || null;
|
|
21142
|
+
this.onProviderSourceConfigChanged = options.onProviderSourceConfigChanged || null;
|
|
20576
21143
|
this.logFn = options.logFn || LOG.forComponent("DevServer").asLogFn();
|
|
20577
21144
|
}
|
|
20578
21145
|
log(msg) {
|
|
@@ -20582,6 +21149,8 @@ var DevServer = class _DevServer {
|
|
|
20582
21149
|
routes = [
|
|
20583
21150
|
// Static routes
|
|
20584
21151
|
{ method: "GET", pattern: "/api/providers", handler: (q, s) => this.handleListProviders(q, s) },
|
|
21152
|
+
{ method: "GET", pattern: "/api/providers/source-config", handler: (q, s) => this.handleGetProviderSourceConfig(q, s) },
|
|
21153
|
+
{ method: "POST", pattern: "/api/providers/source-config", handler: (q, s) => this.handleSetProviderSourceConfig(q, s) },
|
|
20585
21154
|
{ method: "GET", pattern: "/api/providers/versions", handler: (q, s) => this.handleDetectVersions(q, s) },
|
|
20586
21155
|
{ method: "POST", pattern: "/api/providers/reload", handler: (q, s) => this.handleReload(q, s) },
|
|
20587
21156
|
{ method: "POST", pattern: "/api/cdp/evaluate", handler: (q, s) => this.handleCdpEvaluate(q, s) },
|
|
@@ -20679,15 +21248,15 @@ var DevServer = class _DevServer {
|
|
|
20679
21248
|
this.json(res, 500, { error: e.message });
|
|
20680
21249
|
}
|
|
20681
21250
|
});
|
|
20682
|
-
return new Promise((
|
|
21251
|
+
return new Promise((resolve11, reject) => {
|
|
20683
21252
|
this.server.listen(port, "127.0.0.1", () => {
|
|
20684
21253
|
this.log(`Dev server listening on http://127.0.0.1:${port}`);
|
|
20685
|
-
|
|
21254
|
+
resolve11();
|
|
20686
21255
|
});
|
|
20687
21256
|
this.server.on("error", (e) => {
|
|
20688
21257
|
if (e.code === "EADDRINUSE") {
|
|
20689
21258
|
this.log(`Port ${port} in use, skipping dev server`);
|
|
20690
|
-
|
|
21259
|
+
resolve11();
|
|
20691
21260
|
} else {
|
|
20692
21261
|
reject(e);
|
|
20693
21262
|
}
|
|
@@ -20701,7 +21270,33 @@ var DevServer = class _DevServer {
|
|
|
20701
21270
|
// ─── Handlers ───
|
|
20702
21271
|
async handleListProviders(_req, res) {
|
|
20703
21272
|
const providers = this.providerLoader.getAll().map(toProviderListEntry);
|
|
20704
|
-
this.json(res, 200, { providers, count: providers.length });
|
|
21273
|
+
this.json(res, 200, { providers, count: providers.length, sourceConfig: this.providerLoader.getSourceConfig() });
|
|
21274
|
+
}
|
|
21275
|
+
async handleGetProviderSourceConfig(_req, res) {
|
|
21276
|
+
this.json(res, 200, { success: true, sourceConfig: this.providerLoader.getSourceConfig() });
|
|
21277
|
+
}
|
|
21278
|
+
async handleSetProviderSourceConfig(req, res) {
|
|
21279
|
+
const body = await this.readBody(req);
|
|
21280
|
+
const parsed = parseProviderSourceConfigUpdate(body || {});
|
|
21281
|
+
if (!parsed.ok) {
|
|
21282
|
+
this.json(res, 400, { success: false, error: parsed.error });
|
|
21283
|
+
return;
|
|
21284
|
+
}
|
|
21285
|
+
const currentConfig2 = loadConfig();
|
|
21286
|
+
const nextConfig = {
|
|
21287
|
+
...currentConfig2,
|
|
21288
|
+
...parsed.updates.providerSourceMode ? { providerSourceMode: parsed.updates.providerSourceMode } : {},
|
|
21289
|
+
...Object.prototype.hasOwnProperty.call(parsed.updates, "providerDir") ? { providerDir: parsed.updates.providerDir } : {}
|
|
21290
|
+
};
|
|
21291
|
+
saveConfig(nextConfig);
|
|
21292
|
+
const sourceConfig = this.providerLoader.applySourceConfig({
|
|
21293
|
+
sourceMode: nextConfig.providerSourceMode,
|
|
21294
|
+
userDir: Object.prototype.hasOwnProperty.call(parsed.updates, "providerDir") ? parsed.updates.providerDir : this.providerLoader.getSourceConfig().explicitProviderDir || void 0
|
|
21295
|
+
});
|
|
21296
|
+
this.providerLoader.reload();
|
|
21297
|
+
this.providerLoader.registerToDetector();
|
|
21298
|
+
await this.onProviderSourceConfigChanged?.();
|
|
21299
|
+
this.json(res, 200, { success: true, reloaded: true, sourceConfig });
|
|
20705
21300
|
}
|
|
20706
21301
|
async handleProviderConfig(type, _req, res) {
|
|
20707
21302
|
const provider = this.providerLoader.resolve(type);
|
|
@@ -20743,20 +21338,20 @@ var DevServer = class _DevServer {
|
|
|
20743
21338
|
child.stderr?.on("data", (d) => {
|
|
20744
21339
|
stderr += d.toString().slice(0, 2e3);
|
|
20745
21340
|
});
|
|
20746
|
-
await new Promise((
|
|
21341
|
+
await new Promise((resolve11) => {
|
|
20747
21342
|
const timer = setTimeout(() => {
|
|
20748
21343
|
child.kill();
|
|
20749
|
-
|
|
21344
|
+
resolve11();
|
|
20750
21345
|
}, 3e3);
|
|
20751
21346
|
child.on("exit", () => {
|
|
20752
21347
|
clearTimeout(timer);
|
|
20753
|
-
|
|
21348
|
+
resolve11();
|
|
20754
21349
|
});
|
|
20755
21350
|
child.stdout?.once("data", () => {
|
|
20756
21351
|
setTimeout(() => {
|
|
20757
21352
|
child.kill();
|
|
20758
21353
|
clearTimeout(timer);
|
|
20759
|
-
|
|
21354
|
+
resolve11();
|
|
20760
21355
|
}, 500);
|
|
20761
21356
|
});
|
|
20762
21357
|
});
|
|
@@ -21252,14 +21847,14 @@ var DevServer = class _DevServer {
|
|
|
21252
21847
|
child.stderr?.on("data", (d) => {
|
|
21253
21848
|
stderr += d.toString();
|
|
21254
21849
|
});
|
|
21255
|
-
await new Promise((
|
|
21850
|
+
await new Promise((resolve11) => {
|
|
21256
21851
|
const timer = setTimeout(() => {
|
|
21257
21852
|
child.kill();
|
|
21258
|
-
|
|
21853
|
+
resolve11();
|
|
21259
21854
|
}, timeout);
|
|
21260
21855
|
child.on("exit", () => {
|
|
21261
21856
|
clearTimeout(timer);
|
|
21262
|
-
|
|
21857
|
+
resolve11();
|
|
21263
21858
|
});
|
|
21264
21859
|
});
|
|
21265
21860
|
const elapsed = Date.now() - start;
|
|
@@ -21404,18 +21999,6 @@ var DevServer = class _DevServer {
|
|
|
21404
21999
|
if (!fs14.existsSync(providerJson)) {
|
|
21405
22000
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
21406
22001
|
}
|
|
21407
|
-
try {
|
|
21408
|
-
const providerData = JSON.parse(fs14.readFileSync(providerJson, "utf-8"));
|
|
21409
|
-
if (providerData.disableUpstream !== true) {
|
|
21410
|
-
providerData.disableUpstream = true;
|
|
21411
|
-
fs14.writeFileSync(providerJson, JSON.stringify(providerData, null, 2));
|
|
21412
|
-
}
|
|
21413
|
-
} catch (error) {
|
|
21414
|
-
return {
|
|
21415
|
-
dir: null,
|
|
21416
|
-
reason: `Failed to update provider.json in writable provider directory: ${error.message}`
|
|
21417
|
-
};
|
|
21418
|
-
}
|
|
21419
22002
|
return { dir: desiredDir };
|
|
21420
22003
|
}
|
|
21421
22004
|
async handleAutoImplement(type, req, res) {
|
|
@@ -21560,7 +22143,7 @@ var DevServer = class _DevServer {
|
|
|
21560
22143
|
lines.push("## Required Return Format");
|
|
21561
22144
|
lines.push("| Function | Return JSON |");
|
|
21562
22145
|
lines.push("|---|---|");
|
|
21563
|
-
lines.push("| readChat | `{ id, status, title, messages: [{role, content, index, kind?, meta?}], inputContent, activeModal }` \u2014 optional `kind`: standard, thought, tool, terminal;
|
|
22146
|
+
lines.push("| readChat | `{ id, status, title, messages: [{role, content, index, kind?, meta?}], inputContent, activeModal, controlValues?, summaryMetadata? }` \u2014 optional `kind`: standard, thought, tool, terminal; prefer explicit `controlValues` for current selections and `summaryMetadata` for compact always-visible UI metadata |");
|
|
21564
22147
|
lines.push("| sendMessage | `{ sent: false, needsTypeAndSend: true, selector }` |");
|
|
21565
22148
|
lines.push("| resolveAction | `{ resolved: true/false, clicked? }` |");
|
|
21566
22149
|
lines.push("| listSessions | `{ sessions: [{ id, title, active, index }] }` |");
|
|
@@ -21941,14 +22524,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
21941
22524
|
res.end(JSON.stringify(data, null, 2));
|
|
21942
22525
|
}
|
|
21943
22526
|
async readBody(req) {
|
|
21944
|
-
return new Promise((
|
|
22527
|
+
return new Promise((resolve11) => {
|
|
21945
22528
|
let body = "";
|
|
21946
22529
|
req.on("data", (chunk) => body += chunk);
|
|
21947
22530
|
req.on("end", () => {
|
|
21948
22531
|
try {
|
|
21949
|
-
|
|
22532
|
+
resolve11(JSON.parse(body));
|
|
21950
22533
|
} catch {
|
|
21951
|
-
|
|
22534
|
+
resolve11({});
|
|
21952
22535
|
}
|
|
21953
22536
|
});
|
|
21954
22537
|
});
|
|
@@ -22431,7 +23014,7 @@ async function waitForReady(endpoint, timeoutMs = STARTUP_TIMEOUT_MS) {
|
|
|
22431
23014
|
const deadline = Date.now() + timeoutMs;
|
|
22432
23015
|
while (Date.now() < deadline) {
|
|
22433
23016
|
if (await canConnect(endpoint)) return;
|
|
22434
|
-
await new Promise((
|
|
23017
|
+
await new Promise((resolve11) => setTimeout(resolve11, STARTUP_POLL_MS));
|
|
22435
23018
|
}
|
|
22436
23019
|
throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
|
|
22437
23020
|
}
|
|
@@ -22471,61 +23054,6 @@ async function listHostedCliRuntimes(endpoint) {
|
|
|
22471
23054
|
}
|
|
22472
23055
|
}
|
|
22473
23056
|
|
|
22474
|
-
// src/session-host/runtime-surface.ts
|
|
22475
|
-
var LIVE_LIFECYCLES = /* @__PURE__ */ new Set(["starting", "running", "stopping", "interrupted"]);
|
|
22476
|
-
function isSessionHostLiveRuntime(record) {
|
|
22477
|
-
const lifecycle = String(record?.lifecycle || "").trim();
|
|
22478
|
-
return LIVE_LIFECYCLES.has(lifecycle);
|
|
22479
|
-
}
|
|
22480
|
-
function getSessionHostRecoveryLabel(meta) {
|
|
22481
|
-
const recoveryState = typeof meta?.runtimeRecoveryState === "string" ? String(meta.runtimeRecoveryState).trim() : "";
|
|
22482
|
-
if (!recoveryState) return null;
|
|
22483
|
-
if (recoveryState === "auto_resumed") return "restored after restart";
|
|
22484
|
-
if (recoveryState === "resume_failed") return "restore failed";
|
|
22485
|
-
if (recoveryState === "host_restart_interrupted") return "host restart interrupted";
|
|
22486
|
-
if (recoveryState === "orphan_snapshot") return "snapshot recovered";
|
|
22487
|
-
return recoveryState.replace(/_/g, " ");
|
|
22488
|
-
}
|
|
22489
|
-
function isSessionHostRecoverySnapshot(record) {
|
|
22490
|
-
if (!record) return false;
|
|
22491
|
-
if (isSessionHostLiveRuntime(record)) return false;
|
|
22492
|
-
const lifecycle = String(record.lifecycle || "").trim();
|
|
22493
|
-
if (lifecycle && lifecycle !== "stopped" && lifecycle !== "failed") {
|
|
22494
|
-
return false;
|
|
22495
|
-
}
|
|
22496
|
-
const meta = record.meta || void 0;
|
|
22497
|
-
if (meta?.restoredFromStorage === true) return true;
|
|
22498
|
-
return getSessionHostRecoveryLabel(meta) !== null;
|
|
22499
|
-
}
|
|
22500
|
-
function getSessionHostSurfaceKind(record) {
|
|
22501
|
-
if (isSessionHostLiveRuntime(record)) return "live_runtime";
|
|
22502
|
-
if (isSessionHostRecoverySnapshot(record)) return "recovery_snapshot";
|
|
22503
|
-
return "inactive_record";
|
|
22504
|
-
}
|
|
22505
|
-
function partitionSessionHostRecords(records) {
|
|
22506
|
-
const liveRuntimes = [];
|
|
22507
|
-
const recoverySnapshots = [];
|
|
22508
|
-
const inactiveRecords = [];
|
|
22509
|
-
for (const record of records) {
|
|
22510
|
-
const kind = getSessionHostSurfaceKind(record);
|
|
22511
|
-
if (kind === "live_runtime") {
|
|
22512
|
-
liveRuntimes.push(record);
|
|
22513
|
-
} else if (kind === "recovery_snapshot") {
|
|
22514
|
-
recoverySnapshots.push(record);
|
|
22515
|
-
} else {
|
|
22516
|
-
inactiveRecords.push(record);
|
|
22517
|
-
}
|
|
22518
|
-
}
|
|
22519
|
-
return {
|
|
22520
|
-
liveRuntimes,
|
|
22521
|
-
recoverySnapshots,
|
|
22522
|
-
inactiveRecords
|
|
22523
|
-
};
|
|
22524
|
-
}
|
|
22525
|
-
function partitionSessionHostDiagnosticsSessions(records) {
|
|
22526
|
-
return partitionSessionHostRecords(records || []);
|
|
22527
|
-
}
|
|
22528
|
-
|
|
22529
23057
|
// src/session-host/startup-restore-policy.js
|
|
22530
23058
|
function shouldAutoRestoreHostedSessionsOnStartup(env = process.env) {
|
|
22531
23059
|
const raw = typeof env.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP === "string" ? env.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP.trim().toLowerCase() : "";
|
|
@@ -22662,10 +23190,10 @@ async function installExtension(ide, extension) {
|
|
|
22662
23190
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
22663
23191
|
const fs15 = await import("fs");
|
|
22664
23192
|
fs15.writeFileSync(vsixPath, buffer);
|
|
22665
|
-
return new Promise((
|
|
23193
|
+
return new Promise((resolve11) => {
|
|
22666
23194
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
22667
23195
|
exec2(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
|
|
22668
|
-
|
|
23196
|
+
resolve11({
|
|
22669
23197
|
extensionId: extension.id,
|
|
22670
23198
|
marketplaceId: extension.marketplaceId,
|
|
22671
23199
|
success: !error,
|
|
@@ -22678,11 +23206,11 @@ async function installExtension(ide, extension) {
|
|
|
22678
23206
|
} catch (e) {
|
|
22679
23207
|
}
|
|
22680
23208
|
}
|
|
22681
|
-
return new Promise((
|
|
23209
|
+
return new Promise((resolve11) => {
|
|
22682
23210
|
const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
|
|
22683
23211
|
exec2(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
|
|
22684
23212
|
if (error) {
|
|
22685
|
-
|
|
23213
|
+
resolve11({
|
|
22686
23214
|
extensionId: extension.id,
|
|
22687
23215
|
marketplaceId: extension.marketplaceId,
|
|
22688
23216
|
success: false,
|
|
@@ -22690,7 +23218,7 @@ async function installExtension(ide, extension) {
|
|
|
22690
23218
|
error: stderr || error.message
|
|
22691
23219
|
});
|
|
22692
23220
|
} else {
|
|
22693
|
-
|
|
23221
|
+
resolve11({
|
|
22694
23222
|
extensionId: extension.id,
|
|
22695
23223
|
marketplaceId: extension.marketplaceId,
|
|
22696
23224
|
success: true,
|
|
@@ -22787,10 +23315,11 @@ init_config();
|
|
|
22787
23315
|
async function initDaemonComponents(config) {
|
|
22788
23316
|
installGlobalInterceptor();
|
|
22789
23317
|
const appConfig = loadConfig();
|
|
22790
|
-
const
|
|
23318
|
+
const providerSourceMode = appConfig.providerSourceMode || "normal";
|
|
23319
|
+
const disableUpstream = providerSourceMode === "no-upstream";
|
|
22791
23320
|
const providerLoader = new ProviderLoader({
|
|
22792
23321
|
logFn: config.providerLogFn,
|
|
22793
|
-
|
|
23322
|
+
sourceMode: providerSourceMode,
|
|
22794
23323
|
userDir: appConfig.providerDir
|
|
22795
23324
|
});
|
|
22796
23325
|
if (!disableUpstream && !providerLoader.hasUpstream()) {
|
|
@@ -22895,6 +23424,10 @@ async function initDaemonComponents(config) {
|
|
|
22895
23424
|
onProviderSettingChanged: async (providerType) => {
|
|
22896
23425
|
await refreshProviderAvailability(providerType);
|
|
22897
23426
|
config.onStatusChange?.();
|
|
23427
|
+
},
|
|
23428
|
+
onProviderSourceConfigChanged: async () => {
|
|
23429
|
+
await refreshProviderAvailability();
|
|
23430
|
+
config.onStatusChange?.();
|
|
22898
23431
|
}
|
|
22899
23432
|
});
|
|
22900
23433
|
agentStreamManager = new DaemonAgentStreamManager(
|
|
@@ -22944,7 +23477,8 @@ async function initDaemonComponents(config) {
|
|
|
22944
23477
|
cdpInitializer,
|
|
22945
23478
|
cdpManagers,
|
|
22946
23479
|
sessionRegistry,
|
|
22947
|
-
detectedIdes: detectedIdesRef
|
|
23480
|
+
detectedIdes: detectedIdesRef,
|
|
23481
|
+
refreshProviderAvailability
|
|
22948
23482
|
};
|
|
22949
23483
|
}
|
|
22950
23484
|
async function startDaemonDevSupport(options) {
|
|
@@ -22953,7 +23487,10 @@ async function startDaemonDevSupport(options) {
|
|
|
22953
23487
|
cdpManagers: options.components.cdpManagers,
|
|
22954
23488
|
instanceManager: options.components.instanceManager,
|
|
22955
23489
|
cliManager: options.components.cliManager,
|
|
22956
|
-
logFn: options.logFn
|
|
23490
|
+
logFn: options.logFn,
|
|
23491
|
+
onProviderSourceConfigChanged: async () => {
|
|
23492
|
+
await options.components.refreshProviderAvailability();
|
|
23493
|
+
}
|
|
22957
23494
|
});
|
|
22958
23495
|
await devServer.start();
|
|
22959
23496
|
options.components.providerLoader.watch();
|
|
@@ -23079,6 +23616,7 @@ export {
|
|
|
23079
23616
|
normalizeInputEnvelope,
|
|
23080
23617
|
normalizeManagedStatus,
|
|
23081
23618
|
normalizeMessageParts,
|
|
23619
|
+
parseProviderSourceConfigUpdate,
|
|
23082
23620
|
partitionSessionHostDiagnosticsSessions,
|
|
23083
23621
|
partitionSessionHostRecords,
|
|
23084
23622
|
probeCdpPort,
|