@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.js
CHANGED
|
@@ -40,9 +40,16 @@ __export(config_exports, {
|
|
|
40
40
|
loadConfig: () => loadConfig,
|
|
41
41
|
markSetupComplete: () => markSetupComplete,
|
|
42
42
|
resetConfig: () => resetConfig,
|
|
43
|
+
resolveProviderSourceMode: () => resolveProviderSourceMode,
|
|
43
44
|
saveConfig: () => saveConfig,
|
|
44
45
|
updateConfig: () => updateConfig
|
|
45
46
|
});
|
|
47
|
+
function resolveProviderSourceMode(providerSourceMode, legacyDisableUpstream) {
|
|
48
|
+
if (providerSourceMode === "normal" || providerSourceMode === "no-upstream") {
|
|
49
|
+
return providerSourceMode;
|
|
50
|
+
}
|
|
51
|
+
return legacyDisableUpstream === true ? "no-upstream" : "normal";
|
|
52
|
+
}
|
|
46
53
|
function isPlainObject(value) {
|
|
47
54
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
48
55
|
}
|
|
@@ -80,7 +87,7 @@ function normalizeConfig(raw) {
|
|
|
80
87
|
registeredMachineId: asOptionalString(parsed.registeredMachineId),
|
|
81
88
|
providerSettings: isPlainObject(parsed.providerSettings) ? parsed.providerSettings : {},
|
|
82
89
|
ideSettings: isPlainObject(parsed.ideSettings) ? parsed.ideSettings : {},
|
|
83
|
-
|
|
90
|
+
providerSourceMode: resolveProviderSourceMode(parsed.providerSourceMode, parsed.disableUpstream),
|
|
84
91
|
providerDir: asOptionalString(parsed.providerDir),
|
|
85
92
|
terminalSizingMode: parsed.terminalSizingMode === "fit" ? "fit" : "measured"
|
|
86
93
|
};
|
|
@@ -229,7 +236,7 @@ var init_config = __esm({
|
|
|
229
236
|
registeredMachineId: void 0,
|
|
230
237
|
providerSettings: {},
|
|
231
238
|
ideSettings: {},
|
|
232
|
-
|
|
239
|
+
providerSourceMode: "normal",
|
|
233
240
|
terminalSizingMode: "measured"
|
|
234
241
|
};
|
|
235
242
|
MACHINE_ID_PREFIX = "mach_";
|
|
@@ -1897,7 +1904,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
1897
1904
|
`[${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)}`
|
|
1898
1905
|
);
|
|
1899
1906
|
}
|
|
1900
|
-
await new Promise((
|
|
1907
|
+
await new Promise((resolve11) => setTimeout(resolve11, 50));
|
|
1901
1908
|
}
|
|
1902
1909
|
const finalScreenText = this.terminalScreen.getText() || "";
|
|
1903
1910
|
LOG.warn(
|
|
@@ -2470,7 +2477,7 @@ ${data.message || ""}`.trim();
|
|
|
2470
2477
|
const deadline = Date.now() + 1e4;
|
|
2471
2478
|
while (this.startupParseGate && Date.now() < deadline) {
|
|
2472
2479
|
this.resolveStartupState("send_wait");
|
|
2473
|
-
await new Promise((
|
|
2480
|
+
await new Promise((resolve11) => setTimeout(resolve11, 50));
|
|
2474
2481
|
}
|
|
2475
2482
|
}
|
|
2476
2483
|
await this.waitForInteractivePrompt();
|
|
@@ -2540,12 +2547,12 @@ ${data.message || ""}`.trim();
|
|
|
2540
2547
|
if (this.isWaitingForResponse) this.finishResponse();
|
|
2541
2548
|
}, this.timeouts.maxResponse);
|
|
2542
2549
|
};
|
|
2543
|
-
await new Promise((
|
|
2550
|
+
await new Promise((resolve11) => {
|
|
2544
2551
|
let resolved = false;
|
|
2545
2552
|
const resolveOnce = () => {
|
|
2546
2553
|
if (resolved) return;
|
|
2547
2554
|
resolved = true;
|
|
2548
|
-
|
|
2555
|
+
resolve11();
|
|
2549
2556
|
};
|
|
2550
2557
|
const submit = () => {
|
|
2551
2558
|
if (!this.ptyProcess) {
|
|
@@ -2719,17 +2726,17 @@ ${data.message || ""}`.trim();
|
|
|
2719
2726
|
}
|
|
2720
2727
|
}
|
|
2721
2728
|
waitForStopped(timeoutMs) {
|
|
2722
|
-
return new Promise((
|
|
2729
|
+
return new Promise((resolve11) => {
|
|
2723
2730
|
const startedAt = Date.now();
|
|
2724
2731
|
const timer = setInterval(() => {
|
|
2725
2732
|
if (!this.ptyProcess || this.currentStatus === "stopped") {
|
|
2726
2733
|
clearInterval(timer);
|
|
2727
|
-
|
|
2734
|
+
resolve11(true);
|
|
2728
2735
|
return;
|
|
2729
2736
|
}
|
|
2730
2737
|
if (Date.now() - startedAt >= timeoutMs) {
|
|
2731
2738
|
clearInterval(timer);
|
|
2732
|
-
|
|
2739
|
+
resolve11(false);
|
|
2733
2740
|
}
|
|
2734
2741
|
}, 100);
|
|
2735
2742
|
});
|
|
@@ -3084,6 +3091,7 @@ __export(index_exports, {
|
|
|
3084
3091
|
normalizeInputEnvelope: () => normalizeInputEnvelope,
|
|
3085
3092
|
normalizeManagedStatus: () => normalizeManagedStatus,
|
|
3086
3093
|
normalizeMessageParts: () => normalizeMessageParts,
|
|
3094
|
+
parseProviderSourceConfigUpdate: () => parseProviderSourceConfigUpdate,
|
|
3087
3095
|
partitionSessionHostDiagnosticsSessions: () => partitionSessionHostDiagnosticsSessions,
|
|
3088
3096
|
partitionSessionHostRecords: () => partitionSessionHostRecords,
|
|
3089
3097
|
probeCdpPort: () => probeCdpPort,
|
|
@@ -3279,6 +3287,70 @@ function setDefaultWorkspaceId(config, id) {
|
|
|
3279
3287
|
|
|
3280
3288
|
// src/config/recent-activity.ts
|
|
3281
3289
|
var path2 = __toESM(require("path"));
|
|
3290
|
+
|
|
3291
|
+
// src/providers/summary-metadata.ts
|
|
3292
|
+
function normalizeSummaryItem(item) {
|
|
3293
|
+
if (!item || typeof item !== "object") return null;
|
|
3294
|
+
const id = String(item.id || "").trim();
|
|
3295
|
+
const value = String(item.value || "").trim();
|
|
3296
|
+
if (!id || !value) return null;
|
|
3297
|
+
const normalized = {
|
|
3298
|
+
id,
|
|
3299
|
+
value
|
|
3300
|
+
};
|
|
3301
|
+
if (typeof item.label === "string" && item.label.trim()) normalized.label = item.label.trim();
|
|
3302
|
+
if (typeof item.shortValue === "string" && item.shortValue.trim()) normalized.shortValue = item.shortValue.trim();
|
|
3303
|
+
if (typeof item.icon === "string" && item.icon.trim()) normalized.icon = item.icon.trim();
|
|
3304
|
+
if (typeof item.order === "number" && Number.isFinite(item.order)) normalized.order = item.order;
|
|
3305
|
+
return normalized;
|
|
3306
|
+
}
|
|
3307
|
+
function normalizeProviderSummaryMetadata(summary) {
|
|
3308
|
+
if (!summary || !Array.isArray(summary.items)) return void 0;
|
|
3309
|
+
const items = summary.items.map((item) => normalizeSummaryItem(item)).filter((item) => !!item).sort((left, right) => {
|
|
3310
|
+
const orderDiff = (left.order ?? Number.MAX_SAFE_INTEGER) - (right.order ?? Number.MAX_SAFE_INTEGER);
|
|
3311
|
+
if (orderDiff !== 0) return orderDiff;
|
|
3312
|
+
return left.id.localeCompare(right.id);
|
|
3313
|
+
});
|
|
3314
|
+
return items.length > 0 ? { items } : void 0;
|
|
3315
|
+
}
|
|
3316
|
+
function buildProviderSummaryMetadata(items) {
|
|
3317
|
+
return normalizeProviderSummaryMetadata({ items: items.filter(Boolean) });
|
|
3318
|
+
}
|
|
3319
|
+
function buildLegacyModelModeSummaryMetadata(params) {
|
|
3320
|
+
return buildProviderSummaryMetadata([
|
|
3321
|
+
params.model ? {
|
|
3322
|
+
id: "model",
|
|
3323
|
+
label: "Model",
|
|
3324
|
+
value: String(params.modelLabel || params.model).trim(),
|
|
3325
|
+
shortValue: String(params.model).trim(),
|
|
3326
|
+
order: 10
|
|
3327
|
+
} : null,
|
|
3328
|
+
params.mode ? {
|
|
3329
|
+
id: "mode",
|
|
3330
|
+
label: "Mode",
|
|
3331
|
+
value: String(params.modeLabel || params.mode).trim(),
|
|
3332
|
+
shortValue: String(params.mode).trim(),
|
|
3333
|
+
order: 20
|
|
3334
|
+
} : null
|
|
3335
|
+
]);
|
|
3336
|
+
}
|
|
3337
|
+
function resolveProviderStateSummaryMetadata(params) {
|
|
3338
|
+
const explicit = normalizeProviderSummaryMetadata(params.summaryMetadata);
|
|
3339
|
+
if (explicit) return explicit;
|
|
3340
|
+
const model = typeof params.controlValues?.model === "string" ? params.controlValues.model : void 0;
|
|
3341
|
+
const mode = typeof params.controlValues?.mode === "string" ? params.controlValues.mode : void 0;
|
|
3342
|
+
return buildLegacyModelModeSummaryMetadata({
|
|
3343
|
+
model,
|
|
3344
|
+
mode,
|
|
3345
|
+
modelLabel: params.modelLabel,
|
|
3346
|
+
modeLabel: params.modeLabel
|
|
3347
|
+
});
|
|
3348
|
+
}
|
|
3349
|
+
function normalizePersistedSummaryMetadata(params) {
|
|
3350
|
+
return normalizeProviderSummaryMetadata(params.summaryMetadata);
|
|
3351
|
+
}
|
|
3352
|
+
|
|
3353
|
+
// src/config/recent-activity.ts
|
|
3282
3354
|
var MAX_ACTIVITY = 30;
|
|
3283
3355
|
function normalizeWorkspace(workspace) {
|
|
3284
3356
|
if (!workspace) return "";
|
|
@@ -3302,6 +3374,9 @@ function appendRecentActivity(state, entry) {
|
|
|
3302
3374
|
const nextEntry = {
|
|
3303
3375
|
...entry,
|
|
3304
3376
|
workspace: entry.workspace ? normalizeWorkspace(entry.workspace) : void 0,
|
|
3377
|
+
summaryMetadata: normalizePersistedSummaryMetadata({
|
|
3378
|
+
summaryMetadata: entry.summaryMetadata
|
|
3379
|
+
}),
|
|
3305
3380
|
id: buildRecentActivityKeyForEntry(entry),
|
|
3306
3381
|
lastUsedAt: entry.lastUsedAt || Date.now()
|
|
3307
3382
|
};
|
|
@@ -3312,7 +3387,12 @@ function appendRecentActivity(state, entry) {
|
|
|
3312
3387
|
};
|
|
3313
3388
|
}
|
|
3314
3389
|
function getRecentActivity(state, limit = 20) {
|
|
3315
|
-
return [...state.recentActivity || []].
|
|
3390
|
+
return [...state.recentActivity || []].map((entry) => ({
|
|
3391
|
+
...entry,
|
|
3392
|
+
summaryMetadata: normalizePersistedSummaryMetadata({
|
|
3393
|
+
summaryMetadata: entry.summaryMetadata
|
|
3394
|
+
})
|
|
3395
|
+
})).sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, limit);
|
|
3316
3396
|
}
|
|
3317
3397
|
function getSessionSeenAt(state, sessionId) {
|
|
3318
3398
|
return state.sessionReads?.[sessionId] || 0;
|
|
@@ -3364,7 +3444,9 @@ function upsertSavedProviderSession(state, entry) {
|
|
|
3364
3444
|
providerName: entry.providerName,
|
|
3365
3445
|
providerSessionId,
|
|
3366
3446
|
workspace: entry.workspace ? normalizeWorkspace2(entry.workspace) : void 0,
|
|
3367
|
-
|
|
3447
|
+
summaryMetadata: normalizePersistedSummaryMetadata({
|
|
3448
|
+
summaryMetadata: entry.summaryMetadata
|
|
3449
|
+
}),
|
|
3368
3450
|
title: entry.title,
|
|
3369
3451
|
createdAt: existing?.createdAt || entry.createdAt || Date.now(),
|
|
3370
3452
|
lastUsedAt: entry.lastUsedAt || Date.now()
|
|
@@ -3380,7 +3462,12 @@ function getSavedProviderSessions(state, filters) {
|
|
|
3380
3462
|
if (filters?.providerType && entry.providerType !== filters.providerType) return false;
|
|
3381
3463
|
if (filters?.kind && entry.kind !== filters.kind) return false;
|
|
3382
3464
|
return true;
|
|
3383
|
-
}).
|
|
3465
|
+
}).map((entry) => ({
|
|
3466
|
+
...entry,
|
|
3467
|
+
summaryMetadata: normalizePersistedSummaryMetadata({
|
|
3468
|
+
summaryMetadata: entry.summaryMetadata
|
|
3469
|
+
})
|
|
3470
|
+
})).sort((a, b) => b.lastUsedAt - a.lastUsedAt);
|
|
3384
3471
|
}
|
|
3385
3472
|
|
|
3386
3473
|
// src/config/state-store.ts
|
|
@@ -3576,15 +3663,15 @@ function resolveCommandPath(command) {
|
|
|
3576
3663
|
return null;
|
|
3577
3664
|
}
|
|
3578
3665
|
function execAsync(cmd, timeoutMs = 5e3) {
|
|
3579
|
-
return new Promise((
|
|
3666
|
+
return new Promise((resolve11) => {
|
|
3580
3667
|
const child = (0, import_child_process2.exec)(cmd, { encoding: "utf-8", timeout: timeoutMs }, (err, stdout) => {
|
|
3581
3668
|
if (err || !stdout?.trim()) {
|
|
3582
|
-
|
|
3669
|
+
resolve11(null);
|
|
3583
3670
|
} else {
|
|
3584
|
-
|
|
3671
|
+
resolve11(stdout.trim());
|
|
3585
3672
|
}
|
|
3586
3673
|
});
|
|
3587
|
-
child.on("error", () =>
|
|
3674
|
+
child.on("error", () => resolve11(null));
|
|
3588
3675
|
});
|
|
3589
3676
|
}
|
|
3590
3677
|
async function detectCLIs(providerLoader, options) {
|
|
@@ -3795,7 +3882,7 @@ var DaemonCdpManager = class {
|
|
|
3795
3882
|
* Returns multiple entries if multiple IDE windows are open on same port
|
|
3796
3883
|
*/
|
|
3797
3884
|
static listAllTargets(port) {
|
|
3798
|
-
return new Promise((
|
|
3885
|
+
return new Promise((resolve11) => {
|
|
3799
3886
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
3800
3887
|
let data = "";
|
|
3801
3888
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -3811,16 +3898,16 @@ var DaemonCdpManager = class {
|
|
|
3811
3898
|
(t) => !isNonMain(t.title || "") && t.url?.includes("workbench.html") && !t.url?.includes("agent")
|
|
3812
3899
|
);
|
|
3813
3900
|
const fallbackPages = pages.filter((t) => !isNonMain(t.title || ""));
|
|
3814
|
-
|
|
3901
|
+
resolve11(mainPages.length > 0 ? mainPages : fallbackPages);
|
|
3815
3902
|
} catch {
|
|
3816
|
-
|
|
3903
|
+
resolve11([]);
|
|
3817
3904
|
}
|
|
3818
3905
|
});
|
|
3819
3906
|
});
|
|
3820
|
-
req.on("error", () =>
|
|
3907
|
+
req.on("error", () => resolve11([]));
|
|
3821
3908
|
req.setTimeout(2e3, () => {
|
|
3822
3909
|
req.destroy();
|
|
3823
|
-
|
|
3910
|
+
resolve11([]);
|
|
3824
3911
|
});
|
|
3825
3912
|
});
|
|
3826
3913
|
}
|
|
@@ -3860,7 +3947,7 @@ var DaemonCdpManager = class {
|
|
|
3860
3947
|
}
|
|
3861
3948
|
}
|
|
3862
3949
|
findTargetOnPort(port) {
|
|
3863
|
-
return new Promise((
|
|
3950
|
+
return new Promise((resolve11) => {
|
|
3864
3951
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
3865
3952
|
let data = "";
|
|
3866
3953
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -3871,7 +3958,7 @@ var DaemonCdpManager = class {
|
|
|
3871
3958
|
(t) => (t.type === "page" || t.type === "browser" || t.type === "Page") && t.webSocketDebuggerUrl
|
|
3872
3959
|
);
|
|
3873
3960
|
if (pages.length === 0) {
|
|
3874
|
-
|
|
3961
|
+
resolve11(targets.find((t) => t.webSocketDebuggerUrl) || null);
|
|
3875
3962
|
return;
|
|
3876
3963
|
}
|
|
3877
3964
|
const mainPages = pages.filter((t) => !this.isNonMainTitle(t.title || ""));
|
|
@@ -3881,24 +3968,24 @@ var DaemonCdpManager = class {
|
|
|
3881
3968
|
const specific = list.find((t) => t.id === this._targetId);
|
|
3882
3969
|
if (specific) {
|
|
3883
3970
|
this._pageTitle = specific.title || "";
|
|
3884
|
-
|
|
3971
|
+
resolve11(specific);
|
|
3885
3972
|
} else {
|
|
3886
3973
|
this.log(`[CDP] Target ${this._targetId} not found in page list`);
|
|
3887
|
-
|
|
3974
|
+
resolve11(null);
|
|
3888
3975
|
}
|
|
3889
3976
|
return;
|
|
3890
3977
|
}
|
|
3891
3978
|
this._pageTitle = list[0]?.title || "";
|
|
3892
|
-
|
|
3979
|
+
resolve11(list[0]);
|
|
3893
3980
|
} catch {
|
|
3894
|
-
|
|
3981
|
+
resolve11(null);
|
|
3895
3982
|
}
|
|
3896
3983
|
});
|
|
3897
3984
|
});
|
|
3898
|
-
req.on("error", () =>
|
|
3985
|
+
req.on("error", () => resolve11(null));
|
|
3899
3986
|
req.setTimeout(2e3, () => {
|
|
3900
3987
|
req.destroy();
|
|
3901
|
-
|
|
3988
|
+
resolve11(null);
|
|
3902
3989
|
});
|
|
3903
3990
|
});
|
|
3904
3991
|
}
|
|
@@ -3909,7 +3996,7 @@ var DaemonCdpManager = class {
|
|
|
3909
3996
|
this.extensionProviders = providers;
|
|
3910
3997
|
}
|
|
3911
3998
|
connectToTarget(wsUrl) {
|
|
3912
|
-
return new Promise((
|
|
3999
|
+
return new Promise((resolve11) => {
|
|
3913
4000
|
this.ws = new import_ws.default(wsUrl);
|
|
3914
4001
|
this.ws.on("open", async () => {
|
|
3915
4002
|
this._connected = true;
|
|
@@ -3919,17 +4006,17 @@ var DaemonCdpManager = class {
|
|
|
3919
4006
|
}
|
|
3920
4007
|
this.connectBrowserWs().catch(() => {
|
|
3921
4008
|
});
|
|
3922
|
-
|
|
4009
|
+
resolve11(true);
|
|
3923
4010
|
});
|
|
3924
4011
|
this.ws.on("message", (data) => {
|
|
3925
4012
|
try {
|
|
3926
4013
|
const msg = JSON.parse(data.toString());
|
|
3927
4014
|
if (msg.id && this.pending.has(msg.id)) {
|
|
3928
|
-
const { resolve:
|
|
4015
|
+
const { resolve: resolve12, reject } = this.pending.get(msg.id);
|
|
3929
4016
|
this.pending.delete(msg.id);
|
|
3930
4017
|
this.failureCount = 0;
|
|
3931
4018
|
if (msg.error) reject(new Error(msg.error.message));
|
|
3932
|
-
else
|
|
4019
|
+
else resolve12(msg.result);
|
|
3933
4020
|
} else if (msg.method === "Runtime.executionContextCreated") {
|
|
3934
4021
|
this.contexts.add(msg.params.context.id);
|
|
3935
4022
|
} else if (msg.method === "Runtime.executionContextDestroyed") {
|
|
@@ -3952,7 +4039,7 @@ var DaemonCdpManager = class {
|
|
|
3952
4039
|
this.ws.on("error", (err) => {
|
|
3953
4040
|
this.log(`[CDP] WebSocket error: ${err.message}`);
|
|
3954
4041
|
this._connected = false;
|
|
3955
|
-
|
|
4042
|
+
resolve11(false);
|
|
3956
4043
|
});
|
|
3957
4044
|
});
|
|
3958
4045
|
}
|
|
@@ -3966,7 +4053,7 @@ var DaemonCdpManager = class {
|
|
|
3966
4053
|
return;
|
|
3967
4054
|
}
|
|
3968
4055
|
this.log(`[CDP] Connecting browser WS for target discovery...`);
|
|
3969
|
-
await new Promise((
|
|
4056
|
+
await new Promise((resolve11, reject) => {
|
|
3970
4057
|
this.browserWs = new import_ws.default(browserWsUrl);
|
|
3971
4058
|
this.browserWs.on("open", async () => {
|
|
3972
4059
|
this._browserConnected = true;
|
|
@@ -3976,16 +4063,16 @@ var DaemonCdpManager = class {
|
|
|
3976
4063
|
} catch (e) {
|
|
3977
4064
|
this.log(`[CDP] setDiscoverTargets failed: ${e.message}`);
|
|
3978
4065
|
}
|
|
3979
|
-
|
|
4066
|
+
resolve11();
|
|
3980
4067
|
});
|
|
3981
4068
|
this.browserWs.on("message", (data) => {
|
|
3982
4069
|
try {
|
|
3983
4070
|
const msg = JSON.parse(data.toString());
|
|
3984
4071
|
if (msg.id && this.browserPending.has(msg.id)) {
|
|
3985
|
-
const { resolve:
|
|
4072
|
+
const { resolve: resolve12, reject: reject2 } = this.browserPending.get(msg.id);
|
|
3986
4073
|
this.browserPending.delete(msg.id);
|
|
3987
4074
|
if (msg.error) reject2(new Error(msg.error.message));
|
|
3988
|
-
else
|
|
4075
|
+
else resolve12(msg.result);
|
|
3989
4076
|
}
|
|
3990
4077
|
} catch {
|
|
3991
4078
|
}
|
|
@@ -4005,31 +4092,31 @@ var DaemonCdpManager = class {
|
|
|
4005
4092
|
}
|
|
4006
4093
|
}
|
|
4007
4094
|
getBrowserWsUrl() {
|
|
4008
|
-
return new Promise((
|
|
4095
|
+
return new Promise((resolve11) => {
|
|
4009
4096
|
const req = http.get(`http://127.0.0.1:${this.port}/json/version`, (res) => {
|
|
4010
4097
|
let data = "";
|
|
4011
4098
|
res.on("data", (chunk) => data += chunk.toString());
|
|
4012
4099
|
res.on("end", () => {
|
|
4013
4100
|
try {
|
|
4014
4101
|
const info = JSON.parse(data);
|
|
4015
|
-
|
|
4102
|
+
resolve11(info.webSocketDebuggerUrl || null);
|
|
4016
4103
|
} catch {
|
|
4017
|
-
|
|
4104
|
+
resolve11(null);
|
|
4018
4105
|
}
|
|
4019
4106
|
});
|
|
4020
4107
|
});
|
|
4021
|
-
req.on("error", () =>
|
|
4108
|
+
req.on("error", () => resolve11(null));
|
|
4022
4109
|
req.setTimeout(3e3, () => {
|
|
4023
4110
|
req.destroy();
|
|
4024
|
-
|
|
4111
|
+
resolve11(null);
|
|
4025
4112
|
});
|
|
4026
4113
|
});
|
|
4027
4114
|
}
|
|
4028
4115
|
sendBrowser(method, params = {}, timeoutMs = 15e3) {
|
|
4029
|
-
return new Promise((
|
|
4116
|
+
return new Promise((resolve11, reject) => {
|
|
4030
4117
|
if (!this.browserWs || !this._browserConnected) return reject(new Error("Browser WS not connected"));
|
|
4031
4118
|
const id = this.browserMsgId++;
|
|
4032
|
-
this.browserPending.set(id, { resolve:
|
|
4119
|
+
this.browserPending.set(id, { resolve: resolve11, reject });
|
|
4033
4120
|
this.browserWs.send(JSON.stringify({ id, method, params }));
|
|
4034
4121
|
setTimeout(() => {
|
|
4035
4122
|
if (this.browserPending.has(id)) {
|
|
@@ -4069,11 +4156,11 @@ var DaemonCdpManager = class {
|
|
|
4069
4156
|
}
|
|
4070
4157
|
// ─── CDP Protocol ────────────────────────────────────────
|
|
4071
4158
|
sendInternal(method, params = {}, timeoutMs = 15e3) {
|
|
4072
|
-
return new Promise((
|
|
4159
|
+
return new Promise((resolve11, reject) => {
|
|
4073
4160
|
if (!this.ws || !this._connected) return reject(new Error("CDP not connected"));
|
|
4074
4161
|
if (this.ws.readyState !== import_ws.default.OPEN) return reject(new Error("WebSocket not open"));
|
|
4075
4162
|
const id = this.msgId++;
|
|
4076
|
-
this.pending.set(id, { resolve:
|
|
4163
|
+
this.pending.set(id, { resolve: resolve11, reject });
|
|
4077
4164
|
this.ws.send(JSON.stringify({ id, method, params }));
|
|
4078
4165
|
setTimeout(() => {
|
|
4079
4166
|
if (this.pending.has(id)) {
|
|
@@ -4322,7 +4409,7 @@ var DaemonCdpManager = class {
|
|
|
4322
4409
|
const browserWs = this.browserWs;
|
|
4323
4410
|
let msgId = this.browserMsgId;
|
|
4324
4411
|
const sendWs = (method, params = {}, sessionId) => {
|
|
4325
|
-
return new Promise((
|
|
4412
|
+
return new Promise((resolve11, reject) => {
|
|
4326
4413
|
const mid = msgId++;
|
|
4327
4414
|
this.browserMsgId = msgId;
|
|
4328
4415
|
const handler = (raw) => {
|
|
@@ -4331,7 +4418,7 @@ var DaemonCdpManager = class {
|
|
|
4331
4418
|
if (msg.id === mid) {
|
|
4332
4419
|
browserWs.removeListener("message", handler);
|
|
4333
4420
|
if (msg.error) reject(new Error(msg.error.message || JSON.stringify(msg.error)));
|
|
4334
|
-
else
|
|
4421
|
+
else resolve11(msg.result);
|
|
4335
4422
|
}
|
|
4336
4423
|
} catch {
|
|
4337
4424
|
}
|
|
@@ -4532,14 +4619,14 @@ var DaemonCdpManager = class {
|
|
|
4532
4619
|
if (!ws || ws.readyState !== import_ws.default.OPEN) {
|
|
4533
4620
|
throw new Error("CDP not connected");
|
|
4534
4621
|
}
|
|
4535
|
-
return new Promise((
|
|
4622
|
+
return new Promise((resolve11, reject) => {
|
|
4536
4623
|
const id = getNextId();
|
|
4537
4624
|
pendingMap.set(id, {
|
|
4538
4625
|
resolve: (result) => {
|
|
4539
4626
|
if (result?.result?.subtype === "error") {
|
|
4540
4627
|
reject(new Error(result.result.description));
|
|
4541
4628
|
} else {
|
|
4542
|
-
|
|
4629
|
+
resolve11(result?.result?.value);
|
|
4543
4630
|
}
|
|
4544
4631
|
},
|
|
4545
4632
|
reject
|
|
@@ -4571,10 +4658,10 @@ var DaemonCdpManager = class {
|
|
|
4571
4658
|
throw new Error("CDP not connected");
|
|
4572
4659
|
}
|
|
4573
4660
|
const sendViaSession = (method, params = {}) => {
|
|
4574
|
-
return new Promise((
|
|
4661
|
+
return new Promise((resolve11, reject) => {
|
|
4575
4662
|
const pendingMap = this._browserConnected ? this.browserPending : this.pending;
|
|
4576
4663
|
const id = this._browserConnected ? this.browserMsgId++ : this.msgId++;
|
|
4577
|
-
pendingMap.set(id, { resolve:
|
|
4664
|
+
pendingMap.set(id, { resolve: resolve11, reject });
|
|
4578
4665
|
ws.send(JSON.stringify({ id, sessionId, method, params }));
|
|
4579
4666
|
setTimeout(() => {
|
|
4580
4667
|
if (pendingMap.has(id)) {
|
|
@@ -5137,8 +5224,6 @@ function extractProviderControlValues(controls, data) {
|
|
|
5137
5224
|
if (rawValue === void 0 || rawValue === null) continue;
|
|
5138
5225
|
values[ctrl.id] = normalizeControlValue(rawValue);
|
|
5139
5226
|
}
|
|
5140
|
-
if (data.model !== void 0 && values.model === void 0) values.model = normalizeControlValue(data.model);
|
|
5141
|
-
if (data.mode !== void 0 && values.mode === void 0) values.mode = normalizeControlValue(data.mode);
|
|
5142
5227
|
return Object.keys(values).length > 0 ? values : void 0;
|
|
5143
5228
|
}
|
|
5144
5229
|
function normalizeProviderEffects(data) {
|
|
@@ -5240,7 +5325,7 @@ function normalizeControlOption(option) {
|
|
|
5240
5325
|
}
|
|
5241
5326
|
if (!option || typeof option !== "object") return null;
|
|
5242
5327
|
const record = option;
|
|
5243
|
-
const value = typeof record.value === "string" ? record.value : typeof record.id === "string" ? record.id : null;
|
|
5328
|
+
const value = typeof record.value === "string" ? record.value : typeof record.id === "string" ? record.id : typeof record.name === "string" ? record.name : null;
|
|
5244
5329
|
if (!value) return null;
|
|
5245
5330
|
const label = typeof record.label === "string" ? record.label : typeof record.name === "string" ? record.name : value;
|
|
5246
5331
|
const normalized = { value, label };
|
|
@@ -5484,6 +5569,30 @@ var ChatHistoryWriter = class {
|
|
|
5484
5569
|
options.historySessionId
|
|
5485
5570
|
);
|
|
5486
5571
|
}
|
|
5572
|
+
writeSessionStart(agentType, historySessionId, workspace, instanceId) {
|
|
5573
|
+
const id = String(historySessionId || "").trim();
|
|
5574
|
+
const ws = String(workspace || "").trim();
|
|
5575
|
+
if (!id || !ws) return;
|
|
5576
|
+
try {
|
|
5577
|
+
const dir = path7.join(HISTORY_DIR, this.sanitize(agentType));
|
|
5578
|
+
fs3.mkdirSync(dir, { recursive: true });
|
|
5579
|
+
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
5580
|
+
const filePath = path7.join(dir, `${this.sanitize(id)}_${date}.jsonl`);
|
|
5581
|
+
const record = {
|
|
5582
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5583
|
+
receivedAt: Date.now(),
|
|
5584
|
+
role: "system",
|
|
5585
|
+
kind: "session_start",
|
|
5586
|
+
content: ws,
|
|
5587
|
+
agent: agentType,
|
|
5588
|
+
instanceId,
|
|
5589
|
+
historySessionId: id,
|
|
5590
|
+
workspace: ws
|
|
5591
|
+
};
|
|
5592
|
+
fs3.appendFileSync(filePath, JSON.stringify(record) + "\n", "utf-8");
|
|
5593
|
+
} catch {
|
|
5594
|
+
}
|
|
5595
|
+
}
|
|
5487
5596
|
promoteHistorySession(agentType, previousHistorySessionId, nextHistorySessionId) {
|
|
5488
5597
|
const fromId = String(previousHistorySessionId || "").trim();
|
|
5489
5598
|
const toId = String(nextHistorySessionId || "").trim();
|
|
@@ -5703,6 +5812,7 @@ function listSavedHistorySessions(agentType, options = {}) {
|
|
|
5703
5812
|
let lastMessageAt = 0;
|
|
5704
5813
|
let sessionTitle = "";
|
|
5705
5814
|
let preview = "";
|
|
5815
|
+
let workspace = "";
|
|
5706
5816
|
for (const file of files.sort()) {
|
|
5707
5817
|
const filePath = path7.join(dir, file);
|
|
5708
5818
|
const content = fs3.readFileSync(filePath, "utf-8");
|
|
@@ -5715,6 +5825,10 @@ function listSavedHistorySessions(agentType, options = {}) {
|
|
|
5715
5825
|
parsed = null;
|
|
5716
5826
|
}
|
|
5717
5827
|
if (!parsed || parsed.historySessionId !== historySessionId) continue;
|
|
5828
|
+
if (parsed.kind === "session_start") {
|
|
5829
|
+
if (!workspace && parsed.workspace) workspace = parsed.workspace;
|
|
5830
|
+
continue;
|
|
5831
|
+
}
|
|
5718
5832
|
messageCount += 1;
|
|
5719
5833
|
if (!firstMessageAt || parsed.receivedAt < firstMessageAt) firstMessageAt = parsed.receivedAt;
|
|
5720
5834
|
if (!lastMessageAt || parsed.receivedAt > lastMessageAt) lastMessageAt = parsed.receivedAt;
|
|
@@ -5729,7 +5843,8 @@ function listSavedHistorySessions(agentType, options = {}) {
|
|
|
5729
5843
|
messageCount,
|
|
5730
5844
|
firstMessageAt,
|
|
5731
5845
|
lastMessageAt,
|
|
5732
|
-
preview: preview || void 0
|
|
5846
|
+
preview: preview || void 0,
|
|
5847
|
+
workspace: workspace || void 0
|
|
5733
5848
|
});
|
|
5734
5849
|
}
|
|
5735
5850
|
summaries.sort((a, b) => b.lastMessageAt - a.lastMessageAt);
|
|
@@ -5745,6 +5860,61 @@ function listSavedHistorySessions(agentType, options = {}) {
|
|
|
5745
5860
|
}
|
|
5746
5861
|
}
|
|
5747
5862
|
|
|
5863
|
+
// src/providers/provider-patch-state.ts
|
|
5864
|
+
function isControlValue(value) {
|
|
5865
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
5866
|
+
}
|
|
5867
|
+
function asControlValueMap(value) {
|
|
5868
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
5869
|
+
const result = {};
|
|
5870
|
+
for (const [entryKey, entryValue] of Object.entries(value)) {
|
|
5871
|
+
if (isControlValue(entryValue)) result[entryKey] = entryValue;
|
|
5872
|
+
}
|
|
5873
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
5874
|
+
}
|
|
5875
|
+
function getLegacyModelModeValues(data) {
|
|
5876
|
+
if (!data || typeof data !== "object") return void 0;
|
|
5877
|
+
const legacy = {};
|
|
5878
|
+
if (typeof data.model === "string" && data.model.trim()) legacy.model = data.model.trim();
|
|
5879
|
+
if (typeof data.mode === "string" && data.mode.trim()) legacy.mode = data.mode.trim();
|
|
5880
|
+
return Object.keys(legacy).length > 0 ? legacy : void 0;
|
|
5881
|
+
}
|
|
5882
|
+
function mergeProviderPatchState(params) {
|
|
5883
|
+
const {
|
|
5884
|
+
providerControls,
|
|
5885
|
+
data,
|
|
5886
|
+
currentControlValues,
|
|
5887
|
+
currentSummaryMetadata,
|
|
5888
|
+
mergeWithCurrent = true
|
|
5889
|
+
} = params;
|
|
5890
|
+
const sources = [
|
|
5891
|
+
mergeWithCurrent ? asControlValueMap(currentControlValues) : void 0,
|
|
5892
|
+
asControlValueMap(data?.controlValues),
|
|
5893
|
+
asControlValueMap(extractProviderControlValues(providerControls, data)),
|
|
5894
|
+
getLegacyModelModeValues(data)
|
|
5895
|
+
];
|
|
5896
|
+
const controlValues = Object.assign({}, ...sources.filter(Boolean));
|
|
5897
|
+
return {
|
|
5898
|
+
controlValues,
|
|
5899
|
+
summaryMetadata: data?.summaryMetadata !== void 0 ? data.summaryMetadata : currentSummaryMetadata
|
|
5900
|
+
};
|
|
5901
|
+
}
|
|
5902
|
+
function normalizeProviderStateControlValues(controlValues) {
|
|
5903
|
+
return controlValues && Object.keys(controlValues).length > 0 ? controlValues : void 0;
|
|
5904
|
+
}
|
|
5905
|
+
function resolveProviderStateSurface(params) {
|
|
5906
|
+
const controlValues = normalizeProviderStateControlValues(params.controlValues);
|
|
5907
|
+
return {
|
|
5908
|
+
controlValues,
|
|
5909
|
+
summaryMetadata: resolveProviderStateSummaryMetadata({
|
|
5910
|
+
summaryMetadata: params.summaryMetadata,
|
|
5911
|
+
controlValues,
|
|
5912
|
+
modelLabel: params.modelLabel,
|
|
5913
|
+
modeLabel: params.modeLabel
|
|
5914
|
+
})
|
|
5915
|
+
};
|
|
5916
|
+
}
|
|
5917
|
+
|
|
5748
5918
|
// src/providers/extension-provider-instance.ts
|
|
5749
5919
|
var ExtensionProviderInstance = class {
|
|
5750
5920
|
type;
|
|
@@ -5759,9 +5929,8 @@ var ExtensionProviderInstance = class {
|
|
|
5759
5929
|
messages = [];
|
|
5760
5930
|
prevMessageHashes = /* @__PURE__ */ new Map();
|
|
5761
5931
|
activeModal = null;
|
|
5762
|
-
currentModel = "";
|
|
5763
|
-
currentMode = "";
|
|
5764
5932
|
controlValues = {};
|
|
5933
|
+
summaryMetadata = void 0;
|
|
5765
5934
|
appliedEffectKeys = /* @__PURE__ */ new Set();
|
|
5766
5935
|
runtimeMessages = [];
|
|
5767
5936
|
lastAgentStatus = "idle";
|
|
@@ -5796,6 +5965,10 @@ var ExtensionProviderInstance = class {
|
|
|
5796
5965
|
if (!this.context?.cdp?.isConnected) return;
|
|
5797
5966
|
}
|
|
5798
5967
|
getState() {
|
|
5968
|
+
const surface = resolveProviderStateSurface({
|
|
5969
|
+
summaryMetadata: this.summaryMetadata,
|
|
5970
|
+
controlValues: this.controlValues
|
|
5971
|
+
});
|
|
5799
5972
|
return {
|
|
5800
5973
|
type: this.type,
|
|
5801
5974
|
name: this.provider.name,
|
|
@@ -5809,10 +5982,9 @@ var ExtensionProviderInstance = class {
|
|
|
5809
5982
|
activeModal: this.activeModal,
|
|
5810
5983
|
inputContent: ""
|
|
5811
5984
|
} : null,
|
|
5812
|
-
|
|
5813
|
-
currentPlan: this.currentMode || void 0,
|
|
5814
|
-
controlValues: this.controlValues,
|
|
5985
|
+
controlValues: surface.controlValues,
|
|
5815
5986
|
providerControls: this.provider.controls,
|
|
5987
|
+
summaryMetadata: surface.summaryMetadata,
|
|
5816
5988
|
agentStreams: this.agentStreams,
|
|
5817
5989
|
instanceId: this.instanceId,
|
|
5818
5990
|
lastUpdated: Date.now(),
|
|
@@ -5825,10 +5997,14 @@ var ExtensionProviderInstance = class {
|
|
|
5825
5997
|
if (data?.streams) this.agentStreams = data.streams;
|
|
5826
5998
|
if (data?.messages) this.messages = this.assignReceivedAt(data.messages);
|
|
5827
5999
|
if (data?.activeModal !== void 0) this.activeModal = data.activeModal;
|
|
5828
|
-
|
|
5829
|
-
|
|
5830
|
-
|
|
5831
|
-
|
|
6000
|
+
const patchedState = mergeProviderPatchState({
|
|
6001
|
+
providerControls: this.provider.controls,
|
|
6002
|
+
data,
|
|
6003
|
+
currentControlValues: this.controlValues,
|
|
6004
|
+
currentSummaryMetadata: this.summaryMetadata
|
|
6005
|
+
});
|
|
6006
|
+
this.controlValues = patchedState.controlValues;
|
|
6007
|
+
this.summaryMetadata = patchedState.summaryMetadata;
|
|
5832
6008
|
if (typeof data?.sessionId === "string" && data.sessionId.trim()) this.chatId = data.sessionId;
|
|
5833
6009
|
if (typeof data?.title === "string" && data.title.trim()) this.chatTitle = data.title;
|
|
5834
6010
|
if (typeof data?.agentName === "string" && data.agentName.trim()) this.agentName = data.agentName;
|
|
@@ -5929,8 +6105,14 @@ var ExtensionProviderInstance = class {
|
|
|
5929
6105
|
}
|
|
5930
6106
|
applyProviderResponse(data, options) {
|
|
5931
6107
|
if (!data || typeof data !== "object") return;
|
|
5932
|
-
const
|
|
5933
|
-
|
|
6108
|
+
const patchedState = mergeProviderPatchState({
|
|
6109
|
+
providerControls: this.provider.controls,
|
|
6110
|
+
data,
|
|
6111
|
+
currentControlValues: this.controlValues,
|
|
6112
|
+
currentSummaryMetadata: this.summaryMetadata
|
|
6113
|
+
});
|
|
6114
|
+
this.controlValues = patchedState.controlValues;
|
|
6115
|
+
this.summaryMetadata = patchedState.summaryMetadata;
|
|
5934
6116
|
const effects = normalizeProviderEffects(data);
|
|
5935
6117
|
for (const effect of effects) {
|
|
5936
6118
|
const effectWhen = effect.when || "immediate";
|
|
@@ -6080,8 +6262,6 @@ ${effect.notification.body || ""}`.trim();
|
|
|
6080
6262
|
this.messages = [];
|
|
6081
6263
|
this.prevMessageHashes.clear();
|
|
6082
6264
|
this.activeModal = null;
|
|
6083
|
-
this.currentModel = "";
|
|
6084
|
-
this.currentMode = "";
|
|
6085
6265
|
this.controlValues = {};
|
|
6086
6266
|
this.currentStatus = "idle";
|
|
6087
6267
|
this.chatId = null;
|
|
@@ -6217,6 +6397,10 @@ var IdeProviderInstance = class {
|
|
|
6217
6397
|
for (const ext of this.extensions.values()) {
|
|
6218
6398
|
extensionStates.push(ext.getState());
|
|
6219
6399
|
}
|
|
6400
|
+
const surface = resolveProviderStateSurface({
|
|
6401
|
+
summaryMetadata: this.cachedChat?.summaryMetadata,
|
|
6402
|
+
controlValues: this.cachedChat?.controlValues
|
|
6403
|
+
});
|
|
6220
6404
|
return {
|
|
6221
6405
|
type: this.type,
|
|
6222
6406
|
name: this.provider.name,
|
|
@@ -6233,11 +6417,9 @@ var IdeProviderInstance = class {
|
|
|
6233
6417
|
workspace: this.workspace || null,
|
|
6234
6418
|
extensions: extensionStates,
|
|
6235
6419
|
cdpConnected: cdp?.isConnected || false,
|
|
6236
|
-
|
|
6237
|
-
currentPlan: this.cachedChat?.mode || void 0,
|
|
6238
|
-
currentAutoApprove: this.cachedChat?.autoApprove || void 0,
|
|
6239
|
-
controlValues: this.cachedChat?.controlValues || void 0,
|
|
6420
|
+
controlValues: surface.controlValues,
|
|
6240
6421
|
providerControls: this.provider.controls,
|
|
6422
|
+
summaryMetadata: surface.summaryMetadata,
|
|
6241
6423
|
instanceId: this.instanceId,
|
|
6242
6424
|
lastUpdated: Date.now(),
|
|
6243
6425
|
settings: this.settings,
|
|
@@ -6409,8 +6591,13 @@ var IdeProviderInstance = class {
|
|
|
6409
6591
|
chat.messages = messages.filter((m) => !hiddenKinds.has(m.kind || ""));
|
|
6410
6592
|
}
|
|
6411
6593
|
}
|
|
6412
|
-
const
|
|
6413
|
-
|
|
6594
|
+
const patchedState = mergeProviderPatchState({
|
|
6595
|
+
providerControls: this.provider.controls,
|
|
6596
|
+
data: chat,
|
|
6597
|
+
mergeWithCurrent: false
|
|
6598
|
+
});
|
|
6599
|
+
chat.controlValues = Object.keys(patchedState.controlValues).length > 0 ? patchedState.controlValues : void 0;
|
|
6600
|
+
chat.summaryMetadata = patchedState.summaryMetadata;
|
|
6414
6601
|
this.cachedChat = { ...chat, activeModal };
|
|
6415
6602
|
this.detectAgentTransitions(chat, now);
|
|
6416
6603
|
const persistedMessages = chat.messages || messages;
|
|
@@ -6497,14 +6684,18 @@ var IdeProviderInstance = class {
|
|
|
6497
6684
|
}
|
|
6498
6685
|
applyProviderResponse(data, options) {
|
|
6499
6686
|
if (!data || typeof data !== "object") return;
|
|
6500
|
-
const
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6687
|
+
const patchedState = mergeProviderPatchState({
|
|
6688
|
+
providerControls: this.provider.controls,
|
|
6689
|
+
data,
|
|
6690
|
+
currentControlValues: this.cachedChat?.controlValues,
|
|
6691
|
+
currentSummaryMetadata: this.cachedChat?.summaryMetadata
|
|
6692
|
+
});
|
|
6693
|
+
this.cachedChat = {
|
|
6694
|
+
...this.cachedChat || {},
|
|
6695
|
+
...data,
|
|
6696
|
+
controlValues: Object.keys(patchedState.controlValues).length > 0 ? patchedState.controlValues : void 0,
|
|
6697
|
+
summaryMetadata: patchedState.summaryMetadata
|
|
6698
|
+
};
|
|
6508
6699
|
const effects = normalizeProviderEffects(data);
|
|
6509
6700
|
for (const effect of effects) {
|
|
6510
6701
|
const effectWhen = effect.when || "immediate";
|
|
@@ -7287,6 +7478,8 @@ var ACP_SESSION_CAPABILITIES = [
|
|
|
7287
7478
|
function buildIdeWorkspaceSession(state, cdpManagers, options) {
|
|
7288
7479
|
const profile = options.profile || "full";
|
|
7289
7480
|
const activeChat = normalizeActiveChatData(state.activeChat, getActiveChatOptions(profile));
|
|
7481
|
+
const summaryMetadata = normalizeProviderSummaryMetadata(state.summaryMetadata);
|
|
7482
|
+
const controlValues = normalizeProviderStateControlValues(state.controlValues);
|
|
7290
7483
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
7291
7484
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
7292
7485
|
const title = activeChat?.title || state.name;
|
|
@@ -7303,13 +7496,11 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
|
|
|
7303
7496
|
title,
|
|
7304
7497
|
...includeSessionMetadata && { workspace: state.workspace || null },
|
|
7305
7498
|
activeChat,
|
|
7499
|
+
...summaryMetadata && { summaryMetadata },
|
|
7306
7500
|
...includeSessionMetadata && { capabilities: IDE_SESSION_CAPABILITIES },
|
|
7307
7501
|
cdpConnected: state.cdpConnected ?? isCdpConnected(cdpManagers, state.type),
|
|
7308
|
-
currentModel: state.currentModel,
|
|
7309
|
-
currentPlan: state.currentPlan,
|
|
7310
|
-
currentAutoApprove: state.currentAutoApprove,
|
|
7311
7502
|
...includeSessionControls && {
|
|
7312
|
-
controlValues
|
|
7503
|
+
...controlValues && { controlValues },
|
|
7313
7504
|
providerControls: state.providerControls
|
|
7314
7505
|
},
|
|
7315
7506
|
errorMessage: state.errorMessage,
|
|
@@ -7320,6 +7511,8 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
|
|
|
7320
7511
|
function buildExtensionAgentSession(parent, ext, options) {
|
|
7321
7512
|
const profile = options.profile || "full";
|
|
7322
7513
|
const activeChat = normalizeActiveChatData(ext.activeChat, getActiveChatOptions(profile));
|
|
7514
|
+
const summaryMetadata = normalizeProviderSummaryMetadata(ext.summaryMetadata);
|
|
7515
|
+
const controlValues = normalizeProviderStateControlValues(ext.controlValues);
|
|
7323
7516
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
7324
7517
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
7325
7518
|
return {
|
|
@@ -7335,11 +7528,10 @@ function buildExtensionAgentSession(parent, ext, options) {
|
|
|
7335
7528
|
title: activeChat?.title || ext.name,
|
|
7336
7529
|
...includeSessionMetadata && { workspace: parent.workspace || null },
|
|
7337
7530
|
activeChat,
|
|
7531
|
+
...summaryMetadata && { summaryMetadata },
|
|
7338
7532
|
...includeSessionMetadata && { capabilities: EXTENSION_SESSION_CAPABILITIES },
|
|
7339
|
-
currentModel: ext.currentModel,
|
|
7340
|
-
currentPlan: ext.currentPlan,
|
|
7341
7533
|
...includeSessionControls && {
|
|
7342
|
-
controlValues
|
|
7534
|
+
...controlValues && { controlValues },
|
|
7343
7535
|
providerControls: ext.providerControls
|
|
7344
7536
|
},
|
|
7345
7537
|
errorMessage: ext.errorMessage,
|
|
@@ -7350,6 +7542,8 @@ function buildExtensionAgentSession(parent, ext, options) {
|
|
|
7350
7542
|
function buildCliSession(state, options) {
|
|
7351
7543
|
const profile = options.profile || "full";
|
|
7352
7544
|
const activeChat = normalizeActiveChatData(state.activeChat, getActiveChatOptions(profile));
|
|
7545
|
+
const summaryMetadata = normalizeProviderSummaryMetadata(state.summaryMetadata);
|
|
7546
|
+
const controlValues = normalizeProviderStateControlValues(state.controlValues);
|
|
7353
7547
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
7354
7548
|
const includeRuntimeMetadata = shouldIncludeRuntimeMetadata(profile);
|
|
7355
7549
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
@@ -7376,11 +7570,12 @@ function buildCliSession(state, options) {
|
|
|
7376
7570
|
mode: state.mode,
|
|
7377
7571
|
resume: state.resume,
|
|
7378
7572
|
activeChat,
|
|
7573
|
+
...summaryMetadata && { summaryMetadata },
|
|
7379
7574
|
...includeSessionMetadata && {
|
|
7380
7575
|
capabilities: state.mode === "terminal" ? PTY_SESSION_CAPABILITIES : CLI_CHAT_SESSION_CAPABILITIES
|
|
7381
7576
|
},
|
|
7382
7577
|
...includeSessionControls && {
|
|
7383
|
-
controlValues
|
|
7578
|
+
...controlValues && { controlValues },
|
|
7384
7579
|
providerControls: state.providerControls
|
|
7385
7580
|
},
|
|
7386
7581
|
errorMessage: state.errorMessage,
|
|
@@ -7391,6 +7586,8 @@ function buildCliSession(state, options) {
|
|
|
7391
7586
|
function buildAcpSession(state, options) {
|
|
7392
7587
|
const profile = options.profile || "full";
|
|
7393
7588
|
const activeChat = normalizeActiveChatData(state.activeChat, getActiveChatOptions(profile));
|
|
7589
|
+
const summaryMetadata = normalizeProviderSummaryMetadata(state.summaryMetadata);
|
|
7590
|
+
const controlValues = normalizeProviderStateControlValues(state.controlValues);
|
|
7394
7591
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
7395
7592
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
7396
7593
|
return {
|
|
@@ -7406,13 +7603,10 @@ function buildAcpSession(state, options) {
|
|
|
7406
7603
|
title: activeChat?.title || state.name,
|
|
7407
7604
|
...includeSessionMetadata && { workspace: state.workspace || null },
|
|
7408
7605
|
activeChat,
|
|
7606
|
+
...summaryMetadata && { summaryMetadata },
|
|
7409
7607
|
...includeSessionMetadata && { capabilities: ACP_SESSION_CAPABILITIES },
|
|
7410
|
-
currentModel: state.currentModel,
|
|
7411
|
-
currentPlan: state.currentPlan,
|
|
7412
7608
|
...includeSessionControls && {
|
|
7413
|
-
|
|
7414
|
-
acpModes: state.acpModes,
|
|
7415
|
-
controlValues: state.controlValues,
|
|
7609
|
+
...controlValues && { controlValues },
|
|
7416
7610
|
providerControls: state.providerControls
|
|
7417
7611
|
},
|
|
7418
7612
|
errorMessage: state.errorMessage,
|
|
@@ -8104,7 +8298,7 @@ function getStateLastSignature(state) {
|
|
|
8104
8298
|
async function getStableExtensionBaseline(h) {
|
|
8105
8299
|
const first = await readExtensionChatState(h);
|
|
8106
8300
|
if (getStateMessageCount(first) > 0 || getStateLastSignature(first)) return first;
|
|
8107
|
-
await new Promise((
|
|
8301
|
+
await new Promise((resolve11) => setTimeout(resolve11, 150));
|
|
8108
8302
|
const second = await readExtensionChatState(h);
|
|
8109
8303
|
return getStateMessageCount(second) >= getStateMessageCount(first) ? second : first;
|
|
8110
8304
|
}
|
|
@@ -8112,7 +8306,7 @@ async function verifyExtensionSendObserved(h, before) {
|
|
|
8112
8306
|
const beforeCount = getStateMessageCount(before);
|
|
8113
8307
|
const beforeSignature = getStateLastSignature(before);
|
|
8114
8308
|
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
8115
|
-
await new Promise((
|
|
8309
|
+
await new Promise((resolve11) => setTimeout(resolve11, 250));
|
|
8116
8310
|
const state = await readExtensionChatState(h);
|
|
8117
8311
|
if (state?.status === "waiting_approval") return true;
|
|
8118
8312
|
const afterCount = getStateMessageCount(state);
|
|
@@ -9304,6 +9498,30 @@ async function handleFileListBrowse(h, args) {
|
|
|
9304
9498
|
}
|
|
9305
9499
|
}
|
|
9306
9500
|
|
|
9501
|
+
// src/commands/stream-commands.ts
|
|
9502
|
+
init_config();
|
|
9503
|
+
|
|
9504
|
+
// src/config/provider-source-config.ts
|
|
9505
|
+
function normalizeProviderDir(value) {
|
|
9506
|
+
if (typeof value !== "string") return void 0;
|
|
9507
|
+
const trimmed = value.trim();
|
|
9508
|
+
return trimmed ? trimmed : void 0;
|
|
9509
|
+
}
|
|
9510
|
+
function parseProviderSourceConfigUpdate(input) {
|
|
9511
|
+
const updates = {};
|
|
9512
|
+
if (Object.prototype.hasOwnProperty.call(input, "providerSourceMode")) {
|
|
9513
|
+
const { providerSourceMode } = input;
|
|
9514
|
+
if (providerSourceMode !== "normal" && providerSourceMode !== "no-upstream") {
|
|
9515
|
+
return { ok: false, error: "providerSourceMode must be 'normal' or 'no-upstream'" };
|
|
9516
|
+
}
|
|
9517
|
+
updates.providerSourceMode = providerSourceMode;
|
|
9518
|
+
}
|
|
9519
|
+
if (Object.prototype.hasOwnProperty.call(input, "providerDir")) {
|
|
9520
|
+
updates.providerDir = normalizeProviderDir(input.providerDir);
|
|
9521
|
+
}
|
|
9522
|
+
return { ok: true, updates };
|
|
9523
|
+
}
|
|
9524
|
+
|
|
9307
9525
|
// src/providers/cli-script-results.ts
|
|
9308
9526
|
function parseCliScriptResult(result) {
|
|
9309
9527
|
if (typeof result === "string") {
|
|
@@ -9416,8 +9634,49 @@ async function handleSetProviderSetting(h, args) {
|
|
|
9416
9634
|
}
|
|
9417
9635
|
return { success: false, error: `Failed to set ${providerType}.${key} \u2014 invalid key, value, or not a public setting` };
|
|
9418
9636
|
}
|
|
9419
|
-
function
|
|
9637
|
+
function handleGetProviderSourceConfig(h, _args) {
|
|
9638
|
+
const loader = h.ctx.providerLoader;
|
|
9639
|
+
if (!loader) return { success: false, error: "providerLoader not available" };
|
|
9640
|
+
return { success: true, ...loader.getSourceConfig() };
|
|
9641
|
+
}
|
|
9642
|
+
async function handleSetProviderSourceConfig(h, args) {
|
|
9643
|
+
const loader = h.ctx.providerLoader;
|
|
9644
|
+
if (!loader) return { success: false, error: "providerLoader not available" };
|
|
9645
|
+
const parsed = parseProviderSourceConfigUpdate(args || {});
|
|
9646
|
+
if ("error" in parsed) {
|
|
9647
|
+
return { success: false, error: parsed.error };
|
|
9648
|
+
}
|
|
9649
|
+
const currentConfig2 = loadConfig();
|
|
9650
|
+
const nextConfig = {
|
|
9651
|
+
...currentConfig2,
|
|
9652
|
+
...parsed.updates.providerSourceMode ? { providerSourceMode: parsed.updates.providerSourceMode } : {},
|
|
9653
|
+
...Object.prototype.hasOwnProperty.call(parsed.updates, "providerDir") ? { providerDir: parsed.updates.providerDir } : {}
|
|
9654
|
+
};
|
|
9655
|
+
saveConfig(nextConfig);
|
|
9656
|
+
const sourceConfig = loader.applySourceConfig({
|
|
9657
|
+
sourceMode: nextConfig.providerSourceMode,
|
|
9658
|
+
userDir: Object.prototype.hasOwnProperty.call(parsed.updates, "providerDir") ? parsed.updates.providerDir : loader.getSourceConfig().explicitProviderDir || void 0
|
|
9659
|
+
});
|
|
9660
|
+
loader.reload();
|
|
9661
|
+
loader.registerToDetector();
|
|
9662
|
+
await h.ctx.onProviderSourceConfigChanged?.();
|
|
9663
|
+
LOG.info(
|
|
9664
|
+
"Command",
|
|
9665
|
+
`[set_provider_source_config] mode=${sourceConfig.sourceMode} explicitProviderDir=${sourceConfig.explicitProviderDir || "-"} userDir=${sourceConfig.userDir}`
|
|
9666
|
+
);
|
|
9667
|
+
return { success: true, reloaded: true, ...sourceConfig };
|
|
9668
|
+
}
|
|
9669
|
+
function normalizeProviderScriptArgs(args, scriptName) {
|
|
9420
9670
|
const normalizedArgs = { ...args || {} };
|
|
9671
|
+
const normalizedScriptName = String(scriptName || "").toLowerCase();
|
|
9672
|
+
if (Object.prototype.hasOwnProperty.call(normalizedArgs, "value")) {
|
|
9673
|
+
if (normalizedArgs.model === void 0 && (normalizedScriptName === "setmodel" || normalizedScriptName === "setmodelgui" || normalizedScriptName === "webviewsetmodel")) {
|
|
9674
|
+
normalizedArgs.model = normalizedArgs.value;
|
|
9675
|
+
}
|
|
9676
|
+
if (normalizedArgs.mode === void 0 && (normalizedScriptName === "setmode" || normalizedScriptName === "webviewsetmode")) {
|
|
9677
|
+
normalizedArgs.mode = normalizedArgs.value;
|
|
9678
|
+
}
|
|
9679
|
+
}
|
|
9421
9680
|
for (const key of ["mode", "model", "message", "action", "button", "text", "sessionId", "value"]) {
|
|
9422
9681
|
if (key in normalizedArgs && !(key.toUpperCase() in normalizedArgs)) {
|
|
9423
9682
|
normalizedArgs[key.toUpperCase()] = normalizedArgs[key];
|
|
@@ -9463,7 +9722,7 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
9463
9722
|
if (!provider.scripts?.[actualScriptName]) {
|
|
9464
9723
|
return { success: false, error: `Script '${actualScriptName}' not available for ${resolvedProviderType}` };
|
|
9465
9724
|
}
|
|
9466
|
-
const normalizedArgs = normalizeProviderScriptArgs(args);
|
|
9725
|
+
const normalizedArgs = normalizeProviderScriptArgs(args, actualScriptName);
|
|
9467
9726
|
if (provider.category === "cli") {
|
|
9468
9727
|
const adapter = h.getCliAdapter(args?.targetSessionId || resolvedProviderType);
|
|
9469
9728
|
if (!adapter?.invokeScript) {
|
|
@@ -10109,6 +10368,10 @@ var DaemonCommandHandler = class {
|
|
|
10109
10368
|
return handleGetProviderSettings(this, args);
|
|
10110
10369
|
case "set_provider_setting":
|
|
10111
10370
|
return handleSetProviderSetting(this, args);
|
|
10371
|
+
case "get_provider_source_config":
|
|
10372
|
+
return handleGetProviderSourceConfig(this, args);
|
|
10373
|
+
case "set_provider_source_config":
|
|
10374
|
+
return handleSetProviderSourceConfig(this, args);
|
|
10112
10375
|
// ─── IDE Extension Settings (stream-commands.ts) ──────────
|
|
10113
10376
|
case "get_ide_extensions":
|
|
10114
10377
|
return handleGetIdeExtensions(this, args);
|
|
@@ -10148,7 +10411,7 @@ var DaemonCommandHandler = class {
|
|
|
10148
10411
|
try {
|
|
10149
10412
|
const http3 = await import("http");
|
|
10150
10413
|
const postData = JSON.stringify(body);
|
|
10151
|
-
const result = await new Promise((
|
|
10414
|
+
const result = await new Promise((resolve11, reject) => {
|
|
10152
10415
|
const req = http3.request({
|
|
10153
10416
|
hostname: "127.0.0.1",
|
|
10154
10417
|
port: 19280,
|
|
@@ -10160,9 +10423,9 @@ var DaemonCommandHandler = class {
|
|
|
10160
10423
|
res.on("data", (chunk) => data += chunk);
|
|
10161
10424
|
res.on("end", () => {
|
|
10162
10425
|
try {
|
|
10163
|
-
|
|
10426
|
+
resolve11(JSON.parse(data));
|
|
10164
10427
|
} catch {
|
|
10165
|
-
|
|
10428
|
+
resolve11({ raw: data });
|
|
10166
10429
|
}
|
|
10167
10430
|
});
|
|
10168
10431
|
});
|
|
@@ -10180,15 +10443,15 @@ var DaemonCommandHandler = class {
|
|
|
10180
10443
|
if (!providerType) return { success: false, error: "providerType required" };
|
|
10181
10444
|
try {
|
|
10182
10445
|
const http3 = await import("http");
|
|
10183
|
-
const result = await new Promise((
|
|
10446
|
+
const result = await new Promise((resolve11, reject) => {
|
|
10184
10447
|
http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
|
|
10185
10448
|
let data = "";
|
|
10186
10449
|
res.on("data", (chunk) => data += chunk);
|
|
10187
10450
|
res.on("end", () => {
|
|
10188
10451
|
try {
|
|
10189
|
-
|
|
10452
|
+
resolve11(JSON.parse(data));
|
|
10190
10453
|
} catch {
|
|
10191
|
-
|
|
10454
|
+
resolve11({ raw: data });
|
|
10192
10455
|
}
|
|
10193
10456
|
});
|
|
10194
10457
|
}).on("error", reject);
|
|
@@ -10202,7 +10465,7 @@ var DaemonCommandHandler = class {
|
|
|
10202
10465
|
try {
|
|
10203
10466
|
const http3 = await import("http");
|
|
10204
10467
|
const postData = JSON.stringify(args || {});
|
|
10205
|
-
const result = await new Promise((
|
|
10468
|
+
const result = await new Promise((resolve11, reject) => {
|
|
10206
10469
|
const req = http3.request({
|
|
10207
10470
|
hostname: "127.0.0.1",
|
|
10208
10471
|
port: 19280,
|
|
@@ -10214,9 +10477,9 @@ var DaemonCommandHandler = class {
|
|
|
10214
10477
|
res.on("data", (chunk) => data += chunk);
|
|
10215
10478
|
res.on("end", () => {
|
|
10216
10479
|
try {
|
|
10217
|
-
|
|
10480
|
+
resolve11(JSON.parse(data));
|
|
10218
10481
|
} catch {
|
|
10219
|
-
|
|
10482
|
+
resolve11({ raw: data });
|
|
10220
10483
|
}
|
|
10221
10484
|
});
|
|
10222
10485
|
});
|
|
@@ -10266,6 +10529,9 @@ function getForcedNewSessionScriptName(provider, launchMode) {
|
|
|
10266
10529
|
const controls = Array.isArray(provider.controls) ? provider.controls : [];
|
|
10267
10530
|
for (const control of controls) {
|
|
10268
10531
|
if (control?.type !== "action") continue;
|
|
10532
|
+
if (typeof control?.confirmTitle === "string" && control.confirmTitle.trim()) continue;
|
|
10533
|
+
if (typeof control?.confirmMessage === "string" && control.confirmMessage.trim()) continue;
|
|
10534
|
+
if (typeof control?.confirmLabel === "string" && control.confirmLabel.trim()) continue;
|
|
10269
10535
|
const invokeScript = typeof control?.invokeScript === "string" ? control.invokeScript.trim() : "";
|
|
10270
10536
|
if (!invokeScript) continue;
|
|
10271
10537
|
const controlId = typeof control?.id === "string" ? control.id.trim() : "";
|
|
@@ -10275,6 +10541,20 @@ function getForcedNewSessionScriptName(provider, launchMode) {
|
|
|
10275
10541
|
}
|
|
10276
10542
|
return null;
|
|
10277
10543
|
}
|
|
10544
|
+
async function waitForCliAdapterReady(adapter, options) {
|
|
10545
|
+
const timeoutMs = Math.max(100, options?.timeoutMs ?? 15e3);
|
|
10546
|
+
const pollMs = Math.max(10, options?.pollMs ?? 50);
|
|
10547
|
+
const deadline = Date.now() + timeoutMs;
|
|
10548
|
+
while (Date.now() < deadline) {
|
|
10549
|
+
if (adapter?.isReady?.()) return;
|
|
10550
|
+
const status = adapter?.getStatus?.()?.status;
|
|
10551
|
+
if (status === "stopped") {
|
|
10552
|
+
throw new Error("CLI runtime stopped before it became ready");
|
|
10553
|
+
}
|
|
10554
|
+
await new Promise((resolve11) => setTimeout(resolve11, pollMs));
|
|
10555
|
+
}
|
|
10556
|
+
throw new Error(`CLI runtime did not become ready within ${timeoutMs}ms`);
|
|
10557
|
+
}
|
|
10278
10558
|
var CliProviderInstance = class {
|
|
10279
10559
|
constructor(provider, workingDir, cliArgs = [], instanceId, transportFactory, options) {
|
|
10280
10560
|
this.provider = provider;
|
|
@@ -10303,6 +10583,7 @@ var CliProviderInstance = class {
|
|
|
10303
10583
|
generatingDebouncePending = null;
|
|
10304
10584
|
lastApprovalEventAt = 0;
|
|
10305
10585
|
controlValues = {};
|
|
10586
|
+
summaryMetadata = void 0;
|
|
10306
10587
|
appliedEffectKeys = /* @__PURE__ */ new Set();
|
|
10307
10588
|
historyWriter;
|
|
10308
10589
|
runtimeMessages = [];
|
|
@@ -10445,13 +10726,7 @@ var CliProviderInstance = class {
|
|
|
10445
10726
|
if (historyMessageCount !== null) {
|
|
10446
10727
|
parsedMessages = historyMessageCount > 0 ? parsedMessages.slice(-historyMessageCount) : [];
|
|
10447
10728
|
}
|
|
10448
|
-
const controlValues = extractProviderControlValues(this.provider.controls, parsedStatus);
|
|
10449
|
-
if (controlValues) {
|
|
10450
|
-
this.controlValues = { ...this.controlValues, ...controlValues };
|
|
10451
|
-
}
|
|
10452
10729
|
const mergedMessages = this.mergeConversationMessages(parsedMessages);
|
|
10453
|
-
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;
|
|
10454
|
-
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;
|
|
10455
10730
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
10456
10731
|
if (parsedMessages.length > 0) {
|
|
10457
10732
|
const shouldSkipReplayPersist = this.suppressIdleHistoryReplay && adapterStatus.status === "idle" && parsedStatus?.status === "idle";
|
|
@@ -10473,6 +10748,10 @@ var CliProviderInstance = class {
|
|
|
10473
10748
|
}
|
|
10474
10749
|
}
|
|
10475
10750
|
this.applyProviderResponse(parsedStatus, { phase: "immediate" });
|
|
10751
|
+
const surface = resolveProviderStateSurface({
|
|
10752
|
+
summaryMetadata: this.summaryMetadata,
|
|
10753
|
+
controlValues: this.controlValues
|
|
10754
|
+
});
|
|
10476
10755
|
return {
|
|
10477
10756
|
type: this.type,
|
|
10478
10757
|
name: this.provider.name,
|
|
@@ -10488,8 +10767,6 @@ var CliProviderInstance = class {
|
|
|
10488
10767
|
inputContent: ""
|
|
10489
10768
|
},
|
|
10490
10769
|
workspace: this.workingDir,
|
|
10491
|
-
currentModel,
|
|
10492
|
-
currentPlan,
|
|
10493
10770
|
instanceId: this.instanceId,
|
|
10494
10771
|
providerSessionId: this.providerSessionId,
|
|
10495
10772
|
lastUpdated: Date.now(),
|
|
@@ -10504,8 +10781,9 @@ var CliProviderInstance = class {
|
|
|
10504
10781
|
attachedClients: runtime.attachedClients || []
|
|
10505
10782
|
} : void 0,
|
|
10506
10783
|
resume: this.provider.resume,
|
|
10507
|
-
controlValues:
|
|
10508
|
-
providerControls: this.provider.controls
|
|
10784
|
+
controlValues: surface.controlValues,
|
|
10785
|
+
providerControls: this.provider.controls,
|
|
10786
|
+
summaryMetadata: surface.summaryMetadata
|
|
10509
10787
|
};
|
|
10510
10788
|
}
|
|
10511
10789
|
setPresentationMode(mode) {
|
|
@@ -10553,6 +10831,7 @@ var CliProviderInstance = class {
|
|
|
10553
10831
|
const scriptName = getForcedNewSessionScriptName(this.provider, this.launchMode);
|
|
10554
10832
|
if (!scriptName) return;
|
|
10555
10833
|
LOG.info("CLI", `[${this.type}] forcing fresh session launch via script: ${scriptName}`);
|
|
10834
|
+
await waitForCliAdapterReady(this.adapter);
|
|
10556
10835
|
const raw = await this.adapter.invokeScript(scriptName, {});
|
|
10557
10836
|
const parsed = parseCliScriptResult(raw);
|
|
10558
10837
|
if (!parsed.success) {
|
|
@@ -10708,10 +10987,14 @@ var CliProviderInstance = class {
|
|
|
10708
10987
|
this.suppressIdleHistoryReplay = false;
|
|
10709
10988
|
this.adapter.clearHistory();
|
|
10710
10989
|
}
|
|
10711
|
-
const
|
|
10712
|
-
|
|
10713
|
-
|
|
10714
|
-
|
|
10990
|
+
const patchedState = mergeProviderPatchState({
|
|
10991
|
+
providerControls: this.provider.controls,
|
|
10992
|
+
data,
|
|
10993
|
+
currentControlValues: this.controlValues,
|
|
10994
|
+
currentSummaryMetadata: this.summaryMetadata
|
|
10995
|
+
});
|
|
10996
|
+
this.controlValues = patchedState.controlValues;
|
|
10997
|
+
this.summaryMetadata = patchedState.summaryMetadata;
|
|
10715
10998
|
const effects = normalizeProviderEffects(data);
|
|
10716
10999
|
for (const effect of effects) {
|
|
10717
11000
|
const effectWhen = effect.when || "immediate";
|
|
@@ -10902,6 +11185,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
10902
11185
|
const previousProviderSessionId = this.providerSessionId;
|
|
10903
11186
|
this.providerSessionId = nextSessionId;
|
|
10904
11187
|
this.historyWriter.promoteHistorySession(this.type, previousHistorySessionId, nextSessionId);
|
|
11188
|
+
this.historyWriter.writeSessionStart(this.type, nextSessionId, this.workingDir, this.instanceId);
|
|
10905
11189
|
this.adapter.updateRuntimeMeta({ providerSessionId: nextSessionId });
|
|
10906
11190
|
this.onProviderSessionResolved?.({
|
|
10907
11191
|
instanceId: this.instanceId,
|
|
@@ -11076,8 +11360,7 @@ var AcpProviderInstance = class {
|
|
|
11076
11360
|
lastStatus = "starting";
|
|
11077
11361
|
generatingStartedAt = 0;
|
|
11078
11362
|
agentCapabilities = {};
|
|
11079
|
-
|
|
11080
|
-
currentMode;
|
|
11363
|
+
currentSelections = {};
|
|
11081
11364
|
activeToolCalls = [];
|
|
11082
11365
|
stopReason = null;
|
|
11083
11366
|
partialContent = "";
|
|
@@ -11157,8 +11440,6 @@ var AcpProviderInstance = class {
|
|
|
11157
11440
|
inputContent: ""
|
|
11158
11441
|
},
|
|
11159
11442
|
workspace: this.workingDir,
|
|
11160
|
-
currentModel: this.currentModel,
|
|
11161
|
-
currentPlan: this.currentMode,
|
|
11162
11443
|
instanceId: this.instanceId,
|
|
11163
11444
|
lastUpdated: Date.now(),
|
|
11164
11445
|
settings: this.settings,
|
|
@@ -11169,11 +11450,9 @@ var AcpProviderInstance = class {
|
|
|
11169
11450
|
// Error details for dashboard display
|
|
11170
11451
|
errorMessage: this.errorMessage || void 0,
|
|
11171
11452
|
errorReason: this.errorReason || void 0,
|
|
11172
|
-
controlValues:
|
|
11173
|
-
|
|
11174
|
-
|
|
11175
|
-
},
|
|
11176
|
-
providerControls: this.provider.controls
|
|
11453
|
+
controlValues: this.getSelectionControlValues(),
|
|
11454
|
+
providerControls: this.provider.controls,
|
|
11455
|
+
summaryMetadata: this.buildSelectionSummaryMetadata()
|
|
11177
11456
|
};
|
|
11178
11457
|
}
|
|
11179
11458
|
onEvent(event, data) {
|
|
@@ -11207,6 +11486,54 @@ var AcpProviderInstance = class {
|
|
|
11207
11486
|
getInstanceId() {
|
|
11208
11487
|
return this.instanceId;
|
|
11209
11488
|
}
|
|
11489
|
+
resolveConfigOptionLabel(category, value) {
|
|
11490
|
+
if (!value) return void 0;
|
|
11491
|
+
const option = this.configOptions.find((entry) => entry.category === category);
|
|
11492
|
+
return option?.options.find((candidate) => candidate.value === value)?.name || value;
|
|
11493
|
+
}
|
|
11494
|
+
resolveModeLabel(modeId) {
|
|
11495
|
+
if (!modeId) return void 0;
|
|
11496
|
+
return this.availableModes.find((mode) => mode.id === modeId)?.name || modeId;
|
|
11497
|
+
}
|
|
11498
|
+
getCurrentSelection(category) {
|
|
11499
|
+
return this.currentSelections[category];
|
|
11500
|
+
}
|
|
11501
|
+
setCurrentSelection(category, value) {
|
|
11502
|
+
const normalized = typeof value === "string" ? value.trim() : "";
|
|
11503
|
+
if (normalized) {
|
|
11504
|
+
this.currentSelections[category] = normalized;
|
|
11505
|
+
return;
|
|
11506
|
+
}
|
|
11507
|
+
delete this.currentSelections[category];
|
|
11508
|
+
}
|
|
11509
|
+
getSelectionControlValues() {
|
|
11510
|
+
const model = this.getCurrentSelection("model");
|
|
11511
|
+
const mode = this.getCurrentSelection("mode");
|
|
11512
|
+
return {
|
|
11513
|
+
...model ? { model } : {},
|
|
11514
|
+
...mode ? { mode } : {}
|
|
11515
|
+
};
|
|
11516
|
+
}
|
|
11517
|
+
resolveSelectionLabel(category, value) {
|
|
11518
|
+
if (!value) return void 0;
|
|
11519
|
+
const configLabel = this.resolveConfigOptionLabel(category, value);
|
|
11520
|
+
if (configLabel && configLabel !== value) return configLabel;
|
|
11521
|
+
if (category === "mode") {
|
|
11522
|
+
const modeLabel = this.resolveModeLabel(value);
|
|
11523
|
+
if (modeLabel) return modeLabel;
|
|
11524
|
+
}
|
|
11525
|
+
return configLabel || value;
|
|
11526
|
+
}
|
|
11527
|
+
buildSelectionSummaryMetadata() {
|
|
11528
|
+
const model = this.getCurrentSelection("model");
|
|
11529
|
+
const mode = this.getCurrentSelection("mode");
|
|
11530
|
+
return buildLegacyModelModeSummaryMetadata({
|
|
11531
|
+
model,
|
|
11532
|
+
mode,
|
|
11533
|
+
modelLabel: this.resolveSelectionLabel("model", model),
|
|
11534
|
+
modeLabel: this.resolveSelectionLabel("mode", mode)
|
|
11535
|
+
});
|
|
11536
|
+
}
|
|
11210
11537
|
// ─── ACP Config Options & Modes ─────────────────────
|
|
11211
11538
|
parseConfigOptions(raw) {
|
|
11212
11539
|
if (!Array.isArray(raw)) return;
|
|
@@ -11238,12 +11565,14 @@ var AcpProviderInstance = class {
|
|
|
11238
11565
|
}
|
|
11239
11566
|
}
|
|
11240
11567
|
this.configOptions.push({ category, configId, currentValue, options: flatOptions });
|
|
11241
|
-
if (category === "model"
|
|
11568
|
+
if (category === "model" || category === "mode") {
|
|
11569
|
+
this.setCurrentSelection(category, currentValue);
|
|
11570
|
+
}
|
|
11242
11571
|
}
|
|
11243
11572
|
}
|
|
11244
11573
|
parseModes(raw) {
|
|
11245
11574
|
if (!raw) return;
|
|
11246
|
-
|
|
11575
|
+
this.setCurrentSelection("mode", raw.currentModeId);
|
|
11247
11576
|
if (Array.isArray(raw.availableModes)) {
|
|
11248
11577
|
this.availableModes = raw.availableModes.map((m) => ({
|
|
11249
11578
|
id: m.id,
|
|
@@ -11262,8 +11591,7 @@ var AcpProviderInstance = class {
|
|
|
11262
11591
|
if (this.useStaticConfig) {
|
|
11263
11592
|
opt.currentValue = value;
|
|
11264
11593
|
this.selectedConfig[opt.configId] = value;
|
|
11265
|
-
if (category === "model") this.
|
|
11266
|
-
if (category === "mode") this.currentMode = value;
|
|
11594
|
+
if (category === "model" || category === "mode") this.setCurrentSelection(category, value);
|
|
11267
11595
|
this.log.info(`[${this.type}] Static config ${category} set to: ${value} \u2014 restarting agent`);
|
|
11268
11596
|
await this.restartWithNewConfig();
|
|
11269
11597
|
return;
|
|
@@ -11281,7 +11609,7 @@ var AcpProviderInstance = class {
|
|
|
11281
11609
|
value
|
|
11282
11610
|
});
|
|
11283
11611
|
opt.currentValue = value;
|
|
11284
|
-
if (category === "model") this.
|
|
11612
|
+
if (category === "model" || category === "mode") this.setCurrentSelection(category, value);
|
|
11285
11613
|
if (result?.configOptions) this.parseConfigOptions(result.configOptions);
|
|
11286
11614
|
this.log.info(`[${this.type}] Config ${category} set to: ${value} | response: ${JSON.stringify(result)?.slice(0, 300)}`);
|
|
11287
11615
|
} catch (e) {
|
|
@@ -11297,7 +11625,7 @@ var AcpProviderInstance = class {
|
|
|
11297
11625
|
opt.currentValue = modeId;
|
|
11298
11626
|
this.selectedConfig[opt.configId] = modeId;
|
|
11299
11627
|
}
|
|
11300
|
-
this.
|
|
11628
|
+
this.setCurrentSelection("mode", modeId);
|
|
11301
11629
|
this.log.info(`[${this.type}] Static mode set to: ${modeId} \u2014 restarting agent`);
|
|
11302
11630
|
await this.restartWithNewConfig();
|
|
11303
11631
|
return;
|
|
@@ -11312,7 +11640,7 @@ var AcpProviderInstance = class {
|
|
|
11312
11640
|
sessionId: this.sessionId,
|
|
11313
11641
|
modeId
|
|
11314
11642
|
});
|
|
11315
|
-
this.
|
|
11643
|
+
this.setCurrentSelection("mode", modeId);
|
|
11316
11644
|
this.log.info(`[${this.type}] Mode set to: ${modeId}`);
|
|
11317
11645
|
} catch (e) {
|
|
11318
11646
|
const message = e?.message || "Unknown ACP mode error";
|
|
@@ -11483,13 +11811,13 @@ var AcpProviderInstance = class {
|
|
|
11483
11811
|
}
|
|
11484
11812
|
this.currentStatus = "waiting_approval";
|
|
11485
11813
|
this.detectStatusTransition();
|
|
11486
|
-
const approved = await new Promise((
|
|
11487
|
-
this.permissionResolvers.push(
|
|
11814
|
+
const approved = await new Promise((resolve11) => {
|
|
11815
|
+
this.permissionResolvers.push(resolve11);
|
|
11488
11816
|
setTimeout(() => {
|
|
11489
|
-
const idx = this.permissionResolvers.indexOf(
|
|
11817
|
+
const idx = this.permissionResolvers.indexOf(resolve11);
|
|
11490
11818
|
if (idx >= 0) {
|
|
11491
11819
|
this.permissionResolvers.splice(idx, 1);
|
|
11492
|
-
|
|
11820
|
+
resolve11(false);
|
|
11493
11821
|
}
|
|
11494
11822
|
}, 3e5);
|
|
11495
11823
|
});
|
|
@@ -11570,8 +11898,8 @@ var AcpProviderInstance = class {
|
|
|
11570
11898
|
if (result?.modes) this.log.debug(`[${this.type}] modes: ${JSON.stringify(result.modes).slice(0, 300)}`);
|
|
11571
11899
|
this.parseConfigOptions(result?.configOptions);
|
|
11572
11900
|
this.parseModes(result?.modes);
|
|
11573
|
-
if (!this.
|
|
11574
|
-
this.
|
|
11901
|
+
if (!this.getCurrentSelection("model") && result?.models?.currentModelId) {
|
|
11902
|
+
this.setCurrentSelection("model", result.models.currentModelId);
|
|
11575
11903
|
}
|
|
11576
11904
|
if (this.configOptions.length === 0 && this.provider.staticConfigOptions?.length) {
|
|
11577
11905
|
this.useStaticConfig = true;
|
|
@@ -11585,13 +11913,16 @@ var AcpProviderInstance = class {
|
|
|
11585
11913
|
});
|
|
11586
11914
|
if (defaultVal) {
|
|
11587
11915
|
this.selectedConfig[sc.configId] = defaultVal;
|
|
11588
|
-
if (sc.category === "model"
|
|
11589
|
-
|
|
11916
|
+
if (sc.category === "model" || sc.category === "mode") {
|
|
11917
|
+
this.setCurrentSelection(sc.category, defaultVal);
|
|
11918
|
+
}
|
|
11590
11919
|
}
|
|
11591
11920
|
}
|
|
11592
11921
|
this.log.info(`[${this.type}] Using static configOptions (${this.configOptions.length} options)`);
|
|
11593
11922
|
}
|
|
11594
|
-
|
|
11923
|
+
const currentModel = this.getCurrentSelection("model");
|
|
11924
|
+
const currentMode = this.getCurrentSelection("mode");
|
|
11925
|
+
this.log.info(`[${this.type}] Session created: ${this.sessionId}${currentModel ? ` (model: ${currentModel})` : ""}${currentMode ? ` (mode: ${currentMode})` : ""}`);
|
|
11595
11926
|
if (this.configOptions.length > 0) {
|
|
11596
11927
|
this.log.info(`[${this.type}] Config options: ${this.configOptions.map((c) => `${c.category}(${c.options.length})`).join(", ")}`);
|
|
11597
11928
|
}
|
|
@@ -11766,7 +12097,7 @@ var AcpProviderInstance = class {
|
|
|
11766
12097
|
break;
|
|
11767
12098
|
}
|
|
11768
12099
|
case "current_mode_update": {
|
|
11769
|
-
this.
|
|
12100
|
+
this.setCurrentSelection("mode", update.currentModeId);
|
|
11770
12101
|
break;
|
|
11771
12102
|
}
|
|
11772
12103
|
case "config_option_update": {
|
|
@@ -11839,7 +12170,7 @@ var AcpProviderInstance = class {
|
|
|
11839
12170
|
this.detectStatusTransition();
|
|
11840
12171
|
}
|
|
11841
12172
|
if (params.model) {
|
|
11842
|
-
this.
|
|
12173
|
+
this.setCurrentSelection("model", params.model);
|
|
11843
12174
|
}
|
|
11844
12175
|
}
|
|
11845
12176
|
/** Map SDK ToolCallStatus to internal status */
|
|
@@ -12128,7 +12459,11 @@ var DaemonCliManager = class {
|
|
|
12128
12459
|
}
|
|
12129
12460
|
persistRecentActivity(entry) {
|
|
12130
12461
|
try {
|
|
12131
|
-
|
|
12462
|
+
const summaryMetadata = normalizeProviderSummaryMetadata(entry.summaryMetadata);
|
|
12463
|
+
let nextState = appendRecentActivity(loadState(), {
|
|
12464
|
+
...entry,
|
|
12465
|
+
summaryMetadata
|
|
12466
|
+
});
|
|
12132
12467
|
if (entry.providerSessionId && (entry.kind === "cli" || entry.kind === "acp")) {
|
|
12133
12468
|
nextState = upsertSavedProviderSession(nextState, {
|
|
12134
12469
|
kind: entry.kind,
|
|
@@ -12136,7 +12471,7 @@ var DaemonCliManager = class {
|
|
|
12136
12471
|
providerName: entry.providerName,
|
|
12137
12472
|
providerSessionId: entry.providerSessionId,
|
|
12138
12473
|
workspace: entry.workspace,
|
|
12139
|
-
|
|
12474
|
+
summaryMetadata,
|
|
12140
12475
|
title: entry.title
|
|
12141
12476
|
});
|
|
12142
12477
|
}
|
|
@@ -12326,7 +12661,7 @@ ${installInfo}`
|
|
|
12326
12661
|
providerType: normalizedType,
|
|
12327
12662
|
providerName: provider.displayName || provider.name || normalizedType,
|
|
12328
12663
|
workspace: resolvedDir,
|
|
12329
|
-
|
|
12664
|
+
summaryMetadata: buildLegacyModelModeSummaryMetadata({ model: initialModel }),
|
|
12330
12665
|
sessionId,
|
|
12331
12666
|
title: provider.displayName || provider.name || normalizedType
|
|
12332
12667
|
});
|
|
@@ -12428,7 +12763,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
12428
12763
|
providerName: provider?.displayName || provider?.name || normalizedType,
|
|
12429
12764
|
providerSessionId: sessionBinding.providerSessionId,
|
|
12430
12765
|
workspace: resolvedDir,
|
|
12431
|
-
|
|
12766
|
+
summaryMetadata: buildLegacyModelModeSummaryMetadata({ model: initialModel }),
|
|
12432
12767
|
sessionId: key,
|
|
12433
12768
|
title: provider?.displayName || provider?.name || normalizedType
|
|
12434
12769
|
});
|
|
@@ -12805,6 +13140,9 @@ function validateProviderDefinition(raw) {
|
|
|
12805
13140
|
warnings.push(`Unknown provider field: ${key}`);
|
|
12806
13141
|
}
|
|
12807
13142
|
}
|
|
13143
|
+
if (provider.disableUpstream !== void 0) {
|
|
13144
|
+
warnings.push("disableUpstream is deprecated in provider definitions; use machine-level provider source policy instead");
|
|
13145
|
+
}
|
|
12808
13146
|
const category = provider.category;
|
|
12809
13147
|
if (category === "cli" || category === "acp") {
|
|
12810
13148
|
const spawn4 = provider.spawn;
|
|
@@ -12864,8 +13202,11 @@ function validateControl(control, errors) {
|
|
|
12864
13202
|
var ProviderLoader = class _ProviderLoader {
|
|
12865
13203
|
providers = /* @__PURE__ */ new Map();
|
|
12866
13204
|
providerAvailability = /* @__PURE__ */ new Map();
|
|
13205
|
+
defaultProvidersDir;
|
|
13206
|
+
explicitProviderDir = null;
|
|
12867
13207
|
userDir;
|
|
12868
13208
|
upstreamDir;
|
|
13209
|
+
sourceMode = "normal";
|
|
12869
13210
|
disableUpstream;
|
|
12870
13211
|
watchers = [];
|
|
12871
13212
|
logFn;
|
|
@@ -12879,22 +13220,15 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12879
13220
|
static META_FILE = ".meta.json";
|
|
12880
13221
|
constructor(options) {
|
|
12881
13222
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
12882
|
-
|
|
12883
|
-
|
|
12884
|
-
|
|
12885
|
-
|
|
12886
|
-
|
|
12887
|
-
|
|
12888
|
-
|
|
12889
|
-
|
|
12890
|
-
|
|
12891
|
-
} else {
|
|
12892
|
-
this.userDir = defaultProvidersDir;
|
|
12893
|
-
this.log(`Using default user providers directory: ${this.userDir}`);
|
|
12894
|
-
}
|
|
12895
|
-
}
|
|
12896
|
-
this.upstreamDir = path14.join(defaultProvidersDir, ".upstream");
|
|
12897
|
-
this.disableUpstream = options?.disableUpstream ?? false;
|
|
13223
|
+
this.defaultProvidersDir = path14.join(os13.homedir(), ".adhdev", "providers");
|
|
13224
|
+
this.userDir = this.defaultProvidersDir;
|
|
13225
|
+
this.upstreamDir = path14.join(this.defaultProvidersDir, ".upstream");
|
|
13226
|
+
this.disableUpstream = false;
|
|
13227
|
+
this.applySourceConfig({
|
|
13228
|
+
userDir: options?.userDir,
|
|
13229
|
+
sourceMode: options?.sourceMode,
|
|
13230
|
+
disableUpstream: options?.disableUpstream
|
|
13231
|
+
});
|
|
12898
13232
|
}
|
|
12899
13233
|
log(msg) {
|
|
12900
13234
|
this.logFn(`[ProviderLoader] ${msg}`);
|
|
@@ -12919,6 +13253,33 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12919
13253
|
getProviderRoots() {
|
|
12920
13254
|
return [this.userDir, this.upstreamDir];
|
|
12921
13255
|
}
|
|
13256
|
+
getSourceConfig() {
|
|
13257
|
+
return {
|
|
13258
|
+
sourceMode: this.sourceMode,
|
|
13259
|
+
disableUpstream: this.disableUpstream,
|
|
13260
|
+
explicitProviderDir: this.explicitProviderDir,
|
|
13261
|
+
userDir: this.userDir,
|
|
13262
|
+
upstreamDir: this.upstreamDir,
|
|
13263
|
+
providerRoots: this.getProviderRoots()
|
|
13264
|
+
};
|
|
13265
|
+
}
|
|
13266
|
+
applySourceConfig(options) {
|
|
13267
|
+
const nextSourceMode = options?.sourceMode === "no-upstream" ? "no-upstream" : options?.sourceMode === "normal" ? "normal" : options?.disableUpstream ? "no-upstream" : this.sourceMode || "normal";
|
|
13268
|
+
if (options && Object.prototype.hasOwnProperty.call(options, "userDir")) {
|
|
13269
|
+
this.explicitProviderDir = options.userDir?.trim() ? options.userDir : null;
|
|
13270
|
+
}
|
|
13271
|
+
this.sourceMode = nextSourceMode;
|
|
13272
|
+
this.userDir = this.explicitProviderDir || this.defaultProvidersDir;
|
|
13273
|
+
this.upstreamDir = path14.join(this.defaultProvidersDir, ".upstream");
|
|
13274
|
+
this.disableUpstream = this.sourceMode === "no-upstream";
|
|
13275
|
+
if (this.explicitProviderDir) {
|
|
13276
|
+
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
13277
|
+
} else {
|
|
13278
|
+
this.log(`Using default user providers directory: ${this.userDir}`);
|
|
13279
|
+
}
|
|
13280
|
+
this.log(`Provider source config: mode=${this.sourceMode} explicitProviderDir=${this.explicitProviderDir || "-"} userDir=${this.userDir} upstreamDir=${this.upstreamDir}`);
|
|
13281
|
+
return this.getSourceConfig();
|
|
13282
|
+
}
|
|
12922
13283
|
/**
|
|
12923
13284
|
* Canonical provider directory shape for a given root.
|
|
12924
13285
|
*/
|
|
@@ -12969,7 +13330,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
12969
13330
|
this.log(`Loaded ${upstreamCount} upstream providers (auto-updated)`);
|
|
12970
13331
|
}
|
|
12971
13332
|
} else if (this.disableUpstream) {
|
|
12972
|
-
this.log("Upstream loading disabled (
|
|
13333
|
+
this.log("Upstream loading disabled (sourceMode=no-upstream)");
|
|
12973
13334
|
}
|
|
12974
13335
|
if (fs6.existsSync(this.userDir)) {
|
|
12975
13336
|
const userCount = this.loadDir(this.userDir, [".upstream"]);
|
|
@@ -13480,7 +13841,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13480
13841
|
*/
|
|
13481
13842
|
async fetchLatest() {
|
|
13482
13843
|
if (this.disableUpstream) {
|
|
13483
|
-
this.log("Upstream fetch skipped (
|
|
13844
|
+
this.log("Upstream fetch skipped (sourceMode=no-upstream)");
|
|
13484
13845
|
return { updated: false };
|
|
13485
13846
|
}
|
|
13486
13847
|
const https = require("https");
|
|
@@ -13502,7 +13863,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13502
13863
|
return { updated: false };
|
|
13503
13864
|
}
|
|
13504
13865
|
try {
|
|
13505
|
-
const etag = await new Promise((
|
|
13866
|
+
const etag = await new Promise((resolve11, reject) => {
|
|
13506
13867
|
const options = {
|
|
13507
13868
|
method: "HEAD",
|
|
13508
13869
|
hostname: "github.com",
|
|
@@ -13520,7 +13881,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13520
13881
|
headers: { "User-Agent": "adhdev-launcher" },
|
|
13521
13882
|
timeout: 1e4
|
|
13522
13883
|
}, (res2) => {
|
|
13523
|
-
|
|
13884
|
+
resolve11(res2.headers.etag || res2.headers["last-modified"] || "");
|
|
13524
13885
|
});
|
|
13525
13886
|
req2.on("error", reject);
|
|
13526
13887
|
req2.on("timeout", () => {
|
|
@@ -13529,7 +13890,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13529
13890
|
});
|
|
13530
13891
|
req2.end();
|
|
13531
13892
|
} else {
|
|
13532
|
-
|
|
13893
|
+
resolve11(res.headers.etag || res.headers["last-modified"] || "");
|
|
13533
13894
|
}
|
|
13534
13895
|
});
|
|
13535
13896
|
req.on("error", reject);
|
|
@@ -13593,7 +13954,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13593
13954
|
downloadFile(url, destPath) {
|
|
13594
13955
|
const https = require("https");
|
|
13595
13956
|
const http3 = require("http");
|
|
13596
|
-
return new Promise((
|
|
13957
|
+
return new Promise((resolve11, reject) => {
|
|
13597
13958
|
const doRequest = (reqUrl, redirectCount = 0) => {
|
|
13598
13959
|
if (redirectCount > 5) {
|
|
13599
13960
|
reject(new Error("Too many redirects"));
|
|
@@ -13613,7 +13974,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
13613
13974
|
res.pipe(ws);
|
|
13614
13975
|
ws.on("finish", () => {
|
|
13615
13976
|
ws.close();
|
|
13616
|
-
|
|
13977
|
+
resolve11();
|
|
13617
13978
|
});
|
|
13618
13979
|
ws.on("error", reject);
|
|
13619
13980
|
});
|
|
@@ -14088,17 +14449,17 @@ async function findFreePort(ports) {
|
|
|
14088
14449
|
throw new Error("No free port found");
|
|
14089
14450
|
}
|
|
14090
14451
|
function checkPortFree(port) {
|
|
14091
|
-
return new Promise((
|
|
14452
|
+
return new Promise((resolve11) => {
|
|
14092
14453
|
const server = net.createServer();
|
|
14093
14454
|
server.unref();
|
|
14094
|
-
server.on("error", () =>
|
|
14455
|
+
server.on("error", () => resolve11(false));
|
|
14095
14456
|
server.listen(port, "127.0.0.1", () => {
|
|
14096
|
-
server.close(() =>
|
|
14457
|
+
server.close(() => resolve11(true));
|
|
14097
14458
|
});
|
|
14098
14459
|
});
|
|
14099
14460
|
}
|
|
14100
14461
|
async function isCdpActive(port) {
|
|
14101
|
-
return new Promise((
|
|
14462
|
+
return new Promise((resolve11) => {
|
|
14102
14463
|
const req = require("http").get(`http://127.0.0.1:${port}/json/version`, {
|
|
14103
14464
|
timeout: 2e3
|
|
14104
14465
|
}, (res) => {
|
|
@@ -14107,16 +14468,16 @@ async function isCdpActive(port) {
|
|
|
14107
14468
|
res.on("end", () => {
|
|
14108
14469
|
try {
|
|
14109
14470
|
const info = JSON.parse(data);
|
|
14110
|
-
|
|
14471
|
+
resolve11(!!info["WebKit-Version"] || !!info["Browser"]);
|
|
14111
14472
|
} catch {
|
|
14112
|
-
|
|
14473
|
+
resolve11(false);
|
|
14113
14474
|
}
|
|
14114
14475
|
});
|
|
14115
14476
|
});
|
|
14116
|
-
req.on("error", () =>
|
|
14477
|
+
req.on("error", () => resolve11(false));
|
|
14117
14478
|
req.on("timeout", () => {
|
|
14118
14479
|
req.destroy();
|
|
14119
|
-
|
|
14480
|
+
resolve11(false);
|
|
14120
14481
|
});
|
|
14121
14482
|
});
|
|
14122
14483
|
}
|
|
@@ -14567,12 +14928,90 @@ cleanOldFiles();
|
|
|
14567
14928
|
// src/commands/router.ts
|
|
14568
14929
|
init_logger();
|
|
14569
14930
|
|
|
14931
|
+
// src/session-host/runtime-surface.ts
|
|
14932
|
+
var LIVE_LIFECYCLES = /* @__PURE__ */ new Set(["starting", "running", "stopping", "interrupted"]);
|
|
14933
|
+
function isSessionHostLiveRuntime(record) {
|
|
14934
|
+
const lifecycle = String(record?.lifecycle || "").trim();
|
|
14935
|
+
return LIVE_LIFECYCLES.has(lifecycle);
|
|
14936
|
+
}
|
|
14937
|
+
function getSessionHostRecoveryLabel(meta) {
|
|
14938
|
+
const recoveryState = typeof meta?.runtimeRecoveryState === "string" ? String(meta.runtimeRecoveryState).trim() : "";
|
|
14939
|
+
if (!recoveryState) return null;
|
|
14940
|
+
if (recoveryState === "auto_resumed") return "restored after restart";
|
|
14941
|
+
if (recoveryState === "resume_failed") return "restore failed";
|
|
14942
|
+
if (recoveryState === "host_restart_interrupted") return "host restart interrupted";
|
|
14943
|
+
if (recoveryState === "orphan_snapshot") return "snapshot recovered";
|
|
14944
|
+
return recoveryState.replace(/_/g, " ");
|
|
14945
|
+
}
|
|
14946
|
+
function isSessionHostRecoverySnapshot(record) {
|
|
14947
|
+
if (!record) return false;
|
|
14948
|
+
if (isSessionHostLiveRuntime(record)) return false;
|
|
14949
|
+
const lifecycle = String(record.lifecycle || "").trim();
|
|
14950
|
+
if (lifecycle && lifecycle !== "stopped" && lifecycle !== "failed") {
|
|
14951
|
+
return false;
|
|
14952
|
+
}
|
|
14953
|
+
const meta = record.meta || void 0;
|
|
14954
|
+
if (meta?.restoredFromStorage === true) return true;
|
|
14955
|
+
return getSessionHostRecoveryLabel(meta) !== null;
|
|
14956
|
+
}
|
|
14957
|
+
function getSessionHostSurfaceKind(record) {
|
|
14958
|
+
if (isSessionHostLiveRuntime(record)) return "live_runtime";
|
|
14959
|
+
if (isSessionHostRecoverySnapshot(record)) return "recovery_snapshot";
|
|
14960
|
+
return "inactive_record";
|
|
14961
|
+
}
|
|
14962
|
+
function partitionSessionHostRecords(records) {
|
|
14963
|
+
const liveRuntimes = [];
|
|
14964
|
+
const recoverySnapshots = [];
|
|
14965
|
+
const inactiveRecords = [];
|
|
14966
|
+
for (const record of records) {
|
|
14967
|
+
const kind = getSessionHostSurfaceKind(record);
|
|
14968
|
+
if (kind === "live_runtime") {
|
|
14969
|
+
liveRuntimes.push(record);
|
|
14970
|
+
} else if (kind === "recovery_snapshot") {
|
|
14971
|
+
recoverySnapshots.push(record);
|
|
14972
|
+
} else {
|
|
14973
|
+
inactiveRecords.push(record);
|
|
14974
|
+
}
|
|
14975
|
+
}
|
|
14976
|
+
return {
|
|
14977
|
+
liveRuntimes,
|
|
14978
|
+
recoverySnapshots,
|
|
14979
|
+
inactiveRecords
|
|
14980
|
+
};
|
|
14981
|
+
}
|
|
14982
|
+
function partitionSessionHostDiagnosticsSessions(records) {
|
|
14983
|
+
return partitionSessionHostRecords(records || []);
|
|
14984
|
+
}
|
|
14985
|
+
|
|
14570
14986
|
// src/status/snapshot.ts
|
|
14571
14987
|
var os16 = __toESM(require("os"));
|
|
14572
14988
|
init_config();
|
|
14573
14989
|
init_terminal_screen();
|
|
14574
14990
|
init_logger();
|
|
14575
14991
|
var READ_DEBUG_ENABLED = process.argv.includes("--dev") || process.env.ADHDEV_READ_DEBUG === "1";
|
|
14992
|
+
var recentReadDebugSignatureBySession = /* @__PURE__ */ new Map();
|
|
14993
|
+
function buildRecentReadDebugSignature(snapshot) {
|
|
14994
|
+
return [
|
|
14995
|
+
snapshot.providerType,
|
|
14996
|
+
snapshot.status,
|
|
14997
|
+
snapshot.inboxBucket,
|
|
14998
|
+
snapshot.unread ? "1" : "0",
|
|
14999
|
+
String(snapshot.lastSeenAt),
|
|
15000
|
+
snapshot.completionMarker,
|
|
15001
|
+
snapshot.seenCompletionMarker,
|
|
15002
|
+
String(snapshot.lastUpdated),
|
|
15003
|
+
String(snapshot.lastUsedAt),
|
|
15004
|
+
snapshot.lastRole,
|
|
15005
|
+
String(snapshot.messageUpdatedAt)
|
|
15006
|
+
].join("|");
|
|
15007
|
+
}
|
|
15008
|
+
function shouldEmitRecentReadDebugLog(cache, snapshot) {
|
|
15009
|
+
const nextSignature = buildRecentReadDebugSignature(snapshot);
|
|
15010
|
+
const previousSignature = cache.get(snapshot.sessionId);
|
|
15011
|
+
if (previousSignature === nextSignature) return false;
|
|
15012
|
+
cache.set(snapshot.sessionId, nextSignature);
|
|
15013
|
+
return true;
|
|
15014
|
+
}
|
|
14576
15015
|
function buildDetectedIdeInfos(detectedIdes, cdpManagers) {
|
|
14577
15016
|
return detectedIdes.filter((ide) => ide.installed !== false).map((ide) => ({
|
|
14578
15017
|
id: ide.id,
|
|
@@ -14724,7 +15163,7 @@ function buildRecentLaunches(recentActivity) {
|
|
|
14724
15163
|
providerSessionId: item.providerSessionId,
|
|
14725
15164
|
title: item.title || item.providerName,
|
|
14726
15165
|
workspace: item.workspace,
|
|
14727
|
-
|
|
15166
|
+
summaryMetadata: item.summaryMetadata,
|
|
14728
15167
|
lastLaunchedAt: item.lastUsedAt
|
|
14729
15168
|
})).sort((a, b) => b.lastLaunchedAt - a.lastLaunchedAt).slice(0, 12);
|
|
14730
15169
|
}
|
|
@@ -14765,9 +15204,24 @@ function buildStatusSnapshot(options) {
|
|
|
14765
15204
|
session.unread = unread;
|
|
14766
15205
|
session.inboxBucket = inboxBucket;
|
|
14767
15206
|
if (READ_DEBUG_ENABLED && (session.unread || session.inboxBucket !== "idle" || session.providerType.includes("codex"))) {
|
|
15207
|
+
const recentReadSnapshot = {
|
|
15208
|
+
sessionId: session.id,
|
|
15209
|
+
providerType: session.providerType,
|
|
15210
|
+
status: String(session.status || ""),
|
|
15211
|
+
inboxBucket,
|
|
15212
|
+
unread,
|
|
15213
|
+
lastSeenAt,
|
|
15214
|
+
completionMarker: completionMarker || "-",
|
|
15215
|
+
seenCompletionMarker: seenCompletionMarker || "-",
|
|
15216
|
+
lastUpdated: Number(session.lastUpdated || 0),
|
|
15217
|
+
lastUsedAt,
|
|
15218
|
+
lastRole: getLastMessageRole(sourceSession),
|
|
15219
|
+
messageUpdatedAt: getSessionMessageUpdatedAt(sourceSession)
|
|
15220
|
+
};
|
|
15221
|
+
if (!shouldEmitRecentReadDebugLog(recentReadDebugSignatureBySession, recentReadSnapshot)) continue;
|
|
14768
15222
|
LOG.info(
|
|
14769
15223
|
"RecentRead",
|
|
14770
|
-
`snapshot session id=${
|
|
15224
|
+
`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}`
|
|
14771
15225
|
);
|
|
14772
15226
|
}
|
|
14773
15227
|
const lastDisplayMessage = getLastDisplayMessage(sourceSession);
|
|
@@ -14845,7 +15299,7 @@ async function waitForPidExit(pid, timeoutMs) {
|
|
|
14845
15299
|
while (Date.now() - start < timeoutMs) {
|
|
14846
15300
|
try {
|
|
14847
15301
|
process.kill(pid, 0);
|
|
14848
|
-
await new Promise((
|
|
15302
|
+
await new Promise((resolve11) => setTimeout(resolve11, 250));
|
|
14849
15303
|
} catch {
|
|
14850
15304
|
return;
|
|
14851
15305
|
}
|
|
@@ -14960,7 +15414,7 @@ async function runDaemonUpgradeHelper(payload) {
|
|
|
14960
15414
|
appendUpgradeLog(installOutput.trim());
|
|
14961
15415
|
}
|
|
14962
15416
|
if (process.platform === "win32") {
|
|
14963
|
-
await new Promise((
|
|
15417
|
+
await new Promise((resolve11) => setTimeout(resolve11, 500));
|
|
14964
15418
|
cleanupStaleGlobalInstallDirs(payload.packageName);
|
|
14965
15419
|
appendUpgradeLog("Post-install staging cleanup complete");
|
|
14966
15420
|
}
|
|
@@ -15042,11 +15496,104 @@ function toHostedCliRuntimeDescriptor(record) {
|
|
|
15042
15496
|
providerSessionId: typeof record.meta?.providerSessionId === "string" ? String(record.meta.providerSessionId) : void 0
|
|
15043
15497
|
};
|
|
15044
15498
|
}
|
|
15499
|
+
function getWriteConflictOwnerClientId(error) {
|
|
15500
|
+
const message = typeof error === "string" ? error : error instanceof Error ? error.message : "";
|
|
15501
|
+
const match = /^Write owned by\s+(.+)$/.exec(message.trim());
|
|
15502
|
+
return match?.[1]?.trim() || void 0;
|
|
15503
|
+
}
|
|
15504
|
+
function summarizeSessionHostRecord(result) {
|
|
15505
|
+
if (!result || typeof result !== "object") return {};
|
|
15506
|
+
const record = result;
|
|
15507
|
+
return {
|
|
15508
|
+
runtimeKey: typeof record.runtimeKey === "string" ? record.runtimeKey : void 0,
|
|
15509
|
+
lifecycle: typeof record.lifecycle === "string" ? record.lifecycle : void 0,
|
|
15510
|
+
surfaceKind: getSessionHostSurfaceKind(record),
|
|
15511
|
+
attachedClientCount: Array.isArray(record.attachedClients) ? record.attachedClients.length : void 0,
|
|
15512
|
+
hasWriteOwner: !!record.writeOwner,
|
|
15513
|
+
writeOwnerClientId: typeof record.writeOwner?.clientId === "string" ? record.writeOwner.clientId : void 0
|
|
15514
|
+
};
|
|
15515
|
+
}
|
|
15516
|
+
function summarizeSessionHostRecords(result) {
|
|
15517
|
+
const records = Array.isArray(result) ? result : [];
|
|
15518
|
+
const groups = partitionSessionHostRecords(records);
|
|
15519
|
+
return {
|
|
15520
|
+
sessionCount: records.length,
|
|
15521
|
+
liveRuntimeCount: groups.liveRuntimes.length,
|
|
15522
|
+
recoverySnapshotCount: groups.recoverySnapshots.length,
|
|
15523
|
+
inactiveRecordCount: groups.inactiveRecords.length
|
|
15524
|
+
};
|
|
15525
|
+
}
|
|
15526
|
+
function summarizeSessionHostDiagnostics(result) {
|
|
15527
|
+
const diagnostics = result && typeof result === "object" ? result : {};
|
|
15528
|
+
const sessions = Array.isArray(diagnostics.sessions) ? diagnostics.sessions : [];
|
|
15529
|
+
return {
|
|
15530
|
+
runtimeCount: typeof diagnostics.runtimeCount === "number" ? diagnostics.runtimeCount : void 0,
|
|
15531
|
+
...summarizeSessionHostRecords(sessions)
|
|
15532
|
+
};
|
|
15533
|
+
}
|
|
15534
|
+
function summarizeSessionHostPruneResult(result) {
|
|
15535
|
+
const value = result && typeof result === "object" ? result : {};
|
|
15536
|
+
return {
|
|
15537
|
+
duplicateGroupCount: typeof value.duplicateGroupCount === "number" ? value.duplicateGroupCount : void 0,
|
|
15538
|
+
prunedCount: Array.isArray(value.prunedSessionIds) ? value.prunedSessionIds.length : void 0,
|
|
15539
|
+
keptCount: Array.isArray(value.keptSessionIds) ? value.keptSessionIds.length : void 0
|
|
15540
|
+
};
|
|
15541
|
+
}
|
|
15045
15542
|
var DaemonCommandRouter = class {
|
|
15046
15543
|
deps;
|
|
15047
15544
|
constructor(deps) {
|
|
15048
15545
|
this.deps = deps;
|
|
15049
15546
|
}
|
|
15547
|
+
async traceSessionHostAction(action, args, run, summarizeResult) {
|
|
15548
|
+
const interactionId = typeof args?._interactionId === "string" ? args._interactionId : void 0;
|
|
15549
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : void 0;
|
|
15550
|
+
const requestedPayload = { action };
|
|
15551
|
+
if (sessionId) requestedPayload.sessionId = sessionId;
|
|
15552
|
+
if (typeof args?.clientId === "string") requestedPayload.clientId = args.clientId;
|
|
15553
|
+
if (typeof args?.signal === "string") requestedPayload.signal = args.signal;
|
|
15554
|
+
if (typeof args?.providerType === "string") requestedPayload.providerType = args.providerType;
|
|
15555
|
+
if (typeof args?.workspace === "string") requestedPayload.workspace = args.workspace;
|
|
15556
|
+
if (typeof args?.dryRun === "boolean") requestedPayload.dryRun = args.dryRun;
|
|
15557
|
+
recordDebugTrace({
|
|
15558
|
+
interactionId,
|
|
15559
|
+
category: "session_host",
|
|
15560
|
+
stage: "action_requested",
|
|
15561
|
+
level: "info",
|
|
15562
|
+
sessionId,
|
|
15563
|
+
payload: requestedPayload
|
|
15564
|
+
});
|
|
15565
|
+
try {
|
|
15566
|
+
const result = await run();
|
|
15567
|
+
recordDebugTrace({
|
|
15568
|
+
interactionId,
|
|
15569
|
+
category: "session_host",
|
|
15570
|
+
stage: "action_result",
|
|
15571
|
+
level: "info",
|
|
15572
|
+
sessionId,
|
|
15573
|
+
payload: {
|
|
15574
|
+
...requestedPayload,
|
|
15575
|
+
success: true,
|
|
15576
|
+
...summarizeResult ? summarizeResult(result) : {}
|
|
15577
|
+
}
|
|
15578
|
+
});
|
|
15579
|
+
return result;
|
|
15580
|
+
} catch (error) {
|
|
15581
|
+
recordDebugTrace({
|
|
15582
|
+
interactionId,
|
|
15583
|
+
category: "session_host",
|
|
15584
|
+
stage: "action_failed",
|
|
15585
|
+
level: "error",
|
|
15586
|
+
sessionId,
|
|
15587
|
+
payload: {
|
|
15588
|
+
...requestedPayload,
|
|
15589
|
+
error: error?.message || String(error),
|
|
15590
|
+
failureKind: getWriteConflictOwnerClientId(error) ? "write_conflict" : "request_failed",
|
|
15591
|
+
conflictOwnerClientId: getWriteConflictOwnerClientId(error)
|
|
15592
|
+
}
|
|
15593
|
+
});
|
|
15594
|
+
throw error;
|
|
15595
|
+
}
|
|
15596
|
+
}
|
|
15050
15597
|
/**
|
|
15051
15598
|
* Unified command routing.
|
|
15052
15599
|
* Returns result for all commands:
|
|
@@ -15156,44 +15703,60 @@ var DaemonCommandRouter = class {
|
|
|
15156
15703
|
}
|
|
15157
15704
|
case "session_host_get_diagnostics": {
|
|
15158
15705
|
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
15159
|
-
const diagnostics = await this.deps.sessionHostControl.getDiagnostics({
|
|
15706
|
+
const diagnostics = await this.traceSessionHostAction("session_host_get_diagnostics", args, () => this.deps.sessionHostControl.getDiagnostics({
|
|
15160
15707
|
includeSessions: args?.includeSessions !== false,
|
|
15161
15708
|
limit: Number(args?.limit) || void 0
|
|
15162
|
-
})
|
|
15709
|
+
}), (result) => ({
|
|
15710
|
+
includeSessions: args?.includeSessions !== false,
|
|
15711
|
+
limit: Number(args?.limit) || void 0,
|
|
15712
|
+
...summarizeSessionHostDiagnostics(result)
|
|
15713
|
+
}));
|
|
15163
15714
|
return { success: true, diagnostics };
|
|
15164
15715
|
}
|
|
15165
15716
|
case "session_host_list_sessions": {
|
|
15166
15717
|
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
15167
|
-
const sessions = await this.deps.sessionHostControl.listSessions();
|
|
15718
|
+
const sessions = await this.traceSessionHostAction("session_host_list_sessions", args, () => this.deps.sessionHostControl.listSessions(), (records) => summarizeSessionHostRecords(records));
|
|
15168
15719
|
return { success: true, sessions };
|
|
15169
15720
|
}
|
|
15170
15721
|
case "session_host_stop_session": {
|
|
15171
15722
|
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
15172
15723
|
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
15173
15724
|
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
15174
|
-
const record = await this.deps.sessionHostControl.stopSession(sessionId);
|
|
15725
|
+
const record = await this.traceSessionHostAction("session_host_stop_session", args, () => this.deps.sessionHostControl.stopSession(sessionId), (result) => summarizeSessionHostRecord(result));
|
|
15175
15726
|
return { success: true, record };
|
|
15176
15727
|
}
|
|
15177
15728
|
case "session_host_resume_session": {
|
|
15178
15729
|
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
15179
15730
|
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
15180
15731
|
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
15181
|
-
const record = await this.
|
|
15182
|
-
|
|
15183
|
-
|
|
15184
|
-
|
|
15185
|
-
|
|
15732
|
+
const record = await this.traceSessionHostAction("session_host_resume_session", args, async () => {
|
|
15733
|
+
const nextRecord = await this.deps.sessionHostControl.resumeSession(sessionId);
|
|
15734
|
+
const hosted = toHostedCliRuntimeDescriptor(nextRecord);
|
|
15735
|
+
if (hosted) {
|
|
15736
|
+
await this.deps.cliManager.restoreHostedSessions([hosted]);
|
|
15737
|
+
}
|
|
15738
|
+
return nextRecord;
|
|
15739
|
+
}, (result) => ({
|
|
15740
|
+
...summarizeSessionHostRecord(result),
|
|
15741
|
+
restoredHostedSession: !!toHostedCliRuntimeDescriptor(result)
|
|
15742
|
+
}));
|
|
15186
15743
|
return { success: true, record };
|
|
15187
15744
|
}
|
|
15188
15745
|
case "session_host_restart_session": {
|
|
15189
15746
|
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
15190
15747
|
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
15191
15748
|
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
15192
|
-
const record = await this.
|
|
15193
|
-
|
|
15194
|
-
|
|
15195
|
-
|
|
15196
|
-
|
|
15749
|
+
const record = await this.traceSessionHostAction("session_host_restart_session", args, async () => {
|
|
15750
|
+
const nextRecord = await this.deps.sessionHostControl.restartSession(sessionId);
|
|
15751
|
+
const hosted = toHostedCliRuntimeDescriptor(nextRecord);
|
|
15752
|
+
if (hosted) {
|
|
15753
|
+
await this.deps.cliManager.restoreHostedSessions([hosted]);
|
|
15754
|
+
}
|
|
15755
|
+
return nextRecord;
|
|
15756
|
+
}, (result) => ({
|
|
15757
|
+
...summarizeSessionHostRecord(result),
|
|
15758
|
+
restoredHostedSession: !!toHostedCliRuntimeDescriptor(result)
|
|
15759
|
+
}));
|
|
15197
15760
|
return { success: true, record };
|
|
15198
15761
|
}
|
|
15199
15762
|
case "session_host_send_signal": {
|
|
@@ -15202,7 +15765,7 @@ var DaemonCommandRouter = class {
|
|
|
15202
15765
|
const signal = typeof args?.signal === "string" ? args.signal : "";
|
|
15203
15766
|
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
15204
15767
|
if (!signal) return { success: false, error: "signal required" };
|
|
15205
|
-
const record = await this.deps.sessionHostControl.sendSignal(sessionId, signal);
|
|
15768
|
+
const record = await this.traceSessionHostAction("session_host_send_signal", args, () => this.deps.sessionHostControl.sendSignal(sessionId, signal), (result) => summarizeSessionHostRecord(result));
|
|
15206
15769
|
return { success: true, record };
|
|
15207
15770
|
}
|
|
15208
15771
|
case "session_host_force_detach_client": {
|
|
@@ -15211,16 +15774,16 @@ var DaemonCommandRouter = class {
|
|
|
15211
15774
|
const clientId = typeof args?.clientId === "string" ? args.clientId : "";
|
|
15212
15775
|
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
15213
15776
|
if (!clientId) return { success: false, error: "clientId required" };
|
|
15214
|
-
const record = await this.deps.sessionHostControl.forceDetachClient(sessionId, clientId);
|
|
15777
|
+
const record = await this.traceSessionHostAction("session_host_force_detach_client", args, () => this.deps.sessionHostControl.forceDetachClient(sessionId, clientId), (result) => summarizeSessionHostRecord(result));
|
|
15215
15778
|
return { success: true, record };
|
|
15216
15779
|
}
|
|
15217
15780
|
case "session_host_prune_duplicate_sessions": {
|
|
15218
15781
|
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
15219
|
-
const result = await this.deps.sessionHostControl.pruneDuplicateSessions({
|
|
15782
|
+
const result = await this.traceSessionHostAction("session_host_prune_duplicate_sessions", args, () => this.deps.sessionHostControl.pruneDuplicateSessions({
|
|
15220
15783
|
providerType: typeof args?.providerType === "string" ? args.providerType : void 0,
|
|
15221
15784
|
workspace: typeof args?.workspace === "string" ? args.workspace : void 0,
|
|
15222
15785
|
dryRun: args?.dryRun === true
|
|
15223
|
-
});
|
|
15786
|
+
}), (value) => summarizeSessionHostPruneResult(value));
|
|
15224
15787
|
return { success: true, result };
|
|
15225
15788
|
}
|
|
15226
15789
|
case "session_host_acquire_write": {
|
|
@@ -15230,12 +15793,15 @@ var DaemonCommandRouter = class {
|
|
|
15230
15793
|
const ownerType = args?.ownerType === "agent" ? "agent" : "user";
|
|
15231
15794
|
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
15232
15795
|
if (!clientId) return { success: false, error: "clientId required" };
|
|
15233
|
-
const record = await this.deps.sessionHostControl.acquireWrite({
|
|
15796
|
+
const record = await this.traceSessionHostAction("session_host_acquire_write", args, () => this.deps.sessionHostControl.acquireWrite({
|
|
15234
15797
|
sessionId,
|
|
15235
15798
|
clientId,
|
|
15236
15799
|
ownerType,
|
|
15237
15800
|
force: args?.force !== false
|
|
15238
|
-
})
|
|
15801
|
+
}), (result) => ({
|
|
15802
|
+
...summarizeSessionHostRecord(result),
|
|
15803
|
+
ownerType
|
|
15804
|
+
}));
|
|
15239
15805
|
return { success: true, record };
|
|
15240
15806
|
}
|
|
15241
15807
|
case "session_host_release_write": {
|
|
@@ -15244,7 +15810,10 @@ var DaemonCommandRouter = class {
|
|
|
15244
15810
|
const clientId = typeof args?.clientId === "string" ? args.clientId : "";
|
|
15245
15811
|
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
15246
15812
|
if (!clientId) return { success: false, error: "clientId required" };
|
|
15247
|
-
const record = await this.deps.sessionHostControl.releaseWrite({
|
|
15813
|
+
const record = await this.traceSessionHostAction("session_host_release_write", args, () => this.deps.sessionHostControl.releaseWrite({
|
|
15814
|
+
sessionId,
|
|
15815
|
+
clientId
|
|
15816
|
+
}), (result) => summarizeSessionHostRecord(result));
|
|
15248
15817
|
return { success: true, record };
|
|
15249
15818
|
}
|
|
15250
15819
|
case "list_saved_sessions": {
|
|
@@ -15253,8 +15822,9 @@ var DaemonCommandRouter = class {
|
|
|
15253
15822
|
if (!providerType) {
|
|
15254
15823
|
return { success: false, error: "providerType required" };
|
|
15255
15824
|
}
|
|
15256
|
-
const
|
|
15257
|
-
const
|
|
15825
|
+
const wantsAll = args?.all === true;
|
|
15826
|
+
const offset = wantsAll ? 0 : Math.max(0, Number(args?.offset) || 0);
|
|
15827
|
+
const limit = wantsAll ? Number.MAX_SAFE_INTEGER : Math.max(1, Math.min(100, Number(args?.limit) || 30));
|
|
15258
15828
|
const { sessions: historySessions, hasMore } = listSavedHistorySessions(providerType, { offset, limit });
|
|
15259
15829
|
const state = loadState();
|
|
15260
15830
|
const savedSessions = getSavedProviderSessions(state, { providerType, kind });
|
|
@@ -15275,13 +15845,13 @@ var DaemonCommandRouter = class {
|
|
|
15275
15845
|
providerName: saved?.providerName || recent?.providerName || providerType,
|
|
15276
15846
|
kind: saved?.kind || recent?.kind || kind,
|
|
15277
15847
|
title: saved?.title || recent?.title || session.sessionTitle || session.preview || providerType,
|
|
15278
|
-
workspace: saved?.workspace || recent?.workspace,
|
|
15279
|
-
|
|
15848
|
+
workspace: saved?.workspace || recent?.workspace || session.workspace,
|
|
15849
|
+
summaryMetadata: saved?.summaryMetadata || recent?.summaryMetadata,
|
|
15280
15850
|
preview: session.preview,
|
|
15281
15851
|
messageCount: session.messageCount,
|
|
15282
15852
|
firstMessageAt: session.firstMessageAt,
|
|
15283
15853
|
lastMessageAt: session.lastMessageAt,
|
|
15284
|
-
canResume: !!(saved?.workspace || recent?.workspace) && canResumeById
|
|
15854
|
+
canResume: !!(saved?.workspace || recent?.workspace || session.workspace) && canResumeById
|
|
15285
15855
|
};
|
|
15286
15856
|
}),
|
|
15287
15857
|
hasMore
|
|
@@ -15715,7 +16285,7 @@ var DaemonStatusReporter = class {
|
|
|
15715
16285
|
const ideSummary = ideStates.map((s) => {
|
|
15716
16286
|
const msgs = s.activeChat?.messages?.length || 0;
|
|
15717
16287
|
const exts = s.extensions.length;
|
|
15718
|
-
return `${s.type}(${s.status},${msgs}msg,${exts}ext
|
|
16288
|
+
return `${s.type}(${s.status},${msgs}msg,${exts}ext)`;
|
|
15719
16289
|
}).join(", ");
|
|
15720
16290
|
const cliSummary = cliStates.map((s) => `${s.type}(${s.status})`).join(", ");
|
|
15721
16291
|
const acpSummary = acpStates.map((s) => `${s.type}(${s.status})`).join(", ");
|
|
@@ -15777,9 +16347,7 @@ var DaemonStatusReporter = class {
|
|
|
15777
16347
|
workspace: session.workspace ?? null,
|
|
15778
16348
|
title: session.title,
|
|
15779
16349
|
cdpConnected: session.cdpConnected,
|
|
15780
|
-
|
|
15781
|
-
currentPlan: session.currentPlan,
|
|
15782
|
-
currentAutoApprove: session.currentAutoApprove
|
|
16350
|
+
summaryMetadata: session.summaryMetadata
|
|
15783
16351
|
})),
|
|
15784
16352
|
p2p: payload.p2p,
|
|
15785
16353
|
timestamp: now
|
|
@@ -15898,7 +16466,7 @@ var ProviderStreamAdapter = class {
|
|
|
15898
16466
|
const beforeCount = this.messageCount(before);
|
|
15899
16467
|
const beforeSignature = this.lastMessageSignature(before);
|
|
15900
16468
|
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
15901
|
-
await new Promise((
|
|
16469
|
+
await new Promise((resolve11) => setTimeout(resolve11, 250));
|
|
15902
16470
|
let state;
|
|
15903
16471
|
try {
|
|
15904
16472
|
state = await this.readChat(evaluate);
|
|
@@ -15920,7 +16488,7 @@ var ProviderStreamAdapter = class {
|
|
|
15920
16488
|
if (this.messageCount(first) > 0 || this.lastMessageSignature(first)) {
|
|
15921
16489
|
return first;
|
|
15922
16490
|
}
|
|
15923
|
-
await new Promise((
|
|
16491
|
+
await new Promise((resolve11) => setTimeout(resolve11, 150));
|
|
15924
16492
|
const second = await this.readChat(evaluate);
|
|
15925
16493
|
return this.messageCount(second) >= this.messageCount(first) ? second : first;
|
|
15926
16494
|
}
|
|
@@ -15945,15 +16513,18 @@ var ProviderStreamAdapter = class {
|
|
|
15945
16513
|
status: data.status || "idle",
|
|
15946
16514
|
messages: data.messages || [],
|
|
15947
16515
|
inputContent: data.inputContent || "",
|
|
15948
|
-
model: data.model,
|
|
15949
|
-
mode: data.mode,
|
|
15950
16516
|
activeModal: data.activeModal
|
|
15951
16517
|
};
|
|
15952
16518
|
if (typeof data.title === "string" && data.title.trim()) {
|
|
15953
16519
|
state.title = data.title.trim();
|
|
15954
16520
|
}
|
|
15955
16521
|
const controlValues = extractProviderControlValues(this.provider.controls, data);
|
|
15956
|
-
|
|
16522
|
+
const surface = resolveProviderStateSurface({
|
|
16523
|
+
controlValues,
|
|
16524
|
+
summaryMetadata: data.summaryMetadata
|
|
16525
|
+
});
|
|
16526
|
+
if (surface.controlValues) state.controlValues = surface.controlValues;
|
|
16527
|
+
if (surface.summaryMetadata) state.summaryMetadata = surface.summaryMetadata;
|
|
15957
16528
|
const effects = normalizeProviderEffects(data);
|
|
15958
16529
|
if (effects.length > 0) state.effects = effects;
|
|
15959
16530
|
if (state.messages.length > 0) {
|
|
@@ -16060,7 +16631,7 @@ var ProviderStreamAdapter = class {
|
|
|
16060
16631
|
if (typeof data.error === "string" && data.error.trim()) return false;
|
|
16061
16632
|
}
|
|
16062
16633
|
for (let attempt = 0; attempt < 6; attempt += 1) {
|
|
16063
|
-
await new Promise((
|
|
16634
|
+
await new Promise((resolve11) => setTimeout(resolve11, 250));
|
|
16064
16635
|
const state = await this.readChat(evaluate);
|
|
16065
16636
|
const title = this.getStateTitle(state);
|
|
16066
16637
|
if (this.titlesMatch(title, sessionId)) return true;
|
|
@@ -16227,7 +16798,8 @@ var DaemonAgentStreamManager = class {
|
|
|
16227
16798
|
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
|
|
16228
16799
|
const state = await agent.adapter.readChat(evaluate);
|
|
16229
16800
|
const stateError = this.getStateError(state);
|
|
16230
|
-
|
|
16801
|
+
const selectedModelValue = typeof state.controlValues?.model === "string" ? state.controlValues.model : "";
|
|
16802
|
+
LOG.debug("AgentStream", `[AgentStream] readChat(${type}) result: status=${state.status} msgs=${state.messages?.length || 0} model=${selectedModelValue}${state.status === "error" ? " error=" + JSON.stringify(stateError) : ""}`);
|
|
16231
16803
|
if (state.status === "error" && this.isRecoverableSessionError(stateError)) {
|
|
16232
16804
|
throw new Error(stateError);
|
|
16233
16805
|
}
|
|
@@ -16575,9 +17147,8 @@ function forwardAgentStreamsToIdeInstance(instanceManager, ideType, streams) {
|
|
|
16575
17147
|
messages: stream.messages || [],
|
|
16576
17148
|
status: stream.status || "idle",
|
|
16577
17149
|
activeModal: stream.activeModal || null,
|
|
16578
|
-
model: stream.model || void 0,
|
|
16579
|
-
mode: stream.mode || void 0,
|
|
16580
17150
|
controlValues: stream.controlValues || void 0,
|
|
17151
|
+
summaryMetadata: stream.summaryMetadata || void 0,
|
|
16581
17152
|
effects: stream.effects || void 0,
|
|
16582
17153
|
sessionId: stream.sessionId || stream.instanceId || void 0,
|
|
16583
17154
|
title: stream.title || stream.agentName || void 0,
|
|
@@ -16982,6 +17553,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
16982
17553
|
var http2 = __toESM(require("http"));
|
|
16983
17554
|
var fs14 = __toESM(require("fs"));
|
|
16984
17555
|
var path22 = __toESM(require("path"));
|
|
17556
|
+
init_config();
|
|
16985
17557
|
|
|
16986
17558
|
// src/daemon/scaffold-template.ts
|
|
16987
17559
|
function generateFiles(type, name, category, opts = {}) {
|
|
@@ -17112,7 +17684,11 @@ module.exports.setMode = (params) => {
|
|
|
17112
17684
|
* 5. Approval dialog detection (buttons, modal)
|
|
17113
17685
|
* 6. Input field selector
|
|
17114
17686
|
*
|
|
17115
|
-
*
|
|
17687
|
+
* Preferred live-state surface:
|
|
17688
|
+
* - controlValues: explicit current control selections (model/mode/etc.)
|
|
17689
|
+
* - summaryMetadata: compact always-visible metadata for dashboard/recent views
|
|
17690
|
+
* Legacy top-level model/mode output is no longer the preferred shape.
|
|
17691
|
+
* \u2192 { id, status, title, messages[], inputContent, activeModal, controlValues?, summaryMetadata? }
|
|
17116
17692
|
*/
|
|
17117
17693
|
(() => {
|
|
17118
17694
|
try {
|
|
@@ -17140,6 +17716,9 @@ module.exports.setMode = (params) => {
|
|
|
17140
17716
|
messages,
|
|
17141
17717
|
inputContent,
|
|
17142
17718
|
activeModal,
|
|
17719
|
+
// TODO: Return explicit selections when available, e.g.
|
|
17720
|
+
// controlValues: { model: selectedModel, mode: selectedMode },
|
|
17721
|
+
// summaryMetadata: { items: [{ id: 'model', value: selectedModelLabel || selectedModel, shortValue: selectedModel, order: 10 }] },
|
|
17143
17722
|
});
|
|
17144
17723
|
} catch(e) {
|
|
17145
17724
|
return JSON.stringify({ id: '', status: 'error', messages: [], error: e.message });
|
|
@@ -18518,7 +19097,7 @@ function getCliTargetBundle(ctx, type, instanceId) {
|
|
|
18518
19097
|
return { target, instance, adapter };
|
|
18519
19098
|
}
|
|
18520
19099
|
function sleep(ms) {
|
|
18521
|
-
return new Promise((
|
|
19100
|
+
return new Promise((resolve11) => setTimeout(resolve11, ms));
|
|
18522
19101
|
}
|
|
18523
19102
|
async function waitForCliReady(ctx, type, instanceId, timeoutMs) {
|
|
18524
19103
|
const startedAt = Date.now();
|
|
@@ -18880,7 +19459,6 @@ async function handleCliStatus(ctx, _req, res) {
|
|
|
18880
19459
|
lastMessage: s.activeChat?.messages?.slice(-1)[0] || null,
|
|
18881
19460
|
activeModal: s.activeChat?.activeModal || null,
|
|
18882
19461
|
pendingEvents: s.pendingEvents || [],
|
|
18883
|
-
currentModel: s.currentModel,
|
|
18884
19462
|
settings: s.settings
|
|
18885
19463
|
}));
|
|
18886
19464
|
ctx.json(res, 200, { instances: result, count: result.length });
|
|
@@ -19365,18 +19943,6 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
19365
19943
|
if (!fs13.existsSync(providerJson)) {
|
|
19366
19944
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
19367
19945
|
}
|
|
19368
|
-
try {
|
|
19369
|
-
const providerData = JSON.parse(fs13.readFileSync(providerJson, "utf-8"));
|
|
19370
|
-
if (providerData.disableUpstream !== true) {
|
|
19371
|
-
providerData.disableUpstream = true;
|
|
19372
|
-
fs13.writeFileSync(providerJson, JSON.stringify(providerData, null, 2));
|
|
19373
|
-
}
|
|
19374
|
-
} catch (error) {
|
|
19375
|
-
return {
|
|
19376
|
-
dir: null,
|
|
19377
|
-
reason: `Failed to update provider.json in writable provider directory: ${error.message}`
|
|
19378
|
-
};
|
|
19379
|
-
}
|
|
19380
19946
|
return { dir: desiredDir };
|
|
19381
19947
|
}
|
|
19382
19948
|
function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
@@ -20049,7 +20615,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
20049
20615
|
lines.push("## Required Return Format");
|
|
20050
20616
|
lines.push("| Function | Return JSON |");
|
|
20051
20617
|
lines.push("|---|---|");
|
|
20052
|
-
lines.push("| readChat | `{ id, status, title, messages: [{role, content, index, kind?, meta?}], inputContent, activeModal }` \u2014 optional `kind`: standard, thought, tool, terminal;
|
|
20618
|
+
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 |");
|
|
20053
20619
|
lines.push("| sendMessage | `{ sent: false, needsTypeAndSend: true, selector }` |");
|
|
20054
20620
|
lines.push("| resolveAction | `{ resolved: true/false, clicked? }` |");
|
|
20055
20621
|
lines.push("| listSessions | `{ sessions: [{ id, title, active, index }] }` |");
|
|
@@ -20663,6 +21229,7 @@ var DevServer = class _DevServer {
|
|
|
20663
21229
|
cdpManagers;
|
|
20664
21230
|
instanceManager;
|
|
20665
21231
|
cliManager;
|
|
21232
|
+
onProviderSourceConfigChanged;
|
|
20666
21233
|
logFn;
|
|
20667
21234
|
sseClients = [];
|
|
20668
21235
|
watchScriptPath = null;
|
|
@@ -20679,6 +21246,7 @@ var DevServer = class _DevServer {
|
|
|
20679
21246
|
this.cdpManagers = options.cdpManagers;
|
|
20680
21247
|
this.instanceManager = options.instanceManager || null;
|
|
20681
21248
|
this.cliManager = options.cliManager || null;
|
|
21249
|
+
this.onProviderSourceConfigChanged = options.onProviderSourceConfigChanged || null;
|
|
20682
21250
|
this.logFn = options.logFn || LOG.forComponent("DevServer").asLogFn();
|
|
20683
21251
|
}
|
|
20684
21252
|
log(msg) {
|
|
@@ -20688,6 +21256,8 @@ var DevServer = class _DevServer {
|
|
|
20688
21256
|
routes = [
|
|
20689
21257
|
// Static routes
|
|
20690
21258
|
{ method: "GET", pattern: "/api/providers", handler: (q, s) => this.handleListProviders(q, s) },
|
|
21259
|
+
{ method: "GET", pattern: "/api/providers/source-config", handler: (q, s) => this.handleGetProviderSourceConfig(q, s) },
|
|
21260
|
+
{ method: "POST", pattern: "/api/providers/source-config", handler: (q, s) => this.handleSetProviderSourceConfig(q, s) },
|
|
20691
21261
|
{ method: "GET", pattern: "/api/providers/versions", handler: (q, s) => this.handleDetectVersions(q, s) },
|
|
20692
21262
|
{ method: "POST", pattern: "/api/providers/reload", handler: (q, s) => this.handleReload(q, s) },
|
|
20693
21263
|
{ method: "POST", pattern: "/api/cdp/evaluate", handler: (q, s) => this.handleCdpEvaluate(q, s) },
|
|
@@ -20785,15 +21355,15 @@ var DevServer = class _DevServer {
|
|
|
20785
21355
|
this.json(res, 500, { error: e.message });
|
|
20786
21356
|
}
|
|
20787
21357
|
});
|
|
20788
|
-
return new Promise((
|
|
21358
|
+
return new Promise((resolve11, reject) => {
|
|
20789
21359
|
this.server.listen(port, "127.0.0.1", () => {
|
|
20790
21360
|
this.log(`Dev server listening on http://127.0.0.1:${port}`);
|
|
20791
|
-
|
|
21361
|
+
resolve11();
|
|
20792
21362
|
});
|
|
20793
21363
|
this.server.on("error", (e) => {
|
|
20794
21364
|
if (e.code === "EADDRINUSE") {
|
|
20795
21365
|
this.log(`Port ${port} in use, skipping dev server`);
|
|
20796
|
-
|
|
21366
|
+
resolve11();
|
|
20797
21367
|
} else {
|
|
20798
21368
|
reject(e);
|
|
20799
21369
|
}
|
|
@@ -20807,7 +21377,33 @@ var DevServer = class _DevServer {
|
|
|
20807
21377
|
// ─── Handlers ───
|
|
20808
21378
|
async handleListProviders(_req, res) {
|
|
20809
21379
|
const providers = this.providerLoader.getAll().map(toProviderListEntry);
|
|
20810
|
-
this.json(res, 200, { providers, count: providers.length });
|
|
21380
|
+
this.json(res, 200, { providers, count: providers.length, sourceConfig: this.providerLoader.getSourceConfig() });
|
|
21381
|
+
}
|
|
21382
|
+
async handleGetProviderSourceConfig(_req, res) {
|
|
21383
|
+
this.json(res, 200, { success: true, sourceConfig: this.providerLoader.getSourceConfig() });
|
|
21384
|
+
}
|
|
21385
|
+
async handleSetProviderSourceConfig(req, res) {
|
|
21386
|
+
const body = await this.readBody(req);
|
|
21387
|
+
const parsed = parseProviderSourceConfigUpdate(body || {});
|
|
21388
|
+
if (!parsed.ok) {
|
|
21389
|
+
this.json(res, 400, { success: false, error: parsed.error });
|
|
21390
|
+
return;
|
|
21391
|
+
}
|
|
21392
|
+
const currentConfig2 = loadConfig();
|
|
21393
|
+
const nextConfig = {
|
|
21394
|
+
...currentConfig2,
|
|
21395
|
+
...parsed.updates.providerSourceMode ? { providerSourceMode: parsed.updates.providerSourceMode } : {},
|
|
21396
|
+
...Object.prototype.hasOwnProperty.call(parsed.updates, "providerDir") ? { providerDir: parsed.updates.providerDir } : {}
|
|
21397
|
+
};
|
|
21398
|
+
saveConfig(nextConfig);
|
|
21399
|
+
const sourceConfig = this.providerLoader.applySourceConfig({
|
|
21400
|
+
sourceMode: nextConfig.providerSourceMode,
|
|
21401
|
+
userDir: Object.prototype.hasOwnProperty.call(parsed.updates, "providerDir") ? parsed.updates.providerDir : this.providerLoader.getSourceConfig().explicitProviderDir || void 0
|
|
21402
|
+
});
|
|
21403
|
+
this.providerLoader.reload();
|
|
21404
|
+
this.providerLoader.registerToDetector();
|
|
21405
|
+
await this.onProviderSourceConfigChanged?.();
|
|
21406
|
+
this.json(res, 200, { success: true, reloaded: true, sourceConfig });
|
|
20811
21407
|
}
|
|
20812
21408
|
async handleProviderConfig(type, _req, res) {
|
|
20813
21409
|
const provider = this.providerLoader.resolve(type);
|
|
@@ -20849,20 +21445,20 @@ var DevServer = class _DevServer {
|
|
|
20849
21445
|
child.stderr?.on("data", (d) => {
|
|
20850
21446
|
stderr += d.toString().slice(0, 2e3);
|
|
20851
21447
|
});
|
|
20852
|
-
await new Promise((
|
|
21448
|
+
await new Promise((resolve11) => {
|
|
20853
21449
|
const timer = setTimeout(() => {
|
|
20854
21450
|
child.kill();
|
|
20855
|
-
|
|
21451
|
+
resolve11();
|
|
20856
21452
|
}, 3e3);
|
|
20857
21453
|
child.on("exit", () => {
|
|
20858
21454
|
clearTimeout(timer);
|
|
20859
|
-
|
|
21455
|
+
resolve11();
|
|
20860
21456
|
});
|
|
20861
21457
|
child.stdout?.once("data", () => {
|
|
20862
21458
|
setTimeout(() => {
|
|
20863
21459
|
child.kill();
|
|
20864
21460
|
clearTimeout(timer);
|
|
20865
|
-
|
|
21461
|
+
resolve11();
|
|
20866
21462
|
}, 500);
|
|
20867
21463
|
});
|
|
20868
21464
|
});
|
|
@@ -21358,14 +21954,14 @@ var DevServer = class _DevServer {
|
|
|
21358
21954
|
child.stderr?.on("data", (d) => {
|
|
21359
21955
|
stderr += d.toString();
|
|
21360
21956
|
});
|
|
21361
|
-
await new Promise((
|
|
21957
|
+
await new Promise((resolve11) => {
|
|
21362
21958
|
const timer = setTimeout(() => {
|
|
21363
21959
|
child.kill();
|
|
21364
|
-
|
|
21960
|
+
resolve11();
|
|
21365
21961
|
}, timeout);
|
|
21366
21962
|
child.on("exit", () => {
|
|
21367
21963
|
clearTimeout(timer);
|
|
21368
|
-
|
|
21964
|
+
resolve11();
|
|
21369
21965
|
});
|
|
21370
21966
|
});
|
|
21371
21967
|
const elapsed = Date.now() - start;
|
|
@@ -21510,18 +22106,6 @@ var DevServer = class _DevServer {
|
|
|
21510
22106
|
if (!fs14.existsSync(providerJson)) {
|
|
21511
22107
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
21512
22108
|
}
|
|
21513
|
-
try {
|
|
21514
|
-
const providerData = JSON.parse(fs14.readFileSync(providerJson, "utf-8"));
|
|
21515
|
-
if (providerData.disableUpstream !== true) {
|
|
21516
|
-
providerData.disableUpstream = true;
|
|
21517
|
-
fs14.writeFileSync(providerJson, JSON.stringify(providerData, null, 2));
|
|
21518
|
-
}
|
|
21519
|
-
} catch (error) {
|
|
21520
|
-
return {
|
|
21521
|
-
dir: null,
|
|
21522
|
-
reason: `Failed to update provider.json in writable provider directory: ${error.message}`
|
|
21523
|
-
};
|
|
21524
|
-
}
|
|
21525
22109
|
return { dir: desiredDir };
|
|
21526
22110
|
}
|
|
21527
22111
|
async handleAutoImplement(type, req, res) {
|
|
@@ -21666,7 +22250,7 @@ var DevServer = class _DevServer {
|
|
|
21666
22250
|
lines.push("## Required Return Format");
|
|
21667
22251
|
lines.push("| Function | Return JSON |");
|
|
21668
22252
|
lines.push("|---|---|");
|
|
21669
|
-
lines.push("| readChat | `{ id, status, title, messages: [{role, content, index, kind?, meta?}], inputContent, activeModal }` \u2014 optional `kind`: standard, thought, tool, terminal;
|
|
22253
|
+
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 |");
|
|
21670
22254
|
lines.push("| sendMessage | `{ sent: false, needsTypeAndSend: true, selector }` |");
|
|
21671
22255
|
lines.push("| resolveAction | `{ resolved: true/false, clicked? }` |");
|
|
21672
22256
|
lines.push("| listSessions | `{ sessions: [{ id, title, active, index }] }` |");
|
|
@@ -22047,14 +22631,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
22047
22631
|
res.end(JSON.stringify(data, null, 2));
|
|
22048
22632
|
}
|
|
22049
22633
|
async readBody(req) {
|
|
22050
|
-
return new Promise((
|
|
22634
|
+
return new Promise((resolve11) => {
|
|
22051
22635
|
let body = "";
|
|
22052
22636
|
req.on("data", (chunk) => body += chunk);
|
|
22053
22637
|
req.on("end", () => {
|
|
22054
22638
|
try {
|
|
22055
|
-
|
|
22639
|
+
resolve11(JSON.parse(body));
|
|
22056
22640
|
} catch {
|
|
22057
|
-
|
|
22641
|
+
resolve11({});
|
|
22058
22642
|
}
|
|
22059
22643
|
});
|
|
22060
22644
|
});
|
|
@@ -22532,7 +23116,7 @@ async function waitForReady(endpoint, timeoutMs = STARTUP_TIMEOUT_MS) {
|
|
|
22532
23116
|
const deadline = Date.now() + timeoutMs;
|
|
22533
23117
|
while (Date.now() < deadline) {
|
|
22534
23118
|
if (await canConnect(endpoint)) return;
|
|
22535
|
-
await new Promise((
|
|
23119
|
+
await new Promise((resolve11) => setTimeout(resolve11, STARTUP_POLL_MS));
|
|
22536
23120
|
}
|
|
22537
23121
|
throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
|
|
22538
23122
|
}
|
|
@@ -22572,61 +23156,6 @@ async function listHostedCliRuntimes(endpoint) {
|
|
|
22572
23156
|
}
|
|
22573
23157
|
}
|
|
22574
23158
|
|
|
22575
|
-
// src/session-host/runtime-surface.ts
|
|
22576
|
-
var LIVE_LIFECYCLES = /* @__PURE__ */ new Set(["starting", "running", "stopping", "interrupted"]);
|
|
22577
|
-
function isSessionHostLiveRuntime(record) {
|
|
22578
|
-
const lifecycle = String(record?.lifecycle || "").trim();
|
|
22579
|
-
return LIVE_LIFECYCLES.has(lifecycle);
|
|
22580
|
-
}
|
|
22581
|
-
function getSessionHostRecoveryLabel(meta) {
|
|
22582
|
-
const recoveryState = typeof meta?.runtimeRecoveryState === "string" ? String(meta.runtimeRecoveryState).trim() : "";
|
|
22583
|
-
if (!recoveryState) return null;
|
|
22584
|
-
if (recoveryState === "auto_resumed") return "restored after restart";
|
|
22585
|
-
if (recoveryState === "resume_failed") return "restore failed";
|
|
22586
|
-
if (recoveryState === "host_restart_interrupted") return "host restart interrupted";
|
|
22587
|
-
if (recoveryState === "orphan_snapshot") return "snapshot recovered";
|
|
22588
|
-
return recoveryState.replace(/_/g, " ");
|
|
22589
|
-
}
|
|
22590
|
-
function isSessionHostRecoverySnapshot(record) {
|
|
22591
|
-
if (!record) return false;
|
|
22592
|
-
if (isSessionHostLiveRuntime(record)) return false;
|
|
22593
|
-
const lifecycle = String(record.lifecycle || "").trim();
|
|
22594
|
-
if (lifecycle && lifecycle !== "stopped" && lifecycle !== "failed") {
|
|
22595
|
-
return false;
|
|
22596
|
-
}
|
|
22597
|
-
const meta = record.meta || void 0;
|
|
22598
|
-
if (meta?.restoredFromStorage === true) return true;
|
|
22599
|
-
return getSessionHostRecoveryLabel(meta) !== null;
|
|
22600
|
-
}
|
|
22601
|
-
function getSessionHostSurfaceKind(record) {
|
|
22602
|
-
if (isSessionHostLiveRuntime(record)) return "live_runtime";
|
|
22603
|
-
if (isSessionHostRecoverySnapshot(record)) return "recovery_snapshot";
|
|
22604
|
-
return "inactive_record";
|
|
22605
|
-
}
|
|
22606
|
-
function partitionSessionHostRecords(records) {
|
|
22607
|
-
const liveRuntimes = [];
|
|
22608
|
-
const recoverySnapshots = [];
|
|
22609
|
-
const inactiveRecords = [];
|
|
22610
|
-
for (const record of records) {
|
|
22611
|
-
const kind = getSessionHostSurfaceKind(record);
|
|
22612
|
-
if (kind === "live_runtime") {
|
|
22613
|
-
liveRuntimes.push(record);
|
|
22614
|
-
} else if (kind === "recovery_snapshot") {
|
|
22615
|
-
recoverySnapshots.push(record);
|
|
22616
|
-
} else {
|
|
22617
|
-
inactiveRecords.push(record);
|
|
22618
|
-
}
|
|
22619
|
-
}
|
|
22620
|
-
return {
|
|
22621
|
-
liveRuntimes,
|
|
22622
|
-
recoverySnapshots,
|
|
22623
|
-
inactiveRecords
|
|
22624
|
-
};
|
|
22625
|
-
}
|
|
22626
|
-
function partitionSessionHostDiagnosticsSessions(records) {
|
|
22627
|
-
return partitionSessionHostRecords(records || []);
|
|
22628
|
-
}
|
|
22629
|
-
|
|
22630
23159
|
// src/session-host/startup-restore-policy.js
|
|
22631
23160
|
function shouldAutoRestoreHostedSessionsOnStartup(env = process.env) {
|
|
22632
23161
|
const raw = typeof env.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP === "string" ? env.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP.trim().toLowerCase() : "";
|
|
@@ -22763,10 +23292,10 @@ async function installExtension(ide, extension) {
|
|
|
22763
23292
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
22764
23293
|
const fs15 = await import("fs");
|
|
22765
23294
|
fs15.writeFileSync(vsixPath, buffer);
|
|
22766
|
-
return new Promise((
|
|
23295
|
+
return new Promise((resolve11) => {
|
|
22767
23296
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
22768
23297
|
(0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
|
|
22769
|
-
|
|
23298
|
+
resolve11({
|
|
22770
23299
|
extensionId: extension.id,
|
|
22771
23300
|
marketplaceId: extension.marketplaceId,
|
|
22772
23301
|
success: !error,
|
|
@@ -22779,11 +23308,11 @@ async function installExtension(ide, extension) {
|
|
|
22779
23308
|
} catch (e) {
|
|
22780
23309
|
}
|
|
22781
23310
|
}
|
|
22782
|
-
return new Promise((
|
|
23311
|
+
return new Promise((resolve11) => {
|
|
22783
23312
|
const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
|
|
22784
23313
|
(0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
|
|
22785
23314
|
if (error) {
|
|
22786
|
-
|
|
23315
|
+
resolve11({
|
|
22787
23316
|
extensionId: extension.id,
|
|
22788
23317
|
marketplaceId: extension.marketplaceId,
|
|
22789
23318
|
success: false,
|
|
@@ -22791,7 +23320,7 @@ async function installExtension(ide, extension) {
|
|
|
22791
23320
|
error: stderr || error.message
|
|
22792
23321
|
});
|
|
22793
23322
|
} else {
|
|
22794
|
-
|
|
23323
|
+
resolve11({
|
|
22795
23324
|
extensionId: extension.id,
|
|
22796
23325
|
marketplaceId: extension.marketplaceId,
|
|
22797
23326
|
success: true,
|
|
@@ -22888,10 +23417,11 @@ init_config();
|
|
|
22888
23417
|
async function initDaemonComponents(config) {
|
|
22889
23418
|
installGlobalInterceptor();
|
|
22890
23419
|
const appConfig = loadConfig();
|
|
22891
|
-
const
|
|
23420
|
+
const providerSourceMode = appConfig.providerSourceMode || "normal";
|
|
23421
|
+
const disableUpstream = providerSourceMode === "no-upstream";
|
|
22892
23422
|
const providerLoader = new ProviderLoader({
|
|
22893
23423
|
logFn: config.providerLogFn,
|
|
22894
|
-
|
|
23424
|
+
sourceMode: providerSourceMode,
|
|
22895
23425
|
userDir: appConfig.providerDir
|
|
22896
23426
|
});
|
|
22897
23427
|
if (!disableUpstream && !providerLoader.hasUpstream()) {
|
|
@@ -22996,6 +23526,10 @@ async function initDaemonComponents(config) {
|
|
|
22996
23526
|
onProviderSettingChanged: async (providerType) => {
|
|
22997
23527
|
await refreshProviderAvailability(providerType);
|
|
22998
23528
|
config.onStatusChange?.();
|
|
23529
|
+
},
|
|
23530
|
+
onProviderSourceConfigChanged: async () => {
|
|
23531
|
+
await refreshProviderAvailability();
|
|
23532
|
+
config.onStatusChange?.();
|
|
22999
23533
|
}
|
|
23000
23534
|
});
|
|
23001
23535
|
agentStreamManager = new DaemonAgentStreamManager(
|
|
@@ -23045,7 +23579,8 @@ async function initDaemonComponents(config) {
|
|
|
23045
23579
|
cdpInitializer,
|
|
23046
23580
|
cdpManagers,
|
|
23047
23581
|
sessionRegistry,
|
|
23048
|
-
detectedIdes: detectedIdesRef
|
|
23582
|
+
detectedIdes: detectedIdesRef,
|
|
23583
|
+
refreshProviderAvailability
|
|
23049
23584
|
};
|
|
23050
23585
|
}
|
|
23051
23586
|
async function startDaemonDevSupport(options) {
|
|
@@ -23054,7 +23589,10 @@ async function startDaemonDevSupport(options) {
|
|
|
23054
23589
|
cdpManagers: options.components.cdpManagers,
|
|
23055
23590
|
instanceManager: options.components.instanceManager,
|
|
23056
23591
|
cliManager: options.components.cliManager,
|
|
23057
|
-
logFn: options.logFn
|
|
23592
|
+
logFn: options.logFn,
|
|
23593
|
+
onProviderSourceConfigChanged: async () => {
|
|
23594
|
+
await options.components.refreshProviderAvailability();
|
|
23595
|
+
}
|
|
23058
23596
|
});
|
|
23059
23597
|
await devServer.start();
|
|
23060
23598
|
options.components.providerLoader.watch();
|
|
@@ -23181,6 +23719,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
23181
23719
|
normalizeInputEnvelope,
|
|
23182
23720
|
normalizeManagedStatus,
|
|
23183
23721
|
normalizeMessageParts,
|
|
23722
|
+
parseProviderSourceConfigUpdate,
|
|
23184
23723
|
partitionSessionHostDiagnosticsSessions,
|
|
23185
23724
|
partitionSessionHostRecords,
|
|
23186
23725
|
probeCdpPort,
|