@adhdev/daemon-standalone 0.9.52 → 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 +1654 -392
- 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-BBcPdOv8.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
|
}
|
|
@@ -35967,6 +37092,10 @@ ${cleanBody}`;
|
|
|
35967
37092
|
return name.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
35968
37093
|
}
|
|
35969
37094
|
};
|
|
37095
|
+
function normalizePaginationNumber(value, fallback, min) {
|
|
37096
|
+
const numeric = Number(value);
|
|
37097
|
+
return Number.isFinite(numeric) ? Math.max(min, numeric) : fallback;
|
|
37098
|
+
}
|
|
35970
37099
|
function pageHistoryRecords(agentType, records, offset = 0, limit = 30, excludeRecentCount = 0, historyBehavior) {
|
|
35971
37100
|
const allMessages = records.map((message) => sanitizeHistoryMessage(agentType, message)).filter(Boolean);
|
|
35972
37101
|
allMessages.sort((a, b2) => a.receivedAt - b2.receivedAt);
|
|
@@ -35980,9 +37109,12 @@ ${cleanBody}`;
|
|
|
35980
37109
|
if (message.role !== "system") lastTurn = message;
|
|
35981
37110
|
}
|
|
35982
37111
|
const collapsed = collapseReplayAssistantTurns(chronological, historyBehavior);
|
|
35983
|
-
const boundedLimit =
|
|
35984
|
-
const boundedOffset =
|
|
35985
|
-
const boundedExclude = Math.
|
|
37112
|
+
const boundedLimit = normalizePaginationNumber(limit, 30, 1);
|
|
37113
|
+
const boundedOffset = normalizePaginationNumber(offset, 0, 0);
|
|
37114
|
+
const boundedExclude = Math.min(
|
|
37115
|
+
normalizePaginationNumber(excludeRecentCount, 0, 0),
|
|
37116
|
+
collapsed.length
|
|
37117
|
+
);
|
|
35986
37118
|
const endExclusive = Math.max(0, collapsed.length - boundedExclude - boundedOffset);
|
|
35987
37119
|
const startInclusive = Math.max(0, endExclusive - boundedLimit);
|
|
35988
37120
|
const sliced = collapsed.slice(startInclusive, endExclusive);
|
|
@@ -35991,13 +37123,13 @@ ${cleanBody}`;
|
|
|
35991
37123
|
function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
|
|
35992
37124
|
try {
|
|
35993
37125
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
35994
|
-
const dir =
|
|
37126
|
+
const dir = path10.join(HISTORY_DIR, sanitized);
|
|
35995
37127
|
if (!fs32.existsSync(dir)) return { messages: [], hasMore: false };
|
|
35996
37128
|
const files = listHistoryFiles(dir, historySessionId);
|
|
35997
37129
|
const allMessages = [];
|
|
35998
37130
|
const seen = /* @__PURE__ */ new Set();
|
|
35999
37131
|
for (const file2 of files) {
|
|
36000
|
-
const filePath =
|
|
37132
|
+
const filePath = path10.join(dir, file2);
|
|
36001
37133
|
const content = fs32.readFileSync(filePath, "utf-8");
|
|
36002
37134
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
36003
37135
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -36021,7 +37153,7 @@ ${cleanBody}`;
|
|
|
36021
37153
|
function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
36022
37154
|
try {
|
|
36023
37155
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
36024
|
-
const dir =
|
|
37156
|
+
const dir = path10.join(HISTORY_DIR, sanitized);
|
|
36025
37157
|
if (!fs32.existsSync(dir)) {
|
|
36026
37158
|
savedHistorySessionCache.delete(sanitized);
|
|
36027
37159
|
return { sessions: [], hasMore: false };
|
|
@@ -36082,11 +37214,11 @@ ${cleanBody}`;
|
|
|
36082
37214
|
}
|
|
36083
37215
|
function readExistingSessionStartRecord(agentType, historySessionId) {
|
|
36084
37216
|
try {
|
|
36085
|
-
const dir =
|
|
37217
|
+
const dir = path10.join(HISTORY_DIR, agentType);
|
|
36086
37218
|
if (!fs32.existsSync(dir)) return null;
|
|
36087
37219
|
const files = listHistoryFiles(dir, historySessionId).sort();
|
|
36088
37220
|
for (const file2 of files) {
|
|
36089
|
-
const lines = fs32.readFileSync(
|
|
37221
|
+
const lines = fs32.readFileSync(path10.join(dir, file2), "utf-8").split("\n").filter(Boolean);
|
|
36090
37222
|
for (const line of lines) {
|
|
36091
37223
|
try {
|
|
36092
37224
|
const parsed = JSON.parse(line);
|
|
@@ -36106,16 +37238,16 @@ ${cleanBody}`;
|
|
|
36106
37238
|
function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
|
|
36107
37239
|
if (records.length === 0) return false;
|
|
36108
37240
|
try {
|
|
36109
|
-
const dir =
|
|
37241
|
+
const dir = path10.join(HISTORY_DIR, agentType);
|
|
36110
37242
|
fs32.mkdirSync(dir, { recursive: true });
|
|
36111
37243
|
const prefix = `${historySessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
|
|
36112
37244
|
for (const file2 of fs32.readdirSync(dir)) {
|
|
36113
37245
|
if (file2.startsWith(prefix) && file2.endsWith(".jsonl")) {
|
|
36114
|
-
fs32.unlinkSync(
|
|
37246
|
+
fs32.unlinkSync(path10.join(dir, file2));
|
|
36115
37247
|
}
|
|
36116
37248
|
}
|
|
36117
37249
|
const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
|
|
36118
|
-
const filePath =
|
|
37250
|
+
const filePath = path10.join(dir, `${prefix}${targetDate}.jsonl`);
|
|
36119
37251
|
fs32.writeFileSync(filePath, `${records.map((record2) => JSON.stringify(record2)).join("\n")}
|
|
36120
37252
|
`, "utf-8");
|
|
36121
37253
|
invalidatePersistedSavedHistoryIndex(agentType, dir);
|
|
@@ -37959,6 +39091,10 @@ ${effect.notification.body || ""}`.trim();
|
|
|
37959
39091
|
function shouldIncludeRuntimeMetadata(profile) {
|
|
37960
39092
|
return true;
|
|
37961
39093
|
}
|
|
39094
|
+
function getGitSummaryForWorkspace(workspace, options) {
|
|
39095
|
+
if (!workspace) return void 0;
|
|
39096
|
+
return options.getGitSummaryForWorkspace?.(workspace) || void 0;
|
|
39097
|
+
}
|
|
37962
39098
|
function findCdpManager(cdpManagers, key) {
|
|
37963
39099
|
const exact = cdpManagers.get(key);
|
|
37964
39100
|
if (exact) return exact.isConnected ? exact : null;
|
|
@@ -38014,6 +39150,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38014
39150
|
const controlValues = normalizeProviderStateControlValues(state.controlValues);
|
|
38015
39151
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
38016
39152
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
39153
|
+
const workspace = state.workspace || null;
|
|
39154
|
+
const git = getGitSummaryForWorkspace(workspace, options);
|
|
38017
39155
|
const title = activeChat?.title || state.name;
|
|
38018
39156
|
return {
|
|
38019
39157
|
id: state.instanceId || state.type,
|
|
@@ -38026,7 +39164,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38026
39164
|
activeModal: activeChat?.activeModal || null
|
|
38027
39165
|
}),
|
|
38028
39166
|
title,
|
|
38029
|
-
workspace
|
|
39167
|
+
workspace,
|
|
39168
|
+
...git && { git },
|
|
38030
39169
|
activeChat,
|
|
38031
39170
|
...summaryMetadata && { summaryMetadata },
|
|
38032
39171
|
...includeSessionMetadata && { capabilities: state.sessionCapabilities || IDE_SESSION_CAPABILITIES },
|
|
@@ -38047,6 +39186,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38047
39186
|
const controlValues = normalizeProviderStateControlValues(ext.controlValues);
|
|
38048
39187
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
38049
39188
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
39189
|
+
const workspace = parent.workspace || null;
|
|
39190
|
+
const git = getGitSummaryForWorkspace(workspace, options);
|
|
38050
39191
|
return {
|
|
38051
39192
|
id: ext.instanceId || `${parent.instanceId}:${ext.type}`,
|
|
38052
39193
|
parentId: parent.instanceId || parent.type,
|
|
@@ -38059,7 +39200,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38059
39200
|
activeModal: activeChat?.activeModal || null
|
|
38060
39201
|
}),
|
|
38061
39202
|
title: activeChat?.title || ext.name,
|
|
38062
|
-
workspace
|
|
39203
|
+
workspace,
|
|
39204
|
+
...git && { git },
|
|
38063
39205
|
activeChat,
|
|
38064
39206
|
...summaryMetadata && { summaryMetadata },
|
|
38065
39207
|
...includeSessionMetadata && { capabilities: ext.sessionCapabilities || EXTENSION_SESSION_CAPABILITIES },
|
|
@@ -38095,6 +39237,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38095
39237
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
38096
39238
|
const includeRuntimeMetadata = shouldIncludeRuntimeMetadata(profile);
|
|
38097
39239
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
39240
|
+
const workspace = state.workspace || null;
|
|
39241
|
+
const git = getGitSummaryForWorkspace(workspace, options);
|
|
38098
39242
|
return {
|
|
38099
39243
|
id: state.instanceId,
|
|
38100
39244
|
parentId: null,
|
|
@@ -38107,7 +39251,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38107
39251
|
activeModal: activeChat?.activeModal || null
|
|
38108
39252
|
}),
|
|
38109
39253
|
title: activeChat?.title || state.name,
|
|
38110
|
-
workspace
|
|
39254
|
+
workspace,
|
|
39255
|
+
...git && { git },
|
|
38111
39256
|
...includeRuntimeMetadata && {
|
|
38112
39257
|
runtimeKey: state.runtime?.runtimeKey,
|
|
38113
39258
|
runtimeDisplayName: state.runtime?.displayName,
|
|
@@ -38142,6 +39287,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38142
39287
|
const controlValues = normalizeProviderStateControlValues(state.controlValues);
|
|
38143
39288
|
const includeSessionMetadata = shouldIncludeSessionMetadata(profile);
|
|
38144
39289
|
const includeSessionControls = shouldIncludeSessionControls(profile);
|
|
39290
|
+
const workspace = state.workspace || null;
|
|
39291
|
+
const git = getGitSummaryForWorkspace(workspace, options);
|
|
38145
39292
|
return {
|
|
38146
39293
|
id: state.instanceId,
|
|
38147
39294
|
parentId: null,
|
|
@@ -38153,7 +39300,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38153
39300
|
activeModal: activeChat?.activeModal || null
|
|
38154
39301
|
}),
|
|
38155
39302
|
title: activeChat?.title || state.name,
|
|
38156
|
-
workspace
|
|
39303
|
+
workspace,
|
|
39304
|
+
...git && { git },
|
|
38157
39305
|
activeChat,
|
|
38158
39306
|
...summaryMetadata && { summaryMetadata },
|
|
38159
39307
|
...includeSessionMetadata && { capabilities: ACP_SESSION_CAPABILITIES },
|
|
@@ -38264,7 +39412,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38264
39412
|
}
|
|
38265
39413
|
var fs42 = __toESM2(require("fs"));
|
|
38266
39414
|
var os62 = __toESM2(require("os"));
|
|
38267
|
-
var
|
|
39415
|
+
var path11 = __toESM2(require("path"));
|
|
38268
39416
|
var import_node_crypto = require("crypto");
|
|
38269
39417
|
init_contracts();
|
|
38270
39418
|
var VALID_INPUT_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
|
|
@@ -38947,7 +40095,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38947
40095
|
}
|
|
38948
40096
|
function getChatDebugBundleDir() {
|
|
38949
40097
|
const override = typeof process.env.ADHDEV_DEBUG_BUNDLE_DIR === "string" ? process.env.ADHDEV_DEBUG_BUNDLE_DIR.trim() : "";
|
|
38950
|
-
return override ||
|
|
40098
|
+
return override || path11.join(os62.homedir(), ".adhdev", "debug-bundles", "chat");
|
|
38951
40099
|
}
|
|
38952
40100
|
function safeBundleIdSegment(value, fallback) {
|
|
38953
40101
|
const normalized = String(value || fallback).trim().replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
@@ -38980,7 +40128,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38980
40128
|
const bundleId = createChatDebugBundleId(targetSessionId);
|
|
38981
40129
|
const dir = getChatDebugBundleDir();
|
|
38982
40130
|
fs42.mkdirSync(dir, { recursive: true });
|
|
38983
|
-
const savedPath =
|
|
40131
|
+
const savedPath = path11.join(dir, `${bundleId}.json`);
|
|
38984
40132
|
const json2 = `${JSON.stringify(bundle, null, 2)}
|
|
38985
40133
|
`;
|
|
38986
40134
|
fs42.writeFileSync(savedPath, json2, { encoding: "utf8", mode: 384 });
|
|
@@ -39149,10 +40297,32 @@ ${effect.notification.body || ""}`.trim();
|
|
|
39149
40297
|
if (!last) return "";
|
|
39150
40298
|
return `${last.role || ""}:${String(last.content || "").replace(/\s+/g, " ").trim()}`;
|
|
39151
40299
|
}
|
|
40300
|
+
function toNonNegativeNumber(value) {
|
|
40301
|
+
const numeric = Number(value ?? 0);
|
|
40302
|
+
return Number.isFinite(numeric) ? Math.max(0, numeric) : 0;
|
|
40303
|
+
}
|
|
40304
|
+
function getCliVisibleTranscriptCount(adapter) {
|
|
40305
|
+
const adapterStatus = adapter?.getStatus?.() || {};
|
|
40306
|
+
const adapterMessages = Array.isArray(adapterStatus.messages) ? adapterStatus.messages : [];
|
|
40307
|
+
let parsedRecord = null;
|
|
40308
|
+
if (typeof adapter?.getScriptParsedStatus === "function") {
|
|
40309
|
+
try {
|
|
40310
|
+
const parsed = parseMaybeJson(adapter.getScriptParsedStatus());
|
|
40311
|
+
parsedRecord = parsed && typeof parsed === "object" ? parsed : null;
|
|
40312
|
+
} catch {
|
|
40313
|
+
parsedRecord = null;
|
|
40314
|
+
}
|
|
40315
|
+
}
|
|
40316
|
+
const parsedMessages = Array.isArray(parsedRecord?.messages) ? parsedRecord.messages : [];
|
|
40317
|
+
if (!parsedRecord) return adapterMessages.length;
|
|
40318
|
+
const parsedIsProviderAuthoritative = parsedRecord.transcriptAuthority === "provider" || parsedRecord.coverage === "full";
|
|
40319
|
+
const shouldPreferAdapterMessages = !parsedIsProviderAuthoritative && adapterMessages.length > 0 && adapterMessages.length > parsedMessages.length;
|
|
40320
|
+
return shouldPreferAdapterMessages ? adapterMessages.length : parsedMessages.length;
|
|
40321
|
+
}
|
|
39152
40322
|
async function getStableExtensionBaseline(h) {
|
|
39153
40323
|
const first = await readExtensionChatState(h);
|
|
39154
40324
|
if (getStateMessageCount(first) > 0 || getStateLastSignature(first)) return first;
|
|
39155
|
-
await new Promise((
|
|
40325
|
+
await new Promise((resolve15) => setTimeout(resolve15, 150));
|
|
39156
40326
|
const second = await readExtensionChatState(h);
|
|
39157
40327
|
return getStateMessageCount(second) >= getStateMessageCount(first) ? second : first;
|
|
39158
40328
|
}
|
|
@@ -39160,7 +40330,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
39160
40330
|
const beforeCount = getStateMessageCount(before);
|
|
39161
40331
|
const beforeSignature = getStateLastSignature(before);
|
|
39162
40332
|
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
39163
|
-
await new Promise((
|
|
40333
|
+
await new Promise((resolve15) => setTimeout(resolve15, 250));
|
|
39164
40334
|
const state = await readExtensionChatState(h);
|
|
39165
40335
|
if (state?.status === "waiting_approval") return true;
|
|
39166
40336
|
const afterCount = getStateMessageCount(state);
|
|
@@ -39177,11 +40347,11 @@ ${effect.notification.body || ""}`.trim();
|
|
|
39177
40347
|
const provider = h.getProvider(agentType);
|
|
39178
40348
|
const agentStr = provider?.type || agentType || getCurrentProviderType(h);
|
|
39179
40349
|
const transport = getTargetTransport(h, provider);
|
|
39180
|
-
|
|
39181
|
-
|
|
40350
|
+
const hasExplicitExcludeRecentCount = args?.excludeRecentCount !== void 0 && args?.excludeRecentCount !== null;
|
|
40351
|
+
let excludeRecentCount = toNonNegativeNumber(args?.excludeRecentCount);
|
|
40352
|
+
if (!hasExplicitExcludeRecentCount && isCliLikeTransport(transport)) {
|
|
39182
40353
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
39183
|
-
const
|
|
39184
|
-
const visibleCount = Array.isArray(status?.messages) ? status.messages.length : 0;
|
|
40354
|
+
const visibleCount = getCliVisibleTranscriptCount(adapter);
|
|
39185
40355
|
if (visibleCount > excludeRecentCount) excludeRecentCount = visibleCount;
|
|
39186
40356
|
}
|
|
39187
40357
|
const workspace = typeof args?.workspace === "string" ? args.workspace : typeof h.currentSession?.workspace === "string" ? h.currentSession.workspace : void 0;
|
|
@@ -40094,7 +41264,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
40094
41264
|
return { success: false, error: "resolveAction script not available for this provider" };
|
|
40095
41265
|
}
|
|
40096
41266
|
var fs52 = __toESM2(require("fs"));
|
|
40097
|
-
var
|
|
41267
|
+
var path12 = __toESM2(require("path"));
|
|
40098
41268
|
var os7 = __toESM2(require("os"));
|
|
40099
41269
|
var KEY_TO_VK = {
|
|
40100
41270
|
Backspace: 8,
|
|
@@ -40351,25 +41521,25 @@ ${effect.notification.body || ""}`.trim();
|
|
|
40351
41521
|
const inputPath = rawPath || ".";
|
|
40352
41522
|
const home = os7.homedir();
|
|
40353
41523
|
if (inputPath.startsWith("~")) {
|
|
40354
|
-
return
|
|
41524
|
+
return path12.resolve(path12.join(home, inputPath.slice(1)));
|
|
40355
41525
|
}
|
|
40356
41526
|
if (process.platform === "win32") {
|
|
40357
41527
|
const normalized = normalizeWindowsRequestedPath(inputPath);
|
|
40358
|
-
if (
|
|
40359
|
-
return
|
|
41528
|
+
if (path12.win32.isAbsolute(normalized)) {
|
|
41529
|
+
return path12.win32.normalize(normalized);
|
|
40360
41530
|
}
|
|
40361
|
-
return
|
|
41531
|
+
return path12.win32.resolve(normalized);
|
|
40362
41532
|
}
|
|
40363
|
-
if (
|
|
40364
|
-
return
|
|
41533
|
+
if (path12.isAbsolute(inputPath)) {
|
|
41534
|
+
return path12.normalize(inputPath);
|
|
40365
41535
|
}
|
|
40366
|
-
return
|
|
41536
|
+
return path12.resolve(inputPath);
|
|
40367
41537
|
}
|
|
40368
41538
|
function listDirectoryEntriesSafe(dirPath) {
|
|
40369
41539
|
const entries = fs52.readdirSync(dirPath, { withFileTypes: true });
|
|
40370
41540
|
const files = [];
|
|
40371
41541
|
for (const entry of entries) {
|
|
40372
|
-
const entryPath =
|
|
41542
|
+
const entryPath = path12.join(dirPath, entry.name);
|
|
40373
41543
|
try {
|
|
40374
41544
|
if (entry.isDirectory()) {
|
|
40375
41545
|
files.push({ name: entry.name, type: "directory" });
|
|
@@ -40385,11 +41555,11 @@ ${effect.notification.body || ""}`.trim();
|
|
|
40385
41555
|
files.push({ name: entry.name, type: "file", size });
|
|
40386
41556
|
continue;
|
|
40387
41557
|
}
|
|
40388
|
-
const
|
|
41558
|
+
const stat22 = fs52.statSync(entryPath);
|
|
40389
41559
|
files.push({
|
|
40390
41560
|
name: entry.name,
|
|
40391
|
-
type:
|
|
40392
|
-
size:
|
|
41561
|
+
type: stat22.isDirectory() ? "directory" : "file",
|
|
41562
|
+
size: stat22.isFile() ? stat22.size : void 0
|
|
40393
41563
|
});
|
|
40394
41564
|
} catch {
|
|
40395
41565
|
}
|
|
@@ -40423,7 +41593,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
40423
41593
|
async function handleFileWrite(h, args) {
|
|
40424
41594
|
try {
|
|
40425
41595
|
const filePath = resolveSafePath(args?.path);
|
|
40426
|
-
fs52.mkdirSync(
|
|
41596
|
+
fs52.mkdirSync(path12.dirname(filePath), { recursive: true });
|
|
40427
41597
|
fs52.writeFileSync(filePath, args?.content || "", "utf-8");
|
|
40428
41598
|
return { success: true, path: filePath };
|
|
40429
41599
|
} catch (e) {
|
|
@@ -40764,7 +41934,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
40764
41934
|
const enterCount = cliCommand.enterCount || 1;
|
|
40765
41935
|
await adapter.writeRaw(cliCommand.text + "\r");
|
|
40766
41936
|
for (let i = 1; i < enterCount; i += 1) {
|
|
40767
|
-
await new Promise((
|
|
41937
|
+
await new Promise((resolve15) => setTimeout(resolve15, 50));
|
|
40768
41938
|
await adapter.writeRaw("\r");
|
|
40769
41939
|
}
|
|
40770
41940
|
}
|
|
@@ -41254,6 +42424,12 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41254
42424
|
this._currentRoute = this.resolveRoute(args);
|
|
41255
42425
|
const startedAt = Date.now();
|
|
41256
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
|
+
}
|
|
41257
42433
|
const sessionScopedCommands = /* @__PURE__ */ new Set([
|
|
41258
42434
|
"read_chat",
|
|
41259
42435
|
"get_chat_debug_bundle",
|
|
@@ -41279,7 +42455,6 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41279
42455
|
this.logCommandEnd(cmd, result2, startedAt);
|
|
41280
42456
|
return result2;
|
|
41281
42457
|
}
|
|
41282
|
-
let result;
|
|
41283
42458
|
if (!this._currentRoute.session && !this._currentRoute.managerKey && !this._currentRoute.providerType) {
|
|
41284
42459
|
const cdpCommands = ["send_chat", "read_chat", "list_chats", "new_chat", "switch_chat", "set_mode", "change_model", "set_thought_level", "resolve_action"];
|
|
41285
42460
|
if (cdpCommands.includes(cmd)) {
|
|
@@ -41430,7 +42605,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41430
42605
|
try {
|
|
41431
42606
|
const http3 = await import("http");
|
|
41432
42607
|
const postData = JSON.stringify(body);
|
|
41433
|
-
const result = await new Promise((
|
|
42608
|
+
const result = await new Promise((resolve15, reject) => {
|
|
41434
42609
|
const req = http3.request({
|
|
41435
42610
|
hostname: "127.0.0.1",
|
|
41436
42611
|
port: 19280,
|
|
@@ -41442,9 +42617,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41442
42617
|
res.on("data", (chunk) => data += chunk);
|
|
41443
42618
|
res.on("end", () => {
|
|
41444
42619
|
try {
|
|
41445
|
-
|
|
42620
|
+
resolve15(JSON.parse(data));
|
|
41446
42621
|
} catch {
|
|
41447
|
-
|
|
42622
|
+
resolve15({ raw: data });
|
|
41448
42623
|
}
|
|
41449
42624
|
});
|
|
41450
42625
|
});
|
|
@@ -41462,15 +42637,15 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41462
42637
|
if (!providerType) return { success: false, error: "providerType required" };
|
|
41463
42638
|
try {
|
|
41464
42639
|
const http3 = await import("http");
|
|
41465
|
-
const result = await new Promise((
|
|
42640
|
+
const result = await new Promise((resolve15, reject) => {
|
|
41466
42641
|
http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
|
|
41467
42642
|
let data = "";
|
|
41468
42643
|
res.on("data", (chunk) => data += chunk);
|
|
41469
42644
|
res.on("end", () => {
|
|
41470
42645
|
try {
|
|
41471
|
-
|
|
42646
|
+
resolve15(JSON.parse(data));
|
|
41472
42647
|
} catch {
|
|
41473
|
-
|
|
42648
|
+
resolve15({ raw: data });
|
|
41474
42649
|
}
|
|
41475
42650
|
});
|
|
41476
42651
|
}).on("error", reject);
|
|
@@ -41484,7 +42659,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41484
42659
|
try {
|
|
41485
42660
|
const http3 = await import("http");
|
|
41486
42661
|
const postData = JSON.stringify(args || {});
|
|
41487
|
-
const result = await new Promise((
|
|
42662
|
+
const result = await new Promise((resolve15, reject) => {
|
|
41488
42663
|
const req = http3.request({
|
|
41489
42664
|
hostname: "127.0.0.1",
|
|
41490
42665
|
port: 19280,
|
|
@@ -41496,9 +42671,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41496
42671
|
res.on("data", (chunk) => data += chunk);
|
|
41497
42672
|
res.on("end", () => {
|
|
41498
42673
|
try {
|
|
41499
|
-
|
|
42674
|
+
resolve15(JSON.parse(data));
|
|
41500
42675
|
} catch {
|
|
41501
|
-
|
|
42676
|
+
resolve15({ raw: data });
|
|
41502
42677
|
}
|
|
41503
42678
|
});
|
|
41504
42679
|
});
|
|
@@ -41513,7 +42688,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41513
42688
|
}
|
|
41514
42689
|
};
|
|
41515
42690
|
var os13 = __toESM2(require("os"));
|
|
41516
|
-
var
|
|
42691
|
+
var path16 = __toESM2(require("path"));
|
|
41517
42692
|
var crypto4 = __toESM2(require("crypto"));
|
|
41518
42693
|
var import_fs5 = require("fs");
|
|
41519
42694
|
var import_child_process6 = require("child_process");
|
|
@@ -41521,7 +42696,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41521
42696
|
init_provider_cli_adapter();
|
|
41522
42697
|
init_config();
|
|
41523
42698
|
var os12 = __toESM2(require("os"));
|
|
41524
|
-
var
|
|
42699
|
+
var path15 = __toESM2(require("path"));
|
|
41525
42700
|
var crypto3 = __toESM2(require("crypto"));
|
|
41526
42701
|
var fs6 = __toESM2(require("fs"));
|
|
41527
42702
|
var import_node_module = require("module");
|
|
@@ -41578,7 +42753,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41578
42753
|
var CachedDatabaseSync = null;
|
|
41579
42754
|
function getDatabaseSync() {
|
|
41580
42755
|
if (CachedDatabaseSync) return CachedDatabaseSync;
|
|
41581
|
-
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"));
|
|
41582
42757
|
const sqliteModule = requireFn(`node:${"sqlite"}`);
|
|
41583
42758
|
CachedDatabaseSync = sqliteModule.DatabaseSync;
|
|
41584
42759
|
if (!CachedDatabaseSync) {
|
|
@@ -41616,7 +42791,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41616
42791
|
if (status === "stopped") {
|
|
41617
42792
|
throw new Error("CLI runtime stopped before it became ready");
|
|
41618
42793
|
}
|
|
41619
|
-
await new Promise((
|
|
42794
|
+
await new Promise((resolve15) => setTimeout(resolve15, pollMs));
|
|
41620
42795
|
}
|
|
41621
42796
|
throw new Error(`CLI runtime did not become ready within ${timeoutMs}ms`);
|
|
41622
42797
|
}
|
|
@@ -41967,7 +43142,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41967
43142
|
const enterCount = cliCommand.enterCount || 1;
|
|
41968
43143
|
await this.adapter.writeRaw(cliCommand.text + "\r");
|
|
41969
43144
|
for (let i = 1; i < enterCount; i += 1) {
|
|
41970
|
-
await new Promise((
|
|
43145
|
+
await new Promise((resolve15) => setTimeout(resolve15, 50));
|
|
41971
43146
|
await this.adapter.writeRaw("\r");
|
|
41972
43147
|
}
|
|
41973
43148
|
}
|
|
@@ -43079,13 +44254,13 @@ ${effect.notification.body || ""}`.trim();
|
|
|
43079
44254
|
}
|
|
43080
44255
|
this.currentStatus = "waiting_approval";
|
|
43081
44256
|
this.detectStatusTransition();
|
|
43082
|
-
const approved = await new Promise((
|
|
43083
|
-
this.permissionResolvers.push(
|
|
44257
|
+
const approved = await new Promise((resolve15) => {
|
|
44258
|
+
this.permissionResolvers.push(resolve15);
|
|
43084
44259
|
setTimeout(() => {
|
|
43085
|
-
const idx = this.permissionResolvers.indexOf(
|
|
44260
|
+
const idx = this.permissionResolvers.indexOf(resolve15);
|
|
43086
44261
|
if (idx >= 0) {
|
|
43087
44262
|
this.permissionResolvers.splice(idx, 1);
|
|
43088
|
-
|
|
44263
|
+
resolve15(false);
|
|
43089
44264
|
}
|
|
43090
44265
|
}, 3e5);
|
|
43091
44266
|
});
|
|
@@ -43654,11 +44829,11 @@ ${rawInput}` : rawInput;
|
|
|
43654
44829
|
}
|
|
43655
44830
|
function isExplicitCommand(command) {
|
|
43656
44831
|
const trimmed = command.trim();
|
|
43657
|
-
return
|
|
44832
|
+
return path16.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
|
|
43658
44833
|
}
|
|
43659
44834
|
function expandExecutable(command) {
|
|
43660
44835
|
const trimmed = command.trim();
|
|
43661
|
-
return trimmed.startsWith("~") ?
|
|
44836
|
+
return trimmed.startsWith("~") ? path16.join(os13.homedir(), trimmed.slice(1)) : trimmed;
|
|
43662
44837
|
}
|
|
43663
44838
|
function commandExists(command) {
|
|
43664
44839
|
const trimmed = command.trim();
|
|
@@ -43939,7 +45114,7 @@ ${rawInput}` : rawInput;
|
|
|
43939
45114
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
43940
45115
|
const trimmed = (workingDir || "").trim();
|
|
43941
45116
|
if (!trimmed) throw new Error("working directory required");
|
|
43942
|
-
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) :
|
|
45117
|
+
const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os13.homedir()) : path16.resolve(trimmed);
|
|
43943
45118
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
43944
45119
|
const rawProvider = this.providerLoader.getByAlias(cliType);
|
|
43945
45120
|
const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
|
|
@@ -44438,9 +45613,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44438
45613
|
var import_child_process7 = require("child_process");
|
|
44439
45614
|
var net3 = __toESM2(require("net"));
|
|
44440
45615
|
var os15 = __toESM2(require("os"));
|
|
44441
|
-
var
|
|
45616
|
+
var path18 = __toESM2(require("path"));
|
|
44442
45617
|
var fs7 = __toESM2(require("fs"));
|
|
44443
|
-
var
|
|
45618
|
+
var path17 = __toESM2(require("path"));
|
|
44444
45619
|
var os14 = __toESM2(require("os"));
|
|
44445
45620
|
var chokidar = __toESM2((init_chokidar(), __toCommonJS(chokidar_exports)));
|
|
44446
45621
|
init_logger();
|
|
@@ -44701,7 +45876,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44701
45876
|
try {
|
|
44702
45877
|
if (!fs7.existsSync(candidate) || !fs7.statSync(candidate).isDirectory()) return false;
|
|
44703
45878
|
return ["ide", "extension", "cli", "acp"].some(
|
|
44704
|
-
(category) => fs7.existsSync(
|
|
45879
|
+
(category) => fs7.existsSync(path17.join(candidate, category))
|
|
44705
45880
|
);
|
|
44706
45881
|
} catch {
|
|
44707
45882
|
return false;
|
|
@@ -44709,20 +45884,20 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44709
45884
|
}
|
|
44710
45885
|
static hasProviderRootMarker(candidate) {
|
|
44711
45886
|
try {
|
|
44712
|
-
return fs7.existsSync(
|
|
45887
|
+
return fs7.existsSync(path17.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
|
|
44713
45888
|
} catch {
|
|
44714
45889
|
return false;
|
|
44715
45890
|
}
|
|
44716
45891
|
}
|
|
44717
45892
|
detectDefaultUserDir() {
|
|
44718
|
-
const fallback =
|
|
45893
|
+
const fallback = path17.join(os14.homedir(), ".adhdev", "providers");
|
|
44719
45894
|
const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
|
|
44720
45895
|
const visited = /* @__PURE__ */ new Set();
|
|
44721
45896
|
for (const start of this.probeStarts) {
|
|
44722
|
-
let current =
|
|
45897
|
+
let current = path17.resolve(start);
|
|
44723
45898
|
while (!visited.has(current)) {
|
|
44724
45899
|
visited.add(current);
|
|
44725
|
-
const siblingCandidate =
|
|
45900
|
+
const siblingCandidate = path17.join(path17.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
|
|
44726
45901
|
if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
|
|
44727
45902
|
const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
|
|
44728
45903
|
if (envOptIn || hasMarker) {
|
|
@@ -44744,7 +45919,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44744
45919
|
return { path: siblingCandidate, source };
|
|
44745
45920
|
}
|
|
44746
45921
|
}
|
|
44747
|
-
const parent =
|
|
45922
|
+
const parent = path17.dirname(current);
|
|
44748
45923
|
if (parent === current) break;
|
|
44749
45924
|
current = parent;
|
|
44750
45925
|
}
|
|
@@ -44754,11 +45929,11 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44754
45929
|
constructor(options) {
|
|
44755
45930
|
this.logFn = options?.logFn || LOG2.forComponent("Provider").asLogFn();
|
|
44756
45931
|
this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
|
|
44757
|
-
this.defaultProvidersDir =
|
|
45932
|
+
this.defaultProvidersDir = path17.join(os14.homedir(), ".adhdev", "providers");
|
|
44758
45933
|
const detected = this.detectDefaultUserDir();
|
|
44759
45934
|
this.userDir = detected.path;
|
|
44760
45935
|
this.userDirSource = detected.source;
|
|
44761
|
-
this.upstreamDir =
|
|
45936
|
+
this.upstreamDir = path17.join(this.defaultProvidersDir, ".upstream");
|
|
44762
45937
|
this.disableUpstream = false;
|
|
44763
45938
|
this.applySourceConfig({
|
|
44764
45939
|
userDir: options?.userDir,
|
|
@@ -44817,7 +45992,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44817
45992
|
this.userDir = detected.path;
|
|
44818
45993
|
this.userDirSource = detected.source;
|
|
44819
45994
|
}
|
|
44820
|
-
this.upstreamDir =
|
|
45995
|
+
this.upstreamDir = path17.join(this.defaultProvidersDir, ".upstream");
|
|
44821
45996
|
this.disableUpstream = this.sourceMode === "no-upstream";
|
|
44822
45997
|
if (this.explicitProviderDir) {
|
|
44823
45998
|
this.log(`Config 'providerDir' applied: ${this.userDir}`);
|
|
@@ -44831,7 +46006,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44831
46006
|
* Canonical provider directory shape for a given root.
|
|
44832
46007
|
*/
|
|
44833
46008
|
getProviderDir(root, category, type) {
|
|
44834
|
-
return
|
|
46009
|
+
return path17.join(root, category, type);
|
|
44835
46010
|
}
|
|
44836
46011
|
/**
|
|
44837
46012
|
* Canonical user override directory for a provider.
|
|
@@ -44858,7 +46033,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44858
46033
|
resolveProviderFile(type, ...segments) {
|
|
44859
46034
|
const dir = this.findProviderDirInternal(type);
|
|
44860
46035
|
if (!dir) return null;
|
|
44861
|
-
return
|
|
46036
|
+
return path17.join(dir, ...segments);
|
|
44862
46037
|
}
|
|
44863
46038
|
/**
|
|
44864
46039
|
* Load all providers (3-tier priority)
|
|
@@ -44897,7 +46072,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44897
46072
|
if (!fs7.existsSync(this.upstreamDir)) return false;
|
|
44898
46073
|
try {
|
|
44899
46074
|
return fs7.readdirSync(this.upstreamDir).some(
|
|
44900
|
-
(d) => fs7.statSync(
|
|
46075
|
+
(d) => fs7.statSync(path17.join(this.upstreamDir, d)).isDirectory()
|
|
44901
46076
|
);
|
|
44902
46077
|
} catch {
|
|
44903
46078
|
return false;
|
|
@@ -45394,8 +46569,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45394
46569
|
resolved._resolvedScriptDir = entry.scriptDir;
|
|
45395
46570
|
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
45396
46571
|
if (providerDir) {
|
|
45397
|
-
const fullDir =
|
|
45398
|
-
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;
|
|
45399
46574
|
}
|
|
45400
46575
|
matched = true;
|
|
45401
46576
|
}
|
|
@@ -45410,8 +46585,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45410
46585
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
45411
46586
|
resolved._resolvedScriptsSource = "defaultScriptDir:version_miss";
|
|
45412
46587
|
if (providerDir) {
|
|
45413
|
-
const fullDir =
|
|
45414
|
-
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;
|
|
45415
46590
|
}
|
|
45416
46591
|
}
|
|
45417
46592
|
resolved._versionWarning = `Version ${currentVersion} not in compatibility matrix. Using default scripts.`;
|
|
@@ -45428,8 +46603,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45428
46603
|
resolved._resolvedScriptDir = dirOverride;
|
|
45429
46604
|
resolved._resolvedScriptsSource = `versions:${range}`;
|
|
45430
46605
|
if (providerDir) {
|
|
45431
|
-
const fullDir =
|
|
45432
|
-
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;
|
|
45433
46608
|
}
|
|
45434
46609
|
}
|
|
45435
46610
|
} else if (override.scripts) {
|
|
@@ -45445,8 +46620,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45445
46620
|
resolved._resolvedScriptDir = base.defaultScriptDir;
|
|
45446
46621
|
resolved._resolvedScriptsSource = "defaultScriptDir:no_version";
|
|
45447
46622
|
if (providerDir) {
|
|
45448
|
-
const fullDir =
|
|
45449
|
-
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;
|
|
45450
46625
|
}
|
|
45451
46626
|
}
|
|
45452
46627
|
}
|
|
@@ -45478,14 +46653,14 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45478
46653
|
this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
|
|
45479
46654
|
return null;
|
|
45480
46655
|
}
|
|
45481
|
-
const dir =
|
|
46656
|
+
const dir = path17.join(providerDir, scriptDir);
|
|
45482
46657
|
if (!fs7.existsSync(dir)) {
|
|
45483
46658
|
this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
45484
46659
|
return null;
|
|
45485
46660
|
}
|
|
45486
46661
|
const cached2 = this.scriptsCache.get(dir);
|
|
45487
46662
|
if (cached2) return cached2;
|
|
45488
|
-
const scriptsJs =
|
|
46663
|
+
const scriptsJs = path17.join(dir, "scripts.js");
|
|
45489
46664
|
if (fs7.existsSync(scriptsJs)) {
|
|
45490
46665
|
try {
|
|
45491
46666
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -45527,7 +46702,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45527
46702
|
return;
|
|
45528
46703
|
}
|
|
45529
46704
|
if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
|
|
45530
|
-
this.log(`File changed: ${
|
|
46705
|
+
this.log(`File changed: ${path17.basename(filePath)}, reloading...`);
|
|
45531
46706
|
this.reload();
|
|
45532
46707
|
}
|
|
45533
46708
|
};
|
|
@@ -45582,7 +46757,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45582
46757
|
}
|
|
45583
46758
|
const https = require("https");
|
|
45584
46759
|
const { execSync: execSync7 } = require("child_process");
|
|
45585
|
-
const metaPath =
|
|
46760
|
+
const metaPath = path17.join(this.upstreamDir, _ProviderLoader.META_FILE);
|
|
45586
46761
|
let prevEtag = "";
|
|
45587
46762
|
let prevTimestamp = 0;
|
|
45588
46763
|
try {
|
|
@@ -45599,7 +46774,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45599
46774
|
return { updated: false };
|
|
45600
46775
|
}
|
|
45601
46776
|
try {
|
|
45602
|
-
const etag = await new Promise((
|
|
46777
|
+
const etag = await new Promise((resolve15, reject) => {
|
|
45603
46778
|
const options = {
|
|
45604
46779
|
method: "HEAD",
|
|
45605
46780
|
hostname: "github.com",
|
|
@@ -45617,7 +46792,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45617
46792
|
headers: { "User-Agent": "adhdev-launcher" },
|
|
45618
46793
|
timeout: 1e4
|
|
45619
46794
|
}, (res2) => {
|
|
45620
|
-
|
|
46795
|
+
resolve15(res2.headers.etag || res2.headers["last-modified"] || "");
|
|
45621
46796
|
});
|
|
45622
46797
|
req2.on("error", reject);
|
|
45623
46798
|
req2.on("timeout", () => {
|
|
@@ -45626,7 +46801,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45626
46801
|
});
|
|
45627
46802
|
req2.end();
|
|
45628
46803
|
} else {
|
|
45629
|
-
|
|
46804
|
+
resolve15(res.headers.etag || res.headers["last-modified"] || "");
|
|
45630
46805
|
}
|
|
45631
46806
|
});
|
|
45632
46807
|
req.on("error", reject);
|
|
@@ -45642,17 +46817,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45642
46817
|
return { updated: false };
|
|
45643
46818
|
}
|
|
45644
46819
|
this.log("Downloading latest providers from GitHub...");
|
|
45645
|
-
const tmpTar =
|
|
45646
|
-
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()}`);
|
|
45647
46822
|
await this.downloadFile(_ProviderLoader.GITHUB_TARBALL_URL, tmpTar);
|
|
45648
46823
|
fs7.mkdirSync(tmpExtract, { recursive: true });
|
|
45649
46824
|
execSync7(`tar -xzf "${tmpTar}" -C "${tmpExtract}"`, { timeout: 3e4 });
|
|
45650
46825
|
const extracted = fs7.readdirSync(tmpExtract);
|
|
45651
46826
|
const rootDir = extracted.find(
|
|
45652
|
-
(d) => fs7.statSync(
|
|
46827
|
+
(d) => fs7.statSync(path17.join(tmpExtract, d)).isDirectory() && d.startsWith("adhdev-providers")
|
|
45653
46828
|
);
|
|
45654
46829
|
if (!rootDir) throw new Error("Unexpected tarball structure");
|
|
45655
|
-
const sourceDir =
|
|
46830
|
+
const sourceDir = path17.join(tmpExtract, rootDir);
|
|
45656
46831
|
const backupDir = this.upstreamDir + ".bak";
|
|
45657
46832
|
if (fs7.existsSync(this.upstreamDir)) {
|
|
45658
46833
|
if (fs7.existsSync(backupDir)) fs7.rmSync(backupDir, { recursive: true, force: true });
|
|
@@ -45690,7 +46865,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45690
46865
|
downloadFile(url2, destPath) {
|
|
45691
46866
|
const https = require("https");
|
|
45692
46867
|
const http3 = require("http");
|
|
45693
|
-
return new Promise((
|
|
46868
|
+
return new Promise((resolve15, reject) => {
|
|
45694
46869
|
const doRequest = (reqUrl, redirectCount = 0) => {
|
|
45695
46870
|
if (redirectCount > 5) {
|
|
45696
46871
|
reject(new Error("Too many redirects"));
|
|
@@ -45710,7 +46885,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45710
46885
|
res.pipe(ws2);
|
|
45711
46886
|
ws2.on("finish", () => {
|
|
45712
46887
|
ws2.close();
|
|
45713
|
-
|
|
46888
|
+
resolve15();
|
|
45714
46889
|
});
|
|
45715
46890
|
ws2.on("error", reject);
|
|
45716
46891
|
});
|
|
@@ -45727,8 +46902,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45727
46902
|
copyDirRecursive(src, dest) {
|
|
45728
46903
|
fs7.mkdirSync(dest, { recursive: true });
|
|
45729
46904
|
for (const entry of fs7.readdirSync(src, { withFileTypes: true })) {
|
|
45730
|
-
const srcPath =
|
|
45731
|
-
const destPath =
|
|
46905
|
+
const srcPath = path17.join(src, entry.name);
|
|
46906
|
+
const destPath = path17.join(dest, entry.name);
|
|
45732
46907
|
if (entry.isDirectory()) {
|
|
45733
46908
|
this.copyDirRecursive(srcPath, destPath);
|
|
45734
46909
|
} else {
|
|
@@ -45739,7 +46914,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45739
46914
|
/** .meta.json save */
|
|
45740
46915
|
writeMeta(metaPath, etag, timestamp) {
|
|
45741
46916
|
try {
|
|
45742
|
-
fs7.mkdirSync(
|
|
46917
|
+
fs7.mkdirSync(path17.dirname(metaPath), { recursive: true });
|
|
45743
46918
|
fs7.writeFileSync(metaPath, JSON.stringify({
|
|
45744
46919
|
etag,
|
|
45745
46920
|
timestamp,
|
|
@@ -45756,7 +46931,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45756
46931
|
const scan = (d) => {
|
|
45757
46932
|
try {
|
|
45758
46933
|
for (const entry of fs7.readdirSync(d, { withFileTypes: true })) {
|
|
45759
|
-
if (entry.isDirectory()) scan(
|
|
46934
|
+
if (entry.isDirectory()) scan(path17.join(d, entry.name));
|
|
45760
46935
|
else if (entry.name === "provider.json") count++;
|
|
45761
46936
|
}
|
|
45762
46937
|
} catch {
|
|
@@ -45984,17 +47159,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45984
47159
|
for (const root of searchRoots) {
|
|
45985
47160
|
if (!fs7.existsSync(root)) continue;
|
|
45986
47161
|
const candidate = this.getProviderDir(root, cat, type);
|
|
45987
|
-
if (fs7.existsSync(
|
|
45988
|
-
const catDir =
|
|
47162
|
+
if (fs7.existsSync(path17.join(candidate, "provider.json"))) return candidate;
|
|
47163
|
+
const catDir = path17.join(root, cat);
|
|
45989
47164
|
if (fs7.existsSync(catDir)) {
|
|
45990
47165
|
try {
|
|
45991
47166
|
for (const entry of fs7.readdirSync(catDir, { withFileTypes: true })) {
|
|
45992
47167
|
if (!entry.isDirectory()) continue;
|
|
45993
|
-
const jsonPath =
|
|
47168
|
+
const jsonPath = path17.join(catDir, entry.name, "provider.json");
|
|
45994
47169
|
if (fs7.existsSync(jsonPath)) {
|
|
45995
47170
|
try {
|
|
45996
47171
|
const data = JSON.parse(fs7.readFileSync(jsonPath, "utf-8"));
|
|
45997
|
-
if (data.type === type) return
|
|
47172
|
+
if (data.type === type) return path17.join(catDir, entry.name);
|
|
45998
47173
|
} catch {
|
|
45999
47174
|
}
|
|
46000
47175
|
}
|
|
@@ -46011,7 +47186,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46011
47186
|
* (template substitution is NOT applied here — scripts.js handles that)
|
|
46012
47187
|
*/
|
|
46013
47188
|
buildScriptWrappersFromDir(dir) {
|
|
46014
|
-
const scriptsJs =
|
|
47189
|
+
const scriptsJs = path17.join(dir, "scripts.js");
|
|
46015
47190
|
if (fs7.existsSync(scriptsJs)) {
|
|
46016
47191
|
try {
|
|
46017
47192
|
delete require.cache[require.resolve(scriptsJs)];
|
|
@@ -46025,7 +47200,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46025
47200
|
for (const file2 of fs7.readdirSync(dir)) {
|
|
46026
47201
|
if (!file2.endsWith(".js")) continue;
|
|
46027
47202
|
const scriptName = toCamel(file2.replace(".js", ""));
|
|
46028
|
-
const filePath =
|
|
47203
|
+
const filePath = path17.join(dir, file2);
|
|
46029
47204
|
result[scriptName] = (...args) => {
|
|
46030
47205
|
try {
|
|
46031
47206
|
let content = fs7.readFileSync(filePath, "utf-8");
|
|
@@ -46085,7 +47260,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46085
47260
|
}
|
|
46086
47261
|
const hasJson = entries.some((e) => e.name === "provider.json");
|
|
46087
47262
|
if (hasJson) {
|
|
46088
|
-
const jsonPath =
|
|
47263
|
+
const jsonPath = path17.join(d, "provider.json");
|
|
46089
47264
|
try {
|
|
46090
47265
|
const raw = fs7.readFileSync(jsonPath, "utf-8");
|
|
46091
47266
|
const mod = JSON.parse(raw);
|
|
@@ -46106,7 +47281,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46106
47281
|
this.log(`\u26A0 Invalid provider at ${jsonPath}: ${validation.errors.join("; ")}`);
|
|
46107
47282
|
} else {
|
|
46108
47283
|
const hasCompatibility = Array.isArray(normalizedProvider.compatibility);
|
|
46109
|
-
const scriptsPath =
|
|
47284
|
+
const scriptsPath = path17.join(d, "scripts.js");
|
|
46110
47285
|
if (!hasCompatibility && fs7.existsSync(scriptsPath)) {
|
|
46111
47286
|
try {
|
|
46112
47287
|
delete require.cache[require.resolve(scriptsPath)];
|
|
@@ -46132,7 +47307,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46132
47307
|
if (!entry.isDirectory()) continue;
|
|
46133
47308
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
46134
47309
|
if (excludeDirs && d === dir && excludeDirs.includes(entry.name)) continue;
|
|
46135
|
-
scan(
|
|
47310
|
+
scan(path17.join(d, entry.name));
|
|
46136
47311
|
}
|
|
46137
47312
|
}
|
|
46138
47313
|
};
|
|
@@ -46167,9 +47342,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46167
47342
|
}
|
|
46168
47343
|
}
|
|
46169
47344
|
compareVersions(a, b2) {
|
|
46170
|
-
const
|
|
46171
|
-
const pa2 =
|
|
46172
|
-
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);
|
|
46173
47348
|
for (let i = 0; i < Math.max(pa2.length, pb.length); i++) {
|
|
46174
47349
|
const va2 = pa2[i] || 0;
|
|
46175
47350
|
const vb = pb[i] || 0;
|
|
@@ -46285,17 +47460,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46285
47460
|
throw new Error("No free port found");
|
|
46286
47461
|
}
|
|
46287
47462
|
function checkPortFree(port) {
|
|
46288
|
-
return new Promise((
|
|
47463
|
+
return new Promise((resolve15) => {
|
|
46289
47464
|
const server = net3.createServer();
|
|
46290
47465
|
server.unref();
|
|
46291
|
-
server.on("error", () =>
|
|
47466
|
+
server.on("error", () => resolve15(false));
|
|
46292
47467
|
server.listen(port, "127.0.0.1", () => {
|
|
46293
|
-
server.close(() =>
|
|
47468
|
+
server.close(() => resolve15(true));
|
|
46294
47469
|
});
|
|
46295
47470
|
});
|
|
46296
47471
|
}
|
|
46297
47472
|
async function isCdpActive(port) {
|
|
46298
|
-
return new Promise((
|
|
47473
|
+
return new Promise((resolve15) => {
|
|
46299
47474
|
const req = require("http").get(`http://127.0.0.1:${port}/json/version`, {
|
|
46300
47475
|
timeout: 2e3
|
|
46301
47476
|
}, (res) => {
|
|
@@ -46304,16 +47479,16 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46304
47479
|
res.on("end", () => {
|
|
46305
47480
|
try {
|
|
46306
47481
|
const info = JSON.parse(data);
|
|
46307
|
-
|
|
47482
|
+
resolve15(!!info["WebKit-Version"] || !!info["Browser"]);
|
|
46308
47483
|
} catch {
|
|
46309
|
-
|
|
47484
|
+
resolve15(false);
|
|
46310
47485
|
}
|
|
46311
47486
|
});
|
|
46312
47487
|
});
|
|
46313
|
-
req.on("error", () =>
|
|
47488
|
+
req.on("error", () => resolve15(false));
|
|
46314
47489
|
req.on("timeout", () => {
|
|
46315
47490
|
req.destroy();
|
|
46316
|
-
|
|
47491
|
+
resolve15(false);
|
|
46317
47492
|
});
|
|
46318
47493
|
});
|
|
46319
47494
|
}
|
|
@@ -46453,8 +47628,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46453
47628
|
const appNameMap = getMacAppIdentifiers();
|
|
46454
47629
|
const appName = appNameMap[ideId];
|
|
46455
47630
|
if (appName) {
|
|
46456
|
-
const storagePath =
|
|
46457
|
-
process.env.APPDATA ||
|
|
47631
|
+
const storagePath = path18.join(
|
|
47632
|
+
process.env.APPDATA || path18.join(os15.homedir(), "AppData", "Roaming"),
|
|
46458
47633
|
appName,
|
|
46459
47634
|
"storage.json"
|
|
46460
47635
|
);
|
|
@@ -46628,9 +47803,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46628
47803
|
init_config();
|
|
46629
47804
|
init_logger();
|
|
46630
47805
|
var fs8 = __toESM2(require("fs"));
|
|
46631
|
-
var
|
|
47806
|
+
var path19 = __toESM2(require("path"));
|
|
46632
47807
|
var os16 = __toESM2(require("os"));
|
|
46633
|
-
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");
|
|
46634
47809
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
46635
47810
|
var MAX_DAYS = 7;
|
|
46636
47811
|
try {
|
|
@@ -46668,13 +47843,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46668
47843
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
46669
47844
|
}
|
|
46670
47845
|
var currentDate2 = getDateStr2();
|
|
46671
|
-
var currentFile =
|
|
47846
|
+
var currentFile = path19.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
46672
47847
|
var writeCount2 = 0;
|
|
46673
47848
|
function checkRotation() {
|
|
46674
47849
|
const today = getDateStr2();
|
|
46675
47850
|
if (today !== currentDate2) {
|
|
46676
47851
|
currentDate2 = today;
|
|
46677
|
-
currentFile =
|
|
47852
|
+
currentFile = path19.join(LOG_DIR2, `commands-${currentDate2}.jsonl`);
|
|
46678
47853
|
cleanOldFiles();
|
|
46679
47854
|
}
|
|
46680
47855
|
}
|
|
@@ -46688,7 +47863,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46688
47863
|
const dateMatch = file2.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
46689
47864
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
46690
47865
|
try {
|
|
46691
|
-
fs8.unlinkSync(
|
|
47866
|
+
fs8.unlinkSync(path19.join(LOG_DIR2, file2));
|
|
46692
47867
|
} catch {
|
|
46693
47868
|
}
|
|
46694
47869
|
}
|
|
@@ -46698,8 +47873,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46698
47873
|
}
|
|
46699
47874
|
function checkSize() {
|
|
46700
47875
|
try {
|
|
46701
|
-
const
|
|
46702
|
-
if (
|
|
47876
|
+
const stat22 = fs8.statSync(currentFile);
|
|
47877
|
+
if (stat22.size > MAX_FILE_SIZE) {
|
|
46703
47878
|
const backup = currentFile.replace(".jsonl", ".1.jsonl");
|
|
46704
47879
|
try {
|
|
46705
47880
|
fs8.unlinkSync(backup);
|
|
@@ -46981,12 +48156,18 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46981
48156
|
const unreadSourceSessions = buildSessionEntries(
|
|
46982
48157
|
options.allStates,
|
|
46983
48158
|
options.cdpManagers,
|
|
46984
|
-
{
|
|
48159
|
+
{
|
|
48160
|
+
profile: "full",
|
|
48161
|
+
getGitSummaryForWorkspace: options.getGitSummaryForWorkspace
|
|
48162
|
+
}
|
|
46985
48163
|
);
|
|
46986
48164
|
const sessions = profile === "full" ? unreadSourceSessions : profile === "live" ? unreadSourceSessions.map(projectLiveSessionFromFull) : buildSessionEntries(
|
|
46987
48165
|
options.allStates,
|
|
46988
48166
|
options.cdpManagers,
|
|
46989
|
-
{
|
|
48167
|
+
{
|
|
48168
|
+
profile,
|
|
48169
|
+
getGitSummaryForWorkspace: options.getGitSummaryForWorkspace
|
|
48170
|
+
}
|
|
46990
48171
|
);
|
|
46991
48172
|
const sessionsById = new Map(sessions.map((session) => [session.id, session]));
|
|
46992
48173
|
for (const sourceSession of unreadSourceSessions) {
|
|
@@ -47078,13 +48259,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47078
48259
|
var import_child_process9 = require("child_process");
|
|
47079
48260
|
var fs9 = __toESM2(require("fs"));
|
|
47080
48261
|
var os18 = __toESM2(require("os"));
|
|
47081
|
-
var
|
|
48262
|
+
var path20 = __toESM2(require("path"));
|
|
47082
48263
|
var UPGRADE_HELPER_ENV = "ADHDEV_DAEMON_UPGRADE_HELPER";
|
|
47083
48264
|
function getUpgradeLogPath() {
|
|
47084
48265
|
const home = os18.homedir();
|
|
47085
|
-
const dir =
|
|
48266
|
+
const dir = path20.join(home, ".adhdev");
|
|
47086
48267
|
fs9.mkdirSync(dir, { recursive: true });
|
|
47087
|
-
return
|
|
48268
|
+
return path20.join(dir, "daemon-upgrade.log");
|
|
47088
48269
|
}
|
|
47089
48270
|
function appendUpgradeLog(message) {
|
|
47090
48271
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
|
|
@@ -47095,14 +48276,14 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47095
48276
|
}
|
|
47096
48277
|
}
|
|
47097
48278
|
function resolveSiblingNpmInvocation(nodeExecutable, platform10 = process.platform) {
|
|
47098
|
-
const binDir =
|
|
48279
|
+
const binDir = path20.dirname(nodeExecutable);
|
|
47099
48280
|
if (platform10 === "win32") {
|
|
47100
|
-
const npmCliPath =
|
|
48281
|
+
const npmCliPath = path20.join(binDir, "node_modules", "npm", "bin", "npm-cli.js");
|
|
47101
48282
|
if (fs9.existsSync(npmCliPath)) {
|
|
47102
48283
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
47103
48284
|
}
|
|
47104
48285
|
for (const candidate of ["npm.exe", "npm"]) {
|
|
47105
|
-
const candidatePath =
|
|
48286
|
+
const candidatePath = path20.join(binDir, candidate);
|
|
47106
48287
|
if (fs9.existsSync(candidatePath)) {
|
|
47107
48288
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
47108
48289
|
}
|
|
@@ -47110,7 +48291,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47110
48291
|
return { executable: nodeExecutable, argsPrefix: [npmCliPath], execOptions: getNpmExecOptions(platform10) };
|
|
47111
48292
|
}
|
|
47112
48293
|
for (const candidate of ["npm"]) {
|
|
47113
|
-
const candidatePath =
|
|
48294
|
+
const candidatePath = path20.join(binDir, candidate);
|
|
47114
48295
|
if (fs9.existsSync(candidatePath)) {
|
|
47115
48296
|
return { executable: candidatePath, argsPrefix: [], execOptions: getNpmExecOptions(platform10) };
|
|
47116
48297
|
}
|
|
@@ -47127,13 +48308,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47127
48308
|
let currentDir = resolvedPath;
|
|
47128
48309
|
try {
|
|
47129
48310
|
if (fs9.statSync(resolvedPath).isFile()) {
|
|
47130
|
-
currentDir =
|
|
48311
|
+
currentDir = path20.dirname(resolvedPath);
|
|
47131
48312
|
}
|
|
47132
48313
|
} catch {
|
|
47133
|
-
currentDir =
|
|
48314
|
+
currentDir = path20.dirname(resolvedPath);
|
|
47134
48315
|
}
|
|
47135
48316
|
while (true) {
|
|
47136
|
-
const packageJsonPath =
|
|
48317
|
+
const packageJsonPath = path20.join(currentDir, "package.json");
|
|
47137
48318
|
try {
|
|
47138
48319
|
if (fs9.existsSync(packageJsonPath)) {
|
|
47139
48320
|
const parsed = JSON.parse(fs9.readFileSync(packageJsonPath, "utf8"));
|
|
@@ -47144,7 +48325,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47144
48325
|
}
|
|
47145
48326
|
} catch {
|
|
47146
48327
|
}
|
|
47147
|
-
const parentDir =
|
|
48328
|
+
const parentDir = path20.dirname(currentDir);
|
|
47148
48329
|
if (parentDir === currentDir) {
|
|
47149
48330
|
return null;
|
|
47150
48331
|
}
|
|
@@ -47152,13 +48333,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47152
48333
|
}
|
|
47153
48334
|
}
|
|
47154
48335
|
function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
|
|
47155
|
-
const nodeModulesDir = packageName.startsWith("@") ?
|
|
47156
|
-
if (
|
|
48336
|
+
const nodeModulesDir = packageName.startsWith("@") ? path20.dirname(path20.dirname(packageRoot)) : path20.dirname(packageRoot);
|
|
48337
|
+
if (path20.basename(nodeModulesDir) !== "node_modules") {
|
|
47157
48338
|
return null;
|
|
47158
48339
|
}
|
|
47159
|
-
const maybeLibDir =
|
|
47160
|
-
if (
|
|
47161
|
-
return
|
|
48340
|
+
const maybeLibDir = path20.dirname(nodeModulesDir);
|
|
48341
|
+
if (path20.basename(maybeLibDir) === "lib") {
|
|
48342
|
+
return path20.dirname(maybeLibDir);
|
|
47162
48343
|
}
|
|
47163
48344
|
return maybeLibDir;
|
|
47164
48345
|
}
|
|
@@ -47266,14 +48447,14 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47266
48447
|
while (Date.now() - start < timeoutMs) {
|
|
47267
48448
|
try {
|
|
47268
48449
|
process.kill(pid, 0);
|
|
47269
|
-
await new Promise((
|
|
48450
|
+
await new Promise((resolve15) => setTimeout(resolve15, 250));
|
|
47270
48451
|
} catch {
|
|
47271
48452
|
return;
|
|
47272
48453
|
}
|
|
47273
48454
|
}
|
|
47274
48455
|
}
|
|
47275
48456
|
function stopSessionHostProcesses(appName) {
|
|
47276
|
-
const pidFile =
|
|
48457
|
+
const pidFile = path20.join(os18.homedir(), ".adhdev", `${appName}-session-host.pid`);
|
|
47277
48458
|
try {
|
|
47278
48459
|
if (fs9.existsSync(pidFile)) {
|
|
47279
48460
|
const pid = Number.parseInt(fs9.readFileSync(pidFile, "utf8").trim(), 10);
|
|
@@ -47290,7 +48471,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47290
48471
|
}
|
|
47291
48472
|
}
|
|
47292
48473
|
function removeDaemonPidFile() {
|
|
47293
|
-
const pidFile =
|
|
48474
|
+
const pidFile = path20.join(os18.homedir(), ".adhdev", "daemon.pid");
|
|
47294
48475
|
try {
|
|
47295
48476
|
fs9.unlinkSync(pidFile);
|
|
47296
48477
|
} catch {
|
|
@@ -47301,7 +48482,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47301
48482
|
const npmRoot = String(execNpmCommandSync(["root", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
47302
48483
|
if (!npmRoot) return;
|
|
47303
48484
|
const npmPrefix = surface.installPrefix || String(execNpmCommandSync(["prefix", "-g", ...prefixArgs], { encoding: "utf8" }, surface)).trim();
|
|
47304
|
-
const binDir = process.platform === "win32" ? npmPrefix :
|
|
48485
|
+
const binDir = process.platform === "win32" ? npmPrefix : path20.join(npmPrefix, "bin");
|
|
47305
48486
|
const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
|
|
47306
48487
|
const binNames = /* @__PURE__ */ new Set([packageBaseName]);
|
|
47307
48488
|
if (pkgName === "@adhdev/daemon-standalone") {
|
|
@@ -47309,25 +48490,25 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47309
48490
|
}
|
|
47310
48491
|
if (pkgName.startsWith("@")) {
|
|
47311
48492
|
const [scope, name] = pkgName.split("/");
|
|
47312
|
-
const scopeDir =
|
|
48493
|
+
const scopeDir = path20.join(npmRoot, scope);
|
|
47313
48494
|
if (!fs9.existsSync(scopeDir)) return;
|
|
47314
48495
|
for (const entry of fs9.readdirSync(scopeDir)) {
|
|
47315
48496
|
if (!entry.startsWith(`.${name}-`)) continue;
|
|
47316
|
-
fs9.rmSync(
|
|
47317
|
-
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)}`);
|
|
47318
48499
|
}
|
|
47319
48500
|
} else {
|
|
47320
48501
|
for (const entry of fs9.readdirSync(npmRoot)) {
|
|
47321
48502
|
if (!entry.startsWith(`.${pkgName}-`)) continue;
|
|
47322
|
-
fs9.rmSync(
|
|
47323
|
-
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)}`);
|
|
47324
48505
|
}
|
|
47325
48506
|
}
|
|
47326
48507
|
if (fs9.existsSync(binDir)) {
|
|
47327
48508
|
for (const entry of fs9.readdirSync(binDir)) {
|
|
47328
48509
|
if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
|
|
47329
|
-
fs9.rmSync(
|
|
47330
|
-
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)}`);
|
|
47331
48512
|
}
|
|
47332
48513
|
}
|
|
47333
48514
|
}
|
|
@@ -47377,7 +48558,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47377
48558
|
appendUpgradeLog(installOutput.trim());
|
|
47378
48559
|
}
|
|
47379
48560
|
if (process.platform === "win32") {
|
|
47380
|
-
await new Promise((
|
|
48561
|
+
await new Promise((resolve15) => setTimeout(resolve15, 500));
|
|
47381
48562
|
cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
|
|
47382
48563
|
appendUpgradeLog("Post-install staging cleanup complete");
|
|
47383
48564
|
}
|
|
@@ -48757,7 +49938,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
48757
49938
|
const beforeCount = this.messageCount(before);
|
|
48758
49939
|
const beforeSignature = this.lastMessageSignature(before);
|
|
48759
49940
|
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
48760
|
-
await new Promise((
|
|
49941
|
+
await new Promise((resolve15) => setTimeout(resolve15, 250));
|
|
48761
49942
|
let state;
|
|
48762
49943
|
try {
|
|
48763
49944
|
state = await this.readChat(evaluate);
|
|
@@ -48779,7 +49960,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
48779
49960
|
if (this.messageCount(first) > 0 || this.lastMessageSignature(first)) {
|
|
48780
49961
|
return first;
|
|
48781
49962
|
}
|
|
48782
|
-
await new Promise((
|
|
49963
|
+
await new Promise((resolve15) => setTimeout(resolve15, 150));
|
|
48783
49964
|
const second = await this.readChat(evaluate);
|
|
48784
49965
|
return this.messageCount(second) >= this.messageCount(first) ? second : first;
|
|
48785
49966
|
}
|
|
@@ -48930,7 +50111,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
48930
50111
|
if (typeof data.error === "string" && data.error.trim()) return false;
|
|
48931
50112
|
}
|
|
48932
50113
|
for (let attempt = 0; attempt < 6; attempt += 1) {
|
|
48933
|
-
await new Promise((
|
|
50114
|
+
await new Promise((resolve15) => setTimeout(resolve15, 250));
|
|
48934
50115
|
const state = await this.readChat(evaluate);
|
|
48935
50116
|
const title = this.getStateTitle(state);
|
|
48936
50117
|
if (this.titlesMatch(title, sessionId)) return true;
|
|
@@ -49779,11 +50960,11 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
49779
50960
|
init_io_contracts();
|
|
49780
50961
|
init_chat_message_normalization();
|
|
49781
50962
|
var fs11 = __toESM2(require("fs"));
|
|
49782
|
-
var
|
|
50963
|
+
var path21 = __toESM2(require("path"));
|
|
49783
50964
|
var os19 = __toESM2(require("os"));
|
|
49784
50965
|
var import_child_process10 = require("child_process");
|
|
49785
50966
|
var import_os3 = require("os");
|
|
49786
|
-
var ARCHIVE_PATH =
|
|
50967
|
+
var ARCHIVE_PATH = path21.join(os19.homedir(), ".adhdev", "version-history.json");
|
|
49787
50968
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
49788
50969
|
var VersionArchive = class {
|
|
49789
50970
|
history = {};
|
|
@@ -49830,7 +51011,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
49830
51011
|
}
|
|
49831
51012
|
save() {
|
|
49832
51013
|
try {
|
|
49833
|
-
fs11.mkdirSync(
|
|
51014
|
+
fs11.mkdirSync(path21.dirname(ARCHIVE_PATH), { recursive: true });
|
|
49834
51015
|
fs11.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
49835
51016
|
} catch {
|
|
49836
51017
|
}
|
|
@@ -49887,7 +51068,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
49887
51068
|
for (const p of paths) {
|
|
49888
51069
|
if (p.includes("*")) {
|
|
49889
51070
|
const home = os19.homedir();
|
|
49890
|
-
const resolved = p.replace(/\*/g, home.split(
|
|
51071
|
+
const resolved = p.replace(/\*/g, home.split(path21.sep).pop() || "");
|
|
49891
51072
|
if (fs11.existsSync(resolved)) return resolved;
|
|
49892
51073
|
} else {
|
|
49893
51074
|
if (fs11.existsSync(p)) return p;
|
|
@@ -49897,7 +51078,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
49897
51078
|
}
|
|
49898
51079
|
function getMacAppVersion(appPath) {
|
|
49899
51080
|
if ((0, import_os3.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
49900
|
-
const plistPath =
|
|
51081
|
+
const plistPath = path21.join(appPath, "Contents", "Info.plist");
|
|
49901
51082
|
if (!fs11.existsSync(plistPath)) return null;
|
|
49902
51083
|
const raw = runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
49903
51084
|
return raw || null;
|
|
@@ -49923,7 +51104,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
49923
51104
|
const cliBin = provider.cli ? findBinary2(provider.cli) : null;
|
|
49924
51105
|
let resolvedBin = cliBin;
|
|
49925
51106
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
49926
|
-
const bundled =
|
|
51107
|
+
const bundled = path21.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
49927
51108
|
if (provider.cli && fs11.existsSync(bundled)) resolvedBin = bundled;
|
|
49928
51109
|
}
|
|
49929
51110
|
info.installed = !!(appPath || resolvedBin);
|
|
@@ -49962,7 +51143,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
49962
51143
|
}
|
|
49963
51144
|
var http2 = __toESM2(require("http"));
|
|
49964
51145
|
var fs15 = __toESM2(require("fs"));
|
|
49965
|
-
var
|
|
51146
|
+
var path25 = __toESM2(require("path"));
|
|
49966
51147
|
init_config();
|
|
49967
51148
|
function generateFiles(type, name, category, opts = {}) {
|
|
49968
51149
|
const { cdpPorts, cli, processName, installPath, binary, extensionId, version: version2 = "0.1" } = opts;
|
|
@@ -50307,7 +51488,7 @@ async (params) => {
|
|
|
50307
51488
|
}
|
|
50308
51489
|
init_logger();
|
|
50309
51490
|
var fs12 = __toESM2(require("fs"));
|
|
50310
|
-
var
|
|
51491
|
+
var path222 = __toESM2(require("path"));
|
|
50311
51492
|
init_logger();
|
|
50312
51493
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
50313
51494
|
const body = await ctx.readBody(req);
|
|
@@ -50486,17 +51667,17 @@ async (params) => {
|
|
|
50486
51667
|
return;
|
|
50487
51668
|
}
|
|
50488
51669
|
let scriptsPath = "";
|
|
50489
|
-
const directScripts =
|
|
51670
|
+
const directScripts = path222.join(dir, "scripts.js");
|
|
50490
51671
|
if (fs12.existsSync(directScripts)) {
|
|
50491
51672
|
scriptsPath = directScripts;
|
|
50492
51673
|
} else {
|
|
50493
|
-
const scriptsDir =
|
|
51674
|
+
const scriptsDir = path222.join(dir, "scripts");
|
|
50494
51675
|
if (fs12.existsSync(scriptsDir)) {
|
|
50495
51676
|
const versions = fs12.readdirSync(scriptsDir).filter((d) => {
|
|
50496
|
-
return fs12.statSync(
|
|
51677
|
+
return fs12.statSync(path222.join(scriptsDir, d)).isDirectory();
|
|
50497
51678
|
}).sort().reverse();
|
|
50498
51679
|
for (const ver of versions) {
|
|
50499
|
-
const p =
|
|
51680
|
+
const p = path222.join(scriptsDir, ver, "scripts.js");
|
|
50500
51681
|
if (fs12.existsSync(p)) {
|
|
50501
51682
|
scriptsPath = p;
|
|
50502
51683
|
break;
|
|
@@ -51323,7 +52504,7 @@ async (params) => {
|
|
|
51323
52504
|
}
|
|
51324
52505
|
}
|
|
51325
52506
|
var fs13 = __toESM2(require("fs"));
|
|
51326
|
-
var
|
|
52507
|
+
var path232 = __toESM2(require("path"));
|
|
51327
52508
|
function slugifyFixtureName(value) {
|
|
51328
52509
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
51329
52510
|
return normalized || `fixture-${Date.now()}`;
|
|
@@ -51333,11 +52514,11 @@ async (params) => {
|
|
|
51333
52514
|
if (!providerDir) {
|
|
51334
52515
|
throw new Error(`Provider directory not found for '${type}'`);
|
|
51335
52516
|
}
|
|
51336
|
-
return
|
|
52517
|
+
return path232.join(providerDir, "fixtures");
|
|
51337
52518
|
}
|
|
51338
52519
|
function readCliFixture(ctx, type, name) {
|
|
51339
52520
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
51340
|
-
const filePath =
|
|
52521
|
+
const filePath = path232.join(fixtureDir, `${name}.json`);
|
|
51341
52522
|
if (!fs13.existsSync(filePath)) {
|
|
51342
52523
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
51343
52524
|
}
|
|
@@ -51506,7 +52687,7 @@ async (params) => {
|
|
|
51506
52687
|
return { target, instance, adapter };
|
|
51507
52688
|
}
|
|
51508
52689
|
function sleep(ms2) {
|
|
51509
|
-
return new Promise((
|
|
52690
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms2));
|
|
51510
52691
|
}
|
|
51511
52692
|
async function waitForCliReady(ctx, type, instanceId, timeoutMs) {
|
|
51512
52693
|
const startedAt = Date.now();
|
|
@@ -51804,7 +52985,7 @@ async (params) => {
|
|
|
51804
52985
|
return {
|
|
51805
52986
|
mode: "fixture_replay_suite",
|
|
51806
52987
|
pass: results.every((item) => item.pass),
|
|
51807
|
-
failures: results.flatMap((item) => item.failures.map((
|
|
52988
|
+
failures: results.flatMap((item) => item.failures.map((failure2) => `${item.fixtureName}: ${failure2}`)),
|
|
51808
52989
|
result: firstFailure.result,
|
|
51809
52990
|
assertions: firstFailure.assertions,
|
|
51810
52991
|
fixture: firstFailure.fixture,
|
|
@@ -52104,7 +53285,7 @@ async (params) => {
|
|
|
52104
53285
|
},
|
|
52105
53286
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
52106
53287
|
};
|
|
52107
|
-
const filePath =
|
|
53288
|
+
const filePath = path232.join(fixtureDir, `${name}.json`);
|
|
52108
53289
|
fs13.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
52109
53290
|
ctx.json(res, 200, {
|
|
52110
53291
|
saved: true,
|
|
@@ -52128,7 +53309,7 @@ async (params) => {
|
|
|
52128
53309
|
return;
|
|
52129
53310
|
}
|
|
52130
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) => {
|
|
52131
|
-
const fullPath =
|
|
53312
|
+
const fullPath = path232.join(fixtureDir, file2);
|
|
52132
53313
|
try {
|
|
52133
53314
|
const raw = JSON.parse(fs13.readFileSync(fullPath, "utf-8"));
|
|
52134
53315
|
return {
|
|
@@ -52262,7 +53443,7 @@ async (params) => {
|
|
|
52262
53443
|
}
|
|
52263
53444
|
}
|
|
52264
53445
|
var fs14 = __toESM2(require("fs"));
|
|
52265
|
-
var
|
|
53446
|
+
var path24 = __toESM2(require("path"));
|
|
52266
53447
|
var os20 = __toESM2(require("os"));
|
|
52267
53448
|
function getAutoImplPid(ctx) {
|
|
52268
53449
|
const pid = ctx.autoImplProcess?.pid;
|
|
@@ -52312,22 +53493,22 @@ async (params) => {
|
|
|
52312
53493
|
if (!fs14.existsSync(scriptsDir)) return null;
|
|
52313
53494
|
const versions = fs14.readdirSync(scriptsDir).filter((d) => {
|
|
52314
53495
|
try {
|
|
52315
|
-
return fs14.statSync(
|
|
53496
|
+
return fs14.statSync(path24.join(scriptsDir, d)).isDirectory();
|
|
52316
53497
|
} catch {
|
|
52317
53498
|
return false;
|
|
52318
53499
|
}
|
|
52319
53500
|
}).sort((a, b2) => b2.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
52320
53501
|
if (versions.length === 0) return null;
|
|
52321
|
-
return
|
|
53502
|
+
return path24.join(scriptsDir, versions[0]);
|
|
52322
53503
|
}
|
|
52323
53504
|
function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
|
|
52324
|
-
const canonicalUserDir =
|
|
52325
|
-
const desiredDir = requestedDir ?
|
|
52326
|
-
const upstreamRoot =
|
|
52327
|
-
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}`)) {
|
|
52328
53509
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
52329
53510
|
}
|
|
52330
|
-
if (
|
|
53511
|
+
if (path24.basename(desiredDir) !== type) {
|
|
52331
53512
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
52332
53513
|
}
|
|
52333
53514
|
const sourceDir = ctx.findProviderDir(type);
|
|
@@ -52335,11 +53516,11 @@ async (params) => {
|
|
|
52335
53516
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
52336
53517
|
}
|
|
52337
53518
|
if (!fs14.existsSync(desiredDir)) {
|
|
52338
|
-
fs14.mkdirSync(
|
|
53519
|
+
fs14.mkdirSync(path24.dirname(desiredDir), { recursive: true });
|
|
52339
53520
|
fs14.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
52340
53521
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
52341
53522
|
}
|
|
52342
|
-
const providerJson =
|
|
53523
|
+
const providerJson = path24.join(desiredDir, "provider.json");
|
|
52343
53524
|
if (!fs14.existsSync(providerJson)) {
|
|
52344
53525
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
52345
53526
|
}
|
|
@@ -52350,13 +53531,13 @@ async (params) => {
|
|
|
52350
53531
|
const refDir = ctx.findProviderDir(referenceType);
|
|
52351
53532
|
if (!refDir || !fs14.existsSync(refDir)) return {};
|
|
52352
53533
|
const referenceScripts = {};
|
|
52353
|
-
const scriptsDir =
|
|
53534
|
+
const scriptsDir = path24.join(refDir, "scripts");
|
|
52354
53535
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
52355
53536
|
if (!latestDir) return referenceScripts;
|
|
52356
53537
|
for (const file2 of fs14.readdirSync(latestDir)) {
|
|
52357
53538
|
if (!file2.endsWith(".js")) continue;
|
|
52358
53539
|
try {
|
|
52359
|
-
referenceScripts[file2] = fs14.readFileSync(
|
|
53540
|
+
referenceScripts[file2] = fs14.readFileSync(path24.join(latestDir, file2), "utf-8");
|
|
52360
53541
|
} catch {
|
|
52361
53542
|
}
|
|
52362
53543
|
}
|
|
@@ -52464,9 +53645,9 @@ async (params) => {
|
|
|
52464
53645
|
});
|
|
52465
53646
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
52466
53647
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
52467
|
-
const tmpDir =
|
|
53648
|
+
const tmpDir = path24.join(os20.tmpdir(), "adhdev-autoimpl");
|
|
52468
53649
|
if (!fs14.existsSync(tmpDir)) fs14.mkdirSync(tmpDir, { recursive: true });
|
|
52469
|
-
const promptFile =
|
|
53650
|
+
const promptFile = path24.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
52470
53651
|
fs14.writeFileSync(promptFile, prompt, "utf-8");
|
|
52471
53652
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
52472
53653
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
@@ -52898,7 +54079,7 @@ async (params) => {
|
|
|
52898
54079
|
setMode: "set_mode.js"
|
|
52899
54080
|
};
|
|
52900
54081
|
const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
|
|
52901
|
-
const scriptsDir =
|
|
54082
|
+
const scriptsDir = path24.join(providerDir, "scripts");
|
|
52902
54083
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
52903
54084
|
if (latestScriptsDir) {
|
|
52904
54085
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -52909,7 +54090,7 @@ async (params) => {
|
|
|
52909
54090
|
for (const file2 of fs14.readdirSync(latestScriptsDir)) {
|
|
52910
54091
|
if (file2.endsWith(".js") && targetFileNames.has(file2)) {
|
|
52911
54092
|
try {
|
|
52912
|
-
const content = fs14.readFileSync(
|
|
54093
|
+
const content = fs14.readFileSync(path24.join(latestScriptsDir, file2), "utf-8");
|
|
52913
54094
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
52914
54095
|
lines.push("```javascript");
|
|
52915
54096
|
lines.push(content);
|
|
@@ -52926,7 +54107,7 @@ async (params) => {
|
|
|
52926
54107
|
lines.push("");
|
|
52927
54108
|
for (const file2 of refFiles) {
|
|
52928
54109
|
try {
|
|
52929
|
-
const content = fs14.readFileSync(
|
|
54110
|
+
const content = fs14.readFileSync(path24.join(latestScriptsDir, file2), "utf-8");
|
|
52930
54111
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
52931
54112
|
lines.push("```javascript");
|
|
52932
54113
|
lines.push(content);
|
|
@@ -52967,10 +54148,10 @@ async (params) => {
|
|
|
52967
54148
|
lines.push("");
|
|
52968
54149
|
}
|
|
52969
54150
|
}
|
|
52970
|
-
const docsDir =
|
|
54151
|
+
const docsDir = path24.join(providerDir, "../../docs");
|
|
52971
54152
|
const loadGuide = (name) => {
|
|
52972
54153
|
try {
|
|
52973
|
-
const p =
|
|
54154
|
+
const p = path24.join(docsDir, name);
|
|
52974
54155
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
52975
54156
|
} catch {
|
|
52976
54157
|
}
|
|
@@ -53207,7 +54388,7 @@ async (params) => {
|
|
|
53207
54388
|
parseApproval: "parse_approval.js"
|
|
53208
54389
|
};
|
|
53209
54390
|
const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
|
|
53210
|
-
const scriptsDir =
|
|
54391
|
+
const scriptsDir = path24.join(providerDir, "scripts");
|
|
53211
54392
|
const latestScriptsDir = getLatestScriptVersionDir(scriptsDir);
|
|
53212
54393
|
if (latestScriptsDir) {
|
|
53213
54394
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -53219,7 +54400,7 @@ async (params) => {
|
|
|
53219
54400
|
if (!file2.endsWith(".js")) continue;
|
|
53220
54401
|
if (!targetFileNames.has(file2)) continue;
|
|
53221
54402
|
try {
|
|
53222
|
-
const content = fs14.readFileSync(
|
|
54403
|
+
const content = fs14.readFileSync(path24.join(latestScriptsDir, file2), "utf-8");
|
|
53223
54404
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
53224
54405
|
lines.push("```javascript");
|
|
53225
54406
|
lines.push(content);
|
|
@@ -53235,7 +54416,7 @@ async (params) => {
|
|
|
53235
54416
|
lines.push("");
|
|
53236
54417
|
for (const file2 of refFiles) {
|
|
53237
54418
|
try {
|
|
53238
|
-
const content = fs14.readFileSync(
|
|
54419
|
+
const content = fs14.readFileSync(path24.join(latestScriptsDir, file2), "utf-8");
|
|
53239
54420
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
53240
54421
|
lines.push("```javascript");
|
|
53241
54422
|
lines.push(content);
|
|
@@ -53268,10 +54449,10 @@ async (params) => {
|
|
|
53268
54449
|
lines.push("");
|
|
53269
54450
|
}
|
|
53270
54451
|
}
|
|
53271
|
-
const docsDir =
|
|
54452
|
+
const docsDir = path24.join(providerDir, "../../docs");
|
|
53272
54453
|
const loadGuide = (name) => {
|
|
53273
54454
|
try {
|
|
53274
|
-
const p =
|
|
54455
|
+
const p = path24.join(docsDir, name);
|
|
53275
54456
|
if (fs14.existsSync(p)) return fs14.readFileSync(p, "utf-8");
|
|
53276
54457
|
} catch {
|
|
53277
54458
|
}
|
|
@@ -53716,8 +54897,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
53716
54897
|
}
|
|
53717
54898
|
getEndpointList() {
|
|
53718
54899
|
return this.routes.map((r) => {
|
|
53719
|
-
const
|
|
53720
|
-
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}`;
|
|
53721
54902
|
});
|
|
53722
54903
|
}
|
|
53723
54904
|
async start(port = DEV_SERVER_PORT) {
|
|
@@ -53748,15 +54929,15 @@ data: ${JSON.stringify(msg.data)}
|
|
|
53748
54929
|
this.json(res, 500, { error: e.message });
|
|
53749
54930
|
}
|
|
53750
54931
|
});
|
|
53751
|
-
return new Promise((
|
|
54932
|
+
return new Promise((resolve15, reject) => {
|
|
53752
54933
|
this.server.listen(port, "127.0.0.1", () => {
|
|
53753
54934
|
this.log(`Dev server listening on http://127.0.0.1:${port}`);
|
|
53754
|
-
|
|
54935
|
+
resolve15();
|
|
53755
54936
|
});
|
|
53756
54937
|
this.server.on("error", (e) => {
|
|
53757
54938
|
if (e.code === "EADDRINUSE") {
|
|
53758
54939
|
this.log(`Port ${port} in use, skipping dev server`);
|
|
53759
|
-
|
|
54940
|
+
resolve15();
|
|
53760
54941
|
} else {
|
|
53761
54942
|
reject(e);
|
|
53762
54943
|
}
|
|
@@ -53838,20 +55019,20 @@ data: ${JSON.stringify(msg.data)}
|
|
|
53838
55019
|
child.stderr?.on("data", (d) => {
|
|
53839
55020
|
stderr += d.toString().slice(0, 2e3);
|
|
53840
55021
|
});
|
|
53841
|
-
await new Promise((
|
|
55022
|
+
await new Promise((resolve15) => {
|
|
53842
55023
|
const timer = setTimeout(() => {
|
|
53843
55024
|
child.kill();
|
|
53844
|
-
|
|
55025
|
+
resolve15();
|
|
53845
55026
|
}, 3e3);
|
|
53846
55027
|
child.on("exit", () => {
|
|
53847
55028
|
clearTimeout(timer);
|
|
53848
|
-
|
|
55029
|
+
resolve15();
|
|
53849
55030
|
});
|
|
53850
55031
|
child.stdout?.once("data", () => {
|
|
53851
55032
|
setTimeout(() => {
|
|
53852
55033
|
child.kill();
|
|
53853
55034
|
clearTimeout(timer);
|
|
53854
|
-
|
|
55035
|
+
resolve15();
|
|
53855
55036
|
}, 500);
|
|
53856
55037
|
});
|
|
53857
55038
|
});
|
|
@@ -54005,12 +55186,12 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54005
55186
|
// ─── DevConsole SPA ───
|
|
54006
55187
|
getConsoleDistDir() {
|
|
54007
55188
|
const candidates = [
|
|
54008
|
-
|
|
54009
|
-
|
|
54010
|
-
|
|
55189
|
+
path25.resolve(__dirname, "../../web-devconsole/dist"),
|
|
55190
|
+
path25.resolve(__dirname, "../../../web-devconsole/dist"),
|
|
55191
|
+
path25.join(process.cwd(), "packages/web-devconsole/dist")
|
|
54011
55192
|
];
|
|
54012
55193
|
for (const dir of candidates) {
|
|
54013
|
-
if (fs15.existsSync(
|
|
55194
|
+
if (fs15.existsSync(path25.join(dir, "index.html"))) return dir;
|
|
54014
55195
|
}
|
|
54015
55196
|
return null;
|
|
54016
55197
|
}
|
|
@@ -54020,7 +55201,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54020
55201
|
this.json(res, 500, { error: "DevConsole not found. Run: npm run build -w packages/web-devconsole" });
|
|
54021
55202
|
return;
|
|
54022
55203
|
}
|
|
54023
|
-
const htmlPath =
|
|
55204
|
+
const htmlPath = path25.join(distDir, "index.html");
|
|
54024
55205
|
try {
|
|
54025
55206
|
const html = fs15.readFileSync(htmlPath, "utf-8");
|
|
54026
55207
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
@@ -54045,15 +55226,15 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54045
55226
|
this.json(res, 404, { error: "Not found" });
|
|
54046
55227
|
return;
|
|
54047
55228
|
}
|
|
54048
|
-
const safePath =
|
|
54049
|
-
const filePath =
|
|
55229
|
+
const safePath = path25.normalize(pathname).replace(/^\.\.\//, "");
|
|
55230
|
+
const filePath = path25.join(distDir, safePath);
|
|
54050
55231
|
if (!filePath.startsWith(distDir)) {
|
|
54051
55232
|
this.json(res, 403, { error: "Forbidden" });
|
|
54052
55233
|
return;
|
|
54053
55234
|
}
|
|
54054
55235
|
try {
|
|
54055
55236
|
const content = fs15.readFileSync(filePath);
|
|
54056
|
-
const ext =
|
|
55237
|
+
const ext = path25.extname(filePath);
|
|
54057
55238
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
54058
55239
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
54059
55240
|
res.end(content);
|
|
@@ -54166,10 +55347,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54166
55347
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
54167
55348
|
if (entry.isDirectory()) {
|
|
54168
55349
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
54169
|
-
scan(
|
|
55350
|
+
scan(path25.join(d, entry.name), rel);
|
|
54170
55351
|
} else {
|
|
54171
|
-
const
|
|
54172
|
-
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" });
|
|
54173
55354
|
}
|
|
54174
55355
|
}
|
|
54175
55356
|
} catch {
|
|
@@ -54191,7 +55372,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54191
55372
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
54192
55373
|
return;
|
|
54193
55374
|
}
|
|
54194
|
-
const fullPath =
|
|
55375
|
+
const fullPath = path25.resolve(dir, path25.normalize(filePath));
|
|
54195
55376
|
if (!fullPath.startsWith(dir)) {
|
|
54196
55377
|
this.json(res, 403, { error: "Forbidden" });
|
|
54197
55378
|
return;
|
|
@@ -54216,14 +55397,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54216
55397
|
this.json(res, 404, { error: `Provider directory not found: ${type}` });
|
|
54217
55398
|
return;
|
|
54218
55399
|
}
|
|
54219
|
-
const fullPath =
|
|
55400
|
+
const fullPath = path25.resolve(dir, path25.normalize(filePath));
|
|
54220
55401
|
if (!fullPath.startsWith(dir)) {
|
|
54221
55402
|
this.json(res, 403, { error: "Forbidden" });
|
|
54222
55403
|
return;
|
|
54223
55404
|
}
|
|
54224
55405
|
try {
|
|
54225
55406
|
if (fs15.existsSync(fullPath)) fs15.copyFileSync(fullPath, fullPath + ".bak");
|
|
54226
|
-
fs15.mkdirSync(
|
|
55407
|
+
fs15.mkdirSync(path25.dirname(fullPath), { recursive: true });
|
|
54227
55408
|
fs15.writeFileSync(fullPath, content, "utf-8");
|
|
54228
55409
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
54229
55410
|
this.providerLoader.reload();
|
|
@@ -54240,7 +55421,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54240
55421
|
return;
|
|
54241
55422
|
}
|
|
54242
55423
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
54243
|
-
const p =
|
|
55424
|
+
const p = path25.join(dir, name);
|
|
54244
55425
|
if (fs15.existsSync(p)) {
|
|
54245
55426
|
const source = fs15.readFileSync(p, "utf-8");
|
|
54246
55427
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
@@ -54261,8 +55442,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54261
55442
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
54262
55443
|
return;
|
|
54263
55444
|
}
|
|
54264
|
-
const target = fs15.existsSync(
|
|
54265
|
-
const targetPath =
|
|
55445
|
+
const target = fs15.existsSync(path25.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
55446
|
+
const targetPath = path25.join(dir, target);
|
|
54266
55447
|
try {
|
|
54267
55448
|
if (fs15.existsSync(targetPath)) fs15.copyFileSync(targetPath, targetPath + ".bak");
|
|
54268
55449
|
fs15.writeFileSync(targetPath, source, "utf-8");
|
|
@@ -54354,14 +55535,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54354
55535
|
child.stderr?.on("data", (d) => {
|
|
54355
55536
|
stderr += d.toString();
|
|
54356
55537
|
});
|
|
54357
|
-
await new Promise((
|
|
55538
|
+
await new Promise((resolve15) => {
|
|
54358
55539
|
const timer = setTimeout(() => {
|
|
54359
55540
|
child.kill();
|
|
54360
|
-
|
|
55541
|
+
resolve15();
|
|
54361
55542
|
}, timeout);
|
|
54362
55543
|
child.on("exit", () => {
|
|
54363
55544
|
clearTimeout(timer);
|
|
54364
|
-
|
|
55545
|
+
resolve15();
|
|
54365
55546
|
});
|
|
54366
55547
|
});
|
|
54367
55548
|
const elapsed = Date.now() - start;
|
|
@@ -54409,7 +55590,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54409
55590
|
}
|
|
54410
55591
|
let targetDir;
|
|
54411
55592
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
54412
|
-
const jsonPath =
|
|
55593
|
+
const jsonPath = path25.join(targetDir, "provider.json");
|
|
54413
55594
|
if (fs15.existsSync(jsonPath)) {
|
|
54414
55595
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
54415
55596
|
return;
|
|
@@ -54421,8 +55602,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54421
55602
|
const createdFiles = ["provider.json"];
|
|
54422
55603
|
if (result.files) {
|
|
54423
55604
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
54424
|
-
const fullPath =
|
|
54425
|
-
fs15.mkdirSync(
|
|
55605
|
+
const fullPath = path25.join(targetDir, relPath);
|
|
55606
|
+
fs15.mkdirSync(path25.dirname(fullPath), { recursive: true });
|
|
54426
55607
|
fs15.writeFileSync(fullPath, content, "utf-8");
|
|
54427
55608
|
createdFiles.push(relPath);
|
|
54428
55609
|
}
|
|
@@ -54475,22 +55656,22 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54475
55656
|
if (!fs15.existsSync(scriptsDir)) return null;
|
|
54476
55657
|
const versions = fs15.readdirSync(scriptsDir).filter((d) => {
|
|
54477
55658
|
try {
|
|
54478
|
-
return fs15.statSync(
|
|
55659
|
+
return fs15.statSync(path25.join(scriptsDir, d)).isDirectory();
|
|
54479
55660
|
} catch {
|
|
54480
55661
|
return false;
|
|
54481
55662
|
}
|
|
54482
55663
|
}).sort((a, b2) => b2.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
|
|
54483
55664
|
if (versions.length === 0) return null;
|
|
54484
|
-
return
|
|
55665
|
+
return path25.join(scriptsDir, versions[0]);
|
|
54485
55666
|
}
|
|
54486
55667
|
resolveAutoImplWritableProviderDir(category, type, requestedDir) {
|
|
54487
|
-
const canonicalUserDir =
|
|
54488
|
-
const desiredDir = requestedDir ?
|
|
54489
|
-
const upstreamRoot =
|
|
54490
|
-
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}`)) {
|
|
54491
55672
|
return { dir: null, reason: `Refusing to write into upstream provider directory: ${desiredDir}` };
|
|
54492
55673
|
}
|
|
54493
|
-
if (
|
|
55674
|
+
if (path25.basename(desiredDir) !== type) {
|
|
54494
55675
|
return { dir: null, reason: `Requested writable provider directory must end with '${type}': ${desiredDir}` };
|
|
54495
55676
|
}
|
|
54496
55677
|
const sourceDir = this.findProviderDir(type);
|
|
@@ -54498,11 +55679,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54498
55679
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
54499
55680
|
}
|
|
54500
55681
|
if (!fs15.existsSync(desiredDir)) {
|
|
54501
|
-
fs15.mkdirSync(
|
|
55682
|
+
fs15.mkdirSync(path25.dirname(desiredDir), { recursive: true });
|
|
54502
55683
|
fs15.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
54503
55684
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
54504
55685
|
}
|
|
54505
|
-
const providerJson =
|
|
55686
|
+
const providerJson = path25.join(desiredDir, "provider.json");
|
|
54506
55687
|
if (!fs15.existsSync(providerJson)) {
|
|
54507
55688
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
54508
55689
|
}
|
|
@@ -54538,7 +55719,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54538
55719
|
setMode: "set_mode.js"
|
|
54539
55720
|
};
|
|
54540
55721
|
const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
|
|
54541
|
-
const scriptsDir =
|
|
55722
|
+
const scriptsDir = path25.join(providerDir, "scripts");
|
|
54542
55723
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
54543
55724
|
if (latestScriptsDir) {
|
|
54544
55725
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -54549,7 +55730,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54549
55730
|
for (const file2 of fs15.readdirSync(latestScriptsDir)) {
|
|
54550
55731
|
if (file2.endsWith(".js") && targetFileNames.has(file2)) {
|
|
54551
55732
|
try {
|
|
54552
|
-
const content = fs15.readFileSync(
|
|
55733
|
+
const content = fs15.readFileSync(path25.join(latestScriptsDir, file2), "utf-8");
|
|
54553
55734
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
54554
55735
|
lines.push("```javascript");
|
|
54555
55736
|
lines.push(content);
|
|
@@ -54566,7 +55747,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54566
55747
|
lines.push("");
|
|
54567
55748
|
for (const file2 of refFiles) {
|
|
54568
55749
|
try {
|
|
54569
|
-
const content = fs15.readFileSync(
|
|
55750
|
+
const content = fs15.readFileSync(path25.join(latestScriptsDir, file2), "utf-8");
|
|
54570
55751
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
54571
55752
|
lines.push("```javascript");
|
|
54572
55753
|
lines.push(content);
|
|
@@ -54607,10 +55788,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54607
55788
|
lines.push("");
|
|
54608
55789
|
}
|
|
54609
55790
|
}
|
|
54610
|
-
const docsDir =
|
|
55791
|
+
const docsDir = path25.join(providerDir, "../../docs");
|
|
54611
55792
|
const loadGuide = (name) => {
|
|
54612
55793
|
try {
|
|
54613
|
-
const p =
|
|
55794
|
+
const p = path25.join(docsDir, name);
|
|
54614
55795
|
if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
|
|
54615
55796
|
} catch {
|
|
54616
55797
|
}
|
|
@@ -54784,7 +55965,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54784
55965
|
parseApproval: "parse_approval.js"
|
|
54785
55966
|
};
|
|
54786
55967
|
const targetFileNames = new Set(functions.map((fn2) => funcToFile[fn2]).filter(Boolean));
|
|
54787
|
-
const scriptsDir =
|
|
55968
|
+
const scriptsDir = path25.join(providerDir, "scripts");
|
|
54788
55969
|
const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
|
|
54789
55970
|
if (latestScriptsDir) {
|
|
54790
55971
|
lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
|
|
@@ -54796,7 +55977,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54796
55977
|
if (!file2.endsWith(".js")) continue;
|
|
54797
55978
|
if (!targetFileNames.has(file2)) continue;
|
|
54798
55979
|
try {
|
|
54799
|
-
const content = fs15.readFileSync(
|
|
55980
|
+
const content = fs15.readFileSync(path25.join(latestScriptsDir, file2), "utf-8");
|
|
54800
55981
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
54801
55982
|
lines.push("```javascript");
|
|
54802
55983
|
lines.push(content);
|
|
@@ -54812,7 +55993,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54812
55993
|
lines.push("");
|
|
54813
55994
|
for (const file2 of refFiles) {
|
|
54814
55995
|
try {
|
|
54815
|
-
const content = fs15.readFileSync(
|
|
55996
|
+
const content = fs15.readFileSync(path25.join(latestScriptsDir, file2), "utf-8");
|
|
54816
55997
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
54817
55998
|
lines.push("```javascript");
|
|
54818
55999
|
lines.push(content);
|
|
@@ -54845,10 +56026,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
54845
56026
|
lines.push("");
|
|
54846
56027
|
}
|
|
54847
56028
|
}
|
|
54848
|
-
const docsDir =
|
|
56029
|
+
const docsDir = path25.join(providerDir, "../../docs");
|
|
54849
56030
|
const loadGuide = (name) => {
|
|
54850
56031
|
try {
|
|
54851
|
-
const p =
|
|
56032
|
+
const p = path25.join(docsDir, name);
|
|
54852
56033
|
if (fs15.existsSync(p)) return fs15.readFileSync(p, "utf-8");
|
|
54853
56034
|
} catch {
|
|
54854
56035
|
}
|
|
@@ -55031,14 +56212,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
55031
56212
|
res.end(JSON.stringify(data, null, 2));
|
|
55032
56213
|
}
|
|
55033
56214
|
async readBody(req) {
|
|
55034
|
-
return new Promise((
|
|
56215
|
+
return new Promise((resolve15) => {
|
|
55035
56216
|
let body = "";
|
|
55036
56217
|
req.on("data", (chunk) => body += chunk);
|
|
55037
56218
|
req.on("end", () => {
|
|
55038
56219
|
try {
|
|
55039
|
-
|
|
56220
|
+
resolve15(JSON.parse(body));
|
|
55040
56221
|
} catch {
|
|
55041
|
-
|
|
56222
|
+
resolve15({});
|
|
55042
56223
|
}
|
|
55043
56224
|
});
|
|
55044
56225
|
});
|
|
@@ -55540,7 +56721,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
55540
56721
|
const deadline = Date.now() + timeoutMs;
|
|
55541
56722
|
while (Date.now() < deadline) {
|
|
55542
56723
|
if (await canConnect(endpoint)) return;
|
|
55543
|
-
await new Promise((
|
|
56724
|
+
await new Promise((resolve15) => setTimeout(resolve15, STARTUP_POLL_MS));
|
|
55544
56725
|
}
|
|
55545
56726
|
throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
|
|
55546
56727
|
}
|
|
@@ -55714,10 +56895,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
55714
56895
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
55715
56896
|
const fs16 = await import("fs");
|
|
55716
56897
|
fs16.writeFileSync(vsixPath, buffer);
|
|
55717
|
-
return new Promise((
|
|
56898
|
+
return new Promise((resolve15) => {
|
|
55718
56899
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
55719
56900
|
(0, import_child_process11.exec)(cmd, { timeout: 6e4 }, (error48, _stdout, stderr) => {
|
|
55720
|
-
|
|
56901
|
+
resolve15({
|
|
55721
56902
|
extensionId: extension.id,
|
|
55722
56903
|
marketplaceId: extension.marketplaceId,
|
|
55723
56904
|
success: !error48,
|
|
@@ -55730,11 +56911,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
55730
56911
|
} catch (e) {
|
|
55731
56912
|
}
|
|
55732
56913
|
}
|
|
55733
|
-
return new Promise((
|
|
56914
|
+
return new Promise((resolve15) => {
|
|
55734
56915
|
const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
|
|
55735
56916
|
(0, import_child_process11.exec)(cmd, { timeout: 6e4 }, (error48, stdout, stderr) => {
|
|
55736
56917
|
if (error48) {
|
|
55737
|
-
|
|
56918
|
+
resolve15({
|
|
55738
56919
|
extensionId: extension.id,
|
|
55739
56920
|
marketplaceId: extension.marketplaceId,
|
|
55740
56921
|
success: false,
|
|
@@ -55742,7 +56923,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
55742
56923
|
error: stderr || error48.message
|
|
55743
56924
|
});
|
|
55744
56925
|
} else {
|
|
55745
|
-
|
|
56926
|
+
resolve15({
|
|
55746
56927
|
extensionId: extension.id,
|
|
55747
56928
|
marketplaceId: extension.marketplaceId,
|
|
55748
56929
|
success: true,
|
|
@@ -56852,6 +58033,8 @@ var StandaloneServer = class {
|
|
|
56852
58033
|
wsSessionHostDiagnosticsSubscriptions = /* @__PURE__ */ new Map();
|
|
56853
58034
|
wsSessionModalSubscriptions = /* @__PURE__ */ new Map();
|
|
56854
58035
|
wsDaemonMetadataSubscriptions = /* @__PURE__ */ new Map();
|
|
58036
|
+
wsGitSubscriptions = /* @__PURE__ */ new Map();
|
|
58037
|
+
gitWorkspaceMonitor = (0, import_daemon_core2.createGitWorkspaceMonitor)();
|
|
56855
58038
|
authToken = null;
|
|
56856
58039
|
passwordConfigPath = getStandalonePasswordConfigPath();
|
|
56857
58040
|
passwordConfig = null;
|
|
@@ -57117,6 +58300,7 @@ var StandaloneServer = class {
|
|
|
57117
58300
|
void this.flushWsMachineRuntimeSubscriptions();
|
|
57118
58301
|
void this.flushWsSessionHostDiagnosticsSubscriptions();
|
|
57119
58302
|
void this.flushWsSessionModalSubscriptions();
|
|
58303
|
+
if (this.hasWsGitSubscriptions()) void this.flushWsGitSubscriptions();
|
|
57120
58304
|
}, STATUS_INTERVAL);
|
|
57121
58305
|
this.running = true;
|
|
57122
58306
|
await new Promise((resolve4) => {
|
|
@@ -57605,6 +58789,7 @@ var StandaloneServer = class {
|
|
|
57605
58789
|
this.wsSessionHostDiagnosticsSubscriptions.set(ws2, /* @__PURE__ */ new Map());
|
|
57606
58790
|
this.wsSessionModalSubscriptions.set(ws2, /* @__PURE__ */ new Map());
|
|
57607
58791
|
this.wsDaemonMetadataSubscriptions.set(ws2, /* @__PURE__ */ new Map());
|
|
58792
|
+
this.wsGitSubscriptions.set(ws2, /* @__PURE__ */ new Map());
|
|
57608
58793
|
console.log(`[WS] Client connected (total: ${this.clients.size})`);
|
|
57609
58794
|
const status = this.getWsStatus(this.buildSharedSnapshot("live"));
|
|
57610
58795
|
this.lastWsStatusSignature = this.buildWsStatusSignature(status);
|
|
@@ -57648,6 +58833,7 @@ var StandaloneServer = class {
|
|
|
57648
58833
|
this.wsSessionHostDiagnosticsSubscriptions.delete(ws2);
|
|
57649
58834
|
this.wsSessionModalSubscriptions.delete(ws2);
|
|
57650
58835
|
this.wsDaemonMetadataSubscriptions.delete(ws2);
|
|
58836
|
+
this.clearWsGitSubscriptions(ws2);
|
|
57651
58837
|
console.log(`[WS] Client disconnected (total: ${this.clients.size})`);
|
|
57652
58838
|
});
|
|
57653
58839
|
ws2.on("error", () => {
|
|
@@ -57657,8 +58843,19 @@ var StandaloneServer = class {
|
|
|
57657
58843
|
this.wsSessionHostDiagnosticsSubscriptions.delete(ws2);
|
|
57658
58844
|
this.wsSessionModalSubscriptions.delete(ws2);
|
|
57659
58845
|
this.wsDaemonMetadataSubscriptions.delete(ws2);
|
|
58846
|
+
this.clearWsGitSubscriptions(ws2);
|
|
57660
58847
|
});
|
|
57661
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
|
+
}
|
|
57662
58859
|
async handleWsSubscribe(ws2, msg) {
|
|
57663
58860
|
if (msg.topic === "session.chat_tail") {
|
|
57664
58861
|
const params = msg.params;
|
|
@@ -57746,6 +58943,25 @@ var StandaloneServer = class {
|
|
|
57746
58943
|
lastSentAt: 0
|
|
57747
58944
|
});
|
|
57748
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);
|
|
57749
58965
|
}
|
|
57750
58966
|
}
|
|
57751
58967
|
handleWsUnsubscribe(ws2, msg) {
|
|
@@ -57767,6 +58983,12 @@ var StandaloneServer = class {
|
|
|
57767
58983
|
}
|
|
57768
58984
|
if (msg.topic === "daemon.metadata") {
|
|
57769
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);
|
|
57770
58992
|
}
|
|
57771
58993
|
}
|
|
57772
58994
|
async buildChatTailUpdate(request, state, key) {
|
|
@@ -57990,6 +59212,45 @@ var StandaloneServer = class {
|
|
|
57990
59212
|
}
|
|
57991
59213
|
}
|
|
57992
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
|
+
}
|
|
57993
59254
|
// ─── Core Logic ───
|
|
57994
59255
|
buildSharedSnapshot(profile = "full") {
|
|
57995
59256
|
const cfgSnap = (0, import_daemon_core2.loadConfig)();
|
|
@@ -58114,6 +59375,7 @@ var StandaloneServer = class {
|
|
|
58114
59375
|
}
|
|
58115
59376
|
if (type.startsWith("session_host_")) void this.flushWsSessionHostDiagnosticsSubscriptions();
|
|
58116
59377
|
if (type === "resolve_action" || type === "send_chat" || type === "read_chat") void this.flushWsSessionModalSubscriptions();
|
|
59378
|
+
if (type.startsWith("git_") && this.hasWsGitSubscriptions()) void this.flushWsGitSubscriptions();
|
|
58117
59379
|
return result;
|
|
58118
59380
|
}
|
|
58119
59381
|
scheduleBroadcastStatus() {
|