@adhdev/daemon-standalone 0.9.53 → 0.9.54
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 +1618 -385
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/index-B_x0b-hG.css +1 -0
- package/public/assets/index-D4poqwZK.js +92 -0
- package/public/index.html +2 -2
- 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;
|
|
@@ -29839,9 +29839,9 @@ var require_dist2 = __commonJS({
|
|
|
29839
29839
|
const allArgs = [...spawnConfig.args, ...extraArgs];
|
|
29840
29840
|
let shellCmd;
|
|
29841
29841
|
let shellArgs;
|
|
29842
|
-
const useShellUnix = !isWin && (!!spawnConfig.shell || !
|
|
29842
|
+
const useShellUnix = !isWin && (!!spawnConfig.shell || !path14.isAbsolute(binaryPath) || isScriptBinary(binaryPath) || !looksLikeMachOOrElf(binaryPath));
|
|
29843
29843
|
const isCmdShim = isWin && /\.(cmd|bat)$/i.test(binaryPath);
|
|
29844
|
-
const useShellWin = !!spawnConfig.shell || isCmdShim || !
|
|
29844
|
+
const useShellWin = !!spawnConfig.shell || isCmdShim || !path14.isAbsolute(binaryPath) || isScriptBinary(binaryPath);
|
|
29845
29845
|
const useShell = isWin ? useShellWin : useShellUnix;
|
|
29846
29846
|
if (useShell) {
|
|
29847
29847
|
shellCmd = isWin ? "cmd.exe" : process.env.SHELL || "/bin/zsh";
|
|
@@ -29918,13 +29918,13 @@ var require_dist2 = __commonJS({
|
|
|
29918
29918
|
return "";
|
|
29919
29919
|
}
|
|
29920
29920
|
var os10;
|
|
29921
|
-
var
|
|
29921
|
+
var path14;
|
|
29922
29922
|
var import_session_host_core22;
|
|
29923
29923
|
var init_provider_cli_runtime = __esm2({
|
|
29924
29924
|
"src/cli-adapters/provider-cli-runtime.ts"() {
|
|
29925
29925
|
"use strict";
|
|
29926
29926
|
os10 = __toESM2(require("os"));
|
|
29927
|
-
|
|
29927
|
+
path14 = __toESM2(require("path"));
|
|
29928
29928
|
import_session_host_core22 = require_dist();
|
|
29929
29929
|
init_provider_cli_shared();
|
|
29930
29930
|
}
|
|
@@ -30724,7 +30724,7 @@ var require_dist2 = __commonJS({
|
|
|
30724
30724
|
`[${this.cliType}] Waiting for interactive prompt: status=${status} stableMs=${stableMs} recentOutputMs=${recentlyOutput} screen=${JSON.stringify(summarizeCliTraceText(screenText, 220)).slice(0, 260)}`
|
|
30725
30725
|
);
|
|
30726
30726
|
}
|
|
30727
|
-
await new Promise((
|
|
30727
|
+
await new Promise((resolve15) => setTimeout(resolve15, 50));
|
|
30728
30728
|
}
|
|
30729
30729
|
const finalScreenText = this.terminalScreen.getText() || "";
|
|
30730
30730
|
LOG2.warn(
|
|
@@ -31912,7 +31912,7 @@ var require_dist2 = __commonJS({
|
|
|
31912
31912
|
const deadline = Date.now() + 1e4;
|
|
31913
31913
|
while (this.startupParseGate && Date.now() < deadline) {
|
|
31914
31914
|
this.resolveStartupState("send_wait");
|
|
31915
|
-
await new Promise((
|
|
31915
|
+
await new Promise((resolve15) => setTimeout(resolve15, 50));
|
|
31916
31916
|
}
|
|
31917
31917
|
}
|
|
31918
31918
|
if (!allowInterventionPrompt) {
|
|
@@ -31993,13 +31993,13 @@ var require_dist2 = __commonJS({
|
|
|
31993
31993
|
}
|
|
31994
31994
|
this.responseEpoch += 1;
|
|
31995
31995
|
this.responseSettleIgnoreUntil = Date.now() + submitDelayMs + this.timeouts.outputSettle + 250;
|
|
31996
|
-
await new Promise((
|
|
31996
|
+
await new Promise((resolve15, reject) => {
|
|
31997
31997
|
let resolved = false;
|
|
31998
31998
|
const completion = {
|
|
31999
31999
|
resolveOnce: () => {
|
|
32000
32000
|
if (resolved) return;
|
|
32001
32001
|
resolved = true;
|
|
32002
|
-
|
|
32002
|
+
resolve15();
|
|
32003
32003
|
},
|
|
32004
32004
|
rejectOnce: (error48) => {
|
|
32005
32005
|
if (resolved) return;
|
|
@@ -32161,17 +32161,17 @@ var require_dist2 = __commonJS({
|
|
|
32161
32161
|
}
|
|
32162
32162
|
}
|
|
32163
32163
|
waitForStopped(timeoutMs) {
|
|
32164
|
-
return new Promise((
|
|
32164
|
+
return new Promise((resolve15) => {
|
|
32165
32165
|
const startedAt = Date.now();
|
|
32166
32166
|
const timer = setInterval(() => {
|
|
32167
32167
|
if (!this.ptyProcess || this.currentStatus === "stopped") {
|
|
32168
32168
|
clearInterval(timer);
|
|
32169
|
-
|
|
32169
|
+
resolve15(true);
|
|
32170
32170
|
return;
|
|
32171
32171
|
}
|
|
32172
32172
|
if (Date.now() - startedAt >= timeoutMs) {
|
|
32173
32173
|
clearInterval(timer);
|
|
32174
|
-
|
|
32174
|
+
resolve15(false);
|
|
32175
32175
|
}
|
|
32176
32176
|
}, 100);
|
|
32177
32177
|
});
|
|
@@ -32409,6 +32409,7 @@ var require_dist2 = __commonJS({
|
|
|
32409
32409
|
DEFAULT_CDP_SCAN_INTERVAL_MS: () => DEFAULT_CDP_SCAN_INTERVAL_MS,
|
|
32410
32410
|
DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS: () => DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS2,
|
|
32411
32411
|
DEFAULT_DAEMON_PORT: () => DEFAULT_DAEMON_PORT,
|
|
32412
|
+
DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS: () => DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS,
|
|
32412
32413
|
DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS: () => DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS2,
|
|
32413
32414
|
DEFAULT_SESSION_HOST_APP_NAME: () => DEFAULT_SESSION_HOST_APP_NAME,
|
|
32414
32415
|
DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS: () => DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS2,
|
|
@@ -32427,8 +32428,12 @@ var require_dist2 = __commonJS({
|
|
|
32427
32428
|
DaemonCommandRouter: () => DaemonCommandRouter,
|
|
32428
32429
|
DaemonStatusReporter: () => DaemonStatusReporter,
|
|
32429
32430
|
DevServer: () => DevServer,
|
|
32431
|
+
GitCommandError: () => GitCommandError,
|
|
32432
|
+
GitWorkspaceMonitor: () => GitWorkspaceMonitor,
|
|
32430
32433
|
IdeProviderInstance: () => IdeProviderInstance,
|
|
32434
|
+
InMemoryGitSnapshotStore: () => InMemoryGitSnapshotStore,
|
|
32431
32435
|
LOG: () => LOG2,
|
|
32436
|
+
MIN_GIT_WORKSPACE_POLL_INTERVAL_MS: () => MIN_GIT_WORKSPACE_POLL_INTERVAL_MS,
|
|
32432
32437
|
MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS: () => MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS2,
|
|
32433
32438
|
MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS: () => MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS2,
|
|
32434
32439
|
NodePtyTransportFactory: () => NodePtyTransportFactory,
|
|
@@ -32456,9 +32461,14 @@ var require_dist2 = __commonJS({
|
|
|
32456
32461
|
buildUserChatMessage: () => buildUserChatMessage,
|
|
32457
32462
|
classifyHotChatSessionsForSubscriptionFlush: () => classifyHotChatSessionsForSubscriptionFlush2,
|
|
32458
32463
|
clearDebugTrace: () => clearDebugTrace,
|
|
32464
|
+
compareGitSnapshots: () => compareGitSnapshots,
|
|
32459
32465
|
configureDebugTraceStore: () => configureDebugTraceStore,
|
|
32460
32466
|
connectCdpManager: () => connectCdpManager,
|
|
32461
32467
|
createDebugTraceStore: () => createDebugTraceStore,
|
|
32468
|
+
createDefaultGitCommandServices: () => createDefaultGitCommandServices,
|
|
32469
|
+
createGitCompactSummary: () => createGitCompactSummary,
|
|
32470
|
+
createGitSnapshotStore: () => createGitSnapshotStore,
|
|
32471
|
+
createGitWorkspaceMonitor: () => createGitWorkspaceMonitor2,
|
|
32462
32472
|
createInteractionId: () => createInteractionId,
|
|
32463
32473
|
detectAllVersions: () => detectAllVersions,
|
|
32464
32474
|
detectCLIs: () => detectCLIs,
|
|
@@ -32473,6 +32483,9 @@ var require_dist2 = __commonJS({
|
|
|
32473
32483
|
getCurrentDaemonLogPath: () => getCurrentDaemonLogPath,
|
|
32474
32484
|
getDaemonLogDir: () => getDaemonLogDir,
|
|
32475
32485
|
getDebugRuntimeConfig: () => getDebugRuntimeConfig,
|
|
32486
|
+
getGitDiffSummary: () => getGitDiffSummary,
|
|
32487
|
+
getGitFileDiff: () => getGitFileDiff,
|
|
32488
|
+
getGitRepoStatus: () => getGitRepoStatus,
|
|
32476
32489
|
getHostMemorySnapshot: () => getHostMemorySnapshot,
|
|
32477
32490
|
getLogLevel: () => getLogLevel,
|
|
32478
32491
|
getNpmExecOptions: () => getNpmExecOptions,
|
|
@@ -32484,6 +32497,7 @@ var require_dist2 = __commonJS({
|
|
|
32484
32497
|
getSessionHostRecoveryLabel: () => getSessionHostRecoveryLabel,
|
|
32485
32498
|
getSessionHostSurfaceKind: () => getSessionHostSurfaceKind,
|
|
32486
32499
|
getWorkspaceState: () => getWorkspaceState2,
|
|
32500
|
+
handleGitCommand: () => handleGitCommand,
|
|
32487
32501
|
hasCdpManager: () => hasCdpManager,
|
|
32488
32502
|
hashSignatureParts: () => hashSignatureParts,
|
|
32489
32503
|
initDaemonComponents: () => initDaemonComponents2,
|
|
@@ -32492,9 +32506,11 @@ var require_dist2 = __commonJS({
|
|
|
32492
32506
|
isBuiltinChatMessageKind: () => isBuiltinChatMessageKind,
|
|
32493
32507
|
isCdpConnected: () => isCdpConnected,
|
|
32494
32508
|
isExtensionInstalled: () => isExtensionInstalled,
|
|
32509
|
+
isGitCommandName: () => isGitCommandName,
|
|
32495
32510
|
isIdeRunning: () => isIdeRunning,
|
|
32496
32511
|
isManagedStatusWaiting: () => isManagedStatusWaiting,
|
|
32497
32512
|
isManagedStatusWorking: () => isManagedStatusWorking,
|
|
32513
|
+
isPathInside: () => isPathInside,
|
|
32498
32514
|
isSessionHostLiveRuntime: () => isSessionHostLiveRuntime,
|
|
32499
32515
|
isSessionHostRecoverySnapshot: () => isSessionHostRecoverySnapshot,
|
|
32500
32516
|
isSetupComplete: () => isSetupComplete,
|
|
@@ -32512,10 +32528,13 @@ var require_dist2 = __commonJS({
|
|
|
32512
32528
|
normalizeChatMessageKind: () => normalizeChatMessageKind,
|
|
32513
32529
|
normalizeChatMessages: () => normalizeChatMessages,
|
|
32514
32530
|
normalizeChatTailActiveModal: () => normalizeChatTailActiveModal,
|
|
32531
|
+
normalizeGitOutput: () => normalizeGitOutput,
|
|
32532
|
+
normalizeGitWorkspaceSubscriptionParams: () => normalizeGitWorkspaceSubscriptionParams2,
|
|
32515
32533
|
normalizeInputEnvelope: () => normalizeInputEnvelope,
|
|
32516
32534
|
normalizeManagedStatus: () => normalizeManagedStatus,
|
|
32517
32535
|
normalizeMessageParts: () => normalizeMessageParts,
|
|
32518
32536
|
normalizeSessionModalFields: () => normalizeSessionModalFields,
|
|
32537
|
+
parsePorcelainV2Status: () => parsePorcelainV2Status,
|
|
32519
32538
|
parseProviderSourceConfigUpdate: () => parseProviderSourceConfigUpdate,
|
|
32520
32539
|
partitionSessionHostDiagnosticsSessions: () => partitionSessionHostDiagnosticsSessions,
|
|
32521
32540
|
partitionSessionHostRecords: () => partitionSessionHostRecords,
|
|
@@ -32531,9 +32550,11 @@ var require_dist2 = __commonJS({
|
|
|
32531
32550
|
resolveChatMessageKind: () => resolveChatMessageKind,
|
|
32532
32551
|
resolveCurrentGlobalInstallSurface: () => resolveCurrentGlobalInstallSurface,
|
|
32533
32552
|
resolveDebugRuntimeConfig: () => resolveDebugRuntimeConfig,
|
|
32553
|
+
resolveGitRepository: () => resolveGitRepository,
|
|
32534
32554
|
resolveSessionHostAppName: () => resolveSessionHostAppName,
|
|
32535
32555
|
resolveSessionHostAppNameResolution: () => resolveSessionHostAppNameResolution2,
|
|
32536
32556
|
runAsyncBatch: () => runAsyncBatch2,
|
|
32557
|
+
runGit: () => runGit,
|
|
32537
32558
|
saveConfig: () => saveConfig,
|
|
32538
32559
|
saveState: () => saveState,
|
|
32539
32560
|
setDebugRuntimeConfig: () => setDebugRuntimeConfig,
|
|
@@ -32544,21 +32565,1125 @@ var require_dist2 = __commonJS({
|
|
|
32544
32565
|
shutdownDaemonComponents: () => shutdownDaemonComponents2,
|
|
32545
32566
|
spawnDetachedDaemonUpgradeHelper: () => spawnDetachedDaemonUpgradeHelper,
|
|
32546
32567
|
startDaemonDevSupport: () => startDaemonDevSupport2,
|
|
32568
|
+
summarizeGitStatus: () => summarizeGitStatus,
|
|
32547
32569
|
updateConfig: () => updateConfig,
|
|
32548
32570
|
upsertSavedProviderSession: () => upsertSavedProviderSession
|
|
32549
32571
|
});
|
|
32550
32572
|
module2.exports = __toCommonJS2(index_exports);
|
|
32573
|
+
var import_node_child_process = require("child_process");
|
|
32574
|
+
var import_node_fs3 = require("fs");
|
|
32575
|
+
var import_promises4 = require("fs/promises");
|
|
32576
|
+
var path5 = __toESM2(require("path"));
|
|
32577
|
+
var import_node_util = require("util");
|
|
32578
|
+
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
32579
|
+
var DEFAULT_TIMEOUT_MS = 5e3;
|
|
32580
|
+
var DEFAULT_MAX_BUFFER = 1024 * 1024;
|
|
32581
|
+
var GitCommandError = class extends Error {
|
|
32582
|
+
reason;
|
|
32583
|
+
stdout;
|
|
32584
|
+
stderr;
|
|
32585
|
+
exitCode;
|
|
32586
|
+
signal;
|
|
32587
|
+
argv;
|
|
32588
|
+
cwd;
|
|
32589
|
+
constructor(reason, message, details = {}) {
|
|
32590
|
+
super(message);
|
|
32591
|
+
if (details.cause !== void 0) {
|
|
32592
|
+
this.cause = details.cause;
|
|
32593
|
+
}
|
|
32594
|
+
this.name = "GitCommandError";
|
|
32595
|
+
this.reason = reason;
|
|
32596
|
+
this.stdout = normalizeGitOutput(details.stdout);
|
|
32597
|
+
this.stderr = normalizeGitOutput(details.stderr);
|
|
32598
|
+
this.exitCode = details.exitCode;
|
|
32599
|
+
this.signal = details.signal;
|
|
32600
|
+
this.argv = details.argv ? [...details.argv] : void 0;
|
|
32601
|
+
this.cwd = details.cwd;
|
|
32602
|
+
}
|
|
32603
|
+
};
|
|
32604
|
+
async function resolveGitRepository(workspace, options = {}) {
|
|
32605
|
+
const normalizedWorkspace = await validateWorkspace(workspace);
|
|
32606
|
+
const result = await execGitRaw(normalizedWorkspace, ["rev-parse", "--show-toplevel"], options, {
|
|
32607
|
+
mapNotGitRepo: true
|
|
32608
|
+
});
|
|
32609
|
+
const repoRoot = path5.resolve(result.stdout.trim());
|
|
32610
|
+
if (!repoRoot) {
|
|
32611
|
+
throw new GitCommandError("not_git_repo", "Git did not return a repository root", {
|
|
32612
|
+
stdout: result.stdout,
|
|
32613
|
+
stderr: result.stderr,
|
|
32614
|
+
argv: ["rev-parse", "--show-toplevel"],
|
|
32615
|
+
cwd: normalizedWorkspace
|
|
32616
|
+
});
|
|
32617
|
+
}
|
|
32618
|
+
return {
|
|
32619
|
+
workspace: normalizedWorkspace,
|
|
32620
|
+
repoRoot,
|
|
32621
|
+
isGitRepo: true
|
|
32622
|
+
};
|
|
32623
|
+
}
|
|
32624
|
+
async function runGit(repoOrWorkspace, argv, options = {}) {
|
|
32625
|
+
validateGitArgv(argv);
|
|
32626
|
+
const repo = typeof repoOrWorkspace === "string" ? await resolveGitRepository(repoOrWorkspace, options) : repoOrWorkspace;
|
|
32627
|
+
if (!repo.repoRoot || !repo.isGitRepo) {
|
|
32628
|
+
throw new GitCommandError("not_git_repo", "Workspace is not a Git repository", {
|
|
32629
|
+
argv,
|
|
32630
|
+
cwd: repo.workspace
|
|
32631
|
+
});
|
|
32632
|
+
}
|
|
32633
|
+
const cwd = options.cwd ? await validateWorkspace(options.cwd) : await validateWorkspace(repo.workspace);
|
|
32634
|
+
const canonicalRepoRoot = await (0, import_promises4.realpath)(repo.repoRoot);
|
|
32635
|
+
const canonicalCwd = await (0, import_promises4.realpath)(cwd);
|
|
32636
|
+
if (!isPathInside(canonicalRepoRoot, canonicalCwd)) {
|
|
32637
|
+
throw new GitCommandError("path_outside_repo", "Git cwd is outside the repository root", {
|
|
32638
|
+
argv,
|
|
32639
|
+
cwd
|
|
32640
|
+
});
|
|
32641
|
+
}
|
|
32642
|
+
return execGitRaw(cwd, argv, options);
|
|
32643
|
+
}
|
|
32644
|
+
function normalizeGitOutput(value) {
|
|
32645
|
+
if (typeof value === "string") return value.replace(/\r\n/g, "\n");
|
|
32646
|
+
if (Buffer.isBuffer(value)) return value.toString("utf8").replace(/\r\n/g, "\n");
|
|
32647
|
+
if (value == null) return "";
|
|
32648
|
+
return String(value).replace(/\r\n/g, "\n");
|
|
32649
|
+
}
|
|
32650
|
+
function isPathInside(parent, child) {
|
|
32651
|
+
const relative3 = path5.relative(path5.resolve(parent), path5.resolve(child));
|
|
32652
|
+
return relative3 === "" || !relative3.startsWith("..") && !path5.isAbsolute(relative3);
|
|
32653
|
+
}
|
|
32654
|
+
async function validateWorkspace(workspace) {
|
|
32655
|
+
if (typeof workspace !== "string" || workspace.length === 0 || workspace.includes("\0")) {
|
|
32656
|
+
throw new GitCommandError("invalid_args", "Workspace must be a non-empty path");
|
|
32657
|
+
}
|
|
32658
|
+
if (!path5.isAbsolute(workspace)) {
|
|
32659
|
+
throw new GitCommandError("invalid_args", "Workspace must be an absolute path", { cwd: workspace });
|
|
32660
|
+
}
|
|
32661
|
+
const normalizedWorkspace = path5.resolve(workspace);
|
|
32662
|
+
try {
|
|
32663
|
+
const info = await (0, import_promises4.stat)(normalizedWorkspace);
|
|
32664
|
+
if (!info.isDirectory()) {
|
|
32665
|
+
throw new GitCommandError("invalid_args", "Workspace must be an existing directory", {
|
|
32666
|
+
cwd: normalizedWorkspace
|
|
32667
|
+
});
|
|
32668
|
+
}
|
|
32669
|
+
await (0, import_promises4.access)(normalizedWorkspace, import_node_fs3.constants.R_OK);
|
|
32670
|
+
} catch (error48) {
|
|
32671
|
+
if (error48 instanceof GitCommandError) throw error48;
|
|
32672
|
+
throw new GitCommandError("invalid_args", "Workspace must be an existing directory", {
|
|
32673
|
+
cwd: normalizedWorkspace,
|
|
32674
|
+
cause: error48
|
|
32675
|
+
});
|
|
32676
|
+
}
|
|
32677
|
+
return normalizedWorkspace;
|
|
32678
|
+
}
|
|
32679
|
+
function validateGitArgv(argv) {
|
|
32680
|
+
if (!Array.isArray(argv) || argv.length === 0) {
|
|
32681
|
+
throw new GitCommandError("invalid_args", "Git argv must be a non-empty string array", { argv });
|
|
32682
|
+
}
|
|
32683
|
+
for (const arg of argv) {
|
|
32684
|
+
if (typeof arg !== "string" || arg.length === 0 || arg.includes("\0")) {
|
|
32685
|
+
throw new GitCommandError("invalid_args", "Git argv contains an invalid argument", { argv });
|
|
32686
|
+
}
|
|
32687
|
+
}
|
|
32688
|
+
if (argv.includes("-C") || argv.some((arg) => arg.startsWith("--git-dir") || arg.startsWith("--work-tree"))) {
|
|
32689
|
+
throw new GitCommandError("invalid_args", "Git argv contains unsafe repository override arguments", {
|
|
32690
|
+
argv
|
|
32691
|
+
});
|
|
32692
|
+
}
|
|
32693
|
+
}
|
|
32694
|
+
async function execGitRaw(cwd, argv, options, behavior = {}) {
|
|
32695
|
+
validateGitArgv(argv);
|
|
32696
|
+
try {
|
|
32697
|
+
const result = await execFileAsync("git", [...argv], {
|
|
32698
|
+
cwd,
|
|
32699
|
+
encoding: "utf8",
|
|
32700
|
+
timeout: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
32701
|
+
maxBuffer: options.maxBuffer ?? DEFAULT_MAX_BUFFER,
|
|
32702
|
+
windowsHide: true
|
|
32703
|
+
});
|
|
32704
|
+
return {
|
|
32705
|
+
stdout: normalizeGitOutput(result.stdout),
|
|
32706
|
+
stderr: normalizeGitOutput(result.stderr)
|
|
32707
|
+
};
|
|
32708
|
+
} catch (error48) {
|
|
32709
|
+
throw mapExecError(error48, cwd, argv, behavior);
|
|
32710
|
+
}
|
|
32711
|
+
}
|
|
32712
|
+
function mapExecError(error48, cwd, argv, behavior) {
|
|
32713
|
+
const execError = error48;
|
|
32714
|
+
const stdout = normalizeGitOutput(execError.stdout);
|
|
32715
|
+
const stderr = normalizeGitOutput(execError.stderr);
|
|
32716
|
+
const code = execError.code;
|
|
32717
|
+
const signal = execError.signal;
|
|
32718
|
+
const message = [stderr.trim(), execError.message].filter(Boolean).join("\n");
|
|
32719
|
+
if (code === "ENOENT") {
|
|
32720
|
+
return new GitCommandError("git_not_installed", "Git executable was not found", {
|
|
32721
|
+
stdout,
|
|
32722
|
+
stderr,
|
|
32723
|
+
exitCode: code,
|
|
32724
|
+
signal,
|
|
32725
|
+
argv,
|
|
32726
|
+
cwd,
|
|
32727
|
+
cause: error48
|
|
32728
|
+
});
|
|
32729
|
+
}
|
|
32730
|
+
if (execError.killed || /timed out/i.test(execError.message)) {
|
|
32731
|
+
return new GitCommandError("timeout", "Git command timed out", {
|
|
32732
|
+
stdout,
|
|
32733
|
+
stderr,
|
|
32734
|
+
exitCode: code,
|
|
32735
|
+
signal,
|
|
32736
|
+
argv,
|
|
32737
|
+
cwd,
|
|
32738
|
+
cause: error48
|
|
32739
|
+
});
|
|
32740
|
+
}
|
|
32741
|
+
if (behavior.mapNotGitRepo && /not a git repository/i.test(stderr + "\n" + execError.message)) {
|
|
32742
|
+
return new GitCommandError("not_git_repo", "Workspace is not a Git repository", {
|
|
32743
|
+
stdout,
|
|
32744
|
+
stderr,
|
|
32745
|
+
exitCode: code,
|
|
32746
|
+
signal,
|
|
32747
|
+
argv,
|
|
32748
|
+
cwd,
|
|
32749
|
+
cause: error48
|
|
32750
|
+
});
|
|
32751
|
+
}
|
|
32752
|
+
return new GitCommandError("git_command_failed", message || "Git command failed", {
|
|
32753
|
+
stdout,
|
|
32754
|
+
stderr,
|
|
32755
|
+
exitCode: code,
|
|
32756
|
+
signal,
|
|
32757
|
+
argv,
|
|
32758
|
+
cwd,
|
|
32759
|
+
cause: error48
|
|
32760
|
+
});
|
|
32761
|
+
}
|
|
32762
|
+
async function getGitRepoStatus(workspace, options = {}) {
|
|
32763
|
+
const lastCheckedAt = Date.now();
|
|
32764
|
+
try {
|
|
32765
|
+
const repo = await resolveGitRepository(workspace, options);
|
|
32766
|
+
const statusOutput = await runGit(repo, ["status", "--porcelain=v2", "--branch"], options);
|
|
32767
|
+
const parsed = parsePorcelainV2Status(statusOutput.stdout);
|
|
32768
|
+
const head = await readHead(repo, options);
|
|
32769
|
+
const stashCount = await readStashCount(repo, options);
|
|
32770
|
+
return {
|
|
32771
|
+
workspace: repo.workspace,
|
|
32772
|
+
repoRoot: repo.repoRoot,
|
|
32773
|
+
isGitRepo: true,
|
|
32774
|
+
branch: parsed.branch,
|
|
32775
|
+
headCommit: head.commit,
|
|
32776
|
+
headMessage: head.message,
|
|
32777
|
+
upstream: parsed.upstream,
|
|
32778
|
+
ahead: parsed.ahead,
|
|
32779
|
+
behind: parsed.behind,
|
|
32780
|
+
staged: parsed.staged,
|
|
32781
|
+
modified: parsed.modified,
|
|
32782
|
+
untracked: parsed.untracked,
|
|
32783
|
+
deleted: parsed.deleted,
|
|
32784
|
+
renamed: parsed.renamed,
|
|
32785
|
+
hasConflicts: parsed.conflictFiles.length > 0,
|
|
32786
|
+
conflictFiles: parsed.conflictFiles,
|
|
32787
|
+
stashCount,
|
|
32788
|
+
lastCheckedAt
|
|
32789
|
+
};
|
|
32790
|
+
} catch (error48) {
|
|
32791
|
+
if (error48 instanceof GitCommandError) {
|
|
32792
|
+
return emptyStatus(workspace, lastCheckedAt, error48);
|
|
32793
|
+
}
|
|
32794
|
+
return emptyStatus(
|
|
32795
|
+
workspace,
|
|
32796
|
+
lastCheckedAt,
|
|
32797
|
+
new GitCommandError("git_command_failed", "Failed to read Git status", { cause: error48 })
|
|
32798
|
+
);
|
|
32799
|
+
}
|
|
32800
|
+
}
|
|
32801
|
+
function parsePorcelainV2Status(output) {
|
|
32802
|
+
const parsed = {
|
|
32803
|
+
branch: null,
|
|
32804
|
+
upstream: null,
|
|
32805
|
+
ahead: 0,
|
|
32806
|
+
behind: 0,
|
|
32807
|
+
staged: 0,
|
|
32808
|
+
modified: 0,
|
|
32809
|
+
untracked: 0,
|
|
32810
|
+
deleted: 0,
|
|
32811
|
+
renamed: 0,
|
|
32812
|
+
conflictFiles: []
|
|
32813
|
+
};
|
|
32814
|
+
for (const line of output.split("\n")) {
|
|
32815
|
+
if (!line) continue;
|
|
32816
|
+
if (line.startsWith("# branch.head ")) {
|
|
32817
|
+
const branch = line.slice("# branch.head ".length).trim();
|
|
32818
|
+
parsed.branch = branch && branch !== "(detached)" ? branch : null;
|
|
32819
|
+
continue;
|
|
32820
|
+
}
|
|
32821
|
+
if (line.startsWith("# branch.upstream ")) {
|
|
32822
|
+
parsed.upstream = line.slice("# branch.upstream ".length).trim() || null;
|
|
32823
|
+
continue;
|
|
32824
|
+
}
|
|
32825
|
+
if (line.startsWith("# branch.ab ")) {
|
|
32826
|
+
const match = line.match(/\+(-?\d+)\s+-(-?\d+)/);
|
|
32827
|
+
if (match) {
|
|
32828
|
+
parsed.ahead = Number.parseInt(match[1] ?? "0", 10) || 0;
|
|
32829
|
+
parsed.behind = Number.parseInt(match[2] ?? "0", 10) || 0;
|
|
32830
|
+
}
|
|
32831
|
+
continue;
|
|
32832
|
+
}
|
|
32833
|
+
if (line.startsWith("? ")) {
|
|
32834
|
+
parsed.untracked += 1;
|
|
32835
|
+
continue;
|
|
32836
|
+
}
|
|
32837
|
+
if (line.startsWith("u ")) {
|
|
32838
|
+
const fields = line.split(" ");
|
|
32839
|
+
const filePath = fields.slice(10).join(" ");
|
|
32840
|
+
if (filePath) parsed.conflictFiles.push(filePath);
|
|
32841
|
+
continue;
|
|
32842
|
+
}
|
|
32843
|
+
if (line.startsWith("1 ") || line.startsWith("2 ")) {
|
|
32844
|
+
const fields = line.split(" ");
|
|
32845
|
+
const xy = fields[1] ?? "..";
|
|
32846
|
+
const indexStatus = xy[0] ?? ".";
|
|
32847
|
+
const worktreeStatus = xy[1] ?? ".";
|
|
32848
|
+
if (isStagedStatus(indexStatus)) parsed.staged += 1;
|
|
32849
|
+
if (worktreeStatus === "M" || worktreeStatus === "T") parsed.modified += 1;
|
|
32850
|
+
if (indexStatus === "D" || worktreeStatus === "D") parsed.deleted += 1;
|
|
32851
|
+
if (indexStatus === "R" || worktreeStatus === "R") parsed.renamed += 1;
|
|
32852
|
+
if (xy.includes("U")) {
|
|
32853
|
+
const filePath = fields.slice(line.startsWith("2 ") ? 9 : 8).join(" ").split(" ")[0] ?? "";
|
|
32854
|
+
if (filePath) parsed.conflictFiles.push(filePath);
|
|
32855
|
+
}
|
|
32856
|
+
}
|
|
32857
|
+
}
|
|
32858
|
+
parsed.conflictFiles = Array.from(new Set(parsed.conflictFiles));
|
|
32859
|
+
return parsed;
|
|
32860
|
+
}
|
|
32861
|
+
async function readHead(repo, options) {
|
|
32862
|
+
try {
|
|
32863
|
+
const result = await runGit(repo, ["log", "-1", "--pretty=%h%x00%s"], options);
|
|
32864
|
+
const text = result.stdout.trimEnd();
|
|
32865
|
+
if (!text) return { commit: null, message: null };
|
|
32866
|
+
const [commit, ...messageParts] = text.split("\0");
|
|
32867
|
+
return {
|
|
32868
|
+
commit: commit || null,
|
|
32869
|
+
message: messageParts.join("\0") || null
|
|
32870
|
+
};
|
|
32871
|
+
} catch {
|
|
32872
|
+
return { commit: null, message: null };
|
|
32873
|
+
}
|
|
32874
|
+
}
|
|
32875
|
+
async function readStashCount(repo, options) {
|
|
32876
|
+
try {
|
|
32877
|
+
const result = await runGit(repo, ["stash", "list", "--format=%gd"], options);
|
|
32878
|
+
return result.stdout.split("\n").filter((line) => line.trim().length > 0).length;
|
|
32879
|
+
} catch {
|
|
32880
|
+
return 0;
|
|
32881
|
+
}
|
|
32882
|
+
}
|
|
32883
|
+
function isStagedStatus(status) {
|
|
32884
|
+
return status !== "." && status !== "?" && status !== "U";
|
|
32885
|
+
}
|
|
32886
|
+
function emptyStatus(workspace, lastCheckedAt, error48) {
|
|
32887
|
+
return {
|
|
32888
|
+
workspace,
|
|
32889
|
+
repoRoot: null,
|
|
32890
|
+
isGitRepo: false,
|
|
32891
|
+
branch: null,
|
|
32892
|
+
headCommit: null,
|
|
32893
|
+
headMessage: null,
|
|
32894
|
+
upstream: null,
|
|
32895
|
+
ahead: 0,
|
|
32896
|
+
behind: 0,
|
|
32897
|
+
staged: 0,
|
|
32898
|
+
modified: 0,
|
|
32899
|
+
untracked: 0,
|
|
32900
|
+
deleted: 0,
|
|
32901
|
+
renamed: 0,
|
|
32902
|
+
hasConflicts: false,
|
|
32903
|
+
conflictFiles: [],
|
|
32904
|
+
stashCount: 0,
|
|
32905
|
+
lastCheckedAt,
|
|
32906
|
+
error: error48.stderr || error48.message,
|
|
32907
|
+
reason: error48.reason
|
|
32908
|
+
};
|
|
32909
|
+
}
|
|
32910
|
+
var import_promises22 = require("fs/promises");
|
|
32911
|
+
var path23 = __toESM2(require("path"));
|
|
32912
|
+
var DEFAULT_MAX_FILES = 200;
|
|
32913
|
+
var DEFAULT_MAX_BYTES = 2e5;
|
|
32914
|
+
async function getGitDiffSummary(workspace, options = {}) {
|
|
32915
|
+
const lastCheckedAt = Date.now();
|
|
32916
|
+
try {
|
|
32917
|
+
const repo = await resolveGitRepository(workspace, options);
|
|
32918
|
+
const repoRoot = repo.repoRoot;
|
|
32919
|
+
const [unstagedNameStatus, unstagedNumstat, stagedNameStatus, stagedNumstat, untracked] = await Promise.all([
|
|
32920
|
+
runGit(repo, ["diff", "--no-ext-diff", "--name-status"], { ...options, cwd: repoRoot }),
|
|
32921
|
+
runGit(repo, ["diff", "--no-ext-diff", "--numstat"], { ...options, cwd: repoRoot }),
|
|
32922
|
+
runGit(repo, ["diff", "--cached", "--no-ext-diff", "--name-status"], { ...options, cwd: repoRoot }),
|
|
32923
|
+
runGit(repo, ["diff", "--cached", "--no-ext-diff", "--numstat"], { ...options, cwd: repoRoot }),
|
|
32924
|
+
runGit(repo, ["ls-files", "--others", "--exclude-standard"], { ...options, cwd: repoRoot })
|
|
32925
|
+
]);
|
|
32926
|
+
const outputBytes = byteLength(
|
|
32927
|
+
unstagedNameStatus.stdout + unstagedNumstat.stdout + stagedNameStatus.stdout + stagedNumstat.stdout + untracked.stdout
|
|
32928
|
+
);
|
|
32929
|
+
const changes = [
|
|
32930
|
+
...combineDiffEntries(unstagedNameStatus.stdout, unstagedNumstat.stdout, false),
|
|
32931
|
+
...combineDiffEntries(stagedNameStatus.stdout, stagedNumstat.stdout, true),
|
|
32932
|
+
...parseUntrackedFiles(untracked.stdout)
|
|
32933
|
+
];
|
|
32934
|
+
const maxFiles = normalizePositiveInteger(options.maxFiles, DEFAULT_MAX_FILES);
|
|
32935
|
+
const maxBytes = normalizePositiveInteger(options.maxBytes, DEFAULT_MAX_BYTES);
|
|
32936
|
+
const files = changes.slice(0, maxFiles);
|
|
32937
|
+
const truncated = changes.length > files.length || outputBytes > maxBytes;
|
|
32938
|
+
return {
|
|
32939
|
+
workspace: repo.workspace,
|
|
32940
|
+
repoRoot,
|
|
32941
|
+
isGitRepo: true,
|
|
32942
|
+
files,
|
|
32943
|
+
totalInsertions: files.reduce((sum, file2) => sum + file2.insertions, 0),
|
|
32944
|
+
totalDeletions: files.reduce((sum, file2) => sum + file2.deletions, 0),
|
|
32945
|
+
truncated,
|
|
32946
|
+
lastCheckedAt
|
|
32947
|
+
};
|
|
32948
|
+
} catch (error48) {
|
|
32949
|
+
const gitError = error48 instanceof GitCommandError ? error48 : new GitCommandError("git_command_failed", "Failed to read Git diff summary", { cause: error48 });
|
|
32950
|
+
return {
|
|
32951
|
+
workspace,
|
|
32952
|
+
repoRoot: null,
|
|
32953
|
+
isGitRepo: false,
|
|
32954
|
+
files: [],
|
|
32955
|
+
totalInsertions: 0,
|
|
32956
|
+
totalDeletions: 0,
|
|
32957
|
+
truncated: false,
|
|
32958
|
+
lastCheckedAt,
|
|
32959
|
+
error: gitError.stderr || gitError.message,
|
|
32960
|
+
reason: gitError.reason
|
|
32961
|
+
};
|
|
32962
|
+
}
|
|
32963
|
+
}
|
|
32964
|
+
async function getGitFileDiff(workspace, filePath, options = {}) {
|
|
32965
|
+
const lastCheckedAt = Date.now();
|
|
32966
|
+
const repo = await resolveGitRepository(workspace, options);
|
|
32967
|
+
const repoRoot = repo.repoRoot;
|
|
32968
|
+
const selected = await resolveRepoFilePath(repoRoot, filePath);
|
|
32969
|
+
const maxBytes = normalizePositiveInteger(options.maxBytes, DEFAULT_MAX_BYTES);
|
|
32970
|
+
const [unstaged, staged] = await Promise.all([
|
|
32971
|
+
runGit(repo, ["diff", "--no-ext-diff", "--", selected.relativePath], { ...options, cwd: repoRoot }),
|
|
32972
|
+
runGit(repo, ["diff", "--cached", "--no-ext-diff", "--", selected.relativePath], { ...options, cwd: repoRoot })
|
|
32973
|
+
]);
|
|
32974
|
+
let diff = [unstaged.stdout, staged.stdout].filter((part) => part.length > 0).join("\n");
|
|
32975
|
+
if (!diff) {
|
|
32976
|
+
const untracked = await runGit(repo, ["ls-files", "--others", "--exclude-standard", "--", selected.relativePath], {
|
|
32977
|
+
...options,
|
|
32978
|
+
cwd: repoRoot
|
|
32979
|
+
});
|
|
32980
|
+
const untrackedFiles = untracked.stdout.split("\n").filter(Boolean);
|
|
32981
|
+
if (untrackedFiles.includes(selected.relativePath)) {
|
|
32982
|
+
diff = await buildUntrackedDiff(selected.absolutePath, selected.relativePath, maxBytes + 1);
|
|
32983
|
+
}
|
|
32984
|
+
}
|
|
32985
|
+
const bounded = truncateText(diff, maxBytes);
|
|
32986
|
+
return {
|
|
32987
|
+
workspace: repo.workspace,
|
|
32988
|
+
repoRoot,
|
|
32989
|
+
isGitRepo: true,
|
|
32990
|
+
path: selected.relativePath,
|
|
32991
|
+
diff: bounded.text,
|
|
32992
|
+
truncated: bounded.truncated,
|
|
32993
|
+
lastCheckedAt
|
|
32994
|
+
};
|
|
32995
|
+
}
|
|
32996
|
+
function combineDiffEntries(nameStatusOutput, numstatOutput, staged) {
|
|
32997
|
+
const statusEntries = parseNameStatus(nameStatusOutput);
|
|
32998
|
+
const numstatEntries = parseNumstat(numstatOutput);
|
|
32999
|
+
return statusEntries.map((entry, index) => {
|
|
33000
|
+
const stats = numstatEntries[index];
|
|
33001
|
+
return {
|
|
33002
|
+
path: entry.path,
|
|
33003
|
+
oldPath: entry.oldPath,
|
|
33004
|
+
status: entry.status,
|
|
33005
|
+
staged,
|
|
33006
|
+
insertions: stats?.insertions ?? 0,
|
|
33007
|
+
deletions: stats?.deletions ?? 0,
|
|
33008
|
+
binary: stats?.binary || void 0
|
|
33009
|
+
};
|
|
33010
|
+
});
|
|
33011
|
+
}
|
|
33012
|
+
function parseNameStatus(output) {
|
|
33013
|
+
return output.split("\n").filter(Boolean).map((line) => {
|
|
33014
|
+
const fields = line.split(" ");
|
|
33015
|
+
const code = fields[0] ?? "";
|
|
33016
|
+
const statusLetter = code[0] ?? "M";
|
|
33017
|
+
if (statusLetter === "R") {
|
|
33018
|
+
return {
|
|
33019
|
+
oldPath: fields[1] ?? "",
|
|
33020
|
+
path: fields[2] ?? fields[1] ?? "",
|
|
33021
|
+
status: "renamed"
|
|
33022
|
+
};
|
|
33023
|
+
}
|
|
33024
|
+
if (statusLetter === "C") {
|
|
33025
|
+
return {
|
|
33026
|
+
oldPath: fields[1] ?? "",
|
|
33027
|
+
path: fields[2] ?? fields[1] ?? "",
|
|
33028
|
+
status: "copied"
|
|
33029
|
+
};
|
|
33030
|
+
}
|
|
33031
|
+
return {
|
|
33032
|
+
path: fields[1] ?? "",
|
|
33033
|
+
status: mapNameStatus(statusLetter)
|
|
33034
|
+
};
|
|
33035
|
+
}).filter((entry) => entry.path.length > 0);
|
|
33036
|
+
}
|
|
33037
|
+
function parseNumstat(output) {
|
|
33038
|
+
return output.split("\n").filter(Boolean).map((line) => {
|
|
33039
|
+
const fields = line.split(" ");
|
|
33040
|
+
const insertionsText = fields[0] ?? "0";
|
|
33041
|
+
const deletionsText = fields[1] ?? "0";
|
|
33042
|
+
const binary = insertionsText === "-" || deletionsText === "-";
|
|
33043
|
+
return {
|
|
33044
|
+
path: fields.slice(2).join(" "),
|
|
33045
|
+
insertions: binary ? 0 : Number.parseInt(insertionsText, 10) || 0,
|
|
33046
|
+
deletions: binary ? 0 : Number.parseInt(deletionsText, 10) || 0,
|
|
33047
|
+
binary
|
|
33048
|
+
};
|
|
33049
|
+
});
|
|
33050
|
+
}
|
|
33051
|
+
function parseUntrackedFiles(output) {
|
|
33052
|
+
return output.split("\n").filter(Boolean).map((filePath) => ({
|
|
33053
|
+
path: filePath,
|
|
33054
|
+
status: "untracked",
|
|
33055
|
+
staged: false,
|
|
33056
|
+
insertions: 0,
|
|
33057
|
+
deletions: 0
|
|
33058
|
+
}));
|
|
33059
|
+
}
|
|
33060
|
+
function mapNameStatus(status) {
|
|
33061
|
+
switch (status) {
|
|
33062
|
+
case "A":
|
|
33063
|
+
return "added";
|
|
33064
|
+
case "D":
|
|
33065
|
+
return "deleted";
|
|
33066
|
+
case "R":
|
|
33067
|
+
return "renamed";
|
|
33068
|
+
case "C":
|
|
33069
|
+
return "copied";
|
|
33070
|
+
case "U":
|
|
33071
|
+
return "conflict";
|
|
33072
|
+
case "M":
|
|
33073
|
+
case "T":
|
|
33074
|
+
default:
|
|
33075
|
+
return "modified";
|
|
33076
|
+
}
|
|
33077
|
+
}
|
|
33078
|
+
async function resolveRepoFilePath(repoRoot, filePath) {
|
|
33079
|
+
if (typeof filePath !== "string" || filePath.length === 0 || filePath.includes("\0")) {
|
|
33080
|
+
throw new GitCommandError("invalid_args", "File path must be a non-empty path");
|
|
33081
|
+
}
|
|
33082
|
+
const canonicalRepoRoot = await (0, import_promises22.realpath)(repoRoot).catch(() => path23.resolve(repoRoot));
|
|
33083
|
+
const absolutePath = path23.isAbsolute(filePath) ? path23.resolve(filePath) : path23.resolve(repoRoot, filePath);
|
|
33084
|
+
const checkPath = await (0, import_promises22.realpath)(absolutePath).catch(() => absolutePath);
|
|
33085
|
+
const relativeBase = isPathInside(canonicalRepoRoot, checkPath) ? canonicalRepoRoot : path23.resolve(repoRoot);
|
|
33086
|
+
if (!isPathInside(canonicalRepoRoot, checkPath) && !isPathInside(repoRoot, absolutePath)) {
|
|
33087
|
+
throw new GitCommandError("path_outside_repo", "Selected file path is outside the repository root", {
|
|
33088
|
+
cwd: repoRoot
|
|
33089
|
+
});
|
|
33090
|
+
}
|
|
33091
|
+
const relativePath = path23.relative(relativeBase, checkPath).split(path23.sep).join("/");
|
|
33092
|
+
if (!relativePath || relativePath.startsWith("..") || path23.isAbsolute(relativePath)) {
|
|
33093
|
+
throw new GitCommandError("path_outside_repo", "Selected file path is outside the repository root", {
|
|
33094
|
+
cwd: repoRoot
|
|
33095
|
+
});
|
|
33096
|
+
}
|
|
33097
|
+
return { absolutePath, relativePath };
|
|
33098
|
+
}
|
|
33099
|
+
async function buildUntrackedDiff(absolutePath, relativePath, readLimit) {
|
|
33100
|
+
const content = await (0, import_promises22.readFile)(absolutePath, "utf8");
|
|
33101
|
+
const limitedContent = content.length > readLimit ? content.slice(0, readLimit) : content;
|
|
33102
|
+
const lines = limitedContent.length > 0 ? limitedContent.split("\n") : [];
|
|
33103
|
+
const plusLines = lines.filter((line, index) => index < lines.length - 1 || line.length > 0).map((line) => `+${line}`).join("\n");
|
|
33104
|
+
const lineCount = plusLines ? plusLines.split("\n").length : 0;
|
|
33105
|
+
return [
|
|
33106
|
+
`diff --git a/${relativePath} b/${relativePath}`,
|
|
33107
|
+
"new file mode 100644",
|
|
33108
|
+
"index 0000000..0000000",
|
|
33109
|
+
"--- /dev/null",
|
|
33110
|
+
`+++ b/${relativePath}`,
|
|
33111
|
+
`@@ -0,0 +1,${lineCount} @@`,
|
|
33112
|
+
plusLines
|
|
33113
|
+
].filter((line) => line.length > 0).join("\n");
|
|
33114
|
+
}
|
|
33115
|
+
function truncateText(text, maxBytes) {
|
|
33116
|
+
if (byteLength(text) <= maxBytes) return { text, truncated: false };
|
|
33117
|
+
return { text: Buffer.from(text, "utf8").subarray(0, maxBytes).toString("utf8"), truncated: true };
|
|
33118
|
+
}
|
|
33119
|
+
function byteLength(text) {
|
|
33120
|
+
return Buffer.byteLength(text, "utf8");
|
|
33121
|
+
}
|
|
33122
|
+
function normalizePositiveInteger(value, fallback) {
|
|
33123
|
+
if (!Number.isFinite(value) || value == null || value <= 0) return fallback;
|
|
33124
|
+
return Math.floor(value);
|
|
33125
|
+
}
|
|
33126
|
+
function countStatusChangedFiles(status) {
|
|
33127
|
+
const conflictCount = status.conflictFiles.length > 0 ? status.conflictFiles.length : status.hasConflicts ? 1 : 0;
|
|
33128
|
+
return status.staged + status.modified + status.untracked + status.deleted + status.renamed + conflictCount;
|
|
33129
|
+
}
|
|
33130
|
+
function createGitCompactSummary(status, diffSummary) {
|
|
33131
|
+
const statusChangedFiles = countStatusChangedFiles(status);
|
|
33132
|
+
const diffChangedFiles = diffSummary?.files.length ?? 0;
|
|
33133
|
+
const changedFiles = Math.max(statusChangedFiles, diffChangedFiles);
|
|
33134
|
+
const conflictCount = status.conflictFiles.length > 0 ? status.conflictFiles.length : status.hasConflicts ? 1 : 0;
|
|
33135
|
+
return {
|
|
33136
|
+
isGitRepo: status.isGitRepo,
|
|
33137
|
+
repoRoot: status.repoRoot,
|
|
33138
|
+
branch: status.branch,
|
|
33139
|
+
dirty: status.staged > 0 || status.modified > 0 || status.untracked > 0 || status.deleted > 0 || status.renamed > 0 || conflictCount > 0 || changedFiles > 0,
|
|
33140
|
+
changedFiles,
|
|
33141
|
+
ahead: status.ahead,
|
|
33142
|
+
behind: status.behind,
|
|
33143
|
+
hasConflicts: status.hasConflicts || conflictCount > 0,
|
|
33144
|
+
lastCheckedAt: Math.max(status.lastCheckedAt, diffSummary?.lastCheckedAt ?? status.lastCheckedAt),
|
|
33145
|
+
error: status.error ?? diffSummary?.error,
|
|
33146
|
+
reason: status.reason ?? diffSummary?.reason
|
|
33147
|
+
};
|
|
33148
|
+
}
|
|
33149
|
+
var summarizeGitStatus = createGitCompactSummary;
|
|
33150
|
+
function normalizeCapacity(capacity) {
|
|
33151
|
+
return Math.max(1, Math.floor(capacity ?? 100));
|
|
33152
|
+
}
|
|
33153
|
+
function createEmptyDiffSummary(status) {
|
|
33154
|
+
return {
|
|
33155
|
+
workspace: status.workspace,
|
|
33156
|
+
repoRoot: status.repoRoot,
|
|
33157
|
+
isGitRepo: status.isGitRepo,
|
|
33158
|
+
files: [],
|
|
33159
|
+
totalInsertions: 0,
|
|
33160
|
+
totalDeletions: 0,
|
|
33161
|
+
truncated: false,
|
|
33162
|
+
lastCheckedAt: status.lastCheckedAt,
|
|
33163
|
+
error: status.error,
|
|
33164
|
+
reason: status.reason
|
|
33165
|
+
};
|
|
33166
|
+
}
|
|
33167
|
+
function changedFileKey(file2) {
|
|
33168
|
+
return `${file2.oldPath ?? ""}\0${file2.path}`;
|
|
33169
|
+
}
|
|
33170
|
+
function uniqueSorted(values) {
|
|
33171
|
+
return Array.from(new Set(Array.from(values).filter(Boolean))).sort((a, b2) => a.localeCompare(b2));
|
|
33172
|
+
}
|
|
33173
|
+
function plural(count, singular, pluralText = `${singular}s`) {
|
|
33174
|
+
return count === 1 ? singular : pluralText;
|
|
33175
|
+
}
|
|
33176
|
+
function compareGitSnapshots(before, after) {
|
|
33177
|
+
const beforeFileKeys = new Set(before.diffSummary.files.map(changedFileKey));
|
|
33178
|
+
const changedAfterFiles = after.diffSummary.files.filter((file2) => !beforeFileKeys.has(changedFileKey(file2)));
|
|
33179
|
+
const addedFiles = [];
|
|
33180
|
+
const modifiedFiles = [];
|
|
33181
|
+
const deletedFiles = [];
|
|
33182
|
+
const renamedFiles = [];
|
|
33183
|
+
const untrackedFiles = [];
|
|
33184
|
+
const conflictFilesFromDiff = [];
|
|
33185
|
+
let totalInsertions = 0;
|
|
33186
|
+
let totalDeletions = 0;
|
|
33187
|
+
for (const file2 of changedAfterFiles) {
|
|
33188
|
+
totalInsertions += file2.insertions;
|
|
33189
|
+
totalDeletions += file2.deletions;
|
|
33190
|
+
switch (file2.status) {
|
|
33191
|
+
case "added":
|
|
33192
|
+
case "copied":
|
|
33193
|
+
addedFiles.push(file2.path);
|
|
33194
|
+
break;
|
|
33195
|
+
case "modified":
|
|
33196
|
+
modifiedFiles.push(file2.path);
|
|
33197
|
+
break;
|
|
33198
|
+
case "deleted":
|
|
33199
|
+
deletedFiles.push(file2.path);
|
|
33200
|
+
break;
|
|
33201
|
+
case "renamed":
|
|
33202
|
+
renamedFiles.push({ oldPath: file2.oldPath ?? file2.path, path: file2.path });
|
|
33203
|
+
break;
|
|
33204
|
+
case "untracked":
|
|
33205
|
+
untrackedFiles.push(file2.path);
|
|
33206
|
+
break;
|
|
33207
|
+
case "conflict":
|
|
33208
|
+
conflictFilesFromDiff.push(file2.path);
|
|
33209
|
+
break;
|
|
33210
|
+
}
|
|
33211
|
+
}
|
|
33212
|
+
renamedFiles.sort((a, b2) => `${a.oldPath}\0${a.path}`.localeCompare(`${b2.oldPath}\0${b2.path}`));
|
|
33213
|
+
const conflictFiles = uniqueSorted([...after.status.conflictFiles, ...conflictFilesFromDiff]);
|
|
33214
|
+
const changedFiles = changedAfterFiles.length;
|
|
33215
|
+
const hasConflicts = after.status.hasConflicts || conflictFiles.length > 0;
|
|
33216
|
+
const summaryParts = [];
|
|
33217
|
+
if (changedFiles > 0) summaryParts.push(`${changedFiles} ${plural(changedFiles, "file")} changed`);
|
|
33218
|
+
if (addedFiles.length > 0) summaryParts.push(`${addedFiles.length} added`);
|
|
33219
|
+
if (modifiedFiles.length > 0) summaryParts.push(`${modifiedFiles.length} modified`);
|
|
33220
|
+
if (deletedFiles.length > 0) summaryParts.push(`${deletedFiles.length} deleted`);
|
|
33221
|
+
if (renamedFiles.length > 0) summaryParts.push(`${renamedFiles.length} renamed`);
|
|
33222
|
+
if (untrackedFiles.length > 0) summaryParts.push(`${untrackedFiles.length} untracked`);
|
|
33223
|
+
if (hasConflicts) summaryParts.push(`${conflictFiles.length || 1} ${plural(conflictFiles.length || 1, "conflict")}`);
|
|
33224
|
+
return {
|
|
33225
|
+
beforeSnapshotId: before.id,
|
|
33226
|
+
afterSnapshotId: after.id,
|
|
33227
|
+
workspace: after.workspace,
|
|
33228
|
+
repoRoot: after.repoRoot,
|
|
33229
|
+
changedFiles,
|
|
33230
|
+
addedFiles: uniqueSorted(addedFiles),
|
|
33231
|
+
modifiedFiles: uniqueSorted(modifiedFiles),
|
|
33232
|
+
deletedFiles: uniqueSorted(deletedFiles),
|
|
33233
|
+
renamedFiles,
|
|
33234
|
+
untrackedFiles: uniqueSorted(untrackedFiles),
|
|
33235
|
+
conflictFiles,
|
|
33236
|
+
totalInsertions,
|
|
33237
|
+
totalDeletions,
|
|
33238
|
+
hasConflicts,
|
|
33239
|
+
currentStatus: after.status,
|
|
33240
|
+
summaryText: summaryParts.length > 0 ? summaryParts.join(", ") : "No file-set changes between snapshots."
|
|
33241
|
+
};
|
|
33242
|
+
}
|
|
33243
|
+
var InMemoryGitSnapshotStore = class {
|
|
33244
|
+
snapshots = /* @__PURE__ */ new Map();
|
|
33245
|
+
order = [];
|
|
33246
|
+
capacity;
|
|
33247
|
+
now;
|
|
33248
|
+
idPrefix;
|
|
33249
|
+
getStatusProvider;
|
|
33250
|
+
getDiffSummaryProvider;
|
|
33251
|
+
counter = 0;
|
|
33252
|
+
constructor(options = {}) {
|
|
33253
|
+
this.capacity = normalizeCapacity(options.capacity);
|
|
33254
|
+
this.now = options.now ?? Date.now;
|
|
33255
|
+
this.idPrefix = options.idPrefix ?? "git-snapshot";
|
|
33256
|
+
this.getStatusProvider = options.getStatus;
|
|
33257
|
+
this.getDiffSummaryProvider = options.getDiffSummary;
|
|
33258
|
+
}
|
|
33259
|
+
async create(input) {
|
|
33260
|
+
const getStatus = input.getStatus ?? this.getStatusProvider;
|
|
33261
|
+
if (!getStatus) {
|
|
33262
|
+
throw new Error("GitSnapshotStore requires an injected getStatus provider");
|
|
33263
|
+
}
|
|
33264
|
+
const status = await getStatus(input.workspace);
|
|
33265
|
+
const getDiffSummary = input.getDiffSummary ?? this.getDiffSummaryProvider;
|
|
33266
|
+
const diffSummary = getDiffSummary ? await getDiffSummary(input.workspace, status) : createEmptyDiffSummary(status);
|
|
33267
|
+
const createdAt = this.now();
|
|
33268
|
+
const id = `${this.idPrefix}-${createdAt}-${++this.counter}`;
|
|
33269
|
+
const snapshot = {
|
|
33270
|
+
id,
|
|
33271
|
+
workspace: input.workspace,
|
|
33272
|
+
repoRoot: status.repoRoot ?? input.workspace,
|
|
33273
|
+
sessionId: input.sessionId,
|
|
33274
|
+
turnId: input.turnId,
|
|
33275
|
+
reason: input.reason,
|
|
33276
|
+
status,
|
|
33277
|
+
diffSummary,
|
|
33278
|
+
createdAt
|
|
33279
|
+
};
|
|
33280
|
+
this.snapshots.set(id, snapshot);
|
|
33281
|
+
this.order.push(id);
|
|
33282
|
+
this.enforceCapacity();
|
|
33283
|
+
return snapshot;
|
|
33284
|
+
}
|
|
33285
|
+
get(id) {
|
|
33286
|
+
return this.snapshots.get(id);
|
|
33287
|
+
}
|
|
33288
|
+
compare(beforeSnapshotId, afterSnapshotId) {
|
|
33289
|
+
const before = this.snapshots.get(beforeSnapshotId);
|
|
33290
|
+
if (!before) throw new Error(`Unknown before snapshot: ${beforeSnapshotId}`);
|
|
33291
|
+
const after = this.snapshots.get(afterSnapshotId);
|
|
33292
|
+
if (!after) throw new Error(`Unknown after snapshot: ${afterSnapshotId}`);
|
|
33293
|
+
return compareGitSnapshots(before, after);
|
|
33294
|
+
}
|
|
33295
|
+
list(query = {}) {
|
|
33296
|
+
const limit = Math.max(1, Math.floor(query.limit ?? this.capacity));
|
|
33297
|
+
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);
|
|
33298
|
+
}
|
|
33299
|
+
clear() {
|
|
33300
|
+
this.snapshots.clear();
|
|
33301
|
+
this.order.splice(0, this.order.length);
|
|
33302
|
+
}
|
|
33303
|
+
enforceCapacity() {
|
|
33304
|
+
while (this.order.length > this.capacity) {
|
|
33305
|
+
const evictedId = this.order.shift();
|
|
33306
|
+
if (evictedId) this.snapshots.delete(evictedId);
|
|
33307
|
+
}
|
|
33308
|
+
}
|
|
33309
|
+
};
|
|
33310
|
+
function createGitSnapshotStore(options = {}) {
|
|
33311
|
+
return new InMemoryGitSnapshotStore(options);
|
|
33312
|
+
}
|
|
33313
|
+
var DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS = 5e3;
|
|
33314
|
+
var MIN_GIT_WORKSPACE_POLL_INTERVAL_MS = 1e3;
|
|
33315
|
+
function defaultStatusProvider(workspace) {
|
|
33316
|
+
return getGitRepoStatus(workspace);
|
|
33317
|
+
}
|
|
33318
|
+
function defaultDiffSummaryProvider(workspace) {
|
|
33319
|
+
return getGitDiffSummary(workspace);
|
|
33320
|
+
}
|
|
33321
|
+
function normalizeIntervalMs(value, defaultIntervalMs, minIntervalMs) {
|
|
33322
|
+
const requested = Number.isFinite(value) ? Math.floor(value) : defaultIntervalMs;
|
|
33323
|
+
return Math.max(minIntervalMs, requested > 0 ? requested : defaultIntervalMs);
|
|
33324
|
+
}
|
|
33325
|
+
function normalizeGitWorkspaceSubscriptionParams2(params, options = {}) {
|
|
33326
|
+
const minIntervalMs = Math.max(1, Math.floor(options.minIntervalMs ?? MIN_GIT_WORKSPACE_POLL_INTERVAL_MS));
|
|
33327
|
+
const defaultIntervalMs = Math.max(minIntervalMs, Math.floor(options.defaultIntervalMs ?? DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS));
|
|
33328
|
+
return {
|
|
33329
|
+
workspace: params.workspace,
|
|
33330
|
+
includeDiffSummary: Boolean(params.includeDiffSummary),
|
|
33331
|
+
intervalMs: normalizeIntervalMs(params.intervalMs, defaultIntervalMs, minIntervalMs)
|
|
33332
|
+
};
|
|
33333
|
+
}
|
|
33334
|
+
var GitWorkspaceMonitor = class {
|
|
33335
|
+
getStatusProvider;
|
|
33336
|
+
getDiffSummaryProvider;
|
|
33337
|
+
now;
|
|
33338
|
+
minIntervalMs;
|
|
33339
|
+
defaultIntervalMs;
|
|
33340
|
+
keyPrefix;
|
|
33341
|
+
cache = /* @__PURE__ */ new Map();
|
|
33342
|
+
listeners = /* @__PURE__ */ new Set();
|
|
33343
|
+
seq = 0;
|
|
33344
|
+
constructor(options = {}) {
|
|
33345
|
+
this.getStatusProvider = options.getStatus ?? defaultStatusProvider;
|
|
33346
|
+
this.getDiffSummaryProvider = options.getDiffSummary ?? defaultDiffSummaryProvider;
|
|
33347
|
+
this.now = options.now ?? Date.now;
|
|
33348
|
+
this.minIntervalMs = Math.max(1, Math.floor(options.minIntervalMs ?? MIN_GIT_WORKSPACE_POLL_INTERVAL_MS));
|
|
33349
|
+
this.defaultIntervalMs = Math.max(
|
|
33350
|
+
this.minIntervalMs,
|
|
33351
|
+
Math.floor(options.defaultIntervalMs ?? DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS)
|
|
33352
|
+
);
|
|
33353
|
+
this.keyPrefix = options.keyPrefix ?? "git";
|
|
33354
|
+
}
|
|
33355
|
+
async refresh(params) {
|
|
33356
|
+
const normalized = this.normalize(typeof params === "string" ? { workspace: params } : params);
|
|
33357
|
+
const status = await this.getStatusProvider(normalized.workspace);
|
|
33358
|
+
const diffSummary = normalized.includeDiffSummary ? await this.getDiffSummaryProvider(normalized.workspace, status) : void 0;
|
|
33359
|
+
const compactSummary = createGitCompactSummary(status, diffSummary);
|
|
33360
|
+
const timestamp = this.now();
|
|
33361
|
+
const seq = ++this.seq;
|
|
33362
|
+
const key = this.keyForWorkspace(normalized.workspace);
|
|
33363
|
+
const update = {
|
|
33364
|
+
topic: "workspace.git",
|
|
33365
|
+
key,
|
|
33366
|
+
workspace: normalized.workspace,
|
|
33367
|
+
status,
|
|
33368
|
+
diffSummary,
|
|
33369
|
+
seq,
|
|
33370
|
+
timestamp
|
|
33371
|
+
};
|
|
33372
|
+
const cacheEntry = {
|
|
33373
|
+
key,
|
|
33374
|
+
workspace: normalized.workspace,
|
|
33375
|
+
status,
|
|
33376
|
+
diffSummary,
|
|
33377
|
+
compactSummary,
|
|
33378
|
+
seq,
|
|
33379
|
+
timestamp
|
|
33380
|
+
};
|
|
33381
|
+
this.cache.set(normalized.workspace, cacheEntry);
|
|
33382
|
+
this.emit(update, cacheEntry);
|
|
33383
|
+
return update;
|
|
33384
|
+
}
|
|
33385
|
+
poll(params) {
|
|
33386
|
+
return this.refresh(params);
|
|
33387
|
+
}
|
|
33388
|
+
getCached(workspace) {
|
|
33389
|
+
return this.cache.get(workspace);
|
|
33390
|
+
}
|
|
33391
|
+
getCompactSummary(workspace) {
|
|
33392
|
+
return this.cache.get(workspace)?.compactSummary;
|
|
33393
|
+
}
|
|
33394
|
+
onUpdate(listener) {
|
|
33395
|
+
this.listeners.add(listener);
|
|
33396
|
+
return () => {
|
|
33397
|
+
this.listeners.delete(listener);
|
|
33398
|
+
};
|
|
33399
|
+
}
|
|
33400
|
+
createSubscription(params, listener) {
|
|
33401
|
+
const normalized = this.normalize(params);
|
|
33402
|
+
const scopedListener = listener ? (update, cacheEntry) => {
|
|
33403
|
+
if (update.workspace === normalized.workspace) listener(update, cacheEntry);
|
|
33404
|
+
} : void 0;
|
|
33405
|
+
const unsubscribe = scopedListener ? this.onUpdate(scopedListener) : () => void 0;
|
|
33406
|
+
return {
|
|
33407
|
+
params: normalized,
|
|
33408
|
+
refresh: () => this.refresh(normalized),
|
|
33409
|
+
getCached: () => this.getCached(normalized.workspace),
|
|
33410
|
+
dispose: unsubscribe
|
|
33411
|
+
};
|
|
33412
|
+
}
|
|
33413
|
+
normalize(params) {
|
|
33414
|
+
return normalizeGitWorkspaceSubscriptionParams2(params, {
|
|
33415
|
+
defaultIntervalMs: this.defaultIntervalMs,
|
|
33416
|
+
minIntervalMs: this.minIntervalMs
|
|
33417
|
+
});
|
|
33418
|
+
}
|
|
33419
|
+
keyForWorkspace(workspace) {
|
|
33420
|
+
return `${this.keyPrefix}:${workspace}`;
|
|
33421
|
+
}
|
|
33422
|
+
emit(update, cacheEntry) {
|
|
33423
|
+
for (const listener of this.listeners) {
|
|
33424
|
+
listener(update, cacheEntry);
|
|
33425
|
+
}
|
|
33426
|
+
}
|
|
33427
|
+
};
|
|
33428
|
+
function createGitWorkspaceMonitor2(options = {}) {
|
|
33429
|
+
return new GitWorkspaceMonitor(options);
|
|
33430
|
+
}
|
|
33431
|
+
var path32 = __toESM2(require("path"));
|
|
33432
|
+
var GIT_COMMAND_NAMES = /* @__PURE__ */ new Set([
|
|
33433
|
+
"git_status",
|
|
33434
|
+
"git_diff_summary",
|
|
33435
|
+
"git_diff_file",
|
|
33436
|
+
"git_snapshot_create",
|
|
33437
|
+
"git_snapshot_compare",
|
|
33438
|
+
"git_log",
|
|
33439
|
+
"git_checkpoint",
|
|
33440
|
+
"git_stash_push",
|
|
33441
|
+
"git_stash_pop",
|
|
33442
|
+
"git_checkout_files"
|
|
33443
|
+
]);
|
|
33444
|
+
var MUTATING_COMMAND_NAMES = /* @__PURE__ */ new Set([
|
|
33445
|
+
"git_checkpoint",
|
|
33446
|
+
"git_stash_push",
|
|
33447
|
+
"git_stash_pop",
|
|
33448
|
+
"git_checkout_files"
|
|
33449
|
+
]);
|
|
33450
|
+
var SNAPSHOT_REASONS = /* @__PURE__ */ new Set([
|
|
33451
|
+
"session_baseline",
|
|
33452
|
+
"before_user_input_dispatch",
|
|
33453
|
+
"before_agent_work",
|
|
33454
|
+
"after_agent_work",
|
|
33455
|
+
"manual"
|
|
33456
|
+
]);
|
|
33457
|
+
var FAILURE_REASONS = /* @__PURE__ */ new Set([
|
|
33458
|
+
"not_git_repo",
|
|
33459
|
+
"git_not_installed",
|
|
33460
|
+
"timeout",
|
|
33461
|
+
"path_outside_repo",
|
|
33462
|
+
"dirty_index_required",
|
|
33463
|
+
"conflict",
|
|
33464
|
+
"invalid_args",
|
|
33465
|
+
"git_command_failed"
|
|
33466
|
+
]);
|
|
33467
|
+
function failure(reason, error48) {
|
|
33468
|
+
return { success: false, reason, error: error48 };
|
|
33469
|
+
}
|
|
33470
|
+
function serviceNotImplemented(command) {
|
|
33471
|
+
return failure("invalid_args", `${command} is not implemented: daemon-core Git service is not configured`);
|
|
33472
|
+
}
|
|
33473
|
+
var defaultSnapshotStore = createGitSnapshotStore({
|
|
33474
|
+
getStatus: (workspace) => getGitRepoStatus(workspace),
|
|
33475
|
+
getDiffSummary: (workspace) => getGitDiffSummary(workspace)
|
|
33476
|
+
});
|
|
33477
|
+
function createDefaultGitCommandServices() {
|
|
33478
|
+
return {
|
|
33479
|
+
getStatus: ({ workspace }) => getGitRepoStatus(workspace),
|
|
33480
|
+
getDiffSummary: ({ workspace }) => getGitDiffSummary(workspace),
|
|
33481
|
+
getDiffFile: ({ workspace, path: filePath }) => getGitFileDiff(workspace, filePath),
|
|
33482
|
+
createSnapshot: ({ workspace, reason, sessionId, turnId }) => defaultSnapshotStore.create({
|
|
33483
|
+
workspace,
|
|
33484
|
+
reason,
|
|
33485
|
+
sessionId,
|
|
33486
|
+
turnId
|
|
33487
|
+
}),
|
|
33488
|
+
compareSnapshots: ({ beforeSnapshotId, afterSnapshotId }) => defaultSnapshotStore.compare(beforeSnapshotId, afterSnapshotId),
|
|
33489
|
+
getLog: ({ workspace, limit, path: filePath, since, until }) => getGitLog(workspace, { limit, path: filePath, since, until })
|
|
33490
|
+
};
|
|
33491
|
+
}
|
|
33492
|
+
var defaultGitCommandServices = createDefaultGitCommandServices();
|
|
33493
|
+
function validateWorkspace2(args) {
|
|
33494
|
+
if (typeof args?.workspace !== "string") {
|
|
33495
|
+
return failure("invalid_args", "workspace must be a non-empty absolute path");
|
|
33496
|
+
}
|
|
33497
|
+
const workspace = args.workspace.trim();
|
|
33498
|
+
if (!workspace || !path32.isAbsolute(workspace)) {
|
|
33499
|
+
return failure("invalid_args", "workspace must be a non-empty absolute path");
|
|
33500
|
+
}
|
|
33501
|
+
return { workspace };
|
|
33502
|
+
}
|
|
33503
|
+
function validateRepoPath(args) {
|
|
33504
|
+
if (typeof args?.path !== "string" || !args.path.trim()) {
|
|
33505
|
+
return failure("invalid_args", "path must be a non-empty repository-relative path");
|
|
33506
|
+
}
|
|
33507
|
+
return { path: args.path.trim() };
|
|
33508
|
+
}
|
|
33509
|
+
function validateSnapshotId(args, key) {
|
|
33510
|
+
if (typeof args?.[key] !== "string" || !args[key].trim()) {
|
|
33511
|
+
return failure("invalid_args", `${key} must be a non-empty string`);
|
|
33512
|
+
}
|
|
33513
|
+
return args[key].trim();
|
|
33514
|
+
}
|
|
33515
|
+
function parseSnapshotReason(args) {
|
|
33516
|
+
if (args?.reason === void 0 || args?.reason === null || args?.reason === "") {
|
|
33517
|
+
return "manual";
|
|
33518
|
+
}
|
|
33519
|
+
if (typeof args.reason !== "string" || !SNAPSHOT_REASONS.has(args.reason)) {
|
|
33520
|
+
return failure("invalid_args", "reason must be a valid GitSnapshotReason");
|
|
33521
|
+
}
|
|
33522
|
+
return args.reason;
|
|
33523
|
+
}
|
|
33524
|
+
function optionalString(value) {
|
|
33525
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
33526
|
+
}
|
|
33527
|
+
function optionalBoolean(value) {
|
|
33528
|
+
return typeof value === "boolean" ? value : void 0;
|
|
33529
|
+
}
|
|
33530
|
+
function boundedLogLimit(value) {
|
|
33531
|
+
if (value === void 0 || value === null || value === "") return 50;
|
|
33532
|
+
const numeric = typeof value === "number" ? value : Number(value);
|
|
33533
|
+
if (!Number.isFinite(numeric)) return 50;
|
|
33534
|
+
return Math.max(1, Math.min(200, Math.floor(numeric)));
|
|
33535
|
+
}
|
|
33536
|
+
function failureReasonFromError(error48) {
|
|
33537
|
+
return typeof error48?.reason === "string" && FAILURE_REASONS.has(error48.reason) ? error48.reason : "git_command_failed";
|
|
33538
|
+
}
|
|
33539
|
+
async function runService(fn2) {
|
|
33540
|
+
try {
|
|
33541
|
+
return await fn2();
|
|
33542
|
+
} catch (error48) {
|
|
33543
|
+
return failure(failureReasonFromError(error48), error48?.message || "Git command failed");
|
|
33544
|
+
}
|
|
33545
|
+
}
|
|
33546
|
+
function isGitCommandName(command) {
|
|
33547
|
+
return GIT_COMMAND_NAMES.has(command);
|
|
33548
|
+
}
|
|
33549
|
+
async function handleGitCommand(command, args, services = defaultGitCommandServices) {
|
|
33550
|
+
if (!isGitCommandName(command)) {
|
|
33551
|
+
return failure("invalid_args", `Unknown Git command: ${command}`);
|
|
33552
|
+
}
|
|
33553
|
+
if (MUTATING_COMMAND_NAMES.has(command)) {
|
|
33554
|
+
return failure("invalid_args", `${command} is not implemented in daemon-core read-only Git routing`);
|
|
33555
|
+
}
|
|
33556
|
+
const workspaceResult = validateWorkspace2(args);
|
|
33557
|
+
if ("success" in workspaceResult) return workspaceResult;
|
|
33558
|
+
const { workspace } = workspaceResult;
|
|
33559
|
+
switch (command) {
|
|
33560
|
+
case "git_status": {
|
|
33561
|
+
if (!services.getStatus) return serviceNotImplemented(command);
|
|
33562
|
+
const status = await runService(() => services.getStatus({ workspace }));
|
|
33563
|
+
return "success" in status ? status : { success: true, status };
|
|
33564
|
+
}
|
|
33565
|
+
case "git_diff_summary": {
|
|
33566
|
+
if (!services.getDiffSummary) return serviceNotImplemented(command);
|
|
33567
|
+
const diffSummary = await runService(() => services.getDiffSummary({ workspace, staged: optionalBoolean(args?.staged) }));
|
|
33568
|
+
return "success" in diffSummary ? diffSummary : { success: true, diffSummary };
|
|
33569
|
+
}
|
|
33570
|
+
case "git_diff_file": {
|
|
33571
|
+
if (!services.getDiffFile) return serviceNotImplemented(command);
|
|
33572
|
+
const pathResult = validateRepoPath(args);
|
|
33573
|
+
if (typeof pathResult !== "object" || "success" in pathResult) return pathResult;
|
|
33574
|
+
const diff = await runService(() => services.getDiffFile({
|
|
33575
|
+
workspace,
|
|
33576
|
+
path: pathResult.path,
|
|
33577
|
+
staged: optionalBoolean(args?.staged)
|
|
33578
|
+
}));
|
|
33579
|
+
return "success" in diff ? diff : { success: true, diff };
|
|
33580
|
+
}
|
|
33581
|
+
case "git_snapshot_create": {
|
|
33582
|
+
if (!services.createSnapshot) return serviceNotImplemented(command);
|
|
33583
|
+
const reason = parseSnapshotReason(args);
|
|
33584
|
+
if (typeof reason !== "string") return reason;
|
|
33585
|
+
const snapshot = await runService(() => services.createSnapshot({
|
|
33586
|
+
workspace,
|
|
33587
|
+
reason,
|
|
33588
|
+
sessionId: optionalString(args?.sessionId),
|
|
33589
|
+
turnId: optionalString(args?.turnId)
|
|
33590
|
+
}));
|
|
33591
|
+
return "success" in snapshot ? snapshot : { success: true, snapshot };
|
|
33592
|
+
}
|
|
33593
|
+
case "git_snapshot_compare": {
|
|
33594
|
+
if (!services.compareSnapshots) return serviceNotImplemented(command);
|
|
33595
|
+
const beforeSnapshotId = validateSnapshotId(args, "beforeSnapshotId");
|
|
33596
|
+
if (typeof beforeSnapshotId !== "string") return beforeSnapshotId;
|
|
33597
|
+
const afterSnapshotId = validateSnapshotId(args, "afterSnapshotId");
|
|
33598
|
+
if (typeof afterSnapshotId !== "string") return afterSnapshotId;
|
|
33599
|
+
const compare = await runService(() => services.compareSnapshots({ workspace, beforeSnapshotId, afterSnapshotId }));
|
|
33600
|
+
return "success" in compare ? compare : { success: true, compare };
|
|
33601
|
+
}
|
|
33602
|
+
case "git_log": {
|
|
33603
|
+
if (!services.getLog) {
|
|
33604
|
+
return failure("invalid_args", "git_log is not implemented: bounded daemon-core Git log service is not configured");
|
|
33605
|
+
}
|
|
33606
|
+
const log = await runService(() => services.getLog({
|
|
33607
|
+
workspace,
|
|
33608
|
+
limit: boundedLogLimit(args?.limit),
|
|
33609
|
+
path: optionalString(args?.path),
|
|
33610
|
+
since: optionalString(args?.since),
|
|
33611
|
+
until: optionalString(args?.until)
|
|
33612
|
+
}));
|
|
33613
|
+
return "success" in log ? log : { success: true, log };
|
|
33614
|
+
}
|
|
33615
|
+
default:
|
|
33616
|
+
return failure("invalid_args", `Unknown Git command: ${command}`);
|
|
33617
|
+
}
|
|
33618
|
+
}
|
|
33619
|
+
function formatOptionalGitLogRangeArg(flag, value) {
|
|
33620
|
+
return value ? [`${flag}=${value}`] : [];
|
|
33621
|
+
}
|
|
33622
|
+
async function getGitLog(workspace, options) {
|
|
33623
|
+
const lastCheckedAt = Date.now();
|
|
33624
|
+
const repo = await resolveGitRepository(workspace);
|
|
33625
|
+
const repoRoot = repo.repoRoot;
|
|
33626
|
+
const boundedLimit = Math.max(1, Math.min(200, Math.floor(options.limit || 50)));
|
|
33627
|
+
const selectedPath = options.path ? validateGitLogPath(repoRoot, options.path) : void 0;
|
|
33628
|
+
const result = await runGit(
|
|
33629
|
+
repo,
|
|
33630
|
+
[
|
|
33631
|
+
"log",
|
|
33632
|
+
`--max-count=${boundedLimit}`,
|
|
33633
|
+
"--format=%H%x00%an%x00%ae%x00%at%x00%ct%x00%s",
|
|
33634
|
+
...formatOptionalGitLogRangeArg("--since", options.since),
|
|
33635
|
+
...formatOptionalGitLogRangeArg("--until", options.until),
|
|
33636
|
+
"--",
|
|
33637
|
+
...selectedPath ? [selectedPath] : []
|
|
33638
|
+
],
|
|
33639
|
+
{ cwd: repoRoot }
|
|
33640
|
+
);
|
|
33641
|
+
const entries = result.stdout.split("\n").filter((line) => line.trim().length > 0).map((line) => {
|
|
33642
|
+
const [commit = "", authorName, authorEmail, authoredAt, committedAt, ...messageParts] = line.split("\0");
|
|
33643
|
+
return {
|
|
33644
|
+
commit,
|
|
33645
|
+
message: messageParts.join("\0"),
|
|
33646
|
+
authorName: authorName || void 0,
|
|
33647
|
+
authorEmail: authorEmail || void 0,
|
|
33648
|
+
authoredAt: authoredAt ? Number.parseInt(authoredAt, 10) * 1e3 : void 0,
|
|
33649
|
+
committedAt: committedAt ? Number.parseInt(committedAt, 10) * 1e3 : void 0
|
|
33650
|
+
};
|
|
33651
|
+
}).filter((entry) => entry.commit.length > 0);
|
|
33652
|
+
return {
|
|
33653
|
+
workspace: repo.workspace,
|
|
33654
|
+
repoRoot,
|
|
33655
|
+
isGitRepo: true,
|
|
33656
|
+
entries,
|
|
33657
|
+
limit: boundedLimit,
|
|
33658
|
+
truncated: entries.length >= boundedLimit,
|
|
33659
|
+
lastCheckedAt
|
|
33660
|
+
};
|
|
33661
|
+
}
|
|
33662
|
+
function validateGitLogPath(repoRoot, filePath) {
|
|
33663
|
+
if (!filePath.trim() || filePath.includes("\0")) {
|
|
33664
|
+
throw new GitCommandError("invalid_args", "path must be a non-empty repository-relative path");
|
|
33665
|
+
}
|
|
33666
|
+
if (path32.isAbsolute(filePath)) {
|
|
33667
|
+
throw new GitCommandError("invalid_args", "path must be repository-relative");
|
|
33668
|
+
}
|
|
33669
|
+
const normalized = path32.normalize(filePath).split(path32.sep).join("/");
|
|
33670
|
+
const absolutePath = path32.resolve(repoRoot, normalized);
|
|
33671
|
+
if (!isPathInside(repoRoot, absolutePath) || normalized.startsWith("../") || normalized === "..") {
|
|
33672
|
+
throw new GitCommandError("path_outside_repo", "Git log path is outside the repository root");
|
|
33673
|
+
}
|
|
33674
|
+
return normalized;
|
|
33675
|
+
}
|
|
32551
33676
|
init_config();
|
|
32552
33677
|
var fs5 = __toESM2(require("fs"));
|
|
32553
33678
|
var os6 = __toESM2(require("os"));
|
|
32554
|
-
var
|
|
33679
|
+
var path42 = __toESM2(require("path"));
|
|
32555
33680
|
var import_crypto22 = require("crypto");
|
|
32556
33681
|
var MAX_WORKSPACES = 50;
|
|
32557
33682
|
function expandPath(p) {
|
|
32558
33683
|
const t = (p || "").trim();
|
|
32559
33684
|
if (!t) return "";
|
|
32560
|
-
if (t.startsWith("~")) return
|
|
32561
|
-
return
|
|
33685
|
+
if (t.startsWith("~")) return path42.join(os6.homedir(), t.slice(1).replace(/^\//, ""));
|
|
33686
|
+
return path42.resolve(t);
|
|
32562
33687
|
}
|
|
32563
33688
|
function validateWorkspacePath(absPath) {
|
|
32564
33689
|
try {
|
|
@@ -32572,7 +33697,7 @@ var require_dist2 = __commonJS({
|
|
|
32572
33697
|
}
|
|
32573
33698
|
}
|
|
32574
33699
|
function defaultWorkspaceLabel(absPath) {
|
|
32575
|
-
const base =
|
|
33700
|
+
const base = path42.basename(absPath) || absPath;
|
|
32576
33701
|
return base;
|
|
32577
33702
|
}
|
|
32578
33703
|
function getDefaultWorkspacePath(config2) {
|
|
@@ -32663,9 +33788,9 @@ var require_dist2 = __commonJS({
|
|
|
32663
33788
|
return getDefaultWorkspacePath(config2) || void 0;
|
|
32664
33789
|
}
|
|
32665
33790
|
function findWorkspaceByPath(config2, rawPath) {
|
|
32666
|
-
const abs =
|
|
33791
|
+
const abs = path42.resolve(expandPath(rawPath));
|
|
32667
33792
|
if (!abs) return void 0;
|
|
32668
|
-
return (config2.workspaces || []).find((w) =>
|
|
33793
|
+
return (config2.workspaces || []).find((w) => path42.resolve(expandPath(w.path)) === abs);
|
|
32669
33794
|
}
|
|
32670
33795
|
function addWorkspaceEntry(config2, rawPath, label, options) {
|
|
32671
33796
|
const abs = expandPath(rawPath);
|
|
@@ -32681,7 +33806,7 @@ var require_dist2 = __commonJS({
|
|
|
32681
33806
|
const v2 = validateWorkspacePath(abs);
|
|
32682
33807
|
if (!v2.ok) return { error: v2.error };
|
|
32683
33808
|
const list = [...config2.workspaces || []];
|
|
32684
|
-
if (list.some((w) =>
|
|
33809
|
+
if (list.some((w) => path42.resolve(w.path) === abs)) {
|
|
32685
33810
|
return { error: "Workspace already in list" };
|
|
32686
33811
|
}
|
|
32687
33812
|
if (list.length >= MAX_WORKSPACES) {
|
|
@@ -32713,7 +33838,7 @@ var require_dist2 = __commonJS({
|
|
|
32713
33838
|
if (validateWorkspacePath(abs).ok !== true) return { error: "Workspace path is no longer valid" };
|
|
32714
33839
|
return { config: { ...config2, defaultWorkspaceId: id } };
|
|
32715
33840
|
}
|
|
32716
|
-
var
|
|
33841
|
+
var path52 = __toESM2(require("path"));
|
|
32717
33842
|
function normalizeSummaryItem(item) {
|
|
32718
33843
|
if (!item || typeof item !== "object") return null;
|
|
32719
33844
|
const id = String(item.id || "").trim();
|
|
@@ -32778,9 +33903,9 @@ var require_dist2 = __commonJS({
|
|
|
32778
33903
|
function normalizeWorkspace(workspace) {
|
|
32779
33904
|
if (!workspace) return "";
|
|
32780
33905
|
try {
|
|
32781
|
-
return
|
|
33906
|
+
return path52.resolve(expandPath(workspace));
|
|
32782
33907
|
} catch {
|
|
32783
|
-
return
|
|
33908
|
+
return path52.resolve(workspace);
|
|
32784
33909
|
}
|
|
32785
33910
|
}
|
|
32786
33911
|
function buildRecentActivityKey(entry) {
|
|
@@ -32946,14 +34071,14 @@ var require_dist2 = __commonJS({
|
|
|
32946
34071
|
sessionNotificationUnreadOverrides: nextSessionNotificationUnreadOverrides
|
|
32947
34072
|
};
|
|
32948
34073
|
}
|
|
32949
|
-
var
|
|
34074
|
+
var path6 = __toESM2(require("path"));
|
|
32950
34075
|
var MAX_SAVED_SESSIONS = 500;
|
|
32951
34076
|
function normalizeWorkspace2(workspace) {
|
|
32952
34077
|
if (!workspace) return "";
|
|
32953
34078
|
try {
|
|
32954
|
-
return
|
|
34079
|
+
return path6.resolve(expandPath(workspace));
|
|
32955
34080
|
} catch {
|
|
32956
|
-
return
|
|
34081
|
+
return path6.resolve(workspace);
|
|
32957
34082
|
}
|
|
32958
34083
|
}
|
|
32959
34084
|
function buildSavedProviderSessionKey(providerSessionId) {
|
|
@@ -33068,7 +34193,7 @@ var require_dist2 = __commonJS({
|
|
|
33068
34193
|
var import_child_process = require("child_process");
|
|
33069
34194
|
var import_fs3 = require("fs");
|
|
33070
34195
|
var import_os22 = require("os");
|
|
33071
|
-
var
|
|
34196
|
+
var path7 = __toESM2(require("path"));
|
|
33072
34197
|
var BUILTIN_IDE_DEFINITIONS = [];
|
|
33073
34198
|
var registeredIDEs = /* @__PURE__ */ new Map();
|
|
33074
34199
|
function registerIDEDefinition(def) {
|
|
@@ -33087,9 +34212,9 @@ var require_dist2 = __commonJS({
|
|
|
33087
34212
|
function findCliCommand(command) {
|
|
33088
34213
|
const trimmed = String(command || "").trim();
|
|
33089
34214
|
if (!trimmed) return null;
|
|
33090
|
-
if (
|
|
33091
|
-
const candidate = trimmed.startsWith("~") ?
|
|
33092
|
-
const resolved =
|
|
34215
|
+
if (path7.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
34216
|
+
const candidate = trimmed.startsWith("~") ? path7.join((0, import_os22.homedir)(), trimmed.slice(1)) : trimmed;
|
|
34217
|
+
const resolved = path7.isAbsolute(candidate) ? candidate : path7.resolve(candidate);
|
|
33093
34218
|
return (0, import_fs3.existsSync)(resolved) ? resolved : null;
|
|
33094
34219
|
}
|
|
33095
34220
|
try {
|
|
@@ -33117,7 +34242,7 @@ var require_dist2 = __commonJS({
|
|
|
33117
34242
|
function checkPathExists(paths) {
|
|
33118
34243
|
const home = (0, import_os22.homedir)();
|
|
33119
34244
|
for (const p of paths) {
|
|
33120
|
-
const normalized = p.startsWith("~") ?
|
|
34245
|
+
const normalized = p.startsWith("~") ? path7.join(home, p.slice(1)) : p;
|
|
33121
34246
|
if (normalized.includes("*")) {
|
|
33122
34247
|
const username = home.split(/[\\/]/).pop() || "";
|
|
33123
34248
|
const resolved = normalized.replace("*", username);
|
|
@@ -33173,7 +34298,7 @@ var require_dist2 = __commonJS({
|
|
|
33173
34298
|
}
|
|
33174
34299
|
var import_child_process2 = require("child_process");
|
|
33175
34300
|
var os22 = __toESM2(require("os"));
|
|
33176
|
-
var
|
|
34301
|
+
var path8 = __toESM2(require("path"));
|
|
33177
34302
|
var import_fs4 = require("fs");
|
|
33178
34303
|
function parseVersion(raw) {
|
|
33179
34304
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
@@ -33186,36 +34311,36 @@ var require_dist2 = __commonJS({
|
|
|
33186
34311
|
function expandHome(value) {
|
|
33187
34312
|
const trimmed = value.trim();
|
|
33188
34313
|
if (!trimmed.startsWith("~")) return trimmed;
|
|
33189
|
-
return
|
|
34314
|
+
return path8.join(os22.homedir(), trimmed.slice(1));
|
|
33190
34315
|
}
|
|
33191
34316
|
function isExplicitCommandPath(command) {
|
|
33192
34317
|
const trimmed = command.trim();
|
|
33193
|
-
return
|
|
34318
|
+
return path8.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
33194
34319
|
}
|
|
33195
34320
|
function resolveCommandPath(command) {
|
|
33196
34321
|
const trimmed = command.trim();
|
|
33197
34322
|
if (!trimmed) return null;
|
|
33198
34323
|
if (isExplicitCommandPath(trimmed)) {
|
|
33199
34324
|
const expanded = expandHome(trimmed);
|
|
33200
|
-
const candidate =
|
|
34325
|
+
const candidate = path8.isAbsolute(expanded) ? expanded : path8.resolve(expanded);
|
|
33201
34326
|
return (0, import_fs4.existsSync)(candidate) ? candidate : null;
|
|
33202
34327
|
}
|
|
33203
34328
|
return null;
|
|
33204
34329
|
}
|
|
33205
34330
|
function execAsync(cmd, timeoutMs = 5e3) {
|
|
33206
|
-
return new Promise((
|
|
34331
|
+
return new Promise((resolve15) => {
|
|
33207
34332
|
const child = (0, import_child_process2.exec)(cmd, {
|
|
33208
34333
|
encoding: "utf-8",
|
|
33209
34334
|
timeout: timeoutMs,
|
|
33210
34335
|
...process.platform === "win32" ? { windowsHide: true } : {}
|
|
33211
34336
|
}, (err, stdout) => {
|
|
33212
34337
|
if (err || !stdout?.trim()) {
|
|
33213
|
-
|
|
34338
|
+
resolve15(null);
|
|
33214
34339
|
} else {
|
|
33215
|
-
|
|
34340
|
+
resolve15(stdout.trim());
|
|
33216
34341
|
}
|
|
33217
34342
|
});
|
|
33218
|
-
child.on("error", () =>
|
|
34343
|
+
child.on("error", () => resolve15(null));
|
|
33219
34344
|
});
|
|
33220
34345
|
}
|
|
33221
34346
|
async function detectCLIs(providerLoader, options) {
|
|
@@ -33572,7 +34697,7 @@ var require_dist2 = __commonJS({
|
|
|
33572
34697
|
* Returns multiple entries if multiple IDE windows are open on same port
|
|
33573
34698
|
*/
|
|
33574
34699
|
static listAllTargets(port) {
|
|
33575
|
-
return new Promise((
|
|
34700
|
+
return new Promise((resolve15) => {
|
|
33576
34701
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
33577
34702
|
let data = "";
|
|
33578
34703
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -33588,16 +34713,16 @@ var require_dist2 = __commonJS({
|
|
|
33588
34713
|
(t) => !isNonMain(t.title || "") && t.url?.includes("workbench.html") && !t.url?.includes("agent")
|
|
33589
34714
|
);
|
|
33590
34715
|
const fallbackPages = pages.filter((t) => !isNonMain(t.title || ""));
|
|
33591
|
-
|
|
34716
|
+
resolve15(mainPages.length > 0 ? mainPages : fallbackPages);
|
|
33592
34717
|
} catch {
|
|
33593
|
-
|
|
34718
|
+
resolve15([]);
|
|
33594
34719
|
}
|
|
33595
34720
|
});
|
|
33596
34721
|
});
|
|
33597
|
-
req.on("error", () =>
|
|
34722
|
+
req.on("error", () => resolve15([]));
|
|
33598
34723
|
req.setTimeout(2e3, () => {
|
|
33599
34724
|
req.destroy();
|
|
33600
|
-
|
|
34725
|
+
resolve15([]);
|
|
33601
34726
|
});
|
|
33602
34727
|
});
|
|
33603
34728
|
}
|
|
@@ -33637,7 +34762,7 @@ var require_dist2 = __commonJS({
|
|
|
33637
34762
|
}
|
|
33638
34763
|
}
|
|
33639
34764
|
findTargetOnPort(port) {
|
|
33640
|
-
return new Promise((
|
|
34765
|
+
return new Promise((resolve15) => {
|
|
33641
34766
|
const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
|
|
33642
34767
|
let data = "";
|
|
33643
34768
|
res.on("data", (chunk) => data += chunk.toString());
|
|
@@ -33648,7 +34773,7 @@ var require_dist2 = __commonJS({
|
|
|
33648
34773
|
(t) => (t.type === "page" || t.type === "browser" || t.type === "Page") && t.webSocketDebuggerUrl
|
|
33649
34774
|
);
|
|
33650
34775
|
if (pages.length === 0) {
|
|
33651
|
-
|
|
34776
|
+
resolve15(targets.find((t) => t.webSocketDebuggerUrl) || null);
|
|
33652
34777
|
return;
|
|
33653
34778
|
}
|
|
33654
34779
|
const titleFilteredPages = pages.filter((t) => !this.isNonMainTitle(t.title || ""));
|
|
@@ -33667,25 +34792,25 @@ var require_dist2 = __commonJS({
|
|
|
33667
34792
|
this._targetId = selected.target.id;
|
|
33668
34793
|
}
|
|
33669
34794
|
this._pageTitle = selected.target.title || "";
|
|
33670
|
-
|
|
34795
|
+
resolve15(selected.target);
|
|
33671
34796
|
return;
|
|
33672
34797
|
}
|
|
33673
34798
|
if (previousTargetId) {
|
|
33674
34799
|
this.log(`[CDP] Target ${previousTargetId} not found in page list`);
|
|
33675
|
-
|
|
34800
|
+
resolve15(null);
|
|
33676
34801
|
return;
|
|
33677
34802
|
}
|
|
33678
34803
|
this._pageTitle = list[0]?.title || "";
|
|
33679
|
-
|
|
34804
|
+
resolve15(list[0]);
|
|
33680
34805
|
} catch {
|
|
33681
|
-
|
|
34806
|
+
resolve15(null);
|
|
33682
34807
|
}
|
|
33683
34808
|
});
|
|
33684
34809
|
});
|
|
33685
|
-
req.on("error", () =>
|
|
34810
|
+
req.on("error", () => resolve15(null));
|
|
33686
34811
|
req.setTimeout(2e3, () => {
|
|
33687
34812
|
req.destroy();
|
|
33688
|
-
|
|
34813
|
+
resolve15(null);
|
|
33689
34814
|
});
|
|
33690
34815
|
});
|
|
33691
34816
|
}
|
|
@@ -33696,7 +34821,7 @@ var require_dist2 = __commonJS({
|
|
|
33696
34821
|
this.extensionProviders = providers;
|
|
33697
34822
|
}
|
|
33698
34823
|
connectToTarget(wsUrl) {
|
|
33699
|
-
return new Promise((
|
|
34824
|
+
return new Promise((resolve15) => {
|
|
33700
34825
|
this.ws = new import_ws2.default(wsUrl);
|
|
33701
34826
|
this.ws.on("open", async () => {
|
|
33702
34827
|
this._connected = true;
|
|
@@ -33706,17 +34831,17 @@ var require_dist2 = __commonJS({
|
|
|
33706
34831
|
}
|
|
33707
34832
|
this.connectBrowserWs().catch(() => {
|
|
33708
34833
|
});
|
|
33709
|
-
|
|
34834
|
+
resolve15(true);
|
|
33710
34835
|
});
|
|
33711
34836
|
this.ws.on("message", (data) => {
|
|
33712
34837
|
try {
|
|
33713
34838
|
const msg = JSON.parse(data.toString());
|
|
33714
34839
|
if (msg.id && this.pending.has(msg.id)) {
|
|
33715
|
-
const { resolve:
|
|
34840
|
+
const { resolve: resolve16, reject } = this.pending.get(msg.id);
|
|
33716
34841
|
this.pending.delete(msg.id);
|
|
33717
34842
|
this.failureCount = 0;
|
|
33718
34843
|
if (msg.error) reject(new Error(msg.error.message));
|
|
33719
|
-
else
|
|
34844
|
+
else resolve16(msg.result);
|
|
33720
34845
|
} else if (msg.method === "Runtime.executionContextCreated") {
|
|
33721
34846
|
this.contexts.add(msg.params.context.id);
|
|
33722
34847
|
} else if (msg.method === "Runtime.executionContextDestroyed") {
|
|
@@ -33739,7 +34864,7 @@ var require_dist2 = __commonJS({
|
|
|
33739
34864
|
this.ws.on("error", (err) => {
|
|
33740
34865
|
this.log(`[CDP] WebSocket error: ${err.message}`);
|
|
33741
34866
|
this._connected = false;
|
|
33742
|
-
|
|
34867
|
+
resolve15(false);
|
|
33743
34868
|
});
|
|
33744
34869
|
});
|
|
33745
34870
|
}
|
|
@@ -33753,7 +34878,7 @@ var require_dist2 = __commonJS({
|
|
|
33753
34878
|
return;
|
|
33754
34879
|
}
|
|
33755
34880
|
this.log(`[CDP] Connecting browser WS for target discovery...`);
|
|
33756
|
-
await new Promise((
|
|
34881
|
+
await new Promise((resolve15, reject) => {
|
|
33757
34882
|
this.browserWs = new import_ws2.default(browserWsUrl);
|
|
33758
34883
|
this.browserWs.on("open", async () => {
|
|
33759
34884
|
this._browserConnected = true;
|
|
@@ -33763,16 +34888,16 @@ var require_dist2 = __commonJS({
|
|
|
33763
34888
|
} catch (e) {
|
|
33764
34889
|
this.log(`[CDP] setDiscoverTargets failed: ${e.message}`);
|
|
33765
34890
|
}
|
|
33766
|
-
|
|
34891
|
+
resolve15();
|
|
33767
34892
|
});
|
|
33768
34893
|
this.browserWs.on("message", (data) => {
|
|
33769
34894
|
try {
|
|
33770
34895
|
const msg = JSON.parse(data.toString());
|
|
33771
34896
|
if (msg.id && this.browserPending.has(msg.id)) {
|
|
33772
|
-
const { resolve:
|
|
34897
|
+
const { resolve: resolve16, reject: reject2 } = this.browserPending.get(msg.id);
|
|
33773
34898
|
this.browserPending.delete(msg.id);
|
|
33774
34899
|
if (msg.error) reject2(new Error(msg.error.message));
|
|
33775
|
-
else
|
|
34900
|
+
else resolve16(msg.result);
|
|
33776
34901
|
}
|
|
33777
34902
|
} catch {
|
|
33778
34903
|
}
|
|
@@ -33792,31 +34917,31 @@ var require_dist2 = __commonJS({
|
|
|
33792
34917
|
}
|
|
33793
34918
|
}
|
|
33794
34919
|
getBrowserWsUrl() {
|
|
33795
|
-
return new Promise((
|
|
34920
|
+
return new Promise((resolve15) => {
|
|
33796
34921
|
const req = http.get(`http://127.0.0.1:${this.port}/json/version`, (res) => {
|
|
33797
34922
|
let data = "";
|
|
33798
34923
|
res.on("data", (chunk) => data += chunk.toString());
|
|
33799
34924
|
res.on("end", () => {
|
|
33800
34925
|
try {
|
|
33801
34926
|
const info = JSON.parse(data);
|
|
33802
|
-
|
|
34927
|
+
resolve15(info.webSocketDebuggerUrl || null);
|
|
33803
34928
|
} catch {
|
|
33804
|
-
|
|
34929
|
+
resolve15(null);
|
|
33805
34930
|
}
|
|
33806
34931
|
});
|
|
33807
34932
|
});
|
|
33808
|
-
req.on("error", () =>
|
|
34933
|
+
req.on("error", () => resolve15(null));
|
|
33809
34934
|
req.setTimeout(3e3, () => {
|
|
33810
34935
|
req.destroy();
|
|
33811
|
-
|
|
34936
|
+
resolve15(null);
|
|
33812
34937
|
});
|
|
33813
34938
|
});
|
|
33814
34939
|
}
|
|
33815
34940
|
sendBrowser(method, params = {}, timeoutMs = 15e3) {
|
|
33816
|
-
return new Promise((
|
|
34941
|
+
return new Promise((resolve15, reject) => {
|
|
33817
34942
|
if (!this.browserWs || !this._browserConnected) return reject(new Error("Browser WS not connected"));
|
|
33818
34943
|
const id = this.browserMsgId++;
|
|
33819
|
-
this.browserPending.set(id, { resolve:
|
|
34944
|
+
this.browserPending.set(id, { resolve: resolve15, reject });
|
|
33820
34945
|
this.browserWs.send(JSON.stringify({ id, method, params }));
|
|
33821
34946
|
setTimeout(() => {
|
|
33822
34947
|
if (this.browserPending.has(id)) {
|
|
@@ -33856,11 +34981,11 @@ var require_dist2 = __commonJS({
|
|
|
33856
34981
|
}
|
|
33857
34982
|
// ─── CDP Protocol ────────────────────────────────────────
|
|
33858
34983
|
sendInternal(method, params = {}, timeoutMs = 15e3) {
|
|
33859
|
-
return new Promise((
|
|
34984
|
+
return new Promise((resolve15, reject) => {
|
|
33860
34985
|
if (!this.ws || !this._connected) return reject(new Error("CDP not connected"));
|
|
33861
34986
|
if (this.ws.readyState !== import_ws2.default.OPEN) return reject(new Error("WebSocket not open"));
|
|
33862
34987
|
const id = this.msgId++;
|
|
33863
|
-
this.pending.set(id, { resolve:
|
|
34988
|
+
this.pending.set(id, { resolve: resolve15, reject });
|
|
33864
34989
|
this.ws.send(JSON.stringify({ id, method, params }));
|
|
33865
34990
|
setTimeout(() => {
|
|
33866
34991
|
if (this.pending.has(id)) {
|
|
@@ -34109,7 +35234,7 @@ var require_dist2 = __commonJS({
|
|
|
34109
35234
|
const browserWs = this.browserWs;
|
|
34110
35235
|
let msgId = this.browserMsgId;
|
|
34111
35236
|
const sendWs = (method, params = {}, sessionId) => {
|
|
34112
|
-
return new Promise((
|
|
35237
|
+
return new Promise((resolve15, reject) => {
|
|
34113
35238
|
const mid = msgId++;
|
|
34114
35239
|
this.browserMsgId = msgId;
|
|
34115
35240
|
const handler = (raw) => {
|
|
@@ -34118,7 +35243,7 @@ var require_dist2 = __commonJS({
|
|
|
34118
35243
|
if (msg.id === mid) {
|
|
34119
35244
|
browserWs.removeListener("message", handler);
|
|
34120
35245
|
if (msg.error) reject(new Error(msg.error.message || JSON.stringify(msg.error)));
|
|
34121
|
-
else
|
|
35246
|
+
else resolve15(msg.result);
|
|
34122
35247
|
}
|
|
34123
35248
|
} catch {
|
|
34124
35249
|
}
|
|
@@ -34319,14 +35444,14 @@ var require_dist2 = __commonJS({
|
|
|
34319
35444
|
if (!ws2 || ws2.readyState !== import_ws2.default.OPEN) {
|
|
34320
35445
|
throw new Error("CDP not connected");
|
|
34321
35446
|
}
|
|
34322
|
-
return new Promise((
|
|
35447
|
+
return new Promise((resolve15, reject) => {
|
|
34323
35448
|
const id = getNextId();
|
|
34324
35449
|
pendingMap.set(id, {
|
|
34325
35450
|
resolve: (result) => {
|
|
34326
35451
|
if (result?.result?.subtype === "error") {
|
|
34327
35452
|
reject(new Error(result.result.description));
|
|
34328
35453
|
} else {
|
|
34329
|
-
|
|
35454
|
+
resolve15(result?.result?.value);
|
|
34330
35455
|
}
|
|
34331
35456
|
},
|
|
34332
35457
|
reject
|
|
@@ -34358,10 +35483,10 @@ var require_dist2 = __commonJS({
|
|
|
34358
35483
|
throw new Error("CDP not connected");
|
|
34359
35484
|
}
|
|
34360
35485
|
const sendViaSession = (method, params = {}) => {
|
|
34361
|
-
return new Promise((
|
|
35486
|
+
return new Promise((resolve15, reject) => {
|
|
34362
35487
|
const pendingMap = this._browserConnected ? this.browserPending : this.pending;
|
|
34363
35488
|
const id = this._browserConnected ? this.browserMsgId++ : this.msgId++;
|
|
34364
|
-
pendingMap.set(id, { resolve:
|
|
35489
|
+
pendingMap.set(id, { resolve: resolve15, reject });
|
|
34365
35490
|
ws2.send(JSON.stringify({ id, sessionId, method, params }));
|
|
34366
35491
|
setTimeout(() => {
|
|
34367
35492
|
if (pendingMap.has(id)) {
|
|
@@ -35095,10 +36220,10 @@ ${cleanBody}`;
|
|
|
35095
36220
|
return cleanTitle || cleanBody;
|
|
35096
36221
|
}
|
|
35097
36222
|
var fs32 = __toESM2(require("fs"));
|
|
35098
|
-
var
|
|
36223
|
+
var path10 = __toESM2(require("path"));
|
|
35099
36224
|
var os52 = __toESM2(require("os"));
|
|
35100
36225
|
init_chat_message_normalization();
|
|
35101
|
-
var HISTORY_DIR =
|
|
36226
|
+
var HISTORY_DIR = path10.join(os52.homedir(), ".adhdev", "history");
|
|
35102
36227
|
var RETAIN_DAYS = 30;
|
|
35103
36228
|
var SAVED_HISTORY_INDEX_VERSION = 1;
|
|
35104
36229
|
var SAVED_HISTORY_INDEX_FILE = ".saved-history-index.json";
|
|
@@ -35261,8 +36386,8 @@ ${cleanBody}`;
|
|
|
35261
36386
|
function buildSavedHistoryFileSignatureMap(dir, files) {
|
|
35262
36387
|
return new Map(files.map((file2) => {
|
|
35263
36388
|
try {
|
|
35264
|
-
const
|
|
35265
|
-
return [file2, `${file2}:${
|
|
36389
|
+
const stat22 = fs32.statSync(path10.join(dir, file2));
|
|
36390
|
+
return [file2, `${file2}:${stat22.size}:${Math.trunc(stat22.mtimeMs)}`];
|
|
35266
36391
|
} catch {
|
|
35267
36392
|
return [file2, `${file2}:missing`];
|
|
35268
36393
|
}
|
|
@@ -35272,7 +36397,7 @@ ${cleanBody}`;
|
|
|
35272
36397
|
return files.map((file2) => fileSignatures.get(file2) || `${file2}:missing`).join("|");
|
|
35273
36398
|
}
|
|
35274
36399
|
function getSavedHistoryIndexFilePath(dir) {
|
|
35275
|
-
return
|
|
36400
|
+
return path10.join(dir, SAVED_HISTORY_INDEX_FILE);
|
|
35276
36401
|
}
|
|
35277
36402
|
function getSavedHistoryIndexLockPath(dir) {
|
|
35278
36403
|
return `${getSavedHistoryIndexFilePath(dir)}${SAVED_HISTORY_INDEX_LOCK_SUFFIX}`;
|
|
@@ -35325,8 +36450,8 @@ ${cleanBody}`;
|
|
|
35325
36450
|
} catch (error48) {
|
|
35326
36451
|
if (error48?.code !== "EEXIST") return null;
|
|
35327
36452
|
try {
|
|
35328
|
-
const
|
|
35329
|
-
if (Date.now() -
|
|
36453
|
+
const stat22 = fs32.statSync(lockPath);
|
|
36454
|
+
if (Date.now() - stat22.mtimeMs > SAVED_HISTORY_INDEX_LOCK_STALE_MS) {
|
|
35330
36455
|
fs32.rmSync(lockPath, { recursive: true, force: true });
|
|
35331
36456
|
continue;
|
|
35332
36457
|
}
|
|
@@ -35374,7 +36499,7 @@ ${cleanBody}`;
|
|
|
35374
36499
|
}
|
|
35375
36500
|
for (const file2 of Array.from(currentEntries.keys())) {
|
|
35376
36501
|
if (incomingFiles.has(file2)) continue;
|
|
35377
|
-
if (!fs32.existsSync(
|
|
36502
|
+
if (!fs32.existsSync(path10.join(dir, file2))) {
|
|
35378
36503
|
currentEntries.delete(file2);
|
|
35379
36504
|
}
|
|
35380
36505
|
}
|
|
@@ -35389,8 +36514,8 @@ ${cleanBody}`;
|
|
|
35389
36514
|
}
|
|
35390
36515
|
function buildSavedHistoryIndexFileSignature(dir) {
|
|
35391
36516
|
try {
|
|
35392
|
-
const
|
|
35393
|
-
return `index:${
|
|
36517
|
+
const stat22 = fs32.statSync(getSavedHistoryIndexFilePath(dir));
|
|
36518
|
+
return `index:${stat22.size}:${Math.trunc(stat22.mtimeMs)}`;
|
|
35394
36519
|
} catch {
|
|
35395
36520
|
return "index:missing";
|
|
35396
36521
|
}
|
|
@@ -35400,8 +36525,8 @@ ${cleanBody}`;
|
|
|
35400
36525
|
const indexStat = fs32.statSync(getSavedHistoryIndexFilePath(dir));
|
|
35401
36526
|
const files = listHistoryFiles(dir);
|
|
35402
36527
|
for (const file2 of files) {
|
|
35403
|
-
const
|
|
35404
|
-
if (
|
|
36528
|
+
const stat22 = fs32.statSync(path10.join(dir, file2));
|
|
36529
|
+
if (stat22.mtimeMs > indexStat.mtimeMs) return true;
|
|
35405
36530
|
}
|
|
35406
36531
|
return false;
|
|
35407
36532
|
} catch {
|
|
@@ -35410,14 +36535,14 @@ ${cleanBody}`;
|
|
|
35410
36535
|
}
|
|
35411
36536
|
function buildSavedHistoryFileSignature(dir, file2) {
|
|
35412
36537
|
try {
|
|
35413
|
-
const
|
|
35414
|
-
return `${file2}:${
|
|
36538
|
+
const stat22 = fs32.statSync(path10.join(dir, file2));
|
|
36539
|
+
return `${file2}:${stat22.size}:${Math.trunc(stat22.mtimeMs)}`;
|
|
35415
36540
|
} catch {
|
|
35416
36541
|
return `${file2}:missing`;
|
|
35417
36542
|
}
|
|
35418
36543
|
}
|
|
35419
36544
|
function persistSavedHistoryFileSummaryEntry(agentType, dir, file2, updater) {
|
|
35420
|
-
const filePath =
|
|
36545
|
+
const filePath = path10.join(dir, file2);
|
|
35421
36546
|
const result = withLockedPersistedSavedHistoryIndex(dir, (entries) => {
|
|
35422
36547
|
const currentEntry = entries.get(file2) || null;
|
|
35423
36548
|
const nextSummary = updater(currentEntry?.summary || null);
|
|
@@ -35490,7 +36615,7 @@ ${cleanBody}`;
|
|
|
35490
36615
|
function computeSavedHistoryFileSummary(dir, file2) {
|
|
35491
36616
|
const historySessionId = extractSavedHistorySessionIdFromFile(file2);
|
|
35492
36617
|
if (!historySessionId) return null;
|
|
35493
|
-
const filePath =
|
|
36618
|
+
const filePath = path10.join(dir, file2);
|
|
35494
36619
|
const content = fs32.readFileSync(filePath, "utf-8");
|
|
35495
36620
|
const lines = content.split("\n").filter(Boolean);
|
|
35496
36621
|
let messageCount = 0;
|
|
@@ -35577,7 +36702,7 @@ ${cleanBody}`;
|
|
|
35577
36702
|
const summaryBySessionId = /* @__PURE__ */ new Map();
|
|
35578
36703
|
const nextPersistedEntries = /* @__PURE__ */ new Map();
|
|
35579
36704
|
for (const file2 of files.slice().sort()) {
|
|
35580
|
-
const filePath =
|
|
36705
|
+
const filePath = path10.join(dir, file2);
|
|
35581
36706
|
const signature = fileSignatures.get(file2) || `${file2}:missing`;
|
|
35582
36707
|
const cached2 = savedHistoryFileSummaryCache.get(filePath);
|
|
35583
36708
|
const persisted = persistedEntries.get(file2);
|
|
@@ -35697,12 +36822,12 @@ ${cleanBody}`;
|
|
|
35697
36822
|
});
|
|
35698
36823
|
}
|
|
35699
36824
|
if (newMessages.length === 0) return;
|
|
35700
|
-
const dir =
|
|
36825
|
+
const dir = path10.join(HISTORY_DIR, this.sanitize(agentType));
|
|
35701
36826
|
fs32.mkdirSync(dir, { recursive: true });
|
|
35702
36827
|
const date5 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
35703
36828
|
const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
|
|
35704
36829
|
const fileName = `${filePrefix}${date5}.jsonl`;
|
|
35705
|
-
const filePath =
|
|
36830
|
+
const filePath = path10.join(dir, fileName);
|
|
35706
36831
|
const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
35707
36832
|
fs32.appendFileSync(filePath, lines, "utf-8");
|
|
35708
36833
|
updateSavedHistoryIndexForAppendedMessages(agentType, dir, fileName, effectiveHistoryKey, newMessages);
|
|
@@ -35793,11 +36918,11 @@ ${cleanBody}`;
|
|
|
35793
36918
|
const ws2 = String(workspace || "").trim();
|
|
35794
36919
|
if (!id || !ws2) return;
|
|
35795
36920
|
try {
|
|
35796
|
-
const dir =
|
|
36921
|
+
const dir = path10.join(HISTORY_DIR, this.sanitize(agentType));
|
|
35797
36922
|
fs32.mkdirSync(dir, { recursive: true });
|
|
35798
36923
|
const date5 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
35799
36924
|
const fileName = `${this.sanitize(id)}_${date5}.jsonl`;
|
|
35800
|
-
const filePath =
|
|
36925
|
+
const filePath = path10.join(dir, fileName);
|
|
35801
36926
|
const record2 = {
|
|
35802
36927
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35803
36928
|
receivedAt: Date.now(),
|
|
@@ -35843,14 +36968,14 @@ ${cleanBody}`;
|
|
|
35843
36968
|
this.lastSeenCounts.set(toDedupKey, Math.max(fromCount, this.lastSeenCounts.get(toDedupKey) || 0));
|
|
35844
36969
|
this.lastSeenCounts.delete(fromDedupKey);
|
|
35845
36970
|
}
|
|
35846
|
-
const dir =
|
|
36971
|
+
const dir = path10.join(HISTORY_DIR, this.sanitize(agentType));
|
|
35847
36972
|
if (!fs32.existsSync(dir)) return;
|
|
35848
36973
|
const fromPrefix = `${this.sanitize(fromId)}_`;
|
|
35849
36974
|
const toPrefix = `${this.sanitize(toId)}_`;
|
|
35850
36975
|
const files = fs32.readdirSync(dir).filter((file2) => file2.startsWith(fromPrefix) && file2.endsWith(".jsonl"));
|
|
35851
36976
|
for (const file2 of files) {
|
|
35852
|
-
const sourcePath =
|
|
35853
|
-
const targetPath =
|
|
36977
|
+
const sourcePath = path10.join(dir, file2);
|
|
36978
|
+
const targetPath = path10.join(dir, `${toPrefix}${file2.slice(fromPrefix.length)}`);
|
|
35854
36979
|
const sourceLines = fs32.readFileSync(sourcePath, "utf-8").split("\n").filter(Boolean);
|
|
35855
36980
|
const rewritten = sourceLines.map((line) => {
|
|
35856
36981
|
try {
|
|
@@ -35884,13 +37009,13 @@ ${cleanBody}`;
|
|
|
35884
37009
|
const sessionId = String(historySessionId || "").trim();
|
|
35885
37010
|
if (!sessionId) return;
|
|
35886
37011
|
try {
|
|
35887
|
-
const dir =
|
|
37012
|
+
const dir = path10.join(HISTORY_DIR, this.sanitize(agentType));
|
|
35888
37013
|
if (!fs32.existsSync(dir)) return;
|
|
35889
37014
|
const prefix = `${this.sanitize(sessionId)}_`;
|
|
35890
37015
|
const files = fs32.readdirSync(dir).filter((file2) => file2.startsWith(prefix) && file2.endsWith(".jsonl")).sort();
|
|
35891
37016
|
const seen = /* @__PURE__ */ new Set();
|
|
35892
37017
|
for (const file2 of files) {
|
|
35893
|
-
const filePath =
|
|
37018
|
+
const filePath = path10.join(dir, file2);
|
|
35894
37019
|
const lines = fs32.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
|
|
35895
37020
|
const next = [];
|
|
35896
37021
|
for (const line of lines) {
|
|
@@ -35944,13 +37069,13 @@ ${cleanBody}`;
|
|
|
35944
37069
|
const cutoff = Date.now() - RETAIN_DAYS * 24 * 60 * 60 * 1e3;
|
|
35945
37070
|
const agentDirs = fs32.readdirSync(HISTORY_DIR, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
35946
37071
|
for (const dir of agentDirs) {
|
|
35947
|
-
const dirPath =
|
|
37072
|
+
const dirPath = path10.join(HISTORY_DIR, dir.name);
|
|
35948
37073
|
const files = fs32.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
|
|
35949
37074
|
let removedAny = false;
|
|
35950
37075
|
for (const file2 of files) {
|
|
35951
|
-
const filePath =
|
|
35952
|
-
const
|
|
35953
|
-
if (
|
|
37076
|
+
const filePath = path10.join(dirPath, file2);
|
|
37077
|
+
const stat22 = fs32.statSync(filePath);
|
|
37078
|
+
if (stat22.mtimeMs < cutoff) {
|
|
35954
37079
|
fs32.unlinkSync(filePath);
|
|
35955
37080
|
removedAny = true;
|
|
35956
37081
|
}
|
|
@@ -35998,13 +37123,13 @@ ${cleanBody}`;
|
|
|
35998
37123
|
function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
|
|
35999
37124
|
try {
|
|
36000
37125
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
36001
|
-
const dir =
|
|
37126
|
+
const dir = path10.join(HISTORY_DIR, sanitized);
|
|
36002
37127
|
if (!fs32.existsSync(dir)) return { messages: [], hasMore: false };
|
|
36003
37128
|
const files = listHistoryFiles(dir, historySessionId);
|
|
36004
37129
|
const allMessages = [];
|
|
36005
37130
|
const seen = /* @__PURE__ */ new Set();
|
|
36006
37131
|
for (const file2 of files) {
|
|
36007
|
-
const filePath =
|
|
37132
|
+
const filePath = path10.join(dir, file2);
|
|
36008
37133
|
const content = fs32.readFileSync(filePath, "utf-8");
|
|
36009
37134
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
36010
37135
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -36028,7 +37153,7 @@ ${cleanBody}`;
|
|
|
36028
37153
|
function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
36029
37154
|
try {
|
|
36030
37155
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
36031
|
-
const dir =
|
|
37156
|
+
const dir = path10.join(HISTORY_DIR, sanitized);
|
|
36032
37157
|
if (!fs32.existsSync(dir)) {
|
|
36033
37158
|
savedHistorySessionCache.delete(sanitized);
|
|
36034
37159
|
return { sessions: [], hasMore: false };
|
|
@@ -36089,11 +37214,11 @@ ${cleanBody}`;
|
|
|
36089
37214
|
}
|
|
36090
37215
|
function readExistingSessionStartRecord(agentType, historySessionId) {
|
|
36091
37216
|
try {
|
|
36092
|
-
const dir =
|
|
37217
|
+
const dir = path10.join(HISTORY_DIR, agentType);
|
|
36093
37218
|
if (!fs32.existsSync(dir)) return null;
|
|
36094
37219
|
const files = listHistoryFiles(dir, historySessionId).sort();
|
|
36095
37220
|
for (const file2 of files) {
|
|
36096
|
-
const lines = fs32.readFileSync(
|
|
37221
|
+
const lines = fs32.readFileSync(path10.join(dir, file2), "utf-8").split("\n").filter(Boolean);
|
|
36097
37222
|
for (const line of lines) {
|
|
36098
37223
|
try {
|
|
36099
37224
|
const parsed = JSON.parse(line);
|
|
@@ -36113,16 +37238,16 @@ ${cleanBody}`;
|
|
|
36113
37238
|
function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
|
|
36114
37239
|
if (records.length === 0) return false;
|
|
36115
37240
|
try {
|
|
36116
|
-
const dir =
|
|
37241
|
+
const dir = path10.join(HISTORY_DIR, agentType);
|
|
36117
37242
|
fs32.mkdirSync(dir, { recursive: true });
|
|
36118
37243
|
const prefix = `${historySessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
|
|
36119
37244
|
for (const file2 of fs32.readdirSync(dir)) {
|
|
36120
37245
|
if (file2.startsWith(prefix) && file2.endsWith(".jsonl")) {
|
|
36121
|
-
fs32.unlinkSync(
|
|
37246
|
+
fs32.unlinkSync(path10.join(dir, file2));
|
|
36122
37247
|
}
|
|
36123
37248
|
}
|
|
36124
37249
|
const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
|
|
36125
|
-
const filePath =
|
|
37250
|
+
const filePath = path10.join(dir, `${prefix}${targetDate}.jsonl`);
|
|
36126
37251
|
fs32.writeFileSync(filePath, `${records.map((record2) => JSON.stringify(record2)).join("\n")}
|
|
36127
37252
|
`, "utf-8");
|
|
36128
37253
|
invalidatePersistedSavedHistoryIndex(agentType, dir);
|
|
@@ -37966,6 +39091,10 @@ ${effect.notification.body || ""}`.trim();
|
|
|
37966
39091
|
function shouldIncludeRuntimeMetadata(profile) {
|
|
37967
39092
|
return true;
|
|
37968
39093
|
}
|
|
39094
|
+
function getGitSummaryForWorkspace(workspace, options) {
|
|
39095
|
+
if (!workspace) return void 0;
|
|
39096
|
+
return options.getGitSummaryForWorkspace?.(workspace) || void 0;
|
|
39097
|
+
}
|
|
37969
39098
|
function findCdpManager(cdpManagers, key) {
|
|
37970
39099
|
const exact = cdpManagers.get(key);
|
|
37971
39100
|
if (exact) return exact.isConnected ? exact : null;
|
|
@@ -38021,6 +39150,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38021
39150
|
const controlValues = normalizeProviderStateControlValues(state.controlValues);
|
|
38022
39151
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
38023
39152
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
39153
|
+
const workspace = state.workspace || null;
|
|
39154
|
+
const git = getGitSummaryForWorkspace(workspace, options);
|
|
38024
39155
|
const title = activeChat?.title || state.name;
|
|
38025
39156
|
return {
|
|
38026
39157
|
id: state.instanceId || state.type,
|
|
@@ -38033,7 +39164,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38033
39164
|
activeModal: activeChat?.activeModal || null
|
|
38034
39165
|
}),
|
|
38035
39166
|
title,
|
|
38036
|
-
workspace
|
|
39167
|
+
workspace,
|
|
39168
|
+
...git && { git },
|
|
38037
39169
|
activeChat,
|
|
38038
39170
|
...summaryMetadata && { summaryMetadata },
|
|
38039
39171
|
...includeSessionMetadata && { capabilities: state.sessionCapabilities || IDE_SESSION_CAPABILITIES },
|
|
@@ -38054,6 +39186,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38054
39186
|
const controlValues = normalizeProviderStateControlValues(ext.controlValues);
|
|
38055
39187
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
38056
39188
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
39189
|
+
const workspace = parent.workspace || null;
|
|
39190
|
+
const git = getGitSummaryForWorkspace(workspace, options);
|
|
38057
39191
|
return {
|
|
38058
39192
|
id: ext.instanceId || `${parent.instanceId}:${ext.type}`,
|
|
38059
39193
|
parentId: parent.instanceId || parent.type,
|
|
@@ -38066,7 +39200,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38066
39200
|
activeModal: activeChat?.activeModal || null
|
|
38067
39201
|
}),
|
|
38068
39202
|
title: activeChat?.title || ext.name,
|
|
38069
|
-
workspace
|
|
39203
|
+
workspace,
|
|
39204
|
+
...git && { git },
|
|
38070
39205
|
activeChat,
|
|
38071
39206
|
...summaryMetadata && { summaryMetadata },
|
|
38072
39207
|
...includeSessionMetadata && { capabilities: ext.sessionCapabilities || EXTENSION_SESSION_CAPABILITIES },
|
|
@@ -38102,6 +39237,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38102
39237
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
38103
39238
|
const includeRuntimeMetadata = shouldIncludeRuntimeMetadata(profile);
|
|
38104
39239
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
39240
|
+
const workspace = state.workspace || null;
|
|
39241
|
+
const git = getGitSummaryForWorkspace(workspace, options);
|
|
38105
39242
|
return {
|
|
38106
39243
|
id: state.instanceId,
|
|
38107
39244
|
parentId: null,
|
|
@@ -38114,7 +39251,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38114
39251
|
activeModal: activeChat?.activeModal || null
|
|
38115
39252
|
}),
|
|
38116
39253
|
title: activeChat?.title || state.name,
|
|
38117
|
-
workspace
|
|
39254
|
+
workspace,
|
|
39255
|
+
...git && { git },
|
|
38118
39256
|
...includeRuntimeMetadata && {
|
|
38119
39257
|
runtimeKey: state.runtime?.runtimeKey,
|
|
38120
39258
|
runtimeDisplayName: state.runtime?.displayName,
|
|
@@ -38149,6 +39287,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38149
39287
|
const controlValues = normalizeProviderStateControlValues(state.controlValues);
|
|
38150
39288
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
38151
39289
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
39290
|
+
const workspace = state.workspace || null;
|
|
39291
|
+
const git = getGitSummaryForWorkspace(workspace, options);
|
|
38152
39292
|
return {
|
|
38153
39293
|
id: state.instanceId,
|
|
38154
39294
|
parentId: null,
|
|
@@ -38160,7 +39300,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38160
39300
|
activeModal: activeChat?.activeModal || null
|
|
38161
39301
|
}),
|
|
38162
39302
|
title: activeChat?.title || state.name,
|
|
38163
|
-
workspace
|
|
39303
|
+
workspace,
|
|
39304
|
+
...git && { git },
|
|
38164
39305
|
activeChat,
|
|
38165
39306
|
...summaryMetadata && { summaryMetadata },
|
|
38166
39307
|
...includeSessionMetadata && { capabilities: ACP_SESSION_CAPABILITIES },
|
|
@@ -38271,7 +39412,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38271
39412
|
}
|
|
38272
39413
|
var fs42 = __toESM2(require("fs"));
|
|
38273
39414
|
var os62 = __toESM2(require("os"));
|
|
38274
|
-
var
|
|
39415
|
+
var path11 = __toESM2(require("path"));
|
|
38275
39416
|
var import_node_crypto = require("crypto");
|
|
38276
39417
|
init_contracts();
|
|
38277
39418
|
var VALID_INPUT_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
|
|
@@ -38954,7 +40095,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38954
40095
|
}
|
|
38955
40096
|
function getChatDebugBundleDir() {
|
|
38956
40097
|
const override = typeof process.env.ADHDEV_DEBUG_BUNDLE_DIR === "string" ? process.env.ADHDEV_DEBUG_BUNDLE_DIR.trim() : "";
|
|
38957
|
-
return override ||
|
|
40098
|
+
return override || path11.join(os62.homedir(), ".adhdev", "debug-bundles", "chat");
|
|
38958
40099
|
}
|
|
38959
40100
|
function safeBundleIdSegment(value, fallback) {
|
|
38960
40101
|
const normalized = String(value || fallback).trim().replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
@@ -38987,7 +40128,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38987
40128
|
const bundleId = createChatDebugBundleId(targetSessionId);
|
|
38988
40129
|
const dir = getChatDebugBundleDir();
|
|
38989
40130
|
fs42.mkdirSync(dir, { recursive: true });
|
|
38990
|
-
const savedPath =
|
|
40131
|
+
const savedPath = path11.join(dir, `${bundleId}.json`);
|
|
38991
40132
|
const json2 = `${JSON.stringify(bundle, null, 2)}
|
|
38992
40133
|
`;
|
|
38993
40134
|
fs42.writeFileSync(savedPath, json2, { encoding: "utf8", mode: 384 });
|
|
@@ -39181,7 +40322,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
39181
40322
|
async function getStableExtensionBaseline(h) {
|
|
39182
40323
|
const first = await readExtensionChatState(h);
|
|
39183
40324
|
if (getStateMessageCount(first) > 0 || getStateLastSignature(first)) return first;
|
|
39184
|
-
await new Promise((
|
|
40325
|
+
await new Promise((resolve15) => setTimeout(resolve15, 150));
|
|
39185
40326
|
const second = await readExtensionChatState(h);
|
|
39186
40327
|
return getStateMessageCount(second) >= getStateMessageCount(first) ? second : first;
|
|
39187
40328
|
}
|
|
@@ -39189,7 +40330,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
39189
40330
|
const beforeCount = getStateMessageCount(before);
|
|
39190
40331
|
const beforeSignature = getStateLastSignature(before);
|
|
39191
40332
|
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
39192
|
-
await new Promise((
|
|
40333
|
+
await new Promise((resolve15) => setTimeout(resolve15, 250));
|
|
39193
40334
|
const state = await readExtensionChatState(h);
|
|
39194
40335
|
if (state?.status === "waiting_approval") return true;
|
|
39195
40336
|
const afterCount = getStateMessageCount(state);
|
|
@@ -40123,7 +41264,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
40123
41264
|
return { success: false, error: "resolveAction script not available for this provider" };
|
|
40124
41265
|
}
|
|
40125
41266
|
var fs52 = __toESM2(require("fs"));
|
|
40126
|
-
var
|
|
41267
|
+
var path12 = __toESM2(require("path"));
|
|
40127
41268
|
var os7 = __toESM2(require("os"));
|
|
40128
41269
|
var KEY_TO_VK = {
|
|
40129
41270
|
Backspace: 8,
|
|
@@ -40380,25 +41521,25 @@ ${effect.notification.body || ""}`.trim();
|
|
|
40380
41521
|
const inputPath = rawPath || ".";
|
|
40381
41522
|
const home = os7.homedir();
|
|
40382
41523
|
if (inputPath.startsWith("~")) {
|
|
40383
|
-
return
|
|
41524
|
+
return path12.resolve(path12.join(home, inputPath.slice(1)));
|
|
40384
41525
|
}
|
|
40385
41526
|
if (process.platform === "win32") {
|
|
40386
41527
|
const normalized = normalizeWindowsRequestedPath(inputPath);
|
|
40387
|
-
if (
|
|
40388
|
-
return
|
|
41528
|
+
if (path12.win32.isAbsolute(normalized)) {
|
|
41529
|
+
return path12.win32.normalize(normalized);
|
|
40389
41530
|
}
|
|
40390
|
-
return
|
|
41531
|
+
return path12.win32.resolve(normalized);
|
|
40391
41532
|
}
|
|
40392
|
-
if (
|
|
40393
|
-
return
|
|
41533
|
+
if (path12.isAbsolute(inputPath)) {
|
|
41534
|
+
return path12.normalize(inputPath);
|
|
40394
41535
|
}
|
|
40395
|
-
return
|
|
41536
|
+
return path12.resolve(inputPath);
|
|
40396
41537
|
}
|
|
40397
41538
|
function listDirectoryEntriesSafe(dirPath) {
|
|
40398
41539
|
const entries = fs52.readdirSync(dirPath, { withFileTypes: true });
|
|
40399
41540
|
const files = [];
|
|
40400
41541
|
for (const entry of entries) {
|
|
40401
|
-
const entryPath =
|
|
41542
|
+
const entryPath = path12.join(dirPath, entry.name);
|
|
40402
41543
|
try {
|
|
40403
41544
|
if (entry.isDirectory()) {
|
|
40404
41545
|
files.push({ name: entry.name, type: "directory" });
|
|
@@ -40414,11 +41555,11 @@ ${effect.notification.body || ""}`.trim();
|
|
|
40414
41555
|
files.push({ name: entry.name, type: "file", size });
|
|
40415
41556
|
continue;
|
|
40416
41557
|
}
|
|
40417
|
-
const
|
|
41558
|
+
const stat22 = fs52.statSync(entryPath);
|
|
40418
41559
|
files.push({
|
|
40419
41560
|
name: entry.name,
|
|
40420
|
-
type:
|
|
40421
|
-
size:
|
|
41561
|
+
type: stat22.isDirectory() ? "directory" : "file",
|
|
41562
|
+
size: stat22.isFile() ? stat22.size : void 0
|
|
40422
41563
|
});
|
|
40423
41564
|
} catch {
|
|
40424
41565
|
}
|
|
@@ -40452,7 +41593,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
40452
41593
|
async function handleFileWrite(h, args) {
|
|
40453
41594
|
try {
|
|
40454
41595
|
const filePath = resolveSafePath(args?.path);
|
|
40455
|
-
fs52.mkdirSync(
|
|
41596
|
+
fs52.mkdirSync(path12.dirname(filePath), { recursive: true });
|
|
40456
41597
|
fs52.writeFileSync(filePath, args?.content || "", "utf-8");
|
|
40457
41598
|
return { success: true, path: filePath };
|
|
40458
41599
|
} catch (e) {
|
|
@@ -40793,7 +41934,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
40793
41934
|
const enterCount = cliCommand.enterCount || 1;
|
|
40794
41935
|
await adapter.writeRaw(cliCommand.text + "\r");
|
|
40795
41936
|
for (let i = 1; i < enterCount; i += 1) {
|
|
40796
|
-
await new Promise((
|
|
41937
|
+
await new Promise((resolve15) => setTimeout(resolve15, 50));
|
|
40797
41938
|
await adapter.writeRaw("\r");
|
|
40798
41939
|
}
|
|
40799
41940
|
}
|
|
@@ -41283,6 +42424,12 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41283
42424
|
this._currentRoute = this.resolveRoute(args);
|
|
41284
42425
|
const startedAt = Date.now();
|
|
41285
42426
|
this.logCommandStart(cmd, args);
|
|
42427
|
+
let result;
|
|
42428
|
+
if (isGitCommandName(cmd)) {
|
|
42429
|
+
result = await handleGitCommand(cmd, args, this._ctx.gitCommandServices);
|
|
42430
|
+
this.logCommandEnd(cmd, result, startedAt);
|
|
42431
|
+
return result;
|
|
42432
|
+
}
|
|
41286
42433
|
const sessionScopedCommands = /* @__PURE__ */ new Set([
|
|
41287
42434
|
"read_chat",
|
|
41288
42435
|
"get_chat_debug_bundle",
|
|
@@ -41308,7 +42455,6 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41308
42455
|
this.logCommandEnd(cmd, result2, startedAt);
|
|
41309
42456
|
return result2;
|
|
41310
42457
|
}
|
|
41311
|
-
let result;
|
|
41312
42458
|
if (!this._currentRoute.session && !this._currentRoute.managerKey && !this._currentRoute.providerType) {
|
|
41313
42459
|
const cdpCommands = ["send_chat", "read_chat", "list_chats", "new_chat", "switch_chat", "set_mode", "change_model", "set_thought_level", "resolve_action"];
|
|
41314
42460
|
if (cdpCommands.includes(cmd)) {
|
|
@@ -41459,7 +42605,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41459
42605
|
try {
|
|
41460
42606
|
const http3 = await import("http");
|
|
41461
42607
|
const postData = JSON.stringify(body);
|
|
41462
|
-
const result = await new Promise((
|
|
42608
|
+
const result = await new Promise((resolve15, reject) => {
|
|
41463
42609
|
const req = http3.request({
|
|
41464
42610
|
hostname: "127.0.0.1",
|
|
41465
42611
|
port: 19280,
|
|
@@ -41471,9 +42617,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41471
42617
|
res.on("data", (chunk) => data += chunk);
|
|
41472
42618
|
res.on("end", () => {
|
|
41473
42619
|
try {
|
|
41474
|
-
|
|
42620
|
+
resolve15(JSON.parse(data));
|
|
41475
42621
|
} catch {
|
|
41476
|
-
|
|
42622
|
+
resolve15({ raw: data });
|
|
41477
42623
|
}
|
|
41478
42624
|
});
|
|
41479
42625
|
});
|
|
@@ -41491,15 +42637,15 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41491
42637
|
if (!providerType) return { success: false, error: "providerType required" };
|
|
41492
42638
|
try {
|
|
41493
42639
|
const http3 = await import("http");
|
|
41494
|
-
const result = await new Promise((
|
|
42640
|
+
const result = await new Promise((resolve15, reject) => {
|
|
41495
42641
|
http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
|
|
41496
42642
|
let data = "";
|
|
41497
42643
|
res.on("data", (chunk) => data += chunk);
|
|
41498
42644
|
res.on("end", () => {
|
|
41499
42645
|
try {
|
|
41500
|
-
|
|
42646
|
+
resolve15(JSON.parse(data));
|
|
41501
42647
|
} catch {
|
|
41502
|
-
|
|
42648
|
+
resolve15({ raw: data });
|
|
41503
42649
|
}
|
|
41504
42650
|
});
|
|
41505
42651
|
}).on("error", reject);
|
|
@@ -41513,7 +42659,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41513
42659
|
try {
|
|
41514
42660
|
const http3 = await import("http");
|
|
41515
42661
|
const postData = JSON.stringify(args || {});
|
|
41516
|
-
const result = await new Promise((
|
|
42662
|
+
const result = await new Promise((resolve15, reject) => {
|
|
41517
42663
|
const req = http3.request({
|
|
41518
42664
|
hostname: "127.0.0.1",
|
|
41519
42665
|
port: 19280,
|
|
@@ -41525,9 +42671,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41525
42671
|
res.on("data", (chunk) => data += chunk);
|
|
41526
42672
|
res.on("end", () => {
|
|
41527
42673
|
try {
|
|
41528
|
-
|
|
42674
|
+
resolve15(JSON.parse(data));
|
|
41529
42675
|
} catch {
|
|
41530
|
-
|
|
42676
|
+
resolve15({ raw: data });
|
|
41531
42677
|
}
|
|
41532
42678
|
});
|
|
41533
42679
|
});
|
|
@@ -41542,7 +42688,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41542
42688
|
}
|
|
41543
42689
|
};
|
|
41544
42690
|
var os13 = __toESM2(require("os"));
|
|
41545
|
-
var
|
|
42691
|
+
var path16 = __toESM2(require("path"));
|
|
41546
42692
|
var crypto4 = __toESM2(require("crypto"));
|
|
41547
42693
|
var import_fs5 = require("fs");
|
|
41548
42694
|
var import_child_process6 = require("child_process");
|
|
@@ -41550,7 +42696,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41550
42696
|
init_provider_cli_adapter();
|
|
41551
42697
|
init_config();
|
|
41552
42698
|
var os12 = __toESM2(require("os"));
|
|
41553
|
-
var
|
|
42699
|
+
var path15 = __toESM2(require("path"));
|
|
41554
42700
|
var crypto3 = __toESM2(require("crypto"));
|
|
41555
42701
|
var fs6 = __toESM2(require("fs"));
|
|
41556
42702
|
var import_node_module = require("module");
|
|
@@ -41607,7 +42753,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41607
42753
|
var CachedDatabaseSync = null;
|
|
41608
42754
|
function getDatabaseSync() {
|
|
41609
42755
|
if (CachedDatabaseSync) return CachedDatabaseSync;
|
|
41610
|
-
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(
|
|
42756
|
+
const requireFn = typeof require === "function" ? require : (0, import_node_module.createRequire)(path15.join(process.cwd(), "__adhdev_sqlite_loader__.js"));
|
|
41611
42757
|
const sqliteModule = requireFn(`node:${"sqlite"}`);
|
|
41612
42758
|
CachedDatabaseSync = sqliteModule.DatabaseSync;
|
|
41613
42759
|
if (!CachedDatabaseSync) {
|
|
@@ -41645,7 +42791,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41645
42791
|
if (status === "stopped") {
|
|
41646
42792
|
throw new Error("CLI runtime stopped before it became ready");
|
|
41647
42793
|
}
|
|
41648
|
-
await new Promise((
|
|
42794
|
+
await new Promise((resolve15) => setTimeout(resolve15, pollMs));
|
|
41649
42795
|
}
|
|
41650
42796
|
throw new Error(`CLI runtime did not become ready within ${timeoutMs}ms`);
|
|
41651
42797
|
}
|
|
@@ -41996,7 +43142,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41996
43142
|
const enterCount = cliCommand.enterCount || 1;
|
|
41997
43143
|
await this.adapter.writeRaw(cliCommand.text + "\r");
|
|
41998
43144
|
for (let i = 1; i < enterCount; i += 1) {
|
|
41999
|
-
await new Promise((
|
|
43145
|
+
await new Promise((resolve15) => setTimeout(resolve15, 50));
|
|
42000
43146
|
await this.adapter.writeRaw("\r");
|
|
42001
43147
|
}
|
|
42002
43148
|
}
|
|
@@ -43108,13 +44254,13 @@ ${effect.notification.body || ""}`.trim();
|
|
|
43108
44254
|
}
|
|
43109
44255
|
this.currentStatus = "waiting_approval";
|
|
43110
44256
|
this.detectStatusTransition();
|
|
43111
|
-
const approved = await new Promise((
|
|
43112
|
-
this.permissionResolvers.push(
|
|
44257
|
+
const approved = await new Promise((resolve15) => {
|
|
44258
|
+
this.permissionResolvers.push(resolve15);
|
|
43113
44259
|
setTimeout(() => {
|
|
43114
|
-
const idx = this.permissionResolvers.indexOf(
|
|
44260
|
+
const idx = this.permissionResolvers.indexOf(resolve15);
|
|
43115
44261
|
if (idx >= 0) {
|
|
43116
44262
|
this.permissionResolvers.splice(idx, 1);
|
|
43117
|
-
|
|
44263
|
+
resolve15(false);
|
|
43118
44264
|
}
|
|
43119
44265
|
}, 3e5);
|
|
43120
44266
|
});
|
|
@@ -43683,11 +44829,11 @@ ${rawInput}` : rawInput;
|
|
|
43683
44829
|
}
|
|
43684
44830
|
function isExplicitCommand(command) {
|
|
43685
44831
|
const trimmed = command.trim();
|
|
43686
|
-
return
|
|
44832
|
+
return path16.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
43687
44833
|
}
|
|
43688
44834
|
function expandExecutable(command) {
|
|
43689
44835
|
const trimmed = command.trim();
|
|
43690
|
-
return trimmed.startsWith("~") ?
|
|
44836
|
+
return trimmed.startsWith("~") ? path16.join(os13.homedir(), trimmed.slice(1)) : trimmed;
|
|
43691
44837
|
}
|
|
43692
44838
|
function commandExists(command) {
|
|
43693
44839
|
const trimmed = command.trim();
|
|
@@ -43968,7 +45114,7 @@ ${rawInput}` : rawInput;
|
|
|
43968
45114
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
43969
45115
|
const trimmed = (workingDir || "").trim();
|
|
43970
45116
|
if (!trimmed) throw new Error("working directory required");
|
|
43971
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) :
|
|
45117
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path16.resolve(trimmed);
|
|
43972
45118
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
43973
45119
|
const rawProvider = this.providerLoader.getByAlias(cliType);
|
|
43974
45120
|
const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
|
|
@@ -44467,9 +45613,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44467
45613
|
var import_child_process7 = require("child_process");
|
|
44468
45614
|
var net3 = __toESM2(require("net"));
|
|
44469
45615
|
var os15 = __toESM2(require("os"));
|
|
44470
|
-
var
|
|
45616
|
+
var path18 = __toESM2(require("path"));
|
|
44471
45617
|
var fs7 = __toESM2(require("fs"));
|
|
44472
|
-
var
|
|
45618
|
+
var path17 = __toESM2(require("path"));
|
|
44473
45619
|
var os14 = __toESM2(require("os"));
|
|
44474
45620
|
var chokidar = __toESM2((init_chokidar(), __toCommonJS(chokidar_exports)));
|
|
44475
45621
|
init_logger();
|
|
@@ -44730,7 +45876,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44730
45876
|
try {
|
|
44731
45877
|
if (!fs7.existsSync(candidate) || !fs7.statSync(candidate).isDirectory()) return false;
|
|
44732
45878
|
return ["ide", "extension", "cli", "acp"].some(
|
|
44733
|
-
(category) => fs7.existsSync(
|
|
45879
|
+
(category) => fs7.existsSync(path17.join(candidate, category))
|
|
44734
45880
|
);
|
|
44735
45881
|
} catch {
|
|
44736
45882
|
return false;
|
|
@@ -44738,20 +45884,20 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44738
45884
|
}
|
|
44739
45885
|
static hasProviderRootMarker(candidate) {
|
|
44740
45886
|
try {
|
|
44741
|
-
return fs7.existsSync(
|
|
45887
|
+
return fs7.existsSync(path17.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
|
|
44742
45888
|
} catch {
|
|
44743
45889
|
return false;
|
|
44744
45890
|
}
|
|
44745
45891
|
}
|
|
44746
45892
|
detectDefaultUserDir() {
|
|
44747
|
-
const fallback =
|
|
45893
|
+
const fallback = path17.join(os14.homedir(), ".adhdev", "providers");
|
|
44748
45894
|
const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
|
|
44749
45895
|
const visited = /* @__PURE__ */ new Set();
|
|
44750
45896
|
for (const start of this.probeStarts) {
|
|
44751
|
-
let current =
|
|
45897
|
+
let current = path17.resolve(start);
|
|
44752
45898
|
while (!visited.has(current)) {
|
|
44753
45899
|
visited.add(current);
|
|
44754
|
-
const siblingCandidate =
|
|
45900
|
+
const siblingCandidate = path17.join(path17.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
|
|
44755
45901
|
if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
|
|
44756
45902
|
const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
|
|
44757
45903
|
if (envOptIn || hasMarker) {
|
|
@@ -44773,7 +45919,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44773
45919
|
return { path: siblingCandidate, source };
|
|
44774
45920
|
}
|
|
44775
45921
|
}
|
|
44776
|
-
const parent =
|
|
45922
|
+
const parent = path17.dirname(current);
|
|
44777
45923
|
if (parent === current) break;
|
|
44778
45924
|
current = parent;
|
|
44779
45925
|
}
|
|
@@ -44783,11 +45929,11 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44783
45929
|
constructor(options) {
|
|
44784
45930
|
this.logFn = options?.logFn || LOG2.forComponent("Provider").asLogFn();
|
|
44785
45931
|
this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
|
|
44786
|
-
this.defaultProvidersDir =
|
|
45932
|
+
this.defaultProvidersDir = path17.join(os14.homedir(), ".adhdev", "providers");
|
|
44787
45933
|
const detected = this.detectDefaultUserDir();
|
|
44788
45934
|
this.userDir = detected.path;
|
|
44789
45935
|
this.userDirSource = detected.source;
|
|
44790
|
-
this.upstreamDir =
|
|
45936
|
+
this.upstreamDir = path17.join(this.defaultProvidersDir, ".upstream");
|
|
44791
45937
|
this.disableUpstream = false;
|
|
44792
45938
|
this.applySourceConfig({
|
|
44793
45939
|
userDir: options?.userDir,
|
|
@@ -44846,7 +45992,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44846
45992
|
this.userDir = detected.path;
|
|
44847
45993
|
this.userDirSource = detected.source;
|
|
44848
45994
|
}
|
|
44849
|
-
this.upstreamDir =
|
|
45995
|
+
this.upstreamDir = path17.join(this.defaultProvidersDir, ".upstream");
|
|
44850
45996
|
this.disableUpstream = this.sourceMode === "no-upstream";
|
|
44851
45997
|
if (this.explicitProviderDir) {
|
|
44852
45998
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
@@ -44860,7 +46006,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44860
46006
|
* Canonical provider directory shape for a given root.
|
|
44861
46007
|
*/
|
|
44862
46008
|
getProviderDir(root, category, type) {
|
|
44863
|
-
return
|
|
46009
|
+
return path17.join(root, category, type);
|
|
44864
46010
|
}
|
|
44865
46011
|
/**
|
|
44866
46012
|
* Canonical user override directory for a provider.
|
|
@@ -44887,7 +46033,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44887
46033
|
resolveProviderFile(type, ...segments) {
|
|
44888
46034
|
const dir = this.findProviderDirInternal(type);
|
|
44889
46035
|
if (!dir) return null;
|
|
44890
|
-
return
|
|
46036
|
+
return path17.join(dir, ...segments);
|
|
44891
46037
|
}
|
|
44892
46038
|
/**
|
|
44893
46039
|
* Load all providers (3-tier priority)
|
|
@@ -44926,7 +46072,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44926
46072
|
if (!fs7.existsSync(this.upstreamDir)) return false;
|
|
44927
46073
|
try {
|
|
44928
46074
|
return fs7.readdirSync(this.upstreamDir).some(
|
|
44929
|
-
(d) => fs7.statSync(
|
|
46075
|
+
(d) => fs7.statSync(path17.join(this.upstreamDir, d)).isDirectory()
|
|
44930
46076
|
);
|
|
44931
46077
|
} catch {
|
|
44932
46078
|
return false;
|
|
@@ -45423,8 +46569,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45423
46569
|
resolved._resolvedScriptDir = entry.scriptDir;
|
|
45424
46570
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
45425
46571
|
if (providerDir) {
|
|
45426
|
-
const fullDir =
|
|
45427
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
46572
|
+
const fullDir = path17.join(providerDir, entry.scriptDir);
|
|
46573
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path17.join(fullDir, "scripts.js")) ? path17.join(fullDir, "scripts.js") : fullDir;
|
|
45428
46574
|
}
|
|
45429
46575
|
matched = true;
|
|
45430
46576
|
}
|
|
@@ -45439,8 +46585,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45439
46585
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
45440
46586
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
45441
46587
|
if (providerDir) {
|
|
45442
|
-
const fullDir =
|
|
45443
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
46588
|
+
const fullDir = path17.join(providerDir, base.defaultScriptDir);
|
|
46589
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path17.join(fullDir, "scripts.js")) ? path17.join(fullDir, "scripts.js") : fullDir;
|
|
45444
46590
|
}
|
|
45445
46591
|
}
|
|
45446
46592
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -45457,8 +46603,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45457
46603
|
resolved._resolvedScriptDir = dirOverride;
|
|
45458
46604
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
45459
46605
|
if (providerDir) {
|
|
45460
|
-
const fullDir =
|
|
45461
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
46606
|
+
const fullDir = path17.join(providerDir, dirOverride);
|
|
46607
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path17.join(fullDir, "scripts.js")) ? path17.join(fullDir, "scripts.js") : fullDir;
|
|
45462
46608
|
}
|
|
45463
46609
|
}
|
|
45464
46610
|
} else if (override.scripts) {
|
|
@@ -45474,8 +46620,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45474
46620
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
45475
46621
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
45476
46622
|
if (providerDir) {
|
|
45477
|
-
const fullDir =
|
|
45478
|
-
resolved._resolvedScriptsPath = fs7.existsSync(
|
|
46623
|
+
const fullDir = path17.join(providerDir, base.defaultScriptDir);
|
|
46624
|
+
resolved._resolvedScriptsPath = fs7.existsSync(path17.join(fullDir, "scripts.js")) ? path17.join(fullDir, "scripts.js") : fullDir;
|
|
45479
46625
|
}
|
|
45480
46626
|
}
|
|
45481
46627
|
}
|
|
@@ -45507,14 +46653,14 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45507
46653
|
this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
|
|
45508
46654
|
return null;
|
|
45509
46655
|
}
|
|
45510
|
-
const dir =
|
|
46656
|
+
const dir = path17.join(providerDir, scriptDir);
|
|
45511
46657
|
if (!fs7.existsSync(dir)) {
|
|
45512
46658
|
this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
45513
46659
|
return null;
|
|
45514
46660
|
}
|
|
45515
46661
|
const cached2 = this.scriptsCache.get(dir);
|
|
45516
46662
|
if (cached2) return cached2;
|
|
45517
|
-
const scriptsJs =
|
|
46663
|
+
const scriptsJs = path17.join(dir, "scripts.js");
|
|
45518
46664
|
if (fs7.existsSync(scriptsJs)) {
|
|
45519
46665
|
try {
|
|
45520
46666
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -45556,7 +46702,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45556
46702
|
return;
|
|
45557
46703
|
}
|
|
45558
46704
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
45559
|
-
this.log(`File changed: ${
|
|
46705
|
+
this.log(`File changed: ${path17.basename(filePath)}, reloading...`);
|
|
45560
46706
|
this.reload();
|
|
45561
46707
|
}
|
|
45562
46708
|
};
|
|
@@ -45611,7 +46757,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45611
46757
|
}
|
|
45612
46758
|
const https = require("https");
|
|
45613
46759
|
const { execSync: execSync7 } = require("child_process");
|
|
45614
|
-
const metaPath =
|
|
46760
|
+
const metaPath = path17.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
45615
46761
|
let prevEtag = "";
|
|
45616
46762
|
let prevTimestamp = 0;
|
|
45617
46763
|
try {
|
|
@@ -45628,7 +46774,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45628
46774
|
return { updated: false };
|
|
45629
46775
|
}
|
|
45630
46776
|
try {
|
|
45631
|
-
const etag = await new Promise((
|
|
46777
|
+
const etag = await new Promise((resolve15, reject) => {
|
|
45632
46778
|
const options = {
|
|
45633
46779
|
method: "HEAD",
|
|
45634
46780
|
hostname: "github.com",
|
|
@@ -45646,7 +46792,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45646
46792
|
headers: { "User-Agent": "adhdev-launcher" },
|
|
45647
46793
|
timeout: 1e4
|
|
45648
46794
|
}, (res2) => {
|
|
45649
|
-
|
|
46795
|
+
resolve15(res2.headers.etag || res2.headers["last-modified"] || "");
|
|
45650
46796
|
});
|
|
45651
46797
|
req2.on("error", reject);
|
|
45652
46798
|
req2.on("timeout", () => {
|
|
@@ -45655,7 +46801,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45655
46801
|
});
|
|
45656
46802
|
req2.end();
|
|
45657
46803
|
} else {
|
|
45658
|
-
|
|
46804
|
+
resolve15(res.headers.etag || res.headers["last-modified"] || "");
|
|
45659
46805
|
}
|
|
45660
46806
|
});
|
|
45661
46807
|
req.on("error", reject);
|
|
@@ -45671,17 +46817,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45671
46817
|
return { updated: false };
|
|
45672
46818
|
}
|
|
45673
46819
|
this.log("Downloading latest providers from GitHub...");
|
|
45674
|
-
const tmpTar =
|
|
45675
|
-
const tmpExtract =
|
|
46820
|
+
const tmpTar = path17.join(os14.tmpdir(), `adhdev-providers-${Date.now()}.tar.gz`);
|
|
46821
|
+
const tmpExtract = path17.join(os14.tmpdir(), `adhdev-providers-extract-${Date.now()}`);
|
|
45676
46822
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
45677
46823
|
fs7.mkdirSync(tmpExtract, { recursive: true });
|
|
45678
46824
|
execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
45679
46825
|
const extracted = fs7.readdirSync(tmpExtract);
|
|
45680
46826
|
const rootDir = extracted.find(
|
|
45681
|
-
(d) => fs7.statSync(
|
|
46827
|
+
(d) => fs7.statSync(path17.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
45682
46828
|
);
|
|
45683
46829
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
45684
|
-
const sourceDir =
|
|
46830
|
+
const sourceDir = path17.join(tmpExtract, rootDir);
|
|
45685
46831
|
const backupDir = this.upstreamDir + ".bak";
|
|
45686
46832
|
if (fs7.existsSync(this.upstreamDir)) {
|
|
45687
46833
|
if (fs7.existsSync(backupDir)) fs7.rmSync(backupDir, { recursive: true, force: true });
|
|
@@ -45719,7 +46865,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45719
46865
|
downloadFile(url2, destPath) {
|
|
45720
46866
|
const https = require("https");
|
|
45721
46867
|
const http3 = require("http");
|
|
45722
|
-
return new Promise((
|
|
46868
|
+
return new Promise((resolve15, reject) => {
|
|
45723
46869
|
const doRequest = (reqUrl, redirectCount = 0) => {
|
|
45724
46870
|
if (redirectCount > 5) {
|
|
45725
46871
|
reject(new Error("Too many redirects"));
|
|
@@ -45739,7 +46885,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45739
46885
|
res.pipe(ws2);
|
|
45740
46886
|
ws2.on("finish", () => {
|
|
45741
46887
|
ws2.close();
|
|
45742
|
-
|
|
46888
|
+
resolve15();
|
|
45743
46889
|
});
|
|
45744
46890
|
ws2.on("error", reject);
|
|
45745
46891
|
});
|
|
@@ -45756,8 +46902,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45756
46902
|
copyDirRecursive(src, dest) {
|
|
45757
46903
|
fs7.mkdirSync(dest, { recursive: true });
|
|
45758
46904
|
for (const entry of fs7.readdirSync(src, { withFileTypes: true })) {
|
|
45759
|
-
const srcPath =
|
|
45760
|
-
const destPath =
|
|
46905
|
+
const srcPath = path17.join(src, entry.name);
|
|
46906
|
+
const destPath = path17.join(dest, entry.name);
|
|
45761
46907
|
if (entry.isDirectory()) {
|
|
45762
46908
|
this.copyDirRecursive(srcPath, destPath);
|
|
45763
46909
|
} else {
|
|
@@ -45768,7 +46914,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45768
46914
|
/** .meta.json save */
|
|
45769
46915
|
writeMeta(metaPath, etag, timestamp) {
|
|
45770
46916
|
try {
|
|
45771
|
-
fs7.mkdirSync(
|
|
46917
|
+
fs7.mkdirSync(path17.dirname(metaPath), { recursive: true });
|
|
45772
46918
|
fs7.writeFileSync(metaPath, JSON.stringify({
|
|
45773
46919
|
etag,
|
|
45774
46920
|
timestamp,
|
|
@@ -45785,7 +46931,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45785
46931
|
const scan = (d) => {
|
|
45786
46932
|
try {
|
|
45787
46933
|
for (const entry of fs7.readdirSync(d, { withFileTypes: true })) {
|
|
45788
|
-
if (entry.isDirectory()) scan(
|
|
46934
|
+
if (entry.isDirectory()) scan(path17.join(d, entry.name));
|
|
45789
46935
|
else if (entry.name === "provider.json") count++;
|
|
45790
46936
|
}
|
|
45791
46937
|
} catch {
|
|
@@ -46013,17 +47159,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46013
47159
|
for (const root of searchRoots) {
|
|
46014
47160
|
if (!fs7.existsSync(root)) continue;
|
|
46015
47161
|
const candidate = this.getProviderDir(root, cat, type);
|
|
46016
|
-
if (fs7.existsSync(
|
|
46017
|
-
const catDir =
|
|
47162
|
+
if (fs7.existsSync(path17.join(candidate, "provider.json"))) return candidate;
|
|
47163
|
+
const catDir = path17.join(root, cat);
|
|
46018
47164
|
if (fs7.existsSync(catDir)) {
|
|
46019
47165
|
try {
|
|
46020
47166
|
for (const entry of fs7.readdirSync(catDir, { withFileTypes: true })) {
|
|
46021
47167
|
if (!entry.isDirectory()) continue;
|
|
46022
|
-
const jsonPath =
|
|
47168
|
+
const jsonPath = path17.join(catDir, entry.name, "provider.json");
|
|
46023
47169
|
if (fs7.existsSync(jsonPath)) {
|
|
46024
47170
|
try {
|
|
46025
47171
|
const data = JSON.parse(fs7.readFileSync(jsonPath, "utf-8"));
|
|
46026
|
-
if (data.type === type) return
|
|
47172
|
+
if (data.type === type) return path17.join(catDir, entry.name);
|
|
46027
47173
|
} catch {
|
|
46028
47174
|
}
|
|
46029
47175
|
}
|
|
@@ -46040,7 +47186,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46040
47186
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
46041
47187
|
*/
|
|
46042
47188
|
buildScriptWrappersFromDir(dir) {
|
|
46043
|
-
const scriptsJs =
|
|
47189
|
+
const scriptsJs = path17.join(dir, "scripts.js");
|
|
46044
47190
|
if (fs7.existsSync(scriptsJs)) {
|
|
46045
47191
|
try {
|
|
46046
47192
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -46054,7 +47200,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46054
47200
|
for (const file2 of fs7.readdirSync(dir)) {
|
|
46055
47201
|
if (!file2.endsWith(".js")) continue;
|
|
46056
47202
|
const scriptName = toCamel(file2.replace(".js", ""));
|
|
46057
|
-
const filePath =
|
|
47203
|
+
const filePath = path17.join(dir, file2);
|
|
46058
47204
|
result[scriptName] = (...args) => {
|
|
46059
47205
|
try {
|
|
46060
47206
|
let content = fs7.readFileSync(filePath, "utf-8");
|
|
@@ -46114,7 +47260,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46114
47260
|
}
|
|
46115
47261
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
46116
47262
|
if (hasJson) {
|
|
46117
|
-
const jsonPath =
|
|
47263
|
+
const jsonPath = path17.join(d, "provider.json");
|
|
46118
47264
|
try {
|
|
46119
47265
|
const raw = fs7.readFileSync(jsonPath, "utf-8");
|
|
46120
47266
|
const mod = JSON.parse(raw);
|
|
@@ -46135,7 +47281,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46135
47281
|
this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
|
|
46136
47282
|
} else {
|
|
46137
47283
|
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
46138
|
-
const scriptsPath =
|
|
47284
|
+
const scriptsPath = path17.join(d, "scripts.js");
|
|
46139
47285
|
if (!hasCompatibility && fs7.existsSync(scriptsPath)) {
|
|
46140
47286
|
try {
|
|
46141
47287
|
delete require.cache[require.resolve(scriptsPath)];
|
|
@@ -46161,7 +47307,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46161
47307
|
if (!entry.isDirectory()) continue;
|
|
46162
47308
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
46163
47309
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
46164
|
-
scan(
|
|
47310
|
+
scan(path17.join(d, entry.name));
|
|
46165
47311
|
}
|
|
46166
47312
|
}
|
|
46167
47313
|
};
|
|
@@ -46196,9 +47342,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46196
47342
|
}
|
|
46197
47343
|
}
|
|
46198
47344
|
compareVersions(a, b2) {
|
|
46199
|
-
const
|
|
46200
|
-
const pa2 =
|
|
46201
|
-
const pb =
|
|
47345
|
+
const normalize4 = (v2) => v2.split(/[-_+]/)[0].split(".").map((x) => parseInt(x, 10) || 0);
|
|
47346
|
+
const pa2 = normalize4(a);
|
|
47347
|
+
const pb = normalize4(b2);
|
|
46202
47348
|
for (let i = 0; i < Math.max(pa2.length, pb.length); i++) {
|
|
46203
47349
|
const va2 = pa2[i] || 0;
|
|
46204
47350
|
const vb = pb[i] || 0;
|
|
@@ -46314,17 +47460,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46314
47460
|
throw new Error("No free port found");
|
|
46315
47461
|
}
|
|
46316
47462
|
function checkPortFree(port) {
|
|
46317
|
-
return new Promise((
|
|
47463
|
+
return new Promise((resolve15) => {
|
|
46318
47464
|
const server = net3.createServer();
|
|
46319
47465
|
server.unref();
|
|
46320
|
-
server.on("error", () =>
|
|
47466
|
+
server.on("error", () => resolve15(false));
|
|
46321
47467
|
server.listen(port, "127.0.0.1", () => {
|
|
46322
|
-
server.close(() =>
|
|
47468
|
+
server.close(() => resolve15(true));
|
|
46323
47469
|
});
|
|
46324
47470
|
});
|
|
46325
47471
|
}
|
|
46326
47472
|
async function isCdpActive(port) {
|
|
46327
|
-
return new Promise((
|
|
47473
|
+
return new Promise((resolve15) => {
|
|
46328
47474
|
const req = require("http").get(`http://127.0.0.1:${port}/json/version`, {
|
|
46329
47475
|
timeout: 2e3
|
|
46330
47476
|
}, (res) => {
|
|
@@ -46333,16 +47479,16 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46333
47479
|
res.on("end", () => {
|
|
46334
47480
|
try {
|
|
46335
47481
|
const info = JSON.parse(data);
|
|
46336
|
-
|
|
47482
|
+
resolve15(!!info["WebKit-Version"] || !!info["Browser"]);
|
|
46337
47483
|
} catch {
|
|
46338
|
-
|
|
47484
|
+
resolve15(false);
|
|
46339
47485
|
}
|
|
46340
47486
|
});
|
|
46341
47487
|
});
|
|
46342
|
-
req.on("error", () =>
|
|
47488
|
+
req.on("error", () => resolve15(false));
|
|
46343
47489
|
req.on("timeout", () => {
|
|
46344
47490
|
req.destroy();
|
|
46345
|
-
|
|
47491
|
+
resolve15(false);
|
|
46346
47492
|
});
|
|
46347
47493
|
});
|
|
46348
47494
|
}
|
|
@@ -46482,8 +47628,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46482
47628
|
const appNameMap = getMacAppIdentifiers();
|
|
46483
47629
|
const appName = appNameMap[ideId];
|
|
46484
47630
|
if (appName) {
|
|
46485
|
-
const storagePath =
|
|
46486
|
-
process.env.APPDATA ||
|
|
47631
|
+
const storagePath = path18.join(
|
|
47632
|
+
process.env.APPDATA || path18.join(os15.homedir(), "AppData", "Roaming"),
|
|
46487
47633
|
appName,
|
|
46488
47634
|
"storage.json"
|
|
46489
47635
|
);
|
|
@@ -46657,9 +47803,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46657
47803
|
init_config();
|
|
46658
47804
|
init_logger();
|
|
46659
47805
|
var fs8 = __toESM2(require("fs"));
|
|
46660
|
-
var
|
|
47806
|
+
var path19 = __toESM2(require("path"));
|
|
46661
47807
|
var os16 = __toESM2(require("os"));
|
|
46662
|
-
var LOG_DIR2 = process.platform === "win32" ?
|
|
47808
|
+
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
47809
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
46664
47810
|
var MAX_DAYS = 7;
|
|
46665
47811
|
try {
|
|
@@ -46697,13 +47843,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46697
47843
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
46698
47844
|
}
|
|
46699
47845
|
var currentDate2 = getDateStr2();
|
|
46700
|
-
var currentFile =
|
|
47846
|
+
var currentFile = path19.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
46701
47847
|
var writeCount2 = 0;
|
|
46702
47848
|
function checkRotation() {
|
|
46703
47849
|
const today = getDateStr2();
|
|
46704
47850
|
if (today !== currentDate2) {
|
|
46705
47851
|
currentDate2 = today;
|
|
46706
|
-
currentFile =
|
|
47852
|
+
currentFile = path19.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
46707
47853
|
cleanOldFiles();
|
|
46708
47854
|
}
|
|
46709
47855
|
}
|
|
@@ -46717,7 +47863,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46717
47863
|
const dateMatch = file2.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
46718
47864
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
46719
47865
|
try {
|
|
46720
|
-
fs8.unlinkSync(
|
|
47866
|
+
fs8.unlinkSync(path19.join(LOG_DIR2, file2));
|
|
46721
47867
|
} catch {
|
|
46722
47868
|
}
|
|
46723
47869
|
}
|
|
@@ -46727,8 +47873,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46727
47873
|
}
|
|
46728
47874
|
function checkSize() {
|
|
46729
47875
|
try {
|
|
46730
|
-
const
|
|
46731
|
-
if (
|
|
47876
|
+
const stat22 = fs8.statSync(currentFile);
|
|
47877
|
+
if (stat22.size > MAX_FILE_SIZE) {
|
|
46732
47878
|
const backup = currentFile.replace(".jsonl", ".1.jsonl");
|
|
46733
47879
|
try {
|
|
46734
47880
|
fs8.unlinkSync(backup);
|
|
@@ -47010,12 +48156,18 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47010
48156
|
const unreadSourceSessions = buildSessionEntries(
|
|
47011
48157
|
options.allStates,
|
|
47012
48158
|
options.cdpManagers,
|
|
47013
|
-
{
|
|
48159
|
+
{
|
|
48160
|
+
profile: "full",
|
|
48161
|
+
getGitSummaryForWorkspace: options.getGitSummaryForWorkspace
|
|
48162
|
+
}
|
|
47014
48163
|
);
|
|
47015
48164
|
const sessions = profile === "full" ? unreadSourceSessions : profile === "live" ? unreadSourceSessions.map(projectLiveSessionFromFull) : buildSessionEntries(
|
|
47016
48165
|
options.allStates,
|
|
47017
48166
|
options.cdpManagers,
|
|
47018
|
-
{
|
|
48167
|
+
{
|
|
48168
|
+
profile,
|
|
48169
|
+
getGitSummaryForWorkspace: options.getGitSummaryForWorkspace
|
|
48170
|
+
}
|
|
47019
48171
|
);
|
|
47020
48172
|
const sessionsById = new Map(sessions.map((session) => [session.id, session]));
|
|
47021
48173
|
for (const sourceSession of unreadSourceSessions) {
|
|
@@ -47107,13 +48259,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47107
48259
|
var import_child_process9 = require("child_process");
|
|
47108
48260
|
var fs9 = __toESM2(require("fs"));
|
|
47109
48261
|
var os18 = __toESM2(require("os"));
|
|
47110
|
-
var
|
|
48262
|
+
var path20 = __toESM2(require("path"));
|
|
47111
48263
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
47112
48264
|
function getUpgradeLogPath() {
|
|
47113
48265
|
const home = os18.homedir();
|
|
47114
|
-
const dir =
|
|
48266
|
+
const dir = path20.join(home, ".adhdev");
|
|
47115
48267
|
fs9.mkdirSync(dir, { recursive: true });
|
|
47116
|
-
return
|
|
48268
|
+
return path20.join(dir, "daemon-upgrade.log");
|
|
47117
48269
|
}
|
|
47118
48270
|
function appendUpgradeLog(message) {
|
|
47119
48271
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
@@ -47124,14 +48276,14 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47124
48276
|
}
|
|
47125
48277
|
}
|
|
47126
48278
|
function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platform) {
|
|
47127
|
-
const binDir =
|
|
48279
|
+
const binDir = path20.dirname(nodeExecutable);
|
|
47128
48280
|
if (platform10 === "win32") {
|
|
47129
|
-
const npmCliPath =
|
|
48281
|
+
const npmCliPath = path20.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
|
|
47130
48282
|
if (fs9.existsSync(npmCliPath)) {
|
|
47131
48283
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
47132
48284
|
}
|
|
47133
48285
|
for (const candidate of ["npm.exe", "npm"]) {
|
|
47134
|
-
const candidatePath =
|
|
48286
|
+
const candidatePath = path20.join(binDir, candidate);
|
|
47135
48287
|
if (fs9.existsSync(candidatePath)) {
|
|
47136
48288
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
47137
48289
|
}
|
|
@@ -47139,7 +48291,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47139
48291
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
47140
48292
|
}
|
|
47141
48293
|
for (const candidate of ["npm"]) {
|
|
47142
|
-
const candidatePath =
|
|
48294
|
+
const candidatePath = path20.join(binDir, candidate);
|
|
47143
48295
|
if (fs9.existsSync(candidatePath)) {
|
|
47144
48296
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
47145
48297
|
}
|
|
@@ -47156,13 +48308,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47156
48308
|
let currentDir = resolvedPath;
|
|
47157
48309
|
try {
|
|
47158
48310
|
if (fs9.statSync(resolvedPath).isFile()) {
|
|
47159
|
-
currentDir =
|
|
48311
|
+
currentDir = path20.dirname(resolvedPath);
|
|
47160
48312
|
}
|
|
47161
48313
|
} catch {
|
|
47162
|
-
currentDir =
|
|
48314
|
+
currentDir = path20.dirname(resolvedPath);
|
|
47163
48315
|
}
|
|
47164
48316
|
while (true) {
|
|
47165
|
-
const packageJsonPath =
|
|
48317
|
+
const packageJsonPath = path20.join(currentDir, "package.json");
|
|
47166
48318
|
try {
|
|
47167
48319
|
if (fs9.existsSync(packageJsonPath)) {
|
|
47168
48320
|
const parsed = JSON.parse(fs9.readFileSync(packageJsonPath, "utf8"));
|
|
@@ -47173,7 +48325,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47173
48325
|
}
|
|
47174
48326
|
} catch {
|
|
47175
48327
|
}
|
|
47176
|
-
const parentDir =
|
|
48328
|
+
const parentDir = path20.dirname(currentDir);
|
|
47177
48329
|
if (parentDir === currentDir) {
|
|
47178
48330
|
return null;
|
|
47179
48331
|
}
|
|
@@ -47181,13 +48333,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47181
48333
|
}
|
|
47182
48334
|
}
|
|
47183
48335
|
function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
|
|
47184
|
-
const nodeModulesDir = packageName.startsWith("@") ?
|
|
47185
|
-
if (
|
|
48336
|
+
const nodeModulesDir = packageName.startsWith("@") ? path20.dirname(path20.dirname(packageRoot)) : path20.dirname(packageRoot);
|
|
48337
|
+
if (path20.basename(nodeModulesDir) !== "node_modules") {
|
|
47186
48338
|
return null;
|
|
47187
48339
|
}
|
|
47188
|
-
const maybeLibDir =
|
|
47189
|
-
if (
|
|
47190
|
-
return
|
|
48340
|
+
const maybeLibDir = path20.dirname(nodeModulesDir);
|
|
48341
|
+
if (path20.basename(maybeLibDir) === "lib") {
|
|
48342
|
+
return path20.dirname(maybeLibDir);
|
|
47191
48343
|
}
|
|
47192
48344
|
return maybeLibDir;
|
|
47193
48345
|
}
|
|
@@ -47295,14 +48447,14 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47295
48447
|
while (Date.now() - start < timeoutMs) {
|
|
47296
48448
|
try {
|
|
47297
48449
|
process.kill(pid, 0);
|
|
47298
|
-
await new Promise((
|
|
48450
|
+
await new Promise((resolve15) => setTimeout(resolve15, 250));
|
|
47299
48451
|
} catch {
|
|
47300
48452
|
return;
|
|
47301
48453
|
}
|
|
47302
48454
|
}
|
|
47303
48455
|
}
|
|
47304
48456
|
function stopSessionHostProcesses(appName) {
|
|
47305
|
-
const pidFile =
|
|
48457
|
+
const pidFile = path20.join(os18.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
47306
48458
|
try {
|
|
47307
48459
|
if (fs9.existsSync(pidFile)) {
|
|
47308
48460
|
const pid = Number.parseInt(fs9.readFileSync(pidFile, "utf8").trim(), 10);
|
|
@@ -47319,7 +48471,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47319
48471
|
}
|
|
47320
48472
|
}
|
|
47321
48473
|
function removeDaemonPidFile() {
|
|
47322
|
-
const pidFile =
|
|
48474
|
+
const pidFile = path20.join(os18.homedir(), ".adhdev", "daemon.pid");
|
|
47323
48475
|
try {
|
|
47324
48476
|
fs9.unlinkSync(pidFile);
|
|
47325
48477
|
} catch {
|
|
@@ -47330,7 +48482,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47330
48482
|
const npmRoot = String(execNpmCommandSync(["root", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
47331
48483
|
if (!npmRoot) return;
|
|
47332
48484
|
const npmPrefix = surface.installPrefix || String(execNpmCommandSync(["prefix", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
47333
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
48485
|
+
const binDir = process.platform === "win32" ? npmPrefix : path20.join(npmPrefix, "bin");
|
|
47334
48486
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
47335
48487
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
47336
48488
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -47338,25 +48490,25 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47338
48490
|
}
|
|
47339
48491
|
if (pkgName.startsWith("@")) {
|
|
47340
48492
|
const [scope, name] = pkgName.split("/");
|
|
47341
|
-
const scopeDir =
|
|
48493
|
+
const scopeDir = path20.join(npmRoot, scope);
|
|
47342
48494
|
if (!fs9.existsSync(scopeDir)) return;
|
|
47343
48495
|
for (const entry of fs9.readdirSync(scopeDir)) {
|
|
47344
48496
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
47345
|
-
fs9.rmSync(
|
|
47346
|
-
appendUpgradeLog(`Removed stale scoped staging dir: ${
|
|
48497
|
+
fs9.rmSync(path20.join(scopeDir, entry), { recursive: true, force: true });
|
|
48498
|
+
appendUpgradeLog(`Removed stale scoped staging dir: ${path20.join(scopeDir, entry)}`);
|
|
47347
48499
|
}
|
|
47348
48500
|
} else {
|
|
47349
48501
|
for (const entry of fs9.readdirSync(npmRoot)) {
|
|
47350
48502
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
47351
|
-
fs9.rmSync(
|
|
47352
|
-
appendUpgradeLog(`Removed stale staging dir: ${
|
|
48503
|
+
fs9.rmSync(path20.join(npmRoot, entry), { recursive: true, force: true });
|
|
48504
|
+
appendUpgradeLog(`Removed stale staging dir: ${path20.join(npmRoot, entry)}`);
|
|
47353
48505
|
}
|
|
47354
48506
|
}
|
|
47355
48507
|
if (fs9.existsSync(binDir)) {
|
|
47356
48508
|
for (const entry of fs9.readdirSync(binDir)) {
|
|
47357
48509
|
if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
47358
|
-
fs9.rmSync(
|
|
47359
|
-
appendUpgradeLog(`Removed stale bin staging entry: ${
|
|
48510
|
+
fs9.rmSync(path20.join(binDir, entry), { recursive: true, force: true });
|
|
48511
|
+
appendUpgradeLog(`Removed stale bin staging entry: ${path20.join(binDir, entry)}`);
|
|
47360
48512
|
}
|
|
47361
48513
|
}
|
|
47362
48514
|
}
|
|
@@ -47406,7 +48558,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47406
48558
|
appendUpgradeLog(installOutput.trim());
|
|
47407
48559
|
}
|
|
47408
48560
|
if (process.platform === "win32") {
|
|
47409
|
-
await new Promise((
|
|
48561
|
+
await new Promise((resolve15) => setTimeout(resolve15, 500));
|
|
47410
48562
|
cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
|
|
47411
48563
|
appendUpgradeLog("Post-install staging cleanup complete");
|
|
47412
48564
|
}
|
|
@@ -48786,7 +49938,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
48786
49938
|
const beforeCount = this.messageCount(before);
|
|
48787
49939
|
const beforeSignature = this.lastMessageSignature(before);
|
|
48788
49940
|
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
48789
|
-
await new Promise((
|
|
49941
|
+
await new Promise((resolve15) => setTimeout(resolve15, 250));
|
|
48790
49942
|
let state;
|
|
48791
49943
|
try {
|
|
48792
49944
|
state = await this.readChat(evaluate);
|
|
@@ -48808,7 +49960,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
48808
49960
|
if (this.messageCount(first) > 0 || this.lastMessageSignature(first)) {
|
|
48809
49961
|
return first;
|
|
48810
49962
|
}
|
|
48811
|
-
await new Promise((
|
|
49963
|
+
await new Promise((resolve15) => setTimeout(resolve15, 150));
|
|
48812
49964
|
const second = await this.readChat(evaluate);
|
|
48813
49965
|
return this.messageCount(second) >= this.messageCount(first) ? second : first;
|
|
48814
49966
|
}
|
|
@@ -48959,7 +50111,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
48959
50111
|
if (typeof data.error === "string" && data.error.trim()) return false;
|
|
48960
50112
|
}
|
|
48961
50113
|
for (let attempt = 0; attempt < 6; attempt += 1) {
|
|
48962
|
-
await new Promise((
|
|
50114
|
+
await new Promise((resolve15) => setTimeout(resolve15, 250));
|
|
48963
50115
|
const state = await this.readChat(evaluate);
|
|
48964
50116
|
const title = this.getStateTitle(state);
|
|
48965
50117
|
if (this.titlesMatch(title, sessionId)) return true;
|
|
@@ -49808,11 +50960,11 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
49808
50960
|
init_io_contracts();
|
|
49809
50961
|
init_chat_message_normalization();
|
|
49810
50962
|
var fs11 = __toESM2(require("fs"));
|
|
49811
|
-
var
|
|
50963
|
+
var path21 = __toESM2(require("path"));
|
|
49812
50964
|
var os19 = __toESM2(require("os"));
|
|
49813
50965
|
var import_child_process10 = require("child_process");
|
|
49814
50966
|
var import_os3 = require("os");
|
|
49815
|
-
var ARCHIVE_PATH =
|
|
50967
|
+
var ARCHIVE_PATH = path21.join(os19.homedir(), ".adhdev", "version-history.json");
|
|
49816
50968
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
49817
50969
|
var VersionArchive = class {
|
|
49818
50970
|
history = {};
|
|
@@ -49859,7 +51011,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
49859
51011
|
}
|
|
49860
51012
|
save() {
|
|
49861
51013
|
try {
|
|
49862
|
-
fs11.mkdirSync(
|
|
51014
|
+
fs11.mkdirSync(path21.dirname(ARCHIVE_PATH), { recursive: true });
|
|
49863
51015
|
fs11.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
49864
51016
|
} catch {
|
|
49865
51017
|
}
|
|
@@ -49916,7 +51068,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
49916
51068
|
for (const p of paths) {
|
|
49917
51069
|
if (p.includes("*")) {
|
|
49918
51070
|
const home = os19.homedir();
|
|
49919
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
51071
|
+
const resolved = p.replace(/\*/g, home.split(path21.sep).pop() || "");
|
|
49920
51072
|
if (fs11.existsSync(resolved)) return resolved;
|
|
49921
51073
|
} else {
|
|
49922
51074
|
if (fs11.existsSync(p)) return p;
|
|
@@ -49926,7 +51078,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
49926
51078
|
}
|
|
49927
51079
|
function getMacAppVersion(appPath) {
|
|
49928
51080
|
if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
49929
|
-
const plistPath =
|
|
51081
|
+
const plistPath = path21.join(appPath, "Contents", "Info.plist");
|
|
49930
51082
|
if (!fs11.existsSync(plistPath)) return null;
|
|
49931
51083
|
const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
49932
51084
|
return raw || null;
|
|
@@ -49952,7 +51104,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
49952
51104
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
49953
51105
|
let resolvedBin = cliBin;
|
|
49954
51106
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
49955
|
-
const bundled =
|
|
51107
|
+
const bundled = path21.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
49956
51108
|
if (provider.cli && fs11.existsSync(bundled)) resolvedBin = bundled;
|
|
49957
51109
|
}
|
|
49958
51110
|
info.installed = !!(appPath || resolvedBin);
|
|
@@ -49991,7 +51143,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
49991
51143
|
}
|
|
49992
51144
|
var http2 = __toESM2(require("http"));
|
|
49993
51145
|
var fs15 = __toESM2(require("fs"));
|
|
49994
|
-
var
|
|
51146
|
+
var path25 = __toESM2(require("path"));
|
|
49995
51147
|
init_config();
|
|
49996
51148
|
function generateFiles(type, name, category, opts = {}) {
|
|
49997
51149
|
const { cdpPorts, cli, processName, installPath, binary, extensionId, version: version2 = "0.1" } = opts;
|
|
@@ -50336,7 +51488,7 @@ async (params) => {
|
|
|
50336
51488
|
}
|
|
50337
51489
|
init_logger();
|
|
50338
51490
|
var fs12 = __toESM2(require("fs"));
|
|
50339
|
-
var
|
|
51491
|
+
var path222 = __toESM2(require("path"));
|
|
50340
51492
|
init_logger();
|
|
50341
51493
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
50342
51494
|
const body = await ctx.readBody(req);
|
|
@@ -50515,17 +51667,17 @@ async (params) => {
|
|
|
50515
51667
|
return;
|
|
50516
51668
|
}
|
|
50517
51669
|
let scriptsPath = "";
|
|
50518
|
-
const directScripts =
|
|
51670
|
+
const directScripts = path222.join(dir, "scripts.js");
|
|
50519
51671
|
if (fs12.existsSync(directScripts)) {
|
|
50520
51672
|
scriptsPath = directScripts;
|
|
50521
51673
|
} else {
|
|
50522
|
-
const scriptsDir =
|
|
51674
|
+
const scriptsDir = path222.join(dir, "scripts");
|
|
50523
51675
|
if (fs12.existsSync(scriptsDir)) {
|
|
50524
51676
|
const versions = fs12.readdirSync(scriptsDir).filter((d) => {
|
|
50525
|
-
return fs12.statSync(
|
|
51677
|
+
return fs12.statSync(path222.join(scriptsDir, d)).isDirectory();
|
|
50526
51678
|
}).sort().reverse();
|
|
50527
51679
|
for (const ver of versions) {
|
|
50528
|
-
const p =
|
|
51680
|
+
const p = path222.join(scriptsDir, ver, "scripts.js");
|
|
50529
51681
|
if (fs12.existsSync(p)) {
|
|
50530
51682
|
scriptsPath = p;
|
|
50531
51683
|
break;
|
|
@@ -51352,7 +52504,7 @@ async (params) => {
|
|
|
51352
52504
|
}
|
|
51353
52505
|
}
|
|
51354
52506
|
var fs13 = __toESM2(require("fs"));
|
|
51355
|
-
var
|
|
52507
|
+
var path232 = __toESM2(require("path"));
|
|
51356
52508
|
function slugifyFixtureName(value) {
|
|
51357
52509
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
51358
52510
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -51362,11 +52514,11 @@ async (params) => {
|
|
|
51362
52514
|
if (!providerDir) {
|
|
51363
52515
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
51364
52516
|
}
|
|
51365
|
-
return
|
|
52517
|
+
return path232.join(providerDir, "fixtures");
|
|
51366
52518
|
}
|
|
51367
52519
|
function readCliFixture(ctx, type, name) {
|
|
51368
52520
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
51369
|
-
const filePath =
|
|
52521
|
+
const filePath = path232.join(fixtureDir, `${name}.json`);
|
|
51370
52522
|
if (!fs13.existsSync(filePath)) {
|
|
51371
52523
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
51372
52524
|
}
|
|
@@ -51535,7 +52687,7 @@ async (params) => {
|
|
|
51535
52687
|
return { target, instance, adapter };
|
|
51536
52688
|
}
|
|
51537
52689
|
function sleep(ms2) {
|
|
51538
|
-
return new Promise((
|
|
52690
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms2));
|
|
51539
52691
|
}
|
|
51540
52692
|
async function waitForCliReady(ctx, type, instanceId, timeoutMs) {
|
|
51541
52693
|
const startedAt = Date.now();
|
|
@@ -51833,7 +52985,7 @@ async (params) => {
|
|
|
51833
52985
|
return {
|
|
51834
52986
|
mode: "fixture_replay_suite",
|
|
51835
52987
|
pass: results.every((item) => item.pass),
|
|
51836
|
-
failures: results.flatMap((item) => item.failures.map((
|
|
52988
|
+
failures: results.flatMap((item) => item.failures.map((failure2) => `${item.fixtureName}: ${failure2}`)),
|
|
51837
52989
|
result: firstFailure.result,
|
|
51838
52990
|
assertions: firstFailure.assertions,
|
|
51839
52991
|
fixture: firstFailure.fixture,
|
|
@@ -52133,7 +53285,7 @@ async (params) => {
|
|
|
52133
53285
|
},
|
|
52134
53286
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
52135
53287
|
};
|
|
52136
|
-
const filePath =
|
|
53288
|
+
const filePath = path232.join(fixtureDir, `${name}.json`);
|
|
52137
53289
|
fs13.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
52138
53290
|
ctx.json(res, 200, {
|
|
52139
53291
|
saved: true,
|
|
@@ -52157,7 +53309,7 @@ async (params) => {
|
|
|
52157
53309
|
return;
|
|
52158
53310
|
}
|
|
52159
53311
|
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 =
|
|
53312
|
+
const fullPath = path232.join(fixtureDir, file2);
|
|
52161
53313
|
try {
|
|
52162
53314
|
const raw = JSON.parse(fs13.readFileSync(fullPath, "utf-8"));
|
|
52163
53315
|
return {
|
|
@@ -52291,7 +53443,7 @@ async (params) => {
|
|
|
52291
53443
|
}
|
|
52292
53444
|
}
|
|
52293
53445
|
var fs14 = __toESM2(require("fs"));
|
|
52294
|
-
var
|
|
53446
|
+
var path24 = __toESM2(require("path"));
|
|
52295
53447
|
var os20 = __toESM2(require("os"));
|
|
52296
53448
|
function getAutoImplPid(ctx) {
|
|
52297
53449
|
const pid = ctx.autoImplProcess?.pid;
|
|
@@ -52341,22 +53493,22 @@ async (params) => {
|
|
|
52341
53493
|
if (!fs14.existsSync(scriptsDir)) return null;
|
|
52342
53494
|
const versions = fs14.readdirSync(scriptsDir).filter((d) => {
|
|
52343
53495
|
try {
|
|
52344
|
-
return fs14.statSync(
|
|
53496
|
+
return fs14.statSync(path24.join(scriptsDir, d)).isDirectory();
|
|
52345
53497
|
} catch {
|
|
52346
53498
|
return false;
|
|
52347
53499
|
}
|
|
52348
53500
|
}).sort((a, b2) => b2.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
52349
53501
|
if (versions.length === 0) return null;
|
|
52350
|
-
return
|
|
53502
|
+
return path24.join(scriptsDir, versions[0]);
|
|
52351
53503
|
}
|
|
52352
53504
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
52353
|
-
const canonicalUserDir =
|
|
52354
|
-
const desiredDir = requestedDir ?
|
|
52355
|
-
const upstreamRoot =
|
|
52356
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
53505
|
+
const canonicalUserDir = path24.resolve(ctx.providerLoader.getUserProviderDir(category, type));
|
|
53506
|
+
const desiredDir = requestedDir ? path24.resolve(requestedDir) : canonicalUserDir;
|
|
53507
|
+
const upstreamRoot = path24.resolve(ctx.providerLoader.getUpstreamDir());
|
|
53508
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path24.sep}`)) {
|
|
52357
53509
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
52358
53510
|
}
|
|
52359
|
-
if (
|
|
53511
|
+
if (path24.basename(desiredDir) !== type) {
|
|
52360
53512
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
52361
53513
|
}
|
|
52362
53514
|
const sourceDir = ctx.findProviderDir(type);
|
|
@@ -52364,11 +53516,11 @@ async (params) => {
|
|
|
52364
53516
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
52365
53517
|
}
|
|
52366
53518
|
if (!fs14.existsSync(desiredDir)) {
|
|
52367
|
-
fs14.mkdirSync(
|
|
53519
|
+
fs14.mkdirSync(path24.dirname(desiredDir), { recursive: true });
|
|
52368
53520
|
fs14.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
52369
53521
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
52370
53522
|
}
|
|
52371
|
-
const providerJson =
|
|
53523
|
+
const providerJson = path24.join(desiredDir, "provider.json");
|
|
52372
53524
|
if (!fs14.existsSync(providerJson)) {
|
|
52373
53525
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
52374
53526
|
}
|
|
@@ -52379,13 +53531,13 @@ async (params) => {
|
|
|
52379
53531
|
const refDir = ctx.findProviderDir(referenceType);
|
|
52380
53532
|
if (!refDir || !fs14.existsSync(refDir)) return {};
|
|
52381
53533
|
const referenceScripts = {};
|
|
52382
|
-
const scriptsDir =
|
|
53534
|
+
const scriptsDir = path24.join(refDir, "scripts");
|
|
52383
53535
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
52384
53536
|
if (!latestDir) return referenceScripts;
|
|
52385
53537
|
for (const file2 of fs14.readdirSync(latestDir)) {
|
|
52386
53538
|
if (!file2.endsWith(".js")) continue;
|
|
52387
53539
|
try {
|
|
52388
|
-
referenceScripts[file2] = fs14.readFileSync(
|
|
53540
|
+
referenceScripts[file2] = fs14.readFileSync(path24.join(latestDir, file2), "utf-8");
|
|
52389
53541
|
} catch {
|
|
52390
53542
|
}
|
|
52391
53543
|
}
|
|
@@ -52493,9 +53645,9 @@ async (params) => {
|
|
|
52493
53645
|
});
|
|
52494
53646
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
52495
53647
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
52496
|
-
const tmpDir =
|
|
53648
|
+
const tmpDir = path24.join(os20.tmpdir(), "adhdev-autoimpl");
|
|
52497
53649
|
if (!fs14.existsSync(tmpDir)) fs14.mkdirSync(tmpDir, { recursive: true });
|
|
52498
|
-
const promptFile =
|
|
53650
|
+
const promptFile = path24.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
52499
53651
|
fs14.writeFileSync(promptFile, prompt, "utf-8");
|
|
52500
53652
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
52501
53653
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
@@ -52927,7 +54079,7 @@ async (params) => {
|
|
|
52927
54079
|
setMode: "set_mode.js"
|
|
52928
54080
|
};
|
|
52929
54081
|
const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
|
|
52930
|
-
const scriptsDir =
|
|
54082
|
+
const scriptsDir = path24.join(providerDir, "scripts");
|
|
52931
54083
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
52932
54084
|
if (latestScriptsDir) {
|
|
52933
54085
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -52938,7 +54090,7 @@ async (params) => {
|
|
|
52938
54090
|
for (const file2 of fs14.readdirSync(latestScriptsDir)) {
|
|
52939
54091
|
if (file2.endsWith(".js") && targetFileNames.has(file2)) {
|
|
52940
54092
|
try {
|
|
52941
|
-
const content = fs14.readFileSync(
|
|
54093
|
+
const content = fs14.readFileSync(path24.join(latestScriptsDir, file2), "utf-8");
|
|
52942
54094
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
52943
54095
|
lines.push("```javascript");
|
|
52944
54096
|
lines.push(content);
|
|
@@ -52955,7 +54107,7 @@ async (params) => {
|
|
|
52955
54107
|
lines.push("");
|
|
52956
54108
|
for (const file2 of refFiles) {
|
|
52957
54109
|
try {
|
|
52958
|
-
const content = fs14.readFileSync(
|
|
54110
|
+
const content = fs14.readFileSync(path24.join(latestScriptsDir, file2), "utf-8");
|
|
52959
54111
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
52960
54112
|
lines.push("```javascript");
|
|
52961
54113
|
lines.push(content);
|
|
@@ -52996,10 +54148,10 @@ async (params) => {
|
|
|
52996
54148
|
lines.push("");
|
|
52997
54149
|
}
|
|
52998
54150
|
}
|
|
52999
|
-
const docsDir =
|
|
54151
|
+
const docsDir = path24.join(providerDir, "../../docs");
|
|
53000
54152
|
const loadGuide = (name) => {
|
|
53001
54153
|
try {
|
|
53002
|
-
const p =
|
|
54154
|
+
const p = path24.join(docsDir, name);
|
|
53003
54155
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
53004
54156
|
} catch {
|
|
53005
54157
|
}
|
|
@@ -53236,7 +54388,7 @@ async (params) => {
|
|
|
53236
54388
|
parseApproval: "parse_approval.js"
|
|
53237
54389
|
};
|
|
53238
54390
|
const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
|
|
53239
|
-
const scriptsDir =
|
|
54391
|
+
const scriptsDir = path24.join(providerDir, "scripts");
|
|
53240
54392
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
53241
54393
|
if (latestScriptsDir) {
|
|
53242
54394
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -53248,7 +54400,7 @@ async (params) => {
|
|
|
53248
54400
|
if (!file2.endsWith(".js")) continue;
|
|
53249
54401
|
if (!targetFileNames.has(file2)) continue;
|
|
53250
54402
|
try {
|
|
53251
|
-
const content = fs14.readFileSync(
|
|
54403
|
+
const content = fs14.readFileSync(path24.join(latestScriptsDir, file2), "utf-8");
|
|
53252
54404
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
53253
54405
|
lines.push("```javascript");
|
|
53254
54406
|
lines.push(content);
|
|
@@ -53264,7 +54416,7 @@ async (params) => {
|
|
|
53264
54416
|
lines.push("");
|
|
53265
54417
|
for (const file2 of refFiles) {
|
|
53266
54418
|
try {
|
|
53267
|
-
const content = fs14.readFileSync(
|
|
54419
|
+
const content = fs14.readFileSync(path24.join(latestScriptsDir, file2), "utf-8");
|
|
53268
54420
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
53269
54421
|
lines.push("```javascript");
|
|
53270
54422
|
lines.push(content);
|
|
@@ -53297,10 +54449,10 @@ async (params) => {
|
|
|
53297
54449
|
lines.push("");
|
|
53298
54450
|
}
|
|
53299
54451
|
}
|
|
53300
|
-
const docsDir =
|
|
54452
|
+
const docsDir = path24.join(providerDir, "../../docs");
|
|
53301
54453
|
const loadGuide = (name) => {
|
|
53302
54454
|
try {
|
|
53303
|
-
const p =
|
|
54455
|
+
const p = path24.join(docsDir, name);
|
|
53304
54456
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
53305
54457
|
} catch {
|
|
53306
54458
|
}
|
|
@@ -53745,8 +54897,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
53745
54897
|
}
|
|
53746
54898
|
getEndpointList() {
|
|
53747
54899
|
return this.routes.map((r) => {
|
|
53748
|
-
const
|
|
53749
|
-
return `${r.method.padEnd(5)} ${
|
|
54900
|
+
const path26 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
54901
|
+
return `${r.method.padEnd(5)} ${path26}`;
|
|
53750
54902
|
});
|
|
53751
54903
|
}
|
|
53752
54904
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -53777,15 +54929,15 @@ data: ${JSON.stringify(msg.data)}
|
|
|
53777
54929
|
this.json(res, 500, { error: e.message });
|
|
53778
54930
|
}
|
|
53779
54931
|
});
|
|
53780
|
-
return new Promise((
|
|
54932
|
+
return new Promise((resolve15, reject) => {
|
|
53781
54933
|
this.server.listen(port, "127.0.0.1", () => {
|
|
53782
54934
|
this.log(`Dev server listening on http://127.0.0.1:${port}`);
|
|
53783
|
-
|
|
54935
|
+
resolve15();
|
|
53784
54936
|
});
|
|
53785
54937
|
this.server.on("error", (e) => {
|
|
53786
54938
|
if (e.code === "EADDRINUSE") {
|
|
53787
54939
|
this.log(`Port ${port} in use, skipping dev server`);
|
|
53788
|
-
|
|
54940
|
+
resolve15();
|
|
53789
54941
|
} else {
|
|
53790
54942
|
reject(e);
|
|
53791
54943
|
}
|
|
@@ -53867,20 +55019,20 @@ data: ${JSON.stringify(msg.data)}
|
|
|
53867
55019
|
child.stderr?.on("data", (d) => {
|
|
53868
55020
|
stderr += d.toString().slice(0, 2e3);
|
|
53869
55021
|
});
|
|
53870
|
-
await new Promise((
|
|
55022
|
+
await new Promise((resolve15) => {
|
|
53871
55023
|
const timer = setTimeout(() => {
|
|
53872
55024
|
child.kill();
|
|
53873
|
-
|
|
55025
|
+
resolve15();
|
|
53874
55026
|
}, 3e3);
|
|
53875
55027
|
child.on("exit", () => {
|
|
53876
55028
|
clearTimeout(timer);
|
|
53877
|
-
|
|
55029
|
+
resolve15();
|
|
53878
55030
|
});
|
|
53879
55031
|
child.stdout?.once("data", () => {
|
|
53880
55032
|
setTimeout(() => {
|
|
53881
55033
|
child.kill();
|
|
53882
55034
|
clearTimeout(timer);
|
|
53883
|
-
|
|
55035
|
+
resolve15();
|
|
53884
55036
|
}, 500);
|
|
53885
55037
|
});
|
|
53886
55038
|
});
|
|
@@ -54034,12 +55186,12 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54034
55186
|
// ─── DevConsole SPA ───
|
|
54035
55187
|
getConsoleDistDir() {
|
|
54036
55188
|
const candidates = [
|
|
54037
|
-
|
|
54038
|
-
|
|
54039
|
-
|
|
55189
|
+
path25.resolve(__dirname, "../../web-devconsole/dist"),
|
|
55190
|
+
path25.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
55191
|
+
path25.join(process.cwd(), "packages/web-devconsole/dist")
|
|
54040
55192
|
];
|
|
54041
55193
|
for (const dir of candidates) {
|
|
54042
|
-
if (fs15.existsSync(
|
|
55194
|
+
if (fs15.existsSync(path25.join(dir, "index.html"))) return dir;
|
|
54043
55195
|
}
|
|
54044
55196
|
return null;
|
|
54045
55197
|
}
|
|
@@ -54049,7 +55201,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54049
55201
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
54050
55202
|
return;
|
|
54051
55203
|
}
|
|
54052
|
-
const htmlPath =
|
|
55204
|
+
const htmlPath = path25.join(distDir, "index.html");
|
|
54053
55205
|
try {
|
|
54054
55206
|
const html = fs15.readFileSync(htmlPath, "utf-8");
|
|
54055
55207
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
@@ -54074,15 +55226,15 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54074
55226
|
this.json(res, 404, { error: "Not found" });
|
|
54075
55227
|
return;
|
|
54076
55228
|
}
|
|
54077
|
-
const safePath =
|
|
54078
|
-
const filePath =
|
|
55229
|
+
const safePath = path25.normalize(pathname).replace(/^\.\.\//, "");
|
|
55230
|
+
const filePath = path25.join(distDir, safePath);
|
|
54079
55231
|
if (!filePath.startsWith(distDir)) {
|
|
54080
55232
|
this.json(res, 403, { error: "Forbidden" });
|
|
54081
55233
|
return;
|
|
54082
55234
|
}
|
|
54083
55235
|
try {
|
|
54084
55236
|
const content = fs15.readFileSync(filePath);
|
|
54085
|
-
const ext =
|
|
55237
|
+
const ext = path25.extname(filePath);
|
|
54086
55238
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
54087
55239
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
54088
55240
|
res.end(content);
|
|
@@ -54195,10 +55347,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54195
55347
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
54196
55348
|
if (entry.isDirectory()) {
|
|
54197
55349
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
54198
|
-
scan(
|
|
55350
|
+
scan(path25.join(d, entry.name), rel);
|
|
54199
55351
|
} else {
|
|
54200
|
-
const
|
|
54201
|
-
files.push({ path: rel, size:
|
|
55352
|
+
const stat22 = fs15.statSync(path25.join(d, entry.name));
|
|
55353
|
+
files.push({ path: rel, size: stat22.size, type: "file" });
|
|
54202
55354
|
}
|
|
54203
55355
|
}
|
|
54204
55356
|
} catch {
|
|
@@ -54220,7 +55372,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54220
55372
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
54221
55373
|
return;
|
|
54222
55374
|
}
|
|
54223
|
-
const fullPath =
|
|
55375
|
+
const fullPath = path25.resolve(dir, path25.normalize(filePath));
|
|
54224
55376
|
if (!fullPath.startsWith(dir)) {
|
|
54225
55377
|
this.json(res, 403, { error: "Forbidden" });
|
|
54226
55378
|
return;
|
|
@@ -54245,14 +55397,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54245
55397
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
54246
55398
|
return;
|
|
54247
55399
|
}
|
|
54248
|
-
const fullPath =
|
|
55400
|
+
const fullPath = path25.resolve(dir, path25.normalize(filePath));
|
|
54249
55401
|
if (!fullPath.startsWith(dir)) {
|
|
54250
55402
|
this.json(res, 403, { error: "Forbidden" });
|
|
54251
55403
|
return;
|
|
54252
55404
|
}
|
|
54253
55405
|
try {
|
|
54254
55406
|
if (fs15.existsSync(fullPath)) fs15.copyFileSync(fullPath, fullPath + ".bak");
|
|
54255
|
-
fs15.mkdirSync(
|
|
55407
|
+
fs15.mkdirSync(path25.dirname(fullPath), { recursive: true });
|
|
54256
55408
|
fs15.writeFileSync(fullPath, content, "utf-8");
|
|
54257
55409
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
54258
55410
|
this.providerLoader.reload();
|
|
@@ -54269,7 +55421,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54269
55421
|
return;
|
|
54270
55422
|
}
|
|
54271
55423
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
54272
|
-
const p =
|
|
55424
|
+
const p = path25.join(dir, name);
|
|
54273
55425
|
if (fs15.existsSync(p)) {
|
|
54274
55426
|
const source = fs15.readFileSync(p, "utf-8");
|
|
54275
55427
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
@@ -54290,8 +55442,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54290
55442
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
54291
55443
|
return;
|
|
54292
55444
|
}
|
|
54293
|
-
const target = fs15.existsSync(
|
|
54294
|
-
const targetPath =
|
|
55445
|
+
const target = fs15.existsSync(path25.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
55446
|
+
const targetPath = path25.join(dir, target);
|
|
54295
55447
|
try {
|
|
54296
55448
|
if (fs15.existsSync(targetPath)) fs15.copyFileSync(targetPath, targetPath + ".bak");
|
|
54297
55449
|
fs15.writeFileSync(targetPath, source, "utf-8");
|
|
@@ -54383,14 +55535,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54383
55535
|
child.stderr?.on("data", (d) => {
|
|
54384
55536
|
stderr += d.toString();
|
|
54385
55537
|
});
|
|
54386
|
-
await new Promise((
|
|
55538
|
+
await new Promise((resolve15) => {
|
|
54387
55539
|
const timer = setTimeout(() => {
|
|
54388
55540
|
child.kill();
|
|
54389
|
-
|
|
55541
|
+
resolve15();
|
|
54390
55542
|
}, timeout);
|
|
54391
55543
|
child.on("exit", () => {
|
|
54392
55544
|
clearTimeout(timer);
|
|
54393
|
-
|
|
55545
|
+
resolve15();
|
|
54394
55546
|
});
|
|
54395
55547
|
});
|
|
54396
55548
|
const elapsed = Date.now() - start;
|
|
@@ -54438,7 +55590,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54438
55590
|
}
|
|
54439
55591
|
let targetDir;
|
|
54440
55592
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
54441
|
-
const jsonPath =
|
|
55593
|
+
const jsonPath = path25.join(targetDir, "provider.json");
|
|
54442
55594
|
if (fs15.existsSync(jsonPath)) {
|
|
54443
55595
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
54444
55596
|
return;
|
|
@@ -54450,8 +55602,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54450
55602
|
const createdFiles = ["provider.json"];
|
|
54451
55603
|
if (result.files) {
|
|
54452
55604
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
54453
|
-
const fullPath =
|
|
54454
|
-
fs15.mkdirSync(
|
|
55605
|
+
const fullPath = path25.join(targetDir, relPath);
|
|
55606
|
+
fs15.mkdirSync(path25.dirname(fullPath), { recursive: true });
|
|
54455
55607
|
fs15.writeFileSync(fullPath, content, "utf-8");
|
|
54456
55608
|
createdFiles.push(relPath);
|
|
54457
55609
|
}
|
|
@@ -54504,22 +55656,22 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54504
55656
|
if (!fs15.existsSync(scriptsDir)) return null;
|
|
54505
55657
|
const versions = fs15.readdirSync(scriptsDir).filter((d) => {
|
|
54506
55658
|
try {
|
|
54507
|
-
return fs15.statSync(
|
|
55659
|
+
return fs15.statSync(path25.join(scriptsDir, d)).isDirectory();
|
|
54508
55660
|
} catch {
|
|
54509
55661
|
return false;
|
|
54510
55662
|
}
|
|
54511
55663
|
}).sort((a, b2) => b2.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
54512
55664
|
if (versions.length === 0) return null;
|
|
54513
|
-
return
|
|
55665
|
+
return path25.join(scriptsDir, versions[0]);
|
|
54514
55666
|
}
|
|
54515
55667
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
54516
|
-
const canonicalUserDir =
|
|
54517
|
-
const desiredDir = requestedDir ?
|
|
54518
|
-
const upstreamRoot =
|
|
54519
|
-
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${
|
|
55668
|
+
const canonicalUserDir = path25.resolve(this.providerLoader.getUserProviderDir(category, type));
|
|
55669
|
+
const desiredDir = requestedDir ? path25.resolve(requestedDir) : canonicalUserDir;
|
|
55670
|
+
const upstreamRoot = path25.resolve(this.providerLoader.getUpstreamDir());
|
|
55671
|
+
if (desiredDir === upstreamRoot || desiredDir.startsWith(`${upstreamRoot}${path25.sep}`)) {
|
|
54520
55672
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
54521
55673
|
}
|
|
54522
|
-
if (
|
|
55674
|
+
if (path25.basename(desiredDir) !== type) {
|
|
54523
55675
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
54524
55676
|
}
|
|
54525
55677
|
const sourceDir = this.findProviderDir(type);
|
|
@@ -54527,11 +55679,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54527
55679
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
54528
55680
|
}
|
|
54529
55681
|
if (!fs15.existsSync(desiredDir)) {
|
|
54530
|
-
fs15.mkdirSync(
|
|
55682
|
+
fs15.mkdirSync(path25.dirname(desiredDir), { recursive: true });
|
|
54531
55683
|
fs15.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
54532
55684
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
54533
55685
|
}
|
|
54534
|
-
const providerJson =
|
|
55686
|
+
const providerJson = path25.join(desiredDir, "provider.json");
|
|
54535
55687
|
if (!fs15.existsSync(providerJson)) {
|
|
54536
55688
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
54537
55689
|
}
|
|
@@ -54567,7 +55719,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54567
55719
|
setMode: "set_mode.js"
|
|
54568
55720
|
};
|
|
54569
55721
|
const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
|
|
54570
|
-
const scriptsDir =
|
|
55722
|
+
const scriptsDir = path25.join(providerDir, "scripts");
|
|
54571
55723
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
54572
55724
|
if (latestScriptsDir) {
|
|
54573
55725
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -54578,7 +55730,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54578
55730
|
for (const file2 of fs15.readdirSync(latestScriptsDir)) {
|
|
54579
55731
|
if (file2.endsWith(".js") && targetFileNames.has(file2)) {
|
|
54580
55732
|
try {
|
|
54581
|
-
const content = fs15.readFileSync(
|
|
55733
|
+
const content = fs15.readFileSync(path25.join(latestScriptsDir, file2), "utf-8");
|
|
54582
55734
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
54583
55735
|
lines.push("```javascript");
|
|
54584
55736
|
lines.push(content);
|
|
@@ -54595,7 +55747,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54595
55747
|
lines.push("");
|
|
54596
55748
|
for (const file2 of refFiles) {
|
|
54597
55749
|
try {
|
|
54598
|
-
const content = fs15.readFileSync(
|
|
55750
|
+
const content = fs15.readFileSync(path25.join(latestScriptsDir, file2), "utf-8");
|
|
54599
55751
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
54600
55752
|
lines.push("```javascript");
|
|
54601
55753
|
lines.push(content);
|
|
@@ -54636,10 +55788,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54636
55788
|
lines.push("");
|
|
54637
55789
|
}
|
|
54638
55790
|
}
|
|
54639
|
-
const docsDir =
|
|
55791
|
+
const docsDir = path25.join(providerDir, "../../docs");
|
|
54640
55792
|
const loadGuide = (name) => {
|
|
54641
55793
|
try {
|
|
54642
|
-
const p =
|
|
55794
|
+
const p = path25.join(docsDir, name);
|
|
54643
55795
|
if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
|
|
54644
55796
|
} catch {
|
|
54645
55797
|
}
|
|
@@ -54813,7 +55965,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54813
55965
|
parseApproval: "parse_approval.js"
|
|
54814
55966
|
};
|
|
54815
55967
|
const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
|
|
54816
|
-
const scriptsDir =
|
|
55968
|
+
const scriptsDir = path25.join(providerDir, "scripts");
|
|
54817
55969
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
54818
55970
|
if (latestScriptsDir) {
|
|
54819
55971
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -54825,7 +55977,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54825
55977
|
if (!file2.endsWith(".js")) continue;
|
|
54826
55978
|
if (!targetFileNames.has(file2)) continue;
|
|
54827
55979
|
try {
|
|
54828
|
-
const content = fs15.readFileSync(
|
|
55980
|
+
const content = fs15.readFileSync(path25.join(latestScriptsDir, file2), "utf-8");
|
|
54829
55981
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
54830
55982
|
lines.push("```javascript");
|
|
54831
55983
|
lines.push(content);
|
|
@@ -54841,7 +55993,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54841
55993
|
lines.push("");
|
|
54842
55994
|
for (const file2 of refFiles) {
|
|
54843
55995
|
try {
|
|
54844
|
-
const content = fs15.readFileSync(
|
|
55996
|
+
const content = fs15.readFileSync(path25.join(latestScriptsDir, file2), "utf-8");
|
|
54845
55997
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
54846
55998
|
lines.push("```javascript");
|
|
54847
55999
|
lines.push(content);
|
|
@@ -54874,10 +56026,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54874
56026
|
lines.push("");
|
|
54875
56027
|
}
|
|
54876
56028
|
}
|
|
54877
|
-
const docsDir =
|
|
56029
|
+
const docsDir = path25.join(providerDir, "../../docs");
|
|
54878
56030
|
const loadGuide = (name) => {
|
|
54879
56031
|
try {
|
|
54880
|
-
const p =
|
|
56032
|
+
const p = path25.join(docsDir, name);
|
|
54881
56033
|
if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
|
|
54882
56034
|
} catch {
|
|
54883
56035
|
}
|
|
@@ -55060,14 +56212,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
55060
56212
|
res.end(JSON.stringify(data, null, 2));
|
|
55061
56213
|
}
|
|
55062
56214
|
async readBody(req) {
|
|
55063
|
-
return new Promise((
|
|
56215
|
+
return new Promise((resolve15) => {
|
|
55064
56216
|
let body = "";
|
|
55065
56217
|
req.on("data", (chunk) => body += chunk);
|
|
55066
56218
|
req.on("end", () => {
|
|
55067
56219
|
try {
|
|
55068
|
-
|
|
56220
|
+
resolve15(JSON.parse(body));
|
|
55069
56221
|
} catch {
|
|
55070
|
-
|
|
56222
|
+
resolve15({});
|
|
55071
56223
|
}
|
|
55072
56224
|
});
|
|
55073
56225
|
});
|
|
@@ -55569,7 +56721,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
55569
56721
|
const deadline = Date.now() + timeoutMs;
|
|
55570
56722
|
while (Date.now() < deadline) {
|
|
55571
56723
|
if (await canConnect(endpoint)) return;
|
|
55572
|
-
await new Promise((
|
|
56724
|
+
await new Promise((resolve15) => setTimeout(resolve15, STARTUP_POLL_MS));
|
|
55573
56725
|
}
|
|
55574
56726
|
throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
|
|
55575
56727
|
}
|
|
@@ -55743,10 +56895,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
55743
56895
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
55744
56896
|
const fs16 = await import("fs");
|
|
55745
56897
|
fs16.writeFileSync(vsixPath, buffer);
|
|
55746
|
-
return new Promise((
|
|
56898
|
+
return new Promise((resolve15) => {
|
|
55747
56899
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
55748
56900
|
(0, import_child_process11.exec)(cmd, { timeout: 6e4 }, (error48, _stdout, stderr) => {
|
|
55749
|
-
|
|
56901
|
+
resolve15({
|
|
55750
56902
|
extensionId: extension.id,
|
|
55751
56903
|
marketplaceId: extension.marketplaceId,
|
|
55752
56904
|
success: !error48,
|
|
@@ -55759,11 +56911,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
55759
56911
|
} catch (e) {
|
|
55760
56912
|
}
|
|
55761
56913
|
}
|
|
55762
|
-
return new Promise((
|
|
56914
|
+
return new Promise((resolve15) => {
|
|
55763
56915
|
const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
|
|
55764
56916
|
(0, import_child_process11.exec)(cmd, { timeout: 6e4 }, (error48, stdout, stderr) => {
|
|
55765
56917
|
if (error48) {
|
|
55766
|
-
|
|
56918
|
+
resolve15({
|
|
55767
56919
|
extensionId: extension.id,
|
|
55768
56920
|
marketplaceId: extension.marketplaceId,
|
|
55769
56921
|
success: false,
|
|
@@ -55771,7 +56923,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
55771
56923
|
error: stderr || error48.message
|
|
55772
56924
|
});
|
|
55773
56925
|
} else {
|
|
55774
|
-
|
|
56926
|
+
resolve15({
|
|
55775
56927
|
extensionId: extension.id,
|
|
55776
56928
|
marketplaceId: extension.marketplaceId,
|
|
55777
56929
|
success: true,
|
|
@@ -56881,6 +58033,8 @@ var StandaloneServer = class {
|
|
|
56881
58033
|
wsSessionHostDiagnosticsSubscriptions = /* @__PURE__ */ new Map();
|
|
56882
58034
|
wsSessionModalSubscriptions = /* @__PURE__ */ new Map();
|
|
56883
58035
|
wsDaemonMetadataSubscriptions = /* @__PURE__ */ new Map();
|
|
58036
|
+
wsGitSubscriptions = /* @__PURE__ */ new Map();
|
|
58037
|
+
gitWorkspaceMonitor = (0, import_daemon_core2.createGitWorkspaceMonitor)();
|
|
56884
58038
|
authToken = null;
|
|
56885
58039
|
passwordConfigPath = getStandalonePasswordConfigPath();
|
|
56886
58040
|
passwordConfig = null;
|
|
@@ -57146,6 +58300,7 @@ var StandaloneServer = class {
|
|
|
57146
58300
|
void this.flushWsMachineRuntimeSubscriptions();
|
|
57147
58301
|
void this.flushWsSessionHostDiagnosticsSubscriptions();
|
|
57148
58302
|
void this.flushWsSessionModalSubscriptions();
|
|
58303
|
+
if (this.hasWsGitSubscriptions()) void this.flushWsGitSubscriptions();
|
|
57149
58304
|
}, STATUS_INTERVAL);
|
|
57150
58305
|
this.running = true;
|
|
57151
58306
|
await new Promise((resolve4) => {
|
|
@@ -57634,6 +58789,7 @@ var StandaloneServer = class {
|
|
|
57634
58789
|
this.wsSessionHostDiagnosticsSubscriptions.set(ws2, /* @__PURE__ */ new Map());
|
|
57635
58790
|
this.wsSessionModalSubscriptions.set(ws2, /* @__PURE__ */ new Map());
|
|
57636
58791
|
this.wsDaemonMetadataSubscriptions.set(ws2, /* @__PURE__ */ new Map());
|
|
58792
|
+
this.wsGitSubscriptions.set(ws2, /* @__PURE__ */ new Map());
|
|
57637
58793
|
console.log(`[WS] Client connected (total: ${this.clients.size})`);
|
|
57638
58794
|
const status = this.getWsStatus(this.buildSharedSnapshot("live"));
|
|
57639
58795
|
this.lastWsStatusSignature = this.buildWsStatusSignature(status);
|
|
@@ -57677,6 +58833,7 @@ var StandaloneServer = class {
|
|
|
57677
58833
|
this.wsSessionHostDiagnosticsSubscriptions.delete(ws2);
|
|
57678
58834
|
this.wsSessionModalSubscriptions.delete(ws2);
|
|
57679
58835
|
this.wsDaemonMetadataSubscriptions.delete(ws2);
|
|
58836
|
+
this.clearWsGitSubscriptions(ws2);
|
|
57680
58837
|
console.log(`[WS] Client disconnected (total: ${this.clients.size})`);
|
|
57681
58838
|
});
|
|
57682
58839
|
ws2.on("error", () => {
|
|
@@ -57686,8 +58843,19 @@ var StandaloneServer = class {
|
|
|
57686
58843
|
this.wsSessionHostDiagnosticsSubscriptions.delete(ws2);
|
|
57687
58844
|
this.wsSessionModalSubscriptions.delete(ws2);
|
|
57688
58845
|
this.wsDaemonMetadataSubscriptions.delete(ws2);
|
|
58846
|
+
this.clearWsGitSubscriptions(ws2);
|
|
57689
58847
|
});
|
|
57690
58848
|
}
|
|
58849
|
+
clearWsGitSubscriptions(ws2) {
|
|
58850
|
+
const subs = this.wsGitSubscriptions.get(ws2);
|
|
58851
|
+
if (subs) {
|
|
58852
|
+
subs.forEach((sub) => {
|
|
58853
|
+
sub.subscription.dispose();
|
|
58854
|
+
});
|
|
58855
|
+
subs.clear();
|
|
58856
|
+
}
|
|
58857
|
+
this.wsGitSubscriptions.delete(ws2);
|
|
58858
|
+
}
|
|
57691
58859
|
async handleWsSubscribe(ws2, msg) {
|
|
57692
58860
|
if (msg.topic === "session.chat_tail") {
|
|
57693
58861
|
const params = msg.params;
|
|
@@ -57775,6 +58943,25 @@ var StandaloneServer = class {
|
|
|
57775
58943
|
lastSentAt: 0
|
|
57776
58944
|
});
|
|
57777
58945
|
await this.flushWsDaemonMetadataSubscriptions(ws2);
|
|
58946
|
+
return;
|
|
58947
|
+
}
|
|
58948
|
+
if (msg.topic === "workspace.git") {
|
|
58949
|
+
const params = msg.params;
|
|
58950
|
+
if (!params?.workspace) return;
|
|
58951
|
+
const normalized = (0, import_daemon_core2.normalizeGitWorkspaceSubscriptionParams)(params);
|
|
58952
|
+
const subs = this.wsGitSubscriptions.get(ws2) || /* @__PURE__ */ new Map();
|
|
58953
|
+
this.wsGitSubscriptions.set(ws2, subs);
|
|
58954
|
+
subs.get(msg.key)?.subscription.dispose();
|
|
58955
|
+
subs.set(msg.key, {
|
|
58956
|
+
request: {
|
|
58957
|
+
...msg,
|
|
58958
|
+
topic: "workspace.git",
|
|
58959
|
+
params: normalized
|
|
58960
|
+
},
|
|
58961
|
+
subscription: this.gitWorkspaceMonitor.createSubscription(normalized),
|
|
58962
|
+
lastSentAt: 0
|
|
58963
|
+
});
|
|
58964
|
+
await this.flushWsGitSubscriptions(ws2);
|
|
57778
58965
|
}
|
|
57779
58966
|
}
|
|
57780
58967
|
handleWsUnsubscribe(ws2, msg) {
|
|
@@ -57796,6 +58983,12 @@ var StandaloneServer = class {
|
|
|
57796
58983
|
}
|
|
57797
58984
|
if (msg.topic === "daemon.metadata") {
|
|
57798
58985
|
this.wsDaemonMetadataSubscriptions.get(ws2)?.delete(msg.key);
|
|
58986
|
+
return;
|
|
58987
|
+
}
|
|
58988
|
+
if (msg.topic === "workspace.git") {
|
|
58989
|
+
const sub = this.wsGitSubscriptions.get(ws2)?.get(msg.key);
|
|
58990
|
+
sub?.subscription.dispose();
|
|
58991
|
+
this.wsGitSubscriptions.get(ws2)?.delete(msg.key);
|
|
57799
58992
|
}
|
|
57800
58993
|
}
|
|
57801
58994
|
async buildChatTailUpdate(request, state, key) {
|
|
@@ -58019,6 +59212,45 @@ var StandaloneServer = class {
|
|
|
58019
59212
|
}
|
|
58020
59213
|
}
|
|
58021
59214
|
}
|
|
59215
|
+
hasWsGitSubscriptions(targetWs) {
|
|
59216
|
+
const targets = targetWs ? [targetWs] : Array.from(this.clients);
|
|
59217
|
+
for (const ws2 of targets) {
|
|
59218
|
+
const subs = this.wsGitSubscriptions.get(ws2);
|
|
59219
|
+
if (subs && subs.size > 0) return true;
|
|
59220
|
+
}
|
|
59221
|
+
return false;
|
|
59222
|
+
}
|
|
59223
|
+
async flushWsGitSubscriptions(targetWs) {
|
|
59224
|
+
if (!this.hasWsGitSubscriptions(targetWs)) return;
|
|
59225
|
+
const targets = targetWs ? [targetWs] : Array.from(this.clients);
|
|
59226
|
+
const now = Date.now();
|
|
59227
|
+
const tasks = [];
|
|
59228
|
+
for (const ws2 of targets) {
|
|
59229
|
+
if (ws2.readyState !== import_ws.WebSocket.OPEN) continue;
|
|
59230
|
+
const subs = this.wsGitSubscriptions.get(ws2);
|
|
59231
|
+
if (!subs || subs.size === 0) continue;
|
|
59232
|
+
subs.forEach((sub, key) => {
|
|
59233
|
+
const intervalMs = Math.max(1, Number(sub.subscription.params.intervalMs || sub.request.params.intervalMs || 0));
|
|
59234
|
+
if (sub.lastSentAt > 0 && now - sub.lastSentAt < intervalMs) return;
|
|
59235
|
+
tasks.push({ ws: ws2, key, sub });
|
|
59236
|
+
});
|
|
59237
|
+
}
|
|
59238
|
+
await (0, import_daemon_core2.runAsyncBatch)(tasks, async ({ ws: ws2, key, sub }) => {
|
|
59239
|
+
try {
|
|
59240
|
+
const monitorUpdate = await sub.subscription.refresh();
|
|
59241
|
+
const current = this.wsGitSubscriptions.get(ws2)?.get(key);
|
|
59242
|
+
if (current !== sub || ws2.readyState !== import_ws.WebSocket.OPEN) return;
|
|
59243
|
+
sub.lastSentAt = monitorUpdate.timestamp;
|
|
59244
|
+
const update = {
|
|
59245
|
+
...monitorUpdate,
|
|
59246
|
+
key
|
|
59247
|
+
};
|
|
59248
|
+
ws2.send(JSON.stringify({ type: "topic_update", update }));
|
|
59249
|
+
} catch (error48) {
|
|
59250
|
+
import_daemon_core2.LOG.warn("Standalone", `[workspace.git] skipped workspace=${sub.request.params.workspace} key=${key} error=${error48?.message || error48}`);
|
|
59251
|
+
}
|
|
59252
|
+
}, { concurrency: 2 });
|
|
59253
|
+
}
|
|
58022
59254
|
// ─── Core Logic ───
|
|
58023
59255
|
buildSharedSnapshot(profile = "full") {
|
|
58024
59256
|
const cfgSnap = (0, import_daemon_core2.loadConfig)();
|
|
@@ -58143,6 +59375,7 @@ var StandaloneServer = class {
|
|
|
58143
59375
|
}
|
|
58144
59376
|
if (type.startsWith("session_host_")) void this.flushWsSessionHostDiagnosticsSubscriptions();
|
|
58145
59377
|
if (type === "resolve_action" || type === "send_chat" || type === "read_chat") void this.flushWsSessionModalSubscriptions();
|
|
59378
|
+
if (type.startsWith("git_") && this.hasWsGitSubscriptions()) void this.flushWsGitSubscriptions();
|
|
58146
59379
|
return result;
|
|
58147
59380
|
}
|
|
58148
59381
|
scheduleBroadcastStatus() {
|