@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.js
CHANGED
|
@@ -163,8 +163,17 @@ function findWorkspaceByPath(config, rawPath) {
|
|
|
163
163
|
if (!abs) return void 0;
|
|
164
164
|
return (config.workspaces || []).find((w) => path.resolve(expandPath(w.path)) === abs);
|
|
165
165
|
}
|
|
166
|
-
function addWorkspaceEntry(config, rawPath, label) {
|
|
166
|
+
function addWorkspaceEntry(config, rawPath, label, options) {
|
|
167
167
|
const abs = expandPath(rawPath);
|
|
168
|
+
const createIfMissing = options?.createIfMissing === true;
|
|
169
|
+
if (!abs) return { error: "Path required" };
|
|
170
|
+
if (!fs.existsSync(abs) && createIfMissing) {
|
|
171
|
+
try {
|
|
172
|
+
fs.mkdirSync(abs, { recursive: true });
|
|
173
|
+
} catch (e) {
|
|
174
|
+
return { error: e?.message || "Could not create directory" };
|
|
175
|
+
}
|
|
176
|
+
}
|
|
168
177
|
const v = validateWorkspacePath(abs);
|
|
169
178
|
if (!v.ok) return { error: v.error };
|
|
170
179
|
const list = [...config.workspaces || []];
|
|
@@ -394,6 +403,8 @@ var init_config = __esm({
|
|
|
394
403
|
workspaces: [],
|
|
395
404
|
defaultWorkspaceId: null,
|
|
396
405
|
recentWorkspaceActivity: [],
|
|
406
|
+
recentActivity: [],
|
|
407
|
+
recentSessionReads: {},
|
|
397
408
|
machineNickname: null,
|
|
398
409
|
machineId: void 0,
|
|
399
410
|
machineSecret: null,
|
|
@@ -422,7 +433,7 @@ function checkDateRotation() {
|
|
|
422
433
|
const today = getDateStr();
|
|
423
434
|
if (today !== currentDate) {
|
|
424
435
|
currentDate = today;
|
|
425
|
-
currentLogFile =
|
|
436
|
+
currentLogFile = path4.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
426
437
|
cleanOldLogs();
|
|
427
438
|
}
|
|
428
439
|
}
|
|
@@ -436,7 +447,7 @@ function cleanOldLogs() {
|
|
|
436
447
|
const dateMatch = file.match(/daemon-(\d{4}-\d{2}-\d{2})/);
|
|
437
448
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
438
449
|
try {
|
|
439
|
-
fs2.unlinkSync(
|
|
450
|
+
fs2.unlinkSync(path4.join(LOG_DIR, file));
|
|
440
451
|
} catch {
|
|
441
452
|
}
|
|
442
453
|
}
|
|
@@ -553,17 +564,17 @@ function installGlobalInterceptor() {
|
|
|
553
564
|
writeToFile(`Log file: ${currentLogFile}`);
|
|
554
565
|
writeToFile(`Log level: ${currentLevel}`);
|
|
555
566
|
}
|
|
556
|
-
var fs2,
|
|
567
|
+
var fs2, path4, os4, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH;
|
|
557
568
|
var init_logger = __esm({
|
|
558
569
|
"src/logging/logger.ts"() {
|
|
559
570
|
"use strict";
|
|
560
571
|
fs2 = __toESM(require("fs"));
|
|
561
|
-
|
|
572
|
+
path4 = __toESM(require("path"));
|
|
562
573
|
os4 = __toESM(require("os"));
|
|
563
574
|
LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
564
575
|
LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
|
|
565
576
|
currentLevel = "info";
|
|
566
|
-
LOG_DIR = process.platform === "win32" ?
|
|
577
|
+
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");
|
|
567
578
|
MAX_LOG_SIZE = 5 * 1024 * 1024;
|
|
568
579
|
MAX_LOG_DAYS = 7;
|
|
569
580
|
try {
|
|
@@ -571,16 +582,16 @@ var init_logger = __esm({
|
|
|
571
582
|
} catch {
|
|
572
583
|
}
|
|
573
584
|
currentDate = getDateStr();
|
|
574
|
-
currentLogFile =
|
|
585
|
+
currentLogFile = path4.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
575
586
|
cleanOldLogs();
|
|
576
587
|
try {
|
|
577
|
-
const oldLog =
|
|
588
|
+
const oldLog = path4.join(LOG_DIR, "daemon.log");
|
|
578
589
|
if (fs2.existsSync(oldLog)) {
|
|
579
590
|
const stat = fs2.statSync(oldLog);
|
|
580
591
|
const oldDate = stat.mtime.toISOString().slice(0, 10);
|
|
581
|
-
fs2.renameSync(oldLog,
|
|
592
|
+
fs2.renameSync(oldLog, path4.join(LOG_DIR, `daemon-${oldDate}.log`));
|
|
582
593
|
}
|
|
583
|
-
const oldLogBackup =
|
|
594
|
+
const oldLogBackup = path4.join(LOG_DIR, "daemon.log.old");
|
|
584
595
|
if (fs2.existsSync(oldLogBackup)) {
|
|
585
596
|
fs2.unlinkSync(oldLogBackup);
|
|
586
597
|
}
|
|
@@ -612,7 +623,7 @@ var init_logger = __esm({
|
|
|
612
623
|
}
|
|
613
624
|
};
|
|
614
625
|
interceptorInstalled = false;
|
|
615
|
-
LOG_PATH =
|
|
626
|
+
LOG_PATH = path4.join(LOG_DIR, `daemon-${getDateStr()}.log`);
|
|
616
627
|
}
|
|
617
628
|
});
|
|
618
629
|
|
|
@@ -777,6 +788,12 @@ var init_xterm_backend = __esm({
|
|
|
777
788
|
});
|
|
778
789
|
|
|
779
790
|
// src/cli-adapters/terminal-screen.ts
|
|
791
|
+
function getTerminalBackendRuntimeStatus() {
|
|
792
|
+
const preference = resolveTerminalBackendPreference();
|
|
793
|
+
const ghosttyAvailable = isGhosttyVtBackendAvailable();
|
|
794
|
+
const backend = preference === "ghostty-vt" || preference === "auto" && ghosttyAvailable ? "ghostty-vt" : "xterm";
|
|
795
|
+
return { backend, preference, ghosttyAvailable };
|
|
796
|
+
}
|
|
780
797
|
function createTerminalBackend(options, preference) {
|
|
781
798
|
const ghosttyAvailable = isGhosttyVtBackendAvailable();
|
|
782
799
|
if (preference === "ghostty-vt") {
|
|
@@ -934,7 +951,7 @@ function findBinary(name) {
|
|
|
934
951
|
}
|
|
935
952
|
}
|
|
936
953
|
function isScriptBinary(binaryPath) {
|
|
937
|
-
if (!
|
|
954
|
+
if (!path10.isAbsolute(binaryPath)) return false;
|
|
938
955
|
try {
|
|
939
956
|
const fs12 = require("fs");
|
|
940
957
|
const resolved = fs12.realpathSync(binaryPath);
|
|
@@ -950,7 +967,7 @@ function isScriptBinary(binaryPath) {
|
|
|
950
967
|
}
|
|
951
968
|
}
|
|
952
969
|
function looksLikeMachOOrElf(filePath) {
|
|
953
|
-
if (!
|
|
970
|
+
if (!path10.isAbsolute(filePath)) return false;
|
|
954
971
|
try {
|
|
955
972
|
const fs12 = require("fs");
|
|
956
973
|
const resolved = fs12.realpathSync(filePath);
|
|
@@ -1064,12 +1081,12 @@ function normalizeCliProviderForRuntime(raw) {
|
|
|
1064
1081
|
}
|
|
1065
1082
|
};
|
|
1066
1083
|
}
|
|
1067
|
-
var os12,
|
|
1084
|
+
var os12, path10, import_child_process5, pty2, ProviderCliAdapter;
|
|
1068
1085
|
var init_provider_cli_adapter = __esm({
|
|
1069
1086
|
"src/cli-adapters/provider-cli-adapter.ts"() {
|
|
1070
1087
|
"use strict";
|
|
1071
1088
|
os12 = __toESM(require("os"));
|
|
1072
|
-
|
|
1089
|
+
path10 = __toESM(require("path"));
|
|
1073
1090
|
import_child_process5 = require("child_process");
|
|
1074
1091
|
init_logger();
|
|
1075
1092
|
init_terminal_screen();
|
|
@@ -1079,9 +1096,9 @@ var init_provider_cli_adapter = __esm({
|
|
|
1079
1096
|
if (os12.platform() !== "win32") {
|
|
1080
1097
|
try {
|
|
1081
1098
|
const fs12 = require("fs");
|
|
1082
|
-
const ptyDir =
|
|
1099
|
+
const ptyDir = path10.resolve(path10.dirname(require.resolve("node-pty")), "..");
|
|
1083
1100
|
const platformArch = `${os12.platform()}-${os12.arch()}`;
|
|
1084
|
-
const helper =
|
|
1101
|
+
const helper = path10.join(ptyDir, "prebuilds", platformArch, "spawn-helper");
|
|
1085
1102
|
if (fs12.existsSync(helper)) {
|
|
1086
1103
|
const stat = fs12.statSync(helper);
|
|
1087
1104
|
if (!(stat.mode & 73)) {
|
|
@@ -1270,7 +1287,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
1270
1287
|
LOG.info("CLI", `[${this.cliType}] Spawning in ${this.workingDir}`);
|
|
1271
1288
|
let shellCmd;
|
|
1272
1289
|
let shellArgs;
|
|
1273
|
-
const useShellUnix = !isWin && (!!spawnConfig.shell || !
|
|
1290
|
+
const useShellUnix = !isWin && (!!spawnConfig.shell || !path10.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
|
|
1274
1291
|
const useShell = isWin ? !!spawnConfig.shell : useShellUnix;
|
|
1275
1292
|
if (useShell) {
|
|
1276
1293
|
if (!spawnConfig.shell && !isWin) {
|
|
@@ -1695,7 +1712,7 @@ ${data.message || ""}`.trim();
|
|
|
1695
1712
|
if (this.startupParseGate) {
|
|
1696
1713
|
const deadline = Date.now() + 1e4;
|
|
1697
1714
|
while (this.startupParseGate && Date.now() < deadline) {
|
|
1698
|
-
await new Promise((
|
|
1715
|
+
await new Promise((resolve10) => setTimeout(resolve10, 50));
|
|
1699
1716
|
}
|
|
1700
1717
|
}
|
|
1701
1718
|
if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
|
|
@@ -1863,17 +1880,17 @@ ${data.message || ""}`.trim();
|
|
|
1863
1880
|
}
|
|
1864
1881
|
}
|
|
1865
1882
|
waitForStopped(timeoutMs) {
|
|
1866
|
-
return new Promise((
|
|
1883
|
+
return new Promise((resolve10) => {
|
|
1867
1884
|
const startedAt = Date.now();
|
|
1868
1885
|
const timer = setInterval(() => {
|
|
1869
1886
|
if (!this.ptyProcess || this.currentStatus === "stopped") {
|
|
1870
1887
|
clearInterval(timer);
|
|
1871
|
-
|
|
1888
|
+
resolve10(true);
|
|
1872
1889
|
return;
|
|
1873
1890
|
}
|
|
1874
1891
|
if (Date.now() - startedAt >= timeoutMs) {
|
|
1875
1892
|
clearInterval(timer);
|
|
1876
|
-
|
|
1893
|
+
resolve10(false);
|
|
1877
1894
|
}
|
|
1878
1895
|
}, 100);
|
|
1879
1896
|
});
|
|
@@ -2090,6 +2107,7 @@ __export(index_exports, {
|
|
|
2090
2107
|
SessionHostPtyTransportFactory: () => SessionHostPtyTransportFactory,
|
|
2091
2108
|
VersionArchive: () => VersionArchive,
|
|
2092
2109
|
addCliHistory: () => addCliHistory,
|
|
2110
|
+
appendRecentActivity: () => appendRecentActivity,
|
|
2093
2111
|
buildSessionEntries: () => buildSessionEntries,
|
|
2094
2112
|
buildStatusSnapshot: () => buildStatusSnapshot,
|
|
2095
2113
|
connectCdpManager: () => connectCdpManager,
|
|
@@ -2103,6 +2121,7 @@ __export(index_exports, {
|
|
|
2103
2121
|
getAvailableIdeIds: () => getAvailableIdeIds,
|
|
2104
2122
|
getHostMemorySnapshot: () => getHostMemorySnapshot,
|
|
2105
2123
|
getLogLevel: () => getLogLevel,
|
|
2124
|
+
getRecentActivity: () => getRecentActivity,
|
|
2106
2125
|
getRecentCommands: () => getRecentCommands,
|
|
2107
2126
|
getRecentLogs: () => getRecentLogs,
|
|
2108
2127
|
getWorkspaceActivity: () => getWorkspaceActivity,
|
|
@@ -2181,6 +2200,52 @@ function removeActivityForPath(config, rawPath) {
|
|
|
2181
2200
|
};
|
|
2182
2201
|
}
|
|
2183
2202
|
|
|
2203
|
+
// src/config/recent-activity.ts
|
|
2204
|
+
var path3 = __toESM(require("path"));
|
|
2205
|
+
init_workspaces();
|
|
2206
|
+
var MAX_ACTIVITY2 = 30;
|
|
2207
|
+
function normalizeWorkspace(workspace) {
|
|
2208
|
+
if (!workspace) return "";
|
|
2209
|
+
try {
|
|
2210
|
+
return path3.resolve(expandPath(workspace));
|
|
2211
|
+
} catch {
|
|
2212
|
+
return path3.resolve(workspace);
|
|
2213
|
+
}
|
|
2214
|
+
}
|
|
2215
|
+
function buildRecentActivityKey(entry) {
|
|
2216
|
+
return `${entry.kind}:${entry.providerType}:${normalizeWorkspace(entry.workspace)}`;
|
|
2217
|
+
}
|
|
2218
|
+
function appendRecentActivity(config, entry) {
|
|
2219
|
+
const nextEntry = {
|
|
2220
|
+
...entry,
|
|
2221
|
+
workspace: entry.workspace ? normalizeWorkspace(entry.workspace) : void 0,
|
|
2222
|
+
id: buildRecentActivityKey(entry),
|
|
2223
|
+
lastUsedAt: entry.lastUsedAt || Date.now()
|
|
2224
|
+
};
|
|
2225
|
+
const filtered = (config.recentActivity || []).filter((item) => item.id !== nextEntry.id);
|
|
2226
|
+
return {
|
|
2227
|
+
...config,
|
|
2228
|
+
recentActivity: [nextEntry, ...filtered].slice(0, MAX_ACTIVITY2)
|
|
2229
|
+
};
|
|
2230
|
+
}
|
|
2231
|
+
function getRecentActivity(config, limit = 20) {
|
|
2232
|
+
return [...config.recentActivity || []].sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, limit);
|
|
2233
|
+
}
|
|
2234
|
+
function getRecentSessionSeenAt(config, recentKey) {
|
|
2235
|
+
return config.recentSessionReads?.[recentKey] || 0;
|
|
2236
|
+
}
|
|
2237
|
+
function markRecentSessionSeen(config, recentKey, seenAt = Date.now()) {
|
|
2238
|
+
const prev = config.recentSessionReads || {};
|
|
2239
|
+
const nextSeenAt = Math.max(prev[recentKey] || 0, seenAt);
|
|
2240
|
+
return {
|
|
2241
|
+
...config,
|
|
2242
|
+
recentSessionReads: {
|
|
2243
|
+
...prev,
|
|
2244
|
+
[recentKey]: nextSeenAt
|
|
2245
|
+
}
|
|
2246
|
+
};
|
|
2247
|
+
}
|
|
2248
|
+
|
|
2184
2249
|
// src/detection/ide-detector.ts
|
|
2185
2250
|
var import_child_process = require("child_process");
|
|
2186
2251
|
var import_fs2 = require("fs");
|
|
@@ -2288,15 +2353,15 @@ function parseVersion(raw) {
|
|
|
2288
2353
|
return match ? match[1] : raw.split("\n")[0].slice(0, 100);
|
|
2289
2354
|
}
|
|
2290
2355
|
function execAsync(cmd, timeoutMs = 5e3) {
|
|
2291
|
-
return new Promise((
|
|
2356
|
+
return new Promise((resolve10) => {
|
|
2292
2357
|
const child = (0, import_child_process2.exec)(cmd, { encoding: "utf-8", timeout: timeoutMs }, (err, stdout) => {
|
|
2293
2358
|
if (err || !stdout?.trim()) {
|
|
2294
|
-
|
|
2359
|
+
resolve10(null);
|
|
2295
2360
|
} else {
|
|
2296
|
-
|
|
2361
|
+
resolve10(stdout.trim());
|
|
2297
2362
|
}
|
|
2298
2363
|
});
|
|
2299
|
-
child.on("error", () =>
|
|
2364
|
+
child.on("error", () => resolve10(null));
|
|
2300
2365
|
});
|
|
2301
2366
|
}
|
|
2302
2367
|
async function detectCLIs(providerLoader) {
|
|
@@ -2463,7 +2528,7 @@ var DaemonCdpManager = class {
|
|
|
2463
2528
|
* Returns multiple entries if multiple IDE windows are open on same port
|
|
2464
2529
|
*/
|
|
2465
2530
|
static listAllTargets(port) {
|
|
2466
|
-
return new Promise((
|
|
2531
|
+
return new Promise((resolve10) => {
|
|
2467
2532
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
2468
2533
|
let data = "";
|
|
2469
2534
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -2479,16 +2544,16 @@ var DaemonCdpManager = class {
|
|
|
2479
2544
|
(t) => !isNonMain(t.title || "") && t.url?.includes("workbench.html") && !t.url?.includes("agent")
|
|
2480
2545
|
);
|
|
2481
2546
|
const fallbackPages = pages.filter((t) => !isNonMain(t.title || ""));
|
|
2482
|
-
|
|
2547
|
+
resolve10(mainPages.length > 0 ? mainPages : fallbackPages);
|
|
2483
2548
|
} catch {
|
|
2484
|
-
|
|
2549
|
+
resolve10([]);
|
|
2485
2550
|
}
|
|
2486
2551
|
});
|
|
2487
2552
|
});
|
|
2488
|
-
req.on("error", () =>
|
|
2553
|
+
req.on("error", () => resolve10([]));
|
|
2489
2554
|
req.setTimeout(2e3, () => {
|
|
2490
2555
|
req.destroy();
|
|
2491
|
-
|
|
2556
|
+
resolve10([]);
|
|
2492
2557
|
});
|
|
2493
2558
|
});
|
|
2494
2559
|
}
|
|
@@ -2528,7 +2593,7 @@ var DaemonCdpManager = class {
|
|
|
2528
2593
|
}
|
|
2529
2594
|
}
|
|
2530
2595
|
findTargetOnPort(port) {
|
|
2531
|
-
return new Promise((
|
|
2596
|
+
return new Promise((resolve10) => {
|
|
2532
2597
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
2533
2598
|
let data = "";
|
|
2534
2599
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -2539,7 +2604,7 @@ var DaemonCdpManager = class {
|
|
|
2539
2604
|
(t) => (t.type === "page" || t.type === "browser" || t.type === "Page") && t.webSocketDebuggerUrl
|
|
2540
2605
|
);
|
|
2541
2606
|
if (pages.length === 0) {
|
|
2542
|
-
|
|
2607
|
+
resolve10(targets.find((t) => t.webSocketDebuggerUrl) || null);
|
|
2543
2608
|
return;
|
|
2544
2609
|
}
|
|
2545
2610
|
const mainPages = pages.filter((t) => !this.isNonMainTitle(t.title || ""));
|
|
@@ -2549,24 +2614,24 @@ var DaemonCdpManager = class {
|
|
|
2549
2614
|
const specific = list.find((t) => t.id === this._targetId);
|
|
2550
2615
|
if (specific) {
|
|
2551
2616
|
this._pageTitle = specific.title || "";
|
|
2552
|
-
|
|
2617
|
+
resolve10(specific);
|
|
2553
2618
|
} else {
|
|
2554
2619
|
this.log(`[CDP] Target ${this._targetId} not found in page list`);
|
|
2555
|
-
|
|
2620
|
+
resolve10(null);
|
|
2556
2621
|
}
|
|
2557
2622
|
return;
|
|
2558
2623
|
}
|
|
2559
2624
|
this._pageTitle = list[0]?.title || "";
|
|
2560
|
-
|
|
2625
|
+
resolve10(list[0]);
|
|
2561
2626
|
} catch {
|
|
2562
|
-
|
|
2627
|
+
resolve10(null);
|
|
2563
2628
|
}
|
|
2564
2629
|
});
|
|
2565
2630
|
});
|
|
2566
|
-
req.on("error", () =>
|
|
2631
|
+
req.on("error", () => resolve10(null));
|
|
2567
2632
|
req.setTimeout(2e3, () => {
|
|
2568
2633
|
req.destroy();
|
|
2569
|
-
|
|
2634
|
+
resolve10(null);
|
|
2570
2635
|
});
|
|
2571
2636
|
});
|
|
2572
2637
|
}
|
|
@@ -2577,7 +2642,7 @@ var DaemonCdpManager = class {
|
|
|
2577
2642
|
this.extensionProviders = providers;
|
|
2578
2643
|
}
|
|
2579
2644
|
connectToTarget(wsUrl) {
|
|
2580
|
-
return new Promise((
|
|
2645
|
+
return new Promise((resolve10) => {
|
|
2581
2646
|
this.ws = new import_ws.default(wsUrl);
|
|
2582
2647
|
this.ws.on("open", async () => {
|
|
2583
2648
|
this._connected = true;
|
|
@@ -2587,17 +2652,17 @@ var DaemonCdpManager = class {
|
|
|
2587
2652
|
}
|
|
2588
2653
|
this.connectBrowserWs().catch(() => {
|
|
2589
2654
|
});
|
|
2590
|
-
|
|
2655
|
+
resolve10(true);
|
|
2591
2656
|
});
|
|
2592
2657
|
this.ws.on("message", (data) => {
|
|
2593
2658
|
try {
|
|
2594
2659
|
const msg = JSON.parse(data.toString());
|
|
2595
2660
|
if (msg.id && this.pending.has(msg.id)) {
|
|
2596
|
-
const { resolve:
|
|
2661
|
+
const { resolve: resolve11, reject } = this.pending.get(msg.id);
|
|
2597
2662
|
this.pending.delete(msg.id);
|
|
2598
2663
|
this.failureCount = 0;
|
|
2599
2664
|
if (msg.error) reject(new Error(msg.error.message));
|
|
2600
|
-
else
|
|
2665
|
+
else resolve11(msg.result);
|
|
2601
2666
|
} else if (msg.method === "Runtime.executionContextCreated") {
|
|
2602
2667
|
this.contexts.add(msg.params.context.id);
|
|
2603
2668
|
} else if (msg.method === "Runtime.executionContextDestroyed") {
|
|
@@ -2620,7 +2685,7 @@ var DaemonCdpManager = class {
|
|
|
2620
2685
|
this.ws.on("error", (err) => {
|
|
2621
2686
|
this.log(`[CDP] WebSocket error: ${err.message}`);
|
|
2622
2687
|
this._connected = false;
|
|
2623
|
-
|
|
2688
|
+
resolve10(false);
|
|
2624
2689
|
});
|
|
2625
2690
|
});
|
|
2626
2691
|
}
|
|
@@ -2634,7 +2699,7 @@ var DaemonCdpManager = class {
|
|
|
2634
2699
|
return;
|
|
2635
2700
|
}
|
|
2636
2701
|
this.log(`[CDP] Connecting browser WS for target discovery...`);
|
|
2637
|
-
await new Promise((
|
|
2702
|
+
await new Promise((resolve10, reject) => {
|
|
2638
2703
|
this.browserWs = new import_ws.default(browserWsUrl);
|
|
2639
2704
|
this.browserWs.on("open", async () => {
|
|
2640
2705
|
this._browserConnected = true;
|
|
@@ -2644,16 +2709,16 @@ var DaemonCdpManager = class {
|
|
|
2644
2709
|
} catch (e) {
|
|
2645
2710
|
this.log(`[CDP] setDiscoverTargets failed: ${e.message}`);
|
|
2646
2711
|
}
|
|
2647
|
-
|
|
2712
|
+
resolve10();
|
|
2648
2713
|
});
|
|
2649
2714
|
this.browserWs.on("message", (data) => {
|
|
2650
2715
|
try {
|
|
2651
2716
|
const msg = JSON.parse(data.toString());
|
|
2652
2717
|
if (msg.id && this.browserPending.has(msg.id)) {
|
|
2653
|
-
const { resolve:
|
|
2718
|
+
const { resolve: resolve11, reject: reject2 } = this.browserPending.get(msg.id);
|
|
2654
2719
|
this.browserPending.delete(msg.id);
|
|
2655
2720
|
if (msg.error) reject2(new Error(msg.error.message));
|
|
2656
|
-
else
|
|
2721
|
+
else resolve11(msg.result);
|
|
2657
2722
|
}
|
|
2658
2723
|
} catch {
|
|
2659
2724
|
}
|
|
@@ -2673,31 +2738,31 @@ var DaemonCdpManager = class {
|
|
|
2673
2738
|
}
|
|
2674
2739
|
}
|
|
2675
2740
|
getBrowserWsUrl() {
|
|
2676
|
-
return new Promise((
|
|
2741
|
+
return new Promise((resolve10) => {
|
|
2677
2742
|
const req = http.get(`http://127.0.0.1:${this.port}/json/version`, (res) => {
|
|
2678
2743
|
let data = "";
|
|
2679
2744
|
res.on("data", (chunk) => data += chunk.toString());
|
|
2680
2745
|
res.on("end", () => {
|
|
2681
2746
|
try {
|
|
2682
2747
|
const info = JSON.parse(data);
|
|
2683
|
-
|
|
2748
|
+
resolve10(info.webSocketDebuggerUrl || null);
|
|
2684
2749
|
} catch {
|
|
2685
|
-
|
|
2750
|
+
resolve10(null);
|
|
2686
2751
|
}
|
|
2687
2752
|
});
|
|
2688
2753
|
});
|
|
2689
|
-
req.on("error", () =>
|
|
2754
|
+
req.on("error", () => resolve10(null));
|
|
2690
2755
|
req.setTimeout(3e3, () => {
|
|
2691
2756
|
req.destroy();
|
|
2692
|
-
|
|
2757
|
+
resolve10(null);
|
|
2693
2758
|
});
|
|
2694
2759
|
});
|
|
2695
2760
|
}
|
|
2696
2761
|
sendBrowser(method, params = {}, timeoutMs = 15e3) {
|
|
2697
|
-
return new Promise((
|
|
2762
|
+
return new Promise((resolve10, reject) => {
|
|
2698
2763
|
if (!this.browserWs || !this._browserConnected) return reject(new Error("Browser WS not connected"));
|
|
2699
2764
|
const id = this.browserMsgId++;
|
|
2700
|
-
this.browserPending.set(id, { resolve:
|
|
2765
|
+
this.browserPending.set(id, { resolve: resolve10, reject });
|
|
2701
2766
|
this.browserWs.send(JSON.stringify({ id, method, params }));
|
|
2702
2767
|
setTimeout(() => {
|
|
2703
2768
|
if (this.browserPending.has(id)) {
|
|
@@ -2737,11 +2802,11 @@ var DaemonCdpManager = class {
|
|
|
2737
2802
|
}
|
|
2738
2803
|
// ─── CDP Protocol ────────────────────────────────────────
|
|
2739
2804
|
sendInternal(method, params = {}, timeoutMs = 15e3) {
|
|
2740
|
-
return new Promise((
|
|
2805
|
+
return new Promise((resolve10, reject) => {
|
|
2741
2806
|
if (!this.ws || !this._connected) return reject(new Error("CDP not connected"));
|
|
2742
2807
|
if (this.ws.readyState !== import_ws.default.OPEN) return reject(new Error("WebSocket not open"));
|
|
2743
2808
|
const id = this.msgId++;
|
|
2744
|
-
this.pending.set(id, { resolve:
|
|
2809
|
+
this.pending.set(id, { resolve: resolve10, reject });
|
|
2745
2810
|
this.ws.send(JSON.stringify({ id, method, params }));
|
|
2746
2811
|
setTimeout(() => {
|
|
2747
2812
|
if (this.pending.has(id)) {
|
|
@@ -2990,7 +3055,7 @@ var DaemonCdpManager = class {
|
|
|
2990
3055
|
const browserWs = this.browserWs;
|
|
2991
3056
|
let msgId = this.browserMsgId;
|
|
2992
3057
|
const sendWs = (method, params = {}, sessionId) => {
|
|
2993
|
-
return new Promise((
|
|
3058
|
+
return new Promise((resolve10, reject) => {
|
|
2994
3059
|
const mid = msgId++;
|
|
2995
3060
|
this.browserMsgId = msgId;
|
|
2996
3061
|
const handler = (raw) => {
|
|
@@ -2999,7 +3064,7 @@ var DaemonCdpManager = class {
|
|
|
2999
3064
|
if (msg.id === mid) {
|
|
3000
3065
|
browserWs.removeListener("message", handler);
|
|
3001
3066
|
if (msg.error) reject(new Error(msg.error.message || JSON.stringify(msg.error)));
|
|
3002
|
-
else
|
|
3067
|
+
else resolve10(msg.result);
|
|
3003
3068
|
}
|
|
3004
3069
|
} catch {
|
|
3005
3070
|
}
|
|
@@ -3190,14 +3255,14 @@ var DaemonCdpManager = class {
|
|
|
3190
3255
|
if (!ws || ws.readyState !== import_ws.default.OPEN) {
|
|
3191
3256
|
throw new Error("CDP not connected");
|
|
3192
3257
|
}
|
|
3193
|
-
return new Promise((
|
|
3258
|
+
return new Promise((resolve10, reject) => {
|
|
3194
3259
|
const id = getNextId();
|
|
3195
3260
|
pendingMap.set(id, {
|
|
3196
3261
|
resolve: (result) => {
|
|
3197
3262
|
if (result?.result?.subtype === "error") {
|
|
3198
3263
|
reject(new Error(result.result.description));
|
|
3199
3264
|
} else {
|
|
3200
|
-
|
|
3265
|
+
resolve10(result?.result?.value);
|
|
3201
3266
|
}
|
|
3202
3267
|
},
|
|
3203
3268
|
reject
|
|
@@ -3229,10 +3294,10 @@ var DaemonCdpManager = class {
|
|
|
3229
3294
|
throw new Error("CDP not connected");
|
|
3230
3295
|
}
|
|
3231
3296
|
const sendViaSession = (method, params = {}) => {
|
|
3232
|
-
return new Promise((
|
|
3297
|
+
return new Promise((resolve10, reject) => {
|
|
3233
3298
|
const pendingMap = this._browserConnected ? this.browserPending : this.pending;
|
|
3234
3299
|
const id = this._browserConnected ? this.browserMsgId++ : this.msgId++;
|
|
3235
|
-
pendingMap.set(id, { resolve:
|
|
3300
|
+
pendingMap.set(id, { resolve: resolve10, reject });
|
|
3236
3301
|
ws.send(JSON.stringify({ id, sessionId, method, params }));
|
|
3237
3302
|
setTimeout(() => {
|
|
3238
3303
|
if (pendingMap.has(id)) {
|
|
@@ -3784,6 +3849,7 @@ var ExtensionProviderInstance = class {
|
|
|
3784
3849
|
activeModal = null;
|
|
3785
3850
|
currentModel = "";
|
|
3786
3851
|
currentMode = "";
|
|
3852
|
+
controlValues = {};
|
|
3787
3853
|
lastAgentStatus = "idle";
|
|
3788
3854
|
generatingStartedAt = 0;
|
|
3789
3855
|
monitor;
|
|
@@ -3829,6 +3895,8 @@ var ExtensionProviderInstance = class {
|
|
|
3829
3895
|
} : null,
|
|
3830
3896
|
currentModel: this.currentModel || void 0,
|
|
3831
3897
|
currentPlan: this.currentMode || void 0,
|
|
3898
|
+
controlValues: this.controlValues,
|
|
3899
|
+
providerControls: this.provider.controls,
|
|
3832
3900
|
agentStreams: this.agentStreams,
|
|
3833
3901
|
instanceId: this.instanceId,
|
|
3834
3902
|
lastUpdated: Date.now(),
|
|
@@ -3843,6 +3911,7 @@ var ExtensionProviderInstance = class {
|
|
|
3843
3911
|
if (data?.activeModal !== void 0) this.activeModal = data.activeModal;
|
|
3844
3912
|
if (data?.model) this.currentModel = data.model;
|
|
3845
3913
|
if (data?.mode) this.currentMode = data.mode;
|
|
3914
|
+
if (data?.controlValues) this.controlValues = data.controlValues;
|
|
3846
3915
|
if (typeof data?.sessionId === "string" && data.sessionId.trim()) this.chatId = data.sessionId;
|
|
3847
3916
|
if (typeof data?.title === "string" && data.title.trim()) this.chatTitle = data.title;
|
|
3848
3917
|
if (typeof data?.agentName === "string" && data.agentName.trim()) this.agentName = data.agentName;
|
|
@@ -3935,9 +4004,9 @@ var ExtensionProviderInstance = class {
|
|
|
3935
4004
|
|
|
3936
4005
|
// src/config/chat-history.ts
|
|
3937
4006
|
var fs3 = __toESM(require("fs"));
|
|
3938
|
-
var
|
|
4007
|
+
var path5 = __toESM(require("path"));
|
|
3939
4008
|
var os5 = __toESM(require("os"));
|
|
3940
|
-
var HISTORY_DIR =
|
|
4009
|
+
var HISTORY_DIR = path5.join(os5.homedir(), ".adhdev", "history");
|
|
3941
4010
|
var RETAIN_DAYS = 30;
|
|
3942
4011
|
var ChatHistoryWriter = class {
|
|
3943
4012
|
/** Last seen message count per agent (deduplication) */
|
|
@@ -3980,11 +4049,11 @@ var ChatHistoryWriter = class {
|
|
|
3980
4049
|
});
|
|
3981
4050
|
}
|
|
3982
4051
|
if (newMessages.length === 0) return;
|
|
3983
|
-
const dir =
|
|
4052
|
+
const dir = path5.join(HISTORY_DIR, this.sanitize(agentType));
|
|
3984
4053
|
fs3.mkdirSync(dir, { recursive: true });
|
|
3985
4054
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
3986
4055
|
const filePrefix = instanceId ? `${this.sanitize(instanceId)}_` : "";
|
|
3987
|
-
const filePath =
|
|
4056
|
+
const filePath = path5.join(dir, `${filePrefix}${date}.jsonl`);
|
|
3988
4057
|
const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
3989
4058
|
fs3.appendFileSync(filePath, lines, "utf-8");
|
|
3990
4059
|
const prevCount = this.lastSeenCounts.get(dedupKey) || 0;
|
|
@@ -4028,11 +4097,11 @@ ${next}`;
|
|
|
4028
4097
|
this.lastSeenTerminal.set(dedupKey, next);
|
|
4029
4098
|
return;
|
|
4030
4099
|
}
|
|
4031
|
-
const dir =
|
|
4100
|
+
const dir = path5.join(HISTORY_DIR, this.sanitize(agentType));
|
|
4032
4101
|
fs3.mkdirSync(dir, { recursive: true });
|
|
4033
4102
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
4034
4103
|
const filePrefix = instanceId ? `${this.sanitize(instanceId)}_` : "";
|
|
4035
|
-
const filePath =
|
|
4104
|
+
const filePath = path5.join(dir, `${filePrefix}${date}.terminal.log`);
|
|
4036
4105
|
fs3.appendFileSync(filePath, delta, "utf-8");
|
|
4037
4106
|
this.lastSeenTerminal.set(dedupKey, next);
|
|
4038
4107
|
if (!this.rotated) {
|
|
@@ -4056,10 +4125,10 @@ ${next}`;
|
|
|
4056
4125
|
const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
|
|
4057
4126
|
const agentDirs = fs3.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
4058
4127
|
for (const dir of agentDirs) {
|
|
4059
|
-
const dirPath =
|
|
4128
|
+
const dirPath = path5.join(HISTORY_DIR, dir.name);
|
|
4060
4129
|
const files = fs3.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
|
|
4061
4130
|
for (const file of files) {
|
|
4062
|
-
const filePath =
|
|
4131
|
+
const filePath = path5.join(dirPath, file);
|
|
4063
4132
|
const stat = fs3.statSync(filePath);
|
|
4064
4133
|
if (stat.mtimeMs < cutoff) {
|
|
4065
4134
|
fs3.unlinkSync(filePath);
|
|
@@ -4077,7 +4146,7 @@ ${next}`;
|
|
|
4077
4146
|
function readChatHistory(agentType, offset = 0, limit = 30, instanceId) {
|
|
4078
4147
|
try {
|
|
4079
4148
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
4080
|
-
const dir =
|
|
4149
|
+
const dir = path5.join(HISTORY_DIR, sanitized);
|
|
4081
4150
|
if (!fs3.existsSync(dir)) return { messages: [], hasMore: false };
|
|
4082
4151
|
const sanitizedInstance = instanceId?.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
4083
4152
|
const files = fs3.readdirSync(dir).filter((f) => {
|
|
@@ -4091,7 +4160,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, instanceId) {
|
|
|
4091
4160
|
const needed = offset + limit + 1;
|
|
4092
4161
|
for (const file of files) {
|
|
4093
4162
|
if (allMessages.length >= needed) break;
|
|
4094
|
-
const filePath =
|
|
4163
|
+
const filePath = path5.join(dir, file);
|
|
4095
4164
|
const content = fs3.readFileSync(filePath, "utf-8");
|
|
4096
4165
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
4097
4166
|
for (let i = lines.length - 1; i >= 0; i--) {
|
|
@@ -4200,6 +4269,8 @@ var IdeProviderInstance = class {
|
|
|
4200
4269
|
currentModel: this.cachedChat?.model || void 0,
|
|
4201
4270
|
currentPlan: this.cachedChat?.mode || void 0,
|
|
4202
4271
|
currentAutoApprove: this.cachedChat?.autoApprove || void 0,
|
|
4272
|
+
controlValues: this.cachedChat?.controlValues || void 0,
|
|
4273
|
+
providerControls: this.provider.controls,
|
|
4203
4274
|
instanceId: this.instanceId,
|
|
4204
4275
|
lastUpdated: Date.now(),
|
|
4205
4276
|
settings: this.settings,
|
|
@@ -4934,6 +5005,50 @@ function isCdpConnected(cdpManagers, key) {
|
|
|
4934
5005
|
const m = findCdpManager(cdpManagers, key);
|
|
4935
5006
|
return m?.isConnected ?? false;
|
|
4936
5007
|
}
|
|
5008
|
+
function buildFallbackControls(providerControls, serverModel, serverMode, acpConfigOptions, acpModes) {
|
|
5009
|
+
if (providerControls && providerControls.length > 0) return providerControls;
|
|
5010
|
+
const controls = [];
|
|
5011
|
+
const isAcp = !!(acpConfigOptions || acpModes);
|
|
5012
|
+
const modelFromAcp = acpConfigOptions?.find((c) => c.category === "model");
|
|
5013
|
+
if (!isAcp || modelFromAcp) {
|
|
5014
|
+
controls.push({
|
|
5015
|
+
id: "model",
|
|
5016
|
+
type: "select",
|
|
5017
|
+
label: "Model",
|
|
5018
|
+
icon: "\u{1F916}",
|
|
5019
|
+
placement: "bar",
|
|
5020
|
+
dynamic: !modelFromAcp,
|
|
5021
|
+
listScript: "listModels",
|
|
5022
|
+
setScript: "setModel",
|
|
5023
|
+
readFrom: "model",
|
|
5024
|
+
...modelFromAcp && {
|
|
5025
|
+
options: modelFromAcp.options.map((o) => ({ value: o.value, label: o.name || o.value }))
|
|
5026
|
+
}
|
|
5027
|
+
});
|
|
5028
|
+
}
|
|
5029
|
+
const modeFromAcp = acpModes && acpModes.length > 0;
|
|
5030
|
+
const thoughtFromAcp = !modeFromAcp && acpConfigOptions?.find((c) => c.category !== "model");
|
|
5031
|
+
if (!isAcp || modeFromAcp || thoughtFromAcp) {
|
|
5032
|
+
controls.push({
|
|
5033
|
+
id: "mode",
|
|
5034
|
+
type: thoughtFromAcp ? "cycle" : "select",
|
|
5035
|
+
label: thoughtFromAcp ? "Thinking" : "Mode",
|
|
5036
|
+
icon: thoughtFromAcp ? "\u{1F9E0}" : "\u26A1",
|
|
5037
|
+
placement: "bar",
|
|
5038
|
+
dynamic: !modeFromAcp && !thoughtFromAcp,
|
|
5039
|
+
listScript: "listModes",
|
|
5040
|
+
setScript: thoughtFromAcp ? "setThinkingLevel" : "setMode",
|
|
5041
|
+
readFrom: "mode",
|
|
5042
|
+
...modeFromAcp && {
|
|
5043
|
+
options: acpModes.map((m) => ({ value: m.id, label: m.name || m.id }))
|
|
5044
|
+
},
|
|
5045
|
+
...thoughtFromAcp && {
|
|
5046
|
+
options: thoughtFromAcp.options.map((o) => ({ value: o.value, label: o.name || o.value }))
|
|
5047
|
+
}
|
|
5048
|
+
});
|
|
5049
|
+
}
|
|
5050
|
+
return controls;
|
|
5051
|
+
}
|
|
4937
5052
|
var IDE_SESSION_CAPABILITIES = [
|
|
4938
5053
|
"read_chat",
|
|
4939
5054
|
"send_message",
|
|
@@ -4992,8 +5107,15 @@ function buildIdeWorkspaceSession(state, cdpManagers) {
|
|
|
4992
5107
|
currentModel: state.currentModel,
|
|
4993
5108
|
currentPlan: state.currentPlan,
|
|
4994
5109
|
currentAutoApprove: state.currentAutoApprove,
|
|
5110
|
+
controlValues: state.controlValues,
|
|
5111
|
+
providerControls: buildFallbackControls(
|
|
5112
|
+
state.providerControls,
|
|
5113
|
+
state.currentModel,
|
|
5114
|
+
state.currentPlan
|
|
5115
|
+
),
|
|
4995
5116
|
errorMessage: state.errorMessage,
|
|
4996
|
-
errorReason: state.errorReason
|
|
5117
|
+
errorReason: state.errorReason,
|
|
5118
|
+
lastUpdated: state.lastUpdated
|
|
4997
5119
|
};
|
|
4998
5120
|
}
|
|
4999
5121
|
function buildExtensionAgentSession(parent, ext) {
|
|
@@ -5014,8 +5136,15 @@ function buildExtensionAgentSession(parent, ext) {
|
|
|
5014
5136
|
capabilities: EXTENSION_SESSION_CAPABILITIES,
|
|
5015
5137
|
currentModel: ext.currentModel,
|
|
5016
5138
|
currentPlan: ext.currentPlan,
|
|
5139
|
+
controlValues: ext.controlValues,
|
|
5140
|
+
providerControls: buildFallbackControls(
|
|
5141
|
+
ext.providerControls,
|
|
5142
|
+
ext.currentModel,
|
|
5143
|
+
ext.currentPlan
|
|
5144
|
+
),
|
|
5017
5145
|
errorMessage: ext.errorMessage,
|
|
5018
|
-
errorReason: ext.errorReason
|
|
5146
|
+
errorReason: ext.errorReason,
|
|
5147
|
+
lastUpdated: ext.lastUpdated
|
|
5019
5148
|
};
|
|
5020
5149
|
}
|
|
5021
5150
|
function buildCliSession(state) {
|
|
@@ -5040,8 +5169,13 @@ function buildCliSession(state) {
|
|
|
5040
5169
|
resume: state.resume,
|
|
5041
5170
|
activeChat,
|
|
5042
5171
|
capabilities: PTY_SESSION_CAPABILITIES,
|
|
5172
|
+
controlValues: state.controlValues,
|
|
5173
|
+
providerControls: buildFallbackControls(
|
|
5174
|
+
state.providerControls
|
|
5175
|
+
),
|
|
5043
5176
|
errorMessage: state.errorMessage,
|
|
5044
|
-
errorReason: state.errorReason
|
|
5177
|
+
errorReason: state.errorReason,
|
|
5178
|
+
lastUpdated: state.lastUpdated
|
|
5045
5179
|
};
|
|
5046
5180
|
}
|
|
5047
5181
|
function buildAcpSession(state) {
|
|
@@ -5064,8 +5198,17 @@ function buildAcpSession(state) {
|
|
|
5064
5198
|
currentPlan: state.currentPlan,
|
|
5065
5199
|
acpConfigOptions: state.acpConfigOptions,
|
|
5066
5200
|
acpModes: state.acpModes,
|
|
5201
|
+
controlValues: state.controlValues,
|
|
5202
|
+
providerControls: buildFallbackControls(
|
|
5203
|
+
state.providerControls,
|
|
5204
|
+
state.currentModel,
|
|
5205
|
+
state.currentPlan,
|
|
5206
|
+
state.acpConfigOptions,
|
|
5207
|
+
state.acpModes
|
|
5208
|
+
),
|
|
5067
5209
|
errorMessage: state.errorMessage,
|
|
5068
|
-
errorReason: state.errorReason
|
|
5210
|
+
errorReason: state.errorReason,
|
|
5211
|
+
lastUpdated: state.lastUpdated
|
|
5069
5212
|
};
|
|
5070
5213
|
}
|
|
5071
5214
|
function buildSessionEntries(allStates, cdpManagers) {
|
|
@@ -5914,7 +6057,7 @@ async function handleResolveAction(h, args) {
|
|
|
5914
6057
|
|
|
5915
6058
|
// src/commands/cdp-commands.ts
|
|
5916
6059
|
var fs4 = __toESM(require("fs"));
|
|
5917
|
-
var
|
|
6060
|
+
var path6 = __toESM(require("path"));
|
|
5918
6061
|
var os6 = __toESM(require("os"));
|
|
5919
6062
|
var KEY_TO_VK = {
|
|
5920
6063
|
Backspace: 8,
|
|
@@ -6145,11 +6288,11 @@ function resolveSafePath(requestedPath) {
|
|
|
6145
6288
|
const home = os6.homedir();
|
|
6146
6289
|
let resolved;
|
|
6147
6290
|
if (requestedPath.startsWith("~")) {
|
|
6148
|
-
resolved =
|
|
6149
|
-
} else if (
|
|
6291
|
+
resolved = path6.join(home, requestedPath.slice(1));
|
|
6292
|
+
} else if (path6.isAbsolute(requestedPath)) {
|
|
6150
6293
|
resolved = requestedPath;
|
|
6151
6294
|
} else {
|
|
6152
|
-
resolved =
|
|
6295
|
+
resolved = path6.resolve(requestedPath);
|
|
6153
6296
|
}
|
|
6154
6297
|
return resolved;
|
|
6155
6298
|
}
|
|
@@ -6165,7 +6308,7 @@ async function handleFileRead(h, args) {
|
|
|
6165
6308
|
async function handleFileWrite(h, args) {
|
|
6166
6309
|
try {
|
|
6167
6310
|
const filePath = resolveSafePath(args?.path);
|
|
6168
|
-
fs4.mkdirSync(
|
|
6311
|
+
fs4.mkdirSync(path6.dirname(filePath), { recursive: true });
|
|
6169
6312
|
fs4.writeFileSync(filePath, args?.content || "", "utf-8");
|
|
6170
6313
|
return { success: true, path: filePath };
|
|
6171
6314
|
} catch (e) {
|
|
@@ -6179,7 +6322,7 @@ async function handleFileList(h, args) {
|
|
|
6179
6322
|
const files = entries.map((e) => ({
|
|
6180
6323
|
name: e.name,
|
|
6181
6324
|
type: e.isDirectory() ? "directory" : "file",
|
|
6182
|
-
size: e.isFile() ? fs4.statSync(
|
|
6325
|
+
size: e.isFile() ? fs4.statSync(path6.join(dirPath, e.name)).size : void 0
|
|
6183
6326
|
}));
|
|
6184
6327
|
return { success: true, files, path: dirPath };
|
|
6185
6328
|
} catch (e) {
|
|
@@ -6401,9 +6544,10 @@ function handleWorkspaceList() {
|
|
|
6401
6544
|
function handleWorkspaceAdd(args) {
|
|
6402
6545
|
const rawPath = (args?.path || args?.dir || "").trim();
|
|
6403
6546
|
const label = (args?.label || "").trim() || void 0;
|
|
6547
|
+
const createIfMissing = args?.createIfMissing === true;
|
|
6404
6548
|
if (!rawPath) return { success: false, error: "path required" };
|
|
6405
6549
|
const config = loadConfig();
|
|
6406
|
-
const result = addWorkspaceEntry(config, rawPath, label);
|
|
6550
|
+
const result = addWorkspaceEntry(config, rawPath, label, { createIfMissing });
|
|
6407
6551
|
if ("error" in result) return { success: false, error: result.error };
|
|
6408
6552
|
let cfg = appendWorkspaceActivity(result.config, result.entry.path, {});
|
|
6409
6553
|
saveConfig(cfg);
|
|
@@ -6897,7 +7041,7 @@ var DaemonCommandHandler = class {
|
|
|
6897
7041
|
try {
|
|
6898
7042
|
const http3 = await import("http");
|
|
6899
7043
|
const postData = JSON.stringify(body);
|
|
6900
|
-
const result = await new Promise((
|
|
7044
|
+
const result = await new Promise((resolve10, reject) => {
|
|
6901
7045
|
const req = http3.request({
|
|
6902
7046
|
hostname: "127.0.0.1",
|
|
6903
7047
|
port: 19280,
|
|
@@ -6909,9 +7053,9 @@ var DaemonCommandHandler = class {
|
|
|
6909
7053
|
res.on("data", (chunk) => data += chunk);
|
|
6910
7054
|
res.on("end", () => {
|
|
6911
7055
|
try {
|
|
6912
|
-
|
|
7056
|
+
resolve10(JSON.parse(data));
|
|
6913
7057
|
} catch {
|
|
6914
|
-
|
|
7058
|
+
resolve10({ raw: data });
|
|
6915
7059
|
}
|
|
6916
7060
|
});
|
|
6917
7061
|
});
|
|
@@ -6929,15 +7073,15 @@ var DaemonCommandHandler = class {
|
|
|
6929
7073
|
if (!providerType) return { success: false, error: "providerType required" };
|
|
6930
7074
|
try {
|
|
6931
7075
|
const http3 = await import("http");
|
|
6932
|
-
const result = await new Promise((
|
|
7076
|
+
const result = await new Promise((resolve10, reject) => {
|
|
6933
7077
|
http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
|
|
6934
7078
|
let data = "";
|
|
6935
7079
|
res.on("data", (chunk) => data += chunk);
|
|
6936
7080
|
res.on("end", () => {
|
|
6937
7081
|
try {
|
|
6938
|
-
|
|
7082
|
+
resolve10(JSON.parse(data));
|
|
6939
7083
|
} catch {
|
|
6940
|
-
|
|
7084
|
+
resolve10({ raw: data });
|
|
6941
7085
|
}
|
|
6942
7086
|
});
|
|
6943
7087
|
}).on("error", reject);
|
|
@@ -6951,7 +7095,7 @@ var DaemonCommandHandler = class {
|
|
|
6951
7095
|
try {
|
|
6952
7096
|
const http3 = await import("http");
|
|
6953
7097
|
const postData = JSON.stringify(args || {});
|
|
6954
|
-
const result = await new Promise((
|
|
7098
|
+
const result = await new Promise((resolve10, reject) => {
|
|
6955
7099
|
const req = http3.request({
|
|
6956
7100
|
hostname: "127.0.0.1",
|
|
6957
7101
|
port: 19280,
|
|
@@ -6963,9 +7107,9 @@ var DaemonCommandHandler = class {
|
|
|
6963
7107
|
res.on("data", (chunk) => data += chunk);
|
|
6964
7108
|
res.on("end", () => {
|
|
6965
7109
|
try {
|
|
6966
|
-
|
|
7110
|
+
resolve10(JSON.parse(data));
|
|
6967
7111
|
} catch {
|
|
6968
|
-
|
|
7112
|
+
resolve10({ raw: data });
|
|
6969
7113
|
}
|
|
6970
7114
|
});
|
|
6971
7115
|
});
|
|
@@ -6984,11 +7128,11 @@ var DaemonCommandHandler = class {
|
|
|
6984
7128
|
var import_child_process4 = require("child_process");
|
|
6985
7129
|
var net = __toESM(require("net"));
|
|
6986
7130
|
var os8 = __toESM(require("os"));
|
|
6987
|
-
var
|
|
7131
|
+
var path8 = __toESM(require("path"));
|
|
6988
7132
|
|
|
6989
7133
|
// src/providers/provider-loader.ts
|
|
6990
7134
|
var fs5 = __toESM(require("fs"));
|
|
6991
|
-
var
|
|
7135
|
+
var path7 = __toESM(require("path"));
|
|
6992
7136
|
var os7 = __toESM(require("os"));
|
|
6993
7137
|
var chokidar = __toESM(require("chokidar"));
|
|
6994
7138
|
init_logger();
|
|
@@ -7009,12 +7153,12 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7009
7153
|
static META_FILE = ".meta.json";
|
|
7010
7154
|
constructor(options) {
|
|
7011
7155
|
this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
|
|
7012
|
-
const defaultProvidersDir =
|
|
7156
|
+
const defaultProvidersDir = path7.join(os7.homedir(), ".adhdev", "providers");
|
|
7013
7157
|
if (options?.userDir) {
|
|
7014
7158
|
this.userDir = options.userDir;
|
|
7015
7159
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
7016
7160
|
} else {
|
|
7017
|
-
const localRepoPath =
|
|
7161
|
+
const localRepoPath = path7.resolve(__dirname, "../../../../../adhdev-providers");
|
|
7018
7162
|
if (fs5.existsSync(localRepoPath)) {
|
|
7019
7163
|
this.userDir = localRepoPath;
|
|
7020
7164
|
this.log(`Auto-detected local public repository: ${this.userDir} (Dev workspace speedup)`);
|
|
@@ -7023,7 +7167,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7023
7167
|
this.log(`Using default user providers directory: ${this.userDir}`);
|
|
7024
7168
|
}
|
|
7025
7169
|
}
|
|
7026
|
-
this.upstreamDir =
|
|
7170
|
+
this.upstreamDir = path7.join(defaultProvidersDir, ".upstream");
|
|
7027
7171
|
this.disableUpstream = options?.disableUpstream ?? false;
|
|
7028
7172
|
}
|
|
7029
7173
|
log(msg) {
|
|
@@ -7053,7 +7197,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7053
7197
|
* Canonical provider directory shape for a given root.
|
|
7054
7198
|
*/
|
|
7055
7199
|
getProviderDir(root, category, type) {
|
|
7056
|
-
return
|
|
7200
|
+
return path7.join(root, category, type);
|
|
7057
7201
|
}
|
|
7058
7202
|
/**
|
|
7059
7203
|
* Canonical user override directory for a provider.
|
|
@@ -7080,7 +7224,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7080
7224
|
resolveProviderFile(type, ...segments) {
|
|
7081
7225
|
const dir = this.findProviderDirInternal(type);
|
|
7082
7226
|
if (!dir) return null;
|
|
7083
|
-
return
|
|
7227
|
+
return path7.join(dir, ...segments);
|
|
7084
7228
|
}
|
|
7085
7229
|
/**
|
|
7086
7230
|
* Load all providers (3-tier priority)
|
|
@@ -7118,7 +7262,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7118
7262
|
if (!fs5.existsSync(this.upstreamDir)) return false;
|
|
7119
7263
|
try {
|
|
7120
7264
|
return fs5.readdirSync(this.upstreamDir).some(
|
|
7121
|
-
(d) => fs5.statSync(
|
|
7265
|
+
(d) => fs5.statSync(path7.join(this.upstreamDir, d)).isDirectory()
|
|
7122
7266
|
);
|
|
7123
7267
|
} catch {
|
|
7124
7268
|
return false;
|
|
@@ -7410,14 +7554,14 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7410
7554
|
this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
|
|
7411
7555
|
return null;
|
|
7412
7556
|
}
|
|
7413
|
-
const dir =
|
|
7557
|
+
const dir = path7.join(providerDir, scriptDir);
|
|
7414
7558
|
if (!fs5.existsSync(dir)) {
|
|
7415
7559
|
this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
7416
7560
|
return null;
|
|
7417
7561
|
}
|
|
7418
7562
|
const cached = this.scriptsCache.get(dir);
|
|
7419
7563
|
if (cached) return cached;
|
|
7420
|
-
const scriptsJs =
|
|
7564
|
+
const scriptsJs = path7.join(dir, "scripts.js");
|
|
7421
7565
|
if (fs5.existsSync(scriptsJs)) {
|
|
7422
7566
|
try {
|
|
7423
7567
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -7456,7 +7600,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7456
7600
|
});
|
|
7457
7601
|
const handleChange = (filePath) => {
|
|
7458
7602
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
7459
|
-
this.log(`File changed: ${
|
|
7603
|
+
this.log(`File changed: ${path7.basename(filePath)}, reloading...`);
|
|
7460
7604
|
this.reload();
|
|
7461
7605
|
}
|
|
7462
7606
|
};
|
|
@@ -7511,7 +7655,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7511
7655
|
}
|
|
7512
7656
|
const https = require("https");
|
|
7513
7657
|
const { execSync: execSync7 } = require("child_process");
|
|
7514
|
-
const metaPath =
|
|
7658
|
+
const metaPath = path7.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
7515
7659
|
let prevEtag = "";
|
|
7516
7660
|
let prevTimestamp = 0;
|
|
7517
7661
|
try {
|
|
@@ -7528,7 +7672,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7528
7672
|
return { updated: false };
|
|
7529
7673
|
}
|
|
7530
7674
|
try {
|
|
7531
|
-
const etag = await new Promise((
|
|
7675
|
+
const etag = await new Promise((resolve10, reject) => {
|
|
7532
7676
|
const options = {
|
|
7533
7677
|
method: "HEAD",
|
|
7534
7678
|
hostname: "github.com",
|
|
@@ -7546,7 +7690,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7546
7690
|
headers: { "User-Agent": "adhdev-launcher" },
|
|
7547
7691
|
timeout: 1e4
|
|
7548
7692
|
}, (res2) => {
|
|
7549
|
-
|
|
7693
|
+
resolve10(res2.headers.etag || res2.headers["last-modified"] || "");
|
|
7550
7694
|
});
|
|
7551
7695
|
req2.on("error", reject);
|
|
7552
7696
|
req2.on("timeout", () => {
|
|
@@ -7555,7 +7699,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7555
7699
|
});
|
|
7556
7700
|
req2.end();
|
|
7557
7701
|
} else {
|
|
7558
|
-
|
|
7702
|
+
resolve10(res.headers.etag || res.headers["last-modified"] || "");
|
|
7559
7703
|
}
|
|
7560
7704
|
});
|
|
7561
7705
|
req.on("error", reject);
|
|
@@ -7571,17 +7715,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7571
7715
|
return { updated: false };
|
|
7572
7716
|
}
|
|
7573
7717
|
this.log("Downloading latest providers from GitHub...");
|
|
7574
|
-
const tmpTar =
|
|
7575
|
-
const tmpExtract =
|
|
7718
|
+
const tmpTar = path7.join(os7.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
7719
|
+
const tmpExtract = path7.join(os7.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
7576
7720
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
7577
7721
|
fs5.mkdirSync(tmpExtract, { recursive: true });
|
|
7578
7722
|
execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
7579
7723
|
const extracted = fs5.readdirSync(tmpExtract);
|
|
7580
7724
|
const rootDir = extracted.find(
|
|
7581
|
-
(d) => fs5.statSync(
|
|
7725
|
+
(d) => fs5.statSync(path7.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
7582
7726
|
);
|
|
7583
7727
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
7584
|
-
const sourceDir =
|
|
7728
|
+
const sourceDir = path7.join(tmpExtract, rootDir);
|
|
7585
7729
|
const backupDir = this.upstreamDir + ".bak";
|
|
7586
7730
|
if (fs5.existsSync(this.upstreamDir)) {
|
|
7587
7731
|
if (fs5.existsSync(backupDir)) fs5.rmSync(backupDir, { recursive: true, force: true });
|
|
@@ -7619,7 +7763,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7619
7763
|
downloadFile(url, destPath) {
|
|
7620
7764
|
const https = require("https");
|
|
7621
7765
|
const http3 = require("http");
|
|
7622
|
-
return new Promise((
|
|
7766
|
+
return new Promise((resolve10, reject) => {
|
|
7623
7767
|
const doRequest = (reqUrl, redirectCount = 0) => {
|
|
7624
7768
|
if (redirectCount > 5) {
|
|
7625
7769
|
reject(new Error("Too many redirects"));
|
|
@@ -7639,7 +7783,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7639
7783
|
res.pipe(ws);
|
|
7640
7784
|
ws.on("finish", () => {
|
|
7641
7785
|
ws.close();
|
|
7642
|
-
|
|
7786
|
+
resolve10();
|
|
7643
7787
|
});
|
|
7644
7788
|
ws.on("error", reject);
|
|
7645
7789
|
});
|
|
@@ -7656,8 +7800,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7656
7800
|
copyDirRecursive(src, dest) {
|
|
7657
7801
|
fs5.mkdirSync(dest, { recursive: true });
|
|
7658
7802
|
for (const entry of fs5.readdirSync(src, { withFileTypes: true })) {
|
|
7659
|
-
const srcPath =
|
|
7660
|
-
const destPath =
|
|
7803
|
+
const srcPath = path7.join(src, entry.name);
|
|
7804
|
+
const destPath = path7.join(dest, entry.name);
|
|
7661
7805
|
if (entry.isDirectory()) {
|
|
7662
7806
|
this.copyDirRecursive(srcPath, destPath);
|
|
7663
7807
|
} else {
|
|
@@ -7668,7 +7812,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7668
7812
|
/** .meta.json save */
|
|
7669
7813
|
writeMeta(metaPath, etag, timestamp) {
|
|
7670
7814
|
try {
|
|
7671
|
-
fs5.mkdirSync(
|
|
7815
|
+
fs5.mkdirSync(path7.dirname(metaPath), { recursive: true });
|
|
7672
7816
|
fs5.writeFileSync(metaPath, JSON.stringify({
|
|
7673
7817
|
etag,
|
|
7674
7818
|
timestamp,
|
|
@@ -7685,7 +7829,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7685
7829
|
const scan = (d) => {
|
|
7686
7830
|
try {
|
|
7687
7831
|
for (const entry of fs5.readdirSync(d, { withFileTypes: true })) {
|
|
7688
|
-
if (entry.isDirectory()) scan(
|
|
7832
|
+
if (entry.isDirectory()) scan(path7.join(d, entry.name));
|
|
7689
7833
|
else if (entry.name === "provider.json") count++;
|
|
7690
7834
|
}
|
|
7691
7835
|
} catch {
|
|
@@ -7784,17 +7928,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7784
7928
|
for (const root of searchRoots) {
|
|
7785
7929
|
if (!fs5.existsSync(root)) continue;
|
|
7786
7930
|
const candidate = this.getProviderDir(root, cat, type);
|
|
7787
|
-
if (fs5.existsSync(
|
|
7788
|
-
const catDir =
|
|
7931
|
+
if (fs5.existsSync(path7.join(candidate, "provider.json"))) return candidate;
|
|
7932
|
+
const catDir = path7.join(root, cat);
|
|
7789
7933
|
if (fs5.existsSync(catDir)) {
|
|
7790
7934
|
try {
|
|
7791
7935
|
for (const entry of fs5.readdirSync(catDir, { withFileTypes: true })) {
|
|
7792
7936
|
if (!entry.isDirectory()) continue;
|
|
7793
|
-
const jsonPath =
|
|
7937
|
+
const jsonPath = path7.join(catDir, entry.name, "provider.json");
|
|
7794
7938
|
if (fs5.existsSync(jsonPath)) {
|
|
7795
7939
|
try {
|
|
7796
7940
|
const data = JSON.parse(fs5.readFileSync(jsonPath, "utf-8"));
|
|
7797
|
-
if (data.type === type) return
|
|
7941
|
+
if (data.type === type) return path7.join(catDir, entry.name);
|
|
7798
7942
|
} catch {
|
|
7799
7943
|
}
|
|
7800
7944
|
}
|
|
@@ -7811,7 +7955,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7811
7955
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
7812
7956
|
*/
|
|
7813
7957
|
buildScriptWrappersFromDir(dir) {
|
|
7814
|
-
const scriptsJs =
|
|
7958
|
+
const scriptsJs = path7.join(dir, "scripts.js");
|
|
7815
7959
|
if (fs5.existsSync(scriptsJs)) {
|
|
7816
7960
|
try {
|
|
7817
7961
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -7825,7 +7969,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7825
7969
|
for (const file of fs5.readdirSync(dir)) {
|
|
7826
7970
|
if (!file.endsWith(".js")) continue;
|
|
7827
7971
|
const scriptName = toCamel(file.replace(".js", ""));
|
|
7828
|
-
const filePath =
|
|
7972
|
+
const filePath = path7.join(dir, file);
|
|
7829
7973
|
result[scriptName] = (...args) => {
|
|
7830
7974
|
try {
|
|
7831
7975
|
let content = fs5.readFileSync(filePath, "utf-8");
|
|
@@ -7885,7 +8029,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7885
8029
|
}
|
|
7886
8030
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
7887
8031
|
if (hasJson) {
|
|
7888
|
-
const jsonPath =
|
|
8032
|
+
const jsonPath = path7.join(d, "provider.json");
|
|
7889
8033
|
try {
|
|
7890
8034
|
const raw = fs5.readFileSync(jsonPath, "utf-8");
|
|
7891
8035
|
const mod = JSON.parse(raw);
|
|
@@ -7898,7 +8042,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7898
8042
|
delete mod.extensionIdPattern_flags;
|
|
7899
8043
|
}
|
|
7900
8044
|
const hasCompatibility = Array.isArray(mod.compatibility);
|
|
7901
|
-
const scriptsPath =
|
|
8045
|
+
const scriptsPath = path7.join(d, "scripts.js");
|
|
7902
8046
|
if (!hasCompatibility && fs5.existsSync(scriptsPath)) {
|
|
7903
8047
|
try {
|
|
7904
8048
|
delete require.cache[require.resolve(scriptsPath)];
|
|
@@ -7924,7 +8068,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
7924
8068
|
if (!entry.isDirectory()) continue;
|
|
7925
8069
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
7926
8070
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
7927
|
-
scan(
|
|
8071
|
+
scan(path7.join(d, entry.name));
|
|
7928
8072
|
}
|
|
7929
8073
|
}
|
|
7930
8074
|
};
|
|
@@ -8004,17 +8148,17 @@ async function findFreePort(ports) {
|
|
|
8004
8148
|
throw new Error("No free port found");
|
|
8005
8149
|
}
|
|
8006
8150
|
function checkPortFree(port) {
|
|
8007
|
-
return new Promise((
|
|
8151
|
+
return new Promise((resolve10) => {
|
|
8008
8152
|
const server = net.createServer();
|
|
8009
8153
|
server.unref();
|
|
8010
|
-
server.on("error", () =>
|
|
8154
|
+
server.on("error", () => resolve10(false));
|
|
8011
8155
|
server.listen(port, "127.0.0.1", () => {
|
|
8012
|
-
server.close(() =>
|
|
8156
|
+
server.close(() => resolve10(true));
|
|
8013
8157
|
});
|
|
8014
8158
|
});
|
|
8015
8159
|
}
|
|
8016
8160
|
async function isCdpActive(port) {
|
|
8017
|
-
return new Promise((
|
|
8161
|
+
return new Promise((resolve10) => {
|
|
8018
8162
|
const req = require("http").get(`http://127.0.0.1:${port}/json/version`, {
|
|
8019
8163
|
timeout: 2e3
|
|
8020
8164
|
}, (res) => {
|
|
@@ -8023,16 +8167,16 @@ async function isCdpActive(port) {
|
|
|
8023
8167
|
res.on("end", () => {
|
|
8024
8168
|
try {
|
|
8025
8169
|
const info = JSON.parse(data);
|
|
8026
|
-
|
|
8170
|
+
resolve10(!!info["WebKit-Version"] || !!info["Browser"]);
|
|
8027
8171
|
} catch {
|
|
8028
|
-
|
|
8172
|
+
resolve10(false);
|
|
8029
8173
|
}
|
|
8030
8174
|
});
|
|
8031
8175
|
});
|
|
8032
|
-
req.on("error", () =>
|
|
8176
|
+
req.on("error", () => resolve10(false));
|
|
8033
8177
|
req.on("timeout", () => {
|
|
8034
8178
|
req.destroy();
|
|
8035
|
-
|
|
8179
|
+
resolve10(false);
|
|
8036
8180
|
});
|
|
8037
8181
|
});
|
|
8038
8182
|
}
|
|
@@ -8151,8 +8295,8 @@ function detectCurrentWorkspace(ideId) {
|
|
|
8151
8295
|
const appNameMap = getMacAppIdentifiers();
|
|
8152
8296
|
const appName = appNameMap[ideId];
|
|
8153
8297
|
if (appName) {
|
|
8154
|
-
const storagePath =
|
|
8155
|
-
process.env.APPDATA ||
|
|
8298
|
+
const storagePath = path8.join(
|
|
8299
|
+
process.env.APPDATA || path8.join(os8.homedir(), "AppData", "Roaming"),
|
|
8156
8300
|
appName,
|
|
8157
8301
|
"storage.json"
|
|
8158
8302
|
);
|
|
@@ -8327,9 +8471,9 @@ init_logger();
|
|
|
8327
8471
|
|
|
8328
8472
|
// src/logging/command-log.ts
|
|
8329
8473
|
var fs6 = __toESM(require("fs"));
|
|
8330
|
-
var
|
|
8474
|
+
var path9 = __toESM(require("path"));
|
|
8331
8475
|
var os9 = __toESM(require("os"));
|
|
8332
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
8476
|
+
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");
|
|
8333
8477
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
8334
8478
|
var MAX_DAYS = 7;
|
|
8335
8479
|
try {
|
|
@@ -8367,13 +8511,13 @@ function getDateStr2() {
|
|
|
8367
8511
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
8368
8512
|
}
|
|
8369
8513
|
var currentDate2 = getDateStr2();
|
|
8370
|
-
var currentFile =
|
|
8514
|
+
var currentFile = path9.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
8371
8515
|
var writeCount2 = 0;
|
|
8372
8516
|
function checkRotation() {
|
|
8373
8517
|
const today = getDateStr2();
|
|
8374
8518
|
if (today !== currentDate2) {
|
|
8375
8519
|
currentDate2 = today;
|
|
8376
|
-
currentFile =
|
|
8520
|
+
currentFile = path9.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
8377
8521
|
cleanOldFiles();
|
|
8378
8522
|
}
|
|
8379
8523
|
}
|
|
@@ -8387,7 +8531,7 @@ function cleanOldFiles() {
|
|
|
8387
8531
|
const dateMatch = file.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
8388
8532
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
8389
8533
|
try {
|
|
8390
|
-
fs6.unlinkSync(
|
|
8534
|
+
fs6.unlinkSync(path9.join(LOG_DIR2, file));
|
|
8391
8535
|
} catch {
|
|
8392
8536
|
}
|
|
8393
8537
|
}
|
|
@@ -8616,9 +8760,27 @@ var DaemonCommandRouter = class {
|
|
|
8616
8760
|
this.deps.onIdeConnected?.();
|
|
8617
8761
|
if (result.success && resolvedWorkspace) {
|
|
8618
8762
|
try {
|
|
8619
|
-
|
|
8763
|
+
let next = appendWorkspaceActivity(loadConfig(), resolvedWorkspace, {
|
|
8620
8764
|
kind: "ide",
|
|
8621
8765
|
agentType: result.ideId
|
|
8766
|
+
});
|
|
8767
|
+
next = appendRecentActivity(next, {
|
|
8768
|
+
kind: "ide",
|
|
8769
|
+
providerType: result.ideId || ideKey,
|
|
8770
|
+
providerName: result.ideId || ideKey,
|
|
8771
|
+
workspace: resolvedWorkspace,
|
|
8772
|
+
title: result.ideId || ideKey
|
|
8773
|
+
});
|
|
8774
|
+
saveConfig(next);
|
|
8775
|
+
} catch {
|
|
8776
|
+
}
|
|
8777
|
+
} else if (result.success && (result.ideId || ideKey)) {
|
|
8778
|
+
try {
|
|
8779
|
+
saveConfig(appendRecentActivity(loadConfig(), {
|
|
8780
|
+
kind: "ide",
|
|
8781
|
+
providerType: result.ideId || ideKey,
|
|
8782
|
+
providerName: result.ideId || ideKey,
|
|
8783
|
+
title: result.ideId || ideKey
|
|
8622
8784
|
}));
|
|
8623
8785
|
} catch {
|
|
8624
8786
|
}
|
|
@@ -8638,6 +8800,30 @@ var DaemonCommandRouter = class {
|
|
|
8638
8800
|
updateConfig({ userName: name });
|
|
8639
8801
|
return { success: true, userName: name };
|
|
8640
8802
|
}
|
|
8803
|
+
case "mark_recent_seen": {
|
|
8804
|
+
const kind = args?.kind;
|
|
8805
|
+
const providerType = args?.providerType;
|
|
8806
|
+
if (!kind || !providerType) {
|
|
8807
|
+
return { success: false, error: "kind and providerType are required" };
|
|
8808
|
+
}
|
|
8809
|
+
const recentKey = args?.recentKey || buildRecentActivityKey({
|
|
8810
|
+
kind,
|
|
8811
|
+
providerType,
|
|
8812
|
+
workspace: args?.workspace || null
|
|
8813
|
+
});
|
|
8814
|
+
const next = markRecentSessionSeen(
|
|
8815
|
+
loadConfig(),
|
|
8816
|
+
recentKey,
|
|
8817
|
+
typeof args?.seenAt === "number" ? args.seenAt : Date.now()
|
|
8818
|
+
);
|
|
8819
|
+
saveConfig(next);
|
|
8820
|
+
this.deps.onStatusChange?.();
|
|
8821
|
+
return {
|
|
8822
|
+
success: true,
|
|
8823
|
+
recentKey,
|
|
8824
|
+
seenAt: next.recentSessionReads?.[recentKey] || Date.now()
|
|
8825
|
+
};
|
|
8826
|
+
}
|
|
8641
8827
|
// ─── Daemon Self-Upgrade ───
|
|
8642
8828
|
case "daemon_upgrade": {
|
|
8643
8829
|
LOG.info("Upgrade", "Remote upgrade requested from dashboard");
|
|
@@ -8656,9 +8842,9 @@ var DaemonCommandRouter = class {
|
|
|
8656
8842
|
setTimeout(() => {
|
|
8657
8843
|
LOG.info("Upgrade", "Restarting daemon with new version...");
|
|
8658
8844
|
try {
|
|
8659
|
-
const
|
|
8845
|
+
const path16 = require("path");
|
|
8660
8846
|
const fs12 = require("fs");
|
|
8661
|
-
const pidFile =
|
|
8847
|
+
const pidFile = path16.join(process.env.HOME || process.env.USERPROFILE || "", ".adhdev", "daemon.pid");
|
|
8662
8848
|
if (fs12.existsSync(pidFile)) fs12.unlinkSync(pidFile);
|
|
8663
8849
|
} catch {
|
|
8664
8850
|
}
|
|
@@ -8757,6 +8943,7 @@ init_logger();
|
|
|
8757
8943
|
var os10 = __toESM(require("os"));
|
|
8758
8944
|
init_config();
|
|
8759
8945
|
init_workspaces();
|
|
8946
|
+
init_terminal_screen();
|
|
8760
8947
|
function buildDetectedIdeInfos(detectedIdes, cdpManagers) {
|
|
8761
8948
|
return detectedIdes.filter((ide) => ide.installed !== false).map((ide) => ({
|
|
8762
8949
|
id: ide.id,
|
|
@@ -8775,14 +8962,127 @@ function buildAvailableProviders(providerLoader) {
|
|
|
8775
8962
|
category: provider.category
|
|
8776
8963
|
}));
|
|
8777
8964
|
}
|
|
8965
|
+
function parseMessageTime(value) {
|
|
8966
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
8967
|
+
if (typeof value === "string") {
|
|
8968
|
+
const parsed = Date.parse(value);
|
|
8969
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
8970
|
+
}
|
|
8971
|
+
return 0;
|
|
8972
|
+
}
|
|
8973
|
+
function getSessionMessageUpdatedAt(session) {
|
|
8974
|
+
const lastMessage = session.activeChat?.messages?.at?.(-1);
|
|
8975
|
+
if (!lastMessage) return 0;
|
|
8976
|
+
return parseMessageTime(lastMessage.timestamp) || parseMessageTime(lastMessage.receivedAt) || parseMessageTime(lastMessage.createdAt) || 0;
|
|
8977
|
+
}
|
|
8978
|
+
function getSessionLastUsedAt(session) {
|
|
8979
|
+
return getSessionMessageUpdatedAt(session) || session.lastUpdated || Date.now();
|
|
8980
|
+
}
|
|
8981
|
+
function getSessionKind(session) {
|
|
8982
|
+
return session.transport === "cdp-page" || session.transport === "cdp-webview" ? "ide" : session.transport === "acp" ? "acp" : "cli";
|
|
8983
|
+
}
|
|
8984
|
+
function getLastMessageRole(session) {
|
|
8985
|
+
const role = session.activeChat?.messages?.at?.(-1)?.role;
|
|
8986
|
+
return typeof role === "string" ? role : "";
|
|
8987
|
+
}
|
|
8988
|
+
function getUnreadState(hasContentChange, status, lastUsedAt, lastSeenAt, lastRole) {
|
|
8989
|
+
if (status === "waiting_approval") {
|
|
8990
|
+
return { unread: false, inboxBucket: "needs_attention" };
|
|
8991
|
+
}
|
|
8992
|
+
if (status === "generating" || status === "starting") {
|
|
8993
|
+
return { unread: false, inboxBucket: "working" };
|
|
8994
|
+
}
|
|
8995
|
+
const unread = hasContentChange && lastUsedAt > lastSeenAt && lastRole !== "user" && lastRole !== "human";
|
|
8996
|
+
return { unread, inboxBucket: unread ? "task_complete" : "idle" };
|
|
8997
|
+
}
|
|
8998
|
+
function buildRecentSessions(sessions, recentActivity, readState) {
|
|
8999
|
+
const live = sessions.filter((session) => !session.parentId && session.status !== "stopped").map((session) => {
|
|
9000
|
+
const kind = getSessionKind(session);
|
|
9001
|
+
const recentKey = buildRecentActivityKey({
|
|
9002
|
+
kind,
|
|
9003
|
+
providerType: session.providerType,
|
|
9004
|
+
workspace: session.workspace
|
|
9005
|
+
});
|
|
9006
|
+
const lastSeenAt = readState[recentKey] || 0;
|
|
9007
|
+
const lastUsedAt = getSessionLastUsedAt(session);
|
|
9008
|
+
const { unread, inboxBucket } = getUnreadState(
|
|
9009
|
+
getSessionMessageUpdatedAt(session) > 0,
|
|
9010
|
+
session.status,
|
|
9011
|
+
lastUsedAt,
|
|
9012
|
+
lastSeenAt,
|
|
9013
|
+
getLastMessageRole(session)
|
|
9014
|
+
);
|
|
9015
|
+
return {
|
|
9016
|
+
id: session.id,
|
|
9017
|
+
recentKey,
|
|
9018
|
+
sessionId: session.id,
|
|
9019
|
+
providerType: session.providerType,
|
|
9020
|
+
providerName: session.providerName,
|
|
9021
|
+
kind,
|
|
9022
|
+
title: session.activeChat?.title || session.title || session.providerName,
|
|
9023
|
+
workspace: session.workspace,
|
|
9024
|
+
currentModel: session.currentModel,
|
|
9025
|
+
status: session.status,
|
|
9026
|
+
lastUsedAt,
|
|
9027
|
+
unread,
|
|
9028
|
+
lastSeenAt,
|
|
9029
|
+
inboxBucket
|
|
9030
|
+
};
|
|
9031
|
+
});
|
|
9032
|
+
const seen = new Set(live.map((item) => `${item.kind}:${item.providerType}:${item.workspace || ""}`));
|
|
9033
|
+
const persisted = recentActivity.filter((item) => !seen.has(`${item.kind}:${item.providerType}:${item.workspace || ""}`)).map((item) => {
|
|
9034
|
+
const lastSeenAt = readState[item.id] || 0;
|
|
9035
|
+
const unread = item.lastUsedAt > lastSeenAt;
|
|
9036
|
+
return {
|
|
9037
|
+
id: item.id,
|
|
9038
|
+
recentKey: item.id,
|
|
9039
|
+
sessionId: item.sessionId || null,
|
|
9040
|
+
providerType: item.providerType,
|
|
9041
|
+
providerName: item.providerName,
|
|
9042
|
+
kind: item.kind,
|
|
9043
|
+
title: item.title || item.providerName,
|
|
9044
|
+
workspace: item.workspace,
|
|
9045
|
+
currentModel: item.currentModel,
|
|
9046
|
+
lastUsedAt: item.lastUsedAt,
|
|
9047
|
+
unread,
|
|
9048
|
+
lastSeenAt,
|
|
9049
|
+
inboxBucket: unread ? "task_complete" : "idle"
|
|
9050
|
+
};
|
|
9051
|
+
});
|
|
9052
|
+
return [...live, ...persisted].sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, 12);
|
|
9053
|
+
}
|
|
8778
9054
|
function buildStatusSnapshot(options) {
|
|
8779
9055
|
const cfg = loadConfig();
|
|
8780
9056
|
const wsState = getWorkspaceState(cfg);
|
|
8781
9057
|
const memSnap = getHostMemorySnapshot();
|
|
9058
|
+
const recentActivity = getRecentActivity(cfg, 20);
|
|
8782
9059
|
const sessions = buildSessionEntries(
|
|
8783
9060
|
options.allStates,
|
|
8784
9061
|
options.cdpManagers
|
|
8785
9062
|
);
|
|
9063
|
+
const readState = cfg.recentSessionReads || {};
|
|
9064
|
+
for (const session of sessions) {
|
|
9065
|
+
const kind = getSessionKind(session);
|
|
9066
|
+
const recentKey = buildRecentActivityKey({
|
|
9067
|
+
kind,
|
|
9068
|
+
providerType: session.providerType,
|
|
9069
|
+
workspace: session.workspace
|
|
9070
|
+
});
|
|
9071
|
+
const lastSeenAt = getRecentSessionSeenAt(cfg, recentKey);
|
|
9072
|
+
const lastUsedAt = getSessionLastUsedAt(session);
|
|
9073
|
+
const { unread, inboxBucket } = getUnreadState(
|
|
9074
|
+
getSessionMessageUpdatedAt(session) > 0,
|
|
9075
|
+
session.status,
|
|
9076
|
+
lastUsedAt,
|
|
9077
|
+
lastSeenAt,
|
|
9078
|
+
getLastMessageRole(session)
|
|
9079
|
+
);
|
|
9080
|
+
session.recentKey = recentKey;
|
|
9081
|
+
session.lastSeenAt = lastSeenAt;
|
|
9082
|
+
session.unread = unread;
|
|
9083
|
+
session.inboxBucket = inboxBucket;
|
|
9084
|
+
}
|
|
9085
|
+
const terminalBackend = getTerminalBackendRuntimeStatus();
|
|
8786
9086
|
return {
|
|
8787
9087
|
instanceId: options.instanceId,
|
|
8788
9088
|
version: options.version,
|
|
@@ -8808,6 +9108,8 @@ function buildStatusSnapshot(options) {
|
|
|
8808
9108
|
defaultWorkspaceId: wsState.defaultWorkspaceId,
|
|
8809
9109
|
defaultWorkspacePath: wsState.defaultWorkspacePath,
|
|
8810
9110
|
workspaceActivity: getWorkspaceActivity(cfg, 15),
|
|
9111
|
+
recentSessions: buildRecentSessions(sessions, recentActivity, readState),
|
|
9112
|
+
terminalBackend,
|
|
8811
9113
|
availableProviders: buildAvailableProviders(options.providerLoader)
|
|
8812
9114
|
};
|
|
8813
9115
|
}
|
|
@@ -8959,7 +9261,15 @@ var DaemonStatusReporter = class {
|
|
|
8959
9261
|
cdpConnected: session.cdpConnected,
|
|
8960
9262
|
currentModel: session.currentModel,
|
|
8961
9263
|
currentPlan: session.currentPlan,
|
|
8962
|
-
currentAutoApprove: session.currentAutoApprove
|
|
9264
|
+
currentAutoApprove: session.currentAutoApprove,
|
|
9265
|
+
recentKey: session.recentKey,
|
|
9266
|
+
unread: session.unread,
|
|
9267
|
+
lastSeenAt: session.lastSeenAt,
|
|
9268
|
+
inboxBucket: session.inboxBucket,
|
|
9269
|
+
controlValues: session.controlValues,
|
|
9270
|
+
providerControls: session.providerControls,
|
|
9271
|
+
acpConfigOptions: session.acpConfigOptions,
|
|
9272
|
+
acpModes: session.acpModes
|
|
8963
9273
|
})),
|
|
8964
9274
|
p2p: payload.p2p,
|
|
8965
9275
|
timestamp: now
|
|
@@ -8997,7 +9307,7 @@ init_logger();
|
|
|
8997
9307
|
|
|
8998
9308
|
// src/commands/cli-manager.ts
|
|
8999
9309
|
var os13 = __toESM(require("os"));
|
|
9000
|
-
var
|
|
9310
|
+
var path11 = __toESM(require("path"));
|
|
9001
9311
|
var crypto4 = __toESM(require("crypto"));
|
|
9002
9312
|
var import_chalk = __toESM(require("chalk"));
|
|
9003
9313
|
init_provider_cli_adapter();
|
|
@@ -9095,7 +9405,10 @@ var CliProviderInstance = class {
|
|
|
9095
9405
|
writeOwner: runtime.writeOwner || null,
|
|
9096
9406
|
attachedClients: runtime.attachedClients || []
|
|
9097
9407
|
} : void 0,
|
|
9098
|
-
resume: this.provider.resume
|
|
9408
|
+
resume: this.provider.resume,
|
|
9409
|
+
controlValues: void 0,
|
|
9410
|
+
// CLI controls not yet wired from stream
|
|
9411
|
+
providerControls: this.provider.controls
|
|
9099
9412
|
};
|
|
9100
9413
|
}
|
|
9101
9414
|
onEvent(event, data) {
|
|
@@ -9371,7 +9684,12 @@ var AcpProviderInstance = class {
|
|
|
9371
9684
|
acpModes: this.availableModes,
|
|
9372
9685
|
// Error details for dashboard display
|
|
9373
9686
|
errorMessage: this.errorMessage || void 0,
|
|
9374
|
-
errorReason: this.errorReason || void 0
|
|
9687
|
+
errorReason: this.errorReason || void 0,
|
|
9688
|
+
controlValues: {
|
|
9689
|
+
...this.currentModel ? { model: this.currentModel } : {},
|
|
9690
|
+
...this.currentMode ? { mode: this.currentMode } : {}
|
|
9691
|
+
},
|
|
9692
|
+
providerControls: this.provider.controls
|
|
9375
9693
|
};
|
|
9376
9694
|
}
|
|
9377
9695
|
onEvent(event, data) {
|
|
@@ -9670,13 +9988,13 @@ var AcpProviderInstance = class {
|
|
|
9670
9988
|
}
|
|
9671
9989
|
this.currentStatus = "waiting_approval";
|
|
9672
9990
|
this.detectStatusTransition();
|
|
9673
|
-
const approved = await new Promise((
|
|
9674
|
-
this.permissionResolvers.push(
|
|
9991
|
+
const approved = await new Promise((resolve10) => {
|
|
9992
|
+
this.permissionResolvers.push(resolve10);
|
|
9675
9993
|
setTimeout(() => {
|
|
9676
|
-
const idx = this.permissionResolvers.indexOf(
|
|
9994
|
+
const idx = this.permissionResolvers.indexOf(resolve10);
|
|
9677
9995
|
if (idx >= 0) {
|
|
9678
9996
|
this.permissionResolvers.splice(idx, 1);
|
|
9679
|
-
|
|
9997
|
+
resolve10(false);
|
|
9680
9998
|
}
|
|
9681
9999
|
}, 3e5);
|
|
9682
10000
|
});
|
|
@@ -10169,6 +10487,13 @@ var DaemonCliManager = class {
|
|
|
10169
10487
|
console.error(colorize("red", ` \u2717 Failed to save recent workspace: ${e}`));
|
|
10170
10488
|
}
|
|
10171
10489
|
}
|
|
10490
|
+
persistRecentActivity(entry) {
|
|
10491
|
+
try {
|
|
10492
|
+
saveConfig(appendRecentActivity(loadConfig(), entry));
|
|
10493
|
+
} catch (e) {
|
|
10494
|
+
console.error(colorize("red", ` \u2717 Failed to save recent activity: ${e}`));
|
|
10495
|
+
}
|
|
10496
|
+
}
|
|
10172
10497
|
getTransportFactory(runtimeId, providerType, workspace, cliArgs, attachExisting = false) {
|
|
10173
10498
|
return this.deps.createPtyTransportFactory?.({
|
|
10174
10499
|
runtimeId,
|
|
@@ -10251,7 +10576,7 @@ var DaemonCliManager = class {
|
|
|
10251
10576
|
async startSession(cliType, workingDir, cliArgs, initialModel) {
|
|
10252
10577
|
const trimmed = (workingDir || "").trim();
|
|
10253
10578
|
if (!trimmed) throw new Error("working directory required");
|
|
10254
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) :
|
|
10579
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path11.resolve(trimmed);
|
|
10255
10580
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
10256
10581
|
const provider = this.providerLoader.getByAlias(cliType);
|
|
10257
10582
|
const key = crypto4.randomUUID();
|
|
@@ -10327,6 +10652,15 @@ ${installInfo}`
|
|
|
10327
10652
|
} catch (e) {
|
|
10328
10653
|
LOG.warn("CLI", `ACP history save failed: ${e?.message}`);
|
|
10329
10654
|
}
|
|
10655
|
+
this.persistRecentActivity({
|
|
10656
|
+
kind: "acp",
|
|
10657
|
+
providerType: normalizedType,
|
|
10658
|
+
providerName: provider.displayName || provider.name || normalizedType,
|
|
10659
|
+
workspace: resolvedDir,
|
|
10660
|
+
currentModel: initialModel,
|
|
10661
|
+
sessionId,
|
|
10662
|
+
title: provider.displayName || provider.name || normalizedType
|
|
10663
|
+
});
|
|
10330
10664
|
this.deps.onStatusChange();
|
|
10331
10665
|
return;
|
|
10332
10666
|
}
|
|
@@ -10389,6 +10723,15 @@ ${installInfo}`
|
|
|
10389
10723
|
} catch (e) {
|
|
10390
10724
|
LOG.warn("CLI", `CLI history save failed: ${e?.message}`);
|
|
10391
10725
|
}
|
|
10726
|
+
this.persistRecentActivity({
|
|
10727
|
+
kind: "cli",
|
|
10728
|
+
providerType: normalizedType,
|
|
10729
|
+
providerName: provider?.displayName || provider?.name || normalizedType,
|
|
10730
|
+
workspace: resolvedDir,
|
|
10731
|
+
currentModel: initialModel,
|
|
10732
|
+
sessionId: key,
|
|
10733
|
+
title: provider?.displayName || provider?.name || normalizedType
|
|
10734
|
+
});
|
|
10392
10735
|
this.deps.onStatusChange();
|
|
10393
10736
|
}
|
|
10394
10737
|
async stopSession(key) {
|
|
@@ -10634,11 +10977,24 @@ var ProviderStreamAdapter = class {
|
|
|
10634
10977
|
hasScript(name) {
|
|
10635
10978
|
return typeof this.provider.scripts?.[name] === "function";
|
|
10636
10979
|
}
|
|
10980
|
+
summarizeRaw(raw) {
|
|
10981
|
+
try {
|
|
10982
|
+
if (typeof raw === "string") return raw.replace(/\s+/g, " ").trim().slice(0, 240);
|
|
10983
|
+
if (raw == null) return String(raw);
|
|
10984
|
+
return JSON.stringify(raw).replace(/\s+/g, " ").trim().slice(0, 240);
|
|
10985
|
+
} catch {
|
|
10986
|
+
return Object.prototype.toString.call(raw);
|
|
10987
|
+
}
|
|
10988
|
+
}
|
|
10989
|
+
isTransportError(reason) {
|
|
10990
|
+
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);
|
|
10991
|
+
}
|
|
10637
10992
|
async readChat(evaluate) {
|
|
10638
10993
|
const script = this.callScript("readChat");
|
|
10639
10994
|
if (!script) return this.errorState("readChat script not available");
|
|
10995
|
+
let raw = null;
|
|
10640
10996
|
try {
|
|
10641
|
-
|
|
10997
|
+
raw = await evaluate(script);
|
|
10642
10998
|
const data = typeof raw === "string" ? JSON.parse(raw) : raw;
|
|
10643
10999
|
if (data?.error) {
|
|
10644
11000
|
const state2 = this.errorState(data.error);
|
|
@@ -10658,12 +11014,31 @@ var ProviderStreamAdapter = class {
|
|
|
10658
11014
|
mode: data.mode,
|
|
10659
11015
|
activeModal: data.activeModal
|
|
10660
11016
|
};
|
|
11017
|
+
if (this.provider.controls?.length) {
|
|
11018
|
+
const cv = {};
|
|
11019
|
+
for (const ctrl of this.provider.controls) {
|
|
11020
|
+
if (!ctrl.readFrom) continue;
|
|
11021
|
+
const val = data[ctrl.readFrom];
|
|
11022
|
+
if (val !== void 0 && val !== null) {
|
|
11023
|
+
cv[ctrl.id] = typeof val === "object" ? val.name || val.id || String(val) : val;
|
|
11024
|
+
}
|
|
11025
|
+
}
|
|
11026
|
+
if (data.model && !cv["model"]) cv["model"] = data.model;
|
|
11027
|
+
if (data.mode && !cv["mode"]) cv["mode"] = data.mode;
|
|
11028
|
+
if (Object.keys(cv).length > 0) state.controlValues = cv;
|
|
11029
|
+
}
|
|
10661
11030
|
if (state.messages.length > 0) {
|
|
10662
11031
|
this.lastSuccessState = state;
|
|
10663
11032
|
}
|
|
10664
11033
|
return state;
|
|
10665
|
-
} catch {
|
|
10666
|
-
const
|
|
11034
|
+
} catch (error) {
|
|
11035
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
11036
|
+
if (this.isTransportError(reason)) {
|
|
11037
|
+
throw error instanceof Error ? error : new Error(reason);
|
|
11038
|
+
}
|
|
11039
|
+
const preview = this.summarizeRaw(raw);
|
|
11040
|
+
const detail = preview ? ` (reason=${reason}; raw=${preview})` : ` (reason=${reason})`;
|
|
11041
|
+
const state = this.errorState(`Failed to parse ${this.agentName} state${detail}`);
|
|
10667
11042
|
if (this.lastSuccessState?.messages?.length) {
|
|
10668
11043
|
state.messages = this.lastSuccessState.messages;
|
|
10669
11044
|
}
|
|
@@ -10760,6 +11135,9 @@ var DaemonAgentStreamManager = class {
|
|
|
10760
11135
|
getActiveSessionId(parentSessionId) {
|
|
10761
11136
|
return this.activeSessionIdByParent.get(parentSessionId) || null;
|
|
10762
11137
|
}
|
|
11138
|
+
isRecoverableSessionError(message) {
|
|
11139
|
+
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");
|
|
11140
|
+
}
|
|
10763
11141
|
getSessionTarget(sessionId) {
|
|
10764
11142
|
return this.sessionRegistry?.get(sessionId);
|
|
10765
11143
|
}
|
|
@@ -10861,6 +11239,10 @@ var DaemonAgentStreamManager = class {
|
|
|
10861
11239
|
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
|
|
10862
11240
|
const state = await agent.adapter.readChat(evaluate);
|
|
10863
11241
|
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") : ""}`);
|
|
11242
|
+
const stateError = String(state.error || state._error || "");
|
|
11243
|
+
if (state.status === "error" && this.isRecoverableSessionError(stateError)) {
|
|
11244
|
+
throw new Error(stateError);
|
|
11245
|
+
}
|
|
10864
11246
|
agent.lastState = state;
|
|
10865
11247
|
agent.lastError = null;
|
|
10866
11248
|
if (state.status === "panel_hidden") {
|
|
@@ -10871,7 +11253,7 @@ var DaemonAgentStreamManager = class {
|
|
|
10871
11253
|
const errorMsg = e?.message || String(e);
|
|
10872
11254
|
this.logFn(`[AgentStream] readChat(${type}) error: ${errorMsg.slice(0, 200)}`);
|
|
10873
11255
|
agent.lastError = errorMsg;
|
|
10874
|
-
if (
|
|
11256
|
+
if (this.isRecoverableSessionError(errorMsg)) {
|
|
10875
11257
|
try {
|
|
10876
11258
|
await cdp.detachAgent(agent.cdpSessionId);
|
|
10877
11259
|
} catch {
|
|
@@ -11359,11 +11741,11 @@ var ProviderInstanceManager = class {
|
|
|
11359
11741
|
|
|
11360
11742
|
// src/providers/version-archive.ts
|
|
11361
11743
|
var fs8 = __toESM(require("fs"));
|
|
11362
|
-
var
|
|
11744
|
+
var path12 = __toESM(require("path"));
|
|
11363
11745
|
var os14 = __toESM(require("os"));
|
|
11364
11746
|
var import_child_process7 = require("child_process");
|
|
11365
11747
|
var import_os3 = require("os");
|
|
11366
|
-
var ARCHIVE_PATH =
|
|
11748
|
+
var ARCHIVE_PATH = path12.join(os14.homedir(), ".adhdev", "version-history.json");
|
|
11367
11749
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
11368
11750
|
var VersionArchive = class {
|
|
11369
11751
|
history = {};
|
|
@@ -11410,7 +11792,7 @@ var VersionArchive = class {
|
|
|
11410
11792
|
}
|
|
11411
11793
|
save() {
|
|
11412
11794
|
try {
|
|
11413
|
-
fs8.mkdirSync(
|
|
11795
|
+
fs8.mkdirSync(path12.dirname(ARCHIVE_PATH), { recursive: true });
|
|
11414
11796
|
fs8.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
11415
11797
|
} catch {
|
|
11416
11798
|
}
|
|
@@ -11451,7 +11833,7 @@ function checkPathExists2(paths) {
|
|
|
11451
11833
|
for (const p of paths) {
|
|
11452
11834
|
if (p.includes("*")) {
|
|
11453
11835
|
const home = os14.homedir();
|
|
11454
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
11836
|
+
const resolved = p.replace(/\*/g, home.split(path12.sep).pop() || "");
|
|
11455
11837
|
if (fs8.existsSync(resolved)) return resolved;
|
|
11456
11838
|
} else {
|
|
11457
11839
|
if (fs8.existsSync(p)) return p;
|
|
@@ -11461,7 +11843,7 @@ function checkPathExists2(paths) {
|
|
|
11461
11843
|
}
|
|
11462
11844
|
function getMacAppVersion(appPath) {
|
|
11463
11845
|
if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
11464
|
-
const plistPath =
|
|
11846
|
+
const plistPath = path12.join(appPath, "Contents", "Info.plist");
|
|
11465
11847
|
if (!fs8.existsSync(plistPath)) return null;
|
|
11466
11848
|
const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
11467
11849
|
return raw || null;
|
|
@@ -11488,7 +11870,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
11488
11870
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
11489
11871
|
let resolvedBin = cliBin;
|
|
11490
11872
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
11491
|
-
const bundled =
|
|
11873
|
+
const bundled = path12.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
11492
11874
|
if (provider.cli && fs8.existsSync(bundled)) resolvedBin = bundled;
|
|
11493
11875
|
}
|
|
11494
11876
|
info.installed = !!(appPath || resolvedBin);
|
|
@@ -11529,7 +11911,7 @@ async function detectAllVersions(loader, archive) {
|
|
|
11529
11911
|
// src/daemon/dev-server.ts
|
|
11530
11912
|
var http2 = __toESM(require("http"));
|
|
11531
11913
|
var fs11 = __toESM(require("fs"));
|
|
11532
|
-
var
|
|
11914
|
+
var path15 = __toESM(require("path"));
|
|
11533
11915
|
|
|
11534
11916
|
// src/daemon/scaffold-template.ts
|
|
11535
11917
|
function generateFiles(type, name, category, opts = {}) {
|
|
@@ -11865,7 +12247,7 @@ init_logger();
|
|
|
11865
12247
|
|
|
11866
12248
|
// src/daemon/dev-cdp-handlers.ts
|
|
11867
12249
|
var fs9 = __toESM(require("fs"));
|
|
11868
|
-
var
|
|
12250
|
+
var path13 = __toESM(require("path"));
|
|
11869
12251
|
init_logger();
|
|
11870
12252
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
11871
12253
|
const body = await ctx.readBody(req);
|
|
@@ -12044,17 +12426,17 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
12044
12426
|
return;
|
|
12045
12427
|
}
|
|
12046
12428
|
let scriptsPath = "";
|
|
12047
|
-
const directScripts =
|
|
12429
|
+
const directScripts = path13.join(dir, "scripts.js");
|
|
12048
12430
|
if (fs9.existsSync(directScripts)) {
|
|
12049
12431
|
scriptsPath = directScripts;
|
|
12050
12432
|
} else {
|
|
12051
|
-
const scriptsDir =
|
|
12433
|
+
const scriptsDir = path13.join(dir, "scripts");
|
|
12052
12434
|
if (fs9.existsSync(scriptsDir)) {
|
|
12053
12435
|
const versions = fs9.readdirSync(scriptsDir).filter((d) => {
|
|
12054
|
-
return fs9.statSync(
|
|
12436
|
+
return fs9.statSync(path13.join(scriptsDir, d)).isDirectory();
|
|
12055
12437
|
}).sort().reverse();
|
|
12056
12438
|
for (const ver of versions) {
|
|
12057
|
-
const p =
|
|
12439
|
+
const p = path13.join(scriptsDir, ver, "scripts.js");
|
|
12058
12440
|
if (fs9.existsSync(p)) {
|
|
12059
12441
|
scriptsPath = p;
|
|
12060
12442
|
break;
|
|
@@ -13109,7 +13491,7 @@ async function handleCliRaw(ctx, req, res) {
|
|
|
13109
13491
|
|
|
13110
13492
|
// src/daemon/dev-auto-implement.ts
|
|
13111
13493
|
var fs10 = __toESM(require("fs"));
|
|
13112
|
-
var
|
|
13494
|
+
var path14 = __toESM(require("path"));
|
|
13113
13495
|
var os15 = __toESM(require("os"));
|
|
13114
13496
|
function getDefaultAutoImplReference(ctx, category, type) {
|
|
13115
13497
|
if (category === "cli") {
|
|
@@ -13129,22 +13511,22 @@ function getLatestScriptVersionDir(scriptsDir) {
|
|
|
13129
13511
|
if (!fs10.existsSync(scriptsDir)) return null;
|
|
13130
13512
|
const versions = fs10.readdirSync(scriptsDir).filter((d) => {
|
|
13131
13513
|
try {
|
|
13132
|
-
return fs10.statSync(
|
|
13514
|
+
return fs10.statSync(path14.join(scriptsDir, d)).isDirectory();
|
|
13133
13515
|
} catch {
|
|
13134
13516
|
return false;
|
|
13135
13517
|
}
|
|
13136
13518
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
13137
13519
|
if (versions.length === 0) return null;
|
|
13138
|
-
return
|
|
13520
|
+
return path14.join(scriptsDir, versions[0]);
|
|
13139
13521
|
}
|
|
13140
13522
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
13141
|
-
const canonicalUserDir =
|
|
13142
|
-
const desiredDir = requestedDir ?
|
|
13143
|
-
const upstreamRoot =
|
|
13144
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
13523
|
+
const canonicalUserDir = path14.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
13524
|
+
const desiredDir = requestedDir ? path14.resolve(requestedDir) : canonicalUserDir;
|
|
13525
|
+
const upstreamRoot = path14.resolve(ctx.providerLoader.getUpstreamDir());
|
|
13526
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path14.sep}`)) {
|
|
13145
13527
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
13146
13528
|
}
|
|
13147
|
-
if (
|
|
13529
|
+
if (path14.basename(desiredDir) !== type) {
|
|
13148
13530
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
13149
13531
|
}
|
|
13150
13532
|
const sourceDir = ctx.findProviderDir(type);
|
|
@@ -13152,11 +13534,11 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
|
13152
13534
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
13153
13535
|
}
|
|
13154
13536
|
if (!fs10.existsSync(desiredDir)) {
|
|
13155
|
-
fs10.mkdirSync(
|
|
13537
|
+
fs10.mkdirSync(path14.dirname(desiredDir), { recursive: true });
|
|
13156
13538
|
fs10.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
13157
13539
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
13158
13540
|
}
|
|
13159
|
-
const providerJson =
|
|
13541
|
+
const providerJson = path14.join(desiredDir, "provider.json");
|
|
13160
13542
|
if (!fs10.existsSync(providerJson)) {
|
|
13161
13543
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
13162
13544
|
}
|
|
@@ -13179,13 +13561,13 @@ function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
|
13179
13561
|
const refDir = ctx.findProviderDir(referenceType);
|
|
13180
13562
|
if (!refDir || !fs10.existsSync(refDir)) return {};
|
|
13181
13563
|
const referenceScripts = {};
|
|
13182
|
-
const scriptsDir =
|
|
13564
|
+
const scriptsDir = path14.join(refDir, "scripts");
|
|
13183
13565
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
13184
13566
|
if (!latestDir) return referenceScripts;
|
|
13185
13567
|
for (const file of fs10.readdirSync(latestDir)) {
|
|
13186
13568
|
if (!file.endsWith(".js")) continue;
|
|
13187
13569
|
try {
|
|
13188
|
-
referenceScripts[file] = fs10.readFileSync(
|
|
13570
|
+
referenceScripts[file] = fs10.readFileSync(path14.join(latestDir, file), "utf-8");
|
|
13189
13571
|
} catch {
|
|
13190
13572
|
}
|
|
13191
13573
|
}
|
|
@@ -13236,9 +13618,9 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
13236
13618
|
});
|
|
13237
13619
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
13238
13620
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference);
|
|
13239
|
-
const tmpDir =
|
|
13621
|
+
const tmpDir = path14.join(os15.tmpdir(), "adhdev-autoimpl");
|
|
13240
13622
|
if (!fs10.existsSync(tmpDir)) fs10.mkdirSync(tmpDir, { recursive: true });
|
|
13241
|
-
const promptFile =
|
|
13623
|
+
const promptFile = path14.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
13242
13624
|
fs10.writeFileSync(promptFile, prompt, "utf-8");
|
|
13243
13625
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
13244
13626
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
@@ -13609,7 +13991,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
13609
13991
|
setMode: "set_mode.js"
|
|
13610
13992
|
};
|
|
13611
13993
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
13612
|
-
const scriptsDir =
|
|
13994
|
+
const scriptsDir = path14.join(providerDir, "scripts");
|
|
13613
13995
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
13614
13996
|
if (latestScriptsDir) {
|
|
13615
13997
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -13620,7 +14002,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
13620
14002
|
for (const file of fs10.readdirSync(latestScriptsDir)) {
|
|
13621
14003
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
13622
14004
|
try {
|
|
13623
|
-
const content = fs10.readFileSync(
|
|
14005
|
+
const content = fs10.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
|
|
13624
14006
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
13625
14007
|
lines.push("```javascript");
|
|
13626
14008
|
lines.push(content);
|
|
@@ -13637,7 +14019,7 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
13637
14019
|
lines.push("");
|
|
13638
14020
|
for (const file of refFiles) {
|
|
13639
14021
|
try {
|
|
13640
|
-
const content = fs10.readFileSync(
|
|
14022
|
+
const content = fs10.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
|
|
13641
14023
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
13642
14024
|
lines.push("```javascript");
|
|
13643
14025
|
lines.push(content);
|
|
@@ -13678,10 +14060,10 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
13678
14060
|
lines.push("");
|
|
13679
14061
|
}
|
|
13680
14062
|
}
|
|
13681
|
-
const docsDir =
|
|
14063
|
+
const docsDir = path14.join(providerDir, "../../docs");
|
|
13682
14064
|
const loadGuide = (name) => {
|
|
13683
14065
|
try {
|
|
13684
|
-
const p =
|
|
14066
|
+
const p = path14.join(docsDir, name);
|
|
13685
14067
|
if (fs10.existsSync(p)) return fs10.readFileSync(p, "utf-8");
|
|
13686
14068
|
} catch {
|
|
13687
14069
|
}
|
|
@@ -13855,7 +14237,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
13855
14237
|
parseApproval: "parse_approval.js"
|
|
13856
14238
|
};
|
|
13857
14239
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
13858
|
-
const scriptsDir =
|
|
14240
|
+
const scriptsDir = path14.join(providerDir, "scripts");
|
|
13859
14241
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
13860
14242
|
if (latestScriptsDir) {
|
|
13861
14243
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -13867,7 +14249,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
13867
14249
|
if (!file.endsWith(".js")) continue;
|
|
13868
14250
|
if (!targetFileNames.has(file)) continue;
|
|
13869
14251
|
try {
|
|
13870
|
-
const content = fs10.readFileSync(
|
|
14252
|
+
const content = fs10.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
|
|
13871
14253
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
13872
14254
|
lines.push("```javascript");
|
|
13873
14255
|
lines.push(content);
|
|
@@ -13883,7 +14265,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
13883
14265
|
lines.push("");
|
|
13884
14266
|
for (const file of refFiles) {
|
|
13885
14267
|
try {
|
|
13886
|
-
const content = fs10.readFileSync(
|
|
14268
|
+
const content = fs10.readFileSync(path14.join(latestScriptsDir, file), "utf-8");
|
|
13887
14269
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
13888
14270
|
lines.push("```javascript");
|
|
13889
14271
|
lines.push(content);
|
|
@@ -13916,10 +14298,10 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
13916
14298
|
lines.push("");
|
|
13917
14299
|
}
|
|
13918
14300
|
}
|
|
13919
|
-
const docsDir =
|
|
14301
|
+
const docsDir = path14.join(providerDir, "../../docs");
|
|
13920
14302
|
const loadGuide = (name) => {
|
|
13921
14303
|
try {
|
|
13922
|
-
const p =
|
|
14304
|
+
const p = path14.join(docsDir, name);
|
|
13923
14305
|
if (fs10.existsSync(p)) return fs10.readFileSync(p, "utf-8");
|
|
13924
14306
|
} catch {
|
|
13925
14307
|
}
|
|
@@ -14177,8 +14559,8 @@ var DevServer = class _DevServer {
|
|
|
14177
14559
|
}
|
|
14178
14560
|
getEndpointList() {
|
|
14179
14561
|
return this.routes.map((r) => {
|
|
14180
|
-
const
|
|
14181
|
-
return `${r.method.padEnd(5)} ${
|
|
14562
|
+
const path16 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
14563
|
+
return `${r.method.padEnd(5)} ${path16}`;
|
|
14182
14564
|
});
|
|
14183
14565
|
}
|
|
14184
14566
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -14209,15 +14591,15 @@ var DevServer = class _DevServer {
|
|
|
14209
14591
|
this.json(res, 500, { error: e.message });
|
|
14210
14592
|
}
|
|
14211
14593
|
});
|
|
14212
|
-
return new Promise((
|
|
14594
|
+
return new Promise((resolve10, reject) => {
|
|
14213
14595
|
this.server.listen(port, "127.0.0.1", () => {
|
|
14214
14596
|
this.log(`Dev server listening on http://127.0.0.1:${port}`);
|
|
14215
|
-
|
|
14597
|
+
resolve10();
|
|
14216
14598
|
});
|
|
14217
14599
|
this.server.on("error", (e) => {
|
|
14218
14600
|
if (e.code === "EADDRINUSE") {
|
|
14219
14601
|
this.log(`Port ${port} in use, skipping dev server`);
|
|
14220
|
-
|
|
14602
|
+
resolve10();
|
|
14221
14603
|
} else {
|
|
14222
14604
|
reject(e);
|
|
14223
14605
|
}
|
|
@@ -14300,20 +14682,20 @@ var DevServer = class _DevServer {
|
|
|
14300
14682
|
child.stderr?.on("data", (d) => {
|
|
14301
14683
|
stderr += d.toString().slice(0, 2e3);
|
|
14302
14684
|
});
|
|
14303
|
-
await new Promise((
|
|
14685
|
+
await new Promise((resolve10) => {
|
|
14304
14686
|
const timer = setTimeout(() => {
|
|
14305
14687
|
child.kill();
|
|
14306
|
-
|
|
14688
|
+
resolve10();
|
|
14307
14689
|
}, 3e3);
|
|
14308
14690
|
child.on("exit", () => {
|
|
14309
14691
|
clearTimeout(timer);
|
|
14310
|
-
|
|
14692
|
+
resolve10();
|
|
14311
14693
|
});
|
|
14312
14694
|
child.stdout?.once("data", () => {
|
|
14313
14695
|
setTimeout(() => {
|
|
14314
14696
|
child.kill();
|
|
14315
14697
|
clearTimeout(timer);
|
|
14316
|
-
|
|
14698
|
+
resolve10();
|
|
14317
14699
|
}, 500);
|
|
14318
14700
|
});
|
|
14319
14701
|
});
|
|
@@ -14460,12 +14842,12 @@ var DevServer = class _DevServer {
|
|
|
14460
14842
|
// ─── DevConsole SPA ───
|
|
14461
14843
|
getConsoleDistDir() {
|
|
14462
14844
|
const candidates = [
|
|
14463
|
-
|
|
14464
|
-
|
|
14465
|
-
|
|
14845
|
+
path15.resolve(__dirname, "../../web-devconsole/dist"),
|
|
14846
|
+
path15.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
14847
|
+
path15.join(process.cwd(), "packages/web-devconsole/dist")
|
|
14466
14848
|
];
|
|
14467
14849
|
for (const dir of candidates) {
|
|
14468
|
-
if (fs11.existsSync(
|
|
14850
|
+
if (fs11.existsSync(path15.join(dir, "index.html"))) return dir;
|
|
14469
14851
|
}
|
|
14470
14852
|
return null;
|
|
14471
14853
|
}
|
|
@@ -14475,7 +14857,7 @@ var DevServer = class _DevServer {
|
|
|
14475
14857
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
14476
14858
|
return;
|
|
14477
14859
|
}
|
|
14478
|
-
const htmlPath =
|
|
14860
|
+
const htmlPath = path15.join(distDir, "index.html");
|
|
14479
14861
|
try {
|
|
14480
14862
|
const html = fs11.readFileSync(htmlPath, "utf-8");
|
|
14481
14863
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
@@ -14500,15 +14882,15 @@ var DevServer = class _DevServer {
|
|
|
14500
14882
|
this.json(res, 404, { error: "Not found" });
|
|
14501
14883
|
return;
|
|
14502
14884
|
}
|
|
14503
|
-
const safePath =
|
|
14504
|
-
const filePath =
|
|
14885
|
+
const safePath = path15.normalize(pathname).replace(/^\.\.\//, "");
|
|
14886
|
+
const filePath = path15.join(distDir, safePath);
|
|
14505
14887
|
if (!filePath.startsWith(distDir)) {
|
|
14506
14888
|
this.json(res, 403, { error: "Forbidden" });
|
|
14507
14889
|
return;
|
|
14508
14890
|
}
|
|
14509
14891
|
try {
|
|
14510
14892
|
const content = fs11.readFileSync(filePath);
|
|
14511
|
-
const ext =
|
|
14893
|
+
const ext = path15.extname(filePath);
|
|
14512
14894
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
14513
14895
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
14514
14896
|
res.end(content);
|
|
@@ -14621,9 +15003,9 @@ var DevServer = class _DevServer {
|
|
|
14621
15003
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
14622
15004
|
if (entry.isDirectory()) {
|
|
14623
15005
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
14624
|
-
scan(
|
|
15006
|
+
scan(path15.join(d, entry.name), rel);
|
|
14625
15007
|
} else {
|
|
14626
|
-
const stat = fs11.statSync(
|
|
15008
|
+
const stat = fs11.statSync(path15.join(d, entry.name));
|
|
14627
15009
|
files.push({ path: rel, size: stat.size, type: "file" });
|
|
14628
15010
|
}
|
|
14629
15011
|
}
|
|
@@ -14646,7 +15028,7 @@ var DevServer = class _DevServer {
|
|
|
14646
15028
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
14647
15029
|
return;
|
|
14648
15030
|
}
|
|
14649
|
-
const fullPath =
|
|
15031
|
+
const fullPath = path15.resolve(dir, path15.normalize(filePath));
|
|
14650
15032
|
if (!fullPath.startsWith(dir)) {
|
|
14651
15033
|
this.json(res, 403, { error: "Forbidden" });
|
|
14652
15034
|
return;
|
|
@@ -14671,14 +15053,14 @@ var DevServer = class _DevServer {
|
|
|
14671
15053
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
14672
15054
|
return;
|
|
14673
15055
|
}
|
|
14674
|
-
const fullPath =
|
|
15056
|
+
const fullPath = path15.resolve(dir, path15.normalize(filePath));
|
|
14675
15057
|
if (!fullPath.startsWith(dir)) {
|
|
14676
15058
|
this.json(res, 403, { error: "Forbidden" });
|
|
14677
15059
|
return;
|
|
14678
15060
|
}
|
|
14679
15061
|
try {
|
|
14680
15062
|
if (fs11.existsSync(fullPath)) fs11.copyFileSync(fullPath, fullPath + ".bak");
|
|
14681
|
-
fs11.mkdirSync(
|
|
15063
|
+
fs11.mkdirSync(path15.dirname(fullPath), { recursive: true });
|
|
14682
15064
|
fs11.writeFileSync(fullPath, content, "utf-8");
|
|
14683
15065
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
14684
15066
|
this.providerLoader.reload();
|
|
@@ -14695,7 +15077,7 @@ var DevServer = class _DevServer {
|
|
|
14695
15077
|
return;
|
|
14696
15078
|
}
|
|
14697
15079
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
14698
|
-
const p =
|
|
15080
|
+
const p = path15.join(dir, name);
|
|
14699
15081
|
if (fs11.existsSync(p)) {
|
|
14700
15082
|
const source = fs11.readFileSync(p, "utf-8");
|
|
14701
15083
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
@@ -14716,8 +15098,8 @@ var DevServer = class _DevServer {
|
|
|
14716
15098
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
14717
15099
|
return;
|
|
14718
15100
|
}
|
|
14719
|
-
const target = fs11.existsSync(
|
|
14720
|
-
const targetPath =
|
|
15101
|
+
const target = fs11.existsSync(path15.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
15102
|
+
const targetPath = path15.join(dir, target);
|
|
14721
15103
|
try {
|
|
14722
15104
|
if (fs11.existsSync(targetPath)) fs11.copyFileSync(targetPath, targetPath + ".bak");
|
|
14723
15105
|
fs11.writeFileSync(targetPath, source, "utf-8");
|
|
@@ -14822,14 +15204,14 @@ var DevServer = class _DevServer {
|
|
|
14822
15204
|
child.stderr?.on("data", (d) => {
|
|
14823
15205
|
stderr += d.toString();
|
|
14824
15206
|
});
|
|
14825
|
-
await new Promise((
|
|
15207
|
+
await new Promise((resolve10) => {
|
|
14826
15208
|
const timer = setTimeout(() => {
|
|
14827
15209
|
child.kill();
|
|
14828
|
-
|
|
15210
|
+
resolve10();
|
|
14829
15211
|
}, timeout);
|
|
14830
15212
|
child.on("exit", () => {
|
|
14831
15213
|
clearTimeout(timer);
|
|
14832
|
-
|
|
15214
|
+
resolve10();
|
|
14833
15215
|
});
|
|
14834
15216
|
});
|
|
14835
15217
|
const elapsed = Date.now() - start;
|
|
@@ -14877,7 +15259,7 @@ var DevServer = class _DevServer {
|
|
|
14877
15259
|
}
|
|
14878
15260
|
let targetDir;
|
|
14879
15261
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
14880
|
-
const jsonPath =
|
|
15262
|
+
const jsonPath = path15.join(targetDir, "provider.json");
|
|
14881
15263
|
if (fs11.existsSync(jsonPath)) {
|
|
14882
15264
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
14883
15265
|
return;
|
|
@@ -14889,8 +15271,8 @@ var DevServer = class _DevServer {
|
|
|
14889
15271
|
const createdFiles = ["provider.json"];
|
|
14890
15272
|
if (result.files) {
|
|
14891
15273
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
14892
|
-
const fullPath =
|
|
14893
|
-
fs11.mkdirSync(
|
|
15274
|
+
const fullPath = path15.join(targetDir, relPath);
|
|
15275
|
+
fs11.mkdirSync(path15.dirname(fullPath), { recursive: true });
|
|
14894
15276
|
fs11.writeFileSync(fullPath, content, "utf-8");
|
|
14895
15277
|
createdFiles.push(relPath);
|
|
14896
15278
|
}
|
|
@@ -14943,22 +15325,22 @@ var DevServer = class _DevServer {
|
|
|
14943
15325
|
if (!fs11.existsSync(scriptsDir)) return null;
|
|
14944
15326
|
const versions = fs11.readdirSync(scriptsDir).filter((d) => {
|
|
14945
15327
|
try {
|
|
14946
|
-
return fs11.statSync(
|
|
15328
|
+
return fs11.statSync(path15.join(scriptsDir, d)).isDirectory();
|
|
14947
15329
|
} catch {
|
|
14948
15330
|
return false;
|
|
14949
15331
|
}
|
|
14950
15332
|
}).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
14951
15333
|
if (versions.length === 0) return null;
|
|
14952
|
-
return
|
|
15334
|
+
return path15.join(scriptsDir, versions[0]);
|
|
14953
15335
|
}
|
|
14954
15336
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
14955
|
-
const canonicalUserDir =
|
|
14956
|
-
const desiredDir = requestedDir ?
|
|
14957
|
-
const upstreamRoot =
|
|
14958
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
15337
|
+
const canonicalUserDir = path15.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
15338
|
+
const desiredDir = requestedDir ? path15.resolve(requestedDir) : canonicalUserDir;
|
|
15339
|
+
const upstreamRoot = path15.resolve(this.providerLoader.getUpstreamDir());
|
|
15340
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path15.sep}`)) {
|
|
14959
15341
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
14960
15342
|
}
|
|
14961
|
-
if (
|
|
15343
|
+
if (path15.basename(desiredDir) !== type) {
|
|
14962
15344
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
14963
15345
|
}
|
|
14964
15346
|
const sourceDir = this.findProviderDir(type);
|
|
@@ -14966,11 +15348,11 @@ var DevServer = class _DevServer {
|
|
|
14966
15348
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
14967
15349
|
}
|
|
14968
15350
|
if (!fs11.existsSync(desiredDir)) {
|
|
14969
|
-
fs11.mkdirSync(
|
|
15351
|
+
fs11.mkdirSync(path15.dirname(desiredDir), { recursive: true });
|
|
14970
15352
|
fs11.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
14971
15353
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
14972
15354
|
}
|
|
14973
|
-
const providerJson =
|
|
15355
|
+
const providerJson = path15.join(desiredDir, "provider.json");
|
|
14974
15356
|
if (!fs11.existsSync(providerJson)) {
|
|
14975
15357
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
14976
15358
|
}
|
|
@@ -15018,7 +15400,7 @@ var DevServer = class _DevServer {
|
|
|
15018
15400
|
setMode: "set_mode.js"
|
|
15019
15401
|
};
|
|
15020
15402
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
15021
|
-
const scriptsDir =
|
|
15403
|
+
const scriptsDir = path15.join(providerDir, "scripts");
|
|
15022
15404
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
15023
15405
|
if (latestScriptsDir) {
|
|
15024
15406
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -15029,7 +15411,7 @@ var DevServer = class _DevServer {
|
|
|
15029
15411
|
for (const file of fs11.readdirSync(latestScriptsDir)) {
|
|
15030
15412
|
if (file.endsWith(".js") && targetFileNames.has(file)) {
|
|
15031
15413
|
try {
|
|
15032
|
-
const content = fs11.readFileSync(
|
|
15414
|
+
const content = fs11.readFileSync(path15.join(latestScriptsDir, file), "utf-8");
|
|
15033
15415
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
15034
15416
|
lines.push("```javascript");
|
|
15035
15417
|
lines.push(content);
|
|
@@ -15046,7 +15428,7 @@ var DevServer = class _DevServer {
|
|
|
15046
15428
|
lines.push("");
|
|
15047
15429
|
for (const file of refFiles) {
|
|
15048
15430
|
try {
|
|
15049
|
-
const content = fs11.readFileSync(
|
|
15431
|
+
const content = fs11.readFileSync(path15.join(latestScriptsDir, file), "utf-8");
|
|
15050
15432
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
15051
15433
|
lines.push("```javascript");
|
|
15052
15434
|
lines.push(content);
|
|
@@ -15087,10 +15469,10 @@ var DevServer = class _DevServer {
|
|
|
15087
15469
|
lines.push("");
|
|
15088
15470
|
}
|
|
15089
15471
|
}
|
|
15090
|
-
const docsDir =
|
|
15472
|
+
const docsDir = path15.join(providerDir, "../../docs");
|
|
15091
15473
|
const loadGuide = (name) => {
|
|
15092
15474
|
try {
|
|
15093
|
-
const p =
|
|
15475
|
+
const p = path15.join(docsDir, name);
|
|
15094
15476
|
if (fs11.existsSync(p)) return fs11.readFileSync(p, "utf-8");
|
|
15095
15477
|
} catch {
|
|
15096
15478
|
}
|
|
@@ -15264,7 +15646,7 @@ var DevServer = class _DevServer {
|
|
|
15264
15646
|
parseApproval: "parse_approval.js"
|
|
15265
15647
|
};
|
|
15266
15648
|
const targetFileNames = new Set(functions.map((fn) => funcToFile[fn]).filter(Boolean));
|
|
15267
|
-
const scriptsDir =
|
|
15649
|
+
const scriptsDir = path15.join(providerDir, "scripts");
|
|
15268
15650
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
15269
15651
|
if (latestScriptsDir) {
|
|
15270
15652
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -15276,7 +15658,7 @@ var DevServer = class _DevServer {
|
|
|
15276
15658
|
if (!file.endsWith(".js")) continue;
|
|
15277
15659
|
if (!targetFileNames.has(file)) continue;
|
|
15278
15660
|
try {
|
|
15279
|
-
const content = fs11.readFileSync(
|
|
15661
|
+
const content = fs11.readFileSync(path15.join(latestScriptsDir, file), "utf-8");
|
|
15280
15662
|
lines.push(`### \`${file}\` \u270F\uFE0F EDIT`);
|
|
15281
15663
|
lines.push("```javascript");
|
|
15282
15664
|
lines.push(content);
|
|
@@ -15292,7 +15674,7 @@ var DevServer = class _DevServer {
|
|
|
15292
15674
|
lines.push("");
|
|
15293
15675
|
for (const file of refFiles) {
|
|
15294
15676
|
try {
|
|
15295
|
-
const content = fs11.readFileSync(
|
|
15677
|
+
const content = fs11.readFileSync(path15.join(latestScriptsDir, file), "utf-8");
|
|
15296
15678
|
lines.push(`### \`${file}\` \u{1F512}`);
|
|
15297
15679
|
lines.push("```javascript");
|
|
15298
15680
|
lines.push(content);
|
|
@@ -15325,10 +15707,10 @@ var DevServer = class _DevServer {
|
|
|
15325
15707
|
lines.push("");
|
|
15326
15708
|
}
|
|
15327
15709
|
}
|
|
15328
|
-
const docsDir =
|
|
15710
|
+
const docsDir = path15.join(providerDir, "../../docs");
|
|
15329
15711
|
const loadGuide = (name) => {
|
|
15330
15712
|
try {
|
|
15331
|
-
const p =
|
|
15713
|
+
const p = path15.join(docsDir, name);
|
|
15332
15714
|
if (fs11.existsSync(p)) return fs11.readFileSync(p, "utf-8");
|
|
15333
15715
|
} catch {
|
|
15334
15716
|
}
|
|
@@ -15485,14 +15867,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
15485
15867
|
res.end(JSON.stringify(data, null, 2));
|
|
15486
15868
|
}
|
|
15487
15869
|
async readBody(req) {
|
|
15488
|
-
return new Promise((
|
|
15870
|
+
return new Promise((resolve10) => {
|
|
15489
15871
|
let body = "";
|
|
15490
15872
|
req.on("data", (chunk) => body += chunk);
|
|
15491
15873
|
req.on("end", () => {
|
|
15492
15874
|
try {
|
|
15493
|
-
|
|
15875
|
+
resolve10(JSON.parse(body));
|
|
15494
15876
|
} catch {
|
|
15495
|
-
|
|
15877
|
+
resolve10({});
|
|
15496
15878
|
}
|
|
15497
15879
|
});
|
|
15498
15880
|
});
|
|
@@ -15909,7 +16291,7 @@ async function waitForReady(endpoint, timeoutMs = STARTUP_TIMEOUT_MS) {
|
|
|
15909
16291
|
const deadline = Date.now() + timeoutMs;
|
|
15910
16292
|
while (Date.now() < deadline) {
|
|
15911
16293
|
if (await canConnect(endpoint)) return;
|
|
15912
|
-
await new Promise((
|
|
16294
|
+
await new Promise((resolve10) => setTimeout(resolve10, STARTUP_POLL_MS));
|
|
15913
16295
|
}
|
|
15914
16296
|
throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
|
|
15915
16297
|
}
|
|
@@ -16064,10 +16446,10 @@ async function installExtension(ide, extension) {
|
|
|
16064
16446
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
16065
16447
|
const fs12 = await import("fs");
|
|
16066
16448
|
fs12.writeFileSync(vsixPath, buffer);
|
|
16067
|
-
return new Promise((
|
|
16449
|
+
return new Promise((resolve10) => {
|
|
16068
16450
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
16069
16451
|
(0, import_child_process8.exec)(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
|
|
16070
|
-
|
|
16452
|
+
resolve10({
|
|
16071
16453
|
extensionId: extension.id,
|
|
16072
16454
|
marketplaceId: extension.marketplaceId,
|
|
16073
16455
|
success: !error,
|
|
@@ -16080,11 +16462,11 @@ async function installExtension(ide, extension) {
|
|
|
16080
16462
|
} catch (e) {
|
|
16081
16463
|
}
|
|
16082
16464
|
}
|
|
16083
|
-
return new Promise((
|
|
16465
|
+
return new Promise((resolve10) => {
|
|
16084
16466
|
const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
|
|
16085
16467
|
(0, import_child_process8.exec)(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
|
|
16086
16468
|
if (error) {
|
|
16087
|
-
|
|
16469
|
+
resolve10({
|
|
16088
16470
|
extensionId: extension.id,
|
|
16089
16471
|
marketplaceId: extension.marketplaceId,
|
|
16090
16472
|
success: false,
|
|
@@ -16092,7 +16474,7 @@ async function installExtension(ide, extension) {
|
|
|
16092
16474
|
error: stderr || error.message
|
|
16093
16475
|
});
|
|
16094
16476
|
} else {
|
|
16095
|
-
|
|
16477
|
+
resolve10({
|
|
16096
16478
|
extensionId: extension.id,
|
|
16097
16479
|
marketplaceId: extension.marketplaceId,
|
|
16098
16480
|
success: true,
|
|
@@ -16397,6 +16779,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
16397
16779
|
SessionHostPtyTransportFactory,
|
|
16398
16780
|
VersionArchive,
|
|
16399
16781
|
addCliHistory,
|
|
16782
|
+
appendRecentActivity,
|
|
16400
16783
|
buildSessionEntries,
|
|
16401
16784
|
buildStatusSnapshot,
|
|
16402
16785
|
connectCdpManager,
|
|
@@ -16410,6 +16793,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
16410
16793
|
getAvailableIdeIds,
|
|
16411
16794
|
getHostMemorySnapshot,
|
|
16412
16795
|
getLogLevel,
|
|
16796
|
+
getRecentActivity,
|
|
16413
16797
|
getRecentCommands,
|
|
16414
16798
|
getRecentLogs,
|
|
16415
16799
|
getWorkspaceActivity,
|