@sideboard-ai/core 0.1.197 → 0.1.199
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/{abletime-JINF5KJV.js → abletime-3CSCNAXU.js} +2 -2
- package/dist/{abletime-HR6P4GJH.js → abletime-H74RNIKV.js} +2 -2
- package/dist/agents/cursor-runner.cjs +49 -45
- package/dist/agents/cursor-runner.js +5 -3
- package/dist/{agents-IVDCAG7T.js → agents-AVH44CBS.js} +27 -5
- package/dist/{agents-BGT5DUGU.js → agents-BOYOK56K.js} +26 -4
- package/dist/{app-settings-J775CYOO.js → app-settings-FMTDH5RD.js} +3 -1
- package/dist/{app-settings-5KHVKJKO.js → app-settings-MMPLJHWF.js} +3 -1
- package/dist/{chunk-S5GLSRLP.js → chunk-2IQ6W47G.js} +10 -0
- package/dist/{chunk-HZTHWU6A.js → chunk-BLOKJY4U.js} +2 -2
- package/dist/{chunk-E37JHCO3.js → chunk-CA7PWMQ7.js} +1 -1
- package/dist/{chunk-NLHFAMC2.js → chunk-CQ5R3VPP.js} +15 -1
- package/dist/{chunk-ZG7RONNQ.js → chunk-CTABTALL.js} +22 -21
- package/dist/{chunk-PQBRCBIE.js → chunk-DU2ICKLA.js} +382 -6
- package/dist/{chunk-S4QCBBXS.js → chunk-DU4ID3DA.js} +1 -1
- package/dist/{chunk-AH6WIBLY.js → chunk-HQKGK4KO.js} +10 -0
- package/dist/{chunk-N5JBG3BF.js → chunk-KI4YI72Y.js} +371 -6
- package/dist/{chunk-SIIDQV2B.js → chunk-PPVN3APP.js} +24 -23
- package/dist/{chunk-KTHRWHA3.js → chunk-PTAMHXBT.js} +1 -1
- package/dist/{chunk-DP4TKAMZ.js → chunk-QFABSE3Q.js} +1 -1
- package/dist/{chunk-6YTI2HBG.js → chunk-S4EEYOSU.js} +2 -2
- package/dist/{coordinator-prompt-IX66YUJ2.js → coordinator-prompt-LB3GA3U4.js} +3 -3
- package/dist/{coordinator-prompt-LYKS3YNG.js → coordinator-prompt-ROWPLVQ3.js} +3 -3
- package/dist/{global-workspace-SNJ2Z6SL.js → global-workspace-C5XKWCRH.js} +3 -3
- package/dist/{global-workspace-4QX6UEOY.js → global-workspace-V2A4YKZ6.js} +3 -3
- package/dist/index.cjs +688 -262
- package/dist/index.d.cts +78 -1
- package/dist/index.d.ts +78 -1
- package/dist/index.js +33 -9
- package/dist/mcp/run-stdio.cjs +317 -258
- package/dist/mcp/run-stdio.js +8 -8
- package/dist/{orchestrator-SANGGLQV.js → orchestrator-AJGDZEAS.js} +5 -5
- package/dist/{orchestrator-HB4LZ2AA.js → orchestrator-NCGYNVYN.js} +6 -6
- package/dist/{workspaces-URMUVGAQ.js → workspaces-GWEKIS3B.js} +3 -3
- package/dist/{workspaces-UTOYGBYB.js → workspaces-WIRJQ6HA.js} +3 -3
- package/dist/{worktree-RM6UWNGZ.js → worktree-QA4J75FI.js} +2 -2
- package/dist/{worktree-R43JOR4V.js → worktree-UI5WJC3A.js} +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1032,6 +1032,7 @@ __export(app_settings_exports, {
|
|
|
1032
1032
|
childEnvWithAppSettings: () => childEnvWithAppSettings,
|
|
1033
1033
|
claudeChromeEnabled: () => claudeChromeEnabled,
|
|
1034
1034
|
claudeUserSettingsPath: () => claudeUserSettingsPath,
|
|
1035
|
+
confirmClaudeUsageOverLimitEnabled: () => confirmClaudeUsageOverLimitEnabled,
|
|
1035
1036
|
cowboyModeEnabled: () => cowboyModeEnabled,
|
|
1036
1037
|
deleteBranchOnPurgeEnabled: () => deleteBranchOnPurgeEnabled,
|
|
1037
1038
|
disconnectAbleTimeConnection: () => disconnectAbleTimeConnection,
|
|
@@ -1459,6 +1460,9 @@ function normalizeAdvanced(raw) {
|
|
|
1459
1460
|
if (typeof source.showCost === "boolean") {
|
|
1460
1461
|
out.showCost = source.showCost;
|
|
1461
1462
|
}
|
|
1463
|
+
if (typeof source.confirmClaudeUsageOverLimit === "boolean") {
|
|
1464
|
+
out.confirmClaudeUsageOverLimit = source.confirmClaudeUsageOverLimit;
|
|
1465
|
+
}
|
|
1462
1466
|
if (typeof source.autoArchiveOnMerge === "boolean") {
|
|
1463
1467
|
out.autoArchiveOnMerge = source.autoArchiveOnMerge;
|
|
1464
1468
|
}
|
|
@@ -2321,6 +2325,9 @@ function updateAdvancedSettings(patch) {
|
|
|
2321
2325
|
if (typeof patch.showCost === "boolean") {
|
|
2322
2326
|
advanced.showCost = patch.showCost;
|
|
2323
2327
|
}
|
|
2328
|
+
if (typeof patch.confirmClaudeUsageOverLimit === "boolean") {
|
|
2329
|
+
advanced.confirmClaudeUsageOverLimit = patch.confirmClaudeUsageOverLimit;
|
|
2330
|
+
}
|
|
2324
2331
|
if (typeof patch.autoArchiveOnMerge === "boolean") {
|
|
2325
2332
|
advanced.autoArchiveOnMerge = patch.autoArchiveOnMerge;
|
|
2326
2333
|
}
|
|
@@ -2383,6 +2390,9 @@ function cowboyModeEnabled(settings = loadAppSettings()) {
|
|
|
2383
2390
|
function showCostEnabled(settings = loadAppSettings()) {
|
|
2384
2391
|
return Boolean(settings.advanced.showCost);
|
|
2385
2392
|
}
|
|
2393
|
+
function confirmClaudeUsageOverLimitEnabled(settings = loadAppSettings()) {
|
|
2394
|
+
return Boolean(settings.advanced.confirmClaudeUsageOverLimit);
|
|
2395
|
+
}
|
|
2386
2396
|
function autoArchiveOnMergeEnabled(settings = loadAppSettings()) {
|
|
2387
2397
|
return Boolean(settings.advanced.autoArchiveOnMerge);
|
|
2388
2398
|
}
|
|
@@ -2845,14 +2855,14 @@ function fileMtimeMs(path2) {
|
|
|
2845
2855
|
}
|
|
2846
2856
|
}
|
|
2847
2857
|
function rememberThread(thread, mtimeMs) {
|
|
2848
|
-
const
|
|
2849
|
-
|
|
2850
|
-
if (mtimeMs != null)
|
|
2858
|
+
const cache2 = cacheForDir();
|
|
2859
|
+
cache2.byId.set(thread.id, thread);
|
|
2860
|
+
if (mtimeMs != null) cache2.mtimeMs.set(thread.id, mtimeMs);
|
|
2851
2861
|
}
|
|
2852
2862
|
function forgetThread(id) {
|
|
2853
|
-
const
|
|
2854
|
-
|
|
2855
|
-
|
|
2863
|
+
const cache2 = cacheForDir();
|
|
2864
|
+
cache2.byId.delete(id);
|
|
2865
|
+
cache2.mtimeMs.delete(id);
|
|
2856
2866
|
}
|
|
2857
2867
|
function invalidateThreadListCache() {
|
|
2858
2868
|
listCache = null;
|
|
@@ -2864,9 +2874,9 @@ function readThread(id) {
|
|
|
2864
2874
|
forgetThread(id);
|
|
2865
2875
|
return null;
|
|
2866
2876
|
}
|
|
2867
|
-
const
|
|
2868
|
-
const cached =
|
|
2869
|
-
if (cached &&
|
|
2877
|
+
const cache2 = cacheForDir();
|
|
2878
|
+
const cached = cache2.byId.get(id);
|
|
2879
|
+
if (cached && cache2.mtimeMs.get(id) === mtimeMs) return cached;
|
|
2870
2880
|
const raw = (0, import_node_fs9.readFileSync)(path2, "utf8");
|
|
2871
2881
|
const thread = normalizeThread(JSON.parse(raw));
|
|
2872
2882
|
rememberThread(thread, mtimeMs);
|
|
@@ -2888,7 +2898,7 @@ function isThreadRecordFile(nameOrPath) {
|
|
|
2888
2898
|
return name.endsWith(".json") && !name.endsWith(".live.json");
|
|
2889
2899
|
}
|
|
2890
2900
|
function listThreads(opts) {
|
|
2891
|
-
const
|
|
2901
|
+
const cache2 = cacheForDir();
|
|
2892
2902
|
const files = (0, import_node_fs9.readdirSync)(threadsDir()).filter(isThreadRecordFile);
|
|
2893
2903
|
const seen = /* @__PURE__ */ new Set();
|
|
2894
2904
|
for (const f of files) {
|
|
@@ -2900,10 +2910,10 @@ function listThreads(opts) {
|
|
|
2900
2910
|
} catch {
|
|
2901
2911
|
}
|
|
2902
2912
|
}
|
|
2903
|
-
for (const id of [...
|
|
2913
|
+
for (const id of [...cache2.byId.keys()]) {
|
|
2904
2914
|
if (!seen.has(id)) forgetThread(id);
|
|
2905
2915
|
}
|
|
2906
|
-
const threads = [...
|
|
2916
|
+
const threads = [...cache2.byId.values()].sort(
|
|
2907
2917
|
(a, b) => b.updatedAt.localeCompare(a.updatedAt)
|
|
2908
2918
|
);
|
|
2909
2919
|
if (opts?.includeArchived) return threads;
|
|
@@ -8864,11 +8874,20 @@ function looksLikeInvalidAgentSession(text7) {
|
|
|
8864
8874
|
if (!lower) return false;
|
|
8865
8875
|
return /session not found/.test(lower) || /no conversation found/.test(lower) || /conversation .+ not found/.test(lower) || /thread .+ not found/.test(lower) || /unknown session/.test(lower) || /invalid session/.test(lower) || /session .+ (missing|expired|deleted|gone)/.test(lower) || /cannot resume/.test(lower) || /failed to (load|resume|open) session/.test(lower) || /corrupt local agent checkpoint/.test(lower) || /missing root blob/.test(lower) || /\bagent\b.{0,120}\bnot found\b/.test(lower) || /\brun\b.{0,80}\bnot found for agent\b/.test(lower);
|
|
8866
8876
|
}
|
|
8877
|
+
function looksLikeCursorHttp2StreamClose(text7) {
|
|
8878
|
+
return /nghttp2/i.test(text7.trim());
|
|
8879
|
+
}
|
|
8880
|
+
function looksLikeBrightsyEmptyCompletion(text7) {
|
|
8881
|
+
const core = text7.trim().replace(/^exit\s*\d+:\s*/i, "").replace(/^error:\s*/i, "").trim();
|
|
8882
|
+
return /^i did not receive a valid model response\. please try again\.$/i.test(core);
|
|
8883
|
+
}
|
|
8867
8884
|
function looksLikeRetryableRunnerCrash(text7) {
|
|
8868
8885
|
if (looksLikeAgentFailureMessage(text7)) return false;
|
|
8869
8886
|
if (looksLikeInvalidAgentSession(text7)) return false;
|
|
8870
8887
|
if (looksLikeV8Oom(text7)) return false;
|
|
8871
8888
|
if (looksLikeHugeToolResultDump(text7)) return true;
|
|
8889
|
+
if (looksLikeCursorHttp2StreamClose(text7)) return true;
|
|
8890
|
+
if (looksLikeBrightsyEmptyCompletion(text7)) return true;
|
|
8872
8891
|
const lower = text7.trim().toLowerCase();
|
|
8873
8892
|
if (/cannot find (?:package|module)|err_module_not_found/.test(lower)) return false;
|
|
8874
8893
|
if (!lower) return true;
|
|
@@ -8941,9 +8960,12 @@ function humanizeAgentFailDetail(detail) {
|
|
|
8941
8960
|
if (/corrupt local agent checkpoint|missing root blob|truncated crash dump/.test(lower)) {
|
|
8942
8961
|
return `${raw} \u2014 retry the turn (Sideboard will start a fresh Cursor session).`;
|
|
8943
8962
|
}
|
|
8944
|
-
if (/connection stalled/.test(lower)) {
|
|
8963
|
+
if (/connection stalled/.test(lower) || looksLikeCursorHttp2StreamClose(raw)) {
|
|
8945
8964
|
return /retry the turn/i.test(raw) ? raw : `${raw} \u2014 retry the turn (Sideboard will start a fresh Cursor session).`;
|
|
8946
8965
|
}
|
|
8966
|
+
if (looksLikeBrightsyEmptyCompletion(raw)) {
|
|
8967
|
+
return /retry the turn/i.test(raw) ? raw : `${raw} \u2014 retry the turn (Brightsy returned an empty model completion).`;
|
|
8968
|
+
}
|
|
8947
8969
|
if (/network request failed|cursor startup failed:.+\(retryable\)/.test(lower)) {
|
|
8948
8970
|
return /retry the turn/i.test(raw) ? raw : `${raw} \u2014 retry the turn (a transient Cursor SDK network error).`;
|
|
8949
8971
|
}
|
|
@@ -9685,6 +9707,12 @@ function parseBrightsyCliLine(line) {
|
|
|
9685
9707
|
try {
|
|
9686
9708
|
const obj = JSON.parse(trimmed);
|
|
9687
9709
|
if (obj.type === "text" && typeof obj.text === "string") {
|
|
9710
|
+
if (looksLikeBrightsyEmptyCompletion(obj.text)) {
|
|
9711
|
+
return [
|
|
9712
|
+
{ type: "stderr", data: obj.text },
|
|
9713
|
+
{ type: "stdout", data: `Error: ${obj.text}` }
|
|
9714
|
+
];
|
|
9715
|
+
}
|
|
9688
9716
|
return { type: "stdout", data: obj.text };
|
|
9689
9717
|
}
|
|
9690
9718
|
if (obj.type === "thinking" && typeof obj.text === "string") {
|
|
@@ -9728,7 +9756,7 @@ function parseBrightsyCliLine(line) {
|
|
|
9728
9756
|
if (trimmed.startsWith("{") && /"type"\s*:\s*"(tool_use|tool_result|tool|text|thinking|usage|done|error)"/.test(trimmed)) {
|
|
9729
9757
|
return null;
|
|
9730
9758
|
}
|
|
9731
|
-
if (/error|failed|unauthorized|quota|limit|not logged in/i.test(trimmed)) {
|
|
9759
|
+
if (looksLikeBrightsyEmptyCompletion(trimmed) || /error|failed|unauthorized|quota|limit|not logged in/i.test(trimmed)) {
|
|
9732
9760
|
return [
|
|
9733
9761
|
{ type: "stderr", data: trimmed },
|
|
9734
9762
|
{ type: "stdout", data: `Error: ${trimmed}` }
|
|
@@ -9737,6 +9765,12 @@ function parseBrightsyCliLine(line) {
|
|
|
9737
9765
|
return { type: "stdout", data: line };
|
|
9738
9766
|
}
|
|
9739
9767
|
}
|
|
9768
|
+
function adjustBrightsyTurnExit(exitCode, assistantText) {
|
|
9769
|
+
if (looksLikeBrightsyEmptyCompletion(assistantText) && (exitCode === 0 || exitCode == null)) {
|
|
9770
|
+
return 2;
|
|
9771
|
+
}
|
|
9772
|
+
return exitCode;
|
|
9773
|
+
}
|
|
9740
9774
|
async function fetchTeamChatTargets(team) {
|
|
9741
9775
|
const endpoint = (team.endpoint || "https://brightsy.ai").replace(/\/$/, "");
|
|
9742
9776
|
let agents = [
|
|
@@ -13650,6 +13684,361 @@ var init_session_quota = __esm({
|
|
|
13650
13684
|
}
|
|
13651
13685
|
});
|
|
13652
13686
|
|
|
13687
|
+
// src/agents/claude-usage.ts
|
|
13688
|
+
function parseClaudeResetsAt(value) {
|
|
13689
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
13690
|
+
const ms = value > 1e12 ? value : value * 1e3;
|
|
13691
|
+
const d = new Date(ms);
|
|
13692
|
+
return Number.isNaN(d.getTime()) ? null : d.toISOString();
|
|
13693
|
+
}
|
|
13694
|
+
if (typeof value === "string") {
|
|
13695
|
+
const trimmed = value.trim();
|
|
13696
|
+
if (!trimmed) return null;
|
|
13697
|
+
if (/^\d+(\.\d+)?$/.test(trimmed)) {
|
|
13698
|
+
return parseClaudeResetsAt(Number(trimmed));
|
|
13699
|
+
}
|
|
13700
|
+
const d = new Date(trimmed);
|
|
13701
|
+
return Number.isNaN(d.getTime()) ? null : d.toISOString();
|
|
13702
|
+
}
|
|
13703
|
+
return null;
|
|
13704
|
+
}
|
|
13705
|
+
function parseClaudeUtilization(value) {
|
|
13706
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return null;
|
|
13707
|
+
return Math.max(0, Math.min(100, value));
|
|
13708
|
+
}
|
|
13709
|
+
function windowFromRaw(id, raw) {
|
|
13710
|
+
if (!raw || typeof raw !== "object") return null;
|
|
13711
|
+
const row = raw;
|
|
13712
|
+
const used = parseClaudeUtilization(row.utilization ?? row.used_percentage);
|
|
13713
|
+
if (used == null) return null;
|
|
13714
|
+
const meta = WINDOW_META[id];
|
|
13715
|
+
return {
|
|
13716
|
+
id,
|
|
13717
|
+
label: meta.label,
|
|
13718
|
+
shortLabel: meta.shortLabel,
|
|
13719
|
+
detail: meta.detail,
|
|
13720
|
+
usedPercent: used,
|
|
13721
|
+
remainingPercent: Math.max(0, Math.min(100, 100 - used)),
|
|
13722
|
+
resetsAt: parseClaudeResetsAt(row.resets_at)
|
|
13723
|
+
};
|
|
13724
|
+
}
|
|
13725
|
+
function extraUsageFromRaw(raw) {
|
|
13726
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
13727
|
+
const row = raw;
|
|
13728
|
+
const enabled = row.is_enabled === true || row.enabled === true;
|
|
13729
|
+
if (!enabled && row.is_enabled !== false && row.enabled !== false) return void 0;
|
|
13730
|
+
const usedCredits = numberOrUndef(row.used_credits ?? row.used);
|
|
13731
|
+
const monthlyLimit = numberOrUndef(row.monthly_limit);
|
|
13732
|
+
const usedPercent = parseClaudeUtilization(row.utilization) ?? void 0;
|
|
13733
|
+
return {
|
|
13734
|
+
enabled,
|
|
13735
|
+
...usedCredits != null ? { usedCredits } : {},
|
|
13736
|
+
...monthlyLimit != null ? { monthlyLimit } : {},
|
|
13737
|
+
...usedPercent != null ? { usedPercent } : {}
|
|
13738
|
+
};
|
|
13739
|
+
}
|
|
13740
|
+
function numberOrUndef(value) {
|
|
13741
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return void 0;
|
|
13742
|
+
return value;
|
|
13743
|
+
}
|
|
13744
|
+
function parseClaudeUsagePayload(raw, fetchedAt = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
13745
|
+
if (!raw || typeof raw !== "object") return null;
|
|
13746
|
+
const obj = raw;
|
|
13747
|
+
const source = obj.rate_limits && typeof obj.rate_limits === "object" ? obj.rate_limits : obj;
|
|
13748
|
+
const windows = [];
|
|
13749
|
+
for (const id of WINDOW_ORDER) {
|
|
13750
|
+
const parsed = windowFromRaw(id, source[id]);
|
|
13751
|
+
if (parsed) windows.push(parsed);
|
|
13752
|
+
}
|
|
13753
|
+
if (windows.length === 0) return null;
|
|
13754
|
+
const extra = extraUsageFromRaw(obj.extra_usage ?? source.extra_usage);
|
|
13755
|
+
return {
|
|
13756
|
+
windows,
|
|
13757
|
+
...extra ? { extraUsage: extra } : {},
|
|
13758
|
+
fetchedAt
|
|
13759
|
+
};
|
|
13760
|
+
}
|
|
13761
|
+
function hottestClaudeWindow(usage) {
|
|
13762
|
+
if (usage.windows.length === 0) return null;
|
|
13763
|
+
return usage.windows.reduce((a, b) => b.usedPercent > a.usedPercent ? b : a);
|
|
13764
|
+
}
|
|
13765
|
+
function formatClaudeUsageReset(resetsAt, now = /* @__PURE__ */ new Date()) {
|
|
13766
|
+
if (!resetsAt) return "";
|
|
13767
|
+
const at = new Date(resetsAt);
|
|
13768
|
+
if (Number.isNaN(at.getTime())) return "";
|
|
13769
|
+
const ms = at.getTime() - now.getTime();
|
|
13770
|
+
if (ms <= 0) return "resets soon";
|
|
13771
|
+
const minutes = Math.round(ms / 6e4);
|
|
13772
|
+
if (minutes < 60) return `resets in ${Math.max(1, minutes)}m`;
|
|
13773
|
+
const hours = Math.round(minutes / 60);
|
|
13774
|
+
if (hours < 36) return `resets in ${hours}h`;
|
|
13775
|
+
try {
|
|
13776
|
+
return `resets ${at.toLocaleString(void 0, {
|
|
13777
|
+
weekday: "short",
|
|
13778
|
+
hour: "numeric",
|
|
13779
|
+
minute: "2-digit"
|
|
13780
|
+
})}`;
|
|
13781
|
+
} catch {
|
|
13782
|
+
return `resets ${at.toISOString()}`;
|
|
13783
|
+
}
|
|
13784
|
+
}
|
|
13785
|
+
function formatClaudeUsageResetClock(resetsAt) {
|
|
13786
|
+
if (!resetsAt) return "";
|
|
13787
|
+
const at = new Date(resetsAt);
|
|
13788
|
+
if (Number.isNaN(at.getTime())) return "";
|
|
13789
|
+
try {
|
|
13790
|
+
return at.toLocaleString(void 0, {
|
|
13791
|
+
weekday: "short",
|
|
13792
|
+
month: "short",
|
|
13793
|
+
day: "numeric",
|
|
13794
|
+
hour: "numeric",
|
|
13795
|
+
minute: "2-digit"
|
|
13796
|
+
});
|
|
13797
|
+
} catch {
|
|
13798
|
+
return at.toISOString();
|
|
13799
|
+
}
|
|
13800
|
+
}
|
|
13801
|
+
function formatClaudeUsageFetchedAt(fetchedAt, now = /* @__PURE__ */ new Date()) {
|
|
13802
|
+
const at = new Date(fetchedAt);
|
|
13803
|
+
if (Number.isNaN(at.getTime())) return "";
|
|
13804
|
+
const minutes = Math.max(0, Math.round((now.getTime() - at.getTime()) / 6e4));
|
|
13805
|
+
if (minutes < 1) return "Updated just now";
|
|
13806
|
+
if (minutes < 60) return `Updated ${minutes}m ago`;
|
|
13807
|
+
const hours = Math.round(minutes / 60);
|
|
13808
|
+
if (hours < 36) return `Updated ${hours}h ago`;
|
|
13809
|
+
return `Updated ${formatClaudeUsageResetClock(fetchedAt)}`;
|
|
13810
|
+
}
|
|
13811
|
+
function formatClaudeExtraUsageDetail(extra) {
|
|
13812
|
+
if (!extra.enabled) return "Extra usage off";
|
|
13813
|
+
const bits = ["Extra usage on"];
|
|
13814
|
+
if (extra.usedCredits != null && extra.monthlyLimit != null) {
|
|
13815
|
+
bits.push(`${extra.usedCredits} / ${extra.monthlyLimit} credits this month`);
|
|
13816
|
+
} else if (extra.usedCredits != null) {
|
|
13817
|
+
bits.push(`${extra.usedCredits} credits used`);
|
|
13818
|
+
}
|
|
13819
|
+
if (extra.usedPercent != null) {
|
|
13820
|
+
bits.push(`${Math.round(extra.usedPercent)}% of extra pool`);
|
|
13821
|
+
}
|
|
13822
|
+
return bits.join(" \xB7 ");
|
|
13823
|
+
}
|
|
13824
|
+
function formatClaudeUsageWindowLine(window, now = /* @__PURE__ */ new Date()) {
|
|
13825
|
+
const reset = formatClaudeUsageReset(window.resetsAt, now);
|
|
13826
|
+
const clock = formatClaudeUsageResetClock(window.resetsAt);
|
|
13827
|
+
const left = `${Math.round(window.remainingPercent)}% left`;
|
|
13828
|
+
const used = `${Math.round(window.usedPercent)}% used`;
|
|
13829
|
+
const resetBit = reset ? clock && !reset.includes(clock) ? `${reset} (${clock})` : reset : "";
|
|
13830
|
+
return resetBit ? `${window.label} \u2014 ${window.detail}. ${left} \xB7 ${used} \xB7 ${resetBit}` : `${window.label} \u2014 ${window.detail}. ${left} \xB7 ${used}`;
|
|
13831
|
+
}
|
|
13832
|
+
function formatClaudeUsageTooltip(usage, now = /* @__PURE__ */ new Date()) {
|
|
13833
|
+
const lines = [
|
|
13834
|
+
"Claude Code plan",
|
|
13835
|
+
...usage.windows.map((w) => formatClaudeUsageWindowLine(w, now))
|
|
13836
|
+
];
|
|
13837
|
+
if (usage.extraUsage) {
|
|
13838
|
+
lines.push(formatClaudeExtraUsageDetail(usage.extraUsage));
|
|
13839
|
+
}
|
|
13840
|
+
const fetched = formatClaudeUsageFetchedAt(usage.fetchedAt, now);
|
|
13841
|
+
if (fetched) lines.push(fetched);
|
|
13842
|
+
return lines.join("\n");
|
|
13843
|
+
}
|
|
13844
|
+
function formatClaudeUsageCompact(window) {
|
|
13845
|
+
return `${window.shortLabel} ${Math.round(window.remainingPercent)}%`;
|
|
13846
|
+
}
|
|
13847
|
+
function claudeUsageWindowOverLimit(window) {
|
|
13848
|
+
return window.remainingPercent <= 0 || window.usedPercent >= 100;
|
|
13849
|
+
}
|
|
13850
|
+
function claudeUsageOverLimitWindows(usage) {
|
|
13851
|
+
if (!usage) return [];
|
|
13852
|
+
return usage.windows.filter(claudeUsageWindowOverLimit);
|
|
13853
|
+
}
|
|
13854
|
+
function formatClaudeUsageOverLimitConfirm(windows, now = /* @__PURE__ */ new Date()) {
|
|
13855
|
+
if (windows.length === 0) return "";
|
|
13856
|
+
const parts = windows.map((w) => {
|
|
13857
|
+
const reset = formatClaudeUsageReset(w.resetsAt, now);
|
|
13858
|
+
return reset ? `${w.label} (${reset})` : w.label;
|
|
13859
|
+
});
|
|
13860
|
+
const list = parts.join(", ");
|
|
13861
|
+
const verb = windows.length === 1 ? "is" : "are";
|
|
13862
|
+
return `Claude Code ${list} ${verb} at or over the plan limit. Send this message anyway?`;
|
|
13863
|
+
}
|
|
13864
|
+
var WINDOW_META, WINDOW_ORDER;
|
|
13865
|
+
var init_claude_usage = __esm({
|
|
13866
|
+
"src/agents/claude-usage.ts"() {
|
|
13867
|
+
"use strict";
|
|
13868
|
+
WINDOW_META = {
|
|
13869
|
+
five_hour: {
|
|
13870
|
+
label: "5-hour session",
|
|
13871
|
+
shortLabel: "5h",
|
|
13872
|
+
detail: "Rolling 5-hour limit across all models"
|
|
13873
|
+
},
|
|
13874
|
+
seven_day: {
|
|
13875
|
+
label: "Weekly",
|
|
13876
|
+
shortLabel: "wk",
|
|
13877
|
+
detail: "7-day cap across all models"
|
|
13878
|
+
},
|
|
13879
|
+
seven_day_opus: {
|
|
13880
|
+
label: "Opus",
|
|
13881
|
+
shortLabel: "Opus",
|
|
13882
|
+
detail: "Weekly Opus-only cap"
|
|
13883
|
+
},
|
|
13884
|
+
seven_day_sonnet: {
|
|
13885
|
+
label: "Sonnet",
|
|
13886
|
+
shortLabel: "Sonnet",
|
|
13887
|
+
detail: "Weekly Sonnet-only cap"
|
|
13888
|
+
}
|
|
13889
|
+
};
|
|
13890
|
+
WINDOW_ORDER = [
|
|
13891
|
+
"five_hour",
|
|
13892
|
+
"seven_day",
|
|
13893
|
+
"seven_day_opus",
|
|
13894
|
+
"seven_day_sonnet"
|
|
13895
|
+
];
|
|
13896
|
+
}
|
|
13897
|
+
});
|
|
13898
|
+
|
|
13899
|
+
// src/agents/claude-usage-client.ts
|
|
13900
|
+
function accessTokenFromCredentialsJson(raw) {
|
|
13901
|
+
const trimmed = raw.trim();
|
|
13902
|
+
if (!trimmed) return null;
|
|
13903
|
+
if (trimmed.startsWith("sk-ant-")) {
|
|
13904
|
+
const token = trimmed.split(/\s+/)[0];
|
|
13905
|
+
return token || null;
|
|
13906
|
+
}
|
|
13907
|
+
try {
|
|
13908
|
+
const parsed = JSON.parse(trimmed);
|
|
13909
|
+
const oauth = parsed.claudeAiOauth && typeof parsed.claudeAiOauth === "object" ? parsed.claudeAiOauth : parsed;
|
|
13910
|
+
const token = oauth.accessToken ?? oauth.access_token;
|
|
13911
|
+
return typeof token === "string" && token.trim() ? token.trim() : null;
|
|
13912
|
+
} catch {
|
|
13913
|
+
return null;
|
|
13914
|
+
}
|
|
13915
|
+
}
|
|
13916
|
+
function claudeCredentialsPath() {
|
|
13917
|
+
const root = process.env.CLAUDE_CONFIG_DIR?.trim() || (0, import_node_path37.join)((0, import_node_os13.homedir)(), ".claude");
|
|
13918
|
+
return (0, import_node_path37.join)(root, ".credentials.json");
|
|
13919
|
+
}
|
|
13920
|
+
async function readFileAccessToken() {
|
|
13921
|
+
const path2 = claudeCredentialsPath();
|
|
13922
|
+
if (!(0, import_node_fs37.existsSync)(path2)) return null;
|
|
13923
|
+
try {
|
|
13924
|
+
return accessTokenFromCredentialsJson((0, import_node_fs37.readFileSync)(path2, "utf8"));
|
|
13925
|
+
} catch {
|
|
13926
|
+
return null;
|
|
13927
|
+
}
|
|
13928
|
+
}
|
|
13929
|
+
async function readKeychainAccessToken() {
|
|
13930
|
+
if (process.platform !== "darwin") return null;
|
|
13931
|
+
for (const service of KEYCHAIN_SERVICES) {
|
|
13932
|
+
const result = await run("security", ["find-generic-password", "-s", service, "-w"], {
|
|
13933
|
+
reject: false,
|
|
13934
|
+
timeoutMs: 4e3
|
|
13935
|
+
});
|
|
13936
|
+
if (result.exitCode !== 0 || !result.stdout.trim()) continue;
|
|
13937
|
+
const token = accessTokenFromCredentialsJson(result.stdout);
|
|
13938
|
+
if (token) return token;
|
|
13939
|
+
}
|
|
13940
|
+
return null;
|
|
13941
|
+
}
|
|
13942
|
+
async function readClaudeAccessToken() {
|
|
13943
|
+
const envToken = process.env.CLAUDE_CODE_OAUTH_TOKEN?.trim();
|
|
13944
|
+
if (envToken) return envToken;
|
|
13945
|
+
const fromFile = await readFileAccessToken();
|
|
13946
|
+
if (fromFile) return fromFile;
|
|
13947
|
+
return readKeychainAccessToken();
|
|
13948
|
+
}
|
|
13949
|
+
async function resolveClaudeUserAgent() {
|
|
13950
|
+
if (claudeVersion) return `claude-code/${claudeVersion}`;
|
|
13951
|
+
try {
|
|
13952
|
+
const claude = resolveClaudeExecutable();
|
|
13953
|
+
const result = await run(claude, ["--version"], { reject: false, timeoutMs: 4e3 });
|
|
13954
|
+
const match = `${result.stdout}
|
|
13955
|
+
${result.stderr}`.match(/(\d+\.\d+\.\d+)/);
|
|
13956
|
+
claudeVersion = match?.[1] ?? "2.1.80";
|
|
13957
|
+
} catch {
|
|
13958
|
+
claudeVersion = "2.1.80";
|
|
13959
|
+
}
|
|
13960
|
+
return `claude-code/${claudeVersion}`;
|
|
13961
|
+
}
|
|
13962
|
+
function staleOk(now) {
|
|
13963
|
+
if (!lastGood) return null;
|
|
13964
|
+
if (now - lastGood.at > CLAUDE_USAGE_STALE_OK_MS) return null;
|
|
13965
|
+
return lastGood.value;
|
|
13966
|
+
}
|
|
13967
|
+
async function getClaudePlanUsage(opts = {}) {
|
|
13968
|
+
const now = opts.now ?? Date.now();
|
|
13969
|
+
if (!opts.force) {
|
|
13970
|
+
if (cache && now - cache.at < CLAUDE_USAGE_TTL_MS) return cache.value;
|
|
13971
|
+
if (now < errorUntil) return staleOk(now);
|
|
13972
|
+
}
|
|
13973
|
+
if (inflight) return inflight;
|
|
13974
|
+
inflight = (async () => {
|
|
13975
|
+
try {
|
|
13976
|
+
const token = await (opts.readAccessToken ?? readClaudeAccessToken)();
|
|
13977
|
+
if (!token) {
|
|
13978
|
+
cache = { at: now, value: null };
|
|
13979
|
+
return null;
|
|
13980
|
+
}
|
|
13981
|
+
const fetchFn = opts.fetch ?? globalThis.fetch;
|
|
13982
|
+
const userAgent = opts.userAgent ?? await resolveClaudeUserAgent();
|
|
13983
|
+
const ac = new AbortController();
|
|
13984
|
+
const timer = setTimeout(() => ac.abort(), 8e3);
|
|
13985
|
+
let res;
|
|
13986
|
+
try {
|
|
13987
|
+
res = await fetchFn(CLAUDE_OAUTH_USAGE_URL, {
|
|
13988
|
+
headers: {
|
|
13989
|
+
Authorization: `Bearer ${token}`,
|
|
13990
|
+
"anthropic-beta": "oauth-2025-04-20",
|
|
13991
|
+
"User-Agent": userAgent
|
|
13992
|
+
},
|
|
13993
|
+
signal: ac.signal
|
|
13994
|
+
});
|
|
13995
|
+
} finally {
|
|
13996
|
+
clearTimeout(timer);
|
|
13997
|
+
}
|
|
13998
|
+
if (res.status === 401 || res.status === 403) {
|
|
13999
|
+
cache = { at: now, value: null };
|
|
14000
|
+
return null;
|
|
14001
|
+
}
|
|
14002
|
+
if (!res.ok) {
|
|
14003
|
+
errorUntil = now + CLAUDE_USAGE_ERROR_TTL_MS;
|
|
14004
|
+
return staleOk(now);
|
|
14005
|
+
}
|
|
14006
|
+
const usage = parseClaudeUsagePayload(await res.json(), new Date(now).toISOString());
|
|
14007
|
+
cache = { at: now, value: usage };
|
|
14008
|
+
if (usage) lastGood = { at: now, value: usage };
|
|
14009
|
+
return usage;
|
|
14010
|
+
} catch {
|
|
14011
|
+
errorUntil = now + CLAUDE_USAGE_ERROR_TTL_MS;
|
|
14012
|
+
return staleOk(now);
|
|
14013
|
+
} finally {
|
|
14014
|
+
inflight = null;
|
|
14015
|
+
}
|
|
14016
|
+
})();
|
|
14017
|
+
return inflight;
|
|
14018
|
+
}
|
|
14019
|
+
var import_node_fs37, import_node_os13, import_node_path37, CLAUDE_OAUTH_USAGE_URL, CLAUDE_USAGE_TTL_MS, CLAUDE_USAGE_ERROR_TTL_MS, CLAUDE_USAGE_STALE_OK_MS, KEYCHAIN_SERVICES, cache, errorUntil, inflight, lastGood, claudeVersion;
|
|
14020
|
+
var init_claude_usage_client = __esm({
|
|
14021
|
+
"src/agents/claude-usage-client.ts"() {
|
|
14022
|
+
"use strict";
|
|
14023
|
+
import_node_fs37 = require("fs");
|
|
14024
|
+
import_node_os13 = require("os");
|
|
14025
|
+
import_node_path37 = require("path");
|
|
14026
|
+
init_run();
|
|
14027
|
+
init_app_settings();
|
|
14028
|
+
init_claude_usage();
|
|
14029
|
+
CLAUDE_OAUTH_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
|
|
14030
|
+
CLAUDE_USAGE_TTL_MS = 9e4;
|
|
14031
|
+
CLAUDE_USAGE_ERROR_TTL_MS = 5 * 6e4;
|
|
14032
|
+
CLAUDE_USAGE_STALE_OK_MS = 30 * 6e4;
|
|
14033
|
+
KEYCHAIN_SERVICES = ["Claude Code-credentials", "Claude Code"];
|
|
14034
|
+
cache = null;
|
|
14035
|
+
errorUntil = 0;
|
|
14036
|
+
inflight = null;
|
|
14037
|
+
lastGood = null;
|
|
14038
|
+
claudeVersion = null;
|
|
14039
|
+
}
|
|
14040
|
+
});
|
|
14041
|
+
|
|
13653
14042
|
// src/agents/install.ts
|
|
13654
14043
|
function getAgentSetupInfo(agent) {
|
|
13655
14044
|
return SETUP[agent];
|
|
@@ -13898,6 +14287,7 @@ __export(agents_exports, {
|
|
|
13898
14287
|
assertOrchestratorCapableAgent: () => assertOrchestratorCapableAgent,
|
|
13899
14288
|
brightsyAdapter: () => brightsyAdapter,
|
|
13900
14289
|
claudeAdapter: () => claudeAdapter,
|
|
14290
|
+
claudeUsageOverLimitWindows: () => claudeUsageOverLimitWindows,
|
|
13901
14291
|
codexAdapter: () => codexAdapter,
|
|
13902
14292
|
coerceOrchestratorAgent: () => coerceOrchestratorAgent,
|
|
13903
14293
|
conductorBundledBinDir: () => conductorBundledBinDir,
|
|
@@ -13907,8 +14297,17 @@ __export(agents_exports, {
|
|
|
13907
14297
|
encodeBrightsyTarget: () => encodeBrightsyTarget,
|
|
13908
14298
|
enrichPathWithNpmGlobalBin: () => enrichPathWithNpmGlobalBin,
|
|
13909
14299
|
ensureAgentPath: () => ensureAgentPath,
|
|
14300
|
+
formatClaudeExtraUsageDetail: () => formatClaudeExtraUsageDetail,
|
|
14301
|
+
formatClaudeUsageCompact: () => formatClaudeUsageCompact,
|
|
14302
|
+
formatClaudeUsageFetchedAt: () => formatClaudeUsageFetchedAt,
|
|
14303
|
+
formatClaudeUsageOverLimitConfirm: () => formatClaudeUsageOverLimitConfirm,
|
|
14304
|
+
formatClaudeUsageReset: () => formatClaudeUsageReset,
|
|
14305
|
+
formatClaudeUsageResetClock: () => formatClaudeUsageResetClock,
|
|
14306
|
+
formatClaudeUsageTooltip: () => formatClaudeUsageTooltip,
|
|
13910
14307
|
getAdapter: () => getAdapter,
|
|
13911
14308
|
getAgentSetupInfo: () => getAgentSetupInfo,
|
|
14309
|
+
getClaudePlanUsage: () => getClaudePlanUsage,
|
|
14310
|
+
hottestClaudeWindow: () => hottestClaudeWindow,
|
|
13912
14311
|
installAgent: () => installAgent,
|
|
13913
14312
|
installNpmGlobalPackage: () => installNpmGlobalPackage,
|
|
13914
14313
|
isConductorBundledCli: () => isConductorBundledCli,
|
|
@@ -13926,6 +14325,7 @@ __export(agents_exports, {
|
|
|
13926
14325
|
mcpStatusThinkingFromClaudeInit: () => mcpStatusThinkingFromClaudeInit,
|
|
13927
14326
|
openInSystemTerminal: () => openInSystemTerminal,
|
|
13928
14327
|
opencodeAdapter: () => opencodeAdapter,
|
|
14328
|
+
parseClaudeUsagePayload: () => parseClaudeUsagePayload,
|
|
13929
14329
|
parseCursorRunnerLine: () => parseCursorRunnerLine,
|
|
13930
14330
|
parseSessionQuotaResetAt: () => parseSessionQuotaResetAt,
|
|
13931
14331
|
permissionMode: () => permissionMode,
|
|
@@ -13966,6 +14366,8 @@ var init_agents = __esm({
|
|
|
13966
14366
|
init_opencode();
|
|
13967
14367
|
init_list_models();
|
|
13968
14368
|
init_session_quota();
|
|
14369
|
+
init_claude_usage();
|
|
14370
|
+
init_claude_usage_client();
|
|
13969
14371
|
init_orchestrator_capable();
|
|
13970
14372
|
init_path();
|
|
13971
14373
|
init_install();
|
|
@@ -13981,15 +14383,15 @@ var init_agents = __esm({
|
|
|
13981
14383
|
|
|
13982
14384
|
// src/hook/worktree-pkg-cache.ts
|
|
13983
14385
|
function worktreePkgCacheRoot(worktreePath) {
|
|
13984
|
-
return (0,
|
|
14386
|
+
return (0, import_node_path38.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
|
|
13985
14387
|
}
|
|
13986
14388
|
function worktreePkgCacheEnv(worktreePath) {
|
|
13987
14389
|
const root = worktreePkgCacheRoot(worktreePath);
|
|
13988
|
-
const store = (0,
|
|
13989
|
-
const pnpmCache = (0,
|
|
13990
|
-
const npmCache = (0,
|
|
13991
|
-
const nodeGyp = (0,
|
|
13992
|
-
const electron = (0,
|
|
14390
|
+
const store = (0, import_node_path38.join)(root, "pnpm-store");
|
|
14391
|
+
const pnpmCache = (0, import_node_path38.join)(root, "pnpm");
|
|
14392
|
+
const npmCache = (0, import_node_path38.join)(root, "npm");
|
|
14393
|
+
const nodeGyp = (0, import_node_path38.join)(root, "node-gyp");
|
|
14394
|
+
const electron = (0, import_node_path38.join)(root, "electron");
|
|
13993
14395
|
return {
|
|
13994
14396
|
npm_config_store_dir: store,
|
|
13995
14397
|
PNPM_STORE_DIR: store,
|
|
@@ -14011,8 +14413,8 @@ function fillGroup(env, keys, values) {
|
|
|
14011
14413
|
}
|
|
14012
14414
|
}
|
|
14013
14415
|
function ensureWorktreePkgCacheDirs(worktreePath) {
|
|
14014
|
-
if (!(0,
|
|
14015
|
-
(0,
|
|
14416
|
+
if (!(0, import_node_fs38.existsSync)(worktreePath)) return;
|
|
14417
|
+
(0, import_node_fs38.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
|
|
14016
14418
|
}
|
|
14017
14419
|
function applyWorktreePkgCacheEnv(env, worktreePath) {
|
|
14018
14420
|
const cwd = worktreePath.trim();
|
|
@@ -14025,12 +14427,12 @@ function applyWorktreePkgCacheEnv(env, worktreePath) {
|
|
|
14025
14427
|
fillGroup(env, ["electron_config_cache"], next);
|
|
14026
14428
|
ensureWorktreePkgCacheDirs(cwd);
|
|
14027
14429
|
}
|
|
14028
|
-
var
|
|
14430
|
+
var import_node_fs38, import_node_path38, WORKTREE_PKG_CACHE_REL;
|
|
14029
14431
|
var init_worktree_pkg_cache = __esm({
|
|
14030
14432
|
"src/hook/worktree-pkg-cache.ts"() {
|
|
14031
14433
|
"use strict";
|
|
14032
|
-
|
|
14033
|
-
|
|
14434
|
+
import_node_fs38 = require("fs");
|
|
14435
|
+
import_node_path38 = require("path");
|
|
14034
14436
|
WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
|
|
14035
14437
|
}
|
|
14036
14438
|
});
|
|
@@ -14215,11 +14617,11 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
14215
14617
|
consume(child.stderr, "stderr");
|
|
14216
14618
|
const done = child.then((result) => {
|
|
14217
14619
|
outbound.flush();
|
|
14218
|
-
const exitCode = result.exitCode ?? null;
|
|
14219
|
-
onEvent({ type: "exit", data: exitCode });
|
|
14220
14620
|
const finalized = finalizeParts(parts);
|
|
14221
14621
|
const rawText = assistantText.trim() || partsToAssistantText(finalized);
|
|
14222
14622
|
const text7 = thread.agent === "brightsy" ? stripBrightsyNdjsonNoise(rawText) : rawText;
|
|
14623
|
+
const exitCode = thread.agent === "brightsy" ? adjustBrightsyTurnExit(result.exitCode ?? null, text7) : result.exitCode ?? null;
|
|
14624
|
+
onEvent({ type: "exit", data: exitCode });
|
|
14223
14625
|
return { exitCode, sessionId, assistantText: text7, parts: finalized, usage };
|
|
14224
14626
|
});
|
|
14225
14627
|
return {
|
|
@@ -15189,21 +15591,21 @@ function shouldRefreshReviewRequestTemplate(content) {
|
|
|
15189
15591
|
return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
|
|
15190
15592
|
}
|
|
15191
15593
|
function readTextIfPresent(abs) {
|
|
15192
|
-
if (!(0,
|
|
15594
|
+
if (!(0, import_node_fs39.existsSync)(abs)) return null;
|
|
15193
15595
|
try {
|
|
15194
|
-
const content = (0,
|
|
15596
|
+
const content = (0, import_node_fs39.readFileSync)(abs, "utf8");
|
|
15195
15597
|
return content.trim() ? content : null;
|
|
15196
15598
|
} catch {
|
|
15197
15599
|
return null;
|
|
15198
15600
|
}
|
|
15199
15601
|
}
|
|
15200
15602
|
function readLocalGuidelines(worktreePath) {
|
|
15201
|
-
const localAbs = (0,
|
|
15603
|
+
const localAbs = (0, import_node_path39.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
15202
15604
|
const localContent = readTextIfPresent(localAbs);
|
|
15203
15605
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
15204
15606
|
return { path: REVIEW_REQUEST_PATH, content: localContent };
|
|
15205
15607
|
}
|
|
15206
|
-
const legacyAbs = (0,
|
|
15608
|
+
const legacyAbs = (0, import_node_path39.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
|
|
15207
15609
|
const legacyContent = readTextIfPresent(legacyAbs);
|
|
15208
15610
|
if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
|
|
15209
15611
|
return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
|
|
@@ -15227,27 +15629,27 @@ function contextGuidelines(content, source) {
|
|
|
15227
15629
|
};
|
|
15228
15630
|
}
|
|
15229
15631
|
function writeContextGuidelines(worktreePath, content) {
|
|
15230
|
-
const abs = (0,
|
|
15231
|
-
(0,
|
|
15632
|
+
const abs = (0, import_node_path39.join)(worktreePath, CONTEXT_REVIEW_PATH);
|
|
15633
|
+
(0, import_node_fs39.mkdirSync)((0, import_node_path39.dirname)(abs), { recursive: true });
|
|
15232
15634
|
const body = content.endsWith("\n") ? content : `${content}
|
|
15233
15635
|
`;
|
|
15234
|
-
(0,
|
|
15636
|
+
(0, import_node_fs39.writeFileSync)(abs, body, "utf8");
|
|
15235
15637
|
return body;
|
|
15236
15638
|
}
|
|
15237
15639
|
function readSideboardReview(worktreePath, repoPath) {
|
|
15238
|
-
const fromWorktree = readTextIfPresent((0,
|
|
15640
|
+
const fromWorktree = readTextIfPresent((0, import_node_path39.join)(worktreePath, REPO_REVIEW_PATH));
|
|
15239
15641
|
if (fromWorktree) return fromWorktree;
|
|
15240
15642
|
const repo = repoPath?.replace(/\/+$/, "");
|
|
15241
15643
|
const wt = worktreePath.replace(/\/+$/, "");
|
|
15242
15644
|
if (!repo || repo === wt) return null;
|
|
15243
|
-
return readTextIfPresent((0,
|
|
15645
|
+
return readTextIfPresent((0, import_node_path39.join)(repo, REPO_REVIEW_PATH));
|
|
15244
15646
|
}
|
|
15245
15647
|
function ensureReviewGuidelinesFile(worktreePath, repoPath) {
|
|
15246
|
-
const skillContent = readTextIfPresent((0,
|
|
15648
|
+
const skillContent = readTextIfPresent((0, import_node_path39.join)(worktreePath, REVIEW_SKILL_PATH));
|
|
15247
15649
|
if (skillContent) {
|
|
15248
15650
|
return { ...skillGuidelines(skillContent, "skill"), wrote: false };
|
|
15249
15651
|
}
|
|
15250
|
-
const contextContent = readTextIfPresent((0,
|
|
15652
|
+
const contextContent = readTextIfPresent((0, import_node_path39.join)(worktreePath, CONTEXT_REVIEW_PATH));
|
|
15251
15653
|
if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
|
|
15252
15654
|
return { ...contextGuidelines(contextContent, "local"), wrote: false };
|
|
15253
15655
|
}
|
|
@@ -15285,7 +15687,7 @@ function buildReviewRequestAttachment(content, opts) {
|
|
|
15285
15687
|
};
|
|
15286
15688
|
}
|
|
15287
15689
|
function readExistingReviewRequestFile(worktreePath) {
|
|
15288
|
-
return readTextIfPresent((0,
|
|
15690
|
+
return readTextIfPresent((0, import_node_path39.join)(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent((0, import_node_path39.join)(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path39.join)(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent((0, import_node_path39.join)(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent((0, import_node_path39.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
|
|
15289
15691
|
}
|
|
15290
15692
|
async function requestReview(threadRef, send2) {
|
|
15291
15693
|
const from = findThreadByRef(threadRef);
|
|
@@ -15312,13 +15714,13 @@ async function requestReview(threadRef, send2) {
|
|
|
15312
15714
|
const started = await send2(tab.id, REVIEW_REQUEST_PREFILL);
|
|
15313
15715
|
return { tab: started, from };
|
|
15314
15716
|
}
|
|
15315
|
-
var import_node_crypto9,
|
|
15717
|
+
var import_node_crypto9, import_node_fs39, import_node_path39, REPO_REVIEW_PATH, REPO_REVIEW_NAME, CONTEXT_REVIEW_PATH, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
|
|
15316
15718
|
var init_request_review = __esm({
|
|
15317
15719
|
"src/review/request-review.ts"() {
|
|
15318
15720
|
"use strict";
|
|
15319
15721
|
import_node_crypto9 = require("crypto");
|
|
15320
|
-
|
|
15321
|
-
|
|
15722
|
+
import_node_fs39 = require("fs");
|
|
15723
|
+
import_node_path39 = require("path");
|
|
15322
15724
|
init_global_workspace();
|
|
15323
15725
|
init_chat_tabs();
|
|
15324
15726
|
init_thread_store();
|
|
@@ -15344,9 +15746,9 @@ function matchSimpleGlob(pattern, name) {
|
|
|
15344
15746
|
return new RegExp(`^${escaped}$`).test(name);
|
|
15345
15747
|
}
|
|
15346
15748
|
function readWorktreeInclude(repoPath) {
|
|
15347
|
-
const path2 = (0,
|
|
15348
|
-
if (!(0,
|
|
15349
|
-
return (0,
|
|
15749
|
+
const path2 = (0, import_node_path40.join)(repoPath, ".worktreeinclude");
|
|
15750
|
+
if (!(0, import_node_fs40.existsSync)(path2)) return [];
|
|
15751
|
+
return (0, import_node_fs40.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
15350
15752
|
}
|
|
15351
15753
|
function resolveFilesToCopy(repoPath) {
|
|
15352
15754
|
const fromInclude = readWorktreeInclude(repoPath);
|
|
@@ -15356,10 +15758,10 @@ function resolveFilesToCopy(repoPath) {
|
|
|
15356
15758
|
if (settings?.fileIncludeGlobs?.length) {
|
|
15357
15759
|
const matched = [];
|
|
15358
15760
|
try {
|
|
15359
|
-
for (const entry of (0,
|
|
15761
|
+
for (const entry of (0, import_node_fs40.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
15360
15762
|
if (!entry.isFile()) continue;
|
|
15361
15763
|
for (const glob of settings.fileIncludeGlobs) {
|
|
15362
|
-
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0,
|
|
15764
|
+
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path40.basename)(glob), entry.name)) {
|
|
15363
15765
|
matched.push(entry.name);
|
|
15364
15766
|
break;
|
|
15365
15767
|
}
|
|
@@ -15371,7 +15773,7 @@ function resolveFilesToCopy(repoPath) {
|
|
|
15371
15773
|
}
|
|
15372
15774
|
const defaults = [];
|
|
15373
15775
|
try {
|
|
15374
|
-
for (const entry of (0,
|
|
15776
|
+
for (const entry of (0, import_node_fs40.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
15375
15777
|
if (entry.isFile() && entry.name.startsWith(".env")) {
|
|
15376
15778
|
defaults.push(entry.name);
|
|
15377
15779
|
}
|
|
@@ -15385,11 +15787,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
|
|
|
15385
15787
|
const patterns = resolveFilesToCopy(repoPath);
|
|
15386
15788
|
const copied = [];
|
|
15387
15789
|
for (const rel of patterns) {
|
|
15388
|
-
const src = (0,
|
|
15389
|
-
if (!(0,
|
|
15390
|
-
const dest = (0,
|
|
15391
|
-
(0,
|
|
15392
|
-
(0,
|
|
15790
|
+
const src = (0, import_node_path40.join)(repoPath, rel);
|
|
15791
|
+
if (!(0, import_node_fs40.existsSync)(src)) continue;
|
|
15792
|
+
const dest = (0, import_node_path40.join)(worktreePath, rel);
|
|
15793
|
+
(0, import_node_fs40.mkdirSync)((0, import_node_path40.dirname)(dest), { recursive: true });
|
|
15794
|
+
(0, import_node_fs40.copyFileSync)(src, dest);
|
|
15393
15795
|
copied.push(rel);
|
|
15394
15796
|
}
|
|
15395
15797
|
return copied;
|
|
@@ -15424,7 +15826,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
|
15424
15826
|
const env = stripNestedElectronEnv({
|
|
15425
15827
|
...baseEnv ?? process.env
|
|
15426
15828
|
});
|
|
15427
|
-
const name = opts.workspaceName ?? (0,
|
|
15829
|
+
const name = opts.workspaceName ?? (0, import_node_path40.basename)(opts.worktreePath);
|
|
15428
15830
|
const ports = opts.ports ?? [];
|
|
15429
15831
|
const primary = ports[0];
|
|
15430
15832
|
env.SIDEBOARD_WORKSPACE_NAME = name;
|
|
@@ -15687,13 +16089,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
15687
16089
|
done: handle.done
|
|
15688
16090
|
};
|
|
15689
16091
|
}
|
|
15690
|
-
var
|
|
16092
|
+
var import_node_fs40, import_node_net, import_node_path40, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
|
|
15691
16093
|
var init_conductor = __esm({
|
|
15692
16094
|
"src/hook/conductor.ts"() {
|
|
15693
16095
|
"use strict";
|
|
15694
|
-
|
|
16096
|
+
import_node_fs40 = require("fs");
|
|
15695
16097
|
import_node_net = require("net");
|
|
15696
|
-
|
|
16098
|
+
import_node_path40 = require("path");
|
|
15697
16099
|
import_execa4 = require("execa");
|
|
15698
16100
|
import_node_readline3 = require("readline");
|
|
15699
16101
|
init_settings();
|
|
@@ -15721,9 +16123,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
15721
16123
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
15722
16124
|
);
|
|
15723
16125
|
const homeRoot = sideboardWorkspacesDir();
|
|
15724
|
-
if ((0,
|
|
16126
|
+
if ((0, import_node_fs41.existsSync)(homeRoot)) {
|
|
15725
16127
|
try {
|
|
15726
|
-
for (const entry of (0,
|
|
16128
|
+
for (const entry of (0, import_node_fs41.readdirSync)(homeRoot, { withFileTypes: true })) {
|
|
15727
16129
|
if (!entry.isDirectory()) continue;
|
|
15728
16130
|
void entry;
|
|
15729
16131
|
}
|
|
@@ -15733,7 +16135,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
15733
16135
|
const orphans = [];
|
|
15734
16136
|
const seen = /* @__PURE__ */ new Set();
|
|
15735
16137
|
for (const repoPath of repos) {
|
|
15736
|
-
if (!repoPath || !(0,
|
|
16138
|
+
if (!repoPath || !(0, import_node_fs41.existsSync)(repoPath)) continue;
|
|
15737
16139
|
try {
|
|
15738
16140
|
const wts = await listWorktrees(repoPath);
|
|
15739
16141
|
for (const wt of wts) {
|
|
@@ -15744,7 +16146,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
15744
16146
|
seen.add(path2);
|
|
15745
16147
|
let mtimeMs = 0;
|
|
15746
16148
|
try {
|
|
15747
|
-
mtimeMs = (0,
|
|
16149
|
+
mtimeMs = (0, import_node_fs41.statSync)(path2).mtimeMs;
|
|
15748
16150
|
} catch {
|
|
15749
16151
|
mtimeMs = 0;
|
|
15750
16152
|
}
|
|
@@ -15754,16 +16156,16 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
15754
16156
|
}
|
|
15755
16157
|
try {
|
|
15756
16158
|
const root = worktreesRoot(repoPath);
|
|
15757
|
-
if ((0,
|
|
15758
|
-
for (const entry of (0,
|
|
16159
|
+
if ((0, import_node_fs41.existsSync)(root)) {
|
|
16160
|
+
for (const entry of (0, import_node_fs41.readdirSync)(root, { withFileTypes: true })) {
|
|
15759
16161
|
if (!entry.isDirectory()) continue;
|
|
15760
|
-
const path2 = (0,
|
|
16162
|
+
const path2 = (0, import_node_path41.join)(root, entry.name).replace(/\/$/, "");
|
|
15761
16163
|
if (known.has(path2) || seen.has(path2)) continue;
|
|
15762
|
-
if (!(0,
|
|
16164
|
+
if (!(0, import_node_fs41.existsSync)((0, import_node_path41.join)(path2, ".git"))) continue;
|
|
15763
16165
|
seen.add(path2);
|
|
15764
16166
|
let mtimeMs = 0;
|
|
15765
16167
|
try {
|
|
15766
|
-
mtimeMs = (0,
|
|
16168
|
+
mtimeMs = (0, import_node_fs41.statSync)(path2).mtimeMs;
|
|
15767
16169
|
} catch {
|
|
15768
16170
|
mtimeMs = Date.now();
|
|
15769
16171
|
}
|
|
@@ -15824,12 +16226,12 @@ function worktreeCleanupSettings() {
|
|
|
15824
16226
|
autoCleanupOrphans: a.autoCleanupOrphans
|
|
15825
16227
|
};
|
|
15826
16228
|
}
|
|
15827
|
-
var
|
|
16229
|
+
var import_node_fs41, import_node_path41;
|
|
15828
16230
|
var init_orphan_cleanup = __esm({
|
|
15829
16231
|
"src/git/orphan-cleanup.ts"() {
|
|
15830
16232
|
"use strict";
|
|
15831
|
-
|
|
15832
|
-
|
|
16233
|
+
import_node_fs41 = require("fs");
|
|
16234
|
+
import_node_path41 = require("path");
|
|
15833
16235
|
init_worktree();
|
|
15834
16236
|
init_thread_store();
|
|
15835
16237
|
init_paths();
|
|
@@ -15932,12 +16334,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
15932
16334
|
if (!url) throw new Error("Clone URL is required");
|
|
15933
16335
|
let name = opts.name?.trim();
|
|
15934
16336
|
if (!name) {
|
|
15935
|
-
const leaf = (0,
|
|
16337
|
+
const leaf = (0, import_node_path42.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
|
|
15936
16338
|
name = leaf || "repo";
|
|
15937
16339
|
}
|
|
15938
16340
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
15939
|
-
const dest = (0,
|
|
15940
|
-
if ((0,
|
|
16341
|
+
const dest = (0, import_node_path42.join)(sideboardReposDir(), name);
|
|
16342
|
+
if ((0, import_node_fs42.existsSync)(dest)) {
|
|
15941
16343
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
15942
16344
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
15943
16345
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -15952,12 +16354,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
15952
16354
|
const workspace = await ensureWorkspace(repoPath);
|
|
15953
16355
|
return { repoPath, workspace };
|
|
15954
16356
|
}
|
|
15955
|
-
var
|
|
16357
|
+
var import_node_fs42, import_node_path42, import_execa6;
|
|
15956
16358
|
var init_clone_repo = __esm({
|
|
15957
16359
|
"src/git/clone-repo.ts"() {
|
|
15958
16360
|
"use strict";
|
|
15959
|
-
|
|
15960
|
-
|
|
16361
|
+
import_node_fs42 = require("fs");
|
|
16362
|
+
import_node_path42 = require("path");
|
|
15961
16363
|
import_execa6 = require("execa");
|
|
15962
16364
|
init_paths();
|
|
15963
16365
|
init_workspaces();
|
|
@@ -16075,24 +16477,24 @@ function jobTreeAlive(pid) {
|
|
|
16075
16477
|
return jobAlive(pid) || processGroupAlive(pid);
|
|
16076
16478
|
}
|
|
16077
16479
|
function readIntFile(file) {
|
|
16078
|
-
if (!(0,
|
|
16079
|
-
const n = Number.parseInt((0,
|
|
16480
|
+
if (!(0, import_node_fs43.existsSync)(file)) return null;
|
|
16481
|
+
const n = Number.parseInt((0, import_node_fs43.readFileSync)(file, "utf8").trim(), 10);
|
|
16080
16482
|
return Number.isInteger(n) ? n : null;
|
|
16081
16483
|
}
|
|
16082
16484
|
function jobDir(root, id, legacy = false) {
|
|
16083
|
-
return (0,
|
|
16485
|
+
return (0, import_node_path43.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
|
|
16084
16486
|
}
|
|
16085
16487
|
function resolveJobDir(root, id) {
|
|
16086
16488
|
const modern = jobDir(root, id, false);
|
|
16087
|
-
if ((0,
|
|
16489
|
+
if ((0, import_node_fs43.existsSync)(modern)) return modern;
|
|
16088
16490
|
const legacy = jobDir(root, id, true);
|
|
16089
|
-
if ((0,
|
|
16491
|
+
if ((0, import_node_fs43.existsSync)(legacy)) return legacy;
|
|
16090
16492
|
return modern;
|
|
16091
16493
|
}
|
|
16092
16494
|
function listJobIdsIn(root, rel) {
|
|
16093
|
-
const dir = (0,
|
|
16094
|
-
if (!(0,
|
|
16095
|
-
return (0,
|
|
16495
|
+
const dir = (0, import_node_path43.join)(root, rel);
|
|
16496
|
+
if (!(0, import_node_fs43.existsSync)(dir)) return [];
|
|
16497
|
+
return (0, import_node_fs43.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
|
|
16096
16498
|
}
|
|
16097
16499
|
function listRunningDetachedJobs(worktreePath) {
|
|
16098
16500
|
const root = worktreePath.trim();
|
|
@@ -16104,7 +16506,7 @@ function listRunningDetachedJobs(worktreePath) {
|
|
|
16104
16506
|
const running = [];
|
|
16105
16507
|
for (const id of ids) {
|
|
16106
16508
|
const dir = resolveJobDir(root, id);
|
|
16107
|
-
const pid = readIntFile((0,
|
|
16509
|
+
const pid = readIntFile((0, import_node_path43.join)(dir, "pid"));
|
|
16108
16510
|
if (jobTreeAlive(pid)) running.push(id);
|
|
16109
16511
|
}
|
|
16110
16512
|
return running.sort();
|
|
@@ -16186,8 +16588,8 @@ function planJobContinue(opts) {
|
|
|
16186
16588
|
return { action: "none" };
|
|
16187
16589
|
}
|
|
16188
16590
|
function tailProgress(logFile, maxLines = 12) {
|
|
16189
|
-
if (!(0,
|
|
16190
|
-
const lines = (0,
|
|
16591
|
+
if (!(0, import_node_fs43.existsSync)(logFile)) return "(no log yet)";
|
|
16592
|
+
const lines = (0, import_node_fs43.readFileSync)(logFile, "utf8").split("\n");
|
|
16191
16593
|
return lines.slice(-maxLines).join("\n");
|
|
16192
16594
|
}
|
|
16193
16595
|
function lastProgressLine(progress) {
|
|
@@ -16195,8 +16597,8 @@ function lastProgressLine(progress) {
|
|
|
16195
16597
|
return last ? last.slice(0, 72) : void 0;
|
|
16196
16598
|
}
|
|
16197
16599
|
function readLogLines(file) {
|
|
16198
|
-
if (!(0,
|
|
16199
|
-
const lines = (0,
|
|
16600
|
+
if (!(0, import_node_fs43.existsSync)(file)) return [];
|
|
16601
|
+
const lines = (0, import_node_fs43.readFileSync)(file, "utf8").split("\n");
|
|
16200
16602
|
if (lines.length && lines[lines.length - 1] === "") lines.pop();
|
|
16201
16603
|
return lines;
|
|
16202
16604
|
}
|
|
@@ -16207,15 +16609,15 @@ function takeDelta(logFile, cursorFile) {
|
|
|
16207
16609
|
return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
|
|
16208
16610
|
}
|
|
16209
16611
|
function snapshotJob(dir) {
|
|
16210
|
-
const pid = readIntFile((0,
|
|
16612
|
+
const pid = readIntFile((0, import_node_path43.join)(dir, "pid"));
|
|
16211
16613
|
const running = jobTreeAlive(pid);
|
|
16212
16614
|
return {
|
|
16213
16615
|
pid,
|
|
16214
16616
|
running,
|
|
16215
|
-
exitCode: readIntFile((0,
|
|
16216
|
-
log: (0,
|
|
16217
|
-
cursor: (0,
|
|
16218
|
-
progress: tailProgress((0,
|
|
16617
|
+
exitCode: readIntFile((0, import_node_path43.join)(dir, "exit")),
|
|
16618
|
+
log: (0, import_node_path43.join)(dir, "log"),
|
|
16619
|
+
cursor: (0, import_node_path43.join)(dir, "present.cursor"),
|
|
16620
|
+
progress: tailProgress((0, import_node_path43.join)(dir, "log"))
|
|
16219
16621
|
};
|
|
16220
16622
|
}
|
|
16221
16623
|
function toResult(id, snap, extra) {
|
|
@@ -16224,8 +16626,8 @@ function toResult(id, snap, extra) {
|
|
|
16224
16626
|
const stillRunning = snap.running && !ok;
|
|
16225
16627
|
const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
|
|
16226
16628
|
try {
|
|
16227
|
-
(0,
|
|
16228
|
-
(0,
|
|
16629
|
+
(0, import_node_fs43.mkdirSync)((0, import_node_path43.dirname)(snap.cursor), { recursive: true });
|
|
16630
|
+
(0, import_node_fs43.writeFileSync)(snap.cursor, `${nextCursor}
|
|
16229
16631
|
`);
|
|
16230
16632
|
} catch {
|
|
16231
16633
|
}
|
|
@@ -16254,7 +16656,7 @@ async function waitForDetachedJob(cwd, id, opts) {
|
|
|
16254
16656
|
const dir = resolveJobDir(root, jobId);
|
|
16255
16657
|
const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
|
|
16256
16658
|
const sleep2 = opts?.sleep ?? sleepMs;
|
|
16257
|
-
if (!(0,
|
|
16659
|
+
if (!(0, import_node_fs43.existsSync)(dir)) {
|
|
16258
16660
|
return {
|
|
16259
16661
|
stillRunning: false,
|
|
16260
16662
|
ok: false,
|
|
@@ -16300,10 +16702,10 @@ function killProcessTree(pid, signal) {
|
|
|
16300
16702
|
}
|
|
16301
16703
|
function appendJobLog(logFile, line) {
|
|
16302
16704
|
try {
|
|
16303
|
-
(0,
|
|
16705
|
+
(0, import_node_fs43.mkdirSync)((0, import_node_path43.dirname)(logFile), { recursive: true });
|
|
16304
16706
|
const body = line.endsWith("\n") ? line : `${line}
|
|
16305
16707
|
`;
|
|
16306
|
-
(0,
|
|
16708
|
+
(0, import_node_fs43.appendFileSync)(logFile, body);
|
|
16307
16709
|
} catch {
|
|
16308
16710
|
}
|
|
16309
16711
|
}
|
|
@@ -16313,7 +16715,7 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
16313
16715
|
const dir = resolveJobDir(root, jobId);
|
|
16314
16716
|
const sleep2 = opts?.sleep ?? sleepMs;
|
|
16315
16717
|
const why = opts?.reason?.trim() ?? "";
|
|
16316
|
-
if (!(0,
|
|
16718
|
+
if (!(0, import_node_fs43.existsSync)(dir)) {
|
|
16317
16719
|
return {
|
|
16318
16720
|
stillRunning: false,
|
|
16319
16721
|
ok: false,
|
|
@@ -16349,10 +16751,10 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
16349
16751
|
killProcessTree(targetPid, "SIGKILL");
|
|
16350
16752
|
await sleep2(100);
|
|
16351
16753
|
}
|
|
16352
|
-
const exitFile = (0,
|
|
16353
|
-
if (!(0,
|
|
16754
|
+
const exitFile = (0, import_node_path43.join)(dir, "exit");
|
|
16755
|
+
if (!(0, import_node_fs43.existsSync)(exitFile)) {
|
|
16354
16756
|
try {
|
|
16355
|
-
(0,
|
|
16757
|
+
(0, import_node_fs43.writeFileSync)(exitFile, "1\n");
|
|
16356
16758
|
} catch {
|
|
16357
16759
|
}
|
|
16358
16760
|
}
|
|
@@ -16372,12 +16774,12 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
16372
16774
|
hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
|
|
16373
16775
|
};
|
|
16374
16776
|
}
|
|
16375
|
-
var
|
|
16777
|
+
var import_node_fs43, import_node_path43, MAX_JOB_CONTINUES, MAX_JOB_DELTA_LINES, MAX_JOB_DELTA_CHARS, DEFERRED_DONE_MAX_CHARS, GH_WATCH_REFRESH, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
|
|
16376
16778
|
var init_wait_for_job = __esm({
|
|
16377
16779
|
"src/mcp/wait-for-job.ts"() {
|
|
16378
16780
|
"use strict";
|
|
16379
|
-
|
|
16380
|
-
|
|
16781
|
+
import_node_fs43 = require("fs");
|
|
16782
|
+
import_node_path43 = require("path");
|
|
16381
16783
|
init_workspace_scratch();
|
|
16382
16784
|
init_wait_for_turn();
|
|
16383
16785
|
MAX_JOB_CONTINUES = 8;
|
|
@@ -17665,7 +18067,7 @@ function reuseLiveThread(input, repoPath, match) {
|
|
|
17665
18067
|
}
|
|
17666
18068
|
async function createThread(input, _onSetupLine) {
|
|
17667
18069
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
17668
|
-
if (!(0,
|
|
18070
|
+
if (!(0, import_node_fs44.existsSync)(repoPath)) {
|
|
17669
18071
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
17670
18072
|
}
|
|
17671
18073
|
const reused = reuseLiveThread(input, repoPath, {
|
|
@@ -17850,11 +18252,11 @@ async function listLinearIssues(agent, repoPath) {
|
|
|
17850
18252
|
}
|
|
17851
18253
|
return adapter.listLinearIssues(repoPath);
|
|
17852
18254
|
}
|
|
17853
|
-
var
|
|
18255
|
+
var import_node_fs44;
|
|
17854
18256
|
var init_create = __esm({
|
|
17855
18257
|
"src/threads/create.ts"() {
|
|
17856
18258
|
"use strict";
|
|
17857
|
-
|
|
18259
|
+
import_node_fs44 = require("fs");
|
|
17858
18260
|
init_detect();
|
|
17859
18261
|
init_worktree();
|
|
17860
18262
|
init_home_board();
|
|
@@ -17974,20 +18376,20 @@ function writeTurnLive(threadId, progress) {
|
|
|
17974
18376
|
const path2 = threadLivePath(threadId);
|
|
17975
18377
|
const tmp = `${path2}.${process.pid}.tmp`;
|
|
17976
18378
|
try {
|
|
17977
|
-
(0,
|
|
17978
|
-
(0,
|
|
18379
|
+
(0, import_node_fs45.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
|
|
18380
|
+
(0, import_node_fs45.renameSync)(tmp, path2);
|
|
17979
18381
|
} catch {
|
|
17980
18382
|
try {
|
|
17981
|
-
(0,
|
|
18383
|
+
(0, import_node_fs45.unlinkSync)(tmp);
|
|
17982
18384
|
} catch {
|
|
17983
18385
|
}
|
|
17984
18386
|
}
|
|
17985
18387
|
}
|
|
17986
18388
|
function readTurnLive(threadId) {
|
|
17987
18389
|
const path2 = threadLivePath(threadId);
|
|
17988
|
-
if (!(0,
|
|
18390
|
+
if (!(0, import_node_fs45.existsSync)(path2)) return null;
|
|
17989
18391
|
try {
|
|
17990
|
-
const raw = JSON.parse((0,
|
|
18392
|
+
const raw = JSON.parse((0, import_node_fs45.readFileSync)(path2, "utf8"));
|
|
17991
18393
|
if (!raw || typeof raw.summary !== "string") return null;
|
|
17992
18394
|
return raw;
|
|
17993
18395
|
} catch {
|
|
@@ -17999,17 +18401,17 @@ function clearTurnLive(threadId) {
|
|
|
17999
18401
|
if (buf?.timer) clearTimeout(buf.timer);
|
|
18000
18402
|
buffers.delete(threadId);
|
|
18001
18403
|
const path2 = threadLivePath(threadId);
|
|
18002
|
-
if (!(0,
|
|
18404
|
+
if (!(0, import_node_fs45.existsSync)(path2)) return;
|
|
18003
18405
|
try {
|
|
18004
|
-
(0,
|
|
18406
|
+
(0, import_node_fs45.unlinkSync)(path2);
|
|
18005
18407
|
} catch {
|
|
18006
18408
|
}
|
|
18007
18409
|
}
|
|
18008
|
-
var
|
|
18410
|
+
var import_node_fs45, buffers, FLUSH_MS, MAX_PARTS;
|
|
18009
18411
|
var init_turn_live = __esm({
|
|
18010
18412
|
"src/store/turn-live.ts"() {
|
|
18011
18413
|
"use strict";
|
|
18012
|
-
|
|
18414
|
+
import_node_fs45 = require("fs");
|
|
18013
18415
|
init_message_parts();
|
|
18014
18416
|
init_paths();
|
|
18015
18417
|
buffers = /* @__PURE__ */ new Map();
|
|
@@ -18229,7 +18631,7 @@ var init_quota_failover = __esm({
|
|
|
18229
18631
|
// src/threads/adopt.ts
|
|
18230
18632
|
function thisModuleFile() {
|
|
18231
18633
|
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
18232
|
-
return cjsFile || process.argv[1] || (0,
|
|
18634
|
+
return cjsFile || process.argv[1] || (0, import_node_path44.join)(process.cwd(), "package.json");
|
|
18233
18635
|
}
|
|
18234
18636
|
function openReadonlySqlite(file) {
|
|
18235
18637
|
const req = (0, import_node_module4.createRequire)(thisModuleFile());
|
|
@@ -18247,21 +18649,21 @@ function mapAgentType(raw) {
|
|
|
18247
18649
|
return null;
|
|
18248
18650
|
}
|
|
18249
18651
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
18250
|
-
if (!workspacePath || !(0,
|
|
18652
|
+
if (!workspacePath || !(0, import_node_fs46.existsSync)(CURSOR_SDK_STORE)) return null;
|
|
18251
18653
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
18252
18654
|
let best = null;
|
|
18253
18655
|
let hashes;
|
|
18254
18656
|
try {
|
|
18255
|
-
hashes = (0,
|
|
18657
|
+
hashes = (0, import_node_fs46.readdirSync)(CURSOR_SDK_STORE);
|
|
18256
18658
|
} catch {
|
|
18257
18659
|
return null;
|
|
18258
18660
|
}
|
|
18259
18661
|
for (const hash of hashes) {
|
|
18260
|
-
const agentsFile = (0,
|
|
18261
|
-
if (!(0,
|
|
18662
|
+
const agentsFile = (0, import_node_path44.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
18663
|
+
if (!(0, import_node_fs46.existsSync)(agentsFile)) continue;
|
|
18262
18664
|
let text7;
|
|
18263
18665
|
try {
|
|
18264
|
-
text7 = (0,
|
|
18666
|
+
text7 = (0, import_node_fs46.readFileSync)(agentsFile, "utf8");
|
|
18265
18667
|
} catch {
|
|
18266
18668
|
continue;
|
|
18267
18669
|
}
|
|
@@ -18285,7 +18687,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
18285
18687
|
return best?.agentId ?? null;
|
|
18286
18688
|
}
|
|
18287
18689
|
async function adoptThread(input) {
|
|
18288
|
-
if (!(0,
|
|
18690
|
+
if (!(0, import_node_fs46.existsSync)(input.worktreePath)) {
|
|
18289
18691
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
18290
18692
|
}
|
|
18291
18693
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -18314,18 +18716,18 @@ function conductorDbPath() {
|
|
|
18314
18716
|
return CONDUCTOR_DB;
|
|
18315
18717
|
}
|
|
18316
18718
|
function listConductorWorkspaces() {
|
|
18317
|
-
if (!(0,
|
|
18719
|
+
if (!(0, import_node_fs46.existsSync)(CONDUCTOR_DB)) {
|
|
18318
18720
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
18319
18721
|
}
|
|
18320
|
-
const tmp = (0,
|
|
18321
|
-
const snapshot = (0,
|
|
18722
|
+
const tmp = (0, import_node_fs46.mkdtempSync)((0, import_node_path44.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
|
|
18723
|
+
const snapshot = (0, import_node_path44.join)(tmp, "conductor.db");
|
|
18322
18724
|
try {
|
|
18323
|
-
(0,
|
|
18725
|
+
(0, import_node_fs46.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
18324
18726
|
for (const suffix of ["-wal", "-shm"]) {
|
|
18325
18727
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
18326
|
-
if ((0,
|
|
18728
|
+
if ((0, import_node_fs46.existsSync)(src)) {
|
|
18327
18729
|
try {
|
|
18328
|
-
(0,
|
|
18730
|
+
(0, import_node_fs46.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
18329
18731
|
} catch {
|
|
18330
18732
|
}
|
|
18331
18733
|
}
|
|
@@ -18401,22 +18803,22 @@ function listConductorWorkspaces() {
|
|
|
18401
18803
|
db.close();
|
|
18402
18804
|
}
|
|
18403
18805
|
} finally {
|
|
18404
|
-
(0,
|
|
18806
|
+
(0, import_node_fs46.rmSync)(tmp, { recursive: true, force: true });
|
|
18405
18807
|
}
|
|
18406
18808
|
}
|
|
18407
18809
|
function importConductorWorkspace(workspaceId) {
|
|
18408
|
-
if (!(0,
|
|
18810
|
+
if (!(0, import_node_fs46.existsSync)(CONDUCTOR_DB)) {
|
|
18409
18811
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
18410
18812
|
}
|
|
18411
|
-
const tmp = (0,
|
|
18412
|
-
const snapshot = (0,
|
|
18813
|
+
const tmp = (0, import_node_fs46.mkdtempSync)((0, import_node_path44.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
|
|
18814
|
+
const snapshot = (0, import_node_path44.join)(tmp, "conductor.db");
|
|
18413
18815
|
try {
|
|
18414
|
-
(0,
|
|
18816
|
+
(0, import_node_fs46.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
18415
18817
|
for (const suffix of ["-wal", "-shm"]) {
|
|
18416
18818
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
18417
|
-
if ((0,
|
|
18819
|
+
if ((0, import_node_fs46.existsSync)(src)) {
|
|
18418
18820
|
try {
|
|
18419
|
-
(0,
|
|
18821
|
+
(0, import_node_fs46.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
18420
18822
|
} catch {
|
|
18421
18823
|
}
|
|
18422
18824
|
}
|
|
@@ -18434,7 +18836,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
18434
18836
|
).get(workspaceId);
|
|
18435
18837
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
18436
18838
|
const worktreePath = String(row.workspacePath);
|
|
18437
|
-
if (!(0,
|
|
18839
|
+
if (!(0, import_node_fs46.existsSync)(worktreePath)) {
|
|
18438
18840
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
18439
18841
|
}
|
|
18440
18842
|
let sessionId = null;
|
|
@@ -18497,31 +18899,31 @@ function importConductorWorkspace(workspaceId) {
|
|
|
18497
18899
|
db.close();
|
|
18498
18900
|
}
|
|
18499
18901
|
} finally {
|
|
18500
|
-
(0,
|
|
18902
|
+
(0, import_node_fs46.rmSync)(tmp, { recursive: true, force: true });
|
|
18501
18903
|
}
|
|
18502
18904
|
}
|
|
18503
18905
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
18504
18906
|
return importConductorWorkspace(workspaceId);
|
|
18505
18907
|
}
|
|
18506
|
-
var import_node_child_process5,
|
|
18908
|
+
var import_node_child_process5, import_node_fs46, import_node_os14, import_node_path44, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
|
|
18507
18909
|
var init_adopt = __esm({
|
|
18508
18910
|
"src/threads/adopt.ts"() {
|
|
18509
18911
|
"use strict";
|
|
18510
18912
|
import_node_child_process5 = require("child_process");
|
|
18511
|
-
|
|
18512
|
-
|
|
18513
|
-
|
|
18913
|
+
import_node_fs46 = require("fs");
|
|
18914
|
+
import_node_os14 = require("os");
|
|
18915
|
+
import_node_path44 = require("path");
|
|
18514
18916
|
import_node_module4 = require("module");
|
|
18515
18917
|
init_worktree();
|
|
18516
18918
|
init_thread_store();
|
|
18517
|
-
CONDUCTOR_APP_SUPPORT = (0,
|
|
18919
|
+
CONDUCTOR_APP_SUPPORT = (0, import_node_path44.join)(
|
|
18518
18920
|
process.env.HOME ?? "",
|
|
18519
18921
|
"Library",
|
|
18520
18922
|
"Application Support",
|
|
18521
18923
|
"com.conductor.app"
|
|
18522
18924
|
);
|
|
18523
|
-
CONDUCTOR_DB = (0,
|
|
18524
|
-
CURSOR_SDK_STORE = (0,
|
|
18925
|
+
CONDUCTOR_DB = (0, import_node_path44.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
18926
|
+
CURSOR_SDK_STORE = (0, import_node_path44.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
18525
18927
|
}
|
|
18526
18928
|
});
|
|
18527
18929
|
|
|
@@ -18588,7 +18990,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
18588
18990
|
let createdWorktree = false;
|
|
18589
18991
|
const trees = await listWorktrees(repoPath);
|
|
18590
18992
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
18591
|
-
if (checkedOut?.path && (0,
|
|
18993
|
+
if (checkedOut?.path && (0, import_node_fs47.existsSync)(checkedOut.path)) {
|
|
18592
18994
|
if (input.reuseExistingWorktree !== false) {
|
|
18593
18995
|
worktreePath = checkedOut.path;
|
|
18594
18996
|
} else {
|
|
@@ -18730,7 +19132,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
18730
19132
|
async function createPrStack(input, onSetupLine) {
|
|
18731
19133
|
await requireAgent(input.agent);
|
|
18732
19134
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
18733
|
-
if (!(0,
|
|
19135
|
+
if (!(0, import_node_fs47.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
18734
19136
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
18735
19137
|
const status = await detectGhStack(repoPath);
|
|
18736
19138
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -18797,7 +19199,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
18797
19199
|
}
|
|
18798
19200
|
}
|
|
18799
19201
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
18800
|
-
if (!claimed.has(bootstrap.worktreePath) && (0,
|
|
19202
|
+
if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs47.existsSync)(bootstrap.worktreePath)) {
|
|
18801
19203
|
try {
|
|
18802
19204
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
18803
19205
|
deleteBranch: bootstrap.branchName
|
|
@@ -18817,11 +19219,11 @@ function stackAgentDefaultsFrom(input) {
|
|
|
18817
19219
|
planMode: input.planMode
|
|
18818
19220
|
};
|
|
18819
19221
|
}
|
|
18820
|
-
var
|
|
19222
|
+
var import_node_fs47;
|
|
18821
19223
|
var init_stack_layers = __esm({
|
|
18822
19224
|
"src/threads/stack-layers.ts"() {
|
|
18823
19225
|
"use strict";
|
|
18824
|
-
|
|
19226
|
+
import_node_fs47 = require("fs");
|
|
18825
19227
|
init_detect();
|
|
18826
19228
|
init_run();
|
|
18827
19229
|
init_stack();
|
|
@@ -18834,7 +19236,7 @@ var init_stack_layers = __esm({
|
|
|
18834
19236
|
|
|
18835
19237
|
// src/diff/diff.ts
|
|
18836
19238
|
async function inspectGitWorktree(worktreePath) {
|
|
18837
|
-
if (!worktreePath || !(0,
|
|
19239
|
+
if (!worktreePath || !(0, import_node_fs48.existsSync)(worktreePath)) return "missing_worktree";
|
|
18838
19240
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
18839
19241
|
reject: false
|
|
18840
19242
|
});
|
|
@@ -18842,7 +19244,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
18842
19244
|
return "ok";
|
|
18843
19245
|
}
|
|
18844
19246
|
async function initializeGitRepository(worktreePath) {
|
|
18845
|
-
if (!worktreePath || !(0,
|
|
19247
|
+
if (!worktreePath || !(0, import_node_fs48.existsSync)(worktreePath)) {
|
|
18846
19248
|
throw new Error("Worktree not found");
|
|
18847
19249
|
}
|
|
18848
19250
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -18976,11 +19378,11 @@ new file mode 100644
|
|
|
18976
19378
|
};
|
|
18977
19379
|
}
|
|
18978
19380
|
async function untrackedPatch(worktreePath, path2, maxHunk) {
|
|
18979
|
-
const abs = (0,
|
|
19381
|
+
const abs = (0, import_node_path45.join)(worktreePath, path2);
|
|
18980
19382
|
try {
|
|
18981
|
-
const st = (0,
|
|
19383
|
+
const st = (0, import_node_fs48.statSync)(abs);
|
|
18982
19384
|
if (st.isFile() && st.size > maxHunk) {
|
|
18983
|
-
const buf = (0,
|
|
19385
|
+
const buf = (0, import_node_fs48.readFileSync)(abs).subarray(0, maxHunk);
|
|
18984
19386
|
return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
|
|
18985
19387
|
}
|
|
18986
19388
|
} catch {
|
|
@@ -19469,8 +19871,8 @@ function isImageRelativePath(relativePath) {
|
|
|
19469
19871
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
19470
19872
|
assertSafeRelativePath(relativePath);
|
|
19471
19873
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
19472
|
-
const abs = (0,
|
|
19473
|
-
const st = (0,
|
|
19874
|
+
const abs = (0, import_node_path45.join)(worktreePath, relativePath);
|
|
19875
|
+
const st = (0, import_node_fs48.statSync)(abs);
|
|
19474
19876
|
if (!st.isFile()) {
|
|
19475
19877
|
throw new Error(`Not a file: ${relativePath}`);
|
|
19476
19878
|
}
|
|
@@ -19479,7 +19881,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
19479
19881
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
19480
19882
|
);
|
|
19481
19883
|
}
|
|
19482
|
-
const buf = (0,
|
|
19884
|
+
const buf = (0, import_node_fs48.readFileSync)(abs);
|
|
19483
19885
|
return {
|
|
19484
19886
|
path: relativePath,
|
|
19485
19887
|
contentBase64: buf.toString("base64"),
|
|
@@ -19489,12 +19891,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
19489
19891
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
19490
19892
|
assertSafeRelativePath(relativePath);
|
|
19491
19893
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
19492
|
-
const abs = (0,
|
|
19493
|
-
const st = (0,
|
|
19894
|
+
const abs = (0, import_node_path45.join)(worktreePath, relativePath);
|
|
19895
|
+
const st = (0, import_node_fs48.statSync)(abs);
|
|
19494
19896
|
if (!st.isFile()) {
|
|
19495
19897
|
throw new Error(`Not a file: ${relativePath}`);
|
|
19496
19898
|
}
|
|
19497
|
-
const buf = (0,
|
|
19899
|
+
const buf = (0, import_node_fs48.readFileSync)(abs);
|
|
19498
19900
|
if (isImageRelativePath(relativePath)) {
|
|
19499
19901
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
19500
19902
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -19537,9 +19939,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
19537
19939
|
}
|
|
19538
19940
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
19539
19941
|
assertSafeRelativePath(relativePath);
|
|
19540
|
-
const abs = (0,
|
|
19541
|
-
(0,
|
|
19542
|
-
(0,
|
|
19942
|
+
const abs = (0, import_node_path45.join)(worktreePath, relativePath);
|
|
19943
|
+
(0, import_node_fs48.mkdirSync)((0, import_node_path45.dirname)(abs), { recursive: true });
|
|
19944
|
+
(0, import_node_fs48.writeFileSync)(abs, content, "utf8");
|
|
19543
19945
|
return { path: relativePath };
|
|
19544
19946
|
}
|
|
19545
19947
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -19556,12 +19958,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
|
19556
19958
|
truncated: full.files.length > maxFiles
|
|
19557
19959
|
};
|
|
19558
19960
|
}
|
|
19559
|
-
var
|
|
19961
|
+
var import_node_fs48, import_node_path45, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
|
|
19560
19962
|
var init_diff = __esm({
|
|
19561
19963
|
"src/diff/diff.ts"() {
|
|
19562
19964
|
"use strict";
|
|
19563
|
-
|
|
19564
|
-
|
|
19965
|
+
import_node_fs48 = require("fs");
|
|
19966
|
+
import_node_path45 = require("path");
|
|
19565
19967
|
init_run();
|
|
19566
19968
|
init_worktree();
|
|
19567
19969
|
mergeBaseCache = /* @__PURE__ */ new Map();
|
|
@@ -19918,7 +20320,7 @@ function parseFrontmatter(content) {
|
|
|
19918
20320
|
}
|
|
19919
20321
|
function readSkill(skillMd, source) {
|
|
19920
20322
|
try {
|
|
19921
|
-
const content = (0,
|
|
20323
|
+
const content = (0, import_node_fs49.readFileSync)(skillMd, "utf8");
|
|
19922
20324
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
19923
20325
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
19924
20326
|
const name = fmName || dirName;
|
|
@@ -19937,19 +20339,19 @@ function readSkill(skillMd, source) {
|
|
|
19937
20339
|
}
|
|
19938
20340
|
}
|
|
19939
20341
|
function scanSkillsDir(dir, source, out) {
|
|
19940
|
-
if (!(0,
|
|
20342
|
+
if (!(0, import_node_fs49.existsSync)(dir)) return;
|
|
19941
20343
|
let entries;
|
|
19942
20344
|
try {
|
|
19943
|
-
entries = (0,
|
|
20345
|
+
entries = (0, import_node_fs49.readdirSync)(dir);
|
|
19944
20346
|
} catch {
|
|
19945
20347
|
return;
|
|
19946
20348
|
}
|
|
19947
20349
|
for (const entry of entries) {
|
|
19948
20350
|
if (entry.startsWith(".")) continue;
|
|
19949
|
-
const skillMd = (0,
|
|
19950
|
-
if (!(0,
|
|
20351
|
+
const skillMd = (0, import_node_path46.join)(dir, entry, "SKILL.md");
|
|
20352
|
+
if (!(0, import_node_fs49.existsSync)(skillMd)) continue;
|
|
19951
20353
|
try {
|
|
19952
|
-
if (!(0,
|
|
20354
|
+
if (!(0, import_node_fs49.statSync)(skillMd).isFile()) continue;
|
|
19953
20355
|
} catch {
|
|
19954
20356
|
continue;
|
|
19955
20357
|
}
|
|
@@ -19958,24 +20360,24 @@ function scanSkillsDir(dir, source, out) {
|
|
|
19958
20360
|
}
|
|
19959
20361
|
}
|
|
19960
20362
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
19961
|
-
if (!(0,
|
|
20363
|
+
if (!(0, import_node_fs49.existsSync)(pluginsRoot)) return;
|
|
19962
20364
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
19963
20365
|
if (depth > 7) return;
|
|
19964
20366
|
let entries;
|
|
19965
20367
|
try {
|
|
19966
|
-
entries = (0,
|
|
20368
|
+
entries = (0, import_node_fs49.readdirSync)(dir);
|
|
19967
20369
|
} catch {
|
|
19968
20370
|
return;
|
|
19969
20371
|
}
|
|
19970
20372
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
19971
|
-
const skill = readSkill((0,
|
|
20373
|
+
const skill = readSkill((0, import_node_path46.join)(dir, "SKILL.md"), "cli");
|
|
19972
20374
|
if (skill) out.push(skill);
|
|
19973
20375
|
}
|
|
19974
20376
|
for (const entry of entries) {
|
|
19975
20377
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
19976
|
-
const full = (0,
|
|
20378
|
+
const full = (0, import_node_path46.join)(dir, entry);
|
|
19977
20379
|
try {
|
|
19978
|
-
if (!(0,
|
|
20380
|
+
if (!(0, import_node_fs49.statSync)(full).isDirectory()) continue;
|
|
19979
20381
|
} catch {
|
|
19980
20382
|
continue;
|
|
19981
20383
|
}
|
|
@@ -19990,20 +20392,20 @@ function scanClaudePluginSkills(pluginsRoot, out) {
|
|
|
19990
20392
|
walk(pluginsRoot, 0, false);
|
|
19991
20393
|
}
|
|
19992
20394
|
function discoverSkills(worktreePath) {
|
|
19993
|
-
const home = (0,
|
|
20395
|
+
const home = (0, import_node_os15.homedir)();
|
|
19994
20396
|
const collected = [];
|
|
19995
20397
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
19996
|
-
scanSkillsDir((0,
|
|
20398
|
+
scanSkillsDir((0, import_node_path46.join)(worktreePath, rel), "workspace", collected);
|
|
19997
20399
|
}
|
|
19998
20400
|
for (const abs of [
|
|
19999
|
-
(0,
|
|
20000
|
-
(0,
|
|
20001
|
-
(0,
|
|
20002
|
-
(0,
|
|
20401
|
+
(0, import_node_path46.join)(home, ".claude/skills"),
|
|
20402
|
+
(0, import_node_path46.join)(home, ".cursor/skills"),
|
|
20403
|
+
(0, import_node_path46.join)(home, ".sideboard/skills"),
|
|
20404
|
+
(0, import_node_path46.join)(home, ".brightsy/skills")
|
|
20003
20405
|
]) {
|
|
20004
20406
|
scanSkillsDir(abs, "user", collected);
|
|
20005
20407
|
}
|
|
20006
|
-
scanClaudePluginSkills((0,
|
|
20408
|
+
scanClaudePluginSkills((0, import_node_path46.join)(home, ".claude/plugins"), collected);
|
|
20007
20409
|
collected.push(...bundledSkills());
|
|
20008
20410
|
const rank = {
|
|
20009
20411
|
workspace: 0,
|
|
@@ -20029,7 +20431,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
20029
20431
|
\u2026(truncated)` : body;
|
|
20030
20432
|
}
|
|
20031
20433
|
}
|
|
20032
|
-
const raw = (0,
|
|
20434
|
+
const raw = (0, import_node_fs49.readFileSync)(skillPath, "utf8");
|
|
20033
20435
|
if (raw.startsWith("---")) {
|
|
20034
20436
|
const end = raw.indexOf("\n---", 3);
|
|
20035
20437
|
if (end >= 0) {
|
|
@@ -20043,13 +20445,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
20043
20445
|
|
|
20044
20446
|
\u2026(truncated)` : raw;
|
|
20045
20447
|
}
|
|
20046
|
-
var
|
|
20448
|
+
var import_node_fs49, import_node_os15, import_node_path46, BUNDLED_SKILL_PREFIX;
|
|
20047
20449
|
var init_discover = __esm({
|
|
20048
20450
|
"src/skills/discover.ts"() {
|
|
20049
20451
|
"use strict";
|
|
20050
|
-
|
|
20051
|
-
|
|
20052
|
-
|
|
20452
|
+
import_node_fs49 = require("fs");
|
|
20453
|
+
import_node_os15 = require("os");
|
|
20454
|
+
import_node_path46 = require("path");
|
|
20053
20455
|
init_long_running();
|
|
20054
20456
|
BUNDLED_SKILL_PREFIX = "bundled:";
|
|
20055
20457
|
}
|
|
@@ -20143,8 +20545,8 @@ var init_expand = __esm({
|
|
|
20143
20545
|
// src/skills/detached-job-path.ts
|
|
20144
20546
|
function detachedJobScriptIn(dir) {
|
|
20145
20547
|
for (const name of DETACHED_JOB_FILENAMES) {
|
|
20146
|
-
const script = (0,
|
|
20147
|
-
if ((0,
|
|
20548
|
+
const script = (0, import_node_path47.join)(dir, "scripts", name);
|
|
20549
|
+
if ((0, import_node_fs50.existsSync)(script)) return script;
|
|
20148
20550
|
}
|
|
20149
20551
|
return null;
|
|
20150
20552
|
}
|
|
@@ -20156,11 +20558,11 @@ function packagedDetachedJobPath() {
|
|
|
20156
20558
|
function resolveDetachedJobScript() {
|
|
20157
20559
|
const packaged = packagedDetachedJobPath();
|
|
20158
20560
|
if (packaged) return packaged;
|
|
20159
|
-
let dir = (0,
|
|
20561
|
+
let dir = (0, import_node_path47.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
|
|
20160
20562
|
for (let i = 0; i < 8; i++) {
|
|
20161
20563
|
const candidate = detachedJobScriptIn(dir);
|
|
20162
20564
|
if (candidate) return candidate;
|
|
20163
|
-
const parent = (0,
|
|
20565
|
+
const parent = (0, import_node_path47.dirname)(dir);
|
|
20164
20566
|
if (parent === dir) break;
|
|
20165
20567
|
dir = parent;
|
|
20166
20568
|
}
|
|
@@ -20171,12 +20573,12 @@ function formatDetachedJobInvoke(scriptPath) {
|
|
|
20171
20573
|
if (resolved) return `node ${JSON.stringify(resolved)}`;
|
|
20172
20574
|
return "node scripts/detached-job.cjs";
|
|
20173
20575
|
}
|
|
20174
|
-
var
|
|
20576
|
+
var import_node_fs50, import_node_path47, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
|
|
20175
20577
|
var init_detached_job_path = __esm({
|
|
20176
20578
|
"src/skills/detached-job-path.ts"() {
|
|
20177
20579
|
"use strict";
|
|
20178
|
-
|
|
20179
|
-
|
|
20580
|
+
import_node_fs50 = require("fs");
|
|
20581
|
+
import_node_path47 = require("path");
|
|
20180
20582
|
import_node_url3 = require("url");
|
|
20181
20583
|
init_packaged_runtime();
|
|
20182
20584
|
import_meta3 = {};
|
|
@@ -20358,9 +20760,9 @@ function formatPrGateDirective() {
|
|
|
20358
20760
|
}
|
|
20359
20761
|
function formatProcessGuideDirective(opts) {
|
|
20360
20762
|
const worktree = opts?.worktreePath?.trim();
|
|
20361
|
-
const hasGraphSkill = !!worktree && (0,
|
|
20362
|
-
const hasReviewSkill = !!worktree && (0,
|
|
20363
|
-
const hasInstallSkill = !!worktree && (0,
|
|
20763
|
+
const hasGraphSkill = !!worktree && (0, import_node_fs51.existsSync)((0, import_node_path48.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
|
|
20764
|
+
const hasReviewSkill = !!worktree && (0, import_node_fs51.existsSync)((0, import_node_path48.join)(worktree, ".claude/skills/review/SKILL.md"));
|
|
20765
|
+
const hasInstallSkill = !!worktree && (0, import_node_fs51.existsSync)((0, import_node_path48.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
|
|
20364
20766
|
return [
|
|
20365
20767
|
"Process guides (recurring work only):",
|
|
20366
20768
|
hasGraphSkill ? "- Migrations, ports, batch fixes, and other fan-out: follow `.claude/skills/graph-engineering/SKILL.md` (`/graph-engineering`). Judge first; state on disk; grow the rulebook; do not patch around it." : null,
|
|
@@ -20398,12 +20800,12 @@ function formatArtifactDirective() {
|
|
|
20398
20800
|
function formatUiReminder() {
|
|
20399
20801
|
return "Sideboard UI: markdown table is enough to read data; present_schema if they ask to edit/filter (even after markdown); present_files for the file manager. html fence or present_artifact, not both for the same document. type=log appends (same artifact_id, new lines only). ask_user only for a real multiple-choice (not hellos, \u201Cwhat next?\u201D, or after a review) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable.";
|
|
20400
20802
|
}
|
|
20401
|
-
var
|
|
20803
|
+
var import_node_fs51, import_node_path48, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
|
|
20402
20804
|
var init_instructions = __esm({
|
|
20403
20805
|
"src/agents/instructions.ts"() {
|
|
20404
20806
|
"use strict";
|
|
20405
|
-
|
|
20406
|
-
|
|
20807
|
+
import_node_fs51 = require("fs");
|
|
20808
|
+
import_node_path48 = require("path");
|
|
20407
20809
|
init_git_auth_mode();
|
|
20408
20810
|
init_branch_prefix();
|
|
20409
20811
|
init_worktree_labels();
|
|
@@ -20789,40 +21191,40 @@ __export(plan_file_exports, {
|
|
|
20789
21191
|
writePlanFile: () => writePlanFile
|
|
20790
21192
|
});
|
|
20791
21193
|
function ensureAttachmentsGitignore(worktreePath) {
|
|
20792
|
-
const gitignoreAbs = (0,
|
|
20793
|
-
if ((0,
|
|
20794
|
-
(0,
|
|
20795
|
-
(0,
|
|
21194
|
+
const gitignoreAbs = (0, import_node_path49.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
21195
|
+
if ((0, import_node_fs52.existsSync)(gitignoreAbs)) return;
|
|
21196
|
+
(0, import_node_fs52.mkdirSync)((0, import_node_path49.dirname)(gitignoreAbs), { recursive: true });
|
|
21197
|
+
(0, import_node_fs52.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
20796
21198
|
}
|
|
20797
21199
|
function planFileAbs(worktreePath) {
|
|
20798
|
-
return (0,
|
|
21200
|
+
return (0, import_node_path49.join)(worktreePath, PLAN_FILE_REL);
|
|
20799
21201
|
}
|
|
20800
21202
|
function readTextIfPresent2(abs) {
|
|
20801
|
-
if (!(0,
|
|
21203
|
+
if (!(0, import_node_fs52.existsSync)(abs)) return null;
|
|
20802
21204
|
try {
|
|
20803
|
-
const content = (0,
|
|
21205
|
+
const content = (0, import_node_fs52.readFileSync)(abs, "utf8");
|
|
20804
21206
|
return content.trim() ? content : null;
|
|
20805
21207
|
} catch {
|
|
20806
21208
|
return null;
|
|
20807
21209
|
}
|
|
20808
21210
|
}
|
|
20809
21211
|
function readPlanFile(worktreePath) {
|
|
20810
|
-
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0,
|
|
21212
|
+
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path49.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path49.join)(worktreePath, LEGACY_PLAN_FILE_REL));
|
|
20811
21213
|
}
|
|
20812
21214
|
function writePlanFile(worktreePath, content) {
|
|
20813
21215
|
ensureAttachmentsGitignore(worktreePath);
|
|
20814
21216
|
const abs = planFileAbs(worktreePath);
|
|
20815
|
-
(0,
|
|
21217
|
+
(0, import_node_fs52.mkdirSync)((0, import_node_path49.dirname)(abs), { recursive: true });
|
|
20816
21218
|
const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
|
|
20817
|
-
(0,
|
|
21219
|
+
(0, import_node_fs52.writeFileSync)(abs, body, "utf8");
|
|
20818
21220
|
return PLAN_FILE_REL;
|
|
20819
21221
|
}
|
|
20820
|
-
var
|
|
21222
|
+
var import_node_fs52, import_node_path49;
|
|
20821
21223
|
var init_plan_file = __esm({
|
|
20822
21224
|
"src/plan/plan-file.ts"() {
|
|
20823
21225
|
"use strict";
|
|
20824
|
-
|
|
20825
|
-
|
|
21226
|
+
import_node_fs52 = require("fs");
|
|
21227
|
+
import_node_path49 = require("path");
|
|
20826
21228
|
init_workspace_scratch();
|
|
20827
21229
|
init_plan_present();
|
|
20828
21230
|
init_plan_present();
|
|
@@ -20870,13 +21272,13 @@ var init_sync_branch = __esm({
|
|
|
20870
21272
|
|
|
20871
21273
|
// src/agents/cursor-store.ts
|
|
20872
21274
|
function cursorSdkStoreDir(threadId) {
|
|
20873
|
-
const root = (0,
|
|
21275
|
+
const root = (0, import_node_path50.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
|
|
20874
21276
|
const id = sanitizeCursorStoreSegment(threadId);
|
|
20875
21277
|
if (!id) return root;
|
|
20876
|
-
return (0,
|
|
21278
|
+
return (0, import_node_path50.join)(root, "threads", id);
|
|
20877
21279
|
}
|
|
20878
21280
|
function cursorSdkRunsNdjsonPath(threadId) {
|
|
20879
|
-
return (0,
|
|
21281
|
+
return (0, import_node_path50.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
|
|
20880
21282
|
}
|
|
20881
21283
|
function cursorSdkRunsNdjsonSearchPaths(threadId) {
|
|
20882
21284
|
const scoped = cursorSdkRunsNdjsonPath(threadId);
|
|
@@ -20889,11 +21291,11 @@ function cursorSdkRunsNdjsonSearchPaths(threadId) {
|
|
|
20889
21291
|
function sanitizeCursorStoreSegment(threadId) {
|
|
20890
21292
|
return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
20891
21293
|
}
|
|
20892
|
-
var
|
|
21294
|
+
var import_node_path50, CURSOR_SDK_STORE_DIR;
|
|
20893
21295
|
var init_cursor_store = __esm({
|
|
20894
21296
|
"src/agents/cursor-store.ts"() {
|
|
20895
21297
|
"use strict";
|
|
20896
|
-
|
|
21298
|
+
import_node_path50 = require("path");
|
|
20897
21299
|
init_paths();
|
|
20898
21300
|
CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
|
|
20899
21301
|
}
|
|
@@ -20915,9 +21317,9 @@ function recoverFinishedCursorRun(opts) {
|
|
|
20915
21317
|
return best;
|
|
20916
21318
|
}
|
|
20917
21319
|
function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
|
|
20918
|
-
if (!(0,
|
|
21320
|
+
if (!(0, import_node_fs53.existsSync)(runsPath)) return null;
|
|
20919
21321
|
try {
|
|
20920
|
-
const lines = (0,
|
|
21322
|
+
const lines = (0, import_node_fs53.readFileSync)(runsPath, "utf8").split("\n");
|
|
20921
21323
|
let best = null;
|
|
20922
21324
|
for (const line of lines) {
|
|
20923
21325
|
const trimmed = line.trim();
|
|
@@ -20943,11 +21345,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
|
|
|
20943
21345
|
return null;
|
|
20944
21346
|
}
|
|
20945
21347
|
}
|
|
20946
|
-
var
|
|
21348
|
+
var import_node_fs53;
|
|
20947
21349
|
var init_cursor_recover = __esm({
|
|
20948
21350
|
"src/agents/cursor-recover.ts"() {
|
|
20949
21351
|
"use strict";
|
|
20950
|
-
|
|
21352
|
+
import_node_fs53 = require("fs");
|
|
20951
21353
|
init_cursor_store();
|
|
20952
21354
|
}
|
|
20953
21355
|
});
|
|
@@ -21094,13 +21496,13 @@ async function startOrchestration(opts) {
|
|
|
21094
21496
|
}
|
|
21095
21497
|
return updated;
|
|
21096
21498
|
}
|
|
21097
|
-
var import_node_events,
|
|
21499
|
+
var import_node_events, import_node_fs54, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
|
|
21098
21500
|
var init_orchestrator = __esm({
|
|
21099
21501
|
"src/orchestrator/orchestrator.ts"() {
|
|
21100
21502
|
"use strict";
|
|
21101
21503
|
import_node_events = require("events");
|
|
21102
21504
|
init_outbound_watch();
|
|
21103
|
-
|
|
21505
|
+
import_node_fs54 = require("fs");
|
|
21104
21506
|
init_error_detail();
|
|
21105
21507
|
init_run();
|
|
21106
21508
|
init_stale_lock();
|
|
@@ -21274,7 +21676,7 @@ var init_orchestrator = __esm({
|
|
|
21274
21676
|
}
|
|
21275
21677
|
continue;
|
|
21276
21678
|
}
|
|
21277
|
-
if (!(0,
|
|
21679
|
+
if (!(0, import_node_fs54.existsSync)(thread.worktreePath)) {
|
|
21278
21680
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
21279
21681
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
21280
21682
|
continue;
|
|
@@ -23221,7 +23623,7 @@ var init_orchestrator = __esm({
|
|
|
23221
23623
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
23222
23624
|
return restored2;
|
|
23223
23625
|
}
|
|
23224
|
-
if (!(0,
|
|
23626
|
+
if (!(0, import_node_fs54.existsSync)(thread.worktreePath)) {
|
|
23225
23627
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
23226
23628
|
throw new Error(
|
|
23227
23629
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
@@ -23594,6 +23996,7 @@ __export(index_exports, {
|
|
|
23594
23996
|
classifyWorktreeColumn: () => classifyWorktreeColumn,
|
|
23595
23997
|
claudeAdapter: () => claudeAdapter,
|
|
23596
23998
|
claudeChromeEnabled: () => claudeChromeEnabled,
|
|
23999
|
+
claudeUsageOverLimitWindows: () => claudeUsageOverLimitWindows,
|
|
23597
24000
|
claudeUserSettingsPath: () => claudeUserSettingsPath,
|
|
23598
24001
|
cleanupOrphanWorktrees: () => cleanupOrphanWorktrees,
|
|
23599
24002
|
clearBoardPins: () => clearBoardPins,
|
|
@@ -23613,6 +24016,7 @@ __export(index_exports, {
|
|
|
23613
24016
|
computeNextRunAt: () => computeNextRunAt,
|
|
23614
24017
|
conductorBundledBinDir: () => conductorBundledBinDir,
|
|
23615
24018
|
conductorDbPath: () => conductorDbPath,
|
|
24019
|
+
confirmClaudeUsageOverLimitEnabled: () => confirmClaudeUsageOverLimitEnabled,
|
|
23616
24020
|
confirmLand: () => confirmLand,
|
|
23617
24021
|
connectBrightsyTeam: () => connectBrightsyTeam,
|
|
23618
24022
|
connectOptionalService: () => connectOptionalService,
|
|
@@ -23712,6 +24116,13 @@ __export(index_exports, {
|
|
|
23712
24116
|
formatAccountProfilePlaybookLine: () => formatAccountProfilePlaybookLine,
|
|
23713
24117
|
formatArtifactDirective: () => formatArtifactDirective,
|
|
23714
24118
|
formatBrightsyFetchError: () => formatBrightsyFetchError,
|
|
24119
|
+
formatClaudeExtraUsageDetail: () => formatClaudeExtraUsageDetail,
|
|
24120
|
+
formatClaudeUsageCompact: () => formatClaudeUsageCompact,
|
|
24121
|
+
formatClaudeUsageFetchedAt: () => formatClaudeUsageFetchedAt,
|
|
24122
|
+
formatClaudeUsageOverLimitConfirm: () => formatClaudeUsageOverLimitConfirm,
|
|
24123
|
+
formatClaudeUsageReset: () => formatClaudeUsageReset,
|
|
24124
|
+
formatClaudeUsageResetClock: () => formatClaudeUsageResetClock,
|
|
24125
|
+
formatClaudeUsageTooltip: () => formatClaudeUsageTooltip,
|
|
23715
24126
|
formatDetachedJobInvoke: () => formatDetachedJobInvoke,
|
|
23716
24127
|
formatFetchError: () => formatFetchError,
|
|
23717
24128
|
formatGhLandError: () => formatGhLandError,
|
|
@@ -23761,6 +24172,7 @@ __export(index_exports, {
|
|
|
23761
24172
|
getAgentSetupInfo: () => getAgentSetupInfo,
|
|
23762
24173
|
getBrightsySession: () => getBrightsySession,
|
|
23763
24174
|
getCaffeinateHold: () => getCaffeinateHold,
|
|
24175
|
+
getClaudePlanUsage: () => getClaudePlanUsage,
|
|
23764
24176
|
getDefaultAgent: () => getDefaultAgent,
|
|
23765
24177
|
getDefaultEffort: () => getDefaultEffort,
|
|
23766
24178
|
getDefaultFast: () => getDefaultFast,
|
|
@@ -23810,6 +24222,7 @@ __export(index_exports, {
|
|
|
23810
24222
|
hasRepoHook: () => hasRepoHook,
|
|
23811
24223
|
hasWorkspaceHook: () => hasWorkspaceHook,
|
|
23812
24224
|
healOrchestrationSoccerTitles: () => healOrchestrationSoccerTitles,
|
|
24225
|
+
hottestClaudeWindow: () => hottestClaudeWindow,
|
|
23813
24226
|
httpFetch: () => httpFetch,
|
|
23814
24227
|
importConductorWorkspace: () => importConductorWorkspace,
|
|
23815
24228
|
importConductorWorkspaceAsync: () => importConductorWorkspaceAsync,
|
|
@@ -23973,6 +24386,7 @@ __export(index_exports, {
|
|
|
23973
24386
|
originFetchBranch: () => originFetchBranch,
|
|
23974
24387
|
originGhRepoEnv: () => originGhRepoEnv,
|
|
23975
24388
|
packagedDetachedJobPath: () => packagedDetachedJobPath,
|
|
24389
|
+
parseClaudeUsagePayload: () => parseClaudeUsagePayload,
|
|
23976
24390
|
parseCursorRunnerLine: () => parseCursorRunnerLine,
|
|
23977
24391
|
parseDurationMs: () => parseDurationMs,
|
|
23978
24392
|
parseForceStopMessage: () => parseForceStopMessage,
|
|
@@ -26555,7 +26969,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
|
26555
26969
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
26556
26970
|
var import_zod9 = require("zod");
|
|
26557
26971
|
var import_node_crypto14 = require("crypto");
|
|
26558
|
-
var
|
|
26972
|
+
var import_node_path53 = require("path");
|
|
26559
26973
|
init_orchestrator();
|
|
26560
26974
|
init_worktree();
|
|
26561
26975
|
init_global_workspace();
|
|
@@ -28275,27 +28689,27 @@ init_gh_errors();
|
|
|
28275
28689
|
init_git_auth_mode();
|
|
28276
28690
|
|
|
28277
28691
|
// src/board/load-home-board.ts
|
|
28278
|
-
var
|
|
28279
|
-
var
|
|
28692
|
+
var import_node_fs56 = require("fs");
|
|
28693
|
+
var import_node_path52 = require("path");
|
|
28280
28694
|
init_worktree();
|
|
28281
28695
|
init_paths();
|
|
28282
28696
|
|
|
28283
28697
|
// src/board/board-pins.ts
|
|
28284
28698
|
var import_node_crypto13 = require("crypto");
|
|
28285
|
-
var
|
|
28286
|
-
var
|
|
28699
|
+
var import_node_fs55 = require("fs");
|
|
28700
|
+
var import_node_path51 = require("path");
|
|
28287
28701
|
init_paths();
|
|
28288
28702
|
init_home_board();
|
|
28289
28703
|
var FILE = "home-board-pins.json";
|
|
28290
28704
|
var VERSION = 1;
|
|
28291
28705
|
function pinsFile() {
|
|
28292
|
-
return (0,
|
|
28706
|
+
return (0, import_node_path51.join)(appDataDir(), FILE);
|
|
28293
28707
|
}
|
|
28294
28708
|
function readDisk() {
|
|
28295
28709
|
const path2 = pinsFile();
|
|
28296
|
-
if (!(0,
|
|
28710
|
+
if (!(0, import_node_fs55.existsSync)(path2)) return [];
|
|
28297
28711
|
try {
|
|
28298
|
-
const raw = JSON.parse((0,
|
|
28712
|
+
const raw = JSON.parse((0, import_node_fs55.readFileSync)(path2, "utf8"));
|
|
28299
28713
|
if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
|
|
28300
28714
|
return raw.items.filter((item) => item?.id && item.kind && item.ref);
|
|
28301
28715
|
} catch {
|
|
@@ -28303,8 +28717,8 @@ function readDisk() {
|
|
|
28303
28717
|
}
|
|
28304
28718
|
}
|
|
28305
28719
|
function writeDisk(items) {
|
|
28306
|
-
(0,
|
|
28307
|
-
(0,
|
|
28720
|
+
(0, import_node_fs55.mkdirSync)(appDataDir(), { recursive: true });
|
|
28721
|
+
(0, import_node_fs55.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
|
|
28308
28722
|
}
|
|
28309
28723
|
function listBoardPins() {
|
|
28310
28724
|
return readDisk();
|
|
@@ -28356,7 +28770,7 @@ function replaceBoardPins(items) {
|
|
|
28356
28770
|
}
|
|
28357
28771
|
function clearBoardPins() {
|
|
28358
28772
|
try {
|
|
28359
|
-
(0,
|
|
28773
|
+
(0, import_node_fs55.unlinkSync)(pinsFile());
|
|
28360
28774
|
} catch {
|
|
28361
28775
|
}
|
|
28362
28776
|
}
|
|
@@ -28365,7 +28779,7 @@ function clearBoardPins() {
|
|
|
28365
28779
|
init_home_board();
|
|
28366
28780
|
var CACHE_VERSION = 1;
|
|
28367
28781
|
var memory2 = null;
|
|
28368
|
-
var
|
|
28782
|
+
var inflight2 = null;
|
|
28369
28783
|
function errText(err) {
|
|
28370
28784
|
return err instanceof Error ? err.message : String(err);
|
|
28371
28785
|
}
|
|
@@ -28373,7 +28787,7 @@ function homeBoardWorkspaceKey(workspaces) {
|
|
|
28373
28787
|
return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
|
|
28374
28788
|
}
|
|
28375
28789
|
function cacheFile() {
|
|
28376
|
-
return (0,
|
|
28790
|
+
return (0, import_node_path52.join)(appDataDir(), "home-board-cache.json");
|
|
28377
28791
|
}
|
|
28378
28792
|
function emptyInputs() {
|
|
28379
28793
|
return {
|
|
@@ -28399,9 +28813,9 @@ function shouldCacheHomeBoardInputs(inputs) {
|
|
|
28399
28813
|
}
|
|
28400
28814
|
function readDiskCache() {
|
|
28401
28815
|
const path2 = cacheFile();
|
|
28402
|
-
if (!(0,
|
|
28816
|
+
if (!(0, import_node_fs56.existsSync)(path2)) return null;
|
|
28403
28817
|
try {
|
|
28404
|
-
const raw = JSON.parse((0,
|
|
28818
|
+
const raw = JSON.parse((0, import_node_fs56.readFileSync)(path2, "utf8"));
|
|
28405
28819
|
if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
|
|
28406
28820
|
return null;
|
|
28407
28821
|
}
|
|
@@ -28415,20 +28829,20 @@ function readDiskCache() {
|
|
|
28415
28829
|
}
|
|
28416
28830
|
function writeDiskCache(entry) {
|
|
28417
28831
|
try {
|
|
28418
|
-
(0,
|
|
28419
|
-
(0,
|
|
28832
|
+
(0, import_node_fs56.mkdirSync)(appDataDir(), { recursive: true });
|
|
28833
|
+
(0, import_node_fs56.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
|
|
28420
28834
|
} catch {
|
|
28421
28835
|
}
|
|
28422
28836
|
}
|
|
28423
28837
|
function deleteDiskCache() {
|
|
28424
28838
|
try {
|
|
28425
|
-
(0,
|
|
28839
|
+
(0, import_node_fs56.unlinkSync)(cacheFile());
|
|
28426
28840
|
} catch {
|
|
28427
28841
|
}
|
|
28428
28842
|
}
|
|
28429
28843
|
function resetHomeBoardMemory() {
|
|
28430
28844
|
memory2 = null;
|
|
28431
|
-
|
|
28845
|
+
inflight2 = null;
|
|
28432
28846
|
}
|
|
28433
28847
|
function clearHomeBoardCache() {
|
|
28434
28848
|
resetHomeBoardMemory();
|
|
@@ -28527,8 +28941,8 @@ async function getHomeBoardInputs(workspaces, opts) {
|
|
|
28527
28941
|
return asLoaded(best, true);
|
|
28528
28942
|
}
|
|
28529
28943
|
}
|
|
28530
|
-
if (
|
|
28531
|
-
return
|
|
28944
|
+
if (inflight2 && inflight2.key === key) {
|
|
28945
|
+
return inflight2.promise;
|
|
28532
28946
|
}
|
|
28533
28947
|
const promise = (async () => {
|
|
28534
28948
|
const inputs = await loadHomeBoardInputs(workspaces);
|
|
@@ -28548,11 +28962,11 @@ async function getHomeBoardInputs(workspaces, opts) {
|
|
|
28548
28962
|
}
|
|
28549
28963
|
return loaded;
|
|
28550
28964
|
})();
|
|
28551
|
-
|
|
28965
|
+
inflight2 = { key, promise };
|
|
28552
28966
|
try {
|
|
28553
28967
|
return await promise;
|
|
28554
28968
|
} finally {
|
|
28555
|
-
if (
|
|
28969
|
+
if (inflight2?.promise === promise) inflight2 = null;
|
|
28556
28970
|
}
|
|
28557
28971
|
}
|
|
28558
28972
|
|
|
@@ -28772,7 +29186,7 @@ async function startMcpServer() {
|
|
|
28772
29186
|
async () => {
|
|
28773
29187
|
const threads = orch.getThreads(true);
|
|
28774
29188
|
const lines = threads.map((t) => {
|
|
28775
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0,
|
|
29189
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path53.basename)(t.repoPath) || t.repoPath;
|
|
28776
29190
|
const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
|
|
28777
29191
|
const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
|
|
28778
29192
|
const preview = lastMessagePreview(t.messages, 80);
|
|
@@ -31739,9 +32153,9 @@ var import_node_http3 = require("http");
|
|
|
31739
32153
|
var import_ws3 = require("ws");
|
|
31740
32154
|
|
|
31741
32155
|
// src/slack/relay-static.ts
|
|
31742
|
-
var
|
|
32156
|
+
var import_node_fs57 = require("fs");
|
|
31743
32157
|
var import_promises = require("fs/promises");
|
|
31744
|
-
var
|
|
32158
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
31745
32159
|
var TYPES = {
|
|
31746
32160
|
".css": "text/css; charset=utf-8",
|
|
31747
32161
|
".html": "text/html; charset=utf-8",
|
|
@@ -31772,9 +32186,9 @@ function resolveStaticPath(root, requestUrl) {
|
|
|
31772
32186
|
return null;
|
|
31773
32187
|
}
|
|
31774
32188
|
if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
|
|
31775
|
-
const rootResolved =
|
|
31776
|
-
const candidate =
|
|
31777
|
-
if (candidate !== rootResolved && !candidate.startsWith(rootResolved +
|
|
32189
|
+
const rootResolved = import_node_path54.default.resolve(root);
|
|
32190
|
+
const candidate = import_node_path54.default.resolve(rootResolved, `.${pathname}`);
|
|
32191
|
+
if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path54.default.sep)) {
|
|
31778
32192
|
return null;
|
|
31779
32193
|
}
|
|
31780
32194
|
return candidate;
|
|
@@ -31788,7 +32202,7 @@ async function fileSize(file) {
|
|
|
31788
32202
|
}
|
|
31789
32203
|
}
|
|
31790
32204
|
function sendFile(req, res, file, size) {
|
|
31791
|
-
const ext =
|
|
32205
|
+
const ext = import_node_path54.default.extname(file).toLowerCase();
|
|
31792
32206
|
res.writeHead(200, {
|
|
31793
32207
|
"Content-Type": TYPES[ext] ?? "application/octet-stream",
|
|
31794
32208
|
"Content-Length": size,
|
|
@@ -31798,7 +32212,7 @@ function sendFile(req, res, file, size) {
|
|
|
31798
32212
|
res.end();
|
|
31799
32213
|
return true;
|
|
31800
32214
|
}
|
|
31801
|
-
(0,
|
|
32215
|
+
(0, import_node_fs57.createReadStream)(file).pipe(res);
|
|
31802
32216
|
return true;
|
|
31803
32217
|
}
|
|
31804
32218
|
async function tryServeStatic(req, res, root) {
|
|
@@ -31807,7 +32221,7 @@ async function tryServeStatic(req, res, root) {
|
|
|
31807
32221
|
if (!candidate) return false;
|
|
31808
32222
|
const direct = await fileSize(candidate);
|
|
31809
32223
|
if (direct != null) return sendFile(req, res, candidate, direct);
|
|
31810
|
-
const asIndex =
|
|
32224
|
+
const asIndex = import_node_path54.default.join(candidate, "index.html");
|
|
31811
32225
|
const indexSize = await fileSize(asIndex);
|
|
31812
32226
|
if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
|
|
31813
32227
|
return false;
|
|
@@ -32212,6 +32626,7 @@ init_outbound_watch();
|
|
|
32212
32626
|
classifyWorktreeColumn,
|
|
32213
32627
|
claudeAdapter,
|
|
32214
32628
|
claudeChromeEnabled,
|
|
32629
|
+
claudeUsageOverLimitWindows,
|
|
32215
32630
|
claudeUserSettingsPath,
|
|
32216
32631
|
cleanupOrphanWorktrees,
|
|
32217
32632
|
clearBoardPins,
|
|
@@ -32231,6 +32646,7 @@ init_outbound_watch();
|
|
|
32231
32646
|
computeNextRunAt,
|
|
32232
32647
|
conductorBundledBinDir,
|
|
32233
32648
|
conductorDbPath,
|
|
32649
|
+
confirmClaudeUsageOverLimitEnabled,
|
|
32234
32650
|
confirmLand,
|
|
32235
32651
|
connectBrightsyTeam,
|
|
32236
32652
|
connectOptionalService,
|
|
@@ -32330,6 +32746,13 @@ init_outbound_watch();
|
|
|
32330
32746
|
formatAccountProfilePlaybookLine,
|
|
32331
32747
|
formatArtifactDirective,
|
|
32332
32748
|
formatBrightsyFetchError,
|
|
32749
|
+
formatClaudeExtraUsageDetail,
|
|
32750
|
+
formatClaudeUsageCompact,
|
|
32751
|
+
formatClaudeUsageFetchedAt,
|
|
32752
|
+
formatClaudeUsageOverLimitConfirm,
|
|
32753
|
+
formatClaudeUsageReset,
|
|
32754
|
+
formatClaudeUsageResetClock,
|
|
32755
|
+
formatClaudeUsageTooltip,
|
|
32333
32756
|
formatDetachedJobInvoke,
|
|
32334
32757
|
formatFetchError,
|
|
32335
32758
|
formatGhLandError,
|
|
@@ -32379,6 +32802,7 @@ init_outbound_watch();
|
|
|
32379
32802
|
getAgentSetupInfo,
|
|
32380
32803
|
getBrightsySession,
|
|
32381
32804
|
getCaffeinateHold,
|
|
32805
|
+
getClaudePlanUsage,
|
|
32382
32806
|
getDefaultAgent,
|
|
32383
32807
|
getDefaultEffort,
|
|
32384
32808
|
getDefaultFast,
|
|
@@ -32428,6 +32852,7 @@ init_outbound_watch();
|
|
|
32428
32852
|
hasRepoHook,
|
|
32429
32853
|
hasWorkspaceHook,
|
|
32430
32854
|
healOrchestrationSoccerTitles,
|
|
32855
|
+
hottestClaudeWindow,
|
|
32431
32856
|
httpFetch,
|
|
32432
32857
|
importConductorWorkspace,
|
|
32433
32858
|
importConductorWorkspaceAsync,
|
|
@@ -32591,6 +33016,7 @@ init_outbound_watch();
|
|
|
32591
33016
|
originFetchBranch,
|
|
32592
33017
|
originGhRepoEnv,
|
|
32593
33018
|
packagedDetachedJobPath,
|
|
33019
|
+
parseClaudeUsagePayload,
|
|
32594
33020
|
parseCursorRunnerLine,
|
|
32595
33021
|
parseDurationMs,
|
|
32596
33022
|
parseForceStopMessage,
|