@adhdev/daemon-core 0.7.33 → 0.7.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +29 -3
- package/dist/index.d.ts +29 -3
- package/dist/index.js +637 -253
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +637 -255
- package/dist/index.mjs.map +1 -1
- package/dist/{normalize-auJAPmKy.d.mts → normalize-DVI4Lo5I.d.mts} +63 -1
- package/dist/{normalize-auJAPmKy.d.ts → normalize-DVI4Lo5I.d.ts} +63 -1
- package/dist/status/normalize.d.mts +1 -1
- package/dist/status/normalize.d.ts +1 -1
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/agent-stream/manager.ts +14 -1
- package/src/agent-stream/provider-adapter.ts +45 -3
- package/src/agent-stream/types.ts +4 -0
- package/src/cli-adapters/terminal-screen.ts +15 -0
- package/src/commands/cli-manager.ts +35 -0
- package/src/commands/router.ts +44 -1
- package/src/commands/workspace-commands.ts +2 -1
- package/src/config/config.d.ts +4 -0
- package/src/config/config.ts +9 -1
- package/src/config/recent-activity.ts +83 -0
- package/src/config/workspaces.d.ts +3 -1
- package/src/config/workspaces.ts +15 -1
- package/src/index.ts +16 -0
- package/src/providers/acp-provider-instance.ts +5 -0
- package/src/providers/cli-provider-instance.ts +2 -0
- package/src/providers/contracts.ts +94 -0
- package/src/providers/extension-provider-instance.ts +4 -0
- package/src/providers/ide-provider-instance.ts +2 -0
- package/src/providers/provider-instance.ts +5 -1
- package/src/shared-types.d.ts +35 -0
- package/src/shared-types.ts +70 -0
- package/src/status/builders.ts +90 -1
- package/src/status/reporter.ts +8 -0
- package/src/status/snapshot.ts +162 -0
package/dist/index.mjs
CHANGED
|
@@ -162,8 +162,17 @@ function findWorkspaceByPath(config, rawPath) {
|
|
|
162
162
|
if (!abs) return void 0;
|
|
163
163
|
return (config.workspaces || []).find((w) => path.resolve(expandPath(w.path)) === abs);
|
|
164
164
|
}
|
|
165
|
-
function addWorkspaceEntry(config, rawPath, label) {
|
|
165
|
+
function addWorkspaceEntry(config, rawPath, label, options) {
|
|
166
166
|
const abs = expandPath(rawPath);
|
|
167
|
+
const createIfMissing = options?.createIfMissing === true;
|
|
168
|
+
if (!abs) return { error: "Path required" };
|
|
169
|
+
if (!fs.existsSync(abs) && createIfMissing) {
|
|
170
|
+
try {
|
|
171
|
+
fs.mkdirSync(abs, { recursive: true });
|
|
172
|
+
} catch (e) {
|
|
173
|
+
return { error: e?.message || "Could not create directory" };
|
|
174
|
+
}
|
|
175
|
+
}
|
|
167
176
|
const v = validateWorkspacePath(abs);
|
|
168
177
|
if (!v.ok) return { error: v.error };
|
|
169
178
|
const list = [...config.workspaces || []];
|
|
@@ -224,7 +233,7 @@ __export(config_exports, {
|
|
|
224
233
|
});
|
|
225
234
|
import { homedir as homedir2 } from "os";
|
|
226
235
|
import { join as join2 } from "path";
|
|
227
|
-
import { existsSync as existsSync2, mkdirSync, readFileSync, writeFileSync, chmodSync } from "fs";
|
|
236
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync, writeFileSync, chmodSync } from "fs";
|
|
228
237
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
229
238
|
function generateMachineId() {
|
|
230
239
|
return `${MACHINE_ID_PREFIX}${randomUUID2().replace(/-/g, "")}`;
|
|
@@ -249,7 +258,7 @@ function ensureMachineId(config) {
|
|
|
249
258
|
function getConfigDir() {
|
|
250
259
|
const dir = join2(homedir2(), ".adhdev");
|
|
251
260
|
if (!existsSync2(dir)) {
|
|
252
|
-
|
|
261
|
+
mkdirSync2(dir, { recursive: true });
|
|
253
262
|
}
|
|
254
263
|
return dir;
|
|
255
264
|
}
|
|
@@ -298,7 +307,7 @@ function saveConfig(config) {
|
|
|
298
307
|
const configPath = getConfigPath();
|
|
299
308
|
const dir = getConfigDir();
|
|
300
309
|
if (!existsSync2(dir)) {
|
|
301
|
-
|
|
310
|
+
mkdirSync2(dir, { recursive: true, mode: 448 });
|
|
302
311
|
}
|
|
303
312
|
writeFileSync(configPath, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
|
|
304
313
|
try {
|
|
@@ -389,6 +398,8 @@ var init_config = __esm({
|
|
|
389
398
|
workspaces: [],
|
|
390
399
|
defaultWorkspaceId: null,
|
|
391
400
|
recentWorkspaceActivity: [],
|
|
401
|
+
recentActivity: [],
|
|
402
|
+
recentSessionReads: {},
|
|
392
403
|
machineNickname: null,
|
|
393
404
|
machineId: void 0,
|
|
394
405
|
machineSecret: null,
|
|
@@ -404,7 +415,7 @@ var init_config = __esm({
|
|
|
404
415
|
|
|
405
416
|
// src/logging/logger.ts
|
|
406
417
|
import * as fs2 from "fs";
|
|
407
|
-
import * as
|
|
418
|
+
import * as path4 from "path";
|
|
408
419
|
import * as os4 from "os";
|
|
409
420
|
function setLogLevel(level) {
|
|
410
421
|
currentLevel = level;
|
|
@@ -420,7 +431,7 @@ function checkDateRotation() {
|
|
|
420
431
|
const today = getDateStr();
|
|
421
432
|
if (today !== currentDate) {
|
|
422
433
|
currentDate = today;
|
|
423
|
-
currentLogFile =
|
|
434
|
+
currentLogFile = path4.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
424
435
|
cleanOldLogs();
|
|
425
436
|
}
|
|
426
437
|
}
|
|
@@ -434,7 +445,7 @@ function cleanOldLogs() {
|
|
|
434
445
|
const dateMatch = file.match(/daemon-(\d{4}-\d{2}-\d{2})/);
|
|
435
446
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
436
447
|
try {
|
|
437
|
-
fs2.unlinkSync(
|
|
448
|
+
fs2.unlinkSync(path4.join(LOG_DIR, file));
|
|
438
449
|
} catch {
|
|
439
450
|
}
|
|
440
451
|
}
|
|
@@ -558,7 +569,7 @@ var init_logger = __esm({
|
|
|
558
569
|
LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
559
570
|
LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
|
|
560
571
|
currentLevel = "info";
|
|
561
|
-
LOG_DIR = process.platform === "win32" ?
|
|
572
|
+
LOG_DIR = process.platform === "win32" ? path4.join(process.env.LOCALAPPDATA || process.env.APPDATA || path4.join(os4.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path4.join(os4.homedir(), "Library", "Logs", "adhdev") : path4.join(os4.homedir(), ".local", "share", "adhdev", "logs");
|
|
562
573
|
MAX_LOG_SIZE = 5 * 1024 * 1024;
|
|
563
574
|
MAX_LOG_DAYS = 7;
|
|
564
575
|
try {
|
|
@@ -566,16 +577,16 @@ var init_logger = __esm({
|
|
|
566
577
|
} catch {
|
|
567
578
|
}
|
|
568
579
|
currentDate = getDateStr();
|
|
569
|
-
currentLogFile =
|
|
580
|
+
currentLogFile = path4.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
570
581
|
cleanOldLogs();
|
|
571
582
|
try {
|
|
572
|
-
const oldLog =
|
|
583
|
+
const oldLog = path4.join(LOG_DIR, "daemon.log");
|
|
573
584
|
if (fs2.existsSync(oldLog)) {
|
|
574
585
|
const stat = fs2.statSync(oldLog);
|
|
575
586
|
const oldDate = stat.mtime.toISOString().slice(0, 10);
|
|
576
|
-
fs2.renameSync(oldLog,
|
|
587
|
+
fs2.renameSync(oldLog, path4.join(LOG_DIR, `daemon-${oldDate}.log`));
|
|
577
588
|
}
|
|
578
|
-
const oldLogBackup =
|
|
589
|
+
const oldLogBackup = path4.join(LOG_DIR, "daemon.log.old");
|
|
579
590
|
if (fs2.existsSync(oldLogBackup)) {
|
|
580
591
|
fs2.unlinkSync(oldLogBackup);
|
|
581
592
|
}
|
|
@@ -607,7 +618,7 @@ var init_logger = __esm({
|
|
|
607
618
|
}
|
|
608
619
|
};
|
|
609
620
|
interceptorInstalled = false;
|
|
610
|
-
LOG_PATH =
|
|
621
|
+
LOG_PATH = path4.join(LOG_DIR, `daemon-${getDateStr()}.log`);
|
|
611
622
|
}
|
|
612
623
|
});
|
|
613
624
|
|
|
@@ -772,6 +783,12 @@ var init_xterm_backend = __esm({
|
|
|
772
783
|
});
|
|
773
784
|
|
|
774
785
|
// src/cli-adapters/terminal-screen.ts
|
|
786
|
+
function getTerminalBackendRuntimeStatus() {
|
|
787
|
+
const preference = resolveTerminalBackendPreference();
|
|
788
|
+
const ghosttyAvailable = isGhosttyVtBackendAvailable();
|
|
789
|
+
const backend = preference === "ghostty-vt" || preference === "auto" && ghosttyAvailable ? "ghostty-vt" : "xterm";
|
|
790
|
+
return { backend, preference, ghosttyAvailable };
|
|
791
|
+
}
|
|
775
792
|
function createTerminalBackend(options, preference) {
|
|
776
793
|
const ghosttyAvailable = isGhosttyVtBackendAvailable();
|
|
777
794
|
if (preference === "ghostty-vt") {
|
|
@@ -911,7 +928,7 @@ __export(provider_cli_adapter_exports, {
|
|
|
911
928
|
normalizeCliProviderForRuntime: () => normalizeCliProviderForRuntime
|
|
912
929
|
});
|
|
913
930
|
import * as os12 from "os";
|
|
914
|
-
import * as
|
|
931
|
+
import * as path10 from "path";
|
|
915
932
|
import { execSync as execSync4 } from "child_process";
|
|
916
933
|
function stripAnsi(str) {
|
|
917
934
|
return str.replace(/\x1B\[\d*[A-HJKSTfG]/g, " ").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "").replace(/\x1B\][^\x07]*\x07/g, "").replace(/\x1B\][^\x1B]*\x1B\\/g, "").replace(/ +/g, " ");
|
|
@@ -932,7 +949,7 @@ function findBinary(name) {
|
|
|
932
949
|
}
|
|
933
950
|
}
|
|
934
951
|
function isScriptBinary(binaryPath) {
|
|
935
|
-
if (!
|
|
952
|
+
if (!path10.isAbsolute(binaryPath)) return false;
|
|
936
953
|
try {
|
|
937
954
|
const fs12 = __require("fs");
|
|
938
955
|
const resolved = fs12.realpathSync(binaryPath);
|
|
@@ -948,7 +965,7 @@ function isScriptBinary(binaryPath) {
|
|
|
948
965
|
}
|
|
949
966
|
}
|
|
950
967
|
function looksLikeMachOOrElf(filePath) {
|
|
951
|
-
if (!
|
|
968
|
+
if (!path10.isAbsolute(filePath)) return false;
|
|
952
969
|
try {
|
|
953
970
|
const fs12 = __require("fs");
|
|
954
971
|
const resolved = fs12.realpathSync(filePath);
|
|
@@ -1074,9 +1091,9 @@ var init_provider_cli_adapter = __esm({
|
|
|
1074
1091
|
if (os12.platform() !== "win32") {
|
|
1075
1092
|
try {
|
|
1076
1093
|
const fs12 = __require("fs");
|
|
1077
|
-
const ptyDir =
|
|
1094
|
+
const ptyDir = path10.resolve(path10.dirname(__require.resolve("node-pty")), "..");
|
|
1078
1095
|
const platformArch = `${os12.platform()}-${os12.arch()}`;
|
|
1079
|
-
const helper =
|
|
1096
|
+
const helper = path10.join(ptyDir, "prebuilds", platformArch, "spawn-helper");
|
|
1080
1097
|
if (fs12.existsSync(helper)) {
|
|
1081
1098
|
const stat = fs12.statSync(helper);
|
|
1082
1099
|
if (!(stat.mode & 73)) {
|
|
@@ -1265,7 +1282,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
1265
1282
|
LOG.info("CLI", `[${this.cliType}] Spawning in ${this.workingDir}`);
|
|
1266
1283
|
let shellCmd;
|
|
1267
1284
|
let shellArgs;
|
|
1268
|
-
const useShellUnix = !isWin && (!!spawnConfig.shell || !
|
|
1285
|
+
const useShellUnix = !isWin && (!!spawnConfig.shell || !path10.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
|
|
1269
1286
|
const useShell = isWin ? !!spawnConfig.shell : useShellUnix;
|
|
1270
1287
|
if (useShell) {
|
|
1271
1288
|
if (!spawnConfig.shell && !isWin) {
|
|
@@ -1690,7 +1707,7 @@ ${data.message || ""}`.trim();
|
|
|
1690
1707
|
if (this.startupParseGate) {
|
|
1691
1708
|
const deadline = Date.now() + 1e4;
|
|
1692
1709
|
while (this.startupParseGate && Date.now() < deadline) {
|
|
1693
|
-
await new Promise((
|
|
1710
|
+
await new Promise((resolve10) => setTimeout(resolve10, 50));
|
|
1694
1711
|
}
|
|
1695
1712
|
}
|
|
1696
1713
|
if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
|
|
@@ -1858,17 +1875,17 @@ ${data.message || ""}`.trim();
|
|
|
1858
1875
|
}
|
|
1859
1876
|
}
|
|
1860
1877
|
waitForStopped(timeoutMs) {
|
|
1861
|
-
return new Promise((
|
|
1878
|
+
return new Promise((resolve10) => {
|
|
1862
1879
|
const startedAt = Date.now();
|
|
1863
1880
|
const timer = setInterval(() => {
|
|
1864
1881
|
if (!this.ptyProcess || this.currentStatus === "stopped") {
|
|
1865
1882
|
clearInterval(timer);
|
|
1866
|
-
|
|
1883
|
+
resolve10(true);
|
|
1867
1884
|
return;
|
|
1868
1885
|
}
|
|
1869
1886
|
if (Date.now() - startedAt >= timeoutMs) {
|
|
1870
1887
|
clearInterval(timer);
|
|
1871
|
-
|
|
1888
|
+
resolve10(false);
|
|
1872
1889
|
}
|
|
1873
1890
|
}, 100);
|
|
1874
1891
|
});
|
|
@@ -2102,6 +2119,52 @@ function removeActivityForPath(config, rawPath) {
|
|
|
2102
2119
|
};
|
|
2103
2120
|
}
|
|
2104
2121
|
|
|
2122
|
+
// src/config/recent-activity.ts
|
|
2123
|
+
init_workspaces();
|
|
2124
|
+
import * as path3 from "path";
|
|
2125
|
+
var MAX_ACTIVITY2 = 30;
|
|
2126
|
+
function normalizeWorkspace(workspace) {
|
|
2127
|
+
if (!workspace) return "";
|
|
2128
|
+
try {
|
|
2129
|
+
return path3.resolve(expandPath(workspace));
|
|
2130
|
+
} catch {
|
|
2131
|
+
return path3.resolve(workspace);
|
|
2132
|
+
}
|
|
2133
|
+
}
|
|
2134
|
+
function buildRecentActivityKey(entry) {
|
|
2135
|
+
return `${entry.kind}:${entry.providerType}:${normalizeWorkspace(entry.workspace)}`;
|
|
2136
|
+
}
|
|
2137
|
+
function appendRecentActivity(config, entry) {
|
|
2138
|
+
const nextEntry = {
|
|
2139
|
+
...entry,
|
|
2140
|
+
workspace: entry.workspace ? normalizeWorkspace(entry.workspace) : void 0,
|
|
2141
|
+
id: buildRecentActivityKey(entry),
|
|
2142
|
+
lastUsedAt: entry.lastUsedAt || Date.now()
|
|
2143
|
+
};
|
|
2144
|
+
const filtered = (config.recentActivity || []).filter((item) => item.id !== nextEntry.id);
|
|
2145
|
+
return {
|
|
2146
|
+
...config,
|
|
2147
|
+
recentActivity: [nextEntry, ...filtered].slice(0, MAX_ACTIVITY2)
|
|
2148
|
+
};
|
|
2149
|
+
}
|
|
2150
|
+
function getRecentActivity(config, limit = 20) {
|
|
2151
|
+
return [...config.recentActivity || []].sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, limit);
|
|
2152
|
+
}
|
|
2153
|
+
function getRecentSessionSeenAt(config, recentKey) {
|
|
2154
|
+
return config.recentSessionReads?.[recentKey] || 0;
|
|
2155
|
+
}
|
|
2156
|
+
function markRecentSessionSeen(config, recentKey, seenAt = Date.now()) {
|
|
2157
|
+
const prev = config.recentSessionReads || {};
|
|
2158
|
+
const nextSeenAt = Math.max(prev[recentKey] || 0, seenAt);
|
|
2159
|
+
return {
|
|
2160
|
+
...config,
|
|
2161
|
+
recentSessionReads: {
|
|
2162
|
+
...prev,
|
|
2163
|
+
[recentKey]: nextSeenAt
|
|
2164
|
+
}
|
|
2165
|
+
};
|
|
2166
|
+
}
|
|
2167
|
+
|
|
2105
2168
|
// src/detection/ide-detector.ts
|
|
2106
2169
|
import { execSync } from "child_process";
|
|
2107
2170
|
import { existsSync as existsSync3 } from "fs";
|
|
@@ -2209,15 +2272,15 @@ function parseVersion(raw) {
|
|
|
2209
2272
|
return match ? match[1] : raw.split("\n")[0].slice(0, 100);
|
|
2210
2273
|
}
|
|
2211
2274
|
function execAsync(cmd, timeoutMs = 5e3) {
|
|
2212
|
-
return new Promise((
|
|
2275
|
+
return new Promise((resolve10) => {
|
|
2213
2276
|
const child = exec(cmd, { encoding: "utf-8", timeout: timeoutMs }, (err, stdout) => {
|
|
2214
2277
|
if (err || !stdout?.trim()) {
|
|
2215
|
-
|
|
2278
|
+
resolve10(null);
|
|
2216
2279
|
} else {
|
|
2217
|
-
|
|
2280
|
+
resolve10(stdout.trim());
|
|
2218
2281
|
}
|
|
2219
2282
|
});
|
|
2220
|
-
child.on("error", () =>
|
|
2283
|
+
child.on("error", () => resolve10(null));
|
|
2221
2284
|
});
|
|
2222
2285
|
}
|
|
2223
2286
|
async function detectCLIs(providerLoader) {
|
|
@@ -2384,7 +2447,7 @@ var DaemonCdpManager = class {
|
|
|
2384
2447
|
* Returns multiple entries if multiple IDE windows are open on same port
|
|
2385
2448
|
*/
|
|
2386
2449
|
static listAllTargets(port) {
|
|
2387
|
-
return new Promise((
|
|
2450
|
+
return new Promise((resolve10) => {
|
|
2388
2451
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
2389
2452
|
let data = "";
|
|
2390
2453
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -2400,16 +2463,16 @@ var DaemonCdpManager = class {
|
|
|
2400
2463
|
(t) => !isNonMain(t.title || "") && t.url?.includes("workbench.html") && !t.url?.includes("agent")
|
|
2401
2464
|
);
|
|
2402
2465
|
const fallbackPages = pages.filter((t) => !isNonMain(t.title || ""));
|
|
2403
|
-
|
|
2466
|
+
resolve10(mainPages.length > 0 ? mainPages : fallbackPages);
|
|
2404
2467
|
} catch {
|
|
2405
|
-
|
|
2468
|
+
resolve10([]);
|
|
2406
2469
|
}
|
|
2407
2470
|
});
|
|
2408
2471
|
});
|
|
2409
|
-
req.on("error", () =>
|
|
2472
|
+
req.on("error", () => resolve10([]));
|
|
2410
2473
|
req.setTimeout(2e3, () => {
|
|
2411
2474
|
req.destroy();
|
|
2412
|
-
|
|
2475
|
+
resolve10([]);
|
|
2413
2476
|
});
|
|
2414
2477
|
});
|
|
2415
2478
|
}
|
|
@@ -2449,7 +2512,7 @@ var DaemonCdpManager = class {
|
|
|
2449
2512
|
}
|
|
2450
2513
|
}
|
|
2451
2514
|
findTargetOnPort(port) {
|
|
2452
|
-
return new Promise((
|
|
2515
|
+
return new Promise((resolve10) => {
|
|
2453
2516
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
2454
2517
|
let data = "";
|
|
2455
2518
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -2460,7 +2523,7 @@ var DaemonCdpManager = class {
|
|
|
2460
2523
|
(t) => (t.type === "page" || t.type === "browser" || t.type === "Page") && t.webSocketDebuggerUrl
|
|
2461
2524
|
);
|
|
2462
2525
|
if (pages.length === 0) {
|
|
2463
|
-
|
|
2526
|
+
resolve10(targets.find((t) => t.webSocketDebuggerUrl) || null);
|
|
2464
2527
|
return;
|
|
2465
2528
|
}
|
|
2466
2529
|
const mainPages = pages.filter((t) => !this.isNonMainTitle(t.title || ""));
|
|
@@ -2470,24 +2533,24 @@ var DaemonCdpManager = class {
|
|
|
2470
2533
|
const specific = list.find((t) => t.id === this._targetId);
|
|
2471
2534
|
if (specific) {
|
|
2472
2535
|
this._pageTitle = specific.title || "";
|
|
2473
|
-
|
|
2536
|
+
resolve10(specific);
|
|
2474
2537
|
} else {
|
|
2475
2538
|
this.log(`[CDP] Target ${this._targetId} not found in page list`);
|
|
2476
|
-
|
|
2539
|
+
resolve10(null);
|
|
2477
2540
|
}
|
|
2478
2541
|
return;
|
|
2479
2542
|
}
|
|
2480
2543
|
this._pageTitle = list[0]?.title || "";
|
|
2481
|
-
|
|
2544
|
+
resolve10(list[0]);
|
|
2482
2545
|
} catch {
|
|
2483
|
-
|
|
2546
|
+
resolve10(null);
|
|
2484
2547
|
}
|
|
2485
2548
|
});
|
|
2486
2549
|
});
|
|
2487
|
-
req.on("error", () =>
|
|
2550
|
+
req.on("error", () => resolve10(null));
|
|
2488
2551
|
req.setTimeout(2e3, () => {
|
|
2489
2552
|
req.destroy();
|
|
2490
|
-
|
|
2553
|
+
resolve10(null);
|
|
2491
2554
|
});
|
|
2492
2555
|
});
|
|
2493
2556
|
}
|
|
@@ -2498,7 +2561,7 @@ var DaemonCdpManager = class {
|
|
|
2498
2561
|
this.extensionProviders = providers;
|
|
2499
2562
|
}
|
|
2500
2563
|
connectToTarget(wsUrl) {
|
|
2501
|
-
return new Promise((
|
|
2564
|
+
return new Promise((resolve10) => {
|
|
2502
2565
|
this.ws = new WebSocket(wsUrl);
|
|
2503
2566
|
this.ws.on("open", async () => {
|
|
2504
2567
|
this._connected = true;
|
|
@@ -2508,17 +2571,17 @@ var DaemonCdpManager = class {
|
|
|
2508
2571
|
}
|
|
2509
2572
|
this.connectBrowserWs().catch(() => {
|
|
2510
2573
|
});
|
|
2511
|
-
|
|
2574
|
+
resolve10(true);
|
|
2512
2575
|
});
|
|
2513
2576
|
this.ws.on("message", (data) => {
|
|
2514
2577
|
try {
|
|
2515
2578
|
const msg = JSON.parse(data.toString());
|
|
2516
2579
|
if (msg.id && this.pending.has(msg.id)) {
|
|
2517
|
-
const { resolve:
|
|
2580
|
+
const { resolve: resolve11, reject } = this.pending.get(msg.id);
|
|
2518
2581
|
this.pending.delete(msg.id);
|
|
2519
2582
|
this.failureCount = 0;
|
|
2520
2583
|
if (msg.error) reject(new Error(msg.error.message));
|
|
2521
|
-
else
|
|
2584
|
+
else resolve11(msg.result);
|
|
2522
2585
|
} else if (msg.method === "Runtime.executionContextCreated") {
|
|
2523
2586
|
this.contexts.add(msg.params.context.id);
|
|
2524
2587
|
} else if (msg.method === "Runtime.executionContextDestroyed") {
|
|
@@ -2541,7 +2604,7 @@ var DaemonCdpManager = class {
|
|
|
2541
2604
|
this.ws.on("error", (err) => {
|
|
2542
2605
|
this.log(`[CDP] WebSocket error: ${err.message}`);
|
|
2543
2606
|
this._connected = false;
|
|
2544
|
-
|
|
2607
|
+
resolve10(false);
|
|
2545
2608
|
});
|
|
2546
2609
|
});
|
|
2547
2610
|
}
|
|
@@ -2555,7 +2618,7 @@ var DaemonCdpManager = class {
|
|
|
2555
2618
|
return;
|
|
2556
2619
|
}
|
|
2557
2620
|
this.log(`[CDP] Connecting browser WS for target discovery...`);
|
|
2558
|
-
await new Promise((
|
|
2621
|
+
await new Promise((resolve10, reject) => {
|
|
2559
2622
|
this.browserWs = new WebSocket(browserWsUrl);
|
|
2560
2623
|
this.browserWs.on("open", async () => {
|
|
2561
2624
|
this._browserConnected = true;
|
|
@@ -2565,16 +2628,16 @@ var DaemonCdpManager = class {
|
|
|
2565
2628
|
} catch (e) {
|
|
2566
2629
|
this.log(`[CDP] setDiscoverTargets failed: ${e.message}`);
|
|
2567
2630
|
}
|
|
2568
|
-
|
|
2631
|
+
resolve10();
|
|
2569
2632
|
});
|
|
2570
2633
|
this.browserWs.on("message", (data) => {
|
|
2571
2634
|
try {
|
|
2572
2635
|
const msg = JSON.parse(data.toString());
|
|
2573
2636
|
if (msg.id && this.browserPending.has(msg.id)) {
|
|
2574
|
-
const { resolve:
|
|
2637
|
+
const { resolve: resolve11, reject: reject2 } = this.browserPending.get(msg.id);
|
|
2575
2638
|
this.browserPending.delete(msg.id);
|
|
2576
2639
|
if (msg.error) reject2(new Error(msg.error.message));
|
|
2577
|
-
else
|
|
2640
|
+
else resolve11(msg.result);
|
|
2578
2641
|
}
|
|
2579
2642
|
} catch {
|
|
2580
2643
|
}
|
|
@@ -2594,31 +2657,31 @@ var DaemonCdpManager = class {
|
|
|
2594
2657
|
}
|
|
2595
2658
|
}
|
|
2596
2659
|
getBrowserWsUrl() {
|
|
2597
|
-
return new Promise((
|
|
2660
|
+
return new Promise((resolve10) => {
|
|
2598
2661
|
const req = http.get(`http://127.0.0.1:${this.port}/json/version`, (res) => {
|
|
2599
2662
|
let data = "";
|
|
2600
2663
|
res.on("data", (chunk) => data += chunk.toString());
|
|
2601
2664
|
res.on("end", () => {
|
|
2602
2665
|
try {
|
|
2603
2666
|
const info = JSON.parse(data);
|
|
2604
|
-
|
|
2667
|
+
resolve10(info.webSocketDebuggerUrl || null);
|
|
2605
2668
|
} catch {
|
|
2606
|
-
|
|
2669
|
+
resolve10(null);
|
|
2607
2670
|
}
|
|
2608
2671
|
});
|
|
2609
2672
|
});
|
|
2610
|
-
req.on("error", () =>
|
|
2673
|
+
req.on("error", () => resolve10(null));
|
|
2611
2674
|
req.setTimeout(3e3, () => {
|
|
2612
2675
|
req.destroy();
|
|
2613
|
-
|
|
2676
|
+
resolve10(null);
|
|
2614
2677
|
});
|
|
2615
2678
|
});
|
|
2616
2679
|
}
|
|
2617
2680
|
sendBrowser(method, params = {}, timeoutMs = 15e3) {
|
|
2618
|
-
return new Promise((
|
|
2681
|
+
return new Promise((resolve10, reject) => {
|
|
2619
2682
|
if (!this.browserWs || !this._browserConnected) return reject(new Error("Browser WS not connected"));
|
|
2620
2683
|
const id = this.browserMsgId++;
|
|
2621
|
-
this.browserPending.set(id, { resolve:
|
|
2684
|
+
this.browserPending.set(id, { resolve: resolve10, reject });
|
|
2622
2685
|
this.browserWs.send(JSON.stringify({ id, method, params }));
|
|
2623
2686
|
setTimeout(() => {
|
|
2624
2687
|
if (this.browserPending.has(id)) {
|
|
@@ -2658,11 +2721,11 @@ var DaemonCdpManager = class {
|
|
|
2658
2721
|
}
|
|
2659
2722
|
// ─── CDP Protocol ────────────────────────────────────────
|
|
2660
2723
|
sendInternal(method, params = {}, timeoutMs = 15e3) {
|
|
2661
|
-
return new Promise((
|
|
2724
|
+
return new Promise((resolve10, reject) => {
|
|
2662
2725
|
if (!this.ws || !this._connected) return reject(new Error("CDP not connected"));
|
|
2663
2726
|
if (this.ws.readyState !== WebSocket.OPEN) return reject(new Error("WebSocket not open"));
|
|
2664
2727
|
const id = this.msgId++;
|
|
2665
|
-
this.pending.set(id, { resolve:
|
|
2728
|
+
this.pending.set(id, { resolve: resolve10, reject });
|
|
2666
2729
|
this.ws.send(JSON.stringify({ id, method, params }));
|
|
2667
2730
|
setTimeout(() => {
|
|
2668
2731
|
if (this.pending.has(id)) {
|
|
@@ -2911,7 +2974,7 @@ var DaemonCdpManager = class {
|
|
|
2911
2974
|
const browserWs = this.browserWs;
|
|
2912
2975
|
let msgId = this.browserMsgId;
|
|
2913
2976
|
const sendWs = (method, params = {}, sessionId) => {
|
|
2914
|
-
return new Promise((
|
|
2977
|
+
return new Promise((resolve10, reject) => {
|
|
2915
2978
|
const mid = msgId++;
|
|
2916
2979
|
this.browserMsgId = msgId;
|
|
2917
2980
|
const handler = (raw) => {
|
|
@@ -2920,7 +2983,7 @@ var DaemonCdpManager = class {
|
|
|
2920
2983
|
if (msg.id === mid) {
|
|
2921
2984
|
browserWs.removeListener("message", handler);
|
|
2922
2985
|
if (msg.error) reject(new Error(msg.error.message || JSON.stringify(msg.error)));
|
|
2923
|
-
else
|
|
2986
|
+
else resolve10(msg.result);
|
|
2924
2987
|
}
|
|
2925
2988
|
} catch {
|
|
2926
2989
|
}
|
|
@@ -3111,14 +3174,14 @@ var DaemonCdpManager = class {
|
|
|
3111
3174
|
if (!ws || ws.readyState !== WebSocket.OPEN) {
|
|
3112
3175
|
throw new Error("CDP not connected");
|
|
3113
3176
|
}
|
|
3114
|
-
return new Promise((
|
|
3177
|
+
return new Promise((resolve10, reject) => {
|
|
3115
3178
|
const id = getNextId();
|
|
3116
3179
|
pendingMap.set(id, {
|
|
3117
3180
|
resolve: (result) => {
|
|
3118
3181
|
if (result?.result?.subtype === "error") {
|
|
3119
3182
|
reject(new Error(result.result.description));
|
|
3120
3183
|
} else {
|
|
3121
|
-
|
|
3184
|
+
resolve10(result?.result?.value);
|
|
3122
3185
|
}
|
|
3123
3186
|
},
|
|
3124
3187
|
reject
|
|
@@ -3150,10 +3213,10 @@ var DaemonCdpManager = class {
|
|
|
3150
3213
|
throw new Error("CDP not connected");
|
|
3151
3214
|
}
|
|
3152
3215
|
const sendViaSession = (method, params = {}) => {
|
|
3153
|
-
return new Promise((
|
|
3216
|
+
return new Promise((resolve10, reject) => {
|
|
3154
3217
|
const pendingMap = this._browserConnected ? this.browserPending : this.pending;
|
|
3155
3218
|
const id = this._browserConnected ? this.browserMsgId++ : this.msgId++;
|
|
3156
|
-
pendingMap.set(id, { resolve:
|
|
3219
|
+
pendingMap.set(id, { resolve: resolve10, reject });
|
|
3157
3220
|
ws.send(JSON.stringify({ id, sessionId, method, params }));
|
|
3158
3221
|
setTimeout(() => {
|
|
3159
3222
|
if (pendingMap.has(id)) {
|
|
@@ -3705,6 +3768,7 @@ var ExtensionProviderInstance = class {
|
|
|
3705
3768
|
activeModal = null;
|
|
3706
3769
|
currentModel = "";
|
|
3707
3770
|
currentMode = "";
|
|
3771
|
+
controlValues = {};
|
|
3708
3772
|
lastAgentStatus = "idle";
|
|
3709
3773
|
generatingStartedAt = 0;
|
|
3710
3774
|
monitor;
|
|
@@ -3750,6 +3814,8 @@ var ExtensionProviderInstance = class {
|
|
|
3750
3814
|
} : null,
|
|
3751
3815
|
currentModel: this.currentModel || void 0,
|
|
3752
3816
|
currentPlan: this.currentMode || void 0,
|
|
3817
|
+
controlValues: this.controlValues,
|
|
3818
|
+
providerControls: this.provider.controls,
|
|
3753
3819
|
agentStreams: this.agentStreams,
|
|
3754
3820
|
instanceId: this.instanceId,
|
|
3755
3821
|
lastUpdated: Date.now(),
|
|
@@ -3764,6 +3830,7 @@ var ExtensionProviderInstance = class {
|
|
|
3764
3830
|
if (data?.activeModal !== void 0) this.activeModal = data.activeModal;
|
|
3765
3831
|
if (data?.model) this.currentModel = data.model;
|
|
3766
3832
|
if (data?.mode) this.currentMode = data.mode;
|
|
3833
|
+
if (data?.controlValues) this.controlValues = data.controlValues;
|
|
3767
3834
|
if (typeof data?.sessionId === "string" && data.sessionId.trim()) this.chatId = data.sessionId;
|
|
3768
3835
|
if (typeof data?.title === "string" && data.title.trim()) this.chatTitle = data.title;
|
|
3769
3836
|
if (typeof data?.agentName === "string" && data.agentName.trim()) this.agentName = data.agentName;
|
|
@@ -3856,9 +3923,9 @@ var ExtensionProviderInstance = class {
|
|
|
3856
3923
|
|
|
3857
3924
|
// src/config/chat-history.ts
|
|
3858
3925
|
import * as fs3 from "fs";
|
|
3859
|
-
import * as
|
|
3926
|
+
import * as path5 from "path";
|
|
3860
3927
|
import * as os5 from "os";
|
|
3861
|
-
var HISTORY_DIR =
|
|
3928
|
+
var HISTORY_DIR = path5.join(os5.homedir(), ".adhdev", "history");
|
|
3862
3929
|
var RETAIN_DAYS = 30;
|
|
3863
3930
|
var ChatHistoryWriter = class {
|
|
3864
3931
|
/** Last seen message count per agent (deduplication) */
|
|
@@ -3901,11 +3968,11 @@ var ChatHistoryWriter = class {
|
|
|
3901
3968
|
});
|
|
3902
3969
|
}
|
|
3903
3970
|
if (newMessages.length === 0) return;
|
|
3904
|
-
const dir =
|
|
3971
|
+
const dir = path5.join(HISTORY_DIR, this.sanitize(agentType));
|
|
3905
3972
|
fs3.mkdirSync(dir, { recursive: true });
|
|
3906
3973
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
3907
3974
|
const filePrefix = instanceId ? `${this.sanitize(instanceId)}_` : "";
|
|
3908
|
-
const filePath =
|
|
3975
|
+
const filePath = path5.join(dir, `${filePrefix}${date}.jsonl`);
|
|
3909
3976
|
const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
3910
3977
|
fs3.appendFileSync(filePath, lines, "utf-8");
|
|
3911
3978
|
const prevCount = this.lastSeenCounts.get(dedupKey) || 0;
|
|
@@ -3949,11 +4016,11 @@ ${next}`;
|
|
|
3949
4016
|
this.lastSeenTerminal.set(dedupKey, next);
|
|
3950
4017
|
return;
|
|
3951
4018
|
}
|
|
3952
|
-
const dir =
|
|
4019
|
+
const dir = path5.join(HISTORY_DIR, this.sanitize(agentType));
|
|
3953
4020
|
fs3.mkdirSync(dir, { recursive: true });
|
|
3954
4021
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
3955
4022
|
const filePrefix = instanceId ? `${this.sanitize(instanceId)}_` : "";
|
|
3956
|
-
const filePath =
|
|
4023
|
+
const filePath = path5.join(dir, `${filePrefix}${date}.terminal.log`);
|
|
3957
4024
|
fs3.appendFileSync(filePath, delta, "utf-8");
|
|
3958
4025
|
this.lastSeenTerminal.set(dedupKey, next);
|
|
3959
4026
|
if (!this.rotated) {
|
|
@@ -3977,10 +4044,10 @@ ${next}`;
|
|
|
3977
4044
|
const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
|
|
3978
4045
|
const agentDirs = fs3.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
3979
4046
|
for (const dir of agentDirs) {
|
|
3980
|
-
const dirPath =
|
|
4047
|
+
const dirPath = path5.join(HISTORY_DIR, dir.name);
|
|
3981
4048
|
const files = fs3.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
|
|
3982
4049
|
for (const file of files) {
|
|
3983
|
-
const filePath =
|
|
4050
|
+
const filePath = path5.join(dirPath, file);
|
|
3984
4051
|
const stat = fs3.statSync(filePath);
|
|
3985
4052
|
if (stat.mtimeMs < cutoff) {
|
|
3986
4053
|
fs3.unlinkSync(filePath);
|
|
@@ -3998,7 +4065,7 @@ ${next}`;
|
|
|
3998
4065
|
function readChatHistory(agentType, offset = 0, limit = 30, instanceId) {
|
|
3999
4066
|
try {
|
|
4000
4067
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
4001
|
-
const dir =
|
|
4068
|
+
const dir = path5.join(HISTORY_DIR, sanitized);
|
|
4002
4069
|
if (!fs3.existsSync(dir)) return { messages: [], hasMore: false };
|
|
4003
4070
|
const sanitizedInstance = instanceId?.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
4004
4071
|
const files = fs3.readdirSync(dir).filter((f) => {
|
|
@@ -4012,7 +4079,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, instanceId) {
|
|
|
4012
4079
|
const needed = offset + limit + 1;
|
|
4013
4080
|
for (const file of files) {
|
|
4014
4081
|
if (allMessages.length >= needed) break;
|
|
4015
|
-
const filePath =
|
|
4082
|
+
const filePath = path5.join(dir, file);
|
|
4016
4083
|
const content = fs3.readFileSync(filePath, "utf-8");
|
|
4017
4084
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
4018
4085
|
for (let i = lines.length - 1; i >= 0; i--) {
|
|
@@ -4121,6 +4188,8 @@ var IdeProviderInstance = class {
|
|
|
4121
4188
|
currentModel: this.cachedChat?.model || void 0,
|
|
4122
4189
|
currentPlan: this.cachedChat?.mode || void 0,
|
|
4123
4190
|
currentAutoApprove: this.cachedChat?.autoApprove || void 0,
|
|
4191
|
+
controlValues: this.cachedChat?.controlValues || void 0,
|
|
4192
|
+
providerControls: this.provider.controls,
|
|
4124
4193
|
instanceId: this.instanceId,
|
|
4125
4194
|
lastUpdated: Date.now(),
|
|
4126
4195
|
settings: this.settings,
|
|
@@ -4855,6 +4924,50 @@ function isCdpConnected(cdpManagers, key) {
|
|
|
4855
4924
|
const m = findCdpManager(cdpManagers, key);
|
|
4856
4925
|
return m?.isConnected ?? false;
|
|
4857
4926
|
}
|
|
4927
|
+
function buildFallbackControls(providerControls, serverModel, serverMode, acpConfigOptions, acpModes) {
|
|
4928
|
+
if (providerControls && providerControls.length > 0) return providerControls;
|
|
4929
|
+
const controls = [];
|
|
4930
|
+
const isAcp = !!(acpConfigOptions || acpModes);
|
|
4931
|
+
const modelFromAcp = acpConfigOptions?.find((c) => c.category === "model");
|
|
4932
|
+
if (!isAcp || modelFromAcp) {
|
|
4933
|
+
controls.push({
|
|
4934
|
+
id: "model",
|
|
4935
|
+
type: "select",
|
|
4936
|
+
label: "Model",
|
|
4937
|
+
icon: "\u{1F916}",
|
|
4938
|
+
placement: "bar",
|
|
4939
|
+
dynamic: !modelFromAcp,
|
|
4940
|
+
listScript: "listModels",
|
|
4941
|
+
setScript: "setModel",
|
|
4942
|
+
readFrom: "model",
|
|
4943
|
+
...modelFromAcp && {
|
|
4944
|
+
options: modelFromAcp.options.map((o) => ({ value: o.value, label: o.name || o.value }))
|
|
4945
|
+
}
|
|
4946
|
+
});
|
|
4947
|
+
}
|
|
4948
|
+
const modeFromAcp = acpModes && acpModes.length > 0;
|
|
4949
|
+
const thoughtFromAcp = !modeFromAcp && acpConfigOptions?.find((c) => c.category !== "model");
|
|
4950
|
+
if (!isAcp || modeFromAcp || thoughtFromAcp) {
|
|
4951
|
+
controls.push({
|
|
4952
|
+
id: "mode",
|
|
4953
|
+
type: thoughtFromAcp ? "cycle" : "select",
|
|
4954
|
+
label: thoughtFromAcp ? "Thinking" : "Mode",
|
|
4955
|
+
icon: thoughtFromAcp ? "\u{1F9E0}" : "\u26A1",
|
|
4956
|
+
placement: "bar",
|
|
4957
|
+
dynamic: !modeFromAcp && !thoughtFromAcp,
|
|
4958
|
+
listScript: "listModes",
|
|
4959
|
+
setScript: thoughtFromAcp ? "setThinkingLevel" : "setMode",
|
|
4960
|
+
readFrom: "mode",
|
|
4961
|
+
...modeFromAcp && {
|
|
4962
|
+
options: acpModes.map((m) => ({ value: m.id, label: m.name || m.id }))
|
|
4963
|
+
},
|
|
4964
|
+
...thoughtFromAcp && {
|
|
4965
|
+
options: thoughtFromAcp.options.map((o) => ({ value: o.value, label: o.name || o.value }))
|
|
4966
|
+
}
|
|
4967
|
+
});
|
|
4968
|
+
}
|
|
4969
|
+
return controls;
|
|
4970
|
+
}
|
|
4858
4971
|
var IDE_SESSION_CAPABILITIES = [
|
|
4859
4972
|
"read_chat",
|
|
4860
4973
|
"send_message",
|
|
@@ -4913,8 +5026,15 @@ function buildIdeWorkspaceSession(state, cdpManagers) {
|
|
|
4913
5026
|
currentModel: state.currentModel,
|
|
4914
5027
|
currentPlan: state.currentPlan,
|
|
4915
5028
|
currentAutoApprove: state.currentAutoApprove,
|
|
5029
|
+
controlValues: state.controlValues,
|
|
5030
|
+
providerControls: buildFallbackControls(
|
|
5031
|
+
state.providerControls,
|
|
5032
|
+
state.currentModel,
|
|
5033
|
+
state.currentPlan
|
|
5034
|
+
),
|
|
4916
5035
|
errorMessage: state.errorMessage,
|
|
4917
|
-
errorReason: state.errorReason
|
|
5036
|
+
errorReason: state.errorReason,
|
|
5037
|
+
lastUpdated: state.lastUpdated
|
|
4918
5038
|
};
|
|
4919
5039
|
}
|
|
4920
5040
|
function buildExtensionAgentSession(parent, ext) {
|
|
@@ -4935,8 +5055,15 @@ function buildExtensionAgentSession(parent, ext) {
|
|
|
4935
5055
|
capabilities: EXTENSION_SESSION_CAPABILITIES,
|
|
4936
5056
|
currentModel: ext.currentModel,
|
|
4937
5057
|
currentPlan: ext.currentPlan,
|
|
5058
|
+
controlValues: ext.controlValues,
|
|
5059
|
+
providerControls: buildFallbackControls(
|
|
5060
|
+
ext.providerControls,
|
|
5061
|
+
ext.currentModel,
|
|
5062
|
+
ext.currentPlan
|
|
5063
|
+
),
|
|
4938
5064
|
errorMessage: ext.errorMessage,
|
|
4939
|
-
errorReason: ext.errorReason
|
|
5065
|
+
errorReason: ext.errorReason,
|
|
5066
|
+
lastUpdated: ext.lastUpdated
|
|
4940
5067
|
};
|
|
4941
5068
|
}
|
|
4942
5069
|
function buildCliSession(state) {
|
|
@@ -4961,8 +5088,13 @@ function buildCliSession(state) {
|
|
|
4961
5088
|
resume: state.resume,
|
|
4962
5089
|
activeChat,
|
|
4963
5090
|
capabilities: PTY_SESSION_CAPABILITIES,
|
|
5091
|
+
controlValues: state.controlValues,
|
|
5092
|
+
providerControls: buildFallbackControls(
|
|
5093
|
+
state.providerControls
|
|
5094
|
+
),
|
|
4964
5095
|
errorMessage: state.errorMessage,
|
|
4965
|
-
errorReason: state.errorReason
|
|
5096
|
+
errorReason: state.errorReason,
|
|
5097
|
+
lastUpdated: state.lastUpdated
|
|
4966
5098
|
};
|
|
4967
5099
|
}
|
|
4968
5100
|
function buildAcpSession(state) {
|
|
@@ -4985,8 +5117,17 @@ function buildAcpSession(state) {
|
|
|
4985
5117
|
currentPlan: state.currentPlan,
|
|
4986
5118
|
acpConfigOptions: state.acpConfigOptions,
|
|
4987
5119
|
acpModes: state.acpModes,
|
|
5120
|
+
controlValues: state.controlValues,
|
|
5121
|
+
providerControls: buildFallbackControls(
|
|
5122
|
+
state.providerControls,
|
|
5123
|
+
state.currentModel,
|
|
5124
|
+
state.currentPlan,
|
|
5125
|
+
state.acpConfigOptions,
|
|
5126
|
+
state.acpModes
|
|
5127
|
+
),
|
|
4988
5128
|
errorMessage: state.errorMessage,
|
|
4989
|
-
errorReason: state.errorReason
|
|
5129
|
+
errorReason: state.errorReason,
|
|
5130
|
+
lastUpdated: state.lastUpdated
|
|
4990
5131
|
};
|
|
4991
5132
|
}
|
|
4992
5133
|
function buildSessionEntries(allStates, cdpManagers) {
|
|
@@ -5835,7 +5976,7 @@ async function handleResolveAction(h, args) {
|
|
|
5835
5976
|
|
|
5836
5977
|
// src/commands/cdp-commands.ts
|
|
5837
5978
|
import * as fs4 from "fs";
|
|
5838
|
-
import * as
|
|
5979
|
+
import * as path6 from "path";
|
|
5839
5980
|
import * as os6 from "os";
|
|
5840
5981
|
var KEY_TO_VK = {
|
|
5841
5982
|
Backspace: 8,
|
|
@@ -6066,11 +6207,11 @@ function resolveSafePath(requestedPath) {
|
|
|
6066
6207
|
const home = os6.homedir();
|
|
6067
6208
|
let resolved;
|
|
6068
6209
|
if (requestedPath.startsWith("~")) {
|
|
6069
|
-
resolved =
|
|
6070
|
-
} else if (
|
|
6210
|
+
resolved = path6.join(home, requestedPath.slice(1));
|
|
6211
|
+
} else if (path6.isAbsolute(requestedPath)) {
|
|
6071
6212
|
resolved = requestedPath;
|
|
6072
6213
|
} else {
|
|
6073
|
-
resolved =
|
|
6214
|
+
resolved = path6.resolve(requestedPath);
|
|
6074
6215
|
}
|
|
6075
6216
|
return resolved;
|
|
6076
6217
|
}
|
|
@@ -6086,7 +6227,7 @@ async function handleFileRead(h, args) {
|
|
|
6086
6227
|
async function handleFileWrite(h, args) {
|
|
6087
6228
|
try {
|
|
6088
6229
|
const filePath = resolveSafePath(args?.path);
|
|
6089
|
-
fs4.mkdirSync(
|
|
6230
|
+
fs4.mkdirSync(path6.dirname(filePath), { recursive: true });
|
|
6090
6231
|
fs4.writeFileSync(filePath, args?.content || "", "utf-8");
|
|
6091
6232
|
return { success: true, path: filePath };
|
|
6092
6233
|
} catch (e) {
|
|
@@ -6100,7 +6241,7 @@ async function handleFileList(h, args) {
|
|
|
6100
6241
|
const files = entries.map((e) => ({
|
|
6101
6242
|
name: e.name,
|
|
6102
6243
|
type: e.isDirectory() ? "directory" : "file",
|
|
6103
|
-
size: e.isFile() ? fs4.statSync(
|
|
6244
|
+
size: e.isFile() ? fs4.statSync(path6.join(dirPath, e.name)).size : void 0
|
|
6104
6245
|
}));
|
|
6105
6246
|
return { success: true, files, path: dirPath };
|
|
6106
6247
|
} catch (e) {
|
|
@@ -6322,9 +6463,10 @@ function handleWorkspaceList() {
|
|
|
6322
6463
|
function handleWorkspaceAdd(args) {
|
|
6323
6464
|
const rawPath = (args?.path || args?.dir || "").trim();
|
|
6324
6465
|
const label = (args?.label || "").trim() || void 0;
|
|
6466
|
+
const createIfMissing = args?.createIfMissing === true;
|
|
6325
6467
|
if (!rawPath) return { success: false, error: "path required" };
|
|
6326
6468
|
const config = loadConfig();
|
|
6327
|
-
const result = addWorkspaceEntry(config, rawPath, label);
|
|
6469
|
+
const result = addWorkspaceEntry(config, rawPath, label, { createIfMissing });
|
|
6328
6470
|
if ("error" in result) return { success: false, error: result.error };
|
|
6329
6471
|
let cfg = appendWorkspaceActivity(result.config, result.entry.path, {});
|
|
6330
6472
|
saveConfig(cfg);
|
|
@@ -6818,7 +6960,7 @@ var DaemonCommandHandler = class {
|
|
|
6818
6960
|
try {
|
|
6819
6961
|
const http3 = await import("http");
|
|
6820
6962
|
const postData = JSON.stringify(body);
|
|
6821
|
-
const result = await new Promise((
|
|
6963
|
+
const result = await new Promise((resolve10, reject) => {
|
|
6822
6964
|
const req = http3.request({
|
|
6823
6965
|
hostname: "127.0.0.1",
|
|
6824
6966
|
port: 19280,
|
|
@@ -6830,9 +6972,9 @@ var DaemonCommandHandler = class {
|
|
|
6830
6972
|
res.on("data", (chunk) => data += chunk);
|
|
6831
6973
|
res.on("end", () => {
|
|
6832
6974
|
try {
|
|
6833
|
-
|
|
6975
|
+
resolve10(JSON.parse(data));
|
|
6834
6976
|
} catch {
|
|
6835
|
-
|
|
6977
|
+
resolve10({ raw: data });
|
|
6836
6978
|
}
|
|
6837
6979
|
});
|
|
6838
6980
|
});
|
|
@@ -6850,15 +6992,15 @@ var DaemonCommandHandler = class {
|
|
|
6850
6992
|
if (!providerType) return { success: false, error: "providerType required" };
|
|
6851
6993
|
try {
|
|
6852
6994
|
const http3 = await import("http");
|
|
6853
|
-
const result = await new Promise((
|
|
6995
|
+
const result = await new Promise((resolve10, reject) => {
|
|
6854
6996
|
http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
|
|
6855
6997
|
let data = "";
|
|
6856
6998
|
res.on("data", (chunk) => data += chunk);
|
|
6857
6999
|
res.on("end", () => {
|
|
6858
7000
|
try {
|
|
6859
|
-
|
|
7001
|
+
resolve10(JSON.parse(data));
|
|
6860
7002
|
} catch {
|
|
6861
|
-
|
|
7003
|
+
resolve10({ raw: data });
|
|
6862
7004
|
}
|
|
6863
7005
|
});
|
|
6864
7006
|
}).on("error", reject);
|
|
@@ -6872,7 +7014,7 @@ var DaemonCommandHandler = class {
|
|
|
6872
7014
|
try {
|
|
6873
7015
|
const http3 = await import("http");
|
|
6874
7016
|
const postData = JSON.stringify(args || {});
|
|
6875
|
-
const result = await new Promise((
|
|
7017
|
+
const result = await new Promise((resolve10, reject) => {
|
|
6876
7018
|
const req = http3.request({
|
|
6877
7019
|
hostname: "127.0.0.1",
|
|
6878
7020
|
port: 19280,
|
|
@@ -6884,9 +7026,9 @@ var DaemonCommandHandler = class {
|
|
|
6884
7026
|
res.on("data", (chunk) => data += chunk);
|
|
6885
7027
|
res.on("end", () => {
|
|
6886
7028
|
try {
|
|
6887
|
-
|
|
7029
|
+
resolve10(JSON.parse(data));
|
|
6888
7030
|
} catch {
|
|
6889
|
-
|
|
7031
|
+
resolve10({ raw: data });
|
|
6890
7032
|
}
|
|
6891
7033
|
});
|
|
6892
7034
|
});
|
|
@@ -6905,11 +7047,11 @@ var DaemonCommandHandler = class {
|
|
|
6905
7047
|
import { execSync as execSync3, spawn } from "child_process";
|
|
6906
7048
|
import * as net from "net";
|
|
6907
7049
|
import * as os8 from "os";
|
|
6908
|
-
import * as
|
|
7050
|
+
import * as path8 from "path";
|
|
6909
7051
|
|
|
6910
7052
|
// src/providers/provider-loader.ts
|
|
6911
7053
|
import * as fs5 from "fs";
|
|
6912
|
-
import * as
|
|
7054
|
+
import * as path7 from "path";
|
|
6913
7055
|
import * as os7 from "os";
|
|
6914
7056
|
import * as chokidar from "chokidar";
|
|
6915
7057
|
init_logger();
|
|
@@ -6930,12 +7072,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
6930
7072
|
static META_FILE = ".meta.json";
|
|
6931
7073
|
constructor(options) {
|
|
6932
7074
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
6933
|
-
const defaultProvidersDir =
|
|
7075
|
+
const defaultProvidersDir = path7.join(os7.homedir(), ".adhdev", "providers");
|
|
6934
7076
|
if (options?.userDir) {
|
|
6935
7077
|
this.userDir = options.userDir;
|
|
6936
7078
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
6937
7079
|
} else {
|
|
6938
|
-
const localRepoPath =
|
|
7080
|
+
const localRepoPath = path7.resolve(__dirname, "../../../../../adhdev-providers");
|
|
6939
7081
|
if (fs5.existsSync(localRepoPath)) {
|
|
6940
7082
|
this.userDir = localRepoPath;
|
|
6941
7083
|
this.log(`Auto-detected local public repository: ${this.userDir} (Dev workspace speedup)`);
|
|
@@ -6944,7 +7086,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
6944
7086
|
this.log(`Using default user providers directory: ${this.userDir}`);
|
|
6945
7087
|
}
|
|
6946
7088
|
}
|
|
6947
|
-
this.upstreamDir =
|
|
7089
|
+
this.upstreamDir = path7.join(defaultProvidersDir, ".upstream");
|
|
6948
7090
|
this.disableUpstream = options?.disableUpstream ?? false;
|
|
6949
7091
|
}
|
|
6950
7092
|
log(msg) {
|
|
@@ -6974,7 +7116,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
6974
7116
|
* Canonical provider directory shape for a given root.
|
|
6975
7117
|
*/
|
|
6976
7118
|
getProviderDir(root, category, type) {
|
|
6977
|
-
return
|
|
7119
|
+
return path7.join(root, category, type);
|
|
6978
7120
|
}
|
|
6979
7121
|
/**
|
|
6980
7122
|
* Canonical user override directory for a provider.
|
|
@@ -7001,7 +7143,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7001
7143
|
resolveProviderFile(type, ...segments) {
|
|
7002
7144
|
const dir = this.findProviderDirInternal(type);
|
|
7003
7145
|
if (!dir) return null;
|
|
7004
|
-
return
|
|
7146
|
+
return path7.join(dir, ...segments);
|
|
7005
7147
|
}
|
|
7006
7148
|
/**
|
|
7007
7149
|
* Load all providers (3-tier priority)
|
|
@@ -7039,7 +7181,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7039
7181
|
if (!fs5.existsSync(this.upstreamDir)) return false;
|
|
7040
7182
|
try {
|
|
7041
7183
|
return fs5.readdirSync(this.upstreamDir).some(
|
|
7042
|
-
(d) => fs5.statSync(
|
|
7184
|
+
(d) => fs5.statSync(path7.join(this.upstreamDir, d)).isDirectory()
|
|
7043
7185
|
);
|
|
7044
7186
|
} catch {
|
|
7045
7187
|
return false;
|
|
@@ -7331,14 +7473,14 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7331
7473
|
this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
|
|
7332
7474
|
return null;
|
|
7333
7475
|
}
|
|
7334
|
-
const dir =
|
|
7476
|
+
const dir = path7.join(providerDir, scriptDir);
|
|
7335
7477
|
if (!fs5.existsSync(dir)) {
|
|
7336
7478
|
this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
7337
7479
|
return null;
|
|
7338
7480
|
}
|
|
7339
7481
|
const cached = this.scriptsCache.get(dir);
|
|
7340
7482
|
if (cached) return cached;
|
|
7341
|
-
const scriptsJs =
|
|
7483
|
+
const scriptsJs = path7.join(dir, "scripts.js");
|
|
7342
7484
|
if (fs5.existsSync(scriptsJs)) {
|
|
7343
7485
|
try {
|
|
7344
7486
|
delete __require.cache[__require.resolve(scriptsJs)];
|
|
@@ -7377,7 +7519,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7377
7519
|
});
|
|
7378
7520
|
const handleChange = (filePath) => {
|
|
7379
7521
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
7380
|
-
this.log(`File changed: ${
|
|
7522
|
+
this.log(`File changed: ${path7.basename(filePath)}, reloading...`);
|
|
7381
7523
|
this.reload();
|
|
7382
7524
|
}
|
|
7383
7525
|
};
|
|
@@ -7432,7 +7574,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7432
7574
|
}
|
|
7433
7575
|
const https = __require("https");
|
|
7434
7576
|
const { execSync: execSync7 } = __require("child_process");
|
|
7435
|
-
const metaPath =
|
|
7577
|
+
const metaPath = path7.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
7436
7578
|
let prevEtag = "";
|
|
7437
7579
|
let prevTimestamp = 0;
|
|
7438
7580
|
try {
|
|
@@ -7449,7 +7591,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7449
7591
|
return { updated: false };
|
|
7450
7592
|
}
|
|
7451
7593
|
try {
|
|
7452
|
-
const etag = await new Promise((
|
|
7594
|
+
const etag = await new Promise((resolve10, reject) => {
|
|
7453
7595
|
const options = {
|
|
7454
7596
|
method: "HEAD",
|
|
7455
7597
|
hostname: "github.com",
|
|
@@ -7467,7 +7609,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7467
7609
|
headers: { "User-Agent": "adhdev-launcher" },
|
|
7468
7610
|
timeout: 1e4
|
|
7469
7611
|
}, (res2) => {
|
|
7470
|
-
|
|
7612
|
+
resolve10(res2.headers.etag || res2.headers["last-modified"] || "");
|
|
7471
7613
|
});
|
|
7472
7614
|
req2.on("error", reject);
|
|
7473
7615
|
req2.on("timeout", () => {
|
|
@@ -7476,7 +7618,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7476
7618
|
});
|
|
7477
7619
|
req2.end();
|
|
7478
7620
|
} else {
|
|
7479
|
-
|
|
7621
|
+
resolve10(res.headers.etag || res.headers["last-modified"] || "");
|
|
7480
7622
|
}
|
|
7481
7623
|
});
|
|
7482
7624
|
req.on("error", reject);
|
|
@@ -7492,17 +7634,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7492
7634
|
return { updated: false };
|
|
7493
7635
|
}
|
|
7494
7636
|
this.log("Downloading latest providers from GitHub...");
|
|
7495
|
-
const tmpTar =
|
|
7496
|
-
const tmpExtract =
|
|
7637
|
+
const tmpTar = path7.join(os7.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
7638
|
+
const tmpExtract = path7.join(os7.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
7497
7639
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
7498
7640
|
fs5.mkdirSync(tmpExtract, { recursive: true });
|
|
7499
7641
|
execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
7500
7642
|
const extracted = fs5.readdirSync(tmpExtract);
|
|
7501
7643
|
const rootDir = extracted.find(
|
|
7502
|
-
(d) => fs5.statSync(
|
|
7644
|
+
(d) => fs5.statSync(path7.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
7503
7645
|
);
|
|
7504
7646
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
7505
|
-
const sourceDir =
|
|
7647
|
+
const sourceDir = path7.join(tmpExtract, rootDir);
|
|
7506
7648
|
const backupDir = this.upstreamDir + ".bak";
|
|
7507
7649
|
if (fs5.existsSync(this.upstreamDir)) {
|
|
7508
7650
|
if (fs5.existsSync(backupDir)) fs5.rmSync(backupDir, { recursive: true, force: true });
|
|
@@ -7540,7 +7682,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7540
7682
|
downloadFile(url, destPath) {
|
|
7541
7683
|
const https = __require("https");
|
|
7542
7684
|
const http3 = __require("http");
|
|
7543
|
-
return new Promise((
|
|
7685
|
+
return new Promise((resolve10, reject) => {
|
|
7544
7686
|
const doRequest = (reqUrl, redirectCount = 0) => {
|
|
7545
7687
|
if (redirectCount > 5) {
|
|
7546
7688
|
reject(new Error("Too many redirects"));
|
|
@@ -7560,7 +7702,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7560
7702
|
res.pipe(ws);
|
|
7561
7703
|
ws.on("finish", () => {
|
|
7562
7704
|
ws.close();
|
|
7563
|
-
|
|
7705
|
+
resolve10();
|
|
7564
7706
|
});
|
|
7565
7707
|
ws.on("error", reject);
|
|
7566
7708
|
});
|
|
@@ -7577,8 +7719,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7577
7719
|
copyDirRecursive(src, dest) {
|
|
7578
7720
|
fs5.mkdirSync(dest, { recursive: true });
|
|
7579
7721
|
for (const entry of fs5.readdirSync(src, { withFileTypes: true })) {
|
|
7580
|
-
const srcPath =
|
|
7581
|
-
const destPath =
|
|
7722
|
+
const srcPath = path7.join(src, entry.name);
|
|
7723
|
+
const destPath = path7.join(dest, entry.name);
|
|
7582
7724
|
if (entry.isDirectory()) {
|
|
7583
7725
|
this.copyDirRecursive(srcPath, destPath);
|
|
7584
7726
|
} else {
|
|
@@ -7589,7 +7731,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7589
7731
|
/** .meta.json save */
|
|
7590
7732
|
writeMeta(metaPath, etag, timestamp) {
|
|
7591
7733
|
try {
|
|
7592
|
-
fs5.mkdirSync(
|
|
7734
|
+
fs5.mkdirSync(path7.dirname(metaPath), { recursive: true });
|
|
7593
7735
|
fs5.writeFileSync(metaPath, JSON.stringify({
|
|
7594
7736
|
etag,
|
|
7595
7737
|
timestamp,
|
|
@@ -7606,7 +7748,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7606
7748
|
const scan = (d) => {
|
|
7607
7749
|
try {
|
|
7608
7750
|
for (const entry of fs5.readdirSync(d, { withFileTypes: true })) {
|
|
7609
|
-
if (entry.isDirectory()) scan(
|
|
7751
|
+
if (entry.isDirectory()) scan(path7.join(d, entry.name));
|
|
7610
7752
|
else if (entry.name === "provider.json") count++;
|
|
7611
7753
|
}
|
|
7612
7754
|
} catch {
|
|
@@ -7705,17 +7847,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7705
7847
|
for (const root of searchRoots) {
|
|
7706
7848
|
if (!fs5.existsSync(root)) continue;
|
|
7707
7849
|
const candidate = this.getProviderDir(root, cat, type);
|
|
7708
|
-
if (fs5.existsSync(
|
|
7709
|
-
const catDir =
|
|
7850
|
+
if (fs5.existsSync(path7.join(candidate, "provider.json"))) return candidate;
|
|
7851
|
+
const catDir = path7.join(root, cat);
|
|
7710
7852
|
if (fs5.existsSync(catDir)) {
|
|
7711
7853
|
try {
|
|
7712
7854
|
for (const entry of fs5.readdirSync(catDir, { withFileTypes: true })) {
|
|
7713
7855
|
if (!entry.isDirectory()) continue;
|
|
7714
|
-
const jsonPath =
|
|
7856
|
+
const jsonPath = path7.join(catDir, entry.name, "provider.json");
|
|
7715
7857
|
if (fs5.existsSync(jsonPath)) {
|
|
7716
7858
|
try {
|
|
7717
7859
|
const data = JSON.parse(fs5.readFileSync(jsonPath, "utf-8"));
|
|
7718
|
-
if (data.type === type) return
|
|
7860
|
+
if (data.type === type) return path7.join(catDir, entry.name);
|
|
7719
7861
|
} catch {
|
|
7720
7862
|
}
|
|
7721
7863
|
}
|
|
@@ -7732,7 +7874,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7732
7874
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
7733
7875
|
*/
|
|
7734
7876
|
buildScriptWrappersFromDir(dir) {
|
|
7735
|
-
const scriptsJs =
|
|
7877
|
+
const scriptsJs = path7.join(dir, "scripts.js");
|
|
7736
7878
|
if (fs5.existsSync(scriptsJs)) {
|
|
7737
7879
|
try {
|
|
7738
7880
|
delete __require.cache[__require.resolve(scriptsJs)];
|
|
@@ -7746,7 +7888,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7746
7888
|
for (const file of fs5.readdirSync(dir)) {
|
|
7747
7889
|
if (!file.endsWith(".js")) continue;
|
|
7748
7890
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
7749
|
-
const filePath =
|
|
7891
|
+
const filePath = path7.join(dir, file);
|
|
7750
7892
|
result[scriptName] = (...args) => {
|
|
7751
7893
|
try {
|
|
7752
7894
|
let content = fs5.readFileSync(filePath, "utf-8");
|
|
@@ -7806,7 +7948,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7806
7948
|
}
|
|
7807
7949
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
7808
7950
|
if (hasJson) {
|
|
7809
|
-
const jsonPath =
|
|
7951
|
+
const jsonPath = path7.join(d, "provider.json");
|
|
7810
7952
|
try {
|
|
7811
7953
|
const raw = fs5.readFileSync(jsonPath, "utf-8");
|
|
7812
7954
|
const mod = JSON.parse(raw);
|
|
@@ -7819,7 +7961,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7819
7961
|
delete mod.extensionIdPattern_flags;
|
|
7820
7962
|
}
|
|
7821
7963
|
const hasCompatibility = Array.isArray(mod.compatibility);
|
|
7822
|
-
const scriptsPath =
|
|
7964
|
+
const scriptsPath = path7.join(d, "scripts.js");
|
|
7823
7965
|
if (!hasCompatibility && fs5.existsSync(scriptsPath)) {
|
|
7824
7966
|
try {
|
|
7825
7967
|
delete __require.cache[__require.resolve(scriptsPath)];
|
|
@@ -7845,7 +7987,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7845
7987
|
if (!entry.isDirectory()) continue;
|
|
7846
7988
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
7847
7989
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
7848
|
-
scan(
|
|
7990
|
+
scan(path7.join(d, entry.name));
|
|
7849
7991
|
}
|
|
7850
7992
|
}
|
|
7851
7993
|
};
|
|
@@ -7925,17 +8067,17 @@ async function findFreePort(ports) {
|
|
|
7925
8067
|
throw new Error("No free port found");
|
|
7926
8068
|
}
|
|
7927
8069
|
function checkPortFree(port) {
|
|
7928
|
-
return new Promise((
|
|
8070
|
+
return new Promise((resolve10) => {
|
|
7929
8071
|
const server = net.createServer();
|
|
7930
8072
|
server.unref();
|
|
7931
|
-
server.on("error", () =>
|
|
8073
|
+
server.on("error", () => resolve10(false));
|
|
7932
8074
|
server.listen(port, "127.0.0.1", () => {
|
|
7933
|
-
server.close(() =>
|
|
8075
|
+
server.close(() => resolve10(true));
|
|
7934
8076
|
});
|
|
7935
8077
|
});
|
|
7936
8078
|
}
|
|
7937
8079
|
async function isCdpActive(port) {
|
|
7938
|
-
return new Promise((
|
|
8080
|
+
return new Promise((resolve10) => {
|
|
7939
8081
|
const req = __require("http").get(`http://127.0.0.1:${port}/json/version`, {
|
|
7940
8082
|
timeout: 2e3
|
|
7941
8083
|
}, (res) => {
|
|
@@ -7944,16 +8086,16 @@ async function isCdpActive(port) {
|
|
|
7944
8086
|
res.on("end", () => {
|
|
7945
8087
|
try {
|
|
7946
8088
|
const info = JSON.parse(data);
|
|
7947
|
-
|
|
8089
|
+
resolve10(!!info["WebKit-Version"] || !!info["Browser"]);
|
|
7948
8090
|
} catch {
|
|
7949
|
-
|
|
8091
|
+
resolve10(false);
|
|
7950
8092
|
}
|
|
7951
8093
|
});
|
|
7952
8094
|
});
|
|
7953
|
-
req.on("error", () =>
|
|
8095
|
+
req.on("error", () => resolve10(false));
|
|
7954
8096
|
req.on("timeout", () => {
|
|
7955
8097
|
req.destroy();
|
|
7956
|
-
|
|
8098
|
+
resolve10(false);
|
|
7957
8099
|
});
|
|
7958
8100
|
});
|
|
7959
8101
|
}
|
|
@@ -8072,8 +8214,8 @@ function detectCurrentWorkspace(ideId) {
|
|
|
8072
8214
|
const appNameMap = getMacAppIdentifiers();
|
|
8073
8215
|
const appName = appNameMap[ideId];
|
|
8074
8216
|
if (appName) {
|
|
8075
|
-
const storagePath =
|
|
8076
|
-
process.env.APPDATA ||
|
|
8217
|
+
const storagePath = path8.join(
|
|
8218
|
+
process.env.APPDATA || path8.join(os8.homedir(), "AppData", "Roaming"),
|
|
8077
8219
|
appName,
|
|
8078
8220
|
"storage.json"
|
|
8079
8221
|
);
|
|
@@ -8248,9 +8390,9 @@ init_logger();
|
|
|
8248
8390
|
|
|
8249
8391
|
// src/logging/command-log.ts
|
|
8250
8392
|
import * as fs6 from "fs";
|
|
8251
|
-
import * as
|
|
8393
|
+
import * as path9 from "path";
|
|
8252
8394
|
import * as os9 from "os";
|
|
8253
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
8395
|
+
var LOG_DIR2 = process.platform === "win32" ? path9.join(process.env.LOCALAPPDATA || process.env.APPDATA || path9.join(os9.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path9.join(os9.homedir(), "Library", "Logs", "adhdev") : path9.join(os9.homedir(), ".local", "share", "adhdev", "logs");
|
|
8254
8396
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
8255
8397
|
var MAX_DAYS = 7;
|
|
8256
8398
|
try {
|
|
@@ -8288,13 +8430,13 @@ function getDateStr2() {
|
|
|
8288
8430
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
8289
8431
|
}
|
|
8290
8432
|
var currentDate2 = getDateStr2();
|
|
8291
|
-
var currentFile =
|
|
8433
|
+
var currentFile = path9.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
8292
8434
|
var writeCount2 = 0;
|
|
8293
8435
|
function checkRotation() {
|
|
8294
8436
|
const today = getDateStr2();
|
|
8295
8437
|
if (today !== currentDate2) {
|
|
8296
8438
|
currentDate2 = today;
|
|
8297
|
-
currentFile =
|
|
8439
|
+
currentFile = path9.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
8298
8440
|
cleanOldFiles();
|
|
8299
8441
|
}
|
|
8300
8442
|
}
|
|
@@ -8308,7 +8450,7 @@ function cleanOldFiles() {
|
|
|
8308
8450
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
8309
8451
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
8310
8452
|
try {
|
|
8311
|
-
fs6.unlinkSync(
|
|
8453
|
+
fs6.unlinkSync(path9.join(LOG_DIR2, file));
|
|
8312
8454
|
} catch {
|
|
8313
8455
|
}
|
|
8314
8456
|
}
|
|
@@ -8537,9 +8679,27 @@ var DaemonCommandRouter = class {
|
|
|
8537
8679
|
this.deps.onIdeConnected?.();
|
|
8538
8680
|
if (result.success && resolvedWorkspace) {
|
|
8539
8681
|
try {
|
|
8540
|
-
|
|
8682
|
+
let next = appendWorkspaceActivity(loadConfig(), resolvedWorkspace, {
|
|
8541
8683
|
kind: "ide",
|
|
8542
8684
|
agentType: result.ideId
|
|
8685
|
+
});
|
|
8686
|
+
next = appendRecentActivity(next, {
|
|
8687
|
+
kind: "ide",
|
|
8688
|
+
providerType: result.ideId || ideKey,
|
|
8689
|
+
providerName: result.ideId || ideKey,
|
|
8690
|
+
workspace: resolvedWorkspace,
|
|
8691
|
+
title: result.ideId || ideKey
|
|
8692
|
+
});
|
|
8693
|
+
saveConfig(next);
|
|
8694
|
+
} catch {
|
|
8695
|
+
}
|
|
8696
|
+
} else if (result.success && (result.ideId || ideKey)) {
|
|
8697
|
+
try {
|
|
8698
|
+
saveConfig(appendRecentActivity(loadConfig(), {
|
|
8699
|
+
kind: "ide",
|
|
8700
|
+
providerType: result.ideId || ideKey,
|
|
8701
|
+
providerName: result.ideId || ideKey,
|
|
8702
|
+
title: result.ideId || ideKey
|
|
8543
8703
|
}));
|
|
8544
8704
|
} catch {
|
|
8545
8705
|
}
|
|
@@ -8559,6 +8719,30 @@ var DaemonCommandRouter = class {
|
|
|
8559
8719
|
updateConfig({ userName: name });
|
|
8560
8720
|
return { success: true, userName: name };
|
|
8561
8721
|
}
|
|
8722
|
+
case "mark_recent_seen": {
|
|
8723
|
+
const kind = args?.kind;
|
|
8724
|
+
const providerType = args?.providerType;
|
|
8725
|
+
if (!kind || !providerType) {
|
|
8726
|
+
return { success: false, error: "kind and providerType are required" };
|
|
8727
|
+
}
|
|
8728
|
+
const recentKey = args?.recentKey || buildRecentActivityKey({
|
|
8729
|
+
kind,
|
|
8730
|
+
providerType,
|
|
8731
|
+
workspace: args?.workspace || null
|
|
8732
|
+
});
|
|
8733
|
+
const next = markRecentSessionSeen(
|
|
8734
|
+
loadConfig(),
|
|
8735
|
+
recentKey,
|
|
8736
|
+
typeof args?.seenAt === "number" ? args.seenAt : Date.now()
|
|
8737
|
+
);
|
|
8738
|
+
saveConfig(next);
|
|
8739
|
+
this.deps.onStatusChange?.();
|
|
8740
|
+
return {
|
|
8741
|
+
success: true,
|
|
8742
|
+
recentKey,
|
|
8743
|
+
seenAt: next.recentSessionReads?.[recentKey] || Date.now()
|
|
8744
|
+
};
|
|
8745
|
+
}
|
|
8562
8746
|
// ─── Daemon Self-Upgrade ───
|
|
8563
8747
|
case "daemon_upgrade": {
|
|
8564
8748
|
LOG.info("Upgrade", "Remote upgrade requested from dashboard");
|
|
@@ -8577,9 +8761,9 @@ var DaemonCommandRouter = class {
|
|
|
8577
8761
|
setTimeout(() => {
|
|
8578
8762
|
LOG.info("Upgrade", "Restarting daemon with new version...");
|
|
8579
8763
|
try {
|
|
8580
|
-
const
|
|
8764
|
+
const path16 = __require("path");
|
|
8581
8765
|
const fs12 = __require("fs");
|
|
8582
|
-
const pidFile =
|
|
8766
|
+
const pidFile = path16.join(process.env.HOME || process.env.USERPROFILE || "", ".adhdev", "daemon.pid");
|
|
8583
8767
|
if (fs12.existsSync(pidFile)) fs12.unlinkSync(pidFile);
|
|
8584
8768
|
} catch {
|
|
8585
8769
|
}
|
|
@@ -8676,8 +8860,9 @@ init_logger();
|
|
|
8676
8860
|
|
|
8677
8861
|
// src/status/snapshot.ts
|
|
8678
8862
|
init_config();
|
|
8679
|
-
init_workspaces();
|
|
8680
8863
|
import * as os10 from "os";
|
|
8864
|
+
init_workspaces();
|
|
8865
|
+
init_terminal_screen();
|
|
8681
8866
|
function buildDetectedIdeInfos(detectedIdes, cdpManagers) {
|
|
8682
8867
|
return detectedIdes.filter((ide) => ide.installed !== false).map((ide) => ({
|
|
8683
8868
|
id: ide.id,
|
|
@@ -8696,14 +8881,127 @@ function buildAvailableProviders(providerLoader) {
|
|
|
8696
8881
|
category: provider.category
|
|
8697
8882
|
}));
|
|
8698
8883
|
}
|
|
8884
|
+
function parseMessageTime(value) {
|
|
8885
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
8886
|
+
if (typeof value === "string") {
|
|
8887
|
+
const parsed = Date.parse(value);
|
|
8888
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
8889
|
+
}
|
|
8890
|
+
return 0;
|
|
8891
|
+
}
|
|
8892
|
+
function getSessionMessageUpdatedAt(session) {
|
|
8893
|
+
const lastMessage = session.activeChat?.messages?.at?.(-1);
|
|
8894
|
+
if (!lastMessage) return 0;
|
|
8895
|
+
return parseMessageTime(lastMessage.timestamp) || parseMessageTime(lastMessage.receivedAt) || parseMessageTime(lastMessage.createdAt) || 0;
|
|
8896
|
+
}
|
|
8897
|
+
function getSessionLastUsedAt(session) {
|
|
8898
|
+
return getSessionMessageUpdatedAt(session) || session.lastUpdated || Date.now();
|
|
8899
|
+
}
|
|
8900
|
+
function getSessionKind(session) {
|
|
8901
|
+
return session.transport === "cdp-page" || session.transport === "cdp-webview" ? "ide" : session.transport === "acp" ? "acp" : "cli";
|
|
8902
|
+
}
|
|
8903
|
+
function getLastMessageRole(session) {
|
|
8904
|
+
const role = session.activeChat?.messages?.at?.(-1)?.role;
|
|
8905
|
+
return typeof role === "string" ? role : "";
|
|
8906
|
+
}
|
|
8907
|
+
function getUnreadState(hasContentChange, status, lastUsedAt, lastSeenAt, lastRole) {
|
|
8908
|
+
if (status === "waiting_approval") {
|
|
8909
|
+
return { unread: false, inboxBucket: "needs_attention" };
|
|
8910
|
+
}
|
|
8911
|
+
if (status === "generating" || status === "starting") {
|
|
8912
|
+
return { unread: false, inboxBucket: "working" };
|
|
8913
|
+
}
|
|
8914
|
+
const unread = hasContentChange && lastUsedAt > lastSeenAt && lastRole !== "user" && lastRole !== "human";
|
|
8915
|
+
return { unread, inboxBucket: unread ? "task_complete" : "idle" };
|
|
8916
|
+
}
|
|
8917
|
+
function buildRecentSessions(sessions, recentActivity, readState) {
|
|
8918
|
+
const live = sessions.filter((session) => !session.parentId && session.status !== "stopped").map((session) => {
|
|
8919
|
+
const kind = getSessionKind(session);
|
|
8920
|
+
const recentKey = buildRecentActivityKey({
|
|
8921
|
+
kind,
|
|
8922
|
+
providerType: session.providerType,
|
|
8923
|
+
workspace: session.workspace
|
|
8924
|
+
});
|
|
8925
|
+
const lastSeenAt = readState[recentKey] || 0;
|
|
8926
|
+
const lastUsedAt = getSessionLastUsedAt(session);
|
|
8927
|
+
const { unread, inboxBucket } = getUnreadState(
|
|
8928
|
+
getSessionMessageUpdatedAt(session) > 0,
|
|
8929
|
+
session.status,
|
|
8930
|
+
lastUsedAt,
|
|
8931
|
+
lastSeenAt,
|
|
8932
|
+
getLastMessageRole(session)
|
|
8933
|
+
);
|
|
8934
|
+
return {
|
|
8935
|
+
id: session.id,
|
|
8936
|
+
recentKey,
|
|
8937
|
+
sessionId: session.id,
|
|
8938
|
+
providerType: session.providerType,
|
|
8939
|
+
providerName: session.providerName,
|
|
8940
|
+
kind,
|
|
8941
|
+
title: session.activeChat?.title || session.title || session.providerName,
|
|
8942
|
+
workspace: session.workspace,
|
|
8943
|
+
currentModel: session.currentModel,
|
|
8944
|
+
status: session.status,
|
|
8945
|
+
lastUsedAt,
|
|
8946
|
+
unread,
|
|
8947
|
+
lastSeenAt,
|
|
8948
|
+
inboxBucket
|
|
8949
|
+
};
|
|
8950
|
+
});
|
|
8951
|
+
const seen = new Set(live.map((item) => `${item.kind}:${item.providerType}:${item.workspace || ""}`));
|
|
8952
|
+
const persisted = recentActivity.filter((item) => !seen.has(`${item.kind}:${item.providerType}:${item.workspace || ""}`)).map((item) => {
|
|
8953
|
+
const lastSeenAt = readState[item.id] || 0;
|
|
8954
|
+
const unread = item.lastUsedAt > lastSeenAt;
|
|
8955
|
+
return {
|
|
8956
|
+
id: item.id,
|
|
8957
|
+
recentKey: item.id,
|
|
8958
|
+
sessionId: item.sessionId || null,
|
|
8959
|
+
providerType: item.providerType,
|
|
8960
|
+
providerName: item.providerName,
|
|
8961
|
+
kind: item.kind,
|
|
8962
|
+
title: item.title || item.providerName,
|
|
8963
|
+
workspace: item.workspace,
|
|
8964
|
+
currentModel: item.currentModel,
|
|
8965
|
+
lastUsedAt: item.lastUsedAt,
|
|
8966
|
+
unread,
|
|
8967
|
+
lastSeenAt,
|
|
8968
|
+
inboxBucket: unread ? "task_complete" : "idle"
|
|
8969
|
+
};
|
|
8970
|
+
});
|
|
8971
|
+
return [...live, ...persisted].sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, 12);
|
|
8972
|
+
}
|
|
8699
8973
|
function buildStatusSnapshot(options) {
|
|
8700
8974
|
const cfg = loadConfig();
|
|
8701
8975
|
const wsState = getWorkspaceState(cfg);
|
|
8702
8976
|
const memSnap = getHostMemorySnapshot();
|
|
8977
|
+
const recentActivity = getRecentActivity(cfg, 20);
|
|
8703
8978
|
const sessions = buildSessionEntries(
|
|
8704
8979
|
options.allStates,
|
|
8705
8980
|
options.cdpManagers
|
|
8706
8981
|
);
|
|
8982
|
+
const readState = cfg.recentSessionReads || {};
|
|
8983
|
+
for (const session of sessions) {
|
|
8984
|
+
const kind = getSessionKind(session);
|
|
8985
|
+
const recentKey = buildRecentActivityKey({
|
|
8986
|
+
kind,
|
|
8987
|
+
providerType: session.providerType,
|
|
8988
|
+
workspace: session.workspace
|
|
8989
|
+
});
|
|
8990
|
+
const lastSeenAt = getRecentSessionSeenAt(cfg, recentKey);
|
|
8991
|
+
const lastUsedAt = getSessionLastUsedAt(session);
|
|
8992
|
+
const { unread, inboxBucket } = getUnreadState(
|
|
8993
|
+
getSessionMessageUpdatedAt(session) > 0,
|
|
8994
|
+
session.status,
|
|
8995
|
+
lastUsedAt,
|
|
8996
|
+
lastSeenAt,
|
|
8997
|
+
getLastMessageRole(session)
|
|
8998
|
+
);
|
|
8999
|
+
session.recentKey = recentKey;
|
|
9000
|
+
session.lastSeenAt = lastSeenAt;
|
|
9001
|
+
session.unread = unread;
|
|
9002
|
+
session.inboxBucket = inboxBucket;
|
|
9003
|
+
}
|
|
9004
|
+
const terminalBackend = getTerminalBackendRuntimeStatus();
|
|
8707
9005
|
return {
|
|
8708
9006
|
instanceId: options.instanceId,
|
|
8709
9007
|
version: options.version,
|
|
@@ -8729,6 +9027,8 @@ function buildStatusSnapshot(options) {
|
|
|
8729
9027
|
defaultWorkspaceId: wsState.defaultWorkspaceId,
|
|
8730
9028
|
defaultWorkspacePath: wsState.defaultWorkspacePath,
|
|
8731
9029
|
workspaceActivity: getWorkspaceActivity(cfg, 15),
|
|
9030
|
+
recentSessions: buildRecentSessions(sessions, recentActivity, readState),
|
|
9031
|
+
terminalBackend,
|
|
8732
9032
|
availableProviders: buildAvailableProviders(options.providerLoader)
|
|
8733
9033
|
};
|
|
8734
9034
|
}
|
|
@@ -8880,7 +9180,15 @@ var DaemonStatusReporter = class {
|
|
|
8880
9180
|
cdpConnected: session.cdpConnected,
|
|
8881
9181
|
currentModel: session.currentModel,
|
|
8882
9182
|
currentPlan: session.currentPlan,
|
|
8883
|
-
currentAutoApprove: session.currentAutoApprove
|
|
9183
|
+
currentAutoApprove: session.currentAutoApprove,
|
|
9184
|
+
recentKey: session.recentKey,
|
|
9185
|
+
unread: session.unread,
|
|
9186
|
+
lastSeenAt: session.lastSeenAt,
|
|
9187
|
+
inboxBucket: session.inboxBucket,
|
|
9188
|
+
controlValues: session.controlValues,
|
|
9189
|
+
providerControls: session.providerControls,
|
|
9190
|
+
acpConfigOptions: session.acpConfigOptions,
|
|
9191
|
+
acpModes: session.acpModes
|
|
8884
9192
|
})),
|
|
8885
9193
|
p2p: payload.p2p,
|
|
8886
9194
|
timestamp: now
|
|
@@ -8919,7 +9227,7 @@ init_logger();
|
|
|
8919
9227
|
// src/commands/cli-manager.ts
|
|
8920
9228
|
init_provider_cli_adapter();
|
|
8921
9229
|
import * as os13 from "os";
|
|
8922
|
-
import * as
|
|
9230
|
+
import * as path11 from "path";
|
|
8923
9231
|
import * as crypto4 from "crypto";
|
|
8924
9232
|
import chalk from "chalk";
|
|
8925
9233
|
init_config();
|
|
@@ -9016,7 +9324,10 @@ var CliProviderInstance = class {
|
|
|
9016
9324
|
writeOwner: runtime.writeOwner || null,
|
|
9017
9325
|
attachedClients: runtime.attachedClients || []
|
|
9018
9326
|
} : void 0,
|
|
9019
|
-
resume: this.provider.resume
|
|
9327
|
+
resume: this.provider.resume,
|
|
9328
|
+
controlValues: void 0,
|
|
9329
|
+
// CLI controls not yet wired from stream
|
|
9330
|
+
providerControls: this.provider.controls
|
|
9020
9331
|
};
|
|
9021
9332
|
}
|
|
9022
9333
|
onEvent(event, data) {
|
|
@@ -9297,7 +9608,12 @@ var AcpProviderInstance = class {
|
|
|
9297
9608
|
acpModes: this.availableModes,
|
|
9298
9609
|
// Error details for dashboard display
|
|
9299
9610
|
errorMessage: this.errorMessage || void 0,
|
|
9300
|
-
errorReason: this.errorReason || void 0
|
|
9611
|
+
errorReason: this.errorReason || void 0,
|
|
9612
|
+
controlValues: {
|
|
9613
|
+
...this.currentModel ? { model: this.currentModel } : {},
|
|
9614
|
+
...this.currentMode ? { mode: this.currentMode } : {}
|
|
9615
|
+
},
|
|
9616
|
+
providerControls: this.provider.controls
|
|
9301
9617
|
};
|
|
9302
9618
|
}
|
|
9303
9619
|
onEvent(event, data) {
|
|
@@ -9596,13 +9912,13 @@ var AcpProviderInstance = class {
|
|
|
9596
9912
|
}
|
|
9597
9913
|
this.currentStatus = "waiting_approval";
|
|
9598
9914
|
this.detectStatusTransition();
|
|
9599
|
-
const approved = await new Promise((
|
|
9600
|
-
this.permissionResolvers.push(
|
|
9915
|
+
const approved = await new Promise((resolve10) => {
|
|
9916
|
+
this.permissionResolvers.push(resolve10);
|
|
9601
9917
|
setTimeout(() => {
|
|
9602
|
-
const idx = this.permissionResolvers.indexOf(
|
|
9918
|
+
const idx = this.permissionResolvers.indexOf(resolve10);
|
|
9603
9919
|
if (idx >= 0) {
|
|
9604
9920
|
this.permissionResolvers.splice(idx, 1);
|
|
9605
|
-
|
|
9921
|
+
resolve10(false);
|
|
9606
9922
|
}
|
|
9607
9923
|
}, 3e5);
|
|
9608
9924
|
});
|
|
@@ -10095,6 +10411,13 @@ var DaemonCliManager = class {
|
|
|
10095
10411
|
console.error(colorize("red", ` \u2717 Failed to save recent workspace: ${e}`));
|
|
10096
10412
|
}
|
|
10097
10413
|
}
|
|
10414
|
+
persistRecentActivity(entry) {
|
|
10415
|
+
try {
|
|
10416
|
+
saveConfig(appendRecentActivity(loadConfig(), entry));
|
|
10417
|
+
} catch (e) {
|
|
10418
|
+
console.error(colorize("red", ` \u2717 Failed to save recent activity: ${e}`));
|
|
10419
|
+
}
|
|
10420
|
+
}
|
|
10098
10421
|
getTransportFactory(runtimeId, providerType, workspace, cliArgs, attachExisting = false) {
|
|
10099
10422
|
return this.deps.createPtyTransportFactory?.({
|
|
10100
10423
|
runtimeId,
|
|
@@ -10177,7 +10500,7 @@ var DaemonCliManager = class {
|
|
|
10177
10500
|
async startSession(cliType, workingDir, cliArgs, initialModel) {
|
|
10178
10501
|
const trimmed = (workingDir || "").trim();
|
|
10179
10502
|
if (!trimmed) throw new Error("working directory required");
|
|
10180
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) :
|
|
10503
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path11.resolve(trimmed);
|
|
10181
10504
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
10182
10505
|
const provider = this.providerLoader.getByAlias(cliType);
|
|
10183
10506
|
const key = crypto4.randomUUID();
|
|
@@ -10253,6 +10576,15 @@ ${installInfo}`
|
|
|
10253
10576
|
} catch (e) {
|
|
10254
10577
|
LOG.warn("CLI", `ACP history save failed: ${e?.message}`);
|
|
10255
10578
|
}
|
|
10579
|
+
this.persistRecentActivity({
|
|
10580
|
+
kind: "acp",
|
|
10581
|
+
providerType: normalizedType,
|
|
10582
|
+
providerName: provider.displayName || provider.name || normalizedType,
|
|
10583
|
+
workspace: resolvedDir,
|
|
10584
|
+
currentModel: initialModel,
|
|
10585
|
+
sessionId,
|
|
10586
|
+
title: provider.displayName || provider.name || normalizedType
|
|
10587
|
+
});
|
|
10256
10588
|
this.deps.onStatusChange();
|
|
10257
10589
|
return;
|
|
10258
10590
|
}
|
|
@@ -10315,6 +10647,15 @@ ${installInfo}`
|
|
|
10315
10647
|
} catch (e) {
|
|
10316
10648
|
LOG.warn("CLI", `CLI history save failed: ${e?.message}`);
|
|
10317
10649
|
}
|
|
10650
|
+
this.persistRecentActivity({
|
|
10651
|
+
kind: "cli",
|
|
10652
|
+
providerType: normalizedType,
|
|
10653
|
+
providerName: provider?.displayName || provider?.name || normalizedType,
|
|
10654
|
+
workspace: resolvedDir,
|
|
10655
|
+
currentModel: initialModel,
|
|
10656
|
+
sessionId: key,
|
|
10657
|
+
title: provider?.displayName || provider?.name || normalizedType
|
|
10658
|
+
});
|
|
10318
10659
|
this.deps.onStatusChange();
|
|
10319
10660
|
}
|
|
10320
10661
|
async stopSession(key) {
|
|
@@ -10560,11 +10901,24 @@ var ProviderStreamAdapter = class {
|
|
|
10560
10901
|
hasScript(name) {
|
|
10561
10902
|
return typeof this.provider.scripts?.[name] === "function";
|
|
10562
10903
|
}
|
|
10904
|
+
summarizeRaw(raw) {
|
|
10905
|
+
try {
|
|
10906
|
+
if (typeof raw === "string") return raw.replace(/\s+/g, " ").trim().slice(0, 240);
|
|
10907
|
+
if (raw == null) return String(raw);
|
|
10908
|
+
return JSON.stringify(raw).replace(/\s+/g, " ").trim().slice(0, 240);
|
|
10909
|
+
} catch {
|
|
10910
|
+
return Object.prototype.toString.call(raw);
|
|
10911
|
+
}
|
|
10912
|
+
}
|
|
10913
|
+
isTransportError(reason) {
|
|
10914
|
+
return /Session with given id not found/i.test(reason) || /CDP not connected/i.test(reason) || /Target closed/i.test(reason) || /WebSocket not open/i.test(reason) || /not connected/i.test(reason) || /execution context/i.test(reason) || /Cannot find context with specified id/i.test(reason);
|
|
10915
|
+
}
|
|
10563
10916
|
async readChat(evaluate) {
|
|
10564
10917
|
const script = this.callScript("readChat");
|
|
10565
10918
|
if (!script) return this.errorState("readChat script not available");
|
|
10919
|
+
let raw = null;
|
|
10566
10920
|
try {
|
|
10567
|
-
|
|
10921
|
+
raw = await evaluate(script);
|
|
10568
10922
|
const data = typeof raw === "string" ? JSON.parse(raw) : raw;
|
|
10569
10923
|
if (data?.error) {
|
|
10570
10924
|
const state2 = this.errorState(data.error);
|
|
@@ -10584,12 +10938,31 @@ var ProviderStreamAdapter = class {
|
|
|
10584
10938
|
mode: data.mode,
|
|
10585
10939
|
activeModal: data.activeModal
|
|
10586
10940
|
};
|
|
10941
|
+
if (this.provider.controls?.length) {
|
|
10942
|
+
const cv = {};
|
|
10943
|
+
for (const ctrl of this.provider.controls) {
|
|
10944
|
+
if (!ctrl.readFrom) continue;
|
|
10945
|
+
const val = data[ctrl.readFrom];
|
|
10946
|
+
if (val !== void 0 && val !== null) {
|
|
10947
|
+
cv[ctrl.id] = typeof val === "object" ? val.name || val.id || String(val) : val;
|
|
10948
|
+
}
|
|
10949
|
+
}
|
|
10950
|
+
if (data.model && !cv["model"]) cv["model"] = data.model;
|
|
10951
|
+
if (data.mode && !cv["mode"]) cv["mode"] = data.mode;
|
|
10952
|
+
if (Object.keys(cv).length > 0) state.controlValues = cv;
|
|
10953
|
+
}
|
|
10587
10954
|
if (state.messages.length > 0) {
|
|
10588
10955
|
this.lastSuccessState = state;
|
|
10589
10956
|
}
|
|
10590
10957
|
return state;
|
|
10591
|
-
} catch {
|
|
10592
|
-
const
|
|
10958
|
+
} catch (error) {
|
|
10959
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
10960
|
+
if (this.isTransportError(reason)) {
|
|
10961
|
+
throw error instanceof Error ? error : new Error(reason);
|
|
10962
|
+
}
|
|
10963
|
+
const preview = this.summarizeRaw(raw);
|
|
10964
|
+
const detail = preview ? ` (reason=${reason}; raw=${preview})` : ` (reason=${reason})`;
|
|
10965
|
+
const state = this.errorState(`Failed to parse ${this.agentName} state${detail}`);
|
|
10593
10966
|
if (this.lastSuccessState?.messages?.length) {
|
|
10594
10967
|
state.messages = this.lastSuccessState.messages;
|
|
10595
10968
|
}
|
|
@@ -10686,6 +11059,9 @@ var DaemonAgentStreamManager = class {
|
|
|
10686
11059
|
getActiveSessionId(parentSessionId) {
|
|
10687
11060
|
return this.activeSessionIdByParent.get(parentSessionId) || null;
|
|
10688
11061
|
}
|
|
11062
|
+
isRecoverableSessionError(message) {
|
|
11063
|
+
return message.includes("timeout") || message.includes("not connected") || message.includes("Session") || message.includes("Target closed") || message.includes("execution context") || message.includes("context with specified id");
|
|
11064
|
+
}
|
|
10689
11065
|
getSessionTarget(sessionId) {
|
|
10690
11066
|
return this.sessionRegistry?.get(sessionId);
|
|
10691
11067
|
}
|
|
@@ -10787,6 +11163,10 @@ var DaemonAgentStreamManager = class {
|
|
|
10787
11163
|
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
|
|
10788
11164
|
const state = await agent.adapter.readChat(evaluate);
|
|
10789
11165
|
LOG.debug("AgentStream", `[AgentStream] readChat(${type}) result: status=${state.status} msgs=${state.messages?.length || 0} model=${state.model || ""}${state.status === "error" ? " error=" + JSON.stringify(state.error || state._error || "unknown") : ""}`);
|
|
11166
|
+
const stateError = String(state.error || state._error || "");
|
|
11167
|
+
if (state.status === "error" && this.isRecoverableSessionError(stateError)) {
|
|
11168
|
+
throw new Error(stateError);
|
|
11169
|
+
}
|
|
10790
11170
|
agent.lastState = state;
|
|
10791
11171
|
agent.lastError = null;
|
|
10792
11172
|
if (state.status === "panel_hidden") {
|
|
@@ -10797,7 +11177,7 @@ var DaemonAgentStreamManager = class {
|
|
|
10797
11177
|
const errorMsg = e?.message || String(e);
|
|
10798
11178
|
this.logFn(`[AgentStream] readChat(${type}) error: ${errorMsg.slice(0, 200)}`);
|
|
10799
11179
|
agent.lastError = errorMsg;
|
|
10800
|
-
if (
|
|
11180
|
+
if (this.isRecoverableSessionError(errorMsg)) {
|
|
10801
11181
|
try {
|
|
10802
11182
|
await cdp.detachAgent(agent.cdpSessionId);
|
|
10803
11183
|
} catch {
|
|
@@ -11285,11 +11665,11 @@ var ProviderInstanceManager = class {
|
|
|
11285
11665
|
|
|
11286
11666
|
// src/providers/version-archive.ts
|
|
11287
11667
|
import * as fs8 from "fs";
|
|
11288
|
-
import * as
|
|
11668
|
+
import * as path12 from "path";
|
|
11289
11669
|
import * as os14 from "os";
|
|
11290
11670
|
import { execSync as execSync5 } from "child_process";
|
|
11291
11671
|
import { platform as platform8 } from "os";
|
|
11292
|
-
var ARCHIVE_PATH =
|
|
11672
|
+
var ARCHIVE_PATH = path12.join(os14.homedir(), ".adhdev", "version-history.json");
|
|
11293
11673
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
11294
11674
|
var VersionArchive = class {
|
|
11295
11675
|
history = {};
|
|
@@ -11336,7 +11716,7 @@ var VersionArchive = class {
|
|
|
11336
11716
|
}
|
|
11337
11717
|
save() {
|
|
11338
11718
|
try {
|
|
11339
|
-
fs8.mkdirSync(
|
|
11719
|
+
fs8.mkdirSync(path12.dirname(ARCHIVE_PATH), { recursive: true });
|
|
11340
11720
|
fs8.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
11341
11721
|
} catch {
|
|
11342
11722
|
}
|
|
@@ -11377,7 +11757,7 @@ function checkPathExists2(paths) {
|
|
|
11377
11757
|
for (const p of paths) {
|
|
11378
11758
|
if (p.includes("*")) {
|
|
11379
11759
|
const home = os14.homedir();
|
|
11380
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
11760
|
+
const resolved = p.replace(/\*/g, home.split(path12.sep).pop() || "");
|
|
11381
11761
|
if (fs8.existsSync(resolved)) return resolved;
|
|
11382
11762
|
} else {
|
|
11383
11763
|
if (fs8.existsSync(p)) return p;
|
|
@@ -11387,7 +11767,7 @@ function checkPathExists2(paths) {
|
|
|
11387
11767
|
}
|
|
11388
11768
|
function getMacAppVersion(appPath) {
|
|
11389
11769
|
if (platform8() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
11390
|
-
const plistPath =
|
|
11770
|
+
const plistPath = path12.join(appPath, "Contents", "Info.plist");
|
|
11391
11771
|
if (!fs8.existsSync(plistPath)) return null;
|
|
11392
11772
|
const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
11393
11773
|
return raw || null;
|
|
@@ -11414,7 +11794,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
11414
11794
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
11415
11795
|
let resolvedBin = cliBin;
|
|
11416
11796
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
11417
|
-
const bundled =
|
|
11797
|
+
const bundled = path12.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
11418
11798
|
if (provider.cli && fs8.existsSync(bundled)) resolvedBin = bundled;
|
|
11419
11799
|
}
|
|
11420
11800
|
info.installed = !!(appPath || resolvedBin);
|
|
@@ -11455,7 +11835,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
11455
11835
|
// src/daemon/dev-server.ts
|
|
11456
11836
|
import * as http2 from "http";
|
|
11457
11837
|
import * as fs11 from "fs";
|
|
11458
|
-
import * as
|
|
11838
|
+
import * as path15 from "path";
|
|
11459
11839
|
|
|
11460
11840
|
// src/daemon/scaffold-template.ts
|
|
11461
11841
|
function generateFiles(type, name, category, opts = {}) {
|
|
@@ -11792,7 +12172,7 @@ init_logger();
|
|
|
11792
12172
|
// src/daemon/dev-cdp-handlers.ts
|
|
11793
12173
|
init_logger();
|
|
11794
12174
|
import * as fs9 from "fs";
|
|
11795
|
-
import * as
|
|
12175
|
+
import * as path13 from "path";
|
|
11796
12176
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
11797
12177
|
const body = await ctx.readBody(req);
|
|
11798
12178
|
const { expression, timeout, ideType } = body;
|
|
@@ -11970,17 +12350,17 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
11970
12350
|
return;
|
|
11971
12351
|
}
|
|
11972
12352
|
let scriptsPath = "";
|
|
11973
|
-
const directScripts =
|
|
12353
|
+
const directScripts = path13.join(dir, "scripts.js");
|
|
11974
12354
|
if (fs9.existsSync(directScripts)) {
|
|
11975
12355
|
scriptsPath = directScripts;
|
|
11976
12356
|
} else {
|
|
11977
|
-
const scriptsDir =
|
|
12357
|
+
const scriptsDir = path13.join(dir, "scripts");
|
|
11978
12358
|
if (fs9.existsSync(scriptsDir)) {
|
|
11979
12359
|
const versions = fs9.readdirSync(scriptsDir).filter((d) => {
|
|
11980
|
-
return fs9.statSync(
|
|
12360
|
+
return fs9.statSync(path13.join(scriptsDir, d)).isDirectory();
|
|
11981
12361
|
}).sort().reverse();
|
|
11982
12362
|
for (const ver of versions) {
|
|
11983
|
-
const p =
|
|
12363
|
+
const p = path13.join(scriptsDir, ver, "scripts.js");
|
|
11984
12364
|
if (fs9.existsSync(p)) {
|
|
11985
12365
|
scriptsPath = p;
|
|
11986
12366
|
break;
|
|
@@ -13035,7 +13415,7 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
13035
13415
|
|
|
13036
13416
|
// src/daemon/dev-auto-implement.ts
|
|
13037
13417
|
import * as fs10 from "fs";
|
|
13038
|
-
import * as
|
|
13418
|
+
import * as path14 from "path";
|
|
13039
13419
|
import * as os15 from "os";
|
|
13040
13420
|
function getDefaultAutoImplReference(ctx, category, type) {
|
|
13041
13421
|
if (category === "cli") {
|
|
@@ -13055,22 +13435,22 @@ function getLatestScriptVersionDir(scriptsDir) {
|
|
|
13055
13435
|
if (!fs10.existsSync(scriptsDir)) return null;
|
|
13056
13436
|
const versions = fs10.readdirSync(scriptsDir).filter((d) => {
|
|
13057
13437
|
try {
|
|
13058
|
-
return fs10.statSync(
|
|
13438
|
+
return fs10.statSync(path14.join(scriptsDir, d)).isDirectory();
|
|
13059
13439
|
} catch {
|
|
13060
13440
|
return false;
|
|
13061
13441
|
}
|
|
13062
13442
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
13063
13443
|
if (versions.length === 0) return null;
|
|
13064
|
-
return
|
|
13444
|
+
return path14.join(scriptsDir, versions[0]);
|
|
13065
13445
|
}
|
|
13066
13446
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
13067
|
-
const canonicalUserDir =
|
|
13068
|
-
const desiredDir = requestedDir ?
|
|
13069
|
-
const upstreamRoot =
|
|
13070
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
13447
|
+
const canonicalUserDir = path14.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
13448
|
+
const desiredDir = requestedDir ? path14.resolve(requestedDir) : canonicalUserDir;
|
|
13449
|
+
const upstreamRoot = path14.resolve(ctx.providerLoader.getUpstreamDir());
|
|
13450
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path14.sep}`)) {
|
|
13071
13451
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
13072
13452
|
}
|
|
13073
|
-
if (
|
|
13453
|
+
if (path14.basename(desiredDir) !== type) {
|
|
13074
13454
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
13075
13455
|
}
|
|
13076
13456
|
const sourceDir = ctx.findProviderDir(type);
|
|
@@ -13078,11 +13458,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
13078
13458
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
13079
13459
|
}
|
|
13080
13460
|
if (!fs10.existsSync(desiredDir)) {
|
|
13081
|
-
fs10.mkdirSync(
|
|
13461
|
+
fs10.mkdirSync(path14.dirname(desiredDir), { recursive: true });
|
|
13082
13462
|
fs10.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
13083
13463
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
13084
13464
|
}
|
|
13085
|
-
const providerJson =
|
|
13465
|
+
const providerJson = path14.join(desiredDir, "provider.json");
|
|
13086
13466
|
if (!fs10.existsSync(providerJson)) {
|
|
13087
13467
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
13088
13468
|
}
|
|
@@ -13105,13 +13485,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
|
13105
13485
|
const refDir = ctx.findProviderDir(referenceType);
|
|
13106
13486
|
if (!refDir || !fs10.existsSync(refDir)) return {};
|
|
13107
13487
|
const referenceScripts = {};
|
|
13108
|
-
const scriptsDir =
|
|
13488
|
+
const scriptsDir = path14.join(refDir, "scripts");
|
|
13109
13489
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
13110
13490
|
if (!latestDir) return referenceScripts;
|
|
13111
13491
|
for (const file of fs10.readdirSync(latestDir)) {
|
|
13112
13492
|
if (!file.endsWith(".js")) continue;
|
|
13113
13493
|
try {
|
|
13114
|
-
referenceScripts[file] = fs10.readFileSync(
|
|
13494
|
+
referenceScripts[file] = fs10.readFileSync(path14.join(latestDir, file), "utf-8");
|
|
13115
13495
|
} catch {
|
|
13116
13496
|
}
|
|
13117
13497
|
}
|
|
@@ -13162,9 +13542,9 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
13162
13542
|
});
|
|
13163
13543
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
13164
13544
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference);
|
|
13165
|
-
const tmpDir =
|
|
13545
|
+
const tmpDir = path14.join(os15.tmpdir(), "adhdev-autoimpl");
|
|
13166
13546
|
if (!fs10.existsSync(tmpDir)) fs10.mkdirSync(tmpDir, { recursive: true });
|
|
13167
|
-
const promptFile =
|
|
13547
|
+
const promptFile = path14.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
13168
13548
|
fs10.writeFileSync(promptFile, prompt, "utf-8");
|
|
13169
13549
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
13170
13550
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
@@ -13535,7 +13915,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
13535
13915
|
setMode: "set_mode.js"
|
|
13536
13916
|
};
|
|
13537
13917
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
13538
|
-
const scriptsDir =
|
|
13918
|
+
const scriptsDir = path14.join(providerDir, "scripts");
|
|
13539
13919
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
13540
13920
|
if (latestScriptsDir) {
|
|
13541
13921
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -13546,7 +13926,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
13546
13926
|
for (const file of fs10.readdirSync(latestScriptsDir)) {
|
|
13547
13927
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
13548
13928
|
try {
|
|
13549
|
-
const content = fs10.readFileSync(
|
|
13929
|
+
const content = fs10.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
|
|
13550
13930
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
13551
13931
|
lines.push("```javascript");
|
|
13552
13932
|
lines.push(content);
|
|
@@ -13563,7 +13943,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
13563
13943
|
lines.push("");
|
|
13564
13944
|
for (const file of refFiles) {
|
|
13565
13945
|
try {
|
|
13566
|
-
const content = fs10.readFileSync(
|
|
13946
|
+
const content = fs10.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
|
|
13567
13947
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
13568
13948
|
lines.push("```javascript");
|
|
13569
13949
|
lines.push(content);
|
|
@@ -13604,10 +13984,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
13604
13984
|
lines.push("");
|
|
13605
13985
|
}
|
|
13606
13986
|
}
|
|
13607
|
-
const docsDir =
|
|
13987
|
+
const docsDir = path14.join(providerDir, "../../docs");
|
|
13608
13988
|
const loadGuide = (name) => {
|
|
13609
13989
|
try {
|
|
13610
|
-
const p =
|
|
13990
|
+
const p = path14.join(docsDir, name);
|
|
13611
13991
|
if (fs10.existsSync(p)) return fs10.readFileSync(p, "utf-8");
|
|
13612
13992
|
} catch {
|
|
13613
13993
|
}
|
|
@@ -13781,7 +14161,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
13781
14161
|
parseApproval: "parse_approval.js"
|
|
13782
14162
|
};
|
|
13783
14163
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
13784
|
-
const scriptsDir =
|
|
14164
|
+
const scriptsDir = path14.join(providerDir, "scripts");
|
|
13785
14165
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
13786
14166
|
if (latestScriptsDir) {
|
|
13787
14167
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -13793,7 +14173,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
13793
14173
|
if (!file.endsWith(".js")) continue;
|
|
13794
14174
|
if (!targetFileNames.has(file)) continue;
|
|
13795
14175
|
try {
|
|
13796
|
-
const content = fs10.readFileSync(
|
|
14176
|
+
const content = fs10.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
|
|
13797
14177
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
13798
14178
|
lines.push("```javascript");
|
|
13799
14179
|
lines.push(content);
|
|
@@ -13809,7 +14189,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
13809
14189
|
lines.push("");
|
|
13810
14190
|
for (const file of refFiles) {
|
|
13811
14191
|
try {
|
|
13812
|
-
const content = fs10.readFileSync(
|
|
14192
|
+
const content = fs10.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
|
|
13813
14193
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
13814
14194
|
lines.push("```javascript");
|
|
13815
14195
|
lines.push(content);
|
|
@@ -13842,10 +14222,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
13842
14222
|
lines.push("");
|
|
13843
14223
|
}
|
|
13844
14224
|
}
|
|
13845
|
-
const docsDir =
|
|
14225
|
+
const docsDir = path14.join(providerDir, "../../docs");
|
|
13846
14226
|
const loadGuide = (name) => {
|
|
13847
14227
|
try {
|
|
13848
|
-
const p =
|
|
14228
|
+
const p = path14.join(docsDir, name);
|
|
13849
14229
|
if (fs10.existsSync(p)) return fs10.readFileSync(p, "utf-8");
|
|
13850
14230
|
} catch {
|
|
13851
14231
|
}
|
|
@@ -14103,8 +14483,8 @@ var DevServer = class _DevServer {
|
|
|
14103
14483
|
}
|
|
14104
14484
|
getEndpointList() {
|
|
14105
14485
|
return this.routes.map((r) => {
|
|
14106
|
-
const
|
|
14107
|
-
return `${r.method.padEnd(5)} ${
|
|
14486
|
+
const path16 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
14487
|
+
return `${r.method.padEnd(5)} ${path16}`;
|
|
14108
14488
|
});
|
|
14109
14489
|
}
|
|
14110
14490
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -14135,15 +14515,15 @@ var DevServer = class _DevServer {
|
|
|
14135
14515
|
this.json(res, 500, { error: e.message });
|
|
14136
14516
|
}
|
|
14137
14517
|
});
|
|
14138
|
-
return new Promise((
|
|
14518
|
+
return new Promise((resolve10, reject) => {
|
|
14139
14519
|
this.server.listen(port, "127.0.0.1", () => {
|
|
14140
14520
|
this.log(`Dev server listening on http://127.0.0.1:${port}`);
|
|
14141
|
-
|
|
14521
|
+
resolve10();
|
|
14142
14522
|
});
|
|
14143
14523
|
this.server.on("error", (e) => {
|
|
14144
14524
|
if (e.code === "EADDRINUSE") {
|
|
14145
14525
|
this.log(`Port ${port} in use, skipping dev server`);
|
|
14146
|
-
|
|
14526
|
+
resolve10();
|
|
14147
14527
|
} else {
|
|
14148
14528
|
reject(e);
|
|
14149
14529
|
}
|
|
@@ -14226,20 +14606,20 @@ var DevServer = class _DevServer {
|
|
|
14226
14606
|
child.stderr?.on("data", (d) => {
|
|
14227
14607
|
stderr += d.toString().slice(0, 2e3);
|
|
14228
14608
|
});
|
|
14229
|
-
await new Promise((
|
|
14609
|
+
await new Promise((resolve10) => {
|
|
14230
14610
|
const timer = setTimeout(() => {
|
|
14231
14611
|
child.kill();
|
|
14232
|
-
|
|
14612
|
+
resolve10();
|
|
14233
14613
|
}, 3e3);
|
|
14234
14614
|
child.on("exit", () => {
|
|
14235
14615
|
clearTimeout(timer);
|
|
14236
|
-
|
|
14616
|
+
resolve10();
|
|
14237
14617
|
});
|
|
14238
14618
|
child.stdout?.once("data", () => {
|
|
14239
14619
|
setTimeout(() => {
|
|
14240
14620
|
child.kill();
|
|
14241
14621
|
clearTimeout(timer);
|
|
14242
|
-
|
|
14622
|
+
resolve10();
|
|
14243
14623
|
}, 500);
|
|
14244
14624
|
});
|
|
14245
14625
|
});
|
|
@@ -14386,12 +14766,12 @@ var DevServer = class _DevServer {
|
|
|
14386
14766
|
// ─── DevConsole SPA ───
|
|
14387
14767
|
getConsoleDistDir() {
|
|
14388
14768
|
const candidates = [
|
|
14389
|
-
|
|
14390
|
-
|
|
14391
|
-
|
|
14769
|
+
path15.resolve(__dirname, "../../web-devconsole/dist"),
|
|
14770
|
+
path15.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
14771
|
+
path15.join(process.cwd(), "packages/web-devconsole/dist")
|
|
14392
14772
|
];
|
|
14393
14773
|
for (const dir of candidates) {
|
|
14394
|
-
if (fs11.existsSync(
|
|
14774
|
+
if (fs11.existsSync(path15.join(dir, "index.html"))) return dir;
|
|
14395
14775
|
}
|
|
14396
14776
|
return null;
|
|
14397
14777
|
}
|
|
@@ -14401,7 +14781,7 @@ var DevServer = class _DevServer {
|
|
|
14401
14781
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
14402
14782
|
return;
|
|
14403
14783
|
}
|
|
14404
|
-
const htmlPath =
|
|
14784
|
+
const htmlPath = path15.join(distDir, "index.html");
|
|
14405
14785
|
try {
|
|
14406
14786
|
const html = fs11.readFileSync(htmlPath, "utf-8");
|
|
14407
14787
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
@@ -14426,15 +14806,15 @@ var DevServer = class _DevServer {
|
|
|
14426
14806
|
this.json(res, 404, { error: "Not found" });
|
|
14427
14807
|
return;
|
|
14428
14808
|
}
|
|
14429
|
-
const safePath =
|
|
14430
|
-
const filePath =
|
|
14809
|
+
const safePath = path15.normalize(pathname).replace(/^\.\.\//, "");
|
|
14810
|
+
const filePath = path15.join(distDir, safePath);
|
|
14431
14811
|
if (!filePath.startsWith(distDir)) {
|
|
14432
14812
|
this.json(res, 403, { error: "Forbidden" });
|
|
14433
14813
|
return;
|
|
14434
14814
|
}
|
|
14435
14815
|
try {
|
|
14436
14816
|
const content = fs11.readFileSync(filePath);
|
|
14437
|
-
const ext =
|
|
14817
|
+
const ext = path15.extname(filePath);
|
|
14438
14818
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
14439
14819
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
14440
14820
|
res.end(content);
|
|
@@ -14547,9 +14927,9 @@ var DevServer = class _DevServer {
|
|
|
14547
14927
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
14548
14928
|
if (entry.isDirectory()) {
|
|
14549
14929
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
14550
|
-
scan(
|
|
14930
|
+
scan(path15.join(d, entry.name), rel);
|
|
14551
14931
|
} else {
|
|
14552
|
-
const stat = fs11.statSync(
|
|
14932
|
+
const stat = fs11.statSync(path15.join(d, entry.name));
|
|
14553
14933
|
files.push({ path: rel, size: stat.size, type: "file" });
|
|
14554
14934
|
}
|
|
14555
14935
|
}
|
|
@@ -14572,7 +14952,7 @@ var DevServer = class _DevServer {
|
|
|
14572
14952
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
14573
14953
|
return;
|
|
14574
14954
|
}
|
|
14575
|
-
const fullPath =
|
|
14955
|
+
const fullPath = path15.resolve(dir, path15.normalize(filePath));
|
|
14576
14956
|
if (!fullPath.startsWith(dir)) {
|
|
14577
14957
|
this.json(res, 403, { error: "Forbidden" });
|
|
14578
14958
|
return;
|
|
@@ -14597,14 +14977,14 @@ var DevServer = class _DevServer {
|
|
|
14597
14977
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
14598
14978
|
return;
|
|
14599
14979
|
}
|
|
14600
|
-
const fullPath =
|
|
14980
|
+
const fullPath = path15.resolve(dir, path15.normalize(filePath));
|
|
14601
14981
|
if (!fullPath.startsWith(dir)) {
|
|
14602
14982
|
this.json(res, 403, { error: "Forbidden" });
|
|
14603
14983
|
return;
|
|
14604
14984
|
}
|
|
14605
14985
|
try {
|
|
14606
14986
|
if (fs11.existsSync(fullPath)) fs11.copyFileSync(fullPath, fullPath + ".bak");
|
|
14607
|
-
fs11.mkdirSync(
|
|
14987
|
+
fs11.mkdirSync(path15.dirname(fullPath), { recursive: true });
|
|
14608
14988
|
fs11.writeFileSync(fullPath, content, "utf-8");
|
|
14609
14989
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
14610
14990
|
this.providerLoader.reload();
|
|
@@ -14621,7 +15001,7 @@ var DevServer = class _DevServer {
|
|
|
14621
15001
|
return;
|
|
14622
15002
|
}
|
|
14623
15003
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
14624
|
-
const p =
|
|
15004
|
+
const p = path15.join(dir, name);
|
|
14625
15005
|
if (fs11.existsSync(p)) {
|
|
14626
15006
|
const source = fs11.readFileSync(p, "utf-8");
|
|
14627
15007
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
@@ -14642,8 +15022,8 @@ var DevServer = class _DevServer {
|
|
|
14642
15022
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
14643
15023
|
return;
|
|
14644
15024
|
}
|
|
14645
|
-
const target = fs11.existsSync(
|
|
14646
|
-
const targetPath =
|
|
15025
|
+
const target = fs11.existsSync(path15.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
15026
|
+
const targetPath = path15.join(dir, target);
|
|
14647
15027
|
try {
|
|
14648
15028
|
if (fs11.existsSync(targetPath)) fs11.copyFileSync(targetPath, targetPath + ".bak");
|
|
14649
15029
|
fs11.writeFileSync(targetPath, source, "utf-8");
|
|
@@ -14748,14 +15128,14 @@ var DevServer = class _DevServer {
|
|
|
14748
15128
|
child.stderr?.on("data", (d) => {
|
|
14749
15129
|
stderr += d.toString();
|
|
14750
15130
|
});
|
|
14751
|
-
await new Promise((
|
|
15131
|
+
await new Promise((resolve10) => {
|
|
14752
15132
|
const timer = setTimeout(() => {
|
|
14753
15133
|
child.kill();
|
|
14754
|
-
|
|
15134
|
+
resolve10();
|
|
14755
15135
|
}, timeout);
|
|
14756
15136
|
child.on("exit", () => {
|
|
14757
15137
|
clearTimeout(timer);
|
|
14758
|
-
|
|
15138
|
+
resolve10();
|
|
14759
15139
|
});
|
|
14760
15140
|
});
|
|
14761
15141
|
const elapsed = Date.now() - start;
|
|
@@ -14803,7 +15183,7 @@ var DevServer = class _DevServer {
|
|
|
14803
15183
|
}
|
|
14804
15184
|
let targetDir;
|
|
14805
15185
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
14806
|
-
const jsonPath =
|
|
15186
|
+
const jsonPath = path15.join(targetDir, "provider.json");
|
|
14807
15187
|
if (fs11.existsSync(jsonPath)) {
|
|
14808
15188
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
14809
15189
|
return;
|
|
@@ -14815,8 +15195,8 @@ var DevServer = class _DevServer {
|
|
|
14815
15195
|
const createdFiles = ["provider.json"];
|
|
14816
15196
|
if (result.files) {
|
|
14817
15197
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
14818
|
-
const fullPath =
|
|
14819
|
-
fs11.mkdirSync(
|
|
15198
|
+
const fullPath = path15.join(targetDir, relPath);
|
|
15199
|
+
fs11.mkdirSync(path15.dirname(fullPath), { recursive: true });
|
|
14820
15200
|
fs11.writeFileSync(fullPath, content, "utf-8");
|
|
14821
15201
|
createdFiles.push(relPath);
|
|
14822
15202
|
}
|
|
@@ -14869,22 +15249,22 @@ var DevServer = class _DevServer {
|
|
|
14869
15249
|
if (!fs11.existsSync(scriptsDir)) return null;
|
|
14870
15250
|
const versions = fs11.readdirSync(scriptsDir).filter((d) => {
|
|
14871
15251
|
try {
|
|
14872
|
-
return fs11.statSync(
|
|
15252
|
+
return fs11.statSync(path15.join(scriptsDir, d)).isDirectory();
|
|
14873
15253
|
} catch {
|
|
14874
15254
|
return false;
|
|
14875
15255
|
}
|
|
14876
15256
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
14877
15257
|
if (versions.length === 0) return null;
|
|
14878
|
-
return
|
|
15258
|
+
return path15.join(scriptsDir, versions[0]);
|
|
14879
15259
|
}
|
|
14880
15260
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
14881
|
-
const canonicalUserDir =
|
|
14882
|
-
const desiredDir = requestedDir ?
|
|
14883
|
-
const upstreamRoot =
|
|
14884
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
15261
|
+
const canonicalUserDir = path15.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
15262
|
+
const desiredDir = requestedDir ? path15.resolve(requestedDir) : canonicalUserDir;
|
|
15263
|
+
const upstreamRoot = path15.resolve(this.providerLoader.getUpstreamDir());
|
|
15264
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path15.sep}`)) {
|
|
14885
15265
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
14886
15266
|
}
|
|
14887
|
-
if (
|
|
15267
|
+
if (path15.basename(desiredDir) !== type) {
|
|
14888
15268
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
14889
15269
|
}
|
|
14890
15270
|
const sourceDir = this.findProviderDir(type);
|
|
@@ -14892,11 +15272,11 @@ var DevServer = class _DevServer {
|
|
|
14892
15272
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
14893
15273
|
}
|
|
14894
15274
|
if (!fs11.existsSync(desiredDir)) {
|
|
14895
|
-
fs11.mkdirSync(
|
|
15275
|
+
fs11.mkdirSync(path15.dirname(desiredDir), { recursive: true });
|
|
14896
15276
|
fs11.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
14897
15277
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
14898
15278
|
}
|
|
14899
|
-
const providerJson =
|
|
15279
|
+
const providerJson = path15.join(desiredDir, "provider.json");
|
|
14900
15280
|
if (!fs11.existsSync(providerJson)) {
|
|
14901
15281
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
14902
15282
|
}
|
|
@@ -14944,7 +15324,7 @@ var DevServer = class _DevServer {
|
|
|
14944
15324
|
setMode: "set_mode.js"
|
|
14945
15325
|
};
|
|
14946
15326
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
14947
|
-
const scriptsDir =
|
|
15327
|
+
const scriptsDir = path15.join(providerDir, "scripts");
|
|
14948
15328
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
14949
15329
|
if (latestScriptsDir) {
|
|
14950
15330
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -14955,7 +15335,7 @@ var DevServer = class _DevServer {
|
|
|
14955
15335
|
for (const file of fs11.readdirSync(latestScriptsDir)) {
|
|
14956
15336
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
14957
15337
|
try {
|
|
14958
|
-
const content = fs11.readFileSync(
|
|
15338
|
+
const content = fs11.readFileSync(path15.join(latestScriptsDir, file), "utf-8");
|
|
14959
15339
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
14960
15340
|
lines.push("```javascript");
|
|
14961
15341
|
lines.push(content);
|
|
@@ -14972,7 +15352,7 @@ var DevServer = class _DevServer {
|
|
|
14972
15352
|
lines.push("");
|
|
14973
15353
|
for (const file of refFiles) {
|
|
14974
15354
|
try {
|
|
14975
|
-
const content = fs11.readFileSync(
|
|
15355
|
+
const content = fs11.readFileSync(path15.join(latestScriptsDir, file), "utf-8");
|
|
14976
15356
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
14977
15357
|
lines.push("```javascript");
|
|
14978
15358
|
lines.push(content);
|
|
@@ -15013,10 +15393,10 @@ var DevServer = class _DevServer {
|
|
|
15013
15393
|
lines.push("");
|
|
15014
15394
|
}
|
|
15015
15395
|
}
|
|
15016
|
-
const docsDir =
|
|
15396
|
+
const docsDir = path15.join(providerDir, "../../docs");
|
|
15017
15397
|
const loadGuide = (name) => {
|
|
15018
15398
|
try {
|
|
15019
|
-
const p =
|
|
15399
|
+
const p = path15.join(docsDir, name);
|
|
15020
15400
|
if (fs11.existsSync(p)) return fs11.readFileSync(p, "utf-8");
|
|
15021
15401
|
} catch {
|
|
15022
15402
|
}
|
|
@@ -15190,7 +15570,7 @@ var DevServer = class _DevServer {
|
|
|
15190
15570
|
parseApproval: "parse_approval.js"
|
|
15191
15571
|
};
|
|
15192
15572
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
15193
|
-
const scriptsDir =
|
|
15573
|
+
const scriptsDir = path15.join(providerDir, "scripts");
|
|
15194
15574
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
15195
15575
|
if (latestScriptsDir) {
|
|
15196
15576
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -15202,7 +15582,7 @@ var DevServer = class _DevServer {
|
|
|
15202
15582
|
if (!file.endsWith(".js")) continue;
|
|
15203
15583
|
if (!targetFileNames.has(file)) continue;
|
|
15204
15584
|
try {
|
|
15205
|
-
const content = fs11.readFileSync(
|
|
15585
|
+
const content = fs11.readFileSync(path15.join(latestScriptsDir, file), "utf-8");
|
|
15206
15586
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
15207
15587
|
lines.push("```javascript");
|
|
15208
15588
|
lines.push(content);
|
|
@@ -15218,7 +15598,7 @@ var DevServer = class _DevServer {
|
|
|
15218
15598
|
lines.push("");
|
|
15219
15599
|
for (const file of refFiles) {
|
|
15220
15600
|
try {
|
|
15221
|
-
const content = fs11.readFileSync(
|
|
15601
|
+
const content = fs11.readFileSync(path15.join(latestScriptsDir, file), "utf-8");
|
|
15222
15602
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
15223
15603
|
lines.push("```javascript");
|
|
15224
15604
|
lines.push(content);
|
|
@@ -15251,10 +15631,10 @@ var DevServer = class _DevServer {
|
|
|
15251
15631
|
lines.push("");
|
|
15252
15632
|
}
|
|
15253
15633
|
}
|
|
15254
|
-
const docsDir =
|
|
15634
|
+
const docsDir = path15.join(providerDir, "../../docs");
|
|
15255
15635
|
const loadGuide = (name) => {
|
|
15256
15636
|
try {
|
|
15257
|
-
const p =
|
|
15637
|
+
const p = path15.join(docsDir, name);
|
|
15258
15638
|
if (fs11.existsSync(p)) return fs11.readFileSync(p, "utf-8");
|
|
15259
15639
|
} catch {
|
|
15260
15640
|
}
|
|
@@ -15411,14 +15791,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
15411
15791
|
res.end(JSON.stringify(data, null, 2));
|
|
15412
15792
|
}
|
|
15413
15793
|
async readBody(req) {
|
|
15414
|
-
return new Promise((
|
|
15794
|
+
return new Promise((resolve10) => {
|
|
15415
15795
|
let body = "";
|
|
15416
15796
|
req.on("data", (chunk) => body += chunk);
|
|
15417
15797
|
req.on("end", () => {
|
|
15418
15798
|
try {
|
|
15419
|
-
|
|
15799
|
+
resolve10(JSON.parse(body));
|
|
15420
15800
|
} catch {
|
|
15421
|
-
|
|
15801
|
+
resolve10({});
|
|
15422
15802
|
}
|
|
15423
15803
|
});
|
|
15424
15804
|
});
|
|
@@ -15840,7 +16220,7 @@ async function waitForReady(endpoint, timeoutMs = STARTUP_TIMEOUT_MS) {
|
|
|
15840
16220
|
const deadline = Date.now() + timeoutMs;
|
|
15841
16221
|
while (Date.now() < deadline) {
|
|
15842
16222
|
if (await canConnect(endpoint)) return;
|
|
15843
|
-
await new Promise((
|
|
16223
|
+
await new Promise((resolve10) => setTimeout(resolve10, STARTUP_POLL_MS));
|
|
15844
16224
|
}
|
|
15845
16225
|
throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
|
|
15846
16226
|
}
|
|
@@ -15995,10 +16375,10 @@ async function installExtension(ide, extension) {
|
|
|
15995
16375
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
15996
16376
|
const fs12 = await import("fs");
|
|
15997
16377
|
fs12.writeFileSync(vsixPath, buffer);
|
|
15998
|
-
return new Promise((
|
|
16378
|
+
return new Promise((resolve10) => {
|
|
15999
16379
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
16000
16380
|
exec2(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
|
|
16001
|
-
|
|
16381
|
+
resolve10({
|
|
16002
16382
|
extensionId: extension.id,
|
|
16003
16383
|
marketplaceId: extension.marketplaceId,
|
|
16004
16384
|
success: !error,
|
|
@@ -16011,11 +16391,11 @@ async function installExtension(ide, extension) {
|
|
|
16011
16391
|
} catch (e) {
|
|
16012
16392
|
}
|
|
16013
16393
|
}
|
|
16014
|
-
return new Promise((
|
|
16394
|
+
return new Promise((resolve10) => {
|
|
16015
16395
|
const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
|
|
16016
16396
|
exec2(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
|
|
16017
16397
|
if (error) {
|
|
16018
|
-
|
|
16398
|
+
resolve10({
|
|
16019
16399
|
extensionId: extension.id,
|
|
16020
16400
|
marketplaceId: extension.marketplaceId,
|
|
16021
16401
|
success: false,
|
|
@@ -16023,7 +16403,7 @@ async function installExtension(ide, extension) {
|
|
|
16023
16403
|
error: stderr || error.message
|
|
16024
16404
|
});
|
|
16025
16405
|
} else {
|
|
16026
|
-
|
|
16406
|
+
resolve10({
|
|
16027
16407
|
extensionId: extension.id,
|
|
16028
16408
|
marketplaceId: extension.marketplaceId,
|
|
16029
16409
|
success: true,
|
|
@@ -16327,6 +16707,7 @@ export {
|
|
|
16327
16707
|
SessionHostPtyTransportFactory,
|
|
16328
16708
|
VersionArchive,
|
|
16329
16709
|
addCliHistory,
|
|
16710
|
+
appendRecentActivity,
|
|
16330
16711
|
buildSessionEntries,
|
|
16331
16712
|
buildStatusSnapshot,
|
|
16332
16713
|
connectCdpManager,
|
|
@@ -16340,6 +16721,7 @@ export {
|
|
|
16340
16721
|
getAvailableIdeIds,
|
|
16341
16722
|
getHostMemorySnapshot,
|
|
16342
16723
|
getLogLevel,
|
|
16724
|
+
getRecentActivity,
|
|
16343
16725
|
getRecentCommands,
|
|
16344
16726
|
getRecentLogs,
|
|
16345
16727
|
getWorkspaceActivity,
|