@adhdev/daemon-standalone 0.9.53 → 0.9.55
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.js +1814 -387
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/index-C9cvjHjc.css +1 -0
- package/public/assets/index-Dxe0utnC.js +92 -0
- package/public/index.html +2 -2
- package/vendor/session-host-daemon/index.d.mts +2 -0
- package/vendor/session-host-daemon/index.d.ts +2 -0
- package/vendor/session-host-daemon/index.js +59 -1
- package/vendor/session-host-daemon/index.js.map +1 -1
- package/vendor/session-host-daemon/index.mjs +59 -1
- package/vendor/session-host-daemon/index.mjs.map +1 -1
- package/public/assets/index-DwkbC63k.js +0 -92
- package/public/assets/index-blpUofnU.css +0 -1
package/dist/index.js
CHANGED
|
@@ -28139,13 +28139,13 @@ var require_dist2 = __commonJS({
|
|
|
28139
28139
|
return LOG_DIR;
|
|
28140
28140
|
}
|
|
28141
28141
|
function getCurrentDaemonLogPath(date5 = /* @__PURE__ */ new Date()) {
|
|
28142
|
-
return
|
|
28142
|
+
return path9.join(LOG_DIR, `daemon-${date5.toISOString().slice(0, 10)}.log`);
|
|
28143
28143
|
}
|
|
28144
28144
|
function checkDateRotation() {
|
|
28145
28145
|
const today = getDateStr();
|
|
28146
28146
|
if (today !== currentDate) {
|
|
28147
28147
|
currentDate = today;
|
|
28148
|
-
currentLogFile =
|
|
28148
|
+
currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
28149
28149
|
cleanOldLogs();
|
|
28150
28150
|
}
|
|
28151
28151
|
}
|
|
@@ -28159,7 +28159,7 @@ var require_dist2 = __commonJS({
|
|
|
28159
28159
|
const dateMatch = file2.match(/daemon-(\d{4}-\d{2}-\d{2})/);
|
|
28160
28160
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
28161
28161
|
try {
|
|
28162
|
-
fs22.unlinkSync(
|
|
28162
|
+
fs22.unlinkSync(path9.join(LOG_DIR, file2));
|
|
28163
28163
|
} catch {
|
|
28164
28164
|
}
|
|
28165
28165
|
}
|
|
@@ -28169,8 +28169,8 @@ var require_dist2 = __commonJS({
|
|
|
28169
28169
|
}
|
|
28170
28170
|
function rotateSizeIfNeeded() {
|
|
28171
28171
|
try {
|
|
28172
|
-
const
|
|
28173
|
-
if (
|
|
28172
|
+
const stat22 = fs22.statSync(currentLogFile);
|
|
28173
|
+
if (stat22.size > MAX_LOG_SIZE) {
|
|
28174
28174
|
const backup = currentLogFile.replace(".log", ".1.log");
|
|
28175
28175
|
try {
|
|
28176
28176
|
fs22.unlinkSync(backup);
|
|
@@ -28276,7 +28276,7 @@ var require_dist2 = __commonJS({
|
|
|
28276
28276
|
writeToFile(`Log level: ${currentLevel}`);
|
|
28277
28277
|
}
|
|
28278
28278
|
var fs22;
|
|
28279
|
-
var
|
|
28279
|
+
var path9;
|
|
28280
28280
|
var os42;
|
|
28281
28281
|
var LEVEL_NUM;
|
|
28282
28282
|
var LEVEL_LABEL;
|
|
@@ -28299,12 +28299,12 @@ var require_dist2 = __commonJS({
|
|
|
28299
28299
|
"src/logging/logger.ts"() {
|
|
28300
28300
|
"use strict";
|
|
28301
28301
|
fs22 = __toESM2(require("fs"));
|
|
28302
|
-
|
|
28302
|
+
path9 = __toESM2(require("path"));
|
|
28303
28303
|
os42 = __toESM2(require("os"));
|
|
28304
28304
|
LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
28305
28305
|
LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
|
|
28306
28306
|
currentLevel = "info";
|
|
28307
|
-
LOG_DIR = process.platform === "win32" ?
|
|
28307
|
+
LOG_DIR = process.platform === "win32" ? path9.join(process.env.LOCALAPPDATA || process.env.APPDATA || path9.join(os42.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path9.join(os42.homedir(), "Library", "Logs", "adhdev") : path9.join(os42.homedir(), ".local", "share", "adhdev", "logs");
|
|
28308
28308
|
MAX_LOG_SIZE = 5 * 1024 * 1024;
|
|
28309
28309
|
MAX_LOG_DAYS = 7;
|
|
28310
28310
|
try {
|
|
@@ -28312,16 +28312,16 @@ var require_dist2 = __commonJS({
|
|
|
28312
28312
|
} catch {
|
|
28313
28313
|
}
|
|
28314
28314
|
currentDate = getDateStr();
|
|
28315
|
-
currentLogFile =
|
|
28315
|
+
currentLogFile = path9.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
28316
28316
|
cleanOldLogs();
|
|
28317
28317
|
try {
|
|
28318
|
-
const oldLog =
|
|
28318
|
+
const oldLog = path9.join(LOG_DIR, "daemon.log");
|
|
28319
28319
|
if (fs22.existsSync(oldLog)) {
|
|
28320
|
-
const
|
|
28321
|
-
const oldDate =
|
|
28322
|
-
fs22.renameSync(oldLog,
|
|
28320
|
+
const stat22 = fs22.statSync(oldLog);
|
|
28321
|
+
const oldDate = stat22.mtime.toISOString().slice(0, 10);
|
|
28322
|
+
fs22.renameSync(oldLog, path9.join(LOG_DIR, `daemon-${oldDate}.log`));
|
|
28323
28323
|
}
|
|
28324
|
-
const oldLogBackup =
|
|
28324
|
+
const oldLogBackup = path9.join(LOG_DIR, "daemon.log.old");
|
|
28325
28325
|
if (fs22.existsSync(oldLogBackup)) {
|
|
28326
28326
|
fs22.unlinkSync(oldLogBackup);
|
|
28327
28327
|
}
|
|
@@ -28353,7 +28353,7 @@ var require_dist2 = __commonJS({
|
|
|
28353
28353
|
}
|
|
28354
28354
|
};
|
|
28355
28355
|
interceptorInstalled = false;
|
|
28356
|
-
LOG_PATH =
|
|
28356
|
+
LOG_PATH = path9.join(LOG_DIR, `daemon-${getDateStr()}.log`);
|
|
28357
28357
|
}
|
|
28358
28358
|
});
|
|
28359
28359
|
function normalizeInputEnvelope(input) {
|
|
@@ -29254,8 +29254,8 @@ var require_dist2 = __commonJS({
|
|
|
29254
29254
|
if (cwd) {
|
|
29255
29255
|
try {
|
|
29256
29256
|
const fs16 = require("fs");
|
|
29257
|
-
const
|
|
29258
|
-
if (!
|
|
29257
|
+
const stat22 = fs16.statSync(cwd);
|
|
29258
|
+
if (!stat22.isDirectory()) cwd = os8.homedir();
|
|
29259
29259
|
} catch {
|
|
29260
29260
|
cwd = os8.homedir();
|
|
29261
29261
|
}
|
|
@@ -29335,9 +29335,9 @@ var require_dist2 = __commonJS({
|
|
|
29335
29335
|
function findBinary(name) {
|
|
29336
29336
|
const trimmed = String(name || "").trim();
|
|
29337
29337
|
if (!trimmed) return trimmed;
|
|
29338
|
-
const expanded = trimmed.startsWith("~") ?
|
|
29339
|
-
if (
|
|
29340
|
-
return
|
|
29338
|
+
const expanded = trimmed.startsWith("~") ? path13.join(os9.homedir(), trimmed.slice(1)) : trimmed;
|
|
29339
|
+
if (path13.isAbsolute(expanded) || expanded.includes("/") || expanded.includes("\\")) {
|
|
29340
|
+
return path13.isAbsolute(expanded) ? expanded : path13.resolve(expanded);
|
|
29341
29341
|
}
|
|
29342
29342
|
const isWin = os9.platform() === "win32";
|
|
29343
29343
|
try {
|
|
@@ -29353,7 +29353,7 @@ var require_dist2 = __commonJS({
|
|
|
29353
29353
|
}
|
|
29354
29354
|
}
|
|
29355
29355
|
function isScriptBinary(binaryPath) {
|
|
29356
|
-
if (!
|
|
29356
|
+
if (!path13.isAbsolute(binaryPath)) return false;
|
|
29357
29357
|
try {
|
|
29358
29358
|
const fs16 = require("fs");
|
|
29359
29359
|
const resolved = fs16.realpathSync(binaryPath);
|
|
@@ -29369,7 +29369,7 @@ var require_dist2 = __commonJS({
|
|
|
29369
29369
|
}
|
|
29370
29370
|
}
|
|
29371
29371
|
function looksLikeMachOOrElf(filePath) {
|
|
29372
|
-
if (!
|
|
29372
|
+
if (!path13.isAbsolute(filePath)) return false;
|
|
29373
29373
|
try {
|
|
29374
29374
|
const fs16 = require("fs");
|
|
29375
29375
|
const resolved = fs16.realpathSync(filePath);
|
|
@@ -29520,7 +29520,7 @@ var require_dist2 = __commonJS({
|
|
|
29520
29520
|
};
|
|
29521
29521
|
}
|
|
29522
29522
|
var os9;
|
|
29523
|
-
var
|
|
29523
|
+
var path13;
|
|
29524
29524
|
var import_child_process4;
|
|
29525
29525
|
var buildCliSpawnEnv;
|
|
29526
29526
|
var COMMON_COMPARABLE_WRAP_WORDS;
|
|
@@ -29528,7 +29528,7 @@ var require_dist2 = __commonJS({
|
|
|
29528
29528
|
"src/cli-adapters/provider-cli-shared.ts"() {
|
|
29529
29529
|
"use strict";
|
|
29530
29530
|
os9 = __toESM2(require("os"));
|
|
29531
|
-
|
|
29531
|
+
path13 = __toESM2(require("path"));
|
|
29532
29532
|
import_child_process4 = require("child_process");
|
|
29533
29533
|
init_spawn_env();
|
|
29534
29534
|
buildCliSpawnEnv = import_session_host_core3.sanitizeSpawnEnv;
|
|
@@ -29812,6 +29812,7 @@ var require_dist2 = __commonJS({
|
|
|
29812
29812
|
sendDelayMs: typeof provider.sendDelayMs === "number" ? Math.max(0, provider.sendDelayMs) : 0,
|
|
29813
29813
|
sendKey: typeof provider.sendKey === "string" && provider.sendKey.length > 0 ? provider.sendKey : "\r",
|
|
29814
29814
|
submitStrategy: provider.submitStrategy === "immediate" ? "immediate" : "wait_for_echo",
|
|
29815
|
+
requirePromptEchoBeforeSubmit: provider.requirePromptEchoBeforeSubmit === true,
|
|
29815
29816
|
providerResolutionMeta: {
|
|
29816
29817
|
type: provider.type,
|
|
29817
29818
|
name: provider.name,
|
|
@@ -29839,9 +29840,9 @@ var require_dist2 = __commonJS({
|
|
|
29839
29840
|
const allArgs = [...spawnConfig.args, ...extraArgs];
|
|
29840
29841
|
let shellCmd;
|
|
29841
29842
|
let shellArgs;
|
|
29842
|
-
const useShellUnix = !isWin && (!!spawnConfig.shell || !
|
|
29843
|
+
const useShellUnix = !isWin && (!!spawnConfig.shell || !path14.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
|
|
29843
29844
|
const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
|
|
29844
|
-
const useShellWin = !!spawnConfig.shell || isCmdShim || !
|
|
29845
|
+
const useShellWin = !!spawnConfig.shell || isCmdShim || !path14.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
|
|
29845
29846
|
const useShell = isWin ? useShellWin : useShellUnix;
|
|
29846
29847
|
if (useShell) {
|
|
29847
29848
|
shellCmd = isWin ? "cmd.exe" : process.env.SHELL || "/bin/zsh";
|
|
@@ -29918,13 +29919,13 @@ var require_dist2 = __commonJS({
|
|
|
29918
29919
|
return "";
|
|
29919
29920
|
}
|
|
29920
29921
|
var os10;
|
|
29921
|
-
var
|
|
29922
|
+
var path14;
|
|
29922
29923
|
var import_session_host_core22;
|
|
29923
29924
|
var init_provider_cli_runtime = __esm2({
|
|
29924
29925
|
"src/cli-adapters/provider-cli-runtime.ts"() {
|
|
29925
29926
|
"use strict";
|
|
29926
29927
|
os10 = __toESM2(require("os"));
|
|
29927
|
-
|
|
29928
|
+
path14 = __toESM2(require("path"));
|
|
29928
29929
|
import_session_host_core22 = require_dist();
|
|
29929
29930
|
init_provider_cli_shared();
|
|
29930
29931
|
}
|
|
@@ -30077,6 +30078,7 @@ var require_dist2 = __commonJS({
|
|
|
30077
30078
|
this.sendDelayMs = resolvedConfig.sendDelayMs;
|
|
30078
30079
|
this.sendKey = resolvedConfig.sendKey;
|
|
30079
30080
|
this.submitStrategy = resolvedConfig.submitStrategy;
|
|
30081
|
+
this.requirePromptEchoBeforeSubmit = resolvedConfig.requirePromptEchoBeforeSubmit;
|
|
30080
30082
|
this.providerResolutionMeta = resolvedConfig.providerResolutionMeta;
|
|
30081
30083
|
this.cliScripts = provider.scripts || {};
|
|
30082
30084
|
const scriptNames = listCliScriptNames(this.cliScripts);
|
|
@@ -30373,6 +30375,7 @@ var require_dist2 = __commonJS({
|
|
|
30373
30375
|
sendDelayMs;
|
|
30374
30376
|
sendKey;
|
|
30375
30377
|
submitStrategy;
|
|
30378
|
+
requirePromptEchoBeforeSubmit;
|
|
30376
30379
|
static SCRIPT_STATUS_DEBOUNCE_MS = 3e3;
|
|
30377
30380
|
/** Inject CLI scripts after construction (e.g. when resolved by ProviderLoader) */
|
|
30378
30381
|
setCliScripts(scripts) {
|
|
@@ -30724,7 +30727,7 @@ var require_dist2 = __commonJS({
|
|
|
30724
30727
|
`[${this.cliType}] Waiting for interactive prompt: status=${status} stableMs=${stableMs} recentOutputMs=${recentlyOutput} screen=${JSON.stringify(summarizeCliTraceText(screenText, 220)).slice(0, 260)}`
|
|
30725
30728
|
);
|
|
30726
30729
|
}
|
|
30727
|
-
await new Promise((
|
|
30730
|
+
await new Promise((resolve15) => setTimeout(resolve15, 50));
|
|
30728
30731
|
}
|
|
30729
30732
|
const finalScreenText = this.terminalScreen.getText() || "";
|
|
30730
30733
|
LOG2.warn(
|
|
@@ -31893,6 +31896,22 @@ var require_dist2 = __commonJS({
|
|
|
31893
31896
|
}
|
|
31894
31897
|
}
|
|
31895
31898
|
if (elapsed >= state.maxEchoWaitMs) {
|
|
31899
|
+
const diagnostic = {
|
|
31900
|
+
elapsed,
|
|
31901
|
+
maxEchoWaitMs: state.maxEchoWaitMs,
|
|
31902
|
+
submitDelayMs: state.submitDelayMs,
|
|
31903
|
+
promptSnippet: state.normalizedPromptSnippet,
|
|
31904
|
+
requirePromptEchoBeforeSubmit: this.requirePromptEchoBeforeSubmit,
|
|
31905
|
+
screenText: summarizeCliTraceText(screenText, 1e3)
|
|
31906
|
+
};
|
|
31907
|
+
this.recordTrace("submit_echo_missing", diagnostic);
|
|
31908
|
+
if (this.requirePromptEchoBeforeSubmit) {
|
|
31909
|
+
const message = `${this.cliName} prompt echo was not observed on the PTY screen before submit`;
|
|
31910
|
+
LOG2.warn("CLI", `[${this.cliType}] ${message} elapsed=${elapsed}ms maxEchoWaitMs=${state.maxEchoWaitMs} screen=${JSON.stringify(diagnostic.screenText).slice(0, 240)}`);
|
|
31911
|
+
completion.rejectOnce(new Error(message));
|
|
31912
|
+
return;
|
|
31913
|
+
}
|
|
31914
|
+
LOG2.warn("CLI", `[${this.cliType}] prompt echo was not observed before submit; sending submit key anyway elapsed=${elapsed}ms maxEchoWaitMs=${state.maxEchoWaitMs}`);
|
|
31896
31915
|
this.submitSendKey(state, completion);
|
|
31897
31916
|
return;
|
|
31898
31917
|
}
|
|
@@ -31912,7 +31931,7 @@ var require_dist2 = __commonJS({
|
|
|
31912
31931
|
const deadline = Date.now() + 1e4;
|
|
31913
31932
|
while (this.startupParseGate && Date.now() < deadline) {
|
|
31914
31933
|
this.resolveStartupState("send_wait");
|
|
31915
|
-
await new Promise((
|
|
31934
|
+
await new Promise((resolve15) => setTimeout(resolve15, 50));
|
|
31916
31935
|
}
|
|
31917
31936
|
}
|
|
31918
31937
|
if (!allowInterventionPrompt) {
|
|
@@ -31993,13 +32012,13 @@ var require_dist2 = __commonJS({
|
|
|
31993
32012
|
}
|
|
31994
32013
|
this.responseEpoch += 1;
|
|
31995
32014
|
this.responseSettleIgnoreUntil = Date.now() + submitDelayMs + this.timeouts.outputSettle + 250;
|
|
31996
|
-
await new Promise((
|
|
32015
|
+
await new Promise((resolve15, reject) => {
|
|
31997
32016
|
let resolved = false;
|
|
31998
32017
|
const completion = {
|
|
31999
32018
|
resolveOnce: () => {
|
|
32000
32019
|
if (resolved) return;
|
|
32001
32020
|
resolved = true;
|
|
32002
|
-
|
|
32021
|
+
resolve15();
|
|
32003
32022
|
},
|
|
32004
32023
|
rejectOnce: (error48) => {
|
|
32005
32024
|
if (resolved) return;
|
|
@@ -32161,17 +32180,17 @@ var require_dist2 = __commonJS({
|
|
|
32161
32180
|
}
|
|
32162
32181
|
}
|
|
32163
32182
|
waitForStopped(timeoutMs) {
|
|
32164
|
-
return new Promise((
|
|
32183
|
+
return new Promise((resolve15) => {
|
|
32165
32184
|
const startedAt = Date.now();
|
|
32166
32185
|
const timer = setInterval(() => {
|
|
32167
32186
|
if (!this.ptyProcess || this.currentStatus === "stopped") {
|
|
32168
32187
|
clearInterval(timer);
|
|
32169
|
-
|
|
32188
|
+
resolve15(true);
|
|
32170
32189
|
return;
|
|
32171
32190
|
}
|
|
32172
32191
|
if (Date.now() - startedAt >= timeoutMs) {
|
|
32173
32192
|
clearInterval(timer);
|
|
32174
|
-
|
|
32193
|
+
resolve15(false);
|
|
32175
32194
|
}
|
|
32176
32195
|
}, 100);
|
|
32177
32196
|
});
|
|
@@ -32357,6 +32376,7 @@ var require_dist2 = __commonJS({
|
|
|
32357
32376
|
sendDelayMs: this.sendDelayMs,
|
|
32358
32377
|
sendKey: this.sendKey,
|
|
32359
32378
|
submitStrategy: this.submitStrategy,
|
|
32379
|
+
requirePromptEchoBeforeSubmit: this.requirePromptEchoBeforeSubmit,
|
|
32360
32380
|
submitPendingUntil: this.submitPendingUntil,
|
|
32361
32381
|
responseSettleIgnoreUntil: this.responseSettleIgnoreUntil,
|
|
32362
32382
|
resizeSuppressUntil: this.resizeSuppressUntil,
|
|
@@ -32409,6 +32429,7 @@ var require_dist2 = __commonJS({
|
|
|
32409
32429
|
DEFAULT_CDP_SCAN_INTERVAL_MS: () => DEFAULT_CDP_SCAN_INTERVAL_MS,
|
|
32410
32430
|
DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS: () => DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS2,
|
|
32411
32431
|
DEFAULT_DAEMON_PORT: () => DEFAULT_DAEMON_PORT,
|
|
32432
|
+
DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS: () => DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS,
|
|
32412
32433
|
DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS: () => DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS2,
|
|
32413
32434
|
DEFAULT_SESSION_HOST_APP_NAME: () => DEFAULT_SESSION_HOST_APP_NAME,
|
|
32414
32435
|
DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS: () => DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS2,
|
|
@@ -32427,8 +32448,12 @@ var require_dist2 = __commonJS({
|
|
|
32427
32448
|
DaemonCommandRouter: () => DaemonCommandRouter,
|
|
32428
32449
|
DaemonStatusReporter: () => DaemonStatusReporter,
|
|
32429
32450
|
DevServer: () => DevServer,
|
|
32451
|
+
GitCommandError: () => GitCommandError,
|
|
32452
|
+
GitWorkspaceMonitor: () => GitWorkspaceMonitor,
|
|
32430
32453
|
IdeProviderInstance: () => IdeProviderInstance,
|
|
32454
|
+
InMemoryGitSnapshotStore: () => InMemoryGitSnapshotStore,
|
|
32431
32455
|
LOG: () => LOG2,
|
|
32456
|
+
MIN_GIT_WORKSPACE_POLL_INTERVAL_MS: () => MIN_GIT_WORKSPACE_POLL_INTERVAL_MS,
|
|
32432
32457
|
MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS: () => MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS2,
|
|
32433
32458
|
MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS: () => MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS2,
|
|
32434
32459
|
NodePtyTransportFactory: () => NodePtyTransportFactory,
|
|
@@ -32437,6 +32462,7 @@ var require_dist2 = __commonJS({
|
|
|
32437
32462
|
ProviderLoader: () => ProviderLoader,
|
|
32438
32463
|
STANDALONE_CDP_SCAN_INTERVAL_MS: () => STANDALONE_CDP_SCAN_INTERVAL_MS2,
|
|
32439
32464
|
SessionHostPtyTransportFactory: () => SessionHostPtyTransportFactory2,
|
|
32465
|
+
TurnSnapshotTracker: () => TurnSnapshotTracker,
|
|
32440
32466
|
VersionArchive: () => VersionArchive,
|
|
32441
32467
|
appendRecentActivity: () => appendRecentActivity,
|
|
32442
32468
|
buildAssistantChatMessage: () => buildAssistantChatMessage,
|
|
@@ -32456,9 +32482,14 @@ var require_dist2 = __commonJS({
|
|
|
32456
32482
|
buildUserChatMessage: () => buildUserChatMessage,
|
|
32457
32483
|
classifyHotChatSessionsForSubscriptionFlush: () => classifyHotChatSessionsForSubscriptionFlush2,
|
|
32458
32484
|
clearDebugTrace: () => clearDebugTrace,
|
|
32485
|
+
compareGitSnapshots: () => compareGitSnapshots,
|
|
32459
32486
|
configureDebugTraceStore: () => configureDebugTraceStore,
|
|
32460
32487
|
connectCdpManager: () => connectCdpManager,
|
|
32461
32488
|
createDebugTraceStore: () => createDebugTraceStore,
|
|
32489
|
+
createDefaultGitCommandServices: () => createDefaultGitCommandServices,
|
|
32490
|
+
createGitCompactSummary: () => createGitCompactSummary,
|
|
32491
|
+
createGitSnapshotStore: () => createGitSnapshotStore,
|
|
32492
|
+
createGitWorkspaceMonitor: () => createGitWorkspaceMonitor2,
|
|
32462
32493
|
createInteractionId: () => createInteractionId,
|
|
32463
32494
|
detectAllVersions: () => detectAllVersions,
|
|
32464
32495
|
detectCLIs: () => detectCLIs,
|
|
@@ -32473,6 +32504,9 @@ var require_dist2 = __commonJS({
|
|
|
32473
32504
|
getCurrentDaemonLogPath: () => getCurrentDaemonLogPath,
|
|
32474
32505
|
getDaemonLogDir: () => getDaemonLogDir,
|
|
32475
32506
|
getDebugRuntimeConfig: () => getDebugRuntimeConfig,
|
|
32507
|
+
getGitDiffSummary: () => getGitDiffSummary,
|
|
32508
|
+
getGitFileDiff: () => getGitFileDiff,
|
|
32509
|
+
getGitRepoStatus: () => getGitRepoStatus,
|
|
32476
32510
|
getHostMemorySnapshot: () => getHostMemorySnapshot,
|
|
32477
32511
|
getLogLevel: () => getLogLevel,
|
|
32478
32512
|
getNpmExecOptions: () => getNpmExecOptions,
|
|
@@ -32484,6 +32518,7 @@ var require_dist2 = __commonJS({
|
|
|
32484
32518
|
getSessionHostRecoveryLabel: () => getSessionHostRecoveryLabel,
|
|
32485
32519
|
getSessionHostSurfaceKind: () => getSessionHostSurfaceKind,
|
|
32486
32520
|
getWorkspaceState: () => getWorkspaceState2,
|
|
32521
|
+
handleGitCommand: () => handleGitCommand,
|
|
32487
32522
|
hasCdpManager: () => hasCdpManager,
|
|
32488
32523
|
hashSignatureParts: () => hashSignatureParts,
|
|
32489
32524
|
initDaemonComponents: () => initDaemonComponents2,
|
|
@@ -32492,9 +32527,11 @@ var require_dist2 = __commonJS({
|
|
|
32492
32527
|
isBuiltinChatMessageKind: () => isBuiltinChatMessageKind,
|
|
32493
32528
|
isCdpConnected: () => isCdpConnected,
|
|
32494
32529
|
isExtensionInstalled: () => isExtensionInstalled,
|
|
32530
|
+
isGitCommandName: () => isGitCommandName,
|
|
32495
32531
|
isIdeRunning: () => isIdeRunning,
|
|
32496
32532
|
isManagedStatusWaiting: () => isManagedStatusWaiting,
|
|
32497
32533
|
isManagedStatusWorking: () => isManagedStatusWorking,
|
|
32534
|
+
isPathInside: () => isPathInside,
|
|
32498
32535
|
isSessionHostLiveRuntime: () => isSessionHostLiveRuntime,
|
|
32499
32536
|
isSessionHostRecoverySnapshot: () => isSessionHostRecoverySnapshot,
|
|
32500
32537
|
isSetupComplete: () => isSetupComplete,
|
|
@@ -32512,10 +32549,13 @@ var require_dist2 = __commonJS({
|
|
|
32512
32549
|
normalizeChatMessageKind: () => normalizeChatMessageKind,
|
|
32513
32550
|
normalizeChatMessages: () => normalizeChatMessages,
|
|
32514
32551
|
normalizeChatTailActiveModal: () => normalizeChatTailActiveModal,
|
|
32552
|
+
normalizeGitOutput: () => normalizeGitOutput,
|
|
32553
|
+
normalizeGitWorkspaceSubscriptionParams: () => normalizeGitWorkspaceSubscriptionParams2,
|
|
32515
32554
|
normalizeInputEnvelope: () => normalizeInputEnvelope,
|
|
32516
32555
|
normalizeManagedStatus: () => normalizeManagedStatus,
|
|
32517
32556
|
normalizeMessageParts: () => normalizeMessageParts,
|
|
32518
32557
|
normalizeSessionModalFields: () => normalizeSessionModalFields,
|
|
32558
|
+
parsePorcelainV2Status: () => parsePorcelainV2Status,
|
|
32519
32559
|
parseProviderSourceConfigUpdate: () => parseProviderSourceConfigUpdate,
|
|
32520
32560
|
partitionSessionHostDiagnosticsSessions: () => partitionSessionHostDiagnosticsSessions,
|
|
32521
32561
|
partitionSessionHostRecords: () => partitionSessionHostRecords,
|
|
@@ -32531,9 +32571,11 @@ var require_dist2 = __commonJS({
|
|
|
32531
32571
|
resolveChatMessageKind: () => resolveChatMessageKind,
|
|
32532
32572
|
resolveCurrentGlobalInstallSurface: () => resolveCurrentGlobalInstallSurface,
|
|
32533
32573
|
resolveDebugRuntimeConfig: () => resolveDebugRuntimeConfig,
|
|
32574
|
+
resolveGitRepository: () => resolveGitRepository,
|
|
32534
32575
|
resolveSessionHostAppName: () => resolveSessionHostAppName,
|
|
32535
32576
|
resolveSessionHostAppNameResolution: () => resolveSessionHostAppNameResolution2,
|
|
32536
32577
|
runAsyncBatch: () => runAsyncBatch2,
|
|
32578
|
+
runGit: () => runGit,
|
|
32537
32579
|
saveConfig: () => saveConfig,
|
|
32538
32580
|
saveState: () => saveState,
|
|
32539
32581
|
setDebugRuntimeConfig: () => setDebugRuntimeConfig,
|
|
@@ -32544,21 +32586,1284 @@ var require_dist2 = __commonJS({
|
|
|
32544
32586
|
shutdownDaemonComponents: () => shutdownDaemonComponents2,
|
|
32545
32587
|
spawnDetachedDaemonUpgradeHelper: () => spawnDetachedDaemonUpgradeHelper,
|
|
32546
32588
|
startDaemonDevSupport: () => startDaemonDevSupport2,
|
|
32589
|
+
summarizeGitStatus: () => summarizeGitStatus,
|
|
32547
32590
|
updateConfig: () => updateConfig,
|
|
32548
32591
|
upsertSavedProviderSession: () => upsertSavedProviderSession
|
|
32549
32592
|
});
|
|
32550
32593
|
module2.exports = __toCommonJS2(index_exports);
|
|
32594
|
+
var import_node_child_process = require("child_process");
|
|
32595
|
+
var import_node_fs3 = require("fs");
|
|
32596
|
+
var import_promises4 = require("fs/promises");
|
|
32597
|
+
var path5 = __toESM2(require("path"));
|
|
32598
|
+
var import_node_util = require("util");
|
|
32599
|
+
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
32600
|
+
var DEFAULT_TIMEOUT_MS = 5e3;
|
|
32601
|
+
var DEFAULT_MAX_BUFFER = 1024 * 1024;
|
|
32602
|
+
var GitCommandError = class extends Error {
|
|
32603
|
+
reason;
|
|
32604
|
+
stdout;
|
|
32605
|
+
stderr;
|
|
32606
|
+
exitCode;
|
|
32607
|
+
signal;
|
|
32608
|
+
argv;
|
|
32609
|
+
cwd;
|
|
32610
|
+
constructor(reason, message, details = {}) {
|
|
32611
|
+
super(message);
|
|
32612
|
+
if (details.cause !== void 0) {
|
|
32613
|
+
this.cause = details.cause;
|
|
32614
|
+
}
|
|
32615
|
+
this.name = "GitCommandError";
|
|
32616
|
+
this.reason = reason;
|
|
32617
|
+
this.stdout = normalizeGitOutput(details.stdout);
|
|
32618
|
+
this.stderr = normalizeGitOutput(details.stderr);
|
|
32619
|
+
this.exitCode = details.exitCode;
|
|
32620
|
+
this.signal = details.signal;
|
|
32621
|
+
this.argv = details.argv ? [...details.argv] : void 0;
|
|
32622
|
+
this.cwd = details.cwd;
|
|
32623
|
+
}
|
|
32624
|
+
};
|
|
32625
|
+
async function resolveGitRepository(workspace, options = {}) {
|
|
32626
|
+
const normalizedWorkspace = await validateWorkspace(workspace);
|
|
32627
|
+
const result = await execGitRaw(normalizedWorkspace, ["rev-parse", "--show-toplevel"], options, {
|
|
32628
|
+
mapNotGitRepo: true
|
|
32629
|
+
});
|
|
32630
|
+
const repoRoot = path5.resolve(result.stdout.trim());
|
|
32631
|
+
if (!repoRoot) {
|
|
32632
|
+
throw new GitCommandError("not_git_repo", "Git did not return a repository root", {
|
|
32633
|
+
stdout: result.stdout,
|
|
32634
|
+
stderr: result.stderr,
|
|
32635
|
+
argv: ["rev-parse", "--show-toplevel"],
|
|
32636
|
+
cwd: normalizedWorkspace
|
|
32637
|
+
});
|
|
32638
|
+
}
|
|
32639
|
+
return {
|
|
32640
|
+
workspace: normalizedWorkspace,
|
|
32641
|
+
repoRoot,
|
|
32642
|
+
isGitRepo: true
|
|
32643
|
+
};
|
|
32644
|
+
}
|
|
32645
|
+
async function runGit(repoOrWorkspace, argv, options = {}) {
|
|
32646
|
+
validateGitArgv(argv);
|
|
32647
|
+
const repo = typeof repoOrWorkspace === "string" ? await resolveGitRepository(repoOrWorkspace, options) : repoOrWorkspace;
|
|
32648
|
+
if (!repo.repoRoot || !repo.isGitRepo) {
|
|
32649
|
+
throw new GitCommandError("not_git_repo", "Workspace is not a Git repository", {
|
|
32650
|
+
argv,
|
|
32651
|
+
cwd: repo.workspace
|
|
32652
|
+
});
|
|
32653
|
+
}
|
|
32654
|
+
const cwd = options.cwd ? await validateWorkspace(options.cwd) : await validateWorkspace(repo.workspace);
|
|
32655
|
+
const canonicalRepoRoot = await (0, import_promises4.realpath)(repo.repoRoot);
|
|
32656
|
+
const canonicalCwd = await (0, import_promises4.realpath)(cwd);
|
|
32657
|
+
if (!isPathInside(canonicalRepoRoot, canonicalCwd)) {
|
|
32658
|
+
throw new GitCommandError("path_outside_repo", "Git cwd is outside the repository root", {
|
|
32659
|
+
argv,
|
|
32660
|
+
cwd
|
|
32661
|
+
});
|
|
32662
|
+
}
|
|
32663
|
+
return execGitRaw(cwd, argv, options);
|
|
32664
|
+
}
|
|
32665
|
+
function normalizeGitOutput(value) {
|
|
32666
|
+
if (typeof value === "string") return value.replace(/\r\n/g, "\n");
|
|
32667
|
+
if (Buffer.isBuffer(value)) return value.toString("utf8").replace(/\r\n/g, "\n");
|
|
32668
|
+
if (value == null) return "";
|
|
32669
|
+
return String(value).replace(/\r\n/g, "\n");
|
|
32670
|
+
}
|
|
32671
|
+
function isPathInside(parent, child) {
|
|
32672
|
+
const relative3 = path5.relative(path5.resolve(parent), path5.resolve(child));
|
|
32673
|
+
return relative3 === "" || !relative3.startsWith("..") && !path5.isAbsolute(relative3);
|
|
32674
|
+
}
|
|
32675
|
+
async function validateWorkspace(workspace) {
|
|
32676
|
+
if (typeof workspace !== "string" || workspace.length === 0 || workspace.includes("\0")) {
|
|
32677
|
+
throw new GitCommandError("invalid_args", "Workspace must be a non-empty path");
|
|
32678
|
+
}
|
|
32679
|
+
if (!path5.isAbsolute(workspace)) {
|
|
32680
|
+
throw new GitCommandError("invalid_args", "Workspace must be an absolute path", { cwd: workspace });
|
|
32681
|
+
}
|
|
32682
|
+
const normalizedWorkspace = path5.resolve(workspace);
|
|
32683
|
+
try {
|
|
32684
|
+
const info = await (0, import_promises4.stat)(normalizedWorkspace);
|
|
32685
|
+
if (!info.isDirectory()) {
|
|
32686
|
+
throw new GitCommandError("invalid_args", "Workspace must be an existing directory", {
|
|
32687
|
+
cwd: normalizedWorkspace
|
|
32688
|
+
});
|
|
32689
|
+
}
|
|
32690
|
+
await (0, import_promises4.access)(normalizedWorkspace, import_node_fs3.constants.R_OK);
|
|
32691
|
+
} catch (error48) {
|
|
32692
|
+
if (error48 instanceof GitCommandError) throw error48;
|
|
32693
|
+
throw new GitCommandError("invalid_args", "Workspace must be an existing directory", {
|
|
32694
|
+
cwd: normalizedWorkspace,
|
|
32695
|
+
cause: error48
|
|
32696
|
+
});
|
|
32697
|
+
}
|
|
32698
|
+
return normalizedWorkspace;
|
|
32699
|
+
}
|
|
32700
|
+
function validateGitArgv(argv) {
|
|
32701
|
+
if (!Array.isArray(argv) || argv.length === 0) {
|
|
32702
|
+
throw new GitCommandError("invalid_args", "Git argv must be a non-empty string array", { argv });
|
|
32703
|
+
}
|
|
32704
|
+
for (const arg of argv) {
|
|
32705
|
+
if (typeof arg !== "string" || arg.length === 0 || arg.includes("\0")) {
|
|
32706
|
+
throw new GitCommandError("invalid_args", "Git argv contains an invalid argument", { argv });
|
|
32707
|
+
}
|
|
32708
|
+
}
|
|
32709
|
+
if (argv.includes("-C") || argv.some((arg) => arg.startsWith("--git-dir") || arg.startsWith("--work-tree"))) {
|
|
32710
|
+
throw new GitCommandError("invalid_args", "Git argv contains unsafe repository override arguments", {
|
|
32711
|
+
argv
|
|
32712
|
+
});
|
|
32713
|
+
}
|
|
32714
|
+
}
|
|
32715
|
+
async function execGitRaw(cwd, argv, options, behavior = {}) {
|
|
32716
|
+
validateGitArgv(argv);
|
|
32717
|
+
try {
|
|
32718
|
+
const result = await execFileAsync("git", [...argv], {
|
|
32719
|
+
cwd,
|
|
32720
|
+
encoding: "utf8",
|
|
32721
|
+
timeout: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
32722
|
+
maxBuffer: options.maxBuffer ?? DEFAULT_MAX_BUFFER,
|
|
32723
|
+
windowsHide: true
|
|
32724
|
+
});
|
|
32725
|
+
return {
|
|
32726
|
+
stdout: normalizeGitOutput(result.stdout),
|
|
32727
|
+
stderr: normalizeGitOutput(result.stderr)
|
|
32728
|
+
};
|
|
32729
|
+
} catch (error48) {
|
|
32730
|
+
throw mapExecError(error48, cwd, argv, behavior);
|
|
32731
|
+
}
|
|
32732
|
+
}
|
|
32733
|
+
function mapExecError(error48, cwd, argv, behavior) {
|
|
32734
|
+
const execError = error48;
|
|
32735
|
+
const stdout = normalizeGitOutput(execError.stdout);
|
|
32736
|
+
const stderr = normalizeGitOutput(execError.stderr);
|
|
32737
|
+
const code = execError.code;
|
|
32738
|
+
const signal = execError.signal;
|
|
32739
|
+
const message = [stderr.trim(), execError.message].filter(Boolean).join("\n");
|
|
32740
|
+
if (code === "ENOENT") {
|
|
32741
|
+
return new GitCommandError("git_not_installed", "Git executable was not found", {
|
|
32742
|
+
stdout,
|
|
32743
|
+
stderr,
|
|
32744
|
+
exitCode: code,
|
|
32745
|
+
signal,
|
|
32746
|
+
argv,
|
|
32747
|
+
cwd,
|
|
32748
|
+
cause: error48
|
|
32749
|
+
});
|
|
32750
|
+
}
|
|
32751
|
+
if (execError.killed || /timed out/i.test(execError.message)) {
|
|
32752
|
+
return new GitCommandError("timeout", "Git command timed out", {
|
|
32753
|
+
stdout,
|
|
32754
|
+
stderr,
|
|
32755
|
+
exitCode: code,
|
|
32756
|
+
signal,
|
|
32757
|
+
argv,
|
|
32758
|
+
cwd,
|
|
32759
|
+
cause: error48
|
|
32760
|
+
});
|
|
32761
|
+
}
|
|
32762
|
+
if (behavior.mapNotGitRepo && /not a git repository/i.test(stderr + "\n" + execError.message)) {
|
|
32763
|
+
return new GitCommandError("not_git_repo", "Workspace is not a Git repository", {
|
|
32764
|
+
stdout,
|
|
32765
|
+
stderr,
|
|
32766
|
+
exitCode: code,
|
|
32767
|
+
signal,
|
|
32768
|
+
argv,
|
|
32769
|
+
cwd,
|
|
32770
|
+
cause: error48
|
|
32771
|
+
});
|
|
32772
|
+
}
|
|
32773
|
+
return new GitCommandError("git_command_failed", message || "Git command failed", {
|
|
32774
|
+
stdout,
|
|
32775
|
+
stderr,
|
|
32776
|
+
exitCode: code,
|
|
32777
|
+
signal,
|
|
32778
|
+
argv,
|
|
32779
|
+
cwd,
|
|
32780
|
+
cause: error48
|
|
32781
|
+
});
|
|
32782
|
+
}
|
|
32783
|
+
async function getGitRepoStatus(workspace, options = {}) {
|
|
32784
|
+
const lastCheckedAt = Date.now();
|
|
32785
|
+
try {
|
|
32786
|
+
const repo = await resolveGitRepository(workspace, options);
|
|
32787
|
+
const statusOutput = await runGit(repo, ["status", "--porcelain=v2", "--branch"], options);
|
|
32788
|
+
const parsed = parsePorcelainV2Status(statusOutput.stdout);
|
|
32789
|
+
const head = await readHead(repo, options);
|
|
32790
|
+
const stashCount = await readStashCount(repo, options);
|
|
32791
|
+
return {
|
|
32792
|
+
workspace: repo.workspace,
|
|
32793
|
+
repoRoot: repo.repoRoot,
|
|
32794
|
+
isGitRepo: true,
|
|
32795
|
+
branch: parsed.branch,
|
|
32796
|
+
headCommit: head.commit,
|
|
32797
|
+
headMessage: head.message,
|
|
32798
|
+
upstream: parsed.upstream,
|
|
32799
|
+
ahead: parsed.ahead,
|
|
32800
|
+
behind: parsed.behind,
|
|
32801
|
+
staged: parsed.staged,
|
|
32802
|
+
modified: parsed.modified,
|
|
32803
|
+
untracked: parsed.untracked,
|
|
32804
|
+
deleted: parsed.deleted,
|
|
32805
|
+
renamed: parsed.renamed,
|
|
32806
|
+
hasConflicts: parsed.conflictFiles.length > 0,
|
|
32807
|
+
conflictFiles: parsed.conflictFiles,
|
|
32808
|
+
stashCount,
|
|
32809
|
+
lastCheckedAt
|
|
32810
|
+
};
|
|
32811
|
+
} catch (error48) {
|
|
32812
|
+
if (error48 instanceof GitCommandError) {
|
|
32813
|
+
return emptyStatus(workspace, lastCheckedAt, error48);
|
|
32814
|
+
}
|
|
32815
|
+
return emptyStatus(
|
|
32816
|
+
workspace,
|
|
32817
|
+
lastCheckedAt,
|
|
32818
|
+
new GitCommandError("git_command_failed", "Failed to read Git status", { cause: error48 })
|
|
32819
|
+
);
|
|
32820
|
+
}
|
|
32821
|
+
}
|
|
32822
|
+
function parsePorcelainV2Status(output) {
|
|
32823
|
+
const parsed = {
|
|
32824
|
+
branch: null,
|
|
32825
|
+
upstream: null,
|
|
32826
|
+
ahead: 0,
|
|
32827
|
+
behind: 0,
|
|
32828
|
+
staged: 0,
|
|
32829
|
+
modified: 0,
|
|
32830
|
+
untracked: 0,
|
|
32831
|
+
deleted: 0,
|
|
32832
|
+
renamed: 0,
|
|
32833
|
+
conflictFiles: []
|
|
32834
|
+
};
|
|
32835
|
+
for (const line of output.split("\n")) {
|
|
32836
|
+
if (!line) continue;
|
|
32837
|
+
if (line.startsWith("# branch.head ")) {
|
|
32838
|
+
const branch = line.slice("# branch.head ".length).trim();
|
|
32839
|
+
parsed.branch = branch && branch !== "(detached)" ? branch : null;
|
|
32840
|
+
continue;
|
|
32841
|
+
}
|
|
32842
|
+
if (line.startsWith("# branch.upstream ")) {
|
|
32843
|
+
parsed.upstream = line.slice("# branch.upstream ".length).trim() || null;
|
|
32844
|
+
continue;
|
|
32845
|
+
}
|
|
32846
|
+
if (line.startsWith("# branch.ab ")) {
|
|
32847
|
+
const match = line.match(/\+(-?\d+)\s+-(-?\d+)/);
|
|
32848
|
+
if (match) {
|
|
32849
|
+
parsed.ahead = Number.parseInt(match[1] ?? "0", 10) || 0;
|
|
32850
|
+
parsed.behind = Number.parseInt(match[2] ?? "0", 10) || 0;
|
|
32851
|
+
}
|
|
32852
|
+
continue;
|
|
32853
|
+
}
|
|
32854
|
+
if (line.startsWith("? ")) {
|
|
32855
|
+
parsed.untracked += 1;
|
|
32856
|
+
continue;
|
|
32857
|
+
}
|
|
32858
|
+
if (line.startsWith("u ")) {
|
|
32859
|
+
const fields = line.split(" ");
|
|
32860
|
+
const filePath = fields.slice(10).join(" ");
|
|
32861
|
+
if (filePath) parsed.conflictFiles.push(filePath);
|
|
32862
|
+
continue;
|
|
32863
|
+
}
|
|
32864
|
+
if (line.startsWith("1 ") || line.startsWith("2 ")) {
|
|
32865
|
+
const fields = line.split(" ");
|
|
32866
|
+
const xy = fields[1] ?? "..";
|
|
32867
|
+
const indexStatus = xy[0] ?? ".";
|
|
32868
|
+
const worktreeStatus = xy[1] ?? ".";
|
|
32869
|
+
if (isStagedStatus(indexStatus)) parsed.staged += 1;
|
|
32870
|
+
if (worktreeStatus === "M" || worktreeStatus === "T") parsed.modified += 1;
|
|
32871
|
+
if (indexStatus === "D" || worktreeStatus === "D") parsed.deleted += 1;
|
|
32872
|
+
if (indexStatus === "R" || worktreeStatus === "R") parsed.renamed += 1;
|
|
32873
|
+
if (xy.includes("U")) {
|
|
32874
|
+
const filePath = fields.slice(line.startsWith("2 ") ? 9 : 8).join(" ").split(" ")[0] ?? "";
|
|
32875
|
+
if (filePath) parsed.conflictFiles.push(filePath);
|
|
32876
|
+
}
|
|
32877
|
+
}
|
|
32878
|
+
}
|
|
32879
|
+
parsed.conflictFiles = Array.from(new Set(parsed.conflictFiles));
|
|
32880
|
+
return parsed;
|
|
32881
|
+
}
|
|
32882
|
+
async function readHead(repo, options) {
|
|
32883
|
+
try {
|
|
32884
|
+
const result = await runGit(repo, ["log", "-1", "--pretty=%h%x00%s"], options);
|
|
32885
|
+
const text = result.stdout.trimEnd();
|
|
32886
|
+
if (!text) return { commit: null, message: null };
|
|
32887
|
+
const [commit, ...messageParts] = text.split("\0");
|
|
32888
|
+
return {
|
|
32889
|
+
commit: commit || null,
|
|
32890
|
+
message: messageParts.join("\0") || null
|
|
32891
|
+
};
|
|
32892
|
+
} catch {
|
|
32893
|
+
return { commit: null, message: null };
|
|
32894
|
+
}
|
|
32895
|
+
}
|
|
32896
|
+
async function readStashCount(repo, options) {
|
|
32897
|
+
try {
|
|
32898
|
+
const result = await runGit(repo, ["stash", "list", "--format=%gd"], options);
|
|
32899
|
+
return result.stdout.split("\n").filter((line) => line.trim().length > 0).length;
|
|
32900
|
+
} catch {
|
|
32901
|
+
return 0;
|
|
32902
|
+
}
|
|
32903
|
+
}
|
|
32904
|
+
function isStagedStatus(status) {
|
|
32905
|
+
return status !== "." && status !== "?" && status !== "U";
|
|
32906
|
+
}
|
|
32907
|
+
function emptyStatus(workspace, lastCheckedAt, error48) {
|
|
32908
|
+
return {
|
|
32909
|
+
workspace,
|
|
32910
|
+
repoRoot: null,
|
|
32911
|
+
isGitRepo: false,
|
|
32912
|
+
branch: null,
|
|
32913
|
+
headCommit: null,
|
|
32914
|
+
headMessage: null,
|
|
32915
|
+
upstream: null,
|
|
32916
|
+
ahead: 0,
|
|
32917
|
+
behind: 0,
|
|
32918
|
+
staged: 0,
|
|
32919
|
+
modified: 0,
|
|
32920
|
+
untracked: 0,
|
|
32921
|
+
deleted: 0,
|
|
32922
|
+
renamed: 0,
|
|
32923
|
+
hasConflicts: false,
|
|
32924
|
+
conflictFiles: [],
|
|
32925
|
+
stashCount: 0,
|
|
32926
|
+
lastCheckedAt,
|
|
32927
|
+
error: error48.stderr || error48.message,
|
|
32928
|
+
reason: error48.reason
|
|
32929
|
+
};
|
|
32930
|
+
}
|
|
32931
|
+
var import_promises22 = require("fs/promises");
|
|
32932
|
+
var path23 = __toESM2(require("path"));
|
|
32933
|
+
var DEFAULT_MAX_FILES = 200;
|
|
32934
|
+
var DEFAULT_MAX_BYTES = 2e5;
|
|
32935
|
+
async function getGitDiffSummary(workspace, options = {}) {
|
|
32936
|
+
const lastCheckedAt = Date.now();
|
|
32937
|
+
try {
|
|
32938
|
+
const repo = await resolveGitRepository(workspace, options);
|
|
32939
|
+
const repoRoot = repo.repoRoot;
|
|
32940
|
+
const [unstagedNameStatus, unstagedNumstat, stagedNameStatus, stagedNumstat, untracked] = await Promise.all([
|
|
32941
|
+
runGit(repo, ["diff", "--no-ext-diff", "--name-status"], { ...options, cwd: repoRoot }),
|
|
32942
|
+
runGit(repo, ["diff", "--no-ext-diff", "--numstat"], { ...options, cwd: repoRoot }),
|
|
32943
|
+
runGit(repo, ["diff", "--cached", "--no-ext-diff", "--name-status"], { ...options, cwd: repoRoot }),
|
|
32944
|
+
runGit(repo, ["diff", "--cached", "--no-ext-diff", "--numstat"], { ...options, cwd: repoRoot }),
|
|
32945
|
+
runGit(repo, ["ls-files", "--others", "--exclude-standard"], { ...options, cwd: repoRoot })
|
|
32946
|
+
]);
|
|
32947
|
+
const outputBytes = byteLength(
|
|
32948
|
+
unstagedNameStatus.stdout + unstagedNumstat.stdout + stagedNameStatus.stdout + stagedNumstat.stdout + untracked.stdout
|
|
32949
|
+
);
|
|
32950
|
+
const changes = [
|
|
32951
|
+
...combineDiffEntries(unstagedNameStatus.stdout, unstagedNumstat.stdout, false),
|
|
32952
|
+
...combineDiffEntries(stagedNameStatus.stdout, stagedNumstat.stdout, true),
|
|
32953
|
+
...parseUntrackedFiles(untracked.stdout)
|
|
32954
|
+
];
|
|
32955
|
+
const maxFiles = normalizePositiveInteger(options.maxFiles, DEFAULT_MAX_FILES);
|
|
32956
|
+
const maxBytes = normalizePositiveInteger(options.maxBytes, DEFAULT_MAX_BYTES);
|
|
32957
|
+
const files = changes.slice(0, maxFiles);
|
|
32958
|
+
const truncated = changes.length > files.length || outputBytes > maxBytes;
|
|
32959
|
+
return {
|
|
32960
|
+
workspace: repo.workspace,
|
|
32961
|
+
repoRoot,
|
|
32962
|
+
isGitRepo: true,
|
|
32963
|
+
files,
|
|
32964
|
+
totalInsertions: files.reduce((sum, file2) => sum + file2.insertions, 0),
|
|
32965
|
+
totalDeletions: files.reduce((sum, file2) => sum + file2.deletions, 0),
|
|
32966
|
+
truncated,
|
|
32967
|
+
lastCheckedAt
|
|
32968
|
+
};
|
|
32969
|
+
} catch (error48) {
|
|
32970
|
+
const gitError = error48 instanceof GitCommandError ? error48 : new GitCommandError("git_command_failed", "Failed to read Git diff summary", { cause: error48 });
|
|
32971
|
+
return {
|
|
32972
|
+
workspace,
|
|
32973
|
+
repoRoot: null,
|
|
32974
|
+
isGitRepo: false,
|
|
32975
|
+
files: [],
|
|
32976
|
+
totalInsertions: 0,
|
|
32977
|
+
totalDeletions: 0,
|
|
32978
|
+
truncated: false,
|
|
32979
|
+
lastCheckedAt,
|
|
32980
|
+
error: gitError.stderr || gitError.message,
|
|
32981
|
+
reason: gitError.reason
|
|
32982
|
+
};
|
|
32983
|
+
}
|
|
32984
|
+
}
|
|
32985
|
+
async function getGitFileDiff(workspace, filePath, options = {}) {
|
|
32986
|
+
const lastCheckedAt = Date.now();
|
|
32987
|
+
const repo = await resolveGitRepository(workspace, options);
|
|
32988
|
+
const repoRoot = repo.repoRoot;
|
|
32989
|
+
const selected = await resolveRepoFilePath(repoRoot, filePath);
|
|
32990
|
+
const maxBytes = normalizePositiveInteger(options.maxBytes, DEFAULT_MAX_BYTES);
|
|
32991
|
+
const [unstaged, staged] = await Promise.all([
|
|
32992
|
+
runGit(repo, ["diff", "--no-ext-diff", "--", selected.relativePath], { ...options, cwd: repoRoot }),
|
|
32993
|
+
runGit(repo, ["diff", "--cached", "--no-ext-diff", "--", selected.relativePath], { ...options, cwd: repoRoot })
|
|
32994
|
+
]);
|
|
32995
|
+
let diff = [unstaged.stdout, staged.stdout].filter((part) => part.length > 0).join("\n");
|
|
32996
|
+
if (!diff) {
|
|
32997
|
+
const untracked = await runGit(repo, ["ls-files", "--others", "--exclude-standard", "--", selected.relativePath], {
|
|
32998
|
+
...options,
|
|
32999
|
+
cwd: repoRoot
|
|
33000
|
+
});
|
|
33001
|
+
const untrackedFiles = untracked.stdout.split("\n").filter(Boolean);
|
|
33002
|
+
if (untrackedFiles.includes(selected.relativePath)) {
|
|
33003
|
+
diff = await buildUntrackedDiff(selected.absolutePath, selected.relativePath, maxBytes + 1);
|
|
33004
|
+
}
|
|
33005
|
+
}
|
|
33006
|
+
const bounded = truncateText(diff, maxBytes);
|
|
33007
|
+
return {
|
|
33008
|
+
workspace: repo.workspace,
|
|
33009
|
+
repoRoot,
|
|
33010
|
+
isGitRepo: true,
|
|
33011
|
+
path: selected.relativePath,
|
|
33012
|
+
diff: bounded.text,
|
|
33013
|
+
truncated: bounded.truncated,
|
|
33014
|
+
lastCheckedAt
|
|
33015
|
+
};
|
|
33016
|
+
}
|
|
33017
|
+
function combineDiffEntries(nameStatusOutput, numstatOutput, staged) {
|
|
33018
|
+
const statusEntries = parseNameStatus(nameStatusOutput);
|
|
33019
|
+
const numstatEntries = parseNumstat(numstatOutput);
|
|
33020
|
+
return statusEntries.map((entry, index) => {
|
|
33021
|
+
const stats = numstatEntries[index];
|
|
33022
|
+
return {
|
|
33023
|
+
path: entry.path,
|
|
33024
|
+
oldPath: entry.oldPath,
|
|
33025
|
+
status: entry.status,
|
|
33026
|
+
staged,
|
|
33027
|
+
insertions: stats?.insertions ?? 0,
|
|
33028
|
+
deletions: stats?.deletions ?? 0,
|
|
33029
|
+
binary: stats?.binary || void 0
|
|
33030
|
+
};
|
|
33031
|
+
});
|
|
33032
|
+
}
|
|
33033
|
+
function parseNameStatus(output) {
|
|
33034
|
+
return output.split("\n").filter(Boolean).map((line) => {
|
|
33035
|
+
const fields = line.split(" ");
|
|
33036
|
+
const code = fields[0] ?? "";
|
|
33037
|
+
const statusLetter = code[0] ?? "M";
|
|
33038
|
+
if (statusLetter === "R") {
|
|
33039
|
+
return {
|
|
33040
|
+
oldPath: fields[1] ?? "",
|
|
33041
|
+
path: fields[2] ?? fields[1] ?? "",
|
|
33042
|
+
status: "renamed"
|
|
33043
|
+
};
|
|
33044
|
+
}
|
|
33045
|
+
if (statusLetter === "C") {
|
|
33046
|
+
return {
|
|
33047
|
+
oldPath: fields[1] ?? "",
|
|
33048
|
+
path: fields[2] ?? fields[1] ?? "",
|
|
33049
|
+
status: "copied"
|
|
33050
|
+
};
|
|
33051
|
+
}
|
|
33052
|
+
return {
|
|
33053
|
+
path: fields[1] ?? "",
|
|
33054
|
+
status: mapNameStatus(statusLetter)
|
|
33055
|
+
};
|
|
33056
|
+
}).filter((entry) => entry.path.length > 0);
|
|
33057
|
+
}
|
|
33058
|
+
function parseNumstat(output) {
|
|
33059
|
+
return output.split("\n").filter(Boolean).map((line) => {
|
|
33060
|
+
const fields = line.split(" ");
|
|
33061
|
+
const insertionsText = fields[0] ?? "0";
|
|
33062
|
+
const deletionsText = fields[1] ?? "0";
|
|
33063
|
+
const binary = insertionsText === "-" || deletionsText === "-";
|
|
33064
|
+
return {
|
|
33065
|
+
path: fields.slice(2).join(" "),
|
|
33066
|
+
insertions: binary ? 0 : Number.parseInt(insertionsText, 10) || 0,
|
|
33067
|
+
deletions: binary ? 0 : Number.parseInt(deletionsText, 10) || 0,
|
|
33068
|
+
binary
|
|
33069
|
+
};
|
|
33070
|
+
});
|
|
33071
|
+
}
|
|
33072
|
+
function parseUntrackedFiles(output) {
|
|
33073
|
+
return output.split("\n").filter(Boolean).map((filePath) => ({
|
|
33074
|
+
path: filePath,
|
|
33075
|
+
status: "untracked",
|
|
33076
|
+
staged: false,
|
|
33077
|
+
insertions: 0,
|
|
33078
|
+
deletions: 0
|
|
33079
|
+
}));
|
|
33080
|
+
}
|
|
33081
|
+
function mapNameStatus(status) {
|
|
33082
|
+
switch (status) {
|
|
33083
|
+
case "A":
|
|
33084
|
+
return "added";
|
|
33085
|
+
case "D":
|
|
33086
|
+
return "deleted";
|
|
33087
|
+
case "R":
|
|
33088
|
+
return "renamed";
|
|
33089
|
+
case "C":
|
|
33090
|
+
return "copied";
|
|
33091
|
+
case "U":
|
|
33092
|
+
return "conflict";
|
|
33093
|
+
case "M":
|
|
33094
|
+
case "T":
|
|
33095
|
+
default:
|
|
33096
|
+
return "modified";
|
|
33097
|
+
}
|
|
33098
|
+
}
|
|
33099
|
+
async function resolveRepoFilePath(repoRoot, filePath) {
|
|
33100
|
+
if (typeof filePath !== "string" || filePath.length === 0 || filePath.includes("\0")) {
|
|
33101
|
+
throw new GitCommandError("invalid_args", "File path must be a non-empty path");
|
|
33102
|
+
}
|
|
33103
|
+
const canonicalRepoRoot = await (0, import_promises22.realpath)(repoRoot).catch(() => path23.resolve(repoRoot));
|
|
33104
|
+
const absolutePath = path23.isAbsolute(filePath) ? path23.resolve(filePath) : path23.resolve(repoRoot, filePath);
|
|
33105
|
+
const checkPath = await (0, import_promises22.realpath)(absolutePath).catch(() => absolutePath);
|
|
33106
|
+
const relativeBase = isPathInside(canonicalRepoRoot, checkPath) ? canonicalRepoRoot : path23.resolve(repoRoot);
|
|
33107
|
+
if (!isPathInside(canonicalRepoRoot, checkPath) && !isPathInside(repoRoot, absolutePath)) {
|
|
33108
|
+
throw new GitCommandError("path_outside_repo", "Selected file path is outside the repository root", {
|
|
33109
|
+
cwd: repoRoot
|
|
33110
|
+
});
|
|
33111
|
+
}
|
|
33112
|
+
const relativePath = path23.relative(relativeBase, checkPath).split(path23.sep).join("/");
|
|
33113
|
+
if (!relativePath || relativePath.startsWith("..") || path23.isAbsolute(relativePath)) {
|
|
33114
|
+
throw new GitCommandError("path_outside_repo", "Selected file path is outside the repository root", {
|
|
33115
|
+
cwd: repoRoot
|
|
33116
|
+
});
|
|
33117
|
+
}
|
|
33118
|
+
return { absolutePath, relativePath };
|
|
33119
|
+
}
|
|
33120
|
+
async function buildUntrackedDiff(absolutePath, relativePath, readLimit) {
|
|
33121
|
+
const content = await (0, import_promises22.readFile)(absolutePath, "utf8");
|
|
33122
|
+
const limitedContent = content.length > readLimit ? content.slice(0, readLimit) : content;
|
|
33123
|
+
const lines = limitedContent.length > 0 ? limitedContent.split("\n") : [];
|
|
33124
|
+
const plusLines = lines.filter((line, index) => index < lines.length - 1 || line.length > 0).map((line) => `+${line}`).join("\n");
|
|
33125
|
+
const lineCount = plusLines ? plusLines.split("\n").length : 0;
|
|
33126
|
+
return [
|
|
33127
|
+
`diff --git a/${relativePath} b/${relativePath}`,
|
|
33128
|
+
"new file mode 100644",
|
|
33129
|
+
"index 0000000..0000000",
|
|
33130
|
+
"--- /dev/null",
|
|
33131
|
+
`+++ b/${relativePath}`,
|
|
33132
|
+
`@@ -0,0 +1,${lineCount} @@`,
|
|
33133
|
+
plusLines
|
|
33134
|
+
].filter((line) => line.length > 0).join("\n");
|
|
33135
|
+
}
|
|
33136
|
+
function truncateText(text, maxBytes) {
|
|
33137
|
+
if (byteLength(text) <= maxBytes) return { text, truncated: false };
|
|
33138
|
+
return { text: Buffer.from(text, "utf8").subarray(0, maxBytes).toString("utf8"), truncated: true };
|
|
33139
|
+
}
|
|
33140
|
+
function byteLength(text) {
|
|
33141
|
+
return Buffer.byteLength(text, "utf8");
|
|
33142
|
+
}
|
|
33143
|
+
function normalizePositiveInteger(value, fallback) {
|
|
33144
|
+
if (!Number.isFinite(value) || value == null || value <= 0) return fallback;
|
|
33145
|
+
return Math.floor(value);
|
|
33146
|
+
}
|
|
33147
|
+
function countStatusChangedFiles(status) {
|
|
33148
|
+
const conflictCount = status.conflictFiles.length > 0 ? status.conflictFiles.length : status.hasConflicts ? 1 : 0;
|
|
33149
|
+
return status.staged + status.modified + status.untracked + status.deleted + status.renamed + conflictCount;
|
|
33150
|
+
}
|
|
33151
|
+
function createGitCompactSummary(status, diffSummary) {
|
|
33152
|
+
const statusChangedFiles = countStatusChangedFiles(status);
|
|
33153
|
+
const diffChangedFiles = diffSummary?.files.length ?? 0;
|
|
33154
|
+
const changedFiles = Math.max(statusChangedFiles, diffChangedFiles);
|
|
33155
|
+
const conflictCount = status.conflictFiles.length > 0 ? status.conflictFiles.length : status.hasConflicts ? 1 : 0;
|
|
33156
|
+
return {
|
|
33157
|
+
isGitRepo: status.isGitRepo,
|
|
33158
|
+
repoRoot: status.repoRoot,
|
|
33159
|
+
branch: status.branch,
|
|
33160
|
+
dirty: status.staged > 0 || status.modified > 0 || status.untracked > 0 || status.deleted > 0 || status.renamed > 0 || conflictCount > 0 || changedFiles > 0,
|
|
33161
|
+
changedFiles,
|
|
33162
|
+
ahead: status.ahead,
|
|
33163
|
+
behind: status.behind,
|
|
33164
|
+
hasConflicts: status.hasConflicts || conflictCount > 0,
|
|
33165
|
+
lastCheckedAt: Math.max(status.lastCheckedAt, diffSummary?.lastCheckedAt ?? status.lastCheckedAt),
|
|
33166
|
+
error: status.error ?? diffSummary?.error,
|
|
33167
|
+
reason: status.reason ?? diffSummary?.reason
|
|
33168
|
+
};
|
|
33169
|
+
}
|
|
33170
|
+
var summarizeGitStatus = createGitCompactSummary;
|
|
33171
|
+
function normalizeCapacity(capacity) {
|
|
33172
|
+
return Math.max(1, Math.floor(capacity ?? 100));
|
|
33173
|
+
}
|
|
33174
|
+
function createEmptyDiffSummary(status) {
|
|
33175
|
+
return {
|
|
33176
|
+
workspace: status.workspace,
|
|
33177
|
+
repoRoot: status.repoRoot,
|
|
33178
|
+
isGitRepo: status.isGitRepo,
|
|
33179
|
+
files: [],
|
|
33180
|
+
totalInsertions: 0,
|
|
33181
|
+
totalDeletions: 0,
|
|
33182
|
+
truncated: false,
|
|
33183
|
+
lastCheckedAt: status.lastCheckedAt,
|
|
33184
|
+
error: status.error,
|
|
33185
|
+
reason: status.reason
|
|
33186
|
+
};
|
|
33187
|
+
}
|
|
33188
|
+
function changedFileKey(file2) {
|
|
33189
|
+
return `${file2.oldPath ?? ""}\0${file2.path}`;
|
|
33190
|
+
}
|
|
33191
|
+
function uniqueSorted(values) {
|
|
33192
|
+
return Array.from(new Set(Array.from(values).filter(Boolean))).sort((a, b2) => a.localeCompare(b2));
|
|
33193
|
+
}
|
|
33194
|
+
function plural(count, singular, pluralText = `${singular}s`) {
|
|
33195
|
+
return count === 1 ? singular : pluralText;
|
|
33196
|
+
}
|
|
33197
|
+
function compareGitSnapshots(before, after) {
|
|
33198
|
+
const beforeFileKeys = new Set(before.diffSummary.files.map(changedFileKey));
|
|
33199
|
+
const changedAfterFiles = after.diffSummary.files.filter((file2) => !beforeFileKeys.has(changedFileKey(file2)));
|
|
33200
|
+
const addedFiles = [];
|
|
33201
|
+
const modifiedFiles = [];
|
|
33202
|
+
const deletedFiles = [];
|
|
33203
|
+
const renamedFiles = [];
|
|
33204
|
+
const untrackedFiles = [];
|
|
33205
|
+
const conflictFilesFromDiff = [];
|
|
33206
|
+
let totalInsertions = 0;
|
|
33207
|
+
let totalDeletions = 0;
|
|
33208
|
+
for (const file2 of changedAfterFiles) {
|
|
33209
|
+
totalInsertions += file2.insertions;
|
|
33210
|
+
totalDeletions += file2.deletions;
|
|
33211
|
+
switch (file2.status) {
|
|
33212
|
+
case "added":
|
|
33213
|
+
case "copied":
|
|
33214
|
+
addedFiles.push(file2.path);
|
|
33215
|
+
break;
|
|
33216
|
+
case "modified":
|
|
33217
|
+
modifiedFiles.push(file2.path);
|
|
33218
|
+
break;
|
|
33219
|
+
case "deleted":
|
|
33220
|
+
deletedFiles.push(file2.path);
|
|
33221
|
+
break;
|
|
33222
|
+
case "renamed":
|
|
33223
|
+
renamedFiles.push({ oldPath: file2.oldPath ?? file2.path, path: file2.path });
|
|
33224
|
+
break;
|
|
33225
|
+
case "untracked":
|
|
33226
|
+
untrackedFiles.push(file2.path);
|
|
33227
|
+
break;
|
|
33228
|
+
case "conflict":
|
|
33229
|
+
conflictFilesFromDiff.push(file2.path);
|
|
33230
|
+
break;
|
|
33231
|
+
}
|
|
33232
|
+
}
|
|
33233
|
+
renamedFiles.sort((a, b2) => `${a.oldPath}\0${a.path}`.localeCompare(`${b2.oldPath}\0${b2.path}`));
|
|
33234
|
+
const conflictFiles = uniqueSorted([...after.status.conflictFiles, ...conflictFilesFromDiff]);
|
|
33235
|
+
const changedFiles = changedAfterFiles.length;
|
|
33236
|
+
const hasConflicts = after.status.hasConflicts || conflictFiles.length > 0;
|
|
33237
|
+
const summaryParts = [];
|
|
33238
|
+
if (changedFiles > 0) summaryParts.push(`${changedFiles} ${plural(changedFiles, "file")} changed`);
|
|
33239
|
+
if (addedFiles.length > 0) summaryParts.push(`${addedFiles.length} added`);
|
|
33240
|
+
if (modifiedFiles.length > 0) summaryParts.push(`${modifiedFiles.length} modified`);
|
|
33241
|
+
if (deletedFiles.length > 0) summaryParts.push(`${deletedFiles.length} deleted`);
|
|
33242
|
+
if (renamedFiles.length > 0) summaryParts.push(`${renamedFiles.length} renamed`);
|
|
33243
|
+
if (untrackedFiles.length > 0) summaryParts.push(`${untrackedFiles.length} untracked`);
|
|
33244
|
+
if (hasConflicts) summaryParts.push(`${conflictFiles.length || 1} ${plural(conflictFiles.length || 1, "conflict")}`);
|
|
33245
|
+
return {
|
|
33246
|
+
beforeSnapshotId: before.id,
|
|
33247
|
+
afterSnapshotId: after.id,
|
|
33248
|
+
workspace: after.workspace,
|
|
33249
|
+
repoRoot: after.repoRoot,
|
|
33250
|
+
changedFiles,
|
|
33251
|
+
addedFiles: uniqueSorted(addedFiles),
|
|
33252
|
+
modifiedFiles: uniqueSorted(modifiedFiles),
|
|
33253
|
+
deletedFiles: uniqueSorted(deletedFiles),
|
|
33254
|
+
renamedFiles,
|
|
33255
|
+
untrackedFiles: uniqueSorted(untrackedFiles),
|
|
33256
|
+
conflictFiles,
|
|
33257
|
+
totalInsertions,
|
|
33258
|
+
totalDeletions,
|
|
33259
|
+
hasConflicts,
|
|
33260
|
+
currentStatus: after.status,
|
|
33261
|
+
summaryText: summaryParts.length > 0 ? summaryParts.join(", ") : "No file-set changes between snapshots."
|
|
33262
|
+
};
|
|
33263
|
+
}
|
|
33264
|
+
var InMemoryGitSnapshotStore = class {
|
|
33265
|
+
snapshots = /* @__PURE__ */ new Map();
|
|
33266
|
+
order = [];
|
|
33267
|
+
capacity;
|
|
33268
|
+
now;
|
|
33269
|
+
idPrefix;
|
|
33270
|
+
getStatusProvider;
|
|
33271
|
+
getDiffSummaryProvider;
|
|
33272
|
+
counter = 0;
|
|
33273
|
+
constructor(options = {}) {
|
|
33274
|
+
this.capacity = normalizeCapacity(options.capacity);
|
|
33275
|
+
this.now = options.now ?? Date.now;
|
|
33276
|
+
this.idPrefix = options.idPrefix ?? "git-snapshot";
|
|
33277
|
+
this.getStatusProvider = options.getStatus;
|
|
33278
|
+
this.getDiffSummaryProvider = options.getDiffSummary;
|
|
33279
|
+
}
|
|
33280
|
+
async create(input) {
|
|
33281
|
+
const getStatus = input.getStatus ?? this.getStatusProvider;
|
|
33282
|
+
if (!getStatus) {
|
|
33283
|
+
throw new Error("GitSnapshotStore requires an injected getStatus provider");
|
|
33284
|
+
}
|
|
33285
|
+
const status = await getStatus(input.workspace);
|
|
33286
|
+
const getDiffSummary = input.getDiffSummary ?? this.getDiffSummaryProvider;
|
|
33287
|
+
const diffSummary = getDiffSummary ? await getDiffSummary(input.workspace, status) : createEmptyDiffSummary(status);
|
|
33288
|
+
const createdAt = this.now();
|
|
33289
|
+
const id = `${this.idPrefix}-${createdAt}-${++this.counter}`;
|
|
33290
|
+
const snapshot = {
|
|
33291
|
+
id,
|
|
33292
|
+
workspace: input.workspace,
|
|
33293
|
+
repoRoot: status.repoRoot ?? input.workspace,
|
|
33294
|
+
sessionId: input.sessionId,
|
|
33295
|
+
turnId: input.turnId,
|
|
33296
|
+
reason: input.reason,
|
|
33297
|
+
status,
|
|
33298
|
+
diffSummary,
|
|
33299
|
+
createdAt
|
|
33300
|
+
};
|
|
33301
|
+
this.snapshots.set(id, snapshot);
|
|
33302
|
+
this.order.push(id);
|
|
33303
|
+
this.enforceCapacity();
|
|
33304
|
+
return snapshot;
|
|
33305
|
+
}
|
|
33306
|
+
get(id) {
|
|
33307
|
+
return this.snapshots.get(id);
|
|
33308
|
+
}
|
|
33309
|
+
compare(beforeSnapshotId, afterSnapshotId) {
|
|
33310
|
+
const before = this.snapshots.get(beforeSnapshotId);
|
|
33311
|
+
if (!before) throw new Error(`Unknown before snapshot: ${beforeSnapshotId}`);
|
|
33312
|
+
const after = this.snapshots.get(afterSnapshotId);
|
|
33313
|
+
if (!after) throw new Error(`Unknown after snapshot: ${afterSnapshotId}`);
|
|
33314
|
+
return compareGitSnapshots(before, after);
|
|
33315
|
+
}
|
|
33316
|
+
list(query = {}) {
|
|
33317
|
+
const limit = Math.max(1, Math.floor(query.limit ?? this.capacity));
|
|
33318
|
+
return this.order.map((id) => this.snapshots.get(id)).filter((snapshot) => Boolean(snapshot)).filter((snapshot) => !query.workspace || snapshot.workspace === query.workspace).filter((snapshot) => !query.sessionId || snapshot.sessionId === query.sessionId).slice(-limit);
|
|
33319
|
+
}
|
|
33320
|
+
clear() {
|
|
33321
|
+
this.snapshots.clear();
|
|
33322
|
+
this.order.splice(0, this.order.length);
|
|
33323
|
+
}
|
|
33324
|
+
enforceCapacity() {
|
|
33325
|
+
while (this.order.length > this.capacity) {
|
|
33326
|
+
const evictedId = this.order.shift();
|
|
33327
|
+
if (evictedId) this.snapshots.delete(evictedId);
|
|
33328
|
+
}
|
|
33329
|
+
}
|
|
33330
|
+
};
|
|
33331
|
+
function createGitSnapshotStore(options = {}) {
|
|
33332
|
+
return new InMemoryGitSnapshotStore(options);
|
|
33333
|
+
}
|
|
33334
|
+
var DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS = 5e3;
|
|
33335
|
+
var MIN_GIT_WORKSPACE_POLL_INTERVAL_MS = 1e3;
|
|
33336
|
+
function defaultStatusProvider(workspace) {
|
|
33337
|
+
return getGitRepoStatus(workspace);
|
|
33338
|
+
}
|
|
33339
|
+
function defaultDiffSummaryProvider(workspace) {
|
|
33340
|
+
return getGitDiffSummary(workspace);
|
|
33341
|
+
}
|
|
33342
|
+
function normalizeIntervalMs(value, defaultIntervalMs, minIntervalMs) {
|
|
33343
|
+
const requested = Number.isFinite(value) ? Math.floor(value) : defaultIntervalMs;
|
|
33344
|
+
return Math.max(minIntervalMs, requested > 0 ? requested : defaultIntervalMs);
|
|
33345
|
+
}
|
|
33346
|
+
function normalizeGitWorkspaceSubscriptionParams2(params, options = {}) {
|
|
33347
|
+
const minIntervalMs = Math.max(1, Math.floor(options.minIntervalMs ?? MIN_GIT_WORKSPACE_POLL_INTERVAL_MS));
|
|
33348
|
+
const defaultIntervalMs = Math.max(minIntervalMs, Math.floor(options.defaultIntervalMs ?? DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS));
|
|
33349
|
+
return {
|
|
33350
|
+
workspace: params.workspace,
|
|
33351
|
+
includeDiffSummary: Boolean(params.includeDiffSummary),
|
|
33352
|
+
intervalMs: normalizeIntervalMs(params.intervalMs, defaultIntervalMs, minIntervalMs)
|
|
33353
|
+
};
|
|
33354
|
+
}
|
|
33355
|
+
var GitWorkspaceMonitor = class {
|
|
33356
|
+
getStatusProvider;
|
|
33357
|
+
getDiffSummaryProvider;
|
|
33358
|
+
now;
|
|
33359
|
+
minIntervalMs;
|
|
33360
|
+
defaultIntervalMs;
|
|
33361
|
+
keyPrefix;
|
|
33362
|
+
cache = /* @__PURE__ */ new Map();
|
|
33363
|
+
listeners = /* @__PURE__ */ new Set();
|
|
33364
|
+
seq = 0;
|
|
33365
|
+
constructor(options = {}) {
|
|
33366
|
+
this.getStatusProvider = options.getStatus ?? defaultStatusProvider;
|
|
33367
|
+
this.getDiffSummaryProvider = options.getDiffSummary ?? defaultDiffSummaryProvider;
|
|
33368
|
+
this.now = options.now ?? Date.now;
|
|
33369
|
+
this.minIntervalMs = Math.max(1, Math.floor(options.minIntervalMs ?? MIN_GIT_WORKSPACE_POLL_INTERVAL_MS));
|
|
33370
|
+
this.defaultIntervalMs = Math.max(
|
|
33371
|
+
this.minIntervalMs,
|
|
33372
|
+
Math.floor(options.defaultIntervalMs ?? DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS)
|
|
33373
|
+
);
|
|
33374
|
+
this.keyPrefix = options.keyPrefix ?? "git";
|
|
33375
|
+
}
|
|
33376
|
+
async refresh(params) {
|
|
33377
|
+
const normalized = this.normalize(typeof params === "string" ? { workspace: params } : params);
|
|
33378
|
+
const status = await this.getStatusProvider(normalized.workspace);
|
|
33379
|
+
const diffSummary = normalized.includeDiffSummary ? await this.getDiffSummaryProvider(normalized.workspace, status) : void 0;
|
|
33380
|
+
const compactSummary = createGitCompactSummary(status, diffSummary);
|
|
33381
|
+
const timestamp = this.now();
|
|
33382
|
+
const seq = ++this.seq;
|
|
33383
|
+
const key = this.keyForWorkspace(normalized.workspace);
|
|
33384
|
+
const update = {
|
|
33385
|
+
topic: "workspace.git",
|
|
33386
|
+
key,
|
|
33387
|
+
workspace: normalized.workspace,
|
|
33388
|
+
status,
|
|
33389
|
+
diffSummary,
|
|
33390
|
+
seq,
|
|
33391
|
+
timestamp
|
|
33392
|
+
};
|
|
33393
|
+
const cacheEntry = {
|
|
33394
|
+
key,
|
|
33395
|
+
workspace: normalized.workspace,
|
|
33396
|
+
status,
|
|
33397
|
+
diffSummary,
|
|
33398
|
+
compactSummary,
|
|
33399
|
+
seq,
|
|
33400
|
+
timestamp
|
|
33401
|
+
};
|
|
33402
|
+
this.cache.set(normalized.workspace, cacheEntry);
|
|
33403
|
+
this.emit(update, cacheEntry);
|
|
33404
|
+
return update;
|
|
33405
|
+
}
|
|
33406
|
+
poll(params) {
|
|
33407
|
+
return this.refresh(params);
|
|
33408
|
+
}
|
|
33409
|
+
getCached(workspace) {
|
|
33410
|
+
return this.cache.get(workspace);
|
|
33411
|
+
}
|
|
33412
|
+
getCompactSummary(workspace) {
|
|
33413
|
+
return this.cache.get(workspace)?.compactSummary;
|
|
33414
|
+
}
|
|
33415
|
+
onUpdate(listener) {
|
|
33416
|
+
this.listeners.add(listener);
|
|
33417
|
+
return () => {
|
|
33418
|
+
this.listeners.delete(listener);
|
|
33419
|
+
};
|
|
33420
|
+
}
|
|
33421
|
+
createSubscription(params, listener) {
|
|
33422
|
+
const normalized = this.normalize(params);
|
|
33423
|
+
const scopedListener = listener ? (update, cacheEntry) => {
|
|
33424
|
+
if (update.workspace === normalized.workspace) listener(update, cacheEntry);
|
|
33425
|
+
} : void 0;
|
|
33426
|
+
const unsubscribe = scopedListener ? this.onUpdate(scopedListener) : () => void 0;
|
|
33427
|
+
return {
|
|
33428
|
+
params: normalized,
|
|
33429
|
+
refresh: () => this.refresh(normalized),
|
|
33430
|
+
getCached: () => this.getCached(normalized.workspace),
|
|
33431
|
+
dispose: unsubscribe
|
|
33432
|
+
};
|
|
33433
|
+
}
|
|
33434
|
+
normalize(params) {
|
|
33435
|
+
return normalizeGitWorkspaceSubscriptionParams2(params, {
|
|
33436
|
+
defaultIntervalMs: this.defaultIntervalMs,
|
|
33437
|
+
minIntervalMs: this.minIntervalMs
|
|
33438
|
+
});
|
|
33439
|
+
}
|
|
33440
|
+
keyForWorkspace(workspace) {
|
|
33441
|
+
return `${this.keyPrefix}:${workspace}`;
|
|
33442
|
+
}
|
|
33443
|
+
emit(update, cacheEntry) {
|
|
33444
|
+
for (const listener of this.listeners) {
|
|
33445
|
+
listener(update, cacheEntry);
|
|
33446
|
+
}
|
|
33447
|
+
}
|
|
33448
|
+
};
|
|
33449
|
+
function createGitWorkspaceMonitor2(options = {}) {
|
|
33450
|
+
return new GitWorkspaceMonitor(options);
|
|
33451
|
+
}
|
|
33452
|
+
var path32 = __toESM2(require("path"));
|
|
33453
|
+
var GIT_COMMAND_NAMES = /* @__PURE__ */ new Set([
|
|
33454
|
+
"git_status",
|
|
33455
|
+
"git_diff_summary",
|
|
33456
|
+
"git_diff_file",
|
|
33457
|
+
"git_snapshot_create",
|
|
33458
|
+
"git_snapshot_compare",
|
|
33459
|
+
"git_log",
|
|
33460
|
+
"git_checkpoint",
|
|
33461
|
+
"git_stash_push",
|
|
33462
|
+
"git_stash_pop",
|
|
33463
|
+
"git_checkout_files",
|
|
33464
|
+
"git_remote_url"
|
|
33465
|
+
]);
|
|
33466
|
+
var SNAPSHOT_REASONS = /* @__PURE__ */ new Set([
|
|
33467
|
+
"session_baseline",
|
|
33468
|
+
"before_user_input_dispatch",
|
|
33469
|
+
"before_agent_work",
|
|
33470
|
+
"after_agent_work",
|
|
33471
|
+
"manual"
|
|
33472
|
+
]);
|
|
33473
|
+
var FAILURE_REASONS = /* @__PURE__ */ new Set([
|
|
33474
|
+
"not_git_repo",
|
|
33475
|
+
"git_not_installed",
|
|
33476
|
+
"timeout",
|
|
33477
|
+
"path_outside_repo",
|
|
33478
|
+
"dirty_index_required",
|
|
33479
|
+
"conflict",
|
|
33480
|
+
"invalid_args",
|
|
33481
|
+
"git_command_failed"
|
|
33482
|
+
]);
|
|
33483
|
+
function failure(reason, error48) {
|
|
33484
|
+
return { success: false, reason, error: error48 };
|
|
33485
|
+
}
|
|
33486
|
+
function serviceNotImplemented(command) {
|
|
33487
|
+
return failure("invalid_args", `${command} is not implemented: daemon-core Git service is not configured`);
|
|
33488
|
+
}
|
|
33489
|
+
var defaultSnapshotStore = createGitSnapshotStore({
|
|
33490
|
+
getStatus: (workspace) => getGitRepoStatus(workspace),
|
|
33491
|
+
getDiffSummary: (workspace) => getGitDiffSummary(workspace)
|
|
33492
|
+
});
|
|
33493
|
+
function createDefaultGitCommandServices() {
|
|
33494
|
+
return {
|
|
33495
|
+
getStatus: ({ workspace }) => getGitRepoStatus(workspace),
|
|
33496
|
+
getDiffSummary: ({ workspace }) => getGitDiffSummary(workspace),
|
|
33497
|
+
getDiffFile: ({ workspace, path: filePath }) => getGitFileDiff(workspace, filePath),
|
|
33498
|
+
createSnapshot: ({ workspace, reason, sessionId, turnId }) => defaultSnapshotStore.create({
|
|
33499
|
+
workspace,
|
|
33500
|
+
reason,
|
|
33501
|
+
sessionId,
|
|
33502
|
+
turnId
|
|
33503
|
+
}),
|
|
33504
|
+
compareSnapshots: ({ beforeSnapshotId, afterSnapshotId }) => defaultSnapshotStore.compare(beforeSnapshotId, afterSnapshotId),
|
|
33505
|
+
getLog: ({ workspace, limit, path: filePath, since, until }) => getGitLog(workspace, { limit, path: filePath, since, until }),
|
|
33506
|
+
checkpoint: async ({ workspace, message, includeUntracked = false }) => gitCheckpoint(workspace, message, includeUntracked),
|
|
33507
|
+
stashPush: async ({ workspace, message, includeUntracked = false }) => gitStashPush(workspace, message, includeUntracked),
|
|
33508
|
+
stashPop: async ({ workspace, stashRef }) => gitStashPop(workspace, stashRef),
|
|
33509
|
+
checkoutFiles: async ({ workspace, paths }) => gitCheckoutFiles(workspace, paths),
|
|
33510
|
+
getRemoteUrl: async ({ workspace, remote = "origin" }) => gitGetRemoteUrl(workspace, remote)
|
|
33511
|
+
};
|
|
33512
|
+
}
|
|
33513
|
+
var defaultGitCommandServices = createDefaultGitCommandServices();
|
|
33514
|
+
function validateWorkspace2(args) {
|
|
33515
|
+
if (typeof args?.workspace !== "string") {
|
|
33516
|
+
return failure("invalid_args", "workspace must be a non-empty absolute path");
|
|
33517
|
+
}
|
|
33518
|
+
const workspace = args.workspace.trim();
|
|
33519
|
+
if (!workspace || !path32.isAbsolute(workspace)) {
|
|
33520
|
+
return failure("invalid_args", "workspace must be a non-empty absolute path");
|
|
33521
|
+
}
|
|
33522
|
+
return { workspace };
|
|
33523
|
+
}
|
|
33524
|
+
function validateRepoPath(args) {
|
|
33525
|
+
if (typeof args?.path !== "string" || !args.path.trim()) {
|
|
33526
|
+
return failure("invalid_args", "path must be a non-empty repository-relative path");
|
|
33527
|
+
}
|
|
33528
|
+
return { path: args.path.trim() };
|
|
33529
|
+
}
|
|
33530
|
+
function validateSnapshotId(args, key) {
|
|
33531
|
+
if (typeof args?.[key] !== "string" || !args[key].trim()) {
|
|
33532
|
+
return failure("invalid_args", `${key} must be a non-empty string`);
|
|
33533
|
+
}
|
|
33534
|
+
return args[key].trim();
|
|
33535
|
+
}
|
|
33536
|
+
function parseSnapshotReason(args) {
|
|
33537
|
+
if (args?.reason === void 0 || args?.reason === null || args?.reason === "") {
|
|
33538
|
+
return "manual";
|
|
33539
|
+
}
|
|
33540
|
+
if (typeof args.reason !== "string" || !SNAPSHOT_REASONS.has(args.reason)) {
|
|
33541
|
+
return failure("invalid_args", "reason must be a valid GitSnapshotReason");
|
|
33542
|
+
}
|
|
33543
|
+
return args.reason;
|
|
33544
|
+
}
|
|
33545
|
+
function optionalString(value) {
|
|
33546
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
33547
|
+
}
|
|
33548
|
+
function optionalBoolean(value) {
|
|
33549
|
+
return typeof value === "boolean" ? value : void 0;
|
|
33550
|
+
}
|
|
33551
|
+
function boundedLogLimit(value) {
|
|
33552
|
+
if (value === void 0 || value === null || value === "") return 50;
|
|
33553
|
+
const numeric = typeof value === "number" ? value : Number(value);
|
|
33554
|
+
if (!Number.isFinite(numeric)) return 50;
|
|
33555
|
+
return Math.max(1, Math.min(200, Math.floor(numeric)));
|
|
33556
|
+
}
|
|
33557
|
+
function failureReasonFromError(error48) {
|
|
33558
|
+
return typeof error48?.reason === "string" && FAILURE_REASONS.has(error48.reason) ? error48.reason : "git_command_failed";
|
|
33559
|
+
}
|
|
33560
|
+
async function runService(fn2) {
|
|
33561
|
+
try {
|
|
33562
|
+
return await fn2();
|
|
33563
|
+
} catch (error48) {
|
|
33564
|
+
return failure(failureReasonFromError(error48), error48?.message || "Git command failed");
|
|
33565
|
+
}
|
|
33566
|
+
}
|
|
33567
|
+
function isGitCommandName(command) {
|
|
33568
|
+
return GIT_COMMAND_NAMES.has(command);
|
|
33569
|
+
}
|
|
33570
|
+
async function handleGitCommand(command, args, services = defaultGitCommandServices) {
|
|
33571
|
+
if (!isGitCommandName(command)) {
|
|
33572
|
+
return failure("invalid_args", `Unknown Git command: ${command}`);
|
|
33573
|
+
}
|
|
33574
|
+
const workspaceResult = validateWorkspace2(args);
|
|
33575
|
+
if ("success" in workspaceResult) return workspaceResult;
|
|
33576
|
+
const { workspace } = workspaceResult;
|
|
33577
|
+
switch (command) {
|
|
33578
|
+
case "git_status": {
|
|
33579
|
+
if (!services.getStatus) return serviceNotImplemented(command);
|
|
33580
|
+
const status = await runService(() => services.getStatus({ workspace }));
|
|
33581
|
+
return "success" in status ? status : { success: true, status };
|
|
33582
|
+
}
|
|
33583
|
+
case "git_diff_summary": {
|
|
33584
|
+
if (!services.getDiffSummary) return serviceNotImplemented(command);
|
|
33585
|
+
const diffSummary = await runService(() => services.getDiffSummary({ workspace, staged: optionalBoolean(args?.staged) }));
|
|
33586
|
+
return "success" in diffSummary ? diffSummary : { success: true, diffSummary };
|
|
33587
|
+
}
|
|
33588
|
+
case "git_diff_file": {
|
|
33589
|
+
if (!services.getDiffFile) return serviceNotImplemented(command);
|
|
33590
|
+
const pathResult = validateRepoPath(args);
|
|
33591
|
+
if (typeof pathResult !== "object" || "success" in pathResult) return pathResult;
|
|
33592
|
+
const diff = await runService(() => services.getDiffFile({
|
|
33593
|
+
workspace,
|
|
33594
|
+
path: pathResult.path,
|
|
33595
|
+
staged: optionalBoolean(args?.staged)
|
|
33596
|
+
}));
|
|
33597
|
+
return "success" in diff ? diff : { success: true, diff };
|
|
33598
|
+
}
|
|
33599
|
+
case "git_snapshot_create": {
|
|
33600
|
+
if (!services.createSnapshot) return serviceNotImplemented(command);
|
|
33601
|
+
const reason = parseSnapshotReason(args);
|
|
33602
|
+
if (typeof reason !== "string") return reason;
|
|
33603
|
+
const snapshot = await runService(() => services.createSnapshot({
|
|
33604
|
+
workspace,
|
|
33605
|
+
reason,
|
|
33606
|
+
sessionId: optionalString(args?.sessionId),
|
|
33607
|
+
turnId: optionalString(args?.turnId)
|
|
33608
|
+
}));
|
|
33609
|
+
return "success" in snapshot ? snapshot : { success: true, snapshot };
|
|
33610
|
+
}
|
|
33611
|
+
case "git_snapshot_compare": {
|
|
33612
|
+
if (!services.compareSnapshots) return serviceNotImplemented(command);
|
|
33613
|
+
const beforeSnapshotId = validateSnapshotId(args, "beforeSnapshotId");
|
|
33614
|
+
if (typeof beforeSnapshotId !== "string") return beforeSnapshotId;
|
|
33615
|
+
const afterSnapshotId = validateSnapshotId(args, "afterSnapshotId");
|
|
33616
|
+
if (typeof afterSnapshotId !== "string") return afterSnapshotId;
|
|
33617
|
+
const compare = await runService(() => services.compareSnapshots({ workspace, beforeSnapshotId, afterSnapshotId }));
|
|
33618
|
+
return "success" in compare ? compare : { success: true, compare };
|
|
33619
|
+
}
|
|
33620
|
+
case "git_log": {
|
|
33621
|
+
if (!services.getLog) {
|
|
33622
|
+
return failure("invalid_args", "git_log is not implemented: bounded daemon-core Git log service is not configured");
|
|
33623
|
+
}
|
|
33624
|
+
const log = await runService(() => services.getLog({
|
|
33625
|
+
workspace,
|
|
33626
|
+
limit: boundedLogLimit(args?.limit),
|
|
33627
|
+
path: optionalString(args?.path),
|
|
33628
|
+
since: optionalString(args?.since),
|
|
33629
|
+
until: optionalString(args?.until)
|
|
33630
|
+
}));
|
|
33631
|
+
return "success" in log ? log : { success: true, log };
|
|
33632
|
+
}
|
|
33633
|
+
case "git_checkpoint": {
|
|
33634
|
+
if (!services.checkpoint) return serviceNotImplemented(command);
|
|
33635
|
+
const msg = validateMutatingMessage(args?.message);
|
|
33636
|
+
if (typeof msg !== "string") return msg;
|
|
33637
|
+
const includeUntracked = Boolean(args?.includeUntracked);
|
|
33638
|
+
const checkpoint = await runService(() => services.checkpoint({ workspace, message: msg, includeUntracked }));
|
|
33639
|
+
return "success" in checkpoint ? checkpoint : { success: true, checkpoint };
|
|
33640
|
+
}
|
|
33641
|
+
case "git_stash_push": {
|
|
33642
|
+
if (!services.stashPush) return serviceNotImplemented(command);
|
|
33643
|
+
const msg = validateMutatingMessage(args?.message);
|
|
33644
|
+
if (typeof msg !== "string") return msg;
|
|
33645
|
+
const includeUntracked = Boolean(args?.includeUntracked);
|
|
33646
|
+
const stash = await runService(() => services.stashPush({ workspace, message: msg, includeUntracked }));
|
|
33647
|
+
return "success" in stash ? stash : { success: true, stash };
|
|
33648
|
+
}
|
|
33649
|
+
case "git_stash_pop": {
|
|
33650
|
+
if (!services.stashPop) return serviceNotImplemented(command);
|
|
33651
|
+
const stashRef = optionalString(args?.stashRef);
|
|
33652
|
+
if (stashRef !== void 0 && !/^stash@\{\d+\}$/.test(stashRef)) {
|
|
33653
|
+
return failure("invalid_args", "stashRef must match stash@{N} format");
|
|
33654
|
+
}
|
|
33655
|
+
const popResult = await runService(() => services.stashPop({ workspace, stashRef }));
|
|
33656
|
+
if (popResult !== void 0 && "success" in popResult) return popResult;
|
|
33657
|
+
return { success: true, stashPopped: true };
|
|
33658
|
+
}
|
|
33659
|
+
case "git_checkout_files": {
|
|
33660
|
+
if (!services.checkoutFiles) return serviceNotImplemented(command);
|
|
33661
|
+
const paths = args?.paths;
|
|
33662
|
+
if (!Array.isArray(paths) || paths.length === 0) {
|
|
33663
|
+
return failure("invalid_args", "paths must be a non-empty array");
|
|
33664
|
+
}
|
|
33665
|
+
if (paths.length > 50) {
|
|
33666
|
+
return failure("invalid_args", "paths array exceeds maximum of 50 entries");
|
|
33667
|
+
}
|
|
33668
|
+
const checkoutResult = await runService(() => services.checkoutFiles({ workspace, paths }));
|
|
33669
|
+
return "success" in checkoutResult ? checkoutResult : { success: true, checkedOut: checkoutResult.checkedOut };
|
|
33670
|
+
}
|
|
33671
|
+
case "git_remote_url": {
|
|
33672
|
+
if (!services.getRemoteUrl) return serviceNotImplemented(command);
|
|
33673
|
+
const remote = typeof args?.remote === "string" && args.remote.trim() ? args.remote.trim() : "origin";
|
|
33674
|
+
const remoteResult = await runService(() => services.getRemoteUrl({ workspace, remote }));
|
|
33675
|
+
if ("success" in remoteResult) return remoteResult;
|
|
33676
|
+
return { success: true, remoteUrl: remoteResult.remoteUrl, remote: remoteResult.remote };
|
|
33677
|
+
}
|
|
33678
|
+
default:
|
|
33679
|
+
return failure("invalid_args", `Unknown Git command: ${command}`);
|
|
33680
|
+
}
|
|
33681
|
+
}
|
|
33682
|
+
function validateMutatingMessage(value) {
|
|
33683
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
33684
|
+
return failure("invalid_args", "message must be a non-empty string");
|
|
33685
|
+
}
|
|
33686
|
+
const msg = value.trim();
|
|
33687
|
+
if (msg.length > 200) {
|
|
33688
|
+
return failure("invalid_args", "message must be 200 characters or fewer");
|
|
33689
|
+
}
|
|
33690
|
+
return msg;
|
|
33691
|
+
}
|
|
33692
|
+
async function gitCheckpoint(workspace, message, includeUntracked) {
|
|
33693
|
+
const repo = await resolveGitRepository(workspace);
|
|
33694
|
+
const repoRoot = repo.repoRoot;
|
|
33695
|
+
const statusResult = await getGitRepoStatus(workspace);
|
|
33696
|
+
if (statusResult.hasConflicts) {
|
|
33697
|
+
throw new GitCommandError("conflict", "Repository has conflicts \u2014 resolve before checkpointing");
|
|
33698
|
+
}
|
|
33699
|
+
const addArgs = includeUntracked ? ["-A"] : ["-u"];
|
|
33700
|
+
await runGit(repo, ["add", ...addArgs], { cwd: repoRoot });
|
|
33701
|
+
const fullMsg = `adhdev: checkpoint ${message}`;
|
|
33702
|
+
let commitSha;
|
|
33703
|
+
try {
|
|
33704
|
+
await runGit(repo, ["commit", "-m", fullMsg], { cwd: repoRoot });
|
|
33705
|
+
const revResult = await runGit(repo, ["rev-parse", "HEAD"], { cwd: repoRoot });
|
|
33706
|
+
commitSha = revResult.stdout.trim();
|
|
33707
|
+
} catch (err) {
|
|
33708
|
+
const output = (err?.stdout || "") + (err?.stderr || "");
|
|
33709
|
+
if (/nothing to commit/i.test(output)) {
|
|
33710
|
+
throw new GitCommandError("git_command_failed", "Nothing to commit");
|
|
33711
|
+
}
|
|
33712
|
+
throw err;
|
|
33713
|
+
}
|
|
33714
|
+
return {
|
|
33715
|
+
workspace: repo.workspace,
|
|
33716
|
+
repoRoot,
|
|
33717
|
+
isGitRepo: true,
|
|
33718
|
+
commit: commitSha,
|
|
33719
|
+
message: fullMsg,
|
|
33720
|
+
lastCheckedAt: Date.now()
|
|
33721
|
+
};
|
|
33722
|
+
}
|
|
33723
|
+
async function gitStashPush(workspace, message, includeUntracked) {
|
|
33724
|
+
const repo = await resolveGitRepository(workspace);
|
|
33725
|
+
const repoRoot = repo.repoRoot;
|
|
33726
|
+
const stashArgs = ["stash", "push", "-m", message];
|
|
33727
|
+
if (includeUntracked) stashArgs.push("--include-untracked");
|
|
33728
|
+
const result = await runGit(repo, stashArgs, { cwd: repoRoot });
|
|
33729
|
+
if (/No local changes to save/i.test(result.stdout + result.stderr)) {
|
|
33730
|
+
throw new GitCommandError("git_command_failed", "Nothing to stash");
|
|
33731
|
+
}
|
|
33732
|
+
return {
|
|
33733
|
+
workspace: repo.workspace,
|
|
33734
|
+
repoRoot,
|
|
33735
|
+
isGitRepo: true,
|
|
33736
|
+
stashRef: "stash@{0}",
|
|
33737
|
+
message,
|
|
33738
|
+
lastCheckedAt: Date.now()
|
|
33739
|
+
};
|
|
33740
|
+
}
|
|
33741
|
+
async function gitStashPop(workspace, stashRef) {
|
|
33742
|
+
const repo = await resolveGitRepository(workspace);
|
|
33743
|
+
const repoRoot = repo.repoRoot;
|
|
33744
|
+
const popArgs = stashRef ? ["stash", "pop", stashRef] : ["stash", "pop"];
|
|
33745
|
+
await runGit(repo, popArgs, { cwd: repoRoot });
|
|
33746
|
+
}
|
|
33747
|
+
async function gitCheckoutFiles(workspace, paths) {
|
|
33748
|
+
const repo = await resolveGitRepository(workspace);
|
|
33749
|
+
const repoRoot = repo.repoRoot;
|
|
33750
|
+
const normalizedPaths = [];
|
|
33751
|
+
for (const p of paths) {
|
|
33752
|
+
if (typeof p !== "string" || !p.trim() || p.includes("\0")) {
|
|
33753
|
+
throw new GitCommandError("invalid_args", `Invalid path: ${String(p)}`);
|
|
33754
|
+
}
|
|
33755
|
+
if (path32.isAbsolute(p)) {
|
|
33756
|
+
throw new GitCommandError("invalid_args", `Path must be repository-relative, not absolute: ${p}`);
|
|
33757
|
+
}
|
|
33758
|
+
const normalized = path32.normalize(p.trim()).split(path32.sep).join("/");
|
|
33759
|
+
if (normalized.startsWith("../") || normalized === "..") {
|
|
33760
|
+
throw new GitCommandError("path_outside_repo", `Path is outside repository root: ${p}`);
|
|
33761
|
+
}
|
|
33762
|
+
const absolutePath = path32.resolve(repoRoot, normalized);
|
|
33763
|
+
if (!isPathInside(repoRoot, absolutePath)) {
|
|
33764
|
+
throw new GitCommandError("path_outside_repo", `Path is outside repository root: ${p}`);
|
|
33765
|
+
}
|
|
33766
|
+
normalizedPaths.push(normalized);
|
|
33767
|
+
}
|
|
33768
|
+
await runGit(repo, ["checkout", "--", ...normalizedPaths], { cwd: repoRoot });
|
|
33769
|
+
return { checkedOut: normalizedPaths };
|
|
33770
|
+
}
|
|
33771
|
+
async function gitGetRemoteUrl(workspace, remote) {
|
|
33772
|
+
const repo = await resolveGitRepository(workspace);
|
|
33773
|
+
const result = await runGit(repo, ["remote", "get-url", remote], { cwd: repo.repoRoot });
|
|
33774
|
+
const remoteUrl = result.stdout.trim();
|
|
33775
|
+
if (!remoteUrl) {
|
|
33776
|
+
throw new GitCommandError("git_command_failed", `Remote '${remote}' has no URL`);
|
|
33777
|
+
}
|
|
33778
|
+
return { remoteUrl, remote };
|
|
33779
|
+
}
|
|
33780
|
+
function formatOptionalGitLogRangeArg(flag, value) {
|
|
33781
|
+
return value ? [`${flag}=${value}`] : [];
|
|
33782
|
+
}
|
|
33783
|
+
async function getGitLog(workspace, options) {
|
|
33784
|
+
const lastCheckedAt = Date.now();
|
|
33785
|
+
const repo = await resolveGitRepository(workspace);
|
|
33786
|
+
const repoRoot = repo.repoRoot;
|
|
33787
|
+
const boundedLimit = Math.max(1, Math.min(200, Math.floor(options.limit || 50)));
|
|
33788
|
+
const selectedPath = options.path ? validateGitLogPath(repoRoot, options.path) : void 0;
|
|
33789
|
+
const result = await runGit(
|
|
33790
|
+
repo,
|
|
33791
|
+
[
|
|
33792
|
+
"log",
|
|
33793
|
+
`--max-count=${boundedLimit}`,
|
|
33794
|
+
"--format=%H%x00%an%x00%ae%x00%at%x00%ct%x00%s",
|
|
33795
|
+
...formatOptionalGitLogRangeArg("--since", options.since),
|
|
33796
|
+
...formatOptionalGitLogRangeArg("--until", options.until),
|
|
33797
|
+
"--",
|
|
33798
|
+
...selectedPath ? [selectedPath] : []
|
|
33799
|
+
],
|
|
33800
|
+
{ cwd: repoRoot }
|
|
33801
|
+
);
|
|
33802
|
+
const entries = result.stdout.split("\n").filter((line) => line.trim().length > 0).map((line) => {
|
|
33803
|
+
const [commit = "", authorName, authorEmail, authoredAt, committedAt, ...messageParts] = line.split("\0");
|
|
33804
|
+
return {
|
|
33805
|
+
commit,
|
|
33806
|
+
message: messageParts.join("\0"),
|
|
33807
|
+
authorName: authorName || void 0,
|
|
33808
|
+
authorEmail: authorEmail || void 0,
|
|
33809
|
+
authoredAt: authoredAt ? Number.parseInt(authoredAt, 10) * 1e3 : void 0,
|
|
33810
|
+
committedAt: committedAt ? Number.parseInt(committedAt, 10) * 1e3 : void 0
|
|
33811
|
+
};
|
|
33812
|
+
}).filter((entry) => entry.commit.length > 0);
|
|
33813
|
+
return {
|
|
33814
|
+
workspace: repo.workspace,
|
|
33815
|
+
repoRoot,
|
|
33816
|
+
isGitRepo: true,
|
|
33817
|
+
entries,
|
|
33818
|
+
limit: boundedLimit,
|
|
33819
|
+
truncated: entries.length >= boundedLimit,
|
|
33820
|
+
lastCheckedAt
|
|
33821
|
+
};
|
|
33822
|
+
}
|
|
33823
|
+
function validateGitLogPath(repoRoot, filePath) {
|
|
33824
|
+
if (!filePath.trim() || filePath.includes("\0")) {
|
|
33825
|
+
throw new GitCommandError("invalid_args", "path must be a non-empty repository-relative path");
|
|
33826
|
+
}
|
|
33827
|
+
if (path32.isAbsolute(filePath)) {
|
|
33828
|
+
throw new GitCommandError("invalid_args", "path must be repository-relative");
|
|
33829
|
+
}
|
|
33830
|
+
const normalized = path32.normalize(filePath).split(path32.sep).join("/");
|
|
33831
|
+
const absolutePath = path32.resolve(repoRoot, normalized);
|
|
33832
|
+
if (!isPathInside(repoRoot, absolutePath) || normalized.startsWith("../") || normalized === "..") {
|
|
33833
|
+
throw new GitCommandError("path_outside_repo", "Git log path is outside the repository root");
|
|
33834
|
+
}
|
|
33835
|
+
return normalized;
|
|
33836
|
+
}
|
|
33837
|
+
var BUSY_STATUSES = /* @__PURE__ */ new Set(["streaming", "waiting_approval"]);
|
|
33838
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["idle", "error"]);
|
|
33839
|
+
var TurnSnapshotTracker = class {
|
|
33840
|
+
lastStatus = /* @__PURE__ */ new Map();
|
|
33841
|
+
onTurnCompleted;
|
|
33842
|
+
constructor(onTurnCompleted) {
|
|
33843
|
+
this.onTurnCompleted = onTurnCompleted;
|
|
33844
|
+
}
|
|
33845
|
+
record(sessionId, status, workspace) {
|
|
33846
|
+
const prev = this.lastStatus.get(sessionId);
|
|
33847
|
+
this.lastStatus.set(sessionId, status);
|
|
33848
|
+
if (workspace && prev && BUSY_STATUSES.has(prev) && TERMINAL_STATUSES.has(status)) {
|
|
33849
|
+
this.onTurnCompleted({ sessionId, workspace });
|
|
33850
|
+
}
|
|
33851
|
+
}
|
|
33852
|
+
forget(sessionId) {
|
|
33853
|
+
this.lastStatus.delete(sessionId);
|
|
33854
|
+
}
|
|
33855
|
+
};
|
|
32551
33856
|
init_config();
|
|
32552
33857
|
var fs5 = __toESM2(require("fs"));
|
|
32553
33858
|
var os6 = __toESM2(require("os"));
|
|
32554
|
-
var
|
|
33859
|
+
var path42 = __toESM2(require("path"));
|
|
32555
33860
|
var import_crypto22 = require("crypto");
|
|
32556
33861
|
var MAX_WORKSPACES = 50;
|
|
32557
33862
|
function expandPath(p) {
|
|
32558
33863
|
const t = (p || "").trim();
|
|
32559
33864
|
if (!t) return "";
|
|
32560
|
-
if (t.startsWith("~")) return
|
|
32561
|
-
return
|
|
33865
|
+
if (t.startsWith("~")) return path42.join(os6.homedir(), t.slice(1).replace(/^\//, ""));
|
|
33866
|
+
return path42.resolve(t);
|
|
32562
33867
|
}
|
|
32563
33868
|
function validateWorkspacePath(absPath) {
|
|
32564
33869
|
try {
|
|
@@ -32572,7 +33877,7 @@ var require_dist2 = __commonJS({
|
|
|
32572
33877
|
}
|
|
32573
33878
|
}
|
|
32574
33879
|
function defaultWorkspaceLabel(absPath) {
|
|
32575
|
-
const base =
|
|
33880
|
+
const base = path42.basename(absPath) || absPath;
|
|
32576
33881
|
return base;
|
|
32577
33882
|
}
|
|
32578
33883
|
function getDefaultWorkspacePath(config2) {
|
|
@@ -32663,9 +33968,9 @@ var require_dist2 = __commonJS({
|
|
|
32663
33968
|
return getDefaultWorkspacePath(config2) || void 0;
|
|
32664
33969
|
}
|
|
32665
33970
|
function findWorkspaceByPath(config2, rawPath) {
|
|
32666
|
-
const abs =
|
|
33971
|
+
const abs = path42.resolve(expandPath(rawPath));
|
|
32667
33972
|
if (!abs) return void 0;
|
|
32668
|
-
return (config2.workspaces || []).find((w) =>
|
|
33973
|
+
return (config2.workspaces || []).find((w) => path42.resolve(expandPath(w.path)) === abs);
|
|
32669
33974
|
}
|
|
32670
33975
|
function addWorkspaceEntry(config2, rawPath, label, options) {
|
|
32671
33976
|
const abs = expandPath(rawPath);
|
|
@@ -32681,7 +33986,7 @@ var require_dist2 = __commonJS({
|
|
|
32681
33986
|
const v2 = validateWorkspacePath(abs);
|
|
32682
33987
|
if (!v2.ok) return { error: v2.error };
|
|
32683
33988
|
const list = [...config2.workspaces || []];
|
|
32684
|
-
if (list.some((w) =>
|
|
33989
|
+
if (list.some((w) => path42.resolve(w.path) === abs)) {
|
|
32685
33990
|
return { error: "Workspace already in list" };
|
|
32686
33991
|
}
|
|
32687
33992
|
if (list.length >= MAX_WORKSPACES) {
|
|
@@ -32713,7 +34018,7 @@ var require_dist2 = __commonJS({
|
|
|
32713
34018
|
if (validateWorkspacePath(abs).ok !== true) return { error: "Workspace path is no longer valid" };
|
|
32714
34019
|
return { config: { ...config2, defaultWorkspaceId: id } };
|
|
32715
34020
|
}
|
|
32716
|
-
var
|
|
34021
|
+
var path52 = __toESM2(require("path"));
|
|
32717
34022
|
function normalizeSummaryItem(item) {
|
|
32718
34023
|
if (!item || typeof item !== "object") return null;
|
|
32719
34024
|
const id = String(item.id || "").trim();
|
|
@@ -32778,9 +34083,9 @@ var require_dist2 = __commonJS({
|
|
|
32778
34083
|
function normalizeWorkspace(workspace) {
|
|
32779
34084
|
if (!workspace) return "";
|
|
32780
34085
|
try {
|
|
32781
|
-
return
|
|
34086
|
+
return path52.resolve(expandPath(workspace));
|
|
32782
34087
|
} catch {
|
|
32783
|
-
return
|
|
34088
|
+
return path52.resolve(workspace);
|
|
32784
34089
|
}
|
|
32785
34090
|
}
|
|
32786
34091
|
function buildRecentActivityKey(entry) {
|
|
@@ -32946,14 +34251,14 @@ var require_dist2 = __commonJS({
|
|
|
32946
34251
|
sessionNotificationUnreadOverrides: nextSessionNotificationUnreadOverrides
|
|
32947
34252
|
};
|
|
32948
34253
|
}
|
|
32949
|
-
var
|
|
34254
|
+
var path6 = __toESM2(require("path"));
|
|
32950
34255
|
var MAX_SAVED_SESSIONS = 500;
|
|
32951
34256
|
function normalizeWorkspace2(workspace) {
|
|
32952
34257
|
if (!workspace) return "";
|
|
32953
34258
|
try {
|
|
32954
|
-
return
|
|
34259
|
+
return path6.resolve(expandPath(workspace));
|
|
32955
34260
|
} catch {
|
|
32956
|
-
return
|
|
34261
|
+
return path6.resolve(workspace);
|
|
32957
34262
|
}
|
|
32958
34263
|
}
|
|
32959
34264
|
function buildSavedProviderSessionKey(providerSessionId) {
|
|
@@ -33068,7 +34373,7 @@ var require_dist2 = __commonJS({
|
|
|
33068
34373
|
var import_child_process = require("child_process");
|
|
33069
34374
|
var import_fs3 = require("fs");
|
|
33070
34375
|
var import_os22 = require("os");
|
|
33071
|
-
var
|
|
34376
|
+
var path7 = __toESM2(require("path"));
|
|
33072
34377
|
var BUILTIN_IDE_DEFINITIONS = [];
|
|
33073
34378
|
var registeredIDEs = /* @__PURE__ */ new Map();
|
|
33074
34379
|
function registerIDEDefinition(def) {
|
|
@@ -33087,9 +34392,9 @@ var require_dist2 = __commonJS({
|
|
|
33087
34392
|
function findCliCommand(command) {
|
|
33088
34393
|
const trimmed = String(command || "").trim();
|
|
33089
34394
|
if (!trimmed) return null;
|
|
33090
|
-
if (
|
|
33091
|
-
const candidate = trimmed.startsWith("~") ?
|
|
33092
|
-
const resolved =
|
|
34395
|
+
if (path7.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
34396
|
+
const candidate = trimmed.startsWith("~") ? path7.join((0, import_os22.homedir)(), trimmed.slice(1)) : trimmed;
|
|
34397
|
+
const resolved = path7.isAbsolute(candidate) ? candidate : path7.resolve(candidate);
|
|
33093
34398
|
return (0, import_fs3.existsSync)(resolved) ? resolved : null;
|
|
33094
34399
|
}
|
|
33095
34400
|
try {
|
|
@@ -33117,7 +34422,7 @@ var require_dist2 = __commonJS({
|
|
|
33117
34422
|
function checkPathExists(paths) {
|
|
33118
34423
|
const home = (0, import_os22.homedir)();
|
|
33119
34424
|
for (const p of paths) {
|
|
33120
|
-
const normalized = p.startsWith("~") ?
|
|
34425
|
+
const normalized = p.startsWith("~") ? path7.join(home, p.slice(1)) : p;
|
|
33121
34426
|
if (normalized.includes("*")) {
|
|
33122
34427
|
const username = home.split(/[\\/]/).pop() || "";
|
|
33123
34428
|
const resolved = normalized.replace("*", username);
|
|
@@ -33173,7 +34478,7 @@ var require_dist2 = __commonJS({
|
|
|
33173
34478
|
}
|
|
33174
34479
|
var import_child_process2 = require("child_process");
|
|
33175
34480
|
var os22 = __toESM2(require("os"));
|
|
33176
|
-
var
|
|
34481
|
+
var path8 = __toESM2(require("path"));
|
|
33177
34482
|
var import_fs4 = require("fs");
|
|
33178
34483
|
function parseVersion(raw) {
|
|
33179
34484
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
@@ -33186,36 +34491,36 @@ var require_dist2 = __commonJS({
|
|
|
33186
34491
|
function expandHome(value) {
|
|
33187
34492
|
const trimmed = value.trim();
|
|
33188
34493
|
if (!trimmed.startsWith("~")) return trimmed;
|
|
33189
|
-
return
|
|
34494
|
+
return path8.join(os22.homedir(), trimmed.slice(1));
|
|
33190
34495
|
}
|
|
33191
34496
|
function isExplicitCommandPath(command) {
|
|
33192
34497
|
const trimmed = command.trim();
|
|
33193
|
-
return
|
|
34498
|
+
return path8.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
33194
34499
|
}
|
|
33195
34500
|
function resolveCommandPath(command) {
|
|
33196
34501
|
const trimmed = command.trim();
|
|
33197
34502
|
if (!trimmed) return null;
|
|
33198
34503
|
if (isExplicitCommandPath(trimmed)) {
|
|
33199
34504
|
const expanded = expandHome(trimmed);
|
|
33200
|
-
const candidate =
|
|
34505
|
+
const candidate = path8.isAbsolute(expanded) ? expanded : path8.resolve(expanded);
|
|
33201
34506
|
return (0, import_fs4.existsSync)(candidate) ? candidate : null;
|
|
33202
34507
|
}
|
|
33203
34508
|
return null;
|
|
33204
34509
|
}
|
|
33205
34510
|
function execAsync(cmd, timeoutMs = 5e3) {
|
|
33206
|
-
return new Promise((
|
|
34511
|
+
return new Promise((resolve15) => {
|
|
33207
34512
|
const child = (0, import_child_process2.exec)(cmd, {
|
|
33208
34513
|
encoding: "utf-8",
|
|
33209
34514
|
timeout: timeoutMs,
|
|
33210
34515
|
...process.platform === "win32" ? { windowsHide: true } : {}
|
|
33211
34516
|
}, (err, stdout) => {
|
|
33212
34517
|
if (err || !stdout?.trim()) {
|
|
33213
|
-
|
|
34518
|
+
resolve15(null);
|
|
33214
34519
|
} else {
|
|
33215
|
-
|
|
34520
|
+
resolve15(stdout.trim());
|
|
33216
34521
|
}
|
|
33217
34522
|
});
|
|
33218
|
-
child.on("error", () =>
|
|
34523
|
+
child.on("error", () => resolve15(null));
|
|
33219
34524
|
});
|
|
33220
34525
|
}
|
|
33221
34526
|
async function detectCLIs(providerLoader, options) {
|
|
@@ -33572,7 +34877,7 @@ var require_dist2 = __commonJS({
|
|
|
33572
34877
|
* Returns multiple entries if multiple IDE windows are open on same port
|
|
33573
34878
|
*/
|
|
33574
34879
|
static listAllTargets(port) {
|
|
33575
|
-
return new Promise((
|
|
34880
|
+
return new Promise((resolve15) => {
|
|
33576
34881
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
33577
34882
|
let data = "";
|
|
33578
34883
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -33588,16 +34893,16 @@ var require_dist2 = __commonJS({
|
|
|
33588
34893
|
(t) => !isNonMain(t.title || "") && t.url?.includes("workbench.html") && !t.url?.includes("agent")
|
|
33589
34894
|
);
|
|
33590
34895
|
const fallbackPages = pages.filter((t) => !isNonMain(t.title || ""));
|
|
33591
|
-
|
|
34896
|
+
resolve15(mainPages.length > 0 ? mainPages : fallbackPages);
|
|
33592
34897
|
} catch {
|
|
33593
|
-
|
|
34898
|
+
resolve15([]);
|
|
33594
34899
|
}
|
|
33595
34900
|
});
|
|
33596
34901
|
});
|
|
33597
|
-
req.on("error", () =>
|
|
34902
|
+
req.on("error", () => resolve15([]));
|
|
33598
34903
|
req.setTimeout(2e3, () => {
|
|
33599
34904
|
req.destroy();
|
|
33600
|
-
|
|
34905
|
+
resolve15([]);
|
|
33601
34906
|
});
|
|
33602
34907
|
});
|
|
33603
34908
|
}
|
|
@@ -33637,7 +34942,7 @@ var require_dist2 = __commonJS({
|
|
|
33637
34942
|
}
|
|
33638
34943
|
}
|
|
33639
34944
|
findTargetOnPort(port) {
|
|
33640
|
-
return new Promise((
|
|
34945
|
+
return new Promise((resolve15) => {
|
|
33641
34946
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
33642
34947
|
let data = "";
|
|
33643
34948
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -33648,7 +34953,7 @@ var require_dist2 = __commonJS({
|
|
|
33648
34953
|
(t) => (t.type === "page" || t.type === "browser" || t.type === "Page") && t.webSocketDebuggerUrl
|
|
33649
34954
|
);
|
|
33650
34955
|
if (pages.length === 0) {
|
|
33651
|
-
|
|
34956
|
+
resolve15(targets.find((t) => t.webSocketDebuggerUrl) || null);
|
|
33652
34957
|
return;
|
|
33653
34958
|
}
|
|
33654
34959
|
const titleFilteredPages = pages.filter((t) => !this.isNonMainTitle(t.title || ""));
|
|
@@ -33667,25 +34972,25 @@ var require_dist2 = __commonJS({
|
|
|
33667
34972
|
this._targetId = selected.target.id;
|
|
33668
34973
|
}
|
|
33669
34974
|
this._pageTitle = selected.target.title || "";
|
|
33670
|
-
|
|
34975
|
+
resolve15(selected.target);
|
|
33671
34976
|
return;
|
|
33672
34977
|
}
|
|
33673
34978
|
if (previousTargetId) {
|
|
33674
34979
|
this.log(`[CDP] Target ${previousTargetId} not found in page list`);
|
|
33675
|
-
|
|
34980
|
+
resolve15(null);
|
|
33676
34981
|
return;
|
|
33677
34982
|
}
|
|
33678
34983
|
this._pageTitle = list[0]?.title || "";
|
|
33679
|
-
|
|
34984
|
+
resolve15(list[0]);
|
|
33680
34985
|
} catch {
|
|
33681
|
-
|
|
34986
|
+
resolve15(null);
|
|
33682
34987
|
}
|
|
33683
34988
|
});
|
|
33684
34989
|
});
|
|
33685
|
-
req.on("error", () =>
|
|
34990
|
+
req.on("error", () => resolve15(null));
|
|
33686
34991
|
req.setTimeout(2e3, () => {
|
|
33687
34992
|
req.destroy();
|
|
33688
|
-
|
|
34993
|
+
resolve15(null);
|
|
33689
34994
|
});
|
|
33690
34995
|
});
|
|
33691
34996
|
}
|
|
@@ -33696,7 +35001,7 @@ var require_dist2 = __commonJS({
|
|
|
33696
35001
|
this.extensionProviders = providers;
|
|
33697
35002
|
}
|
|
33698
35003
|
connectToTarget(wsUrl) {
|
|
33699
|
-
return new Promise((
|
|
35004
|
+
return new Promise((resolve15) => {
|
|
33700
35005
|
this.ws = new import_ws2.default(wsUrl);
|
|
33701
35006
|
this.ws.on("open", async () => {
|
|
33702
35007
|
this._connected = true;
|
|
@@ -33706,17 +35011,17 @@ var require_dist2 = __commonJS({
|
|
|
33706
35011
|
}
|
|
33707
35012
|
this.connectBrowserWs().catch(() => {
|
|
33708
35013
|
});
|
|
33709
|
-
|
|
35014
|
+
resolve15(true);
|
|
33710
35015
|
});
|
|
33711
35016
|
this.ws.on("message", (data) => {
|
|
33712
35017
|
try {
|
|
33713
35018
|
const msg = JSON.parse(data.toString());
|
|
33714
35019
|
if (msg.id && this.pending.has(msg.id)) {
|
|
33715
|
-
const { resolve:
|
|
35020
|
+
const { resolve: resolve16, reject } = this.pending.get(msg.id);
|
|
33716
35021
|
this.pending.delete(msg.id);
|
|
33717
35022
|
this.failureCount = 0;
|
|
33718
35023
|
if (msg.error) reject(new Error(msg.error.message));
|
|
33719
|
-
else
|
|
35024
|
+
else resolve16(msg.result);
|
|
33720
35025
|
} else if (msg.method === "Runtime.executionContextCreated") {
|
|
33721
35026
|
this.contexts.add(msg.params.context.id);
|
|
33722
35027
|
} else if (msg.method === "Runtime.executionContextDestroyed") {
|
|
@@ -33739,7 +35044,7 @@ var require_dist2 = __commonJS({
|
|
|
33739
35044
|
this.ws.on("error", (err) => {
|
|
33740
35045
|
this.log(`[CDP] WebSocket error: ${err.message}`);
|
|
33741
35046
|
this._connected = false;
|
|
33742
|
-
|
|
35047
|
+
resolve15(false);
|
|
33743
35048
|
});
|
|
33744
35049
|
});
|
|
33745
35050
|
}
|
|
@@ -33753,7 +35058,7 @@ var require_dist2 = __commonJS({
|
|
|
33753
35058
|
return;
|
|
33754
35059
|
}
|
|
33755
35060
|
this.log(`[CDP] Connecting browser WS for target discovery...`);
|
|
33756
|
-
await new Promise((
|
|
35061
|
+
await new Promise((resolve15, reject) => {
|
|
33757
35062
|
this.browserWs = new import_ws2.default(browserWsUrl);
|
|
33758
35063
|
this.browserWs.on("open", async () => {
|
|
33759
35064
|
this._browserConnected = true;
|
|
@@ -33763,16 +35068,16 @@ var require_dist2 = __commonJS({
|
|
|
33763
35068
|
} catch (e) {
|
|
33764
35069
|
this.log(`[CDP] setDiscoverTargets failed: ${e.message}`);
|
|
33765
35070
|
}
|
|
33766
|
-
|
|
35071
|
+
resolve15();
|
|
33767
35072
|
});
|
|
33768
35073
|
this.browserWs.on("message", (data) => {
|
|
33769
35074
|
try {
|
|
33770
35075
|
const msg = JSON.parse(data.toString());
|
|
33771
35076
|
if (msg.id && this.browserPending.has(msg.id)) {
|
|
33772
|
-
const { resolve:
|
|
35077
|
+
const { resolve: resolve16, reject: reject2 } = this.browserPending.get(msg.id);
|
|
33773
35078
|
this.browserPending.delete(msg.id);
|
|
33774
35079
|
if (msg.error) reject2(new Error(msg.error.message));
|
|
33775
|
-
else
|
|
35080
|
+
else resolve16(msg.result);
|
|
33776
35081
|
}
|
|
33777
35082
|
} catch {
|
|
33778
35083
|
}
|
|
@@ -33792,31 +35097,31 @@ var require_dist2 = __commonJS({
|
|
|
33792
35097
|
}
|
|
33793
35098
|
}
|
|
33794
35099
|
getBrowserWsUrl() {
|
|
33795
|
-
return new Promise((
|
|
35100
|
+
return new Promise((resolve15) => {
|
|
33796
35101
|
const req = http.get(`http://127.0.0.1:${this.port}/json/version`, (res) => {
|
|
33797
35102
|
let data = "";
|
|
33798
35103
|
res.on("data", (chunk) => data += chunk.toString());
|
|
33799
35104
|
res.on("end", () => {
|
|
33800
35105
|
try {
|
|
33801
35106
|
const info = JSON.parse(data);
|
|
33802
|
-
|
|
35107
|
+
resolve15(info.webSocketDebuggerUrl || null);
|
|
33803
35108
|
} catch {
|
|
33804
|
-
|
|
35109
|
+
resolve15(null);
|
|
33805
35110
|
}
|
|
33806
35111
|
});
|
|
33807
35112
|
});
|
|
33808
|
-
req.on("error", () =>
|
|
35113
|
+
req.on("error", () => resolve15(null));
|
|
33809
35114
|
req.setTimeout(3e3, () => {
|
|
33810
35115
|
req.destroy();
|
|
33811
|
-
|
|
35116
|
+
resolve15(null);
|
|
33812
35117
|
});
|
|
33813
35118
|
});
|
|
33814
35119
|
}
|
|
33815
35120
|
sendBrowser(method, params = {}, timeoutMs = 15e3) {
|
|
33816
|
-
return new Promise((
|
|
35121
|
+
return new Promise((resolve15, reject) => {
|
|
33817
35122
|
if (!this.browserWs || !this._browserConnected) return reject(new Error("Browser WS not connected"));
|
|
33818
35123
|
const id = this.browserMsgId++;
|
|
33819
|
-
this.browserPending.set(id, { resolve:
|
|
35124
|
+
this.browserPending.set(id, { resolve: resolve15, reject });
|
|
33820
35125
|
this.browserWs.send(JSON.stringify({ id, method, params }));
|
|
33821
35126
|
setTimeout(() => {
|
|
33822
35127
|
if (this.browserPending.has(id)) {
|
|
@@ -33856,11 +35161,11 @@ var require_dist2 = __commonJS({
|
|
|
33856
35161
|
}
|
|
33857
35162
|
// ─── CDP Protocol ────────────────────────────────────────
|
|
33858
35163
|
sendInternal(method, params = {}, timeoutMs = 15e3) {
|
|
33859
|
-
return new Promise((
|
|
35164
|
+
return new Promise((resolve15, reject) => {
|
|
33860
35165
|
if (!this.ws || !this._connected) return reject(new Error("CDP not connected"));
|
|
33861
35166
|
if (this.ws.readyState !== import_ws2.default.OPEN) return reject(new Error("WebSocket not open"));
|
|
33862
35167
|
const id = this.msgId++;
|
|
33863
|
-
this.pending.set(id, { resolve:
|
|
35168
|
+
this.pending.set(id, { resolve: resolve15, reject });
|
|
33864
35169
|
this.ws.send(JSON.stringify({ id, method, params }));
|
|
33865
35170
|
setTimeout(() => {
|
|
33866
35171
|
if (this.pending.has(id)) {
|
|
@@ -34109,7 +35414,7 @@ var require_dist2 = __commonJS({
|
|
|
34109
35414
|
const browserWs = this.browserWs;
|
|
34110
35415
|
let msgId = this.browserMsgId;
|
|
34111
35416
|
const sendWs = (method, params = {}, sessionId) => {
|
|
34112
|
-
return new Promise((
|
|
35417
|
+
return new Promise((resolve15, reject) => {
|
|
34113
35418
|
const mid = msgId++;
|
|
34114
35419
|
this.browserMsgId = msgId;
|
|
34115
35420
|
const handler = (raw) => {
|
|
@@ -34118,7 +35423,7 @@ var require_dist2 = __commonJS({
|
|
|
34118
35423
|
if (msg.id === mid) {
|
|
34119
35424
|
browserWs.removeListener("message", handler);
|
|
34120
35425
|
if (msg.error) reject(new Error(msg.error.message || JSON.stringify(msg.error)));
|
|
34121
|
-
else
|
|
35426
|
+
else resolve15(msg.result);
|
|
34122
35427
|
}
|
|
34123
35428
|
} catch {
|
|
34124
35429
|
}
|
|
@@ -34319,14 +35624,14 @@ var require_dist2 = __commonJS({
|
|
|
34319
35624
|
if (!ws2 || ws2.readyState !== import_ws2.default.OPEN) {
|
|
34320
35625
|
throw new Error("CDP not connected");
|
|
34321
35626
|
}
|
|
34322
|
-
return new Promise((
|
|
35627
|
+
return new Promise((resolve15, reject) => {
|
|
34323
35628
|
const id = getNextId();
|
|
34324
35629
|
pendingMap.set(id, {
|
|
34325
35630
|
resolve: (result) => {
|
|
34326
35631
|
if (result?.result?.subtype === "error") {
|
|
34327
35632
|
reject(new Error(result.result.description));
|
|
34328
35633
|
} else {
|
|
34329
|
-
|
|
35634
|
+
resolve15(result?.result?.value);
|
|
34330
35635
|
}
|
|
34331
35636
|
},
|
|
34332
35637
|
reject
|
|
@@ -34358,10 +35663,10 @@ var require_dist2 = __commonJS({
|
|
|
34358
35663
|
throw new Error("CDP not connected");
|
|
34359
35664
|
}
|
|
34360
35665
|
const sendViaSession = (method, params = {}) => {
|
|
34361
|
-
return new Promise((
|
|
35666
|
+
return new Promise((resolve15, reject) => {
|
|
34362
35667
|
const pendingMap = this._browserConnected ? this.browserPending : this.pending;
|
|
34363
35668
|
const id = this._browserConnected ? this.browserMsgId++ : this.msgId++;
|
|
34364
|
-
pendingMap.set(id, { resolve:
|
|
35669
|
+
pendingMap.set(id, { resolve: resolve15, reject });
|
|
34365
35670
|
ws2.send(JSON.stringify({ id, sessionId, method, params }));
|
|
34366
35671
|
setTimeout(() => {
|
|
34367
35672
|
if (pendingMap.has(id)) {
|
|
@@ -35095,10 +36400,10 @@ ${cleanBody}`;
|
|
|
35095
36400
|
return cleanTitle || cleanBody;
|
|
35096
36401
|
}
|
|
35097
36402
|
var fs32 = __toESM2(require("fs"));
|
|
35098
|
-
var
|
|
36403
|
+
var path10 = __toESM2(require("path"));
|
|
35099
36404
|
var os52 = __toESM2(require("os"));
|
|
35100
36405
|
init_chat_message_normalization();
|
|
35101
|
-
var HISTORY_DIR =
|
|
36406
|
+
var HISTORY_DIR = path10.join(os52.homedir(), ".adhdev", "history");
|
|
35102
36407
|
var RETAIN_DAYS = 30;
|
|
35103
36408
|
var SAVED_HISTORY_INDEX_VERSION = 1;
|
|
35104
36409
|
var SAVED_HISTORY_INDEX_FILE = ".saved-history-index.json";
|
|
@@ -35261,8 +36566,8 @@ ${cleanBody}`;
|
|
|
35261
36566
|
function buildSavedHistoryFileSignatureMap(dir, files) {
|
|
35262
36567
|
return new Map(files.map((file2) => {
|
|
35263
36568
|
try {
|
|
35264
|
-
const
|
|
35265
|
-
return [file2, `${file2}:${
|
|
36569
|
+
const stat22 = fs32.statSync(path10.join(dir, file2));
|
|
36570
|
+
return [file2, `${file2}:${stat22.size}:${Math.trunc(stat22.mtimeMs)}`];
|
|
35266
36571
|
} catch {
|
|
35267
36572
|
return [file2, `${file2}:missing`];
|
|
35268
36573
|
}
|
|
@@ -35272,7 +36577,7 @@ ${cleanBody}`;
|
|
|
35272
36577
|
return files.map((file2) => fileSignatures.get(file2) || `${file2}:missing`).join("|");
|
|
35273
36578
|
}
|
|
35274
36579
|
function getSavedHistoryIndexFilePath(dir) {
|
|
35275
|
-
return
|
|
36580
|
+
return path10.join(dir, SAVED_HISTORY_INDEX_FILE);
|
|
35276
36581
|
}
|
|
35277
36582
|
function getSavedHistoryIndexLockPath(dir) {
|
|
35278
36583
|
return `${getSavedHistoryIndexFilePath(dir)}${SAVED_HISTORY_INDEX_LOCK_SUFFIX}`;
|
|
@@ -35325,8 +36630,8 @@ ${cleanBody}`;
|
|
|
35325
36630
|
} catch (error48) {
|
|
35326
36631
|
if (error48?.code !== "EEXIST") return null;
|
|
35327
36632
|
try {
|
|
35328
|
-
const
|
|
35329
|
-
if (Date.now() -
|
|
36633
|
+
const stat22 = fs32.statSync(lockPath);
|
|
36634
|
+
if (Date.now() - stat22.mtimeMs > SAVED_HISTORY_INDEX_LOCK_STALE_MS) {
|
|
35330
36635
|
fs32.rmSync(lockPath, { recursive: true, force: true });
|
|
35331
36636
|
continue;
|
|
35332
36637
|
}
|
|
@@ -35374,7 +36679,7 @@ ${cleanBody}`;
|
|
|
35374
36679
|
}
|
|
35375
36680
|
for (const file2 of Array.from(currentEntries.keys())) {
|
|
35376
36681
|
if (incomingFiles.has(file2)) continue;
|
|
35377
|
-
if (!fs32.existsSync(
|
|
36682
|
+
if (!fs32.existsSync(path10.join(dir, file2))) {
|
|
35378
36683
|
currentEntries.delete(file2);
|
|
35379
36684
|
}
|
|
35380
36685
|
}
|
|
@@ -35389,8 +36694,8 @@ ${cleanBody}`;
|
|
|
35389
36694
|
}
|
|
35390
36695
|
function buildSavedHistoryIndexFileSignature(dir) {
|
|
35391
36696
|
try {
|
|
35392
|
-
const
|
|
35393
|
-
return `index:${
|
|
36697
|
+
const stat22 = fs32.statSync(getSavedHistoryIndexFilePath(dir));
|
|
36698
|
+
return `index:${stat22.size}:${Math.trunc(stat22.mtimeMs)}`;
|
|
35394
36699
|
} catch {
|
|
35395
36700
|
return "index:missing";
|
|
35396
36701
|
}
|
|
@@ -35400,8 +36705,8 @@ ${cleanBody}`;
|
|
|
35400
36705
|
const indexStat = fs32.statSync(getSavedHistoryIndexFilePath(dir));
|
|
35401
36706
|
const files = listHistoryFiles(dir);
|
|
35402
36707
|
for (const file2 of files) {
|
|
35403
|
-
const
|
|
35404
|
-
if (
|
|
36708
|
+
const stat22 = fs32.statSync(path10.join(dir, file2));
|
|
36709
|
+
if (stat22.mtimeMs > indexStat.mtimeMs) return true;
|
|
35405
36710
|
}
|
|
35406
36711
|
return false;
|
|
35407
36712
|
} catch {
|
|
@@ -35410,14 +36715,14 @@ ${cleanBody}`;
|
|
|
35410
36715
|
}
|
|
35411
36716
|
function buildSavedHistoryFileSignature(dir, file2) {
|
|
35412
36717
|
try {
|
|
35413
|
-
const
|
|
35414
|
-
return `${file2}:${
|
|
36718
|
+
const stat22 = fs32.statSync(path10.join(dir, file2));
|
|
36719
|
+
return `${file2}:${stat22.size}:${Math.trunc(stat22.mtimeMs)}`;
|
|
35415
36720
|
} catch {
|
|
35416
36721
|
return `${file2}:missing`;
|
|
35417
36722
|
}
|
|
35418
36723
|
}
|
|
35419
36724
|
function persistSavedHistoryFileSummaryEntry(agentType, dir, file2, updater) {
|
|
35420
|
-
const filePath =
|
|
36725
|
+
const filePath = path10.join(dir, file2);
|
|
35421
36726
|
const result = withLockedPersistedSavedHistoryIndex(dir, (entries) => {
|
|
35422
36727
|
const currentEntry = entries.get(file2) || null;
|
|
35423
36728
|
const nextSummary = updater(currentEntry?.summary || null);
|
|
@@ -35490,7 +36795,7 @@ ${cleanBody}`;
|
|
|
35490
36795
|
function computeSavedHistoryFileSummary(dir, file2) {
|
|
35491
36796
|
const historySessionId = extractSavedHistorySessionIdFromFile(file2);
|
|
35492
36797
|
if (!historySessionId) return null;
|
|
35493
|
-
const filePath =
|
|
36798
|
+
const filePath = path10.join(dir, file2);
|
|
35494
36799
|
const content = fs32.readFileSync(filePath, "utf-8");
|
|
35495
36800
|
const lines = content.split("\n").filter(Boolean);
|
|
35496
36801
|
let messageCount = 0;
|
|
@@ -35577,7 +36882,7 @@ ${cleanBody}`;
|
|
|
35577
36882
|
const summaryBySessionId = /* @__PURE__ */ new Map();
|
|
35578
36883
|
const nextPersistedEntries = /* @__PURE__ */ new Map();
|
|
35579
36884
|
for (const file2 of files.slice().sort()) {
|
|
35580
|
-
const filePath =
|
|
36885
|
+
const filePath = path10.join(dir, file2);
|
|
35581
36886
|
const signature = fileSignatures.get(file2) || `${file2}:missing`;
|
|
35582
36887
|
const cached2 = savedHistoryFileSummaryCache.get(filePath);
|
|
35583
36888
|
const persisted = persistedEntries.get(file2);
|
|
@@ -35697,12 +37002,12 @@ ${cleanBody}`;
|
|
|
35697
37002
|
});
|
|
35698
37003
|
}
|
|
35699
37004
|
if (newMessages.length === 0) return;
|
|
35700
|
-
const dir =
|
|
37005
|
+
const dir = path10.join(HISTORY_DIR, this.sanitize(agentType));
|
|
35701
37006
|
fs32.mkdirSync(dir, { recursive: true });
|
|
35702
37007
|
const date5 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
35703
37008
|
const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
|
|
35704
37009
|
const fileName = `${filePrefix}${date5}.jsonl`;
|
|
35705
|
-
const filePath =
|
|
37010
|
+
const filePath = path10.join(dir, fileName);
|
|
35706
37011
|
const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
35707
37012
|
fs32.appendFileSync(filePath, lines, "utf-8");
|
|
35708
37013
|
updateSavedHistoryIndexForAppendedMessages(agentType, dir, fileName, effectiveHistoryKey, newMessages);
|
|
@@ -35793,11 +37098,11 @@ ${cleanBody}`;
|
|
|
35793
37098
|
const ws2 = String(workspace || "").trim();
|
|
35794
37099
|
if (!id || !ws2) return;
|
|
35795
37100
|
try {
|
|
35796
|
-
const dir =
|
|
37101
|
+
const dir = path10.join(HISTORY_DIR, this.sanitize(agentType));
|
|
35797
37102
|
fs32.mkdirSync(dir, { recursive: true });
|
|
35798
37103
|
const date5 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
35799
37104
|
const fileName = `${this.sanitize(id)}_${date5}.jsonl`;
|
|
35800
|
-
const filePath =
|
|
37105
|
+
const filePath = path10.join(dir, fileName);
|
|
35801
37106
|
const record2 = {
|
|
35802
37107
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35803
37108
|
receivedAt: Date.now(),
|
|
@@ -35843,14 +37148,14 @@ ${cleanBody}`;
|
|
|
35843
37148
|
this.lastSeenCounts.set(toDedupKey, Math.max(fromCount, this.lastSeenCounts.get(toDedupKey) || 0));
|
|
35844
37149
|
this.lastSeenCounts.delete(fromDedupKey);
|
|
35845
37150
|
}
|
|
35846
|
-
const dir =
|
|
37151
|
+
const dir = path10.join(HISTORY_DIR, this.sanitize(agentType));
|
|
35847
37152
|
if (!fs32.existsSync(dir)) return;
|
|
35848
37153
|
const fromPrefix = `${this.sanitize(fromId)}_`;
|
|
35849
37154
|
const toPrefix = `${this.sanitize(toId)}_`;
|
|
35850
37155
|
const files = fs32.readdirSync(dir).filter((file2) => file2.startsWith(fromPrefix) && file2.endsWith(".jsonl"));
|
|
35851
37156
|
for (const file2 of files) {
|
|
35852
|
-
const sourcePath =
|
|
35853
|
-
const targetPath =
|
|
37157
|
+
const sourcePath = path10.join(dir, file2);
|
|
37158
|
+
const targetPath = path10.join(dir, `${toPrefix}${file2.slice(fromPrefix.length)}`);
|
|
35854
37159
|
const sourceLines = fs32.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
|
|
35855
37160
|
const rewritten = sourceLines.map((line) => {
|
|
35856
37161
|
try {
|
|
@@ -35884,13 +37189,13 @@ ${cleanBody}`;
|
|
|
35884
37189
|
const sessionId = String(historySessionId || "").trim();
|
|
35885
37190
|
if (!sessionId) return;
|
|
35886
37191
|
try {
|
|
35887
|
-
const dir =
|
|
37192
|
+
const dir = path10.join(HISTORY_DIR, this.sanitize(agentType));
|
|
35888
37193
|
if (!fs32.existsSync(dir)) return;
|
|
35889
37194
|
const prefix = `${this.sanitize(sessionId)}_`;
|
|
35890
37195
|
const files = fs32.readdirSync(dir).filter((file2) => file2.startsWith(prefix) && file2.endsWith(".jsonl")).sort();
|
|
35891
37196
|
const seen = /* @__PURE__ */ new Set();
|
|
35892
37197
|
for (const file2 of files) {
|
|
35893
|
-
const filePath =
|
|
37198
|
+
const filePath = path10.join(dir, file2);
|
|
35894
37199
|
const lines = fs32.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
|
|
35895
37200
|
const next = [];
|
|
35896
37201
|
for (const line of lines) {
|
|
@@ -35944,13 +37249,13 @@ ${cleanBody}`;
|
|
|
35944
37249
|
const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
|
|
35945
37250
|
const agentDirs = fs32.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
35946
37251
|
for (const dir of agentDirs) {
|
|
35947
|
-
const dirPath =
|
|
37252
|
+
const dirPath = path10.join(HISTORY_DIR, dir.name);
|
|
35948
37253
|
const files = fs32.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
|
|
35949
37254
|
let removedAny = false;
|
|
35950
37255
|
for (const file2 of files) {
|
|
35951
|
-
const filePath =
|
|
35952
|
-
const
|
|
35953
|
-
if (
|
|
37256
|
+
const filePath = path10.join(dirPath, file2);
|
|
37257
|
+
const stat22 = fs32.statSync(filePath);
|
|
37258
|
+
if (stat22.mtimeMs < cutoff) {
|
|
35954
37259
|
fs32.unlinkSync(filePath);
|
|
35955
37260
|
removedAny = true;
|
|
35956
37261
|
}
|
|
@@ -35998,13 +37303,13 @@ ${cleanBody}`;
|
|
|
35998
37303
|
function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
|
|
35999
37304
|
try {
|
|
36000
37305
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
36001
|
-
const dir =
|
|
37306
|
+
const dir = path10.join(HISTORY_DIR, sanitized);
|
|
36002
37307
|
if (!fs32.existsSync(dir)) return { messages: [], hasMore: false };
|
|
36003
37308
|
const files = listHistoryFiles(dir, historySessionId);
|
|
36004
37309
|
const allMessages = [];
|
|
36005
37310
|
const seen = /* @__PURE__ */ new Set();
|
|
36006
37311
|
for (const file2 of files) {
|
|
36007
|
-
const filePath =
|
|
37312
|
+
const filePath = path10.join(dir, file2);
|
|
36008
37313
|
const content = fs32.readFileSync(filePath, "utf-8");
|
|
36009
37314
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
36010
37315
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -36028,7 +37333,7 @@ ${cleanBody}`;
|
|
|
36028
37333
|
function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
36029
37334
|
try {
|
|
36030
37335
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
36031
|
-
const dir =
|
|
37336
|
+
const dir = path10.join(HISTORY_DIR, sanitized);
|
|
36032
37337
|
if (!fs32.existsSync(dir)) {
|
|
36033
37338
|
savedHistorySessionCache.delete(sanitized);
|
|
36034
37339
|
return { sessions: [], hasMore: false };
|
|
@@ -36089,11 +37394,11 @@ ${cleanBody}`;
|
|
|
36089
37394
|
}
|
|
36090
37395
|
function readExistingSessionStartRecord(agentType, historySessionId) {
|
|
36091
37396
|
try {
|
|
36092
|
-
const dir =
|
|
37397
|
+
const dir = path10.join(HISTORY_DIR, agentType);
|
|
36093
37398
|
if (!fs32.existsSync(dir)) return null;
|
|
36094
37399
|
const files = listHistoryFiles(dir, historySessionId).sort();
|
|
36095
37400
|
for (const file2 of files) {
|
|
36096
|
-
const lines = fs32.readFileSync(
|
|
37401
|
+
const lines = fs32.readFileSync(path10.join(dir, file2), "utf-8").split("\n").filter(Boolean);
|
|
36097
37402
|
for (const line of lines) {
|
|
36098
37403
|
try {
|
|
36099
37404
|
const parsed = JSON.parse(line);
|
|
@@ -36113,16 +37418,16 @@ ${cleanBody}`;
|
|
|
36113
37418
|
function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
|
|
36114
37419
|
if (records.length === 0) return false;
|
|
36115
37420
|
try {
|
|
36116
|
-
const dir =
|
|
37421
|
+
const dir = path10.join(HISTORY_DIR, agentType);
|
|
36117
37422
|
fs32.mkdirSync(dir, { recursive: true });
|
|
36118
37423
|
const prefix = `${historySessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
|
|
36119
37424
|
for (const file2 of fs32.readdirSync(dir)) {
|
|
36120
37425
|
if (file2.startsWith(prefix) && file2.endsWith(".jsonl")) {
|
|
36121
|
-
fs32.unlinkSync(
|
|
37426
|
+
fs32.unlinkSync(path10.join(dir, file2));
|
|
36122
37427
|
}
|
|
36123
37428
|
}
|
|
36124
37429
|
const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
|
|
36125
|
-
const filePath =
|
|
37430
|
+
const filePath = path10.join(dir, `${prefix}${targetDate}.jsonl`);
|
|
36126
37431
|
fs32.writeFileSync(filePath, `${records.map((record2) => JSON.stringify(record2)).join("\n")}
|
|
36127
37432
|
`, "utf-8");
|
|
36128
37433
|
invalidatePersistedSavedHistoryIndex(agentType, dir);
|
|
@@ -37966,6 +39271,10 @@ ${effect.notification.body || ""}`.trim();
|
|
|
37966
39271
|
function shouldIncludeRuntimeMetadata(profile) {
|
|
37967
39272
|
return true;
|
|
37968
39273
|
}
|
|
39274
|
+
function getGitSummaryForWorkspace(workspace, options) {
|
|
39275
|
+
if (!workspace) return void 0;
|
|
39276
|
+
return options.getGitSummaryForWorkspace?.(workspace) || void 0;
|
|
39277
|
+
}
|
|
37969
39278
|
function findCdpManager(cdpManagers, key) {
|
|
37970
39279
|
const exact = cdpManagers.get(key);
|
|
37971
39280
|
if (exact) return exact.isConnected ? exact : null;
|
|
@@ -38021,6 +39330,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38021
39330
|
const controlValues = normalizeProviderStateControlValues(state.controlValues);
|
|
38022
39331
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
38023
39332
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
39333
|
+
const workspace = state.workspace || null;
|
|
39334
|
+
const git = getGitSummaryForWorkspace(workspace, options);
|
|
38024
39335
|
const title = activeChat?.title || state.name;
|
|
38025
39336
|
return {
|
|
38026
39337
|
id: state.instanceId || state.type,
|
|
@@ -38033,7 +39344,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38033
39344
|
activeModal: activeChat?.activeModal || null
|
|
38034
39345
|
}),
|
|
38035
39346
|
title,
|
|
38036
|
-
workspace
|
|
39347
|
+
workspace,
|
|
39348
|
+
...git && { git },
|
|
38037
39349
|
activeChat,
|
|
38038
39350
|
...summaryMetadata && { summaryMetadata },
|
|
38039
39351
|
...includeSessionMetadata && { capabilities: state.sessionCapabilities || IDE_SESSION_CAPABILITIES },
|
|
@@ -38054,6 +39366,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38054
39366
|
const controlValues = normalizeProviderStateControlValues(ext.controlValues);
|
|
38055
39367
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
38056
39368
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
39369
|
+
const workspace = parent.workspace || null;
|
|
39370
|
+
const git = getGitSummaryForWorkspace(workspace, options);
|
|
38057
39371
|
return {
|
|
38058
39372
|
id: ext.instanceId || `${parent.instanceId}:${ext.type}`,
|
|
38059
39373
|
parentId: parent.instanceId || parent.type,
|
|
@@ -38066,7 +39380,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38066
39380
|
activeModal: activeChat?.activeModal || null
|
|
38067
39381
|
}),
|
|
38068
39382
|
title: activeChat?.title || ext.name,
|
|
38069
|
-
workspace
|
|
39383
|
+
workspace,
|
|
39384
|
+
...git && { git },
|
|
38070
39385
|
activeChat,
|
|
38071
39386
|
...summaryMetadata && { summaryMetadata },
|
|
38072
39387
|
...includeSessionMetadata && { capabilities: ext.sessionCapabilities || EXTENSION_SESSION_CAPABILITIES },
|
|
@@ -38102,6 +39417,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38102
39417
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
38103
39418
|
const includeRuntimeMetadata = shouldIncludeRuntimeMetadata(profile);
|
|
38104
39419
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
39420
|
+
const workspace = state.workspace || null;
|
|
39421
|
+
const git = getGitSummaryForWorkspace(workspace, options);
|
|
38105
39422
|
return {
|
|
38106
39423
|
id: state.instanceId,
|
|
38107
39424
|
parentId: null,
|
|
@@ -38114,7 +39431,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38114
39431
|
activeModal: activeChat?.activeModal || null
|
|
38115
39432
|
}),
|
|
38116
39433
|
title: activeChat?.title || state.name,
|
|
38117
|
-
workspace
|
|
39434
|
+
workspace,
|
|
39435
|
+
...git && { git },
|
|
38118
39436
|
...includeRuntimeMetadata && {
|
|
38119
39437
|
runtimeKey: state.runtime?.runtimeKey,
|
|
38120
39438
|
runtimeDisplayName: state.runtime?.displayName,
|
|
@@ -38149,6 +39467,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38149
39467
|
const controlValues = normalizeProviderStateControlValues(state.controlValues);
|
|
38150
39468
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
38151
39469
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
39470
|
+
const workspace = state.workspace || null;
|
|
39471
|
+
const git = getGitSummaryForWorkspace(workspace, options);
|
|
38152
39472
|
return {
|
|
38153
39473
|
id: state.instanceId,
|
|
38154
39474
|
parentId: null,
|
|
@@ -38160,7 +39480,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38160
39480
|
activeModal: activeChat?.activeModal || null
|
|
38161
39481
|
}),
|
|
38162
39482
|
title: activeChat?.title || state.name,
|
|
38163
|
-
workspace
|
|
39483
|
+
workspace,
|
|
39484
|
+
...git && { git },
|
|
38164
39485
|
activeChat,
|
|
38165
39486
|
...summaryMetadata && { summaryMetadata },
|
|
38166
39487
|
...includeSessionMetadata && { capabilities: ACP_SESSION_CAPABILITIES },
|
|
@@ -38271,7 +39592,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38271
39592
|
}
|
|
38272
39593
|
var fs42 = __toESM2(require("fs"));
|
|
38273
39594
|
var os62 = __toESM2(require("os"));
|
|
38274
|
-
var
|
|
39595
|
+
var path11 = __toESM2(require("path"));
|
|
38275
39596
|
var import_node_crypto = require("crypto");
|
|
38276
39597
|
init_contracts();
|
|
38277
39598
|
var VALID_INPUT_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
|
|
@@ -38954,7 +40275,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38954
40275
|
}
|
|
38955
40276
|
function getChatDebugBundleDir() {
|
|
38956
40277
|
const override = typeof process.env.ADHDEV_DEBUG_BUNDLE_DIR === "string" ? process.env.ADHDEV_DEBUG_BUNDLE_DIR.trim() : "";
|
|
38957
|
-
return override ||
|
|
40278
|
+
return override || path11.join(os62.homedir(), ".adhdev", "debug-bundles", "chat");
|
|
38958
40279
|
}
|
|
38959
40280
|
function safeBundleIdSegment(value, fallback) {
|
|
38960
40281
|
const normalized = String(value || fallback).trim().replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
@@ -38987,7 +40308,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38987
40308
|
const bundleId = createChatDebugBundleId(targetSessionId);
|
|
38988
40309
|
const dir = getChatDebugBundleDir();
|
|
38989
40310
|
fs42.mkdirSync(dir, { recursive: true });
|
|
38990
|
-
const savedPath =
|
|
40311
|
+
const savedPath = path11.join(dir, `${bundleId}.json`);
|
|
38991
40312
|
const json2 = `${JSON.stringify(bundle, null, 2)}
|
|
38992
40313
|
`;
|
|
38993
40314
|
fs42.writeFileSync(savedPath, json2, { encoding: "utf8", mode: 384 });
|
|
@@ -39181,7 +40502,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
39181
40502
|
async function getStableExtensionBaseline(h) {
|
|
39182
40503
|
const first = await readExtensionChatState(h);
|
|
39183
40504
|
if (getStateMessageCount(first) > 0 || getStateLastSignature(first)) return first;
|
|
39184
|
-
await new Promise((
|
|
40505
|
+
await new Promise((resolve15) => setTimeout(resolve15, 150));
|
|
39185
40506
|
const second = await readExtensionChatState(h);
|
|
39186
40507
|
return getStateMessageCount(second) >= getStateMessageCount(first) ? second : first;
|
|
39187
40508
|
}
|
|
@@ -39189,7 +40510,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
39189
40510
|
const beforeCount = getStateMessageCount(before);
|
|
39190
40511
|
const beforeSignature = getStateLastSignature(before);
|
|
39191
40512
|
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
39192
|
-
await new Promise((
|
|
40513
|
+
await new Promise((resolve15) => setTimeout(resolve15, 250));
|
|
39193
40514
|
const state = await readExtensionChatState(h);
|
|
39194
40515
|
if (state?.status === "waiting_approval") return true;
|
|
39195
40516
|
const afterCount = getStateMessageCount(state);
|
|
@@ -40123,7 +41444,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
40123
41444
|
return { success: false, error: "resolveAction script not available for this provider" };
|
|
40124
41445
|
}
|
|
40125
41446
|
var fs52 = __toESM2(require("fs"));
|
|
40126
|
-
var
|
|
41447
|
+
var path12 = __toESM2(require("path"));
|
|
40127
41448
|
var os7 = __toESM2(require("os"));
|
|
40128
41449
|
var KEY_TO_VK = {
|
|
40129
41450
|
Backspace: 8,
|
|
@@ -40380,25 +41701,25 @@ ${effect.notification.body || ""}`.trim();
|
|
|
40380
41701
|
const inputPath = rawPath || ".";
|
|
40381
41702
|
const home = os7.homedir();
|
|
40382
41703
|
if (inputPath.startsWith("~")) {
|
|
40383
|
-
return
|
|
41704
|
+
return path12.resolve(path12.join(home, inputPath.slice(1)));
|
|
40384
41705
|
}
|
|
40385
41706
|
if (process.platform === "win32") {
|
|
40386
41707
|
const normalized = normalizeWindowsRequestedPath(inputPath);
|
|
40387
|
-
if (
|
|
40388
|
-
return
|
|
41708
|
+
if (path12.win32.isAbsolute(normalized)) {
|
|
41709
|
+
return path12.win32.normalize(normalized);
|
|
40389
41710
|
}
|
|
40390
|
-
return
|
|
41711
|
+
return path12.win32.resolve(normalized);
|
|
40391
41712
|
}
|
|
40392
|
-
if (
|
|
40393
|
-
return
|
|
41713
|
+
if (path12.isAbsolute(inputPath)) {
|
|
41714
|
+
return path12.normalize(inputPath);
|
|
40394
41715
|
}
|
|
40395
|
-
return
|
|
41716
|
+
return path12.resolve(inputPath);
|
|
40396
41717
|
}
|
|
40397
41718
|
function listDirectoryEntriesSafe(dirPath) {
|
|
40398
41719
|
const entries = fs52.readdirSync(dirPath, { withFileTypes: true });
|
|
40399
41720
|
const files = [];
|
|
40400
41721
|
for (const entry of entries) {
|
|
40401
|
-
const entryPath =
|
|
41722
|
+
const entryPath = path12.join(dirPath, entry.name);
|
|
40402
41723
|
try {
|
|
40403
41724
|
if (entry.isDirectory()) {
|
|
40404
41725
|
files.push({ name: entry.name, type: "directory" });
|
|
@@ -40414,11 +41735,11 @@ ${effect.notification.body || ""}`.trim();
|
|
|
40414
41735
|
files.push({ name: entry.name, type: "file", size });
|
|
40415
41736
|
continue;
|
|
40416
41737
|
}
|
|
40417
|
-
const
|
|
41738
|
+
const stat22 = fs52.statSync(entryPath);
|
|
40418
41739
|
files.push({
|
|
40419
41740
|
name: entry.name,
|
|
40420
|
-
type:
|
|
40421
|
-
size:
|
|
41741
|
+
type: stat22.isDirectory() ? "directory" : "file",
|
|
41742
|
+
size: stat22.isFile() ? stat22.size : void 0
|
|
40422
41743
|
});
|
|
40423
41744
|
} catch {
|
|
40424
41745
|
}
|
|
@@ -40452,7 +41773,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
40452
41773
|
async function handleFileWrite(h, args) {
|
|
40453
41774
|
try {
|
|
40454
41775
|
const filePath = resolveSafePath(args?.path);
|
|
40455
|
-
fs52.mkdirSync(
|
|
41776
|
+
fs52.mkdirSync(path12.dirname(filePath), { recursive: true });
|
|
40456
41777
|
fs52.writeFileSync(filePath, args?.content || "", "utf-8");
|
|
40457
41778
|
return { success: true, path: filePath };
|
|
40458
41779
|
} catch (e) {
|
|
@@ -40793,7 +42114,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
40793
42114
|
const enterCount = cliCommand.enterCount || 1;
|
|
40794
42115
|
await adapter.writeRaw(cliCommand.text + "\r");
|
|
40795
42116
|
for (let i = 1; i < enterCount; i += 1) {
|
|
40796
|
-
await new Promise((
|
|
42117
|
+
await new Promise((resolve15) => setTimeout(resolve15, 50));
|
|
40797
42118
|
await adapter.writeRaw("\r");
|
|
40798
42119
|
}
|
|
40799
42120
|
}
|
|
@@ -41283,6 +42604,12 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41283
42604
|
this._currentRoute = this.resolveRoute(args);
|
|
41284
42605
|
const startedAt = Date.now();
|
|
41285
42606
|
this.logCommandStart(cmd, args);
|
|
42607
|
+
let result;
|
|
42608
|
+
if (isGitCommandName(cmd)) {
|
|
42609
|
+
result = await handleGitCommand(cmd, args, this._ctx.gitCommandServices);
|
|
42610
|
+
this.logCommandEnd(cmd, result, startedAt);
|
|
42611
|
+
return result;
|
|
42612
|
+
}
|
|
41286
42613
|
const sessionScopedCommands = /* @__PURE__ */ new Set([
|
|
41287
42614
|
"read_chat",
|
|
41288
42615
|
"get_chat_debug_bundle",
|
|
@@ -41308,7 +42635,6 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41308
42635
|
this.logCommandEnd(cmd, result2, startedAt);
|
|
41309
42636
|
return result2;
|
|
41310
42637
|
}
|
|
41311
|
-
let result;
|
|
41312
42638
|
if (!this._currentRoute.session && !this._currentRoute.managerKey && !this._currentRoute.providerType) {
|
|
41313
42639
|
const cdpCommands = ["send_chat", "read_chat", "list_chats", "new_chat", "switch_chat", "set_mode", "change_model", "set_thought_level", "resolve_action"];
|
|
41314
42640
|
if (cdpCommands.includes(cmd)) {
|
|
@@ -41317,6 +42643,16 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41317
42643
|
return result;
|
|
41318
42644
|
}
|
|
41319
42645
|
}
|
|
42646
|
+
if (cmd === "send_chat" && this._ctx.onBeforeSendChat) {
|
|
42647
|
+
const sessionId = this._currentRoute.session?.sessionId;
|
|
42648
|
+
const workspace = sessionId ? this._ctx.instanceManager?.getInstance(sessionId)?.getState?.()?.workspace : void 0;
|
|
42649
|
+
if (workspace && sessionId) {
|
|
42650
|
+
try {
|
|
42651
|
+
this._ctx.onBeforeSendChat({ workspace, sessionId });
|
|
42652
|
+
} catch {
|
|
42653
|
+
}
|
|
42654
|
+
}
|
|
42655
|
+
}
|
|
41320
42656
|
try {
|
|
41321
42657
|
result = await this.dispatch(cmd, args);
|
|
41322
42658
|
this.logCommandEnd(cmd, result, startedAt);
|
|
@@ -41459,7 +42795,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41459
42795
|
try {
|
|
41460
42796
|
const http3 = await import("http");
|
|
41461
42797
|
const postData = JSON.stringify(body);
|
|
41462
|
-
const result = await new Promise((
|
|
42798
|
+
const result = await new Promise((resolve15, reject) => {
|
|
41463
42799
|
const req = http3.request({
|
|
41464
42800
|
hostname: "127.0.0.1",
|
|
41465
42801
|
port: 19280,
|
|
@@ -41471,9 +42807,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41471
42807
|
res.on("data", (chunk) => data += chunk);
|
|
41472
42808
|
res.on("end", () => {
|
|
41473
42809
|
try {
|
|
41474
|
-
|
|
42810
|
+
resolve15(JSON.parse(data));
|
|
41475
42811
|
} catch {
|
|
41476
|
-
|
|
42812
|
+
resolve15({ raw: data });
|
|
41477
42813
|
}
|
|
41478
42814
|
});
|
|
41479
42815
|
});
|
|
@@ -41491,15 +42827,15 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41491
42827
|
if (!providerType) return { success: false, error: "providerType required" };
|
|
41492
42828
|
try {
|
|
41493
42829
|
const http3 = await import("http");
|
|
41494
|
-
const result = await new Promise((
|
|
42830
|
+
const result = await new Promise((resolve15, reject) => {
|
|
41495
42831
|
http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
|
|
41496
42832
|
let data = "";
|
|
41497
42833
|
res.on("data", (chunk) => data += chunk);
|
|
41498
42834
|
res.on("end", () => {
|
|
41499
42835
|
try {
|
|
41500
|
-
|
|
42836
|
+
resolve15(JSON.parse(data));
|
|
41501
42837
|
} catch {
|
|
41502
|
-
|
|
42838
|
+
resolve15({ raw: data });
|
|
41503
42839
|
}
|
|
41504
42840
|
});
|
|
41505
42841
|
}).on("error", reject);
|
|
@@ -41513,7 +42849,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41513
42849
|
try {
|
|
41514
42850
|
const http3 = await import("http");
|
|
41515
42851
|
const postData = JSON.stringify(args || {});
|
|
41516
|
-
const result = await new Promise((
|
|
42852
|
+
const result = await new Promise((resolve15, reject) => {
|
|
41517
42853
|
const req = http3.request({
|
|
41518
42854
|
hostname: "127.0.0.1",
|
|
41519
42855
|
port: 19280,
|
|
@@ -41525,9 +42861,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41525
42861
|
res.on("data", (chunk) => data += chunk);
|
|
41526
42862
|
res.on("end", () => {
|
|
41527
42863
|
try {
|
|
41528
|
-
|
|
42864
|
+
resolve15(JSON.parse(data));
|
|
41529
42865
|
} catch {
|
|
41530
|
-
|
|
42866
|
+
resolve15({ raw: data });
|
|
41531
42867
|
}
|
|
41532
42868
|
});
|
|
41533
42869
|
});
|
|
@@ -41542,7 +42878,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41542
42878
|
}
|
|
41543
42879
|
};
|
|
41544
42880
|
var os13 = __toESM2(require("os"));
|
|
41545
|
-
var
|
|
42881
|
+
var path16 = __toESM2(require("path"));
|
|
41546
42882
|
var crypto4 = __toESM2(require("crypto"));
|
|
41547
42883
|
var import_fs5 = require("fs");
|
|
41548
42884
|
var import_child_process6 = require("child_process");
|
|
@@ -41550,7 +42886,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41550
42886
|
init_provider_cli_adapter();
|
|
41551
42887
|
init_config();
|
|
41552
42888
|
var os12 = __toESM2(require("os"));
|
|
41553
|
-
var
|
|
42889
|
+
var path15 = __toESM2(require("path"));
|
|
41554
42890
|
var crypto3 = __toESM2(require("crypto"));
|
|
41555
42891
|
var fs6 = __toESM2(require("fs"));
|
|
41556
42892
|
var import_node_module = require("module");
|
|
@@ -41607,7 +42943,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41607
42943
|
var CachedDatabaseSync = null;
|
|
41608
42944
|
function getDatabaseSync() {
|
|
41609
42945
|
if (CachedDatabaseSync) return CachedDatabaseSync;
|
|
41610
|
-
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(
|
|
42946
|
+
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(path15.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
|
|
41611
42947
|
const sqliteModule = requireFn(`node:${"sqlite"}`);
|
|
41612
42948
|
CachedDatabaseSync = sqliteModule.DatabaseSync;
|
|
41613
42949
|
if (!CachedDatabaseSync) {
|
|
@@ -41645,7 +42981,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41645
42981
|
if (status === "stopped") {
|
|
41646
42982
|
throw new Error("CLI runtime stopped before it became ready");
|
|
41647
42983
|
}
|
|
41648
|
-
await new Promise((
|
|
42984
|
+
await new Promise((resolve15) => setTimeout(resolve15, pollMs));
|
|
41649
42985
|
}
|
|
41650
42986
|
throw new Error(`CLI runtime did not become ready within ${timeoutMs}ms`);
|
|
41651
42987
|
}
|
|
@@ -41996,7 +43332,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41996
43332
|
const enterCount = cliCommand.enterCount || 1;
|
|
41997
43333
|
await this.adapter.writeRaw(cliCommand.text + "\r");
|
|
41998
43334
|
for (let i = 1; i < enterCount; i += 1) {
|
|
41999
|
-
await new Promise((
|
|
43335
|
+
await new Promise((resolve15) => setTimeout(resolve15, 50));
|
|
42000
43336
|
await this.adapter.writeRaw("\r");
|
|
42001
43337
|
}
|
|
42002
43338
|
}
|
|
@@ -43108,13 +44444,13 @@ ${effect.notification.body || ""}`.trim();
|
|
|
43108
44444
|
}
|
|
43109
44445
|
this.currentStatus = "waiting_approval";
|
|
43110
44446
|
this.detectStatusTransition();
|
|
43111
|
-
const approved = await new Promise((
|
|
43112
|
-
this.permissionResolvers.push(
|
|
44447
|
+
const approved = await new Promise((resolve15) => {
|
|
44448
|
+
this.permissionResolvers.push(resolve15);
|
|
43113
44449
|
setTimeout(() => {
|
|
43114
|
-
const idx = this.permissionResolvers.indexOf(
|
|
44450
|
+
const idx = this.permissionResolvers.indexOf(resolve15);
|
|
43115
44451
|
if (idx >= 0) {
|
|
43116
44452
|
this.permissionResolvers.splice(idx, 1);
|
|
43117
|
-
|
|
44453
|
+
resolve15(false);
|
|
43118
44454
|
}
|
|
43119
44455
|
}, 3e5);
|
|
43120
44456
|
});
|
|
@@ -43683,11 +45019,11 @@ ${rawInput}` : rawInput;
|
|
|
43683
45019
|
}
|
|
43684
45020
|
function isExplicitCommand(command) {
|
|
43685
45021
|
const trimmed = command.trim();
|
|
43686
|
-
return
|
|
45022
|
+
return path16.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
43687
45023
|
}
|
|
43688
45024
|
function expandExecutable(command) {
|
|
43689
45025
|
const trimmed = command.trim();
|
|
43690
|
-
return trimmed.startsWith("~") ?
|
|
45026
|
+
return trimmed.startsWith("~") ? path16.join(os13.homedir(), trimmed.slice(1)) : trimmed;
|
|
43691
45027
|
}
|
|
43692
45028
|
function commandExists(command) {
|
|
43693
45029
|
const trimmed = command.trim();
|
|
@@ -43968,7 +45304,7 @@ ${rawInput}` : rawInput;
|
|
|
43968
45304
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
43969
45305
|
const trimmed = (workingDir || "").trim();
|
|
43970
45306
|
if (!trimmed) throw new Error("working directory required");
|
|
43971
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) :
|
|
45307
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path16.resolve(trimmed);
|
|
43972
45308
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
43973
45309
|
const rawProvider = this.providerLoader.getByAlias(cliType);
|
|
43974
45310
|
const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
|
|
@@ -44467,9 +45803,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44467
45803
|
var import_child_process7 = require("child_process");
|
|
44468
45804
|
var net3 = __toESM2(require("net"));
|
|
44469
45805
|
var os15 = __toESM2(require("os"));
|
|
44470
|
-
var
|
|
45806
|
+
var path18 = __toESM2(require("path"));
|
|
44471
45807
|
var fs7 = __toESM2(require("fs"));
|
|
44472
|
-
var
|
|
45808
|
+
var path17 = __toESM2(require("path"));
|
|
44473
45809
|
var os14 = __toESM2(require("os"));
|
|
44474
45810
|
var chokidar = __toESM2((init_chokidar(), __toCommonJS(chokidar_exports)));
|
|
44475
45811
|
init_logger();
|
|
@@ -44530,6 +45866,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44530
45866
|
"sendDelayMs",
|
|
44531
45867
|
"sendKey",
|
|
44532
45868
|
"submitStrategy",
|
|
45869
|
+
"requirePromptEchoBeforeSubmit",
|
|
44533
45870
|
"timeouts",
|
|
44534
45871
|
"disableUpstream"
|
|
44535
45872
|
]);
|
|
@@ -44730,7 +46067,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44730
46067
|
try {
|
|
44731
46068
|
if (!fs7.existsSync(candidate) || !fs7.statSync(candidate).isDirectory()) return false;
|
|
44732
46069
|
return ["ide", "extension", "cli", "acp"].some(
|
|
44733
|
-
(category) => fs7.existsSync(
|
|
46070
|
+
(category) => fs7.existsSync(path17.join(candidate, category))
|
|
44734
46071
|
);
|
|
44735
46072
|
} catch {
|
|
44736
46073
|
return false;
|
|
@@ -44738,20 +46075,20 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44738
46075
|
}
|
|
44739
46076
|
static hasProviderRootMarker(candidate) {
|
|
44740
46077
|
try {
|
|
44741
|
-
return fs7.existsSync(
|
|
46078
|
+
return fs7.existsSync(path17.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
|
|
44742
46079
|
} catch {
|
|
44743
46080
|
return false;
|
|
44744
46081
|
}
|
|
44745
46082
|
}
|
|
44746
46083
|
detectDefaultUserDir() {
|
|
44747
|
-
const fallback =
|
|
46084
|
+
const fallback = path17.join(os14.homedir(), ".adhdev", "providers");
|
|
44748
46085
|
const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
|
|
44749
46086
|
const visited = /* @__PURE__ */ new Set();
|
|
44750
46087
|
for (const start of this.probeStarts) {
|
|
44751
|
-
let current =
|
|
46088
|
+
let current = path17.resolve(start);
|
|
44752
46089
|
while (!visited.has(current)) {
|
|
44753
46090
|
visited.add(current);
|
|
44754
|
-
const siblingCandidate =
|
|
46091
|
+
const siblingCandidate = path17.join(path17.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
|
|
44755
46092
|
if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
|
|
44756
46093
|
const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
|
|
44757
46094
|
if (envOptIn || hasMarker) {
|
|
@@ -44773,7 +46110,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44773
46110
|
return { path: siblingCandidate, source };
|
|
44774
46111
|
}
|
|
44775
46112
|
}
|
|
44776
|
-
const parent =
|
|
46113
|
+
const parent = path17.dirname(current);
|
|
44777
46114
|
if (parent === current) break;
|
|
44778
46115
|
current = parent;
|
|
44779
46116
|
}
|
|
@@ -44783,11 +46120,11 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44783
46120
|
constructor(options) {
|
|
44784
46121
|
this.logFn = options?.logFn || LOG2.forComponent("Provider").asLogFn();
|
|
44785
46122
|
this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
|
|
44786
|
-
this.defaultProvidersDir =
|
|
46123
|
+
this.defaultProvidersDir = path17.join(os14.homedir(), ".adhdev", "providers");
|
|
44787
46124
|
const detected = this.detectDefaultUserDir();
|
|
44788
46125
|
this.userDir = detected.path;
|
|
44789
46126
|
this.userDirSource = detected.source;
|
|
44790
|
-
this.upstreamDir =
|
|
46127
|
+
this.upstreamDir = path17.join(this.defaultProvidersDir, ".upstream");
|
|
44791
46128
|
this.disableUpstream = false;
|
|
44792
46129
|
this.applySourceConfig({
|
|
44793
46130
|
userDir: options?.userDir,
|
|
@@ -44846,7 +46183,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44846
46183
|
this.userDir = detected.path;
|
|
44847
46184
|
this.userDirSource = detected.source;
|
|
44848
46185
|
}
|
|
44849
|
-
this.upstreamDir =
|
|
46186
|
+
this.upstreamDir = path17.join(this.defaultProvidersDir, ".upstream");
|
|
44850
46187
|
this.disableUpstream = this.sourceMode === "no-upstream";
|
|
44851
46188
|
if (this.explicitProviderDir) {
|
|
44852
46189
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
@@ -44860,7 +46197,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44860
46197
|
* Canonical provider directory shape for a given root.
|
|
44861
46198
|
*/
|
|
44862
46199
|
getProviderDir(root, category, type) {
|
|
44863
|
-
return
|
|
46200
|
+
return path17.join(root, category, type);
|
|
44864
46201
|
}
|
|
44865
46202
|
/**
|
|
44866
46203
|
* Canonical user override directory for a provider.
|
|
@@ -44887,7 +46224,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44887
46224
|
resolveProviderFile(type, ...segments) {
|
|
44888
46225
|
const dir = this.findProviderDirInternal(type);
|
|
44889
46226
|
if (!dir) return null;
|
|
44890
|
-
return
|
|
46227
|
+
return path17.join(dir, ...segments);
|
|
44891
46228
|
}
|
|
44892
46229
|
/**
|
|
44893
46230
|
* Load all providers (3-tier priority)
|
|
@@ -44926,7 +46263,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44926
46263
|
if (!fs7.existsSync(this.upstreamDir)) return false;
|
|
44927
46264
|
try {
|
|
44928
46265
|
return fs7.readdirSync(this.upstreamDir).some(
|
|
44929
|
-
(d) => fs7.statSync(
|
|
46266
|
+
(d) => fs7.statSync(path17.join(this.upstreamDir, d)).isDirectory()
|
|
44930
46267
|
);
|
|
44931
46268
|
} catch {
|
|
44932
46269
|
return false;
|
|
@@ -45423,8 +46760,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45423
46760
|
resolved._resolvedScriptDir = entry.scriptDir;
|
|
45424
46761
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
45425
46762
|
if (providerDir) {
|
|
45426
|
-
const fullDir =
|
|
45427
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
46763
|
+
const fullDir = path17.join(providerDir, entry.scriptDir);
|
|
46764
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path17.join(fullDir, "scripts.js")) ? path17.join(fullDir, "scripts.js") : fullDir;
|
|
45428
46765
|
}
|
|
45429
46766
|
matched = true;
|
|
45430
46767
|
}
|
|
@@ -45439,8 +46776,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45439
46776
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
45440
46777
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
45441
46778
|
if (providerDir) {
|
|
45442
|
-
const fullDir =
|
|
45443
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
46779
|
+
const fullDir = path17.join(providerDir, base.defaultScriptDir);
|
|
46780
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path17.join(fullDir, "scripts.js")) ? path17.join(fullDir, "scripts.js") : fullDir;
|
|
45444
46781
|
}
|
|
45445
46782
|
}
|
|
45446
46783
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -45457,8 +46794,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45457
46794
|
resolved._resolvedScriptDir = dirOverride;
|
|
45458
46795
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
45459
46796
|
if (providerDir) {
|
|
45460
|
-
const fullDir =
|
|
45461
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
46797
|
+
const fullDir = path17.join(providerDir, dirOverride);
|
|
46798
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path17.join(fullDir, "scripts.js")) ? path17.join(fullDir, "scripts.js") : fullDir;
|
|
45462
46799
|
}
|
|
45463
46800
|
}
|
|
45464
46801
|
} else if (override.scripts) {
|
|
@@ -45474,8 +46811,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45474
46811
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
45475
46812
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
45476
46813
|
if (providerDir) {
|
|
45477
|
-
const fullDir =
|
|
45478
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
46814
|
+
const fullDir = path17.join(providerDir, base.defaultScriptDir);
|
|
46815
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path17.join(fullDir, "scripts.js")) ? path17.join(fullDir, "scripts.js") : fullDir;
|
|
45479
46816
|
}
|
|
45480
46817
|
}
|
|
45481
46818
|
}
|
|
@@ -45507,14 +46844,14 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45507
46844
|
this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
|
|
45508
46845
|
return null;
|
|
45509
46846
|
}
|
|
45510
|
-
const dir =
|
|
46847
|
+
const dir = path17.join(providerDir, scriptDir);
|
|
45511
46848
|
if (!fs7.existsSync(dir)) {
|
|
45512
46849
|
this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
45513
46850
|
return null;
|
|
45514
46851
|
}
|
|
45515
46852
|
const cached2 = this.scriptsCache.get(dir);
|
|
45516
46853
|
if (cached2) return cached2;
|
|
45517
|
-
const scriptsJs =
|
|
46854
|
+
const scriptsJs = path17.join(dir, "scripts.js");
|
|
45518
46855
|
if (fs7.existsSync(scriptsJs)) {
|
|
45519
46856
|
try {
|
|
45520
46857
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -45556,7 +46893,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45556
46893
|
return;
|
|
45557
46894
|
}
|
|
45558
46895
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
45559
|
-
this.log(`File changed: ${
|
|
46896
|
+
this.log(`File changed: ${path17.basename(filePath)}, reloading...`);
|
|
45560
46897
|
this.reload();
|
|
45561
46898
|
}
|
|
45562
46899
|
};
|
|
@@ -45611,7 +46948,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45611
46948
|
}
|
|
45612
46949
|
const https = require("https");
|
|
45613
46950
|
const { execSync: execSync7 } = require("child_process");
|
|
45614
|
-
const metaPath =
|
|
46951
|
+
const metaPath = path17.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
45615
46952
|
let prevEtag = "";
|
|
45616
46953
|
let prevTimestamp = 0;
|
|
45617
46954
|
try {
|
|
@@ -45628,7 +46965,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45628
46965
|
return { updated: false };
|
|
45629
46966
|
}
|
|
45630
46967
|
try {
|
|
45631
|
-
const etag = await new Promise((
|
|
46968
|
+
const etag = await new Promise((resolve15, reject) => {
|
|
45632
46969
|
const options = {
|
|
45633
46970
|
method: "HEAD",
|
|
45634
46971
|
hostname: "github.com",
|
|
@@ -45646,7 +46983,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45646
46983
|
headers: { "User-Agent": "adhdev-launcher" },
|
|
45647
46984
|
timeout: 1e4
|
|
45648
46985
|
}, (res2) => {
|
|
45649
|
-
|
|
46986
|
+
resolve15(res2.headers.etag || res2.headers["last-modified"] || "");
|
|
45650
46987
|
});
|
|
45651
46988
|
req2.on("error", reject);
|
|
45652
46989
|
req2.on("timeout", () => {
|
|
@@ -45655,7 +46992,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45655
46992
|
});
|
|
45656
46993
|
req2.end();
|
|
45657
46994
|
} else {
|
|
45658
|
-
|
|
46995
|
+
resolve15(res.headers.etag || res.headers["last-modified"] || "");
|
|
45659
46996
|
}
|
|
45660
46997
|
});
|
|
45661
46998
|
req.on("error", reject);
|
|
@@ -45671,17 +47008,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45671
47008
|
return { updated: false };
|
|
45672
47009
|
}
|
|
45673
47010
|
this.log("Downloading latest providers from GitHub...");
|
|
45674
|
-
const tmpTar =
|
|
45675
|
-
const tmpExtract =
|
|
47011
|
+
const tmpTar = path17.join(os14.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
47012
|
+
const tmpExtract = path17.join(os14.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
45676
47013
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
45677
47014
|
fs7.mkdirSync(tmpExtract, { recursive: true });
|
|
45678
47015
|
execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
45679
47016
|
const extracted = fs7.readdirSync(tmpExtract);
|
|
45680
47017
|
const rootDir = extracted.find(
|
|
45681
|
-
(d) => fs7.statSync(
|
|
47018
|
+
(d) => fs7.statSync(path17.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
45682
47019
|
);
|
|
45683
47020
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
45684
|
-
const sourceDir =
|
|
47021
|
+
const sourceDir = path17.join(tmpExtract, rootDir);
|
|
45685
47022
|
const backupDir = this.upstreamDir + ".bak";
|
|
45686
47023
|
if (fs7.existsSync(this.upstreamDir)) {
|
|
45687
47024
|
if (fs7.existsSync(backupDir)) fs7.rmSync(backupDir, { recursive: true, force: true });
|
|
@@ -45719,7 +47056,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45719
47056
|
downloadFile(url2, destPath) {
|
|
45720
47057
|
const https = require("https");
|
|
45721
47058
|
const http3 = require("http");
|
|
45722
|
-
return new Promise((
|
|
47059
|
+
return new Promise((resolve15, reject) => {
|
|
45723
47060
|
const doRequest = (reqUrl, redirectCount = 0) => {
|
|
45724
47061
|
if (redirectCount > 5) {
|
|
45725
47062
|
reject(new Error("Too many redirects"));
|
|
@@ -45739,7 +47076,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45739
47076
|
res.pipe(ws2);
|
|
45740
47077
|
ws2.on("finish", () => {
|
|
45741
47078
|
ws2.close();
|
|
45742
|
-
|
|
47079
|
+
resolve15();
|
|
45743
47080
|
});
|
|
45744
47081
|
ws2.on("error", reject);
|
|
45745
47082
|
});
|
|
@@ -45756,8 +47093,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45756
47093
|
copyDirRecursive(src, dest) {
|
|
45757
47094
|
fs7.mkdirSync(dest, { recursive: true });
|
|
45758
47095
|
for (const entry of fs7.readdirSync(src, { withFileTypes: true })) {
|
|
45759
|
-
const srcPath =
|
|
45760
|
-
const destPath =
|
|
47096
|
+
const srcPath = path17.join(src, entry.name);
|
|
47097
|
+
const destPath = path17.join(dest, entry.name);
|
|
45761
47098
|
if (entry.isDirectory()) {
|
|
45762
47099
|
this.copyDirRecursive(srcPath, destPath);
|
|
45763
47100
|
} else {
|
|
@@ -45768,7 +47105,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45768
47105
|
/** .meta.json save */
|
|
45769
47106
|
writeMeta(metaPath, etag, timestamp) {
|
|
45770
47107
|
try {
|
|
45771
|
-
fs7.mkdirSync(
|
|
47108
|
+
fs7.mkdirSync(path17.dirname(metaPath), { recursive: true });
|
|
45772
47109
|
fs7.writeFileSync(metaPath, JSON.stringify({
|
|
45773
47110
|
etag,
|
|
45774
47111
|
timestamp,
|
|
@@ -45785,7 +47122,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45785
47122
|
const scan = (d) => {
|
|
45786
47123
|
try {
|
|
45787
47124
|
for (const entry of fs7.readdirSync(d, { withFileTypes: true })) {
|
|
45788
|
-
if (entry.isDirectory()) scan(
|
|
47125
|
+
if (entry.isDirectory()) scan(path17.join(d, entry.name));
|
|
45789
47126
|
else if (entry.name === "provider.json") count++;
|
|
45790
47127
|
}
|
|
45791
47128
|
} catch {
|
|
@@ -46013,17 +47350,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46013
47350
|
for (const root of searchRoots) {
|
|
46014
47351
|
if (!fs7.existsSync(root)) continue;
|
|
46015
47352
|
const candidate = this.getProviderDir(root, cat, type);
|
|
46016
|
-
if (fs7.existsSync(
|
|
46017
|
-
const catDir =
|
|
47353
|
+
if (fs7.existsSync(path17.join(candidate, "provider.json"))) return candidate;
|
|
47354
|
+
const catDir = path17.join(root, cat);
|
|
46018
47355
|
if (fs7.existsSync(catDir)) {
|
|
46019
47356
|
try {
|
|
46020
47357
|
for (const entry of fs7.readdirSync(catDir, { withFileTypes: true })) {
|
|
46021
47358
|
if (!entry.isDirectory()) continue;
|
|
46022
|
-
const jsonPath =
|
|
47359
|
+
const jsonPath = path17.join(catDir, entry.name, "provider.json");
|
|
46023
47360
|
if (fs7.existsSync(jsonPath)) {
|
|
46024
47361
|
try {
|
|
46025
47362
|
const data = JSON.parse(fs7.readFileSync(jsonPath, "utf-8"));
|
|
46026
|
-
if (data.type === type) return
|
|
47363
|
+
if (data.type === type) return path17.join(catDir, entry.name);
|
|
46027
47364
|
} catch {
|
|
46028
47365
|
}
|
|
46029
47366
|
}
|
|
@@ -46040,7 +47377,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46040
47377
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
46041
47378
|
*/
|
|
46042
47379
|
buildScriptWrappersFromDir(dir) {
|
|
46043
|
-
const scriptsJs =
|
|
47380
|
+
const scriptsJs = path17.join(dir, "scripts.js");
|
|
46044
47381
|
if (fs7.existsSync(scriptsJs)) {
|
|
46045
47382
|
try {
|
|
46046
47383
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -46054,7 +47391,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46054
47391
|
for (const file2 of fs7.readdirSync(dir)) {
|
|
46055
47392
|
if (!file2.endsWith(".js")) continue;
|
|
46056
47393
|
const scriptName = toCamel(file2.replace(".js", ""));
|
|
46057
|
-
const filePath =
|
|
47394
|
+
const filePath = path17.join(dir, file2);
|
|
46058
47395
|
result[scriptName] = (...args) => {
|
|
46059
47396
|
try {
|
|
46060
47397
|
let content = fs7.readFileSync(filePath, "utf-8");
|
|
@@ -46114,7 +47451,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46114
47451
|
}
|
|
46115
47452
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
46116
47453
|
if (hasJson) {
|
|
46117
|
-
const jsonPath =
|
|
47454
|
+
const jsonPath = path17.join(d, "provider.json");
|
|
46118
47455
|
try {
|
|
46119
47456
|
const raw = fs7.readFileSync(jsonPath, "utf-8");
|
|
46120
47457
|
const mod = JSON.parse(raw);
|
|
@@ -46135,7 +47472,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46135
47472
|
this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
|
|
46136
47473
|
} else {
|
|
46137
47474
|
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
46138
|
-
const scriptsPath =
|
|
47475
|
+
const scriptsPath = path17.join(d, "scripts.js");
|
|
46139
47476
|
if (!hasCompatibility && fs7.existsSync(scriptsPath)) {
|
|
46140
47477
|
try {
|
|
46141
47478
|
delete require.cache[require.resolve(scriptsPath)];
|
|
@@ -46161,7 +47498,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46161
47498
|
if (!entry.isDirectory()) continue;
|
|
46162
47499
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
46163
47500
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
46164
|
-
scan(
|
|
47501
|
+
scan(path17.join(d, entry.name));
|
|
46165
47502
|
}
|
|
46166
47503
|
}
|
|
46167
47504
|
};
|
|
@@ -46196,9 +47533,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46196
47533
|
}
|
|
46197
47534
|
}
|
|
46198
47535
|
compareVersions(a, b2) {
|
|
46199
|
-
const
|
|
46200
|
-
const pa2 =
|
|
46201
|
-
const pb =
|
|
47536
|
+
const normalize4 = (v2) => v2.split(/[-_+]/)[0].split(".").map((x) => parseInt(x, 10) || 0);
|
|
47537
|
+
const pa2 = normalize4(a);
|
|
47538
|
+
const pb = normalize4(b2);
|
|
46202
47539
|
for (let i = 0; i < Math.max(pa2.length, pb.length); i++) {
|
|
46203
47540
|
const va2 = pa2[i] || 0;
|
|
46204
47541
|
const vb = pb[i] || 0;
|
|
@@ -46314,17 +47651,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46314
47651
|
throw new Error("No free port found");
|
|
46315
47652
|
}
|
|
46316
47653
|
function checkPortFree(port) {
|
|
46317
|
-
return new Promise((
|
|
47654
|
+
return new Promise((resolve15) => {
|
|
46318
47655
|
const server = net3.createServer();
|
|
46319
47656
|
server.unref();
|
|
46320
|
-
server.on("error", () =>
|
|
47657
|
+
server.on("error", () => resolve15(false));
|
|
46321
47658
|
server.listen(port, "127.0.0.1", () => {
|
|
46322
|
-
server.close(() =>
|
|
47659
|
+
server.close(() => resolve15(true));
|
|
46323
47660
|
});
|
|
46324
47661
|
});
|
|
46325
47662
|
}
|
|
46326
47663
|
async function isCdpActive(port) {
|
|
46327
|
-
return new Promise((
|
|
47664
|
+
return new Promise((resolve15) => {
|
|
46328
47665
|
const req = require("http").get(`http://127.0.0.1:${port}/json/version`, {
|
|
46329
47666
|
timeout: 2e3
|
|
46330
47667
|
}, (res) => {
|
|
@@ -46333,16 +47670,16 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46333
47670
|
res.on("end", () => {
|
|
46334
47671
|
try {
|
|
46335
47672
|
const info = JSON.parse(data);
|
|
46336
|
-
|
|
47673
|
+
resolve15(!!info["WebKit-Version"] || !!info["Browser"]);
|
|
46337
47674
|
} catch {
|
|
46338
|
-
|
|
47675
|
+
resolve15(false);
|
|
46339
47676
|
}
|
|
46340
47677
|
});
|
|
46341
47678
|
});
|
|
46342
|
-
req.on("error", () =>
|
|
47679
|
+
req.on("error", () => resolve15(false));
|
|
46343
47680
|
req.on("timeout", () => {
|
|
46344
47681
|
req.destroy();
|
|
46345
|
-
|
|
47682
|
+
resolve15(false);
|
|
46346
47683
|
});
|
|
46347
47684
|
});
|
|
46348
47685
|
}
|
|
@@ -46482,8 +47819,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46482
47819
|
const appNameMap = getMacAppIdentifiers();
|
|
46483
47820
|
const appName = appNameMap[ideId];
|
|
46484
47821
|
if (appName) {
|
|
46485
|
-
const storagePath =
|
|
46486
|
-
process.env.APPDATA ||
|
|
47822
|
+
const storagePath = path18.join(
|
|
47823
|
+
process.env.APPDATA || path18.join(os15.homedir(), "AppData", "Roaming"),
|
|
46487
47824
|
appName,
|
|
46488
47825
|
"storage.json"
|
|
46489
47826
|
);
|
|
@@ -46657,9 +47994,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46657
47994
|
init_config();
|
|
46658
47995
|
init_logger();
|
|
46659
47996
|
var fs8 = __toESM2(require("fs"));
|
|
46660
|
-
var
|
|
47997
|
+
var path19 = __toESM2(require("path"));
|
|
46661
47998
|
var os16 = __toESM2(require("os"));
|
|
46662
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
47999
|
+
var LOG_DIR2 = process.platform === "win32" ? path19.join(process.env.LOCALAPPDATA || process.env.APPDATA || path19.join(os16.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path19.join(os16.homedir(), "Library", "Logs", "adhdev") : path19.join(os16.homedir(), ".local", "share", "adhdev", "logs");
|
|
46663
48000
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
46664
48001
|
var MAX_DAYS = 7;
|
|
46665
48002
|
try {
|
|
@@ -46697,13 +48034,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46697
48034
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
46698
48035
|
}
|
|
46699
48036
|
var currentDate2 = getDateStr2();
|
|
46700
|
-
var currentFile =
|
|
48037
|
+
var currentFile = path19.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
46701
48038
|
var writeCount2 = 0;
|
|
46702
48039
|
function checkRotation() {
|
|
46703
48040
|
const today = getDateStr2();
|
|
46704
48041
|
if (today !== currentDate2) {
|
|
46705
48042
|
currentDate2 = today;
|
|
46706
|
-
currentFile =
|
|
48043
|
+
currentFile = path19.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
46707
48044
|
cleanOldFiles();
|
|
46708
48045
|
}
|
|
46709
48046
|
}
|
|
@@ -46717,7 +48054,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46717
48054
|
const dateMatch = file2.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
46718
48055
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
46719
48056
|
try {
|
|
46720
|
-
fs8.unlinkSync(
|
|
48057
|
+
fs8.unlinkSync(path19.join(LOG_DIR2, file2));
|
|
46721
48058
|
} catch {
|
|
46722
48059
|
}
|
|
46723
48060
|
}
|
|
@@ -46727,8 +48064,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46727
48064
|
}
|
|
46728
48065
|
function checkSize() {
|
|
46729
48066
|
try {
|
|
46730
|
-
const
|
|
46731
|
-
if (
|
|
48067
|
+
const stat22 = fs8.statSync(currentFile);
|
|
48068
|
+
if (stat22.size > MAX_FILE_SIZE) {
|
|
46732
48069
|
const backup = currentFile.replace(".jsonl", ".1.jsonl");
|
|
46733
48070
|
try {
|
|
46734
48071
|
fs8.unlinkSync(backup);
|
|
@@ -47010,12 +48347,18 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47010
48347
|
const unreadSourceSessions = buildSessionEntries(
|
|
47011
48348
|
options.allStates,
|
|
47012
48349
|
options.cdpManagers,
|
|
47013
|
-
{
|
|
48350
|
+
{
|
|
48351
|
+
profile: "full",
|
|
48352
|
+
getGitSummaryForWorkspace: options.getGitSummaryForWorkspace
|
|
48353
|
+
}
|
|
47014
48354
|
);
|
|
47015
48355
|
const sessions = profile === "full" ? unreadSourceSessions : profile === "live" ? unreadSourceSessions.map(projectLiveSessionFromFull) : buildSessionEntries(
|
|
47016
48356
|
options.allStates,
|
|
47017
48357
|
options.cdpManagers,
|
|
47018
|
-
{
|
|
48358
|
+
{
|
|
48359
|
+
profile,
|
|
48360
|
+
getGitSummaryForWorkspace: options.getGitSummaryForWorkspace
|
|
48361
|
+
}
|
|
47019
48362
|
);
|
|
47020
48363
|
const sessionsById = new Map(sessions.map((session) => [session.id, session]));
|
|
47021
48364
|
for (const sourceSession of unreadSourceSessions) {
|
|
@@ -47107,13 +48450,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47107
48450
|
var import_child_process9 = require("child_process");
|
|
47108
48451
|
var fs9 = __toESM2(require("fs"));
|
|
47109
48452
|
var os18 = __toESM2(require("os"));
|
|
47110
|
-
var
|
|
48453
|
+
var path20 = __toESM2(require("path"));
|
|
47111
48454
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
47112
48455
|
function getUpgradeLogPath() {
|
|
47113
48456
|
const home = os18.homedir();
|
|
47114
|
-
const dir =
|
|
48457
|
+
const dir = path20.join(home, ".adhdev");
|
|
47115
48458
|
fs9.mkdirSync(dir, { recursive: true });
|
|
47116
|
-
return
|
|
48459
|
+
return path20.join(dir, "daemon-upgrade.log");
|
|
47117
48460
|
}
|
|
47118
48461
|
function appendUpgradeLog(message) {
|
|
47119
48462
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
@@ -47124,14 +48467,14 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47124
48467
|
}
|
|
47125
48468
|
}
|
|
47126
48469
|
function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platform) {
|
|
47127
|
-
const binDir =
|
|
48470
|
+
const binDir = path20.dirname(nodeExecutable);
|
|
47128
48471
|
if (platform10 === "win32") {
|
|
47129
|
-
const npmCliPath =
|
|
48472
|
+
const npmCliPath = path20.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
|
|
47130
48473
|
if (fs9.existsSync(npmCliPath)) {
|
|
47131
48474
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
47132
48475
|
}
|
|
47133
48476
|
for (const candidate of ["npm.exe", "npm"]) {
|
|
47134
|
-
const candidatePath =
|
|
48477
|
+
const candidatePath = path20.join(binDir, candidate);
|
|
47135
48478
|
if (fs9.existsSync(candidatePath)) {
|
|
47136
48479
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
47137
48480
|
}
|
|
@@ -47139,7 +48482,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47139
48482
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
47140
48483
|
}
|
|
47141
48484
|
for (const candidate of ["npm"]) {
|
|
47142
|
-
const candidatePath =
|
|
48485
|
+
const candidatePath = path20.join(binDir, candidate);
|
|
47143
48486
|
if (fs9.existsSync(candidatePath)) {
|
|
47144
48487
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
47145
48488
|
}
|
|
@@ -47156,13 +48499,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47156
48499
|
let currentDir = resolvedPath;
|
|
47157
48500
|
try {
|
|
47158
48501
|
if (fs9.statSync(resolvedPath).isFile()) {
|
|
47159
|
-
currentDir =
|
|
48502
|
+
currentDir = path20.dirname(resolvedPath);
|
|
47160
48503
|
}
|
|
47161
48504
|
} catch {
|
|
47162
|
-
currentDir =
|
|
48505
|
+
currentDir = path20.dirname(resolvedPath);
|
|
47163
48506
|
}
|
|
47164
48507
|
while (true) {
|
|
47165
|
-
const packageJsonPath =
|
|
48508
|
+
const packageJsonPath = path20.join(currentDir, "package.json");
|
|
47166
48509
|
try {
|
|
47167
48510
|
if (fs9.existsSync(packageJsonPath)) {
|
|
47168
48511
|
const parsed = JSON.parse(fs9.readFileSync(packageJsonPath, "utf8"));
|
|
@@ -47173,7 +48516,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47173
48516
|
}
|
|
47174
48517
|
} catch {
|
|
47175
48518
|
}
|
|
47176
|
-
const parentDir =
|
|
48519
|
+
const parentDir = path20.dirname(currentDir);
|
|
47177
48520
|
if (parentDir === currentDir) {
|
|
47178
48521
|
return null;
|
|
47179
48522
|
}
|
|
@@ -47181,13 +48524,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47181
48524
|
}
|
|
47182
48525
|
}
|
|
47183
48526
|
function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
|
|
47184
|
-
const nodeModulesDir = packageName.startsWith("@") ?
|
|
47185
|
-
if (
|
|
48527
|
+
const nodeModulesDir = packageName.startsWith("@") ? path20.dirname(path20.dirname(packageRoot)) : path20.dirname(packageRoot);
|
|
48528
|
+
if (path20.basename(nodeModulesDir) !== "node_modules") {
|
|
47186
48529
|
return null;
|
|
47187
48530
|
}
|
|
47188
|
-
const maybeLibDir =
|
|
47189
|
-
if (
|
|
47190
|
-
return
|
|
48531
|
+
const maybeLibDir = path20.dirname(nodeModulesDir);
|
|
48532
|
+
if (path20.basename(maybeLibDir) === "lib") {
|
|
48533
|
+
return path20.dirname(maybeLibDir);
|
|
47191
48534
|
}
|
|
47192
48535
|
return maybeLibDir;
|
|
47193
48536
|
}
|
|
@@ -47295,14 +48638,14 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47295
48638
|
while (Date.now() - start < timeoutMs) {
|
|
47296
48639
|
try {
|
|
47297
48640
|
process.kill(pid, 0);
|
|
47298
|
-
await new Promise((
|
|
48641
|
+
await new Promise((resolve15) => setTimeout(resolve15, 250));
|
|
47299
48642
|
} catch {
|
|
47300
48643
|
return;
|
|
47301
48644
|
}
|
|
47302
48645
|
}
|
|
47303
48646
|
}
|
|
47304
48647
|
function stopSessionHostProcesses(appName) {
|
|
47305
|
-
const pidFile =
|
|
48648
|
+
const pidFile = path20.join(os18.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
47306
48649
|
try {
|
|
47307
48650
|
if (fs9.existsSync(pidFile)) {
|
|
47308
48651
|
const pid = Number.parseInt(fs9.readFileSync(pidFile, "utf8").trim(), 10);
|
|
@@ -47319,7 +48662,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47319
48662
|
}
|
|
47320
48663
|
}
|
|
47321
48664
|
function removeDaemonPidFile() {
|
|
47322
|
-
const pidFile =
|
|
48665
|
+
const pidFile = path20.join(os18.homedir(), ".adhdev", "daemon.pid");
|
|
47323
48666
|
try {
|
|
47324
48667
|
fs9.unlinkSync(pidFile);
|
|
47325
48668
|
} catch {
|
|
@@ -47330,7 +48673,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47330
48673
|
const npmRoot = String(execNpmCommandSync(["root", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
47331
48674
|
if (!npmRoot) return;
|
|
47332
48675
|
const npmPrefix = surface.installPrefix || String(execNpmCommandSync(["prefix", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
47333
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
48676
|
+
const binDir = process.platform === "win32" ? npmPrefix : path20.join(npmPrefix, "bin");
|
|
47334
48677
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
47335
48678
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
47336
48679
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -47338,25 +48681,25 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47338
48681
|
}
|
|
47339
48682
|
if (pkgName.startsWith("@")) {
|
|
47340
48683
|
const [scope, name] = pkgName.split("/");
|
|
47341
|
-
const scopeDir =
|
|
48684
|
+
const scopeDir = path20.join(npmRoot, scope);
|
|
47342
48685
|
if (!fs9.existsSync(scopeDir)) return;
|
|
47343
48686
|
for (const entry of fs9.readdirSync(scopeDir)) {
|
|
47344
48687
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
47345
|
-
fs9.rmSync(
|
|
47346
|
-
appendUpgradeLog(`Removed stale scoped staging dir: ${
|
|
48688
|
+
fs9.rmSync(path20.join(scopeDir, entry), { recursive: true, force: true });
|
|
48689
|
+
appendUpgradeLog(`Removed stale scoped staging dir: ${path20.join(scopeDir, entry)}`);
|
|
47347
48690
|
}
|
|
47348
48691
|
} else {
|
|
47349
48692
|
for (const entry of fs9.readdirSync(npmRoot)) {
|
|
47350
48693
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
47351
|
-
fs9.rmSync(
|
|
47352
|
-
appendUpgradeLog(`Removed stale staging dir: ${
|
|
48694
|
+
fs9.rmSync(path20.join(npmRoot, entry), { recursive: true, force: true });
|
|
48695
|
+
appendUpgradeLog(`Removed stale staging dir: ${path20.join(npmRoot, entry)}`);
|
|
47353
48696
|
}
|
|
47354
48697
|
}
|
|
47355
48698
|
if (fs9.existsSync(binDir)) {
|
|
47356
48699
|
for (const entry of fs9.readdirSync(binDir)) {
|
|
47357
48700
|
if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
47358
|
-
fs9.rmSync(
|
|
47359
|
-
appendUpgradeLog(`Removed stale bin staging entry: ${
|
|
48701
|
+
fs9.rmSync(path20.join(binDir, entry), { recursive: true, force: true });
|
|
48702
|
+
appendUpgradeLog(`Removed stale bin staging entry: ${path20.join(binDir, entry)}`);
|
|
47360
48703
|
}
|
|
47361
48704
|
}
|
|
47362
48705
|
}
|
|
@@ -47406,7 +48749,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47406
48749
|
appendUpgradeLog(installOutput.trim());
|
|
47407
48750
|
}
|
|
47408
48751
|
if (process.platform === "win32") {
|
|
47409
|
-
await new Promise((
|
|
48752
|
+
await new Promise((resolve15) => setTimeout(resolve15, 500));
|
|
47410
48753
|
cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
|
|
47411
48754
|
appendUpgradeLog("Post-install staging cleanup complete");
|
|
47412
48755
|
}
|
|
@@ -48786,7 +50129,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
48786
50129
|
const beforeCount = this.messageCount(before);
|
|
48787
50130
|
const beforeSignature = this.lastMessageSignature(before);
|
|
48788
50131
|
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
48789
|
-
await new Promise((
|
|
50132
|
+
await new Promise((resolve15) => setTimeout(resolve15, 250));
|
|
48790
50133
|
let state;
|
|
48791
50134
|
try {
|
|
48792
50135
|
state = await this.readChat(evaluate);
|
|
@@ -48808,7 +50151,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
48808
50151
|
if (this.messageCount(first) > 0 || this.lastMessageSignature(first)) {
|
|
48809
50152
|
return first;
|
|
48810
50153
|
}
|
|
48811
|
-
await new Promise((
|
|
50154
|
+
await new Promise((resolve15) => setTimeout(resolve15, 150));
|
|
48812
50155
|
const second = await this.readChat(evaluate);
|
|
48813
50156
|
return this.messageCount(second) >= this.messageCount(first) ? second : first;
|
|
48814
50157
|
}
|
|
@@ -48959,7 +50302,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
48959
50302
|
if (typeof data.error === "string" && data.error.trim()) return false;
|
|
48960
50303
|
}
|
|
48961
50304
|
for (let attempt = 0; attempt < 6; attempt += 1) {
|
|
48962
|
-
await new Promise((
|
|
50305
|
+
await new Promise((resolve15) => setTimeout(resolve15, 250));
|
|
48963
50306
|
const state = await this.readChat(evaluate);
|
|
48964
50307
|
const title = this.getStateTitle(state);
|
|
48965
50308
|
if (this.titlesMatch(title, sessionId)) return true;
|
|
@@ -49808,11 +51151,11 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
49808
51151
|
init_io_contracts();
|
|
49809
51152
|
init_chat_message_normalization();
|
|
49810
51153
|
var fs11 = __toESM2(require("fs"));
|
|
49811
|
-
var
|
|
51154
|
+
var path21 = __toESM2(require("path"));
|
|
49812
51155
|
var os19 = __toESM2(require("os"));
|
|
49813
51156
|
var import_child_process10 = require("child_process");
|
|
49814
51157
|
var import_os3 = require("os");
|
|
49815
|
-
var ARCHIVE_PATH =
|
|
51158
|
+
var ARCHIVE_PATH = path21.join(os19.homedir(), ".adhdev", "version-history.json");
|
|
49816
51159
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
49817
51160
|
var VersionArchive = class {
|
|
49818
51161
|
history = {};
|
|
@@ -49859,7 +51202,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
49859
51202
|
}
|
|
49860
51203
|
save() {
|
|
49861
51204
|
try {
|
|
49862
|
-
fs11.mkdirSync(
|
|
51205
|
+
fs11.mkdirSync(path21.dirname(ARCHIVE_PATH), { recursive: true });
|
|
49863
51206
|
fs11.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
49864
51207
|
} catch {
|
|
49865
51208
|
}
|
|
@@ -49916,7 +51259,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
49916
51259
|
for (const p of paths) {
|
|
49917
51260
|
if (p.includes("*")) {
|
|
49918
51261
|
const home = os19.homedir();
|
|
49919
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
51262
|
+
const resolved = p.replace(/\*/g, home.split(path21.sep).pop() || "");
|
|
49920
51263
|
if (fs11.existsSync(resolved)) return resolved;
|
|
49921
51264
|
} else {
|
|
49922
51265
|
if (fs11.existsSync(p)) return p;
|
|
@@ -49926,7 +51269,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
49926
51269
|
}
|
|
49927
51270
|
function getMacAppVersion(appPath) {
|
|
49928
51271
|
if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
49929
|
-
const plistPath =
|
|
51272
|
+
const plistPath = path21.join(appPath, "Contents", "Info.plist");
|
|
49930
51273
|
if (!fs11.existsSync(plistPath)) return null;
|
|
49931
51274
|
const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
49932
51275
|
return raw || null;
|
|
@@ -49952,7 +51295,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
49952
51295
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
49953
51296
|
let resolvedBin = cliBin;
|
|
49954
51297
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
49955
|
-
const bundled =
|
|
51298
|
+
const bundled = path21.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
49956
51299
|
if (provider.cli && fs11.existsSync(bundled)) resolvedBin = bundled;
|
|
49957
51300
|
}
|
|
49958
51301
|
info.installed = !!(appPath || resolvedBin);
|
|
@@ -49991,7 +51334,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
49991
51334
|
}
|
|
49992
51335
|
var http2 = __toESM2(require("http"));
|
|
49993
51336
|
var fs15 = __toESM2(require("fs"));
|
|
49994
|
-
var
|
|
51337
|
+
var path25 = __toESM2(require("path"));
|
|
49995
51338
|
init_config();
|
|
49996
51339
|
function generateFiles(type, name, category, opts = {}) {
|
|
49997
51340
|
const { cdpPorts, cli, processName, installPath, binary, extensionId, version: version2 = "0.1" } = opts;
|
|
@@ -50336,7 +51679,7 @@ async (params) => {
|
|
|
50336
51679
|
}
|
|
50337
51680
|
init_logger();
|
|
50338
51681
|
var fs12 = __toESM2(require("fs"));
|
|
50339
|
-
var
|
|
51682
|
+
var path222 = __toESM2(require("path"));
|
|
50340
51683
|
init_logger();
|
|
50341
51684
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
50342
51685
|
const body = await ctx.readBody(req);
|
|
@@ -50515,17 +51858,17 @@ async (params) => {
|
|
|
50515
51858
|
return;
|
|
50516
51859
|
}
|
|
50517
51860
|
let scriptsPath = "";
|
|
50518
|
-
const directScripts =
|
|
51861
|
+
const directScripts = path222.join(dir, "scripts.js");
|
|
50519
51862
|
if (fs12.existsSync(directScripts)) {
|
|
50520
51863
|
scriptsPath = directScripts;
|
|
50521
51864
|
} else {
|
|
50522
|
-
const scriptsDir =
|
|
51865
|
+
const scriptsDir = path222.join(dir, "scripts");
|
|
50523
51866
|
if (fs12.existsSync(scriptsDir)) {
|
|
50524
51867
|
const versions = fs12.readdirSync(scriptsDir).filter((d) => {
|
|
50525
|
-
return fs12.statSync(
|
|
51868
|
+
return fs12.statSync(path222.join(scriptsDir, d)).isDirectory();
|
|
50526
51869
|
}).sort().reverse();
|
|
50527
51870
|
for (const ver of versions) {
|
|
50528
|
-
const p =
|
|
51871
|
+
const p = path222.join(scriptsDir, ver, "scripts.js");
|
|
50529
51872
|
if (fs12.existsSync(p)) {
|
|
50530
51873
|
scriptsPath = p;
|
|
50531
51874
|
break;
|
|
@@ -51352,7 +52695,7 @@ async (params) => {
|
|
|
51352
52695
|
}
|
|
51353
52696
|
}
|
|
51354
52697
|
var fs13 = __toESM2(require("fs"));
|
|
51355
|
-
var
|
|
52698
|
+
var path232 = __toESM2(require("path"));
|
|
51356
52699
|
function slugifyFixtureName(value) {
|
|
51357
52700
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
51358
52701
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -51362,11 +52705,11 @@ async (params) => {
|
|
|
51362
52705
|
if (!providerDir) {
|
|
51363
52706
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
51364
52707
|
}
|
|
51365
|
-
return
|
|
52708
|
+
return path232.join(providerDir, "fixtures");
|
|
51366
52709
|
}
|
|
51367
52710
|
function readCliFixture(ctx, type, name) {
|
|
51368
52711
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
51369
|
-
const filePath =
|
|
52712
|
+
const filePath = path232.join(fixtureDir, `${name}.json`);
|
|
51370
52713
|
if (!fs13.existsSync(filePath)) {
|
|
51371
52714
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
51372
52715
|
}
|
|
@@ -51535,7 +52878,7 @@ async (params) => {
|
|
|
51535
52878
|
return { target, instance, adapter };
|
|
51536
52879
|
}
|
|
51537
52880
|
function sleep(ms2) {
|
|
51538
|
-
return new Promise((
|
|
52881
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms2));
|
|
51539
52882
|
}
|
|
51540
52883
|
async function waitForCliReady(ctx, type, instanceId, timeoutMs) {
|
|
51541
52884
|
const startedAt = Date.now();
|
|
@@ -51833,7 +53176,7 @@ async (params) => {
|
|
|
51833
53176
|
return {
|
|
51834
53177
|
mode: "fixture_replay_suite",
|
|
51835
53178
|
pass: results.every((item) => item.pass),
|
|
51836
|
-
failures: results.flatMap((item) => item.failures.map((
|
|
53179
|
+
failures: results.flatMap((item) => item.failures.map((failure2) => `${item.fixtureName}: ${failure2}`)),
|
|
51837
53180
|
result: firstFailure.result,
|
|
51838
53181
|
assertions: firstFailure.assertions,
|
|
51839
53182
|
fixture: firstFailure.fixture,
|
|
@@ -52133,7 +53476,7 @@ async (params) => {
|
|
|
52133
53476
|
},
|
|
52134
53477
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
52135
53478
|
};
|
|
52136
|
-
const filePath =
|
|
53479
|
+
const filePath = path232.join(fixtureDir, `${name}.json`);
|
|
52137
53480
|
fs13.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
52138
53481
|
ctx.json(res, 200, {
|
|
52139
53482
|
saved: true,
|
|
@@ -52157,7 +53500,7 @@ async (params) => {
|
|
|
52157
53500
|
return;
|
|
52158
53501
|
}
|
|
52159
53502
|
const fixtures = fs13.readdirSync(fixtureDir).filter((file2) => file2.endsWith(".json")).sort((a, b2) => b2.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file2) => {
|
|
52160
|
-
const fullPath =
|
|
53503
|
+
const fullPath = path232.join(fixtureDir, file2);
|
|
52161
53504
|
try {
|
|
52162
53505
|
const raw = JSON.parse(fs13.readFileSync(fullPath, "utf-8"));
|
|
52163
53506
|
return {
|
|
@@ -52291,7 +53634,7 @@ async (params) => {
|
|
|
52291
53634
|
}
|
|
52292
53635
|
}
|
|
52293
53636
|
var fs14 = __toESM2(require("fs"));
|
|
52294
|
-
var
|
|
53637
|
+
var path24 = __toESM2(require("path"));
|
|
52295
53638
|
var os20 = __toESM2(require("os"));
|
|
52296
53639
|
function getAutoImplPid(ctx) {
|
|
52297
53640
|
const pid = ctx.autoImplProcess?.pid;
|
|
@@ -52341,22 +53684,22 @@ async (params) => {
|
|
|
52341
53684
|
if (!fs14.existsSync(scriptsDir)) return null;
|
|
52342
53685
|
const versions = fs14.readdirSync(scriptsDir).filter((d) => {
|
|
52343
53686
|
try {
|
|
52344
|
-
return fs14.statSync(
|
|
53687
|
+
return fs14.statSync(path24.join(scriptsDir, d)).isDirectory();
|
|
52345
53688
|
} catch {
|
|
52346
53689
|
return false;
|
|
52347
53690
|
}
|
|
52348
53691
|
}).sort((a, b2) => b2.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
52349
53692
|
if (versions.length === 0) return null;
|
|
52350
|
-
return
|
|
53693
|
+
return path24.join(scriptsDir, versions[0]);
|
|
52351
53694
|
}
|
|
52352
53695
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
52353
|
-
const canonicalUserDir =
|
|
52354
|
-
const desiredDir = requestedDir ?
|
|
52355
|
-
const upstreamRoot =
|
|
52356
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
53696
|
+
const canonicalUserDir = path24.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
53697
|
+
const desiredDir = requestedDir ? path24.resolve(requestedDir) : canonicalUserDir;
|
|
53698
|
+
const upstreamRoot = path24.resolve(ctx.providerLoader.getUpstreamDir());
|
|
53699
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path24.sep}`)) {
|
|
52357
53700
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
52358
53701
|
}
|
|
52359
|
-
if (
|
|
53702
|
+
if (path24.basename(desiredDir) !== type) {
|
|
52360
53703
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
52361
53704
|
}
|
|
52362
53705
|
const sourceDir = ctx.findProviderDir(type);
|
|
@@ -52364,11 +53707,11 @@ async (params) => {
|
|
|
52364
53707
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
52365
53708
|
}
|
|
52366
53709
|
if (!fs14.existsSync(desiredDir)) {
|
|
52367
|
-
fs14.mkdirSync(
|
|
53710
|
+
fs14.mkdirSync(path24.dirname(desiredDir), { recursive: true });
|
|
52368
53711
|
fs14.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
52369
53712
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
52370
53713
|
}
|
|
52371
|
-
const providerJson =
|
|
53714
|
+
const providerJson = path24.join(desiredDir, "provider.json");
|
|
52372
53715
|
if (!fs14.existsSync(providerJson)) {
|
|
52373
53716
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
52374
53717
|
}
|
|
@@ -52379,13 +53722,13 @@ async (params) => {
|
|
|
52379
53722
|
const refDir = ctx.findProviderDir(referenceType);
|
|
52380
53723
|
if (!refDir || !fs14.existsSync(refDir)) return {};
|
|
52381
53724
|
const referenceScripts = {};
|
|
52382
|
-
const scriptsDir =
|
|
53725
|
+
const scriptsDir = path24.join(refDir, "scripts");
|
|
52383
53726
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
52384
53727
|
if (!latestDir) return referenceScripts;
|
|
52385
53728
|
for (const file2 of fs14.readdirSync(latestDir)) {
|
|
52386
53729
|
if (!file2.endsWith(".js")) continue;
|
|
52387
53730
|
try {
|
|
52388
|
-
referenceScripts[file2] = fs14.readFileSync(
|
|
53731
|
+
referenceScripts[file2] = fs14.readFileSync(path24.join(latestDir, file2), "utf-8");
|
|
52389
53732
|
} catch {
|
|
52390
53733
|
}
|
|
52391
53734
|
}
|
|
@@ -52493,9 +53836,9 @@ async (params) => {
|
|
|
52493
53836
|
});
|
|
52494
53837
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
52495
53838
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
52496
|
-
const tmpDir =
|
|
53839
|
+
const tmpDir = path24.join(os20.tmpdir(), "adhdev-autoimpl");
|
|
52497
53840
|
if (!fs14.existsSync(tmpDir)) fs14.mkdirSync(tmpDir, { recursive: true });
|
|
52498
|
-
const promptFile =
|
|
53841
|
+
const promptFile = path24.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
52499
53842
|
fs14.writeFileSync(promptFile, prompt, "utf-8");
|
|
52500
53843
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
52501
53844
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
@@ -52927,7 +54270,7 @@ async (params) => {
|
|
|
52927
54270
|
setMode: "set_mode.js"
|
|
52928
54271
|
};
|
|
52929
54272
|
const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
|
|
52930
|
-
const scriptsDir =
|
|
54273
|
+
const scriptsDir = path24.join(providerDir, "scripts");
|
|
52931
54274
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
52932
54275
|
if (latestScriptsDir) {
|
|
52933
54276
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -52938,7 +54281,7 @@ async (params) => {
|
|
|
52938
54281
|
for (const file2 of fs14.readdirSync(latestScriptsDir)) {
|
|
52939
54282
|
if (file2.endsWith(".js") && targetFileNames.has(file2)) {
|
|
52940
54283
|
try {
|
|
52941
|
-
const content = fs14.readFileSync(
|
|
54284
|
+
const content = fs14.readFileSync(path24.join(latestScriptsDir, file2), "utf-8");
|
|
52942
54285
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
52943
54286
|
lines.push("```javascript");
|
|
52944
54287
|
lines.push(content);
|
|
@@ -52955,7 +54298,7 @@ async (params) => {
|
|
|
52955
54298
|
lines.push("");
|
|
52956
54299
|
for (const file2 of refFiles) {
|
|
52957
54300
|
try {
|
|
52958
|
-
const content = fs14.readFileSync(
|
|
54301
|
+
const content = fs14.readFileSync(path24.join(latestScriptsDir, file2), "utf-8");
|
|
52959
54302
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
52960
54303
|
lines.push("```javascript");
|
|
52961
54304
|
lines.push(content);
|
|
@@ -52996,10 +54339,10 @@ async (params) => {
|
|
|
52996
54339
|
lines.push("");
|
|
52997
54340
|
}
|
|
52998
54341
|
}
|
|
52999
|
-
const docsDir =
|
|
54342
|
+
const docsDir = path24.join(providerDir, "../../docs");
|
|
53000
54343
|
const loadGuide = (name) => {
|
|
53001
54344
|
try {
|
|
53002
|
-
const p =
|
|
54345
|
+
const p = path24.join(docsDir, name);
|
|
53003
54346
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
53004
54347
|
} catch {
|
|
53005
54348
|
}
|
|
@@ -53236,7 +54579,7 @@ async (params) => {
|
|
|
53236
54579
|
parseApproval: "parse_approval.js"
|
|
53237
54580
|
};
|
|
53238
54581
|
const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
|
|
53239
|
-
const scriptsDir =
|
|
54582
|
+
const scriptsDir = path24.join(providerDir, "scripts");
|
|
53240
54583
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
53241
54584
|
if (latestScriptsDir) {
|
|
53242
54585
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -53248,7 +54591,7 @@ async (params) => {
|
|
|
53248
54591
|
if (!file2.endsWith(".js")) continue;
|
|
53249
54592
|
if (!targetFileNames.has(file2)) continue;
|
|
53250
54593
|
try {
|
|
53251
|
-
const content = fs14.readFileSync(
|
|
54594
|
+
const content = fs14.readFileSync(path24.join(latestScriptsDir, file2), "utf-8");
|
|
53252
54595
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
53253
54596
|
lines.push("```javascript");
|
|
53254
54597
|
lines.push(content);
|
|
@@ -53264,7 +54607,7 @@ async (params) => {
|
|
|
53264
54607
|
lines.push("");
|
|
53265
54608
|
for (const file2 of refFiles) {
|
|
53266
54609
|
try {
|
|
53267
|
-
const content = fs14.readFileSync(
|
|
54610
|
+
const content = fs14.readFileSync(path24.join(latestScriptsDir, file2), "utf-8");
|
|
53268
54611
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
53269
54612
|
lines.push("```javascript");
|
|
53270
54613
|
lines.push(content);
|
|
@@ -53297,10 +54640,10 @@ async (params) => {
|
|
|
53297
54640
|
lines.push("");
|
|
53298
54641
|
}
|
|
53299
54642
|
}
|
|
53300
|
-
const docsDir =
|
|
54643
|
+
const docsDir = path24.join(providerDir, "../../docs");
|
|
53301
54644
|
const loadGuide = (name) => {
|
|
53302
54645
|
try {
|
|
53303
|
-
const p =
|
|
54646
|
+
const p = path24.join(docsDir, name);
|
|
53304
54647
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
53305
54648
|
} catch {
|
|
53306
54649
|
}
|
|
@@ -53745,8 +55088,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
53745
55088
|
}
|
|
53746
55089
|
getEndpointList() {
|
|
53747
55090
|
return this.routes.map((r) => {
|
|
53748
|
-
const
|
|
53749
|
-
return `${r.method.padEnd(5)} ${
|
|
55091
|
+
const path26 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
55092
|
+
return `${r.method.padEnd(5)} ${path26}`;
|
|
53750
55093
|
});
|
|
53751
55094
|
}
|
|
53752
55095
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -53777,15 +55120,15 @@ data: ${JSON.stringify(msg.data)}
|
|
|
53777
55120
|
this.json(res, 500, { error: e.message });
|
|
53778
55121
|
}
|
|
53779
55122
|
});
|
|
53780
|
-
return new Promise((
|
|
55123
|
+
return new Promise((resolve15, reject) => {
|
|
53781
55124
|
this.server.listen(port, "127.0.0.1", () => {
|
|
53782
55125
|
this.log(`Dev server listening on http://127.0.0.1:${port}`);
|
|
53783
|
-
|
|
55126
|
+
resolve15();
|
|
53784
55127
|
});
|
|
53785
55128
|
this.server.on("error", (e) => {
|
|
53786
55129
|
if (e.code === "EADDRINUSE") {
|
|
53787
55130
|
this.log(`Port ${port} in use, skipping dev server`);
|
|
53788
|
-
|
|
55131
|
+
resolve15();
|
|
53789
55132
|
} else {
|
|
53790
55133
|
reject(e);
|
|
53791
55134
|
}
|
|
@@ -53867,20 +55210,20 @@ data: ${JSON.stringify(msg.data)}
|
|
|
53867
55210
|
child.stderr?.on("data", (d) => {
|
|
53868
55211
|
stderr += d.toString().slice(0, 2e3);
|
|
53869
55212
|
});
|
|
53870
|
-
await new Promise((
|
|
55213
|
+
await new Promise((resolve15) => {
|
|
53871
55214
|
const timer = setTimeout(() => {
|
|
53872
55215
|
child.kill();
|
|
53873
|
-
|
|
55216
|
+
resolve15();
|
|
53874
55217
|
}, 3e3);
|
|
53875
55218
|
child.on("exit", () => {
|
|
53876
55219
|
clearTimeout(timer);
|
|
53877
|
-
|
|
55220
|
+
resolve15();
|
|
53878
55221
|
});
|
|
53879
55222
|
child.stdout?.once("data", () => {
|
|
53880
55223
|
setTimeout(() => {
|
|
53881
55224
|
child.kill();
|
|
53882
55225
|
clearTimeout(timer);
|
|
53883
|
-
|
|
55226
|
+
resolve15();
|
|
53884
55227
|
}, 500);
|
|
53885
55228
|
});
|
|
53886
55229
|
});
|
|
@@ -54034,12 +55377,12 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54034
55377
|
// ─── DevConsole SPA ───
|
|
54035
55378
|
getConsoleDistDir() {
|
|
54036
55379
|
const candidates = [
|
|
54037
|
-
|
|
54038
|
-
|
|
54039
|
-
|
|
55380
|
+
path25.resolve(__dirname, "../../web-devconsole/dist"),
|
|
55381
|
+
path25.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
55382
|
+
path25.join(process.cwd(), "packages/web-devconsole/dist")
|
|
54040
55383
|
];
|
|
54041
55384
|
for (const dir of candidates) {
|
|
54042
|
-
if (fs15.existsSync(
|
|
55385
|
+
if (fs15.existsSync(path25.join(dir, "index.html"))) return dir;
|
|
54043
55386
|
}
|
|
54044
55387
|
return null;
|
|
54045
55388
|
}
|
|
@@ -54049,7 +55392,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54049
55392
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
54050
55393
|
return;
|
|
54051
55394
|
}
|
|
54052
|
-
const htmlPath =
|
|
55395
|
+
const htmlPath = path25.join(distDir, "index.html");
|
|
54053
55396
|
try {
|
|
54054
55397
|
const html = fs15.readFileSync(htmlPath, "utf-8");
|
|
54055
55398
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
@@ -54074,15 +55417,15 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54074
55417
|
this.json(res, 404, { error: "Not found" });
|
|
54075
55418
|
return;
|
|
54076
55419
|
}
|
|
54077
|
-
const safePath =
|
|
54078
|
-
const filePath =
|
|
55420
|
+
const safePath = path25.normalize(pathname).replace(/^\.\.\//, "");
|
|
55421
|
+
const filePath = path25.join(distDir, safePath);
|
|
54079
55422
|
if (!filePath.startsWith(distDir)) {
|
|
54080
55423
|
this.json(res, 403, { error: "Forbidden" });
|
|
54081
55424
|
return;
|
|
54082
55425
|
}
|
|
54083
55426
|
try {
|
|
54084
55427
|
const content = fs15.readFileSync(filePath);
|
|
54085
|
-
const ext =
|
|
55428
|
+
const ext = path25.extname(filePath);
|
|
54086
55429
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
54087
55430
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
54088
55431
|
res.end(content);
|
|
@@ -54195,10 +55538,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54195
55538
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
54196
55539
|
if (entry.isDirectory()) {
|
|
54197
55540
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
54198
|
-
scan(
|
|
55541
|
+
scan(path25.join(d, entry.name), rel);
|
|
54199
55542
|
} else {
|
|
54200
|
-
const
|
|
54201
|
-
files.push({ path: rel, size:
|
|
55543
|
+
const stat22 = fs15.statSync(path25.join(d, entry.name));
|
|
55544
|
+
files.push({ path: rel, size: stat22.size, type: "file" });
|
|
54202
55545
|
}
|
|
54203
55546
|
}
|
|
54204
55547
|
} catch {
|
|
@@ -54220,7 +55563,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54220
55563
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
54221
55564
|
return;
|
|
54222
55565
|
}
|
|
54223
|
-
const fullPath =
|
|
55566
|
+
const fullPath = path25.resolve(dir, path25.normalize(filePath));
|
|
54224
55567
|
if (!fullPath.startsWith(dir)) {
|
|
54225
55568
|
this.json(res, 403, { error: "Forbidden" });
|
|
54226
55569
|
return;
|
|
@@ -54245,14 +55588,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54245
55588
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
54246
55589
|
return;
|
|
54247
55590
|
}
|
|
54248
|
-
const fullPath =
|
|
55591
|
+
const fullPath = path25.resolve(dir, path25.normalize(filePath));
|
|
54249
55592
|
if (!fullPath.startsWith(dir)) {
|
|
54250
55593
|
this.json(res, 403, { error: "Forbidden" });
|
|
54251
55594
|
return;
|
|
54252
55595
|
}
|
|
54253
55596
|
try {
|
|
54254
55597
|
if (fs15.existsSync(fullPath)) fs15.copyFileSync(fullPath, fullPath + ".bak");
|
|
54255
|
-
fs15.mkdirSync(
|
|
55598
|
+
fs15.mkdirSync(path25.dirname(fullPath), { recursive: true });
|
|
54256
55599
|
fs15.writeFileSync(fullPath, content, "utf-8");
|
|
54257
55600
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
54258
55601
|
this.providerLoader.reload();
|
|
@@ -54269,7 +55612,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54269
55612
|
return;
|
|
54270
55613
|
}
|
|
54271
55614
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
54272
|
-
const p =
|
|
55615
|
+
const p = path25.join(dir, name);
|
|
54273
55616
|
if (fs15.existsSync(p)) {
|
|
54274
55617
|
const source = fs15.readFileSync(p, "utf-8");
|
|
54275
55618
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
@@ -54290,8 +55633,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54290
55633
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
54291
55634
|
return;
|
|
54292
55635
|
}
|
|
54293
|
-
const target = fs15.existsSync(
|
|
54294
|
-
const targetPath =
|
|
55636
|
+
const target = fs15.existsSync(path25.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
55637
|
+
const targetPath = path25.join(dir, target);
|
|
54295
55638
|
try {
|
|
54296
55639
|
if (fs15.existsSync(targetPath)) fs15.copyFileSync(targetPath, targetPath + ".bak");
|
|
54297
55640
|
fs15.writeFileSync(targetPath, source, "utf-8");
|
|
@@ -54383,14 +55726,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54383
55726
|
child.stderr?.on("data", (d) => {
|
|
54384
55727
|
stderr += d.toString();
|
|
54385
55728
|
});
|
|
54386
|
-
await new Promise((
|
|
55729
|
+
await new Promise((resolve15) => {
|
|
54387
55730
|
const timer = setTimeout(() => {
|
|
54388
55731
|
child.kill();
|
|
54389
|
-
|
|
55732
|
+
resolve15();
|
|
54390
55733
|
}, timeout);
|
|
54391
55734
|
child.on("exit", () => {
|
|
54392
55735
|
clearTimeout(timer);
|
|
54393
|
-
|
|
55736
|
+
resolve15();
|
|
54394
55737
|
});
|
|
54395
55738
|
});
|
|
54396
55739
|
const elapsed = Date.now() - start;
|
|
@@ -54438,7 +55781,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54438
55781
|
}
|
|
54439
55782
|
let targetDir;
|
|
54440
55783
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
54441
|
-
const jsonPath =
|
|
55784
|
+
const jsonPath = path25.join(targetDir, "provider.json");
|
|
54442
55785
|
if (fs15.existsSync(jsonPath)) {
|
|
54443
55786
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
54444
55787
|
return;
|
|
@@ -54450,8 +55793,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54450
55793
|
const createdFiles = ["provider.json"];
|
|
54451
55794
|
if (result.files) {
|
|
54452
55795
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
54453
|
-
const fullPath =
|
|
54454
|
-
fs15.mkdirSync(
|
|
55796
|
+
const fullPath = path25.join(targetDir, relPath);
|
|
55797
|
+
fs15.mkdirSync(path25.dirname(fullPath), { recursive: true });
|
|
54455
55798
|
fs15.writeFileSync(fullPath, content, "utf-8");
|
|
54456
55799
|
createdFiles.push(relPath);
|
|
54457
55800
|
}
|
|
@@ -54504,22 +55847,22 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54504
55847
|
if (!fs15.existsSync(scriptsDir)) return null;
|
|
54505
55848
|
const versions = fs15.readdirSync(scriptsDir).filter((d) => {
|
|
54506
55849
|
try {
|
|
54507
|
-
return fs15.statSync(
|
|
55850
|
+
return fs15.statSync(path25.join(scriptsDir, d)).isDirectory();
|
|
54508
55851
|
} catch {
|
|
54509
55852
|
return false;
|
|
54510
55853
|
}
|
|
54511
55854
|
}).sort((a, b2) => b2.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
54512
55855
|
if (versions.length === 0) return null;
|
|
54513
|
-
return
|
|
55856
|
+
return path25.join(scriptsDir, versions[0]);
|
|
54514
55857
|
}
|
|
54515
55858
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
54516
|
-
const canonicalUserDir =
|
|
54517
|
-
const desiredDir = requestedDir ?
|
|
54518
|
-
const upstreamRoot =
|
|
54519
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
55859
|
+
const canonicalUserDir = path25.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
55860
|
+
const desiredDir = requestedDir ? path25.resolve(requestedDir) : canonicalUserDir;
|
|
55861
|
+
const upstreamRoot = path25.resolve(this.providerLoader.getUpstreamDir());
|
|
55862
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path25.sep}`)) {
|
|
54520
55863
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
54521
55864
|
}
|
|
54522
|
-
if (
|
|
55865
|
+
if (path25.basename(desiredDir) !== type) {
|
|
54523
55866
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
54524
55867
|
}
|
|
54525
55868
|
const sourceDir = this.findProviderDir(type);
|
|
@@ -54527,11 +55870,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54527
55870
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
54528
55871
|
}
|
|
54529
55872
|
if (!fs15.existsSync(desiredDir)) {
|
|
54530
|
-
fs15.mkdirSync(
|
|
55873
|
+
fs15.mkdirSync(path25.dirname(desiredDir), { recursive: true });
|
|
54531
55874
|
fs15.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
54532
55875
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
54533
55876
|
}
|
|
54534
|
-
const providerJson =
|
|
55877
|
+
const providerJson = path25.join(desiredDir, "provider.json");
|
|
54535
55878
|
if (!fs15.existsSync(providerJson)) {
|
|
54536
55879
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
54537
55880
|
}
|
|
@@ -54567,7 +55910,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54567
55910
|
setMode: "set_mode.js"
|
|
54568
55911
|
};
|
|
54569
55912
|
const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
|
|
54570
|
-
const scriptsDir =
|
|
55913
|
+
const scriptsDir = path25.join(providerDir, "scripts");
|
|
54571
55914
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
54572
55915
|
if (latestScriptsDir) {
|
|
54573
55916
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -54578,7 +55921,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54578
55921
|
for (const file2 of fs15.readdirSync(latestScriptsDir)) {
|
|
54579
55922
|
if (file2.endsWith(".js") && targetFileNames.has(file2)) {
|
|
54580
55923
|
try {
|
|
54581
|
-
const content = fs15.readFileSync(
|
|
55924
|
+
const content = fs15.readFileSync(path25.join(latestScriptsDir, file2), "utf-8");
|
|
54582
55925
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
54583
55926
|
lines.push("```javascript");
|
|
54584
55927
|
lines.push(content);
|
|
@@ -54595,7 +55938,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54595
55938
|
lines.push("");
|
|
54596
55939
|
for (const file2 of refFiles) {
|
|
54597
55940
|
try {
|
|
54598
|
-
const content = fs15.readFileSync(
|
|
55941
|
+
const content = fs15.readFileSync(path25.join(latestScriptsDir, file2), "utf-8");
|
|
54599
55942
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
54600
55943
|
lines.push("```javascript");
|
|
54601
55944
|
lines.push(content);
|
|
@@ -54636,10 +55979,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54636
55979
|
lines.push("");
|
|
54637
55980
|
}
|
|
54638
55981
|
}
|
|
54639
|
-
const docsDir =
|
|
55982
|
+
const docsDir = path25.join(providerDir, "../../docs");
|
|
54640
55983
|
const loadGuide = (name) => {
|
|
54641
55984
|
try {
|
|
54642
|
-
const p =
|
|
55985
|
+
const p = path25.join(docsDir, name);
|
|
54643
55986
|
if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
|
|
54644
55987
|
} catch {
|
|
54645
55988
|
}
|
|
@@ -54813,7 +56156,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54813
56156
|
parseApproval: "parse_approval.js"
|
|
54814
56157
|
};
|
|
54815
56158
|
const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
|
|
54816
|
-
const scriptsDir =
|
|
56159
|
+
const scriptsDir = path25.join(providerDir, "scripts");
|
|
54817
56160
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
54818
56161
|
if (latestScriptsDir) {
|
|
54819
56162
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -54825,7 +56168,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54825
56168
|
if (!file2.endsWith(".js")) continue;
|
|
54826
56169
|
if (!targetFileNames.has(file2)) continue;
|
|
54827
56170
|
try {
|
|
54828
|
-
const content = fs15.readFileSync(
|
|
56171
|
+
const content = fs15.readFileSync(path25.join(latestScriptsDir, file2), "utf-8");
|
|
54829
56172
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
54830
56173
|
lines.push("```javascript");
|
|
54831
56174
|
lines.push(content);
|
|
@@ -54841,7 +56184,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54841
56184
|
lines.push("");
|
|
54842
56185
|
for (const file2 of refFiles) {
|
|
54843
56186
|
try {
|
|
54844
|
-
const content = fs15.readFileSync(
|
|
56187
|
+
const content = fs15.readFileSync(path25.join(latestScriptsDir, file2), "utf-8");
|
|
54845
56188
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
54846
56189
|
lines.push("```javascript");
|
|
54847
56190
|
lines.push(content);
|
|
@@ -54874,10 +56217,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54874
56217
|
lines.push("");
|
|
54875
56218
|
}
|
|
54876
56219
|
}
|
|
54877
|
-
const docsDir =
|
|
56220
|
+
const docsDir = path25.join(providerDir, "../../docs");
|
|
54878
56221
|
const loadGuide = (name) => {
|
|
54879
56222
|
try {
|
|
54880
|
-
const p =
|
|
56223
|
+
const p = path25.join(docsDir, name);
|
|
54881
56224
|
if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
|
|
54882
56225
|
} catch {
|
|
54883
56226
|
}
|
|
@@ -55060,14 +56403,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
55060
56403
|
res.end(JSON.stringify(data, null, 2));
|
|
55061
56404
|
}
|
|
55062
56405
|
async readBody(req) {
|
|
55063
|
-
return new Promise((
|
|
56406
|
+
return new Promise((resolve15) => {
|
|
55064
56407
|
let body = "";
|
|
55065
56408
|
req.on("data", (chunk) => body += chunk);
|
|
55066
56409
|
req.on("end", () => {
|
|
55067
56410
|
try {
|
|
55068
|
-
|
|
56411
|
+
resolve15(JSON.parse(body));
|
|
55069
56412
|
} catch {
|
|
55070
|
-
|
|
56413
|
+
resolve15({});
|
|
55071
56414
|
}
|
|
55072
56415
|
});
|
|
55073
56416
|
});
|
|
@@ -55569,7 +56912,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
55569
56912
|
const deadline = Date.now() + timeoutMs;
|
|
55570
56913
|
while (Date.now() < deadline) {
|
|
55571
56914
|
if (await canConnect(endpoint)) return;
|
|
55572
|
-
await new Promise((
|
|
56915
|
+
await new Promise((resolve15) => setTimeout(resolve15, STARTUP_POLL_MS));
|
|
55573
56916
|
}
|
|
55574
56917
|
throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
|
|
55575
56918
|
}
|
|
@@ -55743,10 +57086,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
55743
57086
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
55744
57087
|
const fs16 = await import("fs");
|
|
55745
57088
|
fs16.writeFileSync(vsixPath, buffer);
|
|
55746
|
-
return new Promise((
|
|
57089
|
+
return new Promise((resolve15) => {
|
|
55747
57090
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
55748
57091
|
(0, import_child_process11.exec)(cmd, { timeout: 6e4 }, (error48, _stdout, stderr) => {
|
|
55749
|
-
|
|
57092
|
+
resolve15({
|
|
55750
57093
|
extensionId: extension.id,
|
|
55751
57094
|
marketplaceId: extension.marketplaceId,
|
|
55752
57095
|
success: !error48,
|
|
@@ -55759,11 +57102,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
55759
57102
|
} catch (e) {
|
|
55760
57103
|
}
|
|
55761
57104
|
}
|
|
55762
|
-
return new Promise((
|
|
57105
|
+
return new Promise((resolve15) => {
|
|
55763
57106
|
const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
|
|
55764
57107
|
(0, import_child_process11.exec)(cmd, { timeout: 6e4 }, (error48, stdout, stderr) => {
|
|
55765
57108
|
if (error48) {
|
|
55766
|
-
|
|
57109
|
+
resolve15({
|
|
55767
57110
|
extensionId: extension.id,
|
|
55768
57111
|
marketplaceId: extension.marketplaceId,
|
|
55769
57112
|
success: false,
|
|
@@ -55771,7 +57114,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
55771
57114
|
error: stderr || error48.message
|
|
55772
57115
|
});
|
|
55773
57116
|
} else {
|
|
55774
|
-
|
|
57117
|
+
resolve15({
|
|
55775
57118
|
extensionId: extension.id,
|
|
55776
57119
|
marketplaceId: extension.marketplaceId,
|
|
55777
57120
|
success: true,
|
|
@@ -55971,6 +57314,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
55971
57314
|
providerLoader,
|
|
55972
57315
|
instanceManager,
|
|
55973
57316
|
sessionRegistry,
|
|
57317
|
+
gitCommandServices: createDefaultGitCommandServices(),
|
|
55974
57318
|
onProviderSettingChanged: async (providerType) => {
|
|
55975
57319
|
await refreshProviderAvailability(providerType);
|
|
55976
57320
|
config2.onStatusChange?.();
|
|
@@ -55978,7 +57322,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
55978
57322
|
onProviderSourceConfigChanged: async () => {
|
|
55979
57323
|
await refreshProviderAvailability();
|
|
55980
57324
|
config2.onStatusChange?.();
|
|
55981
|
-
}
|
|
57325
|
+
},
|
|
57326
|
+
onBeforeSendChat: config2.onBeforeSendChat
|
|
55982
57327
|
});
|
|
55983
57328
|
agentStreamManager = new DaemonAgentStreamManager(
|
|
55984
57329
|
LOG2.forComponent("AgentStream").asLogFn(),
|
|
@@ -56881,6 +58226,8 @@ var StandaloneServer = class {
|
|
|
56881
58226
|
wsSessionHostDiagnosticsSubscriptions = /* @__PURE__ */ new Map();
|
|
56882
58227
|
wsSessionModalSubscriptions = /* @__PURE__ */ new Map();
|
|
56883
58228
|
wsDaemonMetadataSubscriptions = /* @__PURE__ */ new Map();
|
|
58229
|
+
wsGitSubscriptions = /* @__PURE__ */ new Map();
|
|
58230
|
+
gitWorkspaceMonitor = (0, import_daemon_core2.createGitWorkspaceMonitor)();
|
|
56884
58231
|
authToken = null;
|
|
56885
58232
|
passwordConfigPath = getStandalonePasswordConfigPath();
|
|
56886
58233
|
passwordConfig = null;
|
|
@@ -57146,6 +58493,7 @@ var StandaloneServer = class {
|
|
|
57146
58493
|
void this.flushWsMachineRuntimeSubscriptions();
|
|
57147
58494
|
void this.flushWsSessionHostDiagnosticsSubscriptions();
|
|
57148
58495
|
void this.flushWsSessionModalSubscriptions();
|
|
58496
|
+
if (this.hasWsGitSubscriptions()) void this.flushWsGitSubscriptions();
|
|
57149
58497
|
}, STATUS_INTERVAL);
|
|
57150
58498
|
this.running = true;
|
|
57151
58499
|
await new Promise((resolve4) => {
|
|
@@ -57634,6 +58982,7 @@ var StandaloneServer = class {
|
|
|
57634
58982
|
this.wsSessionHostDiagnosticsSubscriptions.set(ws2, /* @__PURE__ */ new Map());
|
|
57635
58983
|
this.wsSessionModalSubscriptions.set(ws2, /* @__PURE__ */ new Map());
|
|
57636
58984
|
this.wsDaemonMetadataSubscriptions.set(ws2, /* @__PURE__ */ new Map());
|
|
58985
|
+
this.wsGitSubscriptions.set(ws2, /* @__PURE__ */ new Map());
|
|
57637
58986
|
console.log(`[WS] Client connected (total: ${this.clients.size})`);
|
|
57638
58987
|
const status = this.getWsStatus(this.buildSharedSnapshot("live"));
|
|
57639
58988
|
this.lastWsStatusSignature = this.buildWsStatusSignature(status);
|
|
@@ -57677,6 +59026,7 @@ var StandaloneServer = class {
|
|
|
57677
59026
|
this.wsSessionHostDiagnosticsSubscriptions.delete(ws2);
|
|
57678
59027
|
this.wsSessionModalSubscriptions.delete(ws2);
|
|
57679
59028
|
this.wsDaemonMetadataSubscriptions.delete(ws2);
|
|
59029
|
+
this.clearWsGitSubscriptions(ws2);
|
|
57680
59030
|
console.log(`[WS] Client disconnected (total: ${this.clients.size})`);
|
|
57681
59031
|
});
|
|
57682
59032
|
ws2.on("error", () => {
|
|
@@ -57686,8 +59036,19 @@ var StandaloneServer = class {
|
|
|
57686
59036
|
this.wsSessionHostDiagnosticsSubscriptions.delete(ws2);
|
|
57687
59037
|
this.wsSessionModalSubscriptions.delete(ws2);
|
|
57688
59038
|
this.wsDaemonMetadataSubscriptions.delete(ws2);
|
|
59039
|
+
this.clearWsGitSubscriptions(ws2);
|
|
57689
59040
|
});
|
|
57690
59041
|
}
|
|
59042
|
+
clearWsGitSubscriptions(ws2) {
|
|
59043
|
+
const subs = this.wsGitSubscriptions.get(ws2);
|
|
59044
|
+
if (subs) {
|
|
59045
|
+
subs.forEach((sub) => {
|
|
59046
|
+
sub.subscription.dispose();
|
|
59047
|
+
});
|
|
59048
|
+
subs.clear();
|
|
59049
|
+
}
|
|
59050
|
+
this.wsGitSubscriptions.delete(ws2);
|
|
59051
|
+
}
|
|
57691
59052
|
async handleWsSubscribe(ws2, msg) {
|
|
57692
59053
|
if (msg.topic === "session.chat_tail") {
|
|
57693
59054
|
const params = msg.params;
|
|
@@ -57775,6 +59136,25 @@ var StandaloneServer = class {
|
|
|
57775
59136
|
lastSentAt: 0
|
|
57776
59137
|
});
|
|
57777
59138
|
await this.flushWsDaemonMetadataSubscriptions(ws2);
|
|
59139
|
+
return;
|
|
59140
|
+
}
|
|
59141
|
+
if (msg.topic === "workspace.git") {
|
|
59142
|
+
const params = msg.params;
|
|
59143
|
+
if (!params?.workspace) return;
|
|
59144
|
+
const normalized = (0, import_daemon_core2.normalizeGitWorkspaceSubscriptionParams)(params);
|
|
59145
|
+
const subs = this.wsGitSubscriptions.get(ws2) || /* @__PURE__ */ new Map();
|
|
59146
|
+
this.wsGitSubscriptions.set(ws2, subs);
|
|
59147
|
+
subs.get(msg.key)?.subscription.dispose();
|
|
59148
|
+
subs.set(msg.key, {
|
|
59149
|
+
request: {
|
|
59150
|
+
...msg,
|
|
59151
|
+
topic: "workspace.git",
|
|
59152
|
+
params: normalized
|
|
59153
|
+
},
|
|
59154
|
+
subscription: this.gitWorkspaceMonitor.createSubscription(normalized),
|
|
59155
|
+
lastSentAt: 0
|
|
59156
|
+
});
|
|
59157
|
+
await this.flushWsGitSubscriptions(ws2);
|
|
57778
59158
|
}
|
|
57779
59159
|
}
|
|
57780
59160
|
handleWsUnsubscribe(ws2, msg) {
|
|
@@ -57796,6 +59176,12 @@ var StandaloneServer = class {
|
|
|
57796
59176
|
}
|
|
57797
59177
|
if (msg.topic === "daemon.metadata") {
|
|
57798
59178
|
this.wsDaemonMetadataSubscriptions.get(ws2)?.delete(msg.key);
|
|
59179
|
+
return;
|
|
59180
|
+
}
|
|
59181
|
+
if (msg.topic === "workspace.git") {
|
|
59182
|
+
const sub = this.wsGitSubscriptions.get(ws2)?.get(msg.key);
|
|
59183
|
+
sub?.subscription.dispose();
|
|
59184
|
+
this.wsGitSubscriptions.get(ws2)?.delete(msg.key);
|
|
57799
59185
|
}
|
|
57800
59186
|
}
|
|
57801
59187
|
async buildChatTailUpdate(request, state, key) {
|
|
@@ -58019,6 +59405,45 @@ var StandaloneServer = class {
|
|
|
58019
59405
|
}
|
|
58020
59406
|
}
|
|
58021
59407
|
}
|
|
59408
|
+
hasWsGitSubscriptions(targetWs) {
|
|
59409
|
+
const targets = targetWs ? [targetWs] : Array.from(this.clients);
|
|
59410
|
+
for (const ws2 of targets) {
|
|
59411
|
+
const subs = this.wsGitSubscriptions.get(ws2);
|
|
59412
|
+
if (subs && subs.size > 0) return true;
|
|
59413
|
+
}
|
|
59414
|
+
return false;
|
|
59415
|
+
}
|
|
59416
|
+
async flushWsGitSubscriptions(targetWs) {
|
|
59417
|
+
if (!this.hasWsGitSubscriptions(targetWs)) return;
|
|
59418
|
+
const targets = targetWs ? [targetWs] : Array.from(this.clients);
|
|
59419
|
+
const now = Date.now();
|
|
59420
|
+
const tasks = [];
|
|
59421
|
+
for (const ws2 of targets) {
|
|
59422
|
+
if (ws2.readyState !== import_ws.WebSocket.OPEN) continue;
|
|
59423
|
+
const subs = this.wsGitSubscriptions.get(ws2);
|
|
59424
|
+
if (!subs || subs.size === 0) continue;
|
|
59425
|
+
subs.forEach((sub, key) => {
|
|
59426
|
+
const intervalMs = Math.max(1, Number(sub.subscription.params.intervalMs || sub.request.params.intervalMs || 0));
|
|
59427
|
+
if (sub.lastSentAt > 0 && now - sub.lastSentAt < intervalMs) return;
|
|
59428
|
+
tasks.push({ ws: ws2, key, sub });
|
|
59429
|
+
});
|
|
59430
|
+
}
|
|
59431
|
+
await (0, import_daemon_core2.runAsyncBatch)(tasks, async ({ ws: ws2, key, sub }) => {
|
|
59432
|
+
try {
|
|
59433
|
+
const monitorUpdate = await sub.subscription.refresh();
|
|
59434
|
+
const current = this.wsGitSubscriptions.get(ws2)?.get(key);
|
|
59435
|
+
if (current !== sub || ws2.readyState !== import_ws.WebSocket.OPEN) return;
|
|
59436
|
+
sub.lastSentAt = monitorUpdate.timestamp;
|
|
59437
|
+
const update = {
|
|
59438
|
+
...monitorUpdate,
|
|
59439
|
+
key
|
|
59440
|
+
};
|
|
59441
|
+
ws2.send(JSON.stringify({ type: "topic_update", update }));
|
|
59442
|
+
} catch (error48) {
|
|
59443
|
+
import_daemon_core2.LOG.warn("Standalone", `[workspace.git] skipped workspace=${sub.request.params.workspace} key=${key} error=${error48?.message || error48}`);
|
|
59444
|
+
}
|
|
59445
|
+
}, { concurrency: 2 });
|
|
59446
|
+
}
|
|
58022
59447
|
// ─── Core Logic ───
|
|
58023
59448
|
buildSharedSnapshot(profile = "full") {
|
|
58024
59449
|
const cfgSnap = (0, import_daemon_core2.loadConfig)();
|
|
@@ -58034,7 +59459,8 @@ var StandaloneServer = class {
|
|
|
58034
59459
|
})),
|
|
58035
59460
|
instanceId: `standalone_${machineId}`,
|
|
58036
59461
|
version: pkgVersion,
|
|
58037
|
-
profile
|
|
59462
|
+
profile,
|
|
59463
|
+
getGitSummaryForWorkspace: (workspace) => this.gitWorkspaceMonitor.getCompactSummary(workspace)
|
|
58038
59464
|
});
|
|
58039
59465
|
}
|
|
58040
59466
|
async pushWsRuntimeSnapshots(ws2) {
|
|
@@ -58143,6 +59569,7 @@ var StandaloneServer = class {
|
|
|
58143
59569
|
}
|
|
58144
59570
|
if (type.startsWith("session_host_")) void this.flushWsSessionHostDiagnosticsSubscriptions();
|
|
58145
59571
|
if (type === "resolve_action" || type === "send_chat" || type === "read_chat") void this.flushWsSessionModalSubscriptions();
|
|
59572
|
+
if (type.startsWith("git_") && this.hasWsGitSubscriptions()) void this.flushWsGitSubscriptions();
|
|
58146
59573
|
return result;
|
|
58147
59574
|
}
|
|
58148
59575
|
scheduleBroadcastStatus() {
|