@sideboard-ai/core 0.1.198 → 0.1.200
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-345SE3B4.js} +2 -2
- package/dist/{abletime-HR6P4GJH.js → abletime-KGPD3UUJ.js} +2 -2
- package/dist/{agents-5TZY6LLX.js → agents-N7WXOGN6.js} +28 -4
- package/dist/{agents-AQQKPD46.js → agents-ZRIFDXCB.js} +28 -4
- package/dist/{app-settings-5KHVKJKO.js → app-settings-AXCURTZJ.js} +11 -1
- package/dist/{app-settings-J775CYOO.js → app-settings-V6IHESEQ.js} +11 -1
- package/dist/{chunk-SYXSSU7G.js → chunk-5XSDGJMP.js} +369 -4
- package/dist/{chunk-DROELG52.js → chunk-62IMZIIZ.js} +58 -41
- package/dist/{chunk-E37JHCO3.js → chunk-7AHAABKN.js} +1 -1
- package/dist/{chunk-S5GLSRLP.js → chunk-CXFW5LIH.js} +48 -1
- package/dist/{chunk-6YTI2HBG.js → chunk-EWDE54OI.js} +2 -2
- package/dist/{chunk-AH6WIBLY.js → chunk-ISV5IFH3.js} +48 -1
- package/dist/{chunk-DP4TKAMZ.js → chunk-NXM45OS3.js} +1 -1
- package/dist/{chunk-6YS5IKD2.js → chunk-O2DRYD2B.js} +59 -42
- package/dist/{chunk-S4QCBBXS.js → chunk-OSPE25A7.js} +1 -1
- package/dist/{chunk-HZTHWU6A.js → chunk-PDMNYCPL.js} +2 -2
- package/dist/{chunk-KTHRWHA3.js → chunk-PGQGP4FD.js} +1 -1
- package/dist/{chunk-EA67VQM2.js → chunk-PKUPOVKP.js} +369 -4
- package/dist/{coordinator-prompt-IX66YUJ2.js → coordinator-prompt-2RWBH6W7.js} +3 -3
- package/dist/{coordinator-prompt-LYKS3YNG.js → coordinator-prompt-AL62H73U.js} +3 -3
- package/dist/{global-workspace-SNJ2Z6SL.js → global-workspace-VAO3BQP5.js} +3 -3
- package/dist/{global-workspace-4QX6UEOY.js → global-workspace-Y5KKGXN7.js} +3 -3
- package/dist/index.cjs +766 -280
- package/dist/index.d.cts +116 -11
- package/dist/index.d.ts +116 -11
- package/dist/index.js +42 -8
- package/dist/mcp/run-stdio.cjs +374 -276
- package/dist/mcp/run-stdio.js +8 -8
- package/dist/{orchestrator-L2H42HPW.js → orchestrator-D2EJ4Z7Z.js} +5 -5
- package/dist/{orchestrator-6ZNKCPNL.js → orchestrator-DPHIMK44.js} +5 -5
- package/dist/{workspaces-URMUVGAQ.js → workspaces-DZZQM745.js} +3 -3
- package/dist/{workspaces-UTOYGBYB.js → workspaces-HEKFQP4B.js} +3 -3
- package/dist/{worktree-R43JOR4V.js → worktree-ENRMJUI3.js} +2 -2
- package/dist/{worktree-RM6UWNGZ.js → worktree-IEUSQ63V.js} +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -988,6 +988,30 @@ var init_branch_prefix = __esm({
|
|
|
988
988
|
}
|
|
989
989
|
});
|
|
990
990
|
|
|
991
|
+
// src/store/usage-on-limit.ts
|
|
992
|
+
function isUsageOnLimit(value) {
|
|
993
|
+
return value === "keep_going" || value === "confirm" || value === "switch_agent" || value === "wait_reset";
|
|
994
|
+
}
|
|
995
|
+
function resolveUsageOnLimit(advanced = {}) {
|
|
996
|
+
if (isUsageOnLimit(advanced.usageOnLimit)) return advanced.usageOnLimit;
|
|
997
|
+
if (advanced.confirmClaudeUsageOverLimit) return "confirm";
|
|
998
|
+
if (advanced.orchestrationQuotaOnLimit === "wait_reset") return "wait_reset";
|
|
999
|
+
if (advanced.orchestrationQuotaOnLimit === "switch_agent") return "switch_agent";
|
|
1000
|
+
return "keep_going";
|
|
1001
|
+
}
|
|
1002
|
+
var USAGE_ON_LIMIT_VALUES;
|
|
1003
|
+
var init_usage_on_limit = __esm({
|
|
1004
|
+
"src/store/usage-on-limit.ts"() {
|
|
1005
|
+
"use strict";
|
|
1006
|
+
USAGE_ON_LIMIT_VALUES = [
|
|
1007
|
+
"keep_going",
|
|
1008
|
+
"confirm",
|
|
1009
|
+
"switch_agent",
|
|
1010
|
+
"wait_reset"
|
|
1011
|
+
];
|
|
1012
|
+
}
|
|
1013
|
+
});
|
|
1014
|
+
|
|
991
1015
|
// src/store/issue-source-labels.ts
|
|
992
1016
|
function issueSourceLabel(source) {
|
|
993
1017
|
if (source && source in ISSUE_SOURCE_LABELS) {
|
|
@@ -1016,6 +1040,7 @@ __export(app_settings_exports, {
|
|
|
1016
1040
|
HARNESS_ENV_KEYS: () => HARNESS_ENV_KEYS,
|
|
1017
1041
|
ISSUE_SOURCE_LABELS: () => ISSUE_SOURCE_LABELS,
|
|
1018
1042
|
PROFILE_NOTES_MAX: () => PROFILE_NOTES_MAX,
|
|
1043
|
+
USAGE_ON_LIMIT_VALUES: () => USAGE_ON_LIMIT_VALUES,
|
|
1019
1044
|
appSettingsPath: () => appSettingsPath,
|
|
1020
1045
|
applyAppEnvironment: () => applyAppEnvironment,
|
|
1021
1046
|
autoArchiveOnMergeEnabled: () => autoArchiveOnMergeEnabled,
|
|
@@ -1032,6 +1057,7 @@ __export(app_settings_exports, {
|
|
|
1032
1057
|
childEnvWithAppSettings: () => childEnvWithAppSettings,
|
|
1033
1058
|
claudeChromeEnabled: () => claudeChromeEnabled,
|
|
1034
1059
|
claudeUserSettingsPath: () => claudeUserSettingsPath,
|
|
1060
|
+
confirmClaudeUsageOverLimitEnabled: () => confirmClaudeUsageOverLimitEnabled,
|
|
1035
1061
|
cowboyModeEnabled: () => cowboyModeEnabled,
|
|
1036
1062
|
deleteBranchOnPurgeEnabled: () => deleteBranchOnPurgeEnabled,
|
|
1037
1063
|
disconnectAbleTimeConnection: () => disconnectAbleTimeConnection,
|
|
@@ -1061,6 +1087,7 @@ __export(app_settings_exports, {
|
|
|
1061
1087
|
isAbleTimeConnected: () => isAbleTimeConnected,
|
|
1062
1088
|
isIssueSourceConnected: () => isIssueSourceConnected,
|
|
1063
1089
|
isLinearConnected: () => isLinearConnected,
|
|
1090
|
+
isUsageOnLimit: () => isUsageOnLimit,
|
|
1064
1091
|
issueSourceLabel: () => issueSourceLabel,
|
|
1065
1092
|
loadAppSettings: () => loadAppSettings,
|
|
1066
1093
|
maxConcurrentAgents: () => maxConcurrentAgents,
|
|
@@ -1076,6 +1103,7 @@ __export(app_settings_exports, {
|
|
|
1076
1103
|
resolveNewThreadOptions: () => resolveNewThreadOptions,
|
|
1077
1104
|
resolveOrchestratorDefaults: () => resolveOrchestratorDefaults,
|
|
1078
1105
|
resolveThreadDefaults: () => resolveThreadDefaults,
|
|
1106
|
+
resolveUsageOnLimit: () => resolveUsageOnLimit,
|
|
1079
1107
|
resolveViewerProfile: () => resolveViewerProfile,
|
|
1080
1108
|
resolveViewerProfileForRepo: () => resolveViewerProfileForRepo,
|
|
1081
1109
|
saveAbleTimeConnection: () => saveAbleTimeConnection,
|
|
@@ -1095,6 +1123,7 @@ __export(app_settings_exports, {
|
|
|
1095
1123
|
updateIntegrationsSettings: () => updateIntegrationsSettings,
|
|
1096
1124
|
updateOpencodeSettings: () => updateOpencodeSettings,
|
|
1097
1125
|
updateProjectProfileSettings: () => updateProjectProfileSettings,
|
|
1126
|
+
usageOnLimit: () => usageOnLimit,
|
|
1098
1127
|
writeViewerContext: () => writeViewerContext
|
|
1099
1128
|
});
|
|
1100
1129
|
function emptyPublicIntegrations() {
|
|
@@ -1459,6 +1488,12 @@ function normalizeAdvanced(raw) {
|
|
|
1459
1488
|
if (typeof source.showCost === "boolean") {
|
|
1460
1489
|
out.showCost = source.showCost;
|
|
1461
1490
|
}
|
|
1491
|
+
if (isUsageOnLimit(source.usageOnLimit)) {
|
|
1492
|
+
out.usageOnLimit = source.usageOnLimit;
|
|
1493
|
+
}
|
|
1494
|
+
if (typeof source.confirmClaudeUsageOverLimit === "boolean") {
|
|
1495
|
+
out.confirmClaudeUsageOverLimit = source.confirmClaudeUsageOverLimit;
|
|
1496
|
+
}
|
|
1462
1497
|
if (typeof source.autoArchiveOnMerge === "boolean") {
|
|
1463
1498
|
out.autoArchiveOnMerge = source.autoArchiveOnMerge;
|
|
1464
1499
|
}
|
|
@@ -2321,6 +2356,17 @@ function updateAdvancedSettings(patch) {
|
|
|
2321
2356
|
if (typeof patch.showCost === "boolean") {
|
|
2322
2357
|
advanced.showCost = patch.showCost;
|
|
2323
2358
|
}
|
|
2359
|
+
if (isUsageOnLimit(patch.usageOnLimit)) {
|
|
2360
|
+
advanced.usageOnLimit = patch.usageOnLimit;
|
|
2361
|
+
advanced.confirmClaudeUsageOverLimit = patch.usageOnLimit === "confirm";
|
|
2362
|
+
if (patch.usageOnLimit === "switch_agent" || patch.usageOnLimit === "wait_reset") {
|
|
2363
|
+
advanced.orchestrationQuotaOnLimit = patch.usageOnLimit;
|
|
2364
|
+
}
|
|
2365
|
+
} else if (typeof patch.confirmClaudeUsageOverLimit === "boolean") {
|
|
2366
|
+
advanced.confirmClaudeUsageOverLimit = patch.confirmClaudeUsageOverLimit;
|
|
2367
|
+
if (patch.confirmClaudeUsageOverLimit) advanced.usageOnLimit = "confirm";
|
|
2368
|
+
else if (advanced.usageOnLimit === "confirm") advanced.usageOnLimit = "keep_going";
|
|
2369
|
+
}
|
|
2324
2370
|
if (typeof patch.autoArchiveOnMerge === "boolean") {
|
|
2325
2371
|
advanced.autoArchiveOnMerge = patch.autoArchiveOnMerge;
|
|
2326
2372
|
}
|
|
@@ -2383,14 +2429,21 @@ function cowboyModeEnabled(settings = loadAppSettings()) {
|
|
|
2383
2429
|
function showCostEnabled(settings = loadAppSettings()) {
|
|
2384
2430
|
return Boolean(settings.advanced.showCost);
|
|
2385
2431
|
}
|
|
2432
|
+
function confirmClaudeUsageOverLimitEnabled(settings = loadAppSettings()) {
|
|
2433
|
+
return usageOnLimit(settings) === "confirm";
|
|
2434
|
+
}
|
|
2386
2435
|
function autoArchiveOnMergeEnabled(settings = loadAppSettings()) {
|
|
2387
2436
|
return Boolean(settings.advanced.autoArchiveOnMerge);
|
|
2388
2437
|
}
|
|
2389
2438
|
function autoCleanupOrphansEnabled(settings = loadAppSettings()) {
|
|
2390
2439
|
return Boolean(settings.advanced.autoCleanupOrphans);
|
|
2391
2440
|
}
|
|
2441
|
+
function usageOnLimit(settings = loadAppSettings()) {
|
|
2442
|
+
return resolveUsageOnLimit(settings.advanced);
|
|
2443
|
+
}
|
|
2392
2444
|
function orchestrationQuotaOnLimit(settings = loadAppSettings()) {
|
|
2393
|
-
|
|
2445
|
+
const action = usageOnLimit(settings);
|
|
2446
|
+
return action === "wait_reset" ? "wait_reset" : "switch_agent";
|
|
2394
2447
|
}
|
|
2395
2448
|
function orchestrationQuotaFallbackAgent(settings = loadAppSettings()) {
|
|
2396
2449
|
const preferred = settings.advanced.orchestrationQuotaFallbackAgent;
|
|
@@ -2505,6 +2558,8 @@ var init_app_settings = __esm({
|
|
|
2505
2558
|
init_private_file();
|
|
2506
2559
|
init_secret_vault();
|
|
2507
2560
|
init_branch_prefix();
|
|
2561
|
+
init_usage_on_limit();
|
|
2562
|
+
init_usage_on_limit();
|
|
2508
2563
|
init_issue_source_labels();
|
|
2509
2564
|
init_account_profile();
|
|
2510
2565
|
HARNESS_ENV_KEYS = {
|
|
@@ -2845,14 +2900,14 @@ function fileMtimeMs(path2) {
|
|
|
2845
2900
|
}
|
|
2846
2901
|
}
|
|
2847
2902
|
function rememberThread(thread, mtimeMs) {
|
|
2848
|
-
const
|
|
2849
|
-
|
|
2850
|
-
if (mtimeMs != null)
|
|
2903
|
+
const cache2 = cacheForDir();
|
|
2904
|
+
cache2.byId.set(thread.id, thread);
|
|
2905
|
+
if (mtimeMs != null) cache2.mtimeMs.set(thread.id, mtimeMs);
|
|
2851
2906
|
}
|
|
2852
2907
|
function forgetThread(id) {
|
|
2853
|
-
const
|
|
2854
|
-
|
|
2855
|
-
|
|
2908
|
+
const cache2 = cacheForDir();
|
|
2909
|
+
cache2.byId.delete(id);
|
|
2910
|
+
cache2.mtimeMs.delete(id);
|
|
2856
2911
|
}
|
|
2857
2912
|
function invalidateThreadListCache() {
|
|
2858
2913
|
listCache = null;
|
|
@@ -2864,9 +2919,9 @@ function readThread(id) {
|
|
|
2864
2919
|
forgetThread(id);
|
|
2865
2920
|
return null;
|
|
2866
2921
|
}
|
|
2867
|
-
const
|
|
2868
|
-
const cached =
|
|
2869
|
-
if (cached &&
|
|
2922
|
+
const cache2 = cacheForDir();
|
|
2923
|
+
const cached = cache2.byId.get(id);
|
|
2924
|
+
if (cached && cache2.mtimeMs.get(id) === mtimeMs) return cached;
|
|
2870
2925
|
const raw = (0, import_node_fs9.readFileSync)(path2, "utf8");
|
|
2871
2926
|
const thread = normalizeThread(JSON.parse(raw));
|
|
2872
2927
|
rememberThread(thread, mtimeMs);
|
|
@@ -2888,7 +2943,7 @@ function isThreadRecordFile(nameOrPath) {
|
|
|
2888
2943
|
return name.endsWith(".json") && !name.endsWith(".live.json");
|
|
2889
2944
|
}
|
|
2890
2945
|
function listThreads(opts) {
|
|
2891
|
-
const
|
|
2946
|
+
const cache2 = cacheForDir();
|
|
2892
2947
|
const files = (0, import_node_fs9.readdirSync)(threadsDir()).filter(isThreadRecordFile);
|
|
2893
2948
|
const seen = /* @__PURE__ */ new Set();
|
|
2894
2949
|
for (const f of files) {
|
|
@@ -2900,10 +2955,10 @@ function listThreads(opts) {
|
|
|
2900
2955
|
} catch {
|
|
2901
2956
|
}
|
|
2902
2957
|
}
|
|
2903
|
-
for (const id of [...
|
|
2958
|
+
for (const id of [...cache2.byId.keys()]) {
|
|
2904
2959
|
if (!seen.has(id)) forgetThread(id);
|
|
2905
2960
|
}
|
|
2906
|
-
const threads = [...
|
|
2961
|
+
const threads = [...cache2.byId.values()].sort(
|
|
2907
2962
|
(a, b) => b.updatedAt.localeCompare(a.updatedAt)
|
|
2908
2963
|
);
|
|
2909
2964
|
if (opts?.includeArchived) return threads;
|
|
@@ -13674,6 +13729,372 @@ var init_session_quota = __esm({
|
|
|
13674
13729
|
}
|
|
13675
13730
|
});
|
|
13676
13731
|
|
|
13732
|
+
// src/agents/claude-usage.ts
|
|
13733
|
+
function parseClaudeResetsAt(value) {
|
|
13734
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
13735
|
+
const ms = value > 1e12 ? value : value * 1e3;
|
|
13736
|
+
const d = new Date(ms);
|
|
13737
|
+
return Number.isNaN(d.getTime()) ? null : d.toISOString();
|
|
13738
|
+
}
|
|
13739
|
+
if (typeof value === "string") {
|
|
13740
|
+
const trimmed = value.trim();
|
|
13741
|
+
if (!trimmed) return null;
|
|
13742
|
+
if (/^\d+(\.\d+)?$/.test(trimmed)) {
|
|
13743
|
+
return parseClaudeResetsAt(Number(trimmed));
|
|
13744
|
+
}
|
|
13745
|
+
const d = new Date(trimmed);
|
|
13746
|
+
return Number.isNaN(d.getTime()) ? null : d.toISOString();
|
|
13747
|
+
}
|
|
13748
|
+
return null;
|
|
13749
|
+
}
|
|
13750
|
+
function parseClaudeUtilization(value) {
|
|
13751
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return null;
|
|
13752
|
+
return Math.max(0, Math.min(100, value));
|
|
13753
|
+
}
|
|
13754
|
+
function windowFromRaw(id, raw) {
|
|
13755
|
+
if (!raw || typeof raw !== "object") return null;
|
|
13756
|
+
const row = raw;
|
|
13757
|
+
const used = parseClaudeUtilization(row.utilization ?? row.used_percentage);
|
|
13758
|
+
if (used == null) return null;
|
|
13759
|
+
const meta = WINDOW_META[id];
|
|
13760
|
+
return {
|
|
13761
|
+
id,
|
|
13762
|
+
label: meta.label,
|
|
13763
|
+
shortLabel: meta.shortLabel,
|
|
13764
|
+
detail: meta.detail,
|
|
13765
|
+
usedPercent: used,
|
|
13766
|
+
remainingPercent: Math.max(0, Math.min(100, 100 - used)),
|
|
13767
|
+
resetsAt: parseClaudeResetsAt(row.resets_at)
|
|
13768
|
+
};
|
|
13769
|
+
}
|
|
13770
|
+
function extraUsageFromRaw(raw) {
|
|
13771
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
13772
|
+
const row = raw;
|
|
13773
|
+
const enabled = row.is_enabled === true || row.enabled === true;
|
|
13774
|
+
if (!enabled && row.is_enabled !== false && row.enabled !== false) return void 0;
|
|
13775
|
+
const usedCredits = numberOrUndef(row.used_credits ?? row.used);
|
|
13776
|
+
const monthlyLimit = numberOrUndef(row.monthly_limit);
|
|
13777
|
+
const usedPercent = parseClaudeUtilization(row.utilization) ?? void 0;
|
|
13778
|
+
return {
|
|
13779
|
+
enabled,
|
|
13780
|
+
...usedCredits != null ? { usedCredits } : {},
|
|
13781
|
+
...monthlyLimit != null ? { monthlyLimit } : {},
|
|
13782
|
+
...usedPercent != null ? { usedPercent } : {}
|
|
13783
|
+
};
|
|
13784
|
+
}
|
|
13785
|
+
function numberOrUndef(value) {
|
|
13786
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return void 0;
|
|
13787
|
+
return value;
|
|
13788
|
+
}
|
|
13789
|
+
function parseClaudeUsagePayload(raw, fetchedAt = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
13790
|
+
if (!raw || typeof raw !== "object") return null;
|
|
13791
|
+
const obj = raw;
|
|
13792
|
+
const source = obj.rate_limits && typeof obj.rate_limits === "object" ? obj.rate_limits : obj;
|
|
13793
|
+
const windows = [];
|
|
13794
|
+
for (const id of WINDOW_ORDER) {
|
|
13795
|
+
const parsed = windowFromRaw(id, source[id]);
|
|
13796
|
+
if (parsed) windows.push(parsed);
|
|
13797
|
+
}
|
|
13798
|
+
if (windows.length === 0) return null;
|
|
13799
|
+
const extra = extraUsageFromRaw(obj.extra_usage ?? source.extra_usage);
|
|
13800
|
+
return {
|
|
13801
|
+
windows,
|
|
13802
|
+
...extra ? { extraUsage: extra } : {},
|
|
13803
|
+
fetchedAt
|
|
13804
|
+
};
|
|
13805
|
+
}
|
|
13806
|
+
function hottestClaudeWindow(usage) {
|
|
13807
|
+
if (usage.windows.length === 0) return null;
|
|
13808
|
+
return usage.windows.reduce((a, b) => b.usedPercent > a.usedPercent ? b : a);
|
|
13809
|
+
}
|
|
13810
|
+
function formatClaudeUsageReset(resetsAt, now = /* @__PURE__ */ new Date()) {
|
|
13811
|
+
if (!resetsAt) return "";
|
|
13812
|
+
const at = new Date(resetsAt);
|
|
13813
|
+
if (Number.isNaN(at.getTime())) return "";
|
|
13814
|
+
const ms = at.getTime() - now.getTime();
|
|
13815
|
+
if (ms <= 0) return "resets soon";
|
|
13816
|
+
const minutes = Math.round(ms / 6e4);
|
|
13817
|
+
if (minutes < 60) return `resets in ${Math.max(1, minutes)}m`;
|
|
13818
|
+
const hours = Math.round(minutes / 60);
|
|
13819
|
+
if (hours < 36) return `resets in ${hours}h`;
|
|
13820
|
+
try {
|
|
13821
|
+
return `resets ${at.toLocaleString(void 0, {
|
|
13822
|
+
weekday: "short",
|
|
13823
|
+
hour: "numeric",
|
|
13824
|
+
minute: "2-digit"
|
|
13825
|
+
})}`;
|
|
13826
|
+
} catch {
|
|
13827
|
+
return `resets ${at.toISOString()}`;
|
|
13828
|
+
}
|
|
13829
|
+
}
|
|
13830
|
+
function formatClaudeUsageResetClock(resetsAt) {
|
|
13831
|
+
if (!resetsAt) return "";
|
|
13832
|
+
const at = new Date(resetsAt);
|
|
13833
|
+
if (Number.isNaN(at.getTime())) return "";
|
|
13834
|
+
try {
|
|
13835
|
+
return at.toLocaleString(void 0, {
|
|
13836
|
+
weekday: "short",
|
|
13837
|
+
month: "short",
|
|
13838
|
+
day: "numeric",
|
|
13839
|
+
hour: "numeric",
|
|
13840
|
+
minute: "2-digit"
|
|
13841
|
+
});
|
|
13842
|
+
} catch {
|
|
13843
|
+
return at.toISOString();
|
|
13844
|
+
}
|
|
13845
|
+
}
|
|
13846
|
+
function formatClaudeUsageFetchedAt(fetchedAt, now = /* @__PURE__ */ new Date()) {
|
|
13847
|
+
const at = new Date(fetchedAt);
|
|
13848
|
+
if (Number.isNaN(at.getTime())) return "";
|
|
13849
|
+
const minutes = Math.max(0, Math.round((now.getTime() - at.getTime()) / 6e4));
|
|
13850
|
+
if (minutes < 1) return "Updated just now";
|
|
13851
|
+
if (minutes < 60) return `Updated ${minutes}m ago`;
|
|
13852
|
+
const hours = Math.round(minutes / 60);
|
|
13853
|
+
if (hours < 36) return `Updated ${hours}h ago`;
|
|
13854
|
+
return `Updated ${formatClaudeUsageResetClock(fetchedAt)}`;
|
|
13855
|
+
}
|
|
13856
|
+
function formatClaudeExtraUsageDetail(extra) {
|
|
13857
|
+
if (!extra.enabled) return "Extra usage off";
|
|
13858
|
+
const bits = ["Extra usage on"];
|
|
13859
|
+
if (extra.usedCredits != null && extra.monthlyLimit != null) {
|
|
13860
|
+
bits.push(`${extra.usedCredits} / ${extra.monthlyLimit} credits this month`);
|
|
13861
|
+
} else if (extra.usedCredits != null) {
|
|
13862
|
+
bits.push(`${extra.usedCredits} credits used`);
|
|
13863
|
+
}
|
|
13864
|
+
if (extra.usedPercent != null) {
|
|
13865
|
+
bits.push(`${Math.round(extra.usedPercent)}% of extra pool`);
|
|
13866
|
+
}
|
|
13867
|
+
return bits.join(" \xB7 ");
|
|
13868
|
+
}
|
|
13869
|
+
function formatClaudeUsageWindowLine(window, now = /* @__PURE__ */ new Date()) {
|
|
13870
|
+
const reset = formatClaudeUsageReset(window.resetsAt, now);
|
|
13871
|
+
const clock = formatClaudeUsageResetClock(window.resetsAt);
|
|
13872
|
+
const left = `${Math.round(window.remainingPercent)}% left`;
|
|
13873
|
+
const used = `${Math.round(window.usedPercent)}% used`;
|
|
13874
|
+
const resetBit = reset ? clock && !reset.includes(clock) ? `${reset} (${clock})` : reset : "";
|
|
13875
|
+
return resetBit ? `${window.label} \u2014 ${window.detail}. ${left} \xB7 ${used} \xB7 ${resetBit}` : `${window.label} \u2014 ${window.detail}. ${left} \xB7 ${used}`;
|
|
13876
|
+
}
|
|
13877
|
+
function formatClaudeUsageTooltip(usage, now = /* @__PURE__ */ new Date()) {
|
|
13878
|
+
const lines = [
|
|
13879
|
+
"Claude Code plan",
|
|
13880
|
+
...usage.windows.map((w) => formatClaudeUsageWindowLine(w, now))
|
|
13881
|
+
];
|
|
13882
|
+
if (usage.extraUsage) {
|
|
13883
|
+
lines.push(formatClaudeExtraUsageDetail(usage.extraUsage));
|
|
13884
|
+
}
|
|
13885
|
+
const fetched = formatClaudeUsageFetchedAt(usage.fetchedAt, now);
|
|
13886
|
+
if (fetched) lines.push(fetched);
|
|
13887
|
+
return lines.join("\n");
|
|
13888
|
+
}
|
|
13889
|
+
function formatClaudeUsageCompact(window) {
|
|
13890
|
+
return `${window.shortLabel} ${Math.round(window.remainingPercent)}%`;
|
|
13891
|
+
}
|
|
13892
|
+
function claudeUsageWindowOverLimit(window) {
|
|
13893
|
+
return window.remainingPercent <= 0 || window.usedPercent >= 100;
|
|
13894
|
+
}
|
|
13895
|
+
function claudeUsageOverLimitWindows(usage) {
|
|
13896
|
+
if (!usage) return [];
|
|
13897
|
+
return usage.windows.filter(claudeUsageWindowOverLimit);
|
|
13898
|
+
}
|
|
13899
|
+
function formatOverLimitWindowList(windows, now) {
|
|
13900
|
+
const parts = windows.map((w) => {
|
|
13901
|
+
const reset = formatClaudeUsageReset(w.resetsAt, now);
|
|
13902
|
+
return reset ? `${w.label} (${reset})` : w.label;
|
|
13903
|
+
});
|
|
13904
|
+
return {
|
|
13905
|
+
list: parts.join(", "),
|
|
13906
|
+
verb: windows.length === 1 ? "is" : "are"
|
|
13907
|
+
};
|
|
13908
|
+
}
|
|
13909
|
+
function formatClaudeUsageOverLimitConfirm(windows, now = /* @__PURE__ */ new Date()) {
|
|
13910
|
+
if (windows.length === 0) return "";
|
|
13911
|
+
const { list, verb } = formatOverLimitWindowList(windows, now);
|
|
13912
|
+
return `Claude Code ${list} ${verb} at or over the plan limit. Send this message anyway?`;
|
|
13913
|
+
}
|
|
13914
|
+
function formatClaudeUsageOverLimitWait(windows, now = /* @__PURE__ */ new Date()) {
|
|
13915
|
+
if (windows.length === 0) return "";
|
|
13916
|
+
const { list, verb } = formatOverLimitWindowList(windows, now);
|
|
13917
|
+
return `Claude Code ${list} ${verb} at or over the plan limit. Sending is paused until the window resets.`;
|
|
13918
|
+
}
|
|
13919
|
+
var WINDOW_META, WINDOW_ORDER;
|
|
13920
|
+
var init_claude_usage = __esm({
|
|
13921
|
+
"src/agents/claude-usage.ts"() {
|
|
13922
|
+
"use strict";
|
|
13923
|
+
WINDOW_META = {
|
|
13924
|
+
five_hour: {
|
|
13925
|
+
label: "5-hour session",
|
|
13926
|
+
shortLabel: "5h",
|
|
13927
|
+
detail: "Rolling 5-hour limit across all models"
|
|
13928
|
+
},
|
|
13929
|
+
seven_day: {
|
|
13930
|
+
label: "Weekly",
|
|
13931
|
+
shortLabel: "wk",
|
|
13932
|
+
detail: "7-day cap across all models"
|
|
13933
|
+
},
|
|
13934
|
+
seven_day_opus: {
|
|
13935
|
+
label: "Opus",
|
|
13936
|
+
shortLabel: "Opus",
|
|
13937
|
+
detail: "Weekly Opus-only cap"
|
|
13938
|
+
},
|
|
13939
|
+
seven_day_sonnet: {
|
|
13940
|
+
label: "Sonnet",
|
|
13941
|
+
shortLabel: "Sonnet",
|
|
13942
|
+
detail: "Weekly Sonnet-only cap"
|
|
13943
|
+
}
|
|
13944
|
+
};
|
|
13945
|
+
WINDOW_ORDER = [
|
|
13946
|
+
"five_hour",
|
|
13947
|
+
"seven_day",
|
|
13948
|
+
"seven_day_opus",
|
|
13949
|
+
"seven_day_sonnet"
|
|
13950
|
+
];
|
|
13951
|
+
}
|
|
13952
|
+
});
|
|
13953
|
+
|
|
13954
|
+
// src/agents/claude-usage-client.ts
|
|
13955
|
+
function accessTokenFromCredentialsJson(raw) {
|
|
13956
|
+
const trimmed = raw.trim();
|
|
13957
|
+
if (!trimmed) return null;
|
|
13958
|
+
if (trimmed.startsWith("sk-ant-")) {
|
|
13959
|
+
const token = trimmed.split(/\s+/)[0];
|
|
13960
|
+
return token || null;
|
|
13961
|
+
}
|
|
13962
|
+
try {
|
|
13963
|
+
const parsed = JSON.parse(trimmed);
|
|
13964
|
+
const oauth = parsed.claudeAiOauth && typeof parsed.claudeAiOauth === "object" ? parsed.claudeAiOauth : parsed;
|
|
13965
|
+
const token = oauth.accessToken ?? oauth.access_token;
|
|
13966
|
+
return typeof token === "string" && token.trim() ? token.trim() : null;
|
|
13967
|
+
} catch {
|
|
13968
|
+
return null;
|
|
13969
|
+
}
|
|
13970
|
+
}
|
|
13971
|
+
function claudeCredentialsPath() {
|
|
13972
|
+
const root = process.env.CLAUDE_CONFIG_DIR?.trim() || (0, import_node_path37.join)((0, import_node_os13.homedir)(), ".claude");
|
|
13973
|
+
return (0, import_node_path37.join)(root, ".credentials.json");
|
|
13974
|
+
}
|
|
13975
|
+
async function readFileAccessToken() {
|
|
13976
|
+
const path2 = claudeCredentialsPath();
|
|
13977
|
+
if (!(0, import_node_fs37.existsSync)(path2)) return null;
|
|
13978
|
+
try {
|
|
13979
|
+
return accessTokenFromCredentialsJson((0, import_node_fs37.readFileSync)(path2, "utf8"));
|
|
13980
|
+
} catch {
|
|
13981
|
+
return null;
|
|
13982
|
+
}
|
|
13983
|
+
}
|
|
13984
|
+
async function readKeychainAccessToken() {
|
|
13985
|
+
if (process.platform !== "darwin") return null;
|
|
13986
|
+
for (const service of KEYCHAIN_SERVICES) {
|
|
13987
|
+
const result = await run("security", ["find-generic-password", "-s", service, "-w"], {
|
|
13988
|
+
reject: false,
|
|
13989
|
+
timeoutMs: 4e3
|
|
13990
|
+
});
|
|
13991
|
+
if (result.exitCode !== 0 || !result.stdout.trim()) continue;
|
|
13992
|
+
const token = accessTokenFromCredentialsJson(result.stdout);
|
|
13993
|
+
if (token) return token;
|
|
13994
|
+
}
|
|
13995
|
+
return null;
|
|
13996
|
+
}
|
|
13997
|
+
async function readClaudeAccessToken() {
|
|
13998
|
+
const envToken = process.env.CLAUDE_CODE_OAUTH_TOKEN?.trim();
|
|
13999
|
+
if (envToken) return envToken;
|
|
14000
|
+
const fromFile = await readFileAccessToken();
|
|
14001
|
+
if (fromFile) return fromFile;
|
|
14002
|
+
return readKeychainAccessToken();
|
|
14003
|
+
}
|
|
14004
|
+
async function resolveClaudeUserAgent() {
|
|
14005
|
+
if (claudeVersion) return `claude-code/${claudeVersion}`;
|
|
14006
|
+
try {
|
|
14007
|
+
const claude = resolveClaudeExecutable();
|
|
14008
|
+
const result = await run(claude, ["--version"], { reject: false, timeoutMs: 4e3 });
|
|
14009
|
+
const match = `${result.stdout}
|
|
14010
|
+
${result.stderr}`.match(/(\d+\.\d+\.\d+)/);
|
|
14011
|
+
claudeVersion = match?.[1] ?? "2.1.80";
|
|
14012
|
+
} catch {
|
|
14013
|
+
claudeVersion = "2.1.80";
|
|
14014
|
+
}
|
|
14015
|
+
return `claude-code/${claudeVersion}`;
|
|
14016
|
+
}
|
|
14017
|
+
function staleOk(now) {
|
|
14018
|
+
if (!lastGood) return null;
|
|
14019
|
+
if (now - lastGood.at > CLAUDE_USAGE_STALE_OK_MS) return null;
|
|
14020
|
+
return lastGood.value;
|
|
14021
|
+
}
|
|
14022
|
+
async function getClaudePlanUsage(opts = {}) {
|
|
14023
|
+
const now = opts.now ?? Date.now();
|
|
14024
|
+
if (!opts.force) {
|
|
14025
|
+
if (cache && now - cache.at < CLAUDE_USAGE_TTL_MS) return cache.value;
|
|
14026
|
+
if (now < errorUntil) return staleOk(now);
|
|
14027
|
+
}
|
|
14028
|
+
if (inflight) return inflight;
|
|
14029
|
+
inflight = (async () => {
|
|
14030
|
+
try {
|
|
14031
|
+
const token = await (opts.readAccessToken ?? readClaudeAccessToken)();
|
|
14032
|
+
if (!token) {
|
|
14033
|
+
cache = { at: now, value: null };
|
|
14034
|
+
return null;
|
|
14035
|
+
}
|
|
14036
|
+
const fetchFn = opts.fetch ?? httpFetch;
|
|
14037
|
+
const userAgent = opts.userAgent ?? await resolveClaudeUserAgent();
|
|
14038
|
+
const ac = new AbortController();
|
|
14039
|
+
const timer = setTimeout(() => ac.abort(), 8e3);
|
|
14040
|
+
let res;
|
|
14041
|
+
try {
|
|
14042
|
+
res = await fetchFn(CLAUDE_OAUTH_USAGE_URL, {
|
|
14043
|
+
headers: {
|
|
14044
|
+
Authorization: `Bearer ${token}`,
|
|
14045
|
+
"anthropic-beta": "oauth-2025-04-20",
|
|
14046
|
+
"User-Agent": userAgent
|
|
14047
|
+
},
|
|
14048
|
+
signal: ac.signal
|
|
14049
|
+
});
|
|
14050
|
+
} finally {
|
|
14051
|
+
clearTimeout(timer);
|
|
14052
|
+
}
|
|
14053
|
+
if (res.status === 401 || res.status === 403) {
|
|
14054
|
+
cache = { at: now, value: null };
|
|
14055
|
+
return null;
|
|
14056
|
+
}
|
|
14057
|
+
if (!res.ok) {
|
|
14058
|
+
errorUntil = now + CLAUDE_USAGE_ERROR_TTL_MS;
|
|
14059
|
+
return staleOk(now);
|
|
14060
|
+
}
|
|
14061
|
+
const usage = parseClaudeUsagePayload(await res.json(), new Date(now).toISOString());
|
|
14062
|
+
cache = { at: now, value: usage };
|
|
14063
|
+
if (usage) lastGood = { at: now, value: usage };
|
|
14064
|
+
return usage;
|
|
14065
|
+
} catch {
|
|
14066
|
+
errorUntil = now + CLAUDE_USAGE_ERROR_TTL_MS;
|
|
14067
|
+
return staleOk(now);
|
|
14068
|
+
} finally {
|
|
14069
|
+
inflight = null;
|
|
14070
|
+
}
|
|
14071
|
+
})();
|
|
14072
|
+
return inflight;
|
|
14073
|
+
}
|
|
14074
|
+
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;
|
|
14075
|
+
var init_claude_usage_client = __esm({
|
|
14076
|
+
"src/agents/claude-usage-client.ts"() {
|
|
14077
|
+
"use strict";
|
|
14078
|
+
import_node_fs37 = require("fs");
|
|
14079
|
+
import_node_os13 = require("os");
|
|
14080
|
+
import_node_path37 = require("path");
|
|
14081
|
+
init_run();
|
|
14082
|
+
init_fetch();
|
|
14083
|
+
init_app_settings();
|
|
14084
|
+
init_claude_usage();
|
|
14085
|
+
CLAUDE_OAUTH_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
|
|
14086
|
+
CLAUDE_USAGE_TTL_MS = 9e4;
|
|
14087
|
+
CLAUDE_USAGE_ERROR_TTL_MS = 5 * 6e4;
|
|
14088
|
+
CLAUDE_USAGE_STALE_OK_MS = 30 * 6e4;
|
|
14089
|
+
KEYCHAIN_SERVICES = ["Claude Code-credentials", "Claude Code"];
|
|
14090
|
+
cache = null;
|
|
14091
|
+
errorUntil = 0;
|
|
14092
|
+
inflight = null;
|
|
14093
|
+
lastGood = null;
|
|
14094
|
+
claudeVersion = null;
|
|
14095
|
+
}
|
|
14096
|
+
});
|
|
14097
|
+
|
|
13677
14098
|
// src/agents/install.ts
|
|
13678
14099
|
function getAgentSetupInfo(agent) {
|
|
13679
14100
|
return SETUP[agent];
|
|
@@ -13922,6 +14343,7 @@ __export(agents_exports, {
|
|
|
13922
14343
|
assertOrchestratorCapableAgent: () => assertOrchestratorCapableAgent,
|
|
13923
14344
|
brightsyAdapter: () => brightsyAdapter,
|
|
13924
14345
|
claudeAdapter: () => claudeAdapter,
|
|
14346
|
+
claudeUsageOverLimitWindows: () => claudeUsageOverLimitWindows,
|
|
13925
14347
|
codexAdapter: () => codexAdapter,
|
|
13926
14348
|
coerceOrchestratorAgent: () => coerceOrchestratorAgent,
|
|
13927
14349
|
conductorBundledBinDir: () => conductorBundledBinDir,
|
|
@@ -13931,8 +14353,18 @@ __export(agents_exports, {
|
|
|
13931
14353
|
encodeBrightsyTarget: () => encodeBrightsyTarget,
|
|
13932
14354
|
enrichPathWithNpmGlobalBin: () => enrichPathWithNpmGlobalBin,
|
|
13933
14355
|
ensureAgentPath: () => ensureAgentPath,
|
|
14356
|
+
formatClaudeExtraUsageDetail: () => formatClaudeExtraUsageDetail,
|
|
14357
|
+
formatClaudeUsageCompact: () => formatClaudeUsageCompact,
|
|
14358
|
+
formatClaudeUsageFetchedAt: () => formatClaudeUsageFetchedAt,
|
|
14359
|
+
formatClaudeUsageOverLimitConfirm: () => formatClaudeUsageOverLimitConfirm,
|
|
14360
|
+
formatClaudeUsageOverLimitWait: () => formatClaudeUsageOverLimitWait,
|
|
14361
|
+
formatClaudeUsageReset: () => formatClaudeUsageReset,
|
|
14362
|
+
formatClaudeUsageResetClock: () => formatClaudeUsageResetClock,
|
|
14363
|
+
formatClaudeUsageTooltip: () => formatClaudeUsageTooltip,
|
|
13934
14364
|
getAdapter: () => getAdapter,
|
|
13935
14365
|
getAgentSetupInfo: () => getAgentSetupInfo,
|
|
14366
|
+
getClaudePlanUsage: () => getClaudePlanUsage,
|
|
14367
|
+
hottestClaudeWindow: () => hottestClaudeWindow,
|
|
13936
14368
|
installAgent: () => installAgent,
|
|
13937
14369
|
installNpmGlobalPackage: () => installNpmGlobalPackage,
|
|
13938
14370
|
isConductorBundledCli: () => isConductorBundledCli,
|
|
@@ -13950,6 +14382,7 @@ __export(agents_exports, {
|
|
|
13950
14382
|
mcpStatusThinkingFromClaudeInit: () => mcpStatusThinkingFromClaudeInit,
|
|
13951
14383
|
openInSystemTerminal: () => openInSystemTerminal,
|
|
13952
14384
|
opencodeAdapter: () => opencodeAdapter,
|
|
14385
|
+
parseClaudeUsagePayload: () => parseClaudeUsagePayload,
|
|
13953
14386
|
parseCursorRunnerLine: () => parseCursorRunnerLine,
|
|
13954
14387
|
parseSessionQuotaResetAt: () => parseSessionQuotaResetAt,
|
|
13955
14388
|
permissionMode: () => permissionMode,
|
|
@@ -13990,6 +14423,8 @@ var init_agents = __esm({
|
|
|
13990
14423
|
init_opencode();
|
|
13991
14424
|
init_list_models();
|
|
13992
14425
|
init_session_quota();
|
|
14426
|
+
init_claude_usage();
|
|
14427
|
+
init_claude_usage_client();
|
|
13993
14428
|
init_orchestrator_capable();
|
|
13994
14429
|
init_path();
|
|
13995
14430
|
init_install();
|
|
@@ -14005,15 +14440,15 @@ var init_agents = __esm({
|
|
|
14005
14440
|
|
|
14006
14441
|
// src/hook/worktree-pkg-cache.ts
|
|
14007
14442
|
function worktreePkgCacheRoot(worktreePath) {
|
|
14008
|
-
return (0,
|
|
14443
|
+
return (0, import_node_path38.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
|
|
14009
14444
|
}
|
|
14010
14445
|
function worktreePkgCacheEnv(worktreePath) {
|
|
14011
14446
|
const root = worktreePkgCacheRoot(worktreePath);
|
|
14012
|
-
const store = (0,
|
|
14013
|
-
const pnpmCache = (0,
|
|
14014
|
-
const npmCache = (0,
|
|
14015
|
-
const nodeGyp = (0,
|
|
14016
|
-
const electron = (0,
|
|
14447
|
+
const store = (0, import_node_path38.join)(root, "pnpm-store");
|
|
14448
|
+
const pnpmCache = (0, import_node_path38.join)(root, "pnpm");
|
|
14449
|
+
const npmCache = (0, import_node_path38.join)(root, "npm");
|
|
14450
|
+
const nodeGyp = (0, import_node_path38.join)(root, "node-gyp");
|
|
14451
|
+
const electron = (0, import_node_path38.join)(root, "electron");
|
|
14017
14452
|
return {
|
|
14018
14453
|
npm_config_store_dir: store,
|
|
14019
14454
|
PNPM_STORE_DIR: store,
|
|
@@ -14035,8 +14470,8 @@ function fillGroup(env, keys, values) {
|
|
|
14035
14470
|
}
|
|
14036
14471
|
}
|
|
14037
14472
|
function ensureWorktreePkgCacheDirs(worktreePath) {
|
|
14038
|
-
if (!(0,
|
|
14039
|
-
(0,
|
|
14473
|
+
if (!(0, import_node_fs38.existsSync)(worktreePath)) return;
|
|
14474
|
+
(0, import_node_fs38.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
|
|
14040
14475
|
}
|
|
14041
14476
|
function applyWorktreePkgCacheEnv(env, worktreePath) {
|
|
14042
14477
|
const cwd = worktreePath.trim();
|
|
@@ -14049,12 +14484,12 @@ function applyWorktreePkgCacheEnv(env, worktreePath) {
|
|
|
14049
14484
|
fillGroup(env, ["electron_config_cache"], next);
|
|
14050
14485
|
ensureWorktreePkgCacheDirs(cwd);
|
|
14051
14486
|
}
|
|
14052
|
-
var
|
|
14487
|
+
var import_node_fs38, import_node_path38, WORKTREE_PKG_CACHE_REL;
|
|
14053
14488
|
var init_worktree_pkg_cache = __esm({
|
|
14054
14489
|
"src/hook/worktree-pkg-cache.ts"() {
|
|
14055
14490
|
"use strict";
|
|
14056
|
-
|
|
14057
|
-
|
|
14491
|
+
import_node_fs38 = require("fs");
|
|
14492
|
+
import_node_path38 = require("path");
|
|
14058
14493
|
WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
|
|
14059
14494
|
}
|
|
14060
14495
|
});
|
|
@@ -15213,21 +15648,21 @@ function shouldRefreshReviewRequestTemplate(content) {
|
|
|
15213
15648
|
return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
|
|
15214
15649
|
}
|
|
15215
15650
|
function readTextIfPresent(abs) {
|
|
15216
|
-
if (!(0,
|
|
15651
|
+
if (!(0, import_node_fs39.existsSync)(abs)) return null;
|
|
15217
15652
|
try {
|
|
15218
|
-
const content = (0,
|
|
15653
|
+
const content = (0, import_node_fs39.readFileSync)(abs, "utf8");
|
|
15219
15654
|
return content.trim() ? content : null;
|
|
15220
15655
|
} catch {
|
|
15221
15656
|
return null;
|
|
15222
15657
|
}
|
|
15223
15658
|
}
|
|
15224
15659
|
function readLocalGuidelines(worktreePath) {
|
|
15225
|
-
const localAbs = (0,
|
|
15660
|
+
const localAbs = (0, import_node_path39.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
15226
15661
|
const localContent = readTextIfPresent(localAbs);
|
|
15227
15662
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
15228
15663
|
return { path: REVIEW_REQUEST_PATH, content: localContent };
|
|
15229
15664
|
}
|
|
15230
|
-
const legacyAbs = (0,
|
|
15665
|
+
const legacyAbs = (0, import_node_path39.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
|
|
15231
15666
|
const legacyContent = readTextIfPresent(legacyAbs);
|
|
15232
15667
|
if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
|
|
15233
15668
|
return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
|
|
@@ -15251,27 +15686,27 @@ function contextGuidelines(content, source) {
|
|
|
15251
15686
|
};
|
|
15252
15687
|
}
|
|
15253
15688
|
function writeContextGuidelines(worktreePath, content) {
|
|
15254
|
-
const abs = (0,
|
|
15255
|
-
(0,
|
|
15689
|
+
const abs = (0, import_node_path39.join)(worktreePath, CONTEXT_REVIEW_PATH);
|
|
15690
|
+
(0, import_node_fs39.mkdirSync)((0, import_node_path39.dirname)(abs), { recursive: true });
|
|
15256
15691
|
const body = content.endsWith("\n") ? content : `${content}
|
|
15257
15692
|
`;
|
|
15258
|
-
(0,
|
|
15693
|
+
(0, import_node_fs39.writeFileSync)(abs, body, "utf8");
|
|
15259
15694
|
return body;
|
|
15260
15695
|
}
|
|
15261
15696
|
function readSideboardReview(worktreePath, repoPath) {
|
|
15262
|
-
const fromWorktree = readTextIfPresent((0,
|
|
15697
|
+
const fromWorktree = readTextIfPresent((0, import_node_path39.join)(worktreePath, REPO_REVIEW_PATH));
|
|
15263
15698
|
if (fromWorktree) return fromWorktree;
|
|
15264
15699
|
const repo = repoPath?.replace(/\/+$/, "");
|
|
15265
15700
|
const wt = worktreePath.replace(/\/+$/, "");
|
|
15266
15701
|
if (!repo || repo === wt) return null;
|
|
15267
|
-
return readTextIfPresent((0,
|
|
15702
|
+
return readTextIfPresent((0, import_node_path39.join)(repo, REPO_REVIEW_PATH));
|
|
15268
15703
|
}
|
|
15269
15704
|
function ensureReviewGuidelinesFile(worktreePath, repoPath) {
|
|
15270
|
-
const skillContent = readTextIfPresent((0,
|
|
15705
|
+
const skillContent = readTextIfPresent((0, import_node_path39.join)(worktreePath, REVIEW_SKILL_PATH));
|
|
15271
15706
|
if (skillContent) {
|
|
15272
15707
|
return { ...skillGuidelines(skillContent, "skill"), wrote: false };
|
|
15273
15708
|
}
|
|
15274
|
-
const contextContent = readTextIfPresent((0,
|
|
15709
|
+
const contextContent = readTextIfPresent((0, import_node_path39.join)(worktreePath, CONTEXT_REVIEW_PATH));
|
|
15275
15710
|
if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
|
|
15276
15711
|
return { ...contextGuidelines(contextContent, "local"), wrote: false };
|
|
15277
15712
|
}
|
|
@@ -15309,7 +15744,7 @@ function buildReviewRequestAttachment(content, opts) {
|
|
|
15309
15744
|
};
|
|
15310
15745
|
}
|
|
15311
15746
|
function readExistingReviewRequestFile(worktreePath) {
|
|
15312
|
-
return readTextIfPresent((0,
|
|
15747
|
+
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));
|
|
15313
15748
|
}
|
|
15314
15749
|
async function requestReview(threadRef, send2) {
|
|
15315
15750
|
const from = findThreadByRef(threadRef);
|
|
@@ -15336,13 +15771,13 @@ async function requestReview(threadRef, send2) {
|
|
|
15336
15771
|
const started = await send2(tab.id, REVIEW_REQUEST_PREFILL);
|
|
15337
15772
|
return { tab: started, from };
|
|
15338
15773
|
}
|
|
15339
|
-
var import_node_crypto9,
|
|
15774
|
+
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;
|
|
15340
15775
|
var init_request_review = __esm({
|
|
15341
15776
|
"src/review/request-review.ts"() {
|
|
15342
15777
|
"use strict";
|
|
15343
15778
|
import_node_crypto9 = require("crypto");
|
|
15344
|
-
|
|
15345
|
-
|
|
15779
|
+
import_node_fs39 = require("fs");
|
|
15780
|
+
import_node_path39 = require("path");
|
|
15346
15781
|
init_global_workspace();
|
|
15347
15782
|
init_chat_tabs();
|
|
15348
15783
|
init_thread_store();
|
|
@@ -15368,9 +15803,9 @@ function matchSimpleGlob(pattern, name) {
|
|
|
15368
15803
|
return new RegExp(`^${escaped}$`).test(name);
|
|
15369
15804
|
}
|
|
15370
15805
|
function readWorktreeInclude(repoPath) {
|
|
15371
|
-
const path2 = (0,
|
|
15372
|
-
if (!(0,
|
|
15373
|
-
return (0,
|
|
15806
|
+
const path2 = (0, import_node_path40.join)(repoPath, ".worktreeinclude");
|
|
15807
|
+
if (!(0, import_node_fs40.existsSync)(path2)) return [];
|
|
15808
|
+
return (0, import_node_fs40.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
15374
15809
|
}
|
|
15375
15810
|
function resolveFilesToCopy(repoPath) {
|
|
15376
15811
|
const fromInclude = readWorktreeInclude(repoPath);
|
|
@@ -15380,10 +15815,10 @@ function resolveFilesToCopy(repoPath) {
|
|
|
15380
15815
|
if (settings?.fileIncludeGlobs?.length) {
|
|
15381
15816
|
const matched = [];
|
|
15382
15817
|
try {
|
|
15383
|
-
for (const entry of (0,
|
|
15818
|
+
for (const entry of (0, import_node_fs40.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
15384
15819
|
if (!entry.isFile()) continue;
|
|
15385
15820
|
for (const glob of settings.fileIncludeGlobs) {
|
|
15386
|
-
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0,
|
|
15821
|
+
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path40.basename)(glob), entry.name)) {
|
|
15387
15822
|
matched.push(entry.name);
|
|
15388
15823
|
break;
|
|
15389
15824
|
}
|
|
@@ -15395,7 +15830,7 @@ function resolveFilesToCopy(repoPath) {
|
|
|
15395
15830
|
}
|
|
15396
15831
|
const defaults = [];
|
|
15397
15832
|
try {
|
|
15398
|
-
for (const entry of (0,
|
|
15833
|
+
for (const entry of (0, import_node_fs40.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
15399
15834
|
if (entry.isFile() && entry.name.startsWith(".env")) {
|
|
15400
15835
|
defaults.push(entry.name);
|
|
15401
15836
|
}
|
|
@@ -15409,11 +15844,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
|
|
|
15409
15844
|
const patterns = resolveFilesToCopy(repoPath);
|
|
15410
15845
|
const copied = [];
|
|
15411
15846
|
for (const rel of patterns) {
|
|
15412
|
-
const src = (0,
|
|
15413
|
-
if (!(0,
|
|
15414
|
-
const dest = (0,
|
|
15415
|
-
(0,
|
|
15416
|
-
(0,
|
|
15847
|
+
const src = (0, import_node_path40.join)(repoPath, rel);
|
|
15848
|
+
if (!(0, import_node_fs40.existsSync)(src)) continue;
|
|
15849
|
+
const dest = (0, import_node_path40.join)(worktreePath, rel);
|
|
15850
|
+
(0, import_node_fs40.mkdirSync)((0, import_node_path40.dirname)(dest), { recursive: true });
|
|
15851
|
+
(0, import_node_fs40.copyFileSync)(src, dest);
|
|
15417
15852
|
copied.push(rel);
|
|
15418
15853
|
}
|
|
15419
15854
|
return copied;
|
|
@@ -15448,7 +15883,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
|
15448
15883
|
const env = stripNestedElectronEnv({
|
|
15449
15884
|
...baseEnv ?? process.env
|
|
15450
15885
|
});
|
|
15451
|
-
const name = opts.workspaceName ?? (0,
|
|
15886
|
+
const name = opts.workspaceName ?? (0, import_node_path40.basename)(opts.worktreePath);
|
|
15452
15887
|
const ports = opts.ports ?? [];
|
|
15453
15888
|
const primary = ports[0];
|
|
15454
15889
|
env.SIDEBOARD_WORKSPACE_NAME = name;
|
|
@@ -15711,13 +16146,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
15711
16146
|
done: handle.done
|
|
15712
16147
|
};
|
|
15713
16148
|
}
|
|
15714
|
-
var
|
|
16149
|
+
var import_node_fs40, import_node_net, import_node_path40, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
|
|
15715
16150
|
var init_conductor = __esm({
|
|
15716
16151
|
"src/hook/conductor.ts"() {
|
|
15717
16152
|
"use strict";
|
|
15718
|
-
|
|
16153
|
+
import_node_fs40 = require("fs");
|
|
15719
16154
|
import_node_net = require("net");
|
|
15720
|
-
|
|
16155
|
+
import_node_path40 = require("path");
|
|
15721
16156
|
import_execa4 = require("execa");
|
|
15722
16157
|
import_node_readline3 = require("readline");
|
|
15723
16158
|
init_settings();
|
|
@@ -15745,9 +16180,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
15745
16180
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
15746
16181
|
);
|
|
15747
16182
|
const homeRoot = sideboardWorkspacesDir();
|
|
15748
|
-
if ((0,
|
|
16183
|
+
if ((0, import_node_fs41.existsSync)(homeRoot)) {
|
|
15749
16184
|
try {
|
|
15750
|
-
for (const entry of (0,
|
|
16185
|
+
for (const entry of (0, import_node_fs41.readdirSync)(homeRoot, { withFileTypes: true })) {
|
|
15751
16186
|
if (!entry.isDirectory()) continue;
|
|
15752
16187
|
void entry;
|
|
15753
16188
|
}
|
|
@@ -15757,7 +16192,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
15757
16192
|
const orphans = [];
|
|
15758
16193
|
const seen = /* @__PURE__ */ new Set();
|
|
15759
16194
|
for (const repoPath of repos) {
|
|
15760
|
-
if (!repoPath || !(0,
|
|
16195
|
+
if (!repoPath || !(0, import_node_fs41.existsSync)(repoPath)) continue;
|
|
15761
16196
|
try {
|
|
15762
16197
|
const wts = await listWorktrees(repoPath);
|
|
15763
16198
|
for (const wt of wts) {
|
|
@@ -15768,7 +16203,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
15768
16203
|
seen.add(path2);
|
|
15769
16204
|
let mtimeMs = 0;
|
|
15770
16205
|
try {
|
|
15771
|
-
mtimeMs = (0,
|
|
16206
|
+
mtimeMs = (0, import_node_fs41.statSync)(path2).mtimeMs;
|
|
15772
16207
|
} catch {
|
|
15773
16208
|
mtimeMs = 0;
|
|
15774
16209
|
}
|
|
@@ -15778,16 +16213,16 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
15778
16213
|
}
|
|
15779
16214
|
try {
|
|
15780
16215
|
const root = worktreesRoot(repoPath);
|
|
15781
|
-
if ((0,
|
|
15782
|
-
for (const entry of (0,
|
|
16216
|
+
if ((0, import_node_fs41.existsSync)(root)) {
|
|
16217
|
+
for (const entry of (0, import_node_fs41.readdirSync)(root, { withFileTypes: true })) {
|
|
15783
16218
|
if (!entry.isDirectory()) continue;
|
|
15784
|
-
const path2 = (0,
|
|
16219
|
+
const path2 = (0, import_node_path41.join)(root, entry.name).replace(/\/$/, "");
|
|
15785
16220
|
if (known.has(path2) || seen.has(path2)) continue;
|
|
15786
|
-
if (!(0,
|
|
16221
|
+
if (!(0, import_node_fs41.existsSync)((0, import_node_path41.join)(path2, ".git"))) continue;
|
|
15787
16222
|
seen.add(path2);
|
|
15788
16223
|
let mtimeMs = 0;
|
|
15789
16224
|
try {
|
|
15790
|
-
mtimeMs = (0,
|
|
16225
|
+
mtimeMs = (0, import_node_fs41.statSync)(path2).mtimeMs;
|
|
15791
16226
|
} catch {
|
|
15792
16227
|
mtimeMs = Date.now();
|
|
15793
16228
|
}
|
|
@@ -15848,12 +16283,12 @@ function worktreeCleanupSettings() {
|
|
|
15848
16283
|
autoCleanupOrphans: a.autoCleanupOrphans
|
|
15849
16284
|
};
|
|
15850
16285
|
}
|
|
15851
|
-
var
|
|
16286
|
+
var import_node_fs41, import_node_path41;
|
|
15852
16287
|
var init_orphan_cleanup = __esm({
|
|
15853
16288
|
"src/git/orphan-cleanup.ts"() {
|
|
15854
16289
|
"use strict";
|
|
15855
|
-
|
|
15856
|
-
|
|
16290
|
+
import_node_fs41 = require("fs");
|
|
16291
|
+
import_node_path41 = require("path");
|
|
15857
16292
|
init_worktree();
|
|
15858
16293
|
init_thread_store();
|
|
15859
16294
|
init_paths();
|
|
@@ -15956,12 +16391,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
15956
16391
|
if (!url) throw new Error("Clone URL is required");
|
|
15957
16392
|
let name = opts.name?.trim();
|
|
15958
16393
|
if (!name) {
|
|
15959
|
-
const leaf = (0,
|
|
16394
|
+
const leaf = (0, import_node_path42.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
|
|
15960
16395
|
name = leaf || "repo";
|
|
15961
16396
|
}
|
|
15962
16397
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
15963
|
-
const dest = (0,
|
|
15964
|
-
if ((0,
|
|
16398
|
+
const dest = (0, import_node_path42.join)(sideboardReposDir(), name);
|
|
16399
|
+
if ((0, import_node_fs42.existsSync)(dest)) {
|
|
15965
16400
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
15966
16401
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
15967
16402
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -15976,12 +16411,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
15976
16411
|
const workspace = await ensureWorkspace(repoPath);
|
|
15977
16412
|
return { repoPath, workspace };
|
|
15978
16413
|
}
|
|
15979
|
-
var
|
|
16414
|
+
var import_node_fs42, import_node_path42, import_execa6;
|
|
15980
16415
|
var init_clone_repo = __esm({
|
|
15981
16416
|
"src/git/clone-repo.ts"() {
|
|
15982
16417
|
"use strict";
|
|
15983
|
-
|
|
15984
|
-
|
|
16418
|
+
import_node_fs42 = require("fs");
|
|
16419
|
+
import_node_path42 = require("path");
|
|
15985
16420
|
import_execa6 = require("execa");
|
|
15986
16421
|
init_paths();
|
|
15987
16422
|
init_workspaces();
|
|
@@ -16099,24 +16534,24 @@ function jobTreeAlive(pid) {
|
|
|
16099
16534
|
return jobAlive(pid) || processGroupAlive(pid);
|
|
16100
16535
|
}
|
|
16101
16536
|
function readIntFile(file) {
|
|
16102
|
-
if (!(0,
|
|
16103
|
-
const n = Number.parseInt((0,
|
|
16537
|
+
if (!(0, import_node_fs43.existsSync)(file)) return null;
|
|
16538
|
+
const n = Number.parseInt((0, import_node_fs43.readFileSync)(file, "utf8").trim(), 10);
|
|
16104
16539
|
return Number.isInteger(n) ? n : null;
|
|
16105
16540
|
}
|
|
16106
16541
|
function jobDir(root, id, legacy = false) {
|
|
16107
|
-
return (0,
|
|
16542
|
+
return (0, import_node_path43.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
|
|
16108
16543
|
}
|
|
16109
16544
|
function resolveJobDir(root, id) {
|
|
16110
16545
|
const modern = jobDir(root, id, false);
|
|
16111
|
-
if ((0,
|
|
16546
|
+
if ((0, import_node_fs43.existsSync)(modern)) return modern;
|
|
16112
16547
|
const legacy = jobDir(root, id, true);
|
|
16113
|
-
if ((0,
|
|
16548
|
+
if ((0, import_node_fs43.existsSync)(legacy)) return legacy;
|
|
16114
16549
|
return modern;
|
|
16115
16550
|
}
|
|
16116
16551
|
function listJobIdsIn(root, rel) {
|
|
16117
|
-
const dir = (0,
|
|
16118
|
-
if (!(0,
|
|
16119
|
-
return (0,
|
|
16552
|
+
const dir = (0, import_node_path43.join)(root, rel);
|
|
16553
|
+
if (!(0, import_node_fs43.existsSync)(dir)) return [];
|
|
16554
|
+
return (0, import_node_fs43.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
|
|
16120
16555
|
}
|
|
16121
16556
|
function listRunningDetachedJobs(worktreePath) {
|
|
16122
16557
|
const root = worktreePath.trim();
|
|
@@ -16128,7 +16563,7 @@ function listRunningDetachedJobs(worktreePath) {
|
|
|
16128
16563
|
const running = [];
|
|
16129
16564
|
for (const id of ids) {
|
|
16130
16565
|
const dir = resolveJobDir(root, id);
|
|
16131
|
-
const pid = readIntFile((0,
|
|
16566
|
+
const pid = readIntFile((0, import_node_path43.join)(dir, "pid"));
|
|
16132
16567
|
if (jobTreeAlive(pid)) running.push(id);
|
|
16133
16568
|
}
|
|
16134
16569
|
return running.sort();
|
|
@@ -16210,8 +16645,8 @@ function planJobContinue(opts) {
|
|
|
16210
16645
|
return { action: "none" };
|
|
16211
16646
|
}
|
|
16212
16647
|
function tailProgress(logFile, maxLines = 12) {
|
|
16213
|
-
if (!(0,
|
|
16214
|
-
const lines = (0,
|
|
16648
|
+
if (!(0, import_node_fs43.existsSync)(logFile)) return "(no log yet)";
|
|
16649
|
+
const lines = (0, import_node_fs43.readFileSync)(logFile, "utf8").split("\n");
|
|
16215
16650
|
return lines.slice(-maxLines).join("\n");
|
|
16216
16651
|
}
|
|
16217
16652
|
function lastProgressLine(progress) {
|
|
@@ -16219,8 +16654,8 @@ function lastProgressLine(progress) {
|
|
|
16219
16654
|
return last ? last.slice(0, 72) : void 0;
|
|
16220
16655
|
}
|
|
16221
16656
|
function readLogLines(file) {
|
|
16222
|
-
if (!(0,
|
|
16223
|
-
const lines = (0,
|
|
16657
|
+
if (!(0, import_node_fs43.existsSync)(file)) return [];
|
|
16658
|
+
const lines = (0, import_node_fs43.readFileSync)(file, "utf8").split("\n");
|
|
16224
16659
|
if (lines.length && lines[lines.length - 1] === "") lines.pop();
|
|
16225
16660
|
return lines;
|
|
16226
16661
|
}
|
|
@@ -16231,15 +16666,15 @@ function takeDelta(logFile, cursorFile) {
|
|
|
16231
16666
|
return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
|
|
16232
16667
|
}
|
|
16233
16668
|
function snapshotJob(dir) {
|
|
16234
|
-
const pid = readIntFile((0,
|
|
16669
|
+
const pid = readIntFile((0, import_node_path43.join)(dir, "pid"));
|
|
16235
16670
|
const running = jobTreeAlive(pid);
|
|
16236
16671
|
return {
|
|
16237
16672
|
pid,
|
|
16238
16673
|
running,
|
|
16239
|
-
exitCode: readIntFile((0,
|
|
16240
|
-
log: (0,
|
|
16241
|
-
cursor: (0,
|
|
16242
|
-
progress: tailProgress((0,
|
|
16674
|
+
exitCode: readIntFile((0, import_node_path43.join)(dir, "exit")),
|
|
16675
|
+
log: (0, import_node_path43.join)(dir, "log"),
|
|
16676
|
+
cursor: (0, import_node_path43.join)(dir, "present.cursor"),
|
|
16677
|
+
progress: tailProgress((0, import_node_path43.join)(dir, "log"))
|
|
16243
16678
|
};
|
|
16244
16679
|
}
|
|
16245
16680
|
function toResult(id, snap, extra) {
|
|
@@ -16248,8 +16683,8 @@ function toResult(id, snap, extra) {
|
|
|
16248
16683
|
const stillRunning = snap.running && !ok;
|
|
16249
16684
|
const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
|
|
16250
16685
|
try {
|
|
16251
|
-
(0,
|
|
16252
|
-
(0,
|
|
16686
|
+
(0, import_node_fs43.mkdirSync)((0, import_node_path43.dirname)(snap.cursor), { recursive: true });
|
|
16687
|
+
(0, import_node_fs43.writeFileSync)(snap.cursor, `${nextCursor}
|
|
16253
16688
|
`);
|
|
16254
16689
|
} catch {
|
|
16255
16690
|
}
|
|
@@ -16278,7 +16713,7 @@ async function waitForDetachedJob(cwd, id, opts) {
|
|
|
16278
16713
|
const dir = resolveJobDir(root, jobId);
|
|
16279
16714
|
const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
|
|
16280
16715
|
const sleep2 = opts?.sleep ?? sleepMs;
|
|
16281
|
-
if (!(0,
|
|
16716
|
+
if (!(0, import_node_fs43.existsSync)(dir)) {
|
|
16282
16717
|
return {
|
|
16283
16718
|
stillRunning: false,
|
|
16284
16719
|
ok: false,
|
|
@@ -16324,10 +16759,10 @@ function killProcessTree(pid, signal) {
|
|
|
16324
16759
|
}
|
|
16325
16760
|
function appendJobLog(logFile, line) {
|
|
16326
16761
|
try {
|
|
16327
|
-
(0,
|
|
16762
|
+
(0, import_node_fs43.mkdirSync)((0, import_node_path43.dirname)(logFile), { recursive: true });
|
|
16328
16763
|
const body = line.endsWith("\n") ? line : `${line}
|
|
16329
16764
|
`;
|
|
16330
|
-
(0,
|
|
16765
|
+
(0, import_node_fs43.appendFileSync)(logFile, body);
|
|
16331
16766
|
} catch {
|
|
16332
16767
|
}
|
|
16333
16768
|
}
|
|
@@ -16337,7 +16772,7 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
16337
16772
|
const dir = resolveJobDir(root, jobId);
|
|
16338
16773
|
const sleep2 = opts?.sleep ?? sleepMs;
|
|
16339
16774
|
const why = opts?.reason?.trim() ?? "";
|
|
16340
|
-
if (!(0,
|
|
16775
|
+
if (!(0, import_node_fs43.existsSync)(dir)) {
|
|
16341
16776
|
return {
|
|
16342
16777
|
stillRunning: false,
|
|
16343
16778
|
ok: false,
|
|
@@ -16373,10 +16808,10 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
16373
16808
|
killProcessTree(targetPid, "SIGKILL");
|
|
16374
16809
|
await sleep2(100);
|
|
16375
16810
|
}
|
|
16376
|
-
const exitFile = (0,
|
|
16377
|
-
if (!(0,
|
|
16811
|
+
const exitFile = (0, import_node_path43.join)(dir, "exit");
|
|
16812
|
+
if (!(0, import_node_fs43.existsSync)(exitFile)) {
|
|
16378
16813
|
try {
|
|
16379
|
-
(0,
|
|
16814
|
+
(0, import_node_fs43.writeFileSync)(exitFile, "1\n");
|
|
16380
16815
|
} catch {
|
|
16381
16816
|
}
|
|
16382
16817
|
}
|
|
@@ -16396,12 +16831,12 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
16396
16831
|
hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
|
|
16397
16832
|
};
|
|
16398
16833
|
}
|
|
16399
|
-
var
|
|
16834
|
+
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;
|
|
16400
16835
|
var init_wait_for_job = __esm({
|
|
16401
16836
|
"src/mcp/wait-for-job.ts"() {
|
|
16402
16837
|
"use strict";
|
|
16403
|
-
|
|
16404
|
-
|
|
16838
|
+
import_node_fs43 = require("fs");
|
|
16839
|
+
import_node_path43 = require("path");
|
|
16405
16840
|
init_workspace_scratch();
|
|
16406
16841
|
init_wait_for_turn();
|
|
16407
16842
|
MAX_JOB_CONTINUES = 8;
|
|
@@ -17689,7 +18124,7 @@ function reuseLiveThread(input, repoPath, match) {
|
|
|
17689
18124
|
}
|
|
17690
18125
|
async function createThread(input, _onSetupLine) {
|
|
17691
18126
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
17692
|
-
if (!(0,
|
|
18127
|
+
if (!(0, import_node_fs44.existsSync)(repoPath)) {
|
|
17693
18128
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
17694
18129
|
}
|
|
17695
18130
|
const reused = reuseLiveThread(input, repoPath, {
|
|
@@ -17874,11 +18309,11 @@ async function listLinearIssues(agent, repoPath) {
|
|
|
17874
18309
|
}
|
|
17875
18310
|
return adapter.listLinearIssues(repoPath);
|
|
17876
18311
|
}
|
|
17877
|
-
var
|
|
18312
|
+
var import_node_fs44;
|
|
17878
18313
|
var init_create = __esm({
|
|
17879
18314
|
"src/threads/create.ts"() {
|
|
17880
18315
|
"use strict";
|
|
17881
|
-
|
|
18316
|
+
import_node_fs44 = require("fs");
|
|
17882
18317
|
init_detect();
|
|
17883
18318
|
init_worktree();
|
|
17884
18319
|
init_home_board();
|
|
@@ -17998,20 +18433,20 @@ function writeTurnLive(threadId, progress) {
|
|
|
17998
18433
|
const path2 = threadLivePath(threadId);
|
|
17999
18434
|
const tmp = `${path2}.${process.pid}.tmp`;
|
|
18000
18435
|
try {
|
|
18001
|
-
(0,
|
|
18002
|
-
(0,
|
|
18436
|
+
(0, import_node_fs45.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
|
|
18437
|
+
(0, import_node_fs45.renameSync)(tmp, path2);
|
|
18003
18438
|
} catch {
|
|
18004
18439
|
try {
|
|
18005
|
-
(0,
|
|
18440
|
+
(0, import_node_fs45.unlinkSync)(tmp);
|
|
18006
18441
|
} catch {
|
|
18007
18442
|
}
|
|
18008
18443
|
}
|
|
18009
18444
|
}
|
|
18010
18445
|
function readTurnLive(threadId) {
|
|
18011
18446
|
const path2 = threadLivePath(threadId);
|
|
18012
|
-
if (!(0,
|
|
18447
|
+
if (!(0, import_node_fs45.existsSync)(path2)) return null;
|
|
18013
18448
|
try {
|
|
18014
|
-
const raw = JSON.parse((0,
|
|
18449
|
+
const raw = JSON.parse((0, import_node_fs45.readFileSync)(path2, "utf8"));
|
|
18015
18450
|
if (!raw || typeof raw.summary !== "string") return null;
|
|
18016
18451
|
return raw;
|
|
18017
18452
|
} catch {
|
|
@@ -18023,17 +18458,17 @@ function clearTurnLive(threadId) {
|
|
|
18023
18458
|
if (buf?.timer) clearTimeout(buf.timer);
|
|
18024
18459
|
buffers.delete(threadId);
|
|
18025
18460
|
const path2 = threadLivePath(threadId);
|
|
18026
|
-
if (!(0,
|
|
18461
|
+
if (!(0, import_node_fs45.existsSync)(path2)) return;
|
|
18027
18462
|
try {
|
|
18028
|
-
(0,
|
|
18463
|
+
(0, import_node_fs45.unlinkSync)(path2);
|
|
18029
18464
|
} catch {
|
|
18030
18465
|
}
|
|
18031
18466
|
}
|
|
18032
|
-
var
|
|
18467
|
+
var import_node_fs45, buffers, FLUSH_MS, MAX_PARTS;
|
|
18033
18468
|
var init_turn_live = __esm({
|
|
18034
18469
|
"src/store/turn-live.ts"() {
|
|
18035
18470
|
"use strict";
|
|
18036
|
-
|
|
18471
|
+
import_node_fs45 = require("fs");
|
|
18037
18472
|
init_message_parts();
|
|
18038
18473
|
init_paths();
|
|
18039
18474
|
buffers = /* @__PURE__ */ new Map();
|
|
@@ -18136,12 +18571,18 @@ var init_fork_worktree = __esm({
|
|
|
18136
18571
|
|
|
18137
18572
|
// src/orchestrator/quota-failover.ts
|
|
18138
18573
|
function planOrchestrationQuotaFailover(thread, limitText, opts) {
|
|
18139
|
-
if (!isOrchestratorThread(thread)) return null;
|
|
18140
18574
|
if (!isSessionQuotaLimit(limitText)) return null;
|
|
18141
|
-
const onLimit = opts?.onLimit ??
|
|
18575
|
+
const onLimit = opts?.onLimit ?? usageOnLimit();
|
|
18142
18576
|
const resumeAt = parseSessionQuotaResetAt(limitText, opts?.now);
|
|
18577
|
+
if (onLimit === "keep_going" || onLimit === "confirm") {
|
|
18578
|
+
return {
|
|
18579
|
+
action: "none",
|
|
18580
|
+
reason: onLimit === "confirm" ? "Settings: confirm with user; no automatic continue." : "Settings: keep going; no automatic continue.",
|
|
18581
|
+
limitText
|
|
18582
|
+
};
|
|
18583
|
+
}
|
|
18143
18584
|
if (thread.quotaContinuedFromId) {
|
|
18144
|
-
if (resumeAt) {
|
|
18585
|
+
if (onLimit === "switch_agent" && resumeAt) {
|
|
18145
18586
|
return {
|
|
18146
18587
|
action: "wait_reset",
|
|
18147
18588
|
reason: "Already continued once; waiting for quota reset instead.",
|
|
@@ -18151,7 +18592,7 @@ function planOrchestrationQuotaFailover(thread, limitText, opts) {
|
|
|
18151
18592
|
}
|
|
18152
18593
|
return {
|
|
18153
18594
|
action: "none",
|
|
18154
|
-
reason: "Already continued once; no
|
|
18595
|
+
reason: "Already continued once; no further automatic continue.",
|
|
18155
18596
|
limitText
|
|
18156
18597
|
};
|
|
18157
18598
|
}
|
|
@@ -18188,8 +18629,19 @@ function buildQuotaHandoffAttachment(from, limitText, fallbackAgent) {
|
|
|
18188
18629
|
const text7 = m.text.trim().replace(/\s+/g, " ").slice(0, 280);
|
|
18189
18630
|
return text7 ? `- ${role}: ${text7}` : null;
|
|
18190
18631
|
}).filter(Boolean);
|
|
18632
|
+
const orch = isOrchestratorThread(from);
|
|
18633
|
+
const instructions = orch ? [
|
|
18634
|
+
"- Continue fleet orchestration from this handoff.",
|
|
18635
|
+
"- Prefer Sideboard MCP (list_board, list_threads, get_thread, send_to_thread, \u2026) for live status.",
|
|
18636
|
+
"- Leave model Auto unless there is a specific reason to pin one.",
|
|
18637
|
+
`- Do not wait on the limited ${from.agent} account; keep going on ${fallbackAgent}.`
|
|
18638
|
+
] : [
|
|
18639
|
+
"- Continue this worktree chat from the handoff.",
|
|
18640
|
+
"- Leave model Auto unless there is a specific reason to pin one.",
|
|
18641
|
+
`- Do not wait on the limited ${from.agent} account; keep going on ${fallbackAgent}.`
|
|
18642
|
+
];
|
|
18191
18643
|
const body = [
|
|
18192
|
-
`# Orchestration handoff`,
|
|
18644
|
+
`# ${orch ? "Orchestration" : "Chat"} handoff`,
|
|
18193
18645
|
"",
|
|
18194
18646
|
`Previous chat: ${from.title} (\`${from.id}\`) on **${from.agent}** hit a session/usage limit.`,
|
|
18195
18647
|
`Limit: ${limitText.trim()}`,
|
|
@@ -18205,14 +18657,11 @@ function buildQuotaHandoffAttachment(from, limitText, fallbackAgent) {
|
|
|
18205
18657
|
recent.length ? recent.join("\n") : "(none)",
|
|
18206
18658
|
"",
|
|
18207
18659
|
`## Instructions`,
|
|
18208
|
-
|
|
18209
|
-
`- Prefer Sideboard MCP (list_board, list_threads, get_thread, send_to_thread, \u2026) for live status.`,
|
|
18210
|
-
`- Leave model Auto unless there is a specific reason to pin one.`,
|
|
18211
|
-
`- Do not wait on the limited ${from.agent} account; keep going on ${fallbackAgent}.`
|
|
18660
|
+
...instructions
|
|
18212
18661
|
].join("\n");
|
|
18213
18662
|
return {
|
|
18214
18663
|
id: (0, import_node_crypto10.randomUUID)(),
|
|
18215
|
-
name: "Orchestration quota handoff.md",
|
|
18664
|
+
name: orch ? "Orchestration quota handoff.md" : "Quota handoff.md",
|
|
18216
18665
|
kind: "transcript",
|
|
18217
18666
|
content: body
|
|
18218
18667
|
};
|
|
@@ -18225,12 +18674,15 @@ function createQuotaFailoverChat(from, fallbackAgent, limitText) {
|
|
|
18225
18674
|
model: null,
|
|
18226
18675
|
attachments: [handoff]
|
|
18227
18676
|
});
|
|
18228
|
-
|
|
18229
|
-
parentThreadId: from.id,
|
|
18677
|
+
const patch = {
|
|
18230
18678
|
quotaContinuedFromId: from.id,
|
|
18231
|
-
sourceRef: from.sourceRef
|
|
18232
|
-
|
|
18233
|
-
|
|
18679
|
+
sourceRef: from.sourceRef
|
|
18680
|
+
};
|
|
18681
|
+
if (isOrchestratorThread(from)) {
|
|
18682
|
+
patch.parentThreadId = from.id;
|
|
18683
|
+
patch.sourceType = "orchestration";
|
|
18684
|
+
}
|
|
18685
|
+
return updateThread(tab.id, patch);
|
|
18234
18686
|
}
|
|
18235
18687
|
var import_node_crypto10, QUOTA_CONTINUE_PROMPT, QUOTA_RESUME_PROMPT;
|
|
18236
18688
|
var init_quota_failover = __esm({
|
|
@@ -18243,17 +18695,17 @@ var init_quota_failover = __esm({
|
|
|
18243
18695
|
init_thread_store();
|
|
18244
18696
|
init_chat_tabs();
|
|
18245
18697
|
QUOTA_CONTINUE_PROMPT = (fromAgent, fallback) => [
|
|
18246
|
-
`${fromAgent} hit a session/usage limit. Continue this
|
|
18247
|
-
"
|
|
18698
|
+
`${fromAgent} hit a session/usage limit. Continue this chat on ${fallback} using the attached handoff.`,
|
|
18699
|
+
"Proceed with the goal. Leave model Auto unless needed."
|
|
18248
18700
|
].join(" ");
|
|
18249
|
-
QUOTA_RESUME_PROMPT = "Session/usage limit window should have reset. Continue
|
|
18701
|
+
QUOTA_RESUME_PROMPT = "Session/usage limit window should have reset. Continue this chat from where you left off.";
|
|
18250
18702
|
}
|
|
18251
18703
|
});
|
|
18252
18704
|
|
|
18253
18705
|
// src/threads/adopt.ts
|
|
18254
18706
|
function thisModuleFile() {
|
|
18255
18707
|
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
18256
|
-
return cjsFile || process.argv[1] || (0,
|
|
18708
|
+
return cjsFile || process.argv[1] || (0, import_node_path44.join)(process.cwd(), "package.json");
|
|
18257
18709
|
}
|
|
18258
18710
|
function openReadonlySqlite(file) {
|
|
18259
18711
|
const req = (0, import_node_module4.createRequire)(thisModuleFile());
|
|
@@ -18271,21 +18723,21 @@ function mapAgentType(raw) {
|
|
|
18271
18723
|
return null;
|
|
18272
18724
|
}
|
|
18273
18725
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
18274
|
-
if (!workspacePath || !(0,
|
|
18726
|
+
if (!workspacePath || !(0, import_node_fs46.existsSync)(CURSOR_SDK_STORE)) return null;
|
|
18275
18727
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
18276
18728
|
let best = null;
|
|
18277
18729
|
let hashes;
|
|
18278
18730
|
try {
|
|
18279
|
-
hashes = (0,
|
|
18731
|
+
hashes = (0, import_node_fs46.readdirSync)(CURSOR_SDK_STORE);
|
|
18280
18732
|
} catch {
|
|
18281
18733
|
return null;
|
|
18282
18734
|
}
|
|
18283
18735
|
for (const hash of hashes) {
|
|
18284
|
-
const agentsFile = (0,
|
|
18285
|
-
if (!(0,
|
|
18736
|
+
const agentsFile = (0, import_node_path44.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
18737
|
+
if (!(0, import_node_fs46.existsSync)(agentsFile)) continue;
|
|
18286
18738
|
let text7;
|
|
18287
18739
|
try {
|
|
18288
|
-
text7 = (0,
|
|
18740
|
+
text7 = (0, import_node_fs46.readFileSync)(agentsFile, "utf8");
|
|
18289
18741
|
} catch {
|
|
18290
18742
|
continue;
|
|
18291
18743
|
}
|
|
@@ -18309,7 +18761,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
18309
18761
|
return best?.agentId ?? null;
|
|
18310
18762
|
}
|
|
18311
18763
|
async function adoptThread(input) {
|
|
18312
|
-
if (!(0,
|
|
18764
|
+
if (!(0, import_node_fs46.existsSync)(input.worktreePath)) {
|
|
18313
18765
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
18314
18766
|
}
|
|
18315
18767
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -18338,18 +18790,18 @@ function conductorDbPath() {
|
|
|
18338
18790
|
return CONDUCTOR_DB;
|
|
18339
18791
|
}
|
|
18340
18792
|
function listConductorWorkspaces() {
|
|
18341
|
-
if (!(0,
|
|
18793
|
+
if (!(0, import_node_fs46.existsSync)(CONDUCTOR_DB)) {
|
|
18342
18794
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
18343
18795
|
}
|
|
18344
|
-
const tmp = (0,
|
|
18345
|
-
const snapshot = (0,
|
|
18796
|
+
const tmp = (0, import_node_fs46.mkdtempSync)((0, import_node_path44.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
|
|
18797
|
+
const snapshot = (0, import_node_path44.join)(tmp, "conductor.db");
|
|
18346
18798
|
try {
|
|
18347
|
-
(0,
|
|
18799
|
+
(0, import_node_fs46.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
18348
18800
|
for (const suffix of ["-wal", "-shm"]) {
|
|
18349
18801
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
18350
|
-
if ((0,
|
|
18802
|
+
if ((0, import_node_fs46.existsSync)(src)) {
|
|
18351
18803
|
try {
|
|
18352
|
-
(0,
|
|
18804
|
+
(0, import_node_fs46.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
18353
18805
|
} catch {
|
|
18354
18806
|
}
|
|
18355
18807
|
}
|
|
@@ -18425,22 +18877,22 @@ function listConductorWorkspaces() {
|
|
|
18425
18877
|
db.close();
|
|
18426
18878
|
}
|
|
18427
18879
|
} finally {
|
|
18428
|
-
(0,
|
|
18880
|
+
(0, import_node_fs46.rmSync)(tmp, { recursive: true, force: true });
|
|
18429
18881
|
}
|
|
18430
18882
|
}
|
|
18431
18883
|
function importConductorWorkspace(workspaceId) {
|
|
18432
|
-
if (!(0,
|
|
18884
|
+
if (!(0, import_node_fs46.existsSync)(CONDUCTOR_DB)) {
|
|
18433
18885
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
18434
18886
|
}
|
|
18435
|
-
const tmp = (0,
|
|
18436
|
-
const snapshot = (0,
|
|
18887
|
+
const tmp = (0, import_node_fs46.mkdtempSync)((0, import_node_path44.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
|
|
18888
|
+
const snapshot = (0, import_node_path44.join)(tmp, "conductor.db");
|
|
18437
18889
|
try {
|
|
18438
|
-
(0,
|
|
18890
|
+
(0, import_node_fs46.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
18439
18891
|
for (const suffix of ["-wal", "-shm"]) {
|
|
18440
18892
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
18441
|
-
if ((0,
|
|
18893
|
+
if ((0, import_node_fs46.existsSync)(src)) {
|
|
18442
18894
|
try {
|
|
18443
|
-
(0,
|
|
18895
|
+
(0, import_node_fs46.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
18444
18896
|
} catch {
|
|
18445
18897
|
}
|
|
18446
18898
|
}
|
|
@@ -18458,7 +18910,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
18458
18910
|
).get(workspaceId);
|
|
18459
18911
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
18460
18912
|
const worktreePath = String(row.workspacePath);
|
|
18461
|
-
if (!(0,
|
|
18913
|
+
if (!(0, import_node_fs46.existsSync)(worktreePath)) {
|
|
18462
18914
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
18463
18915
|
}
|
|
18464
18916
|
let sessionId = null;
|
|
@@ -18521,31 +18973,31 @@ function importConductorWorkspace(workspaceId) {
|
|
|
18521
18973
|
db.close();
|
|
18522
18974
|
}
|
|
18523
18975
|
} finally {
|
|
18524
|
-
(0,
|
|
18976
|
+
(0, import_node_fs46.rmSync)(tmp, { recursive: true, force: true });
|
|
18525
18977
|
}
|
|
18526
18978
|
}
|
|
18527
18979
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
18528
18980
|
return importConductorWorkspace(workspaceId);
|
|
18529
18981
|
}
|
|
18530
|
-
var import_node_child_process5,
|
|
18982
|
+
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;
|
|
18531
18983
|
var init_adopt = __esm({
|
|
18532
18984
|
"src/threads/adopt.ts"() {
|
|
18533
18985
|
"use strict";
|
|
18534
18986
|
import_node_child_process5 = require("child_process");
|
|
18535
|
-
|
|
18536
|
-
|
|
18537
|
-
|
|
18987
|
+
import_node_fs46 = require("fs");
|
|
18988
|
+
import_node_os14 = require("os");
|
|
18989
|
+
import_node_path44 = require("path");
|
|
18538
18990
|
import_node_module4 = require("module");
|
|
18539
18991
|
init_worktree();
|
|
18540
18992
|
init_thread_store();
|
|
18541
|
-
CONDUCTOR_APP_SUPPORT = (0,
|
|
18993
|
+
CONDUCTOR_APP_SUPPORT = (0, import_node_path44.join)(
|
|
18542
18994
|
process.env.HOME ?? "",
|
|
18543
18995
|
"Library",
|
|
18544
18996
|
"Application Support",
|
|
18545
18997
|
"com.conductor.app"
|
|
18546
18998
|
);
|
|
18547
|
-
CONDUCTOR_DB = (0,
|
|
18548
|
-
CURSOR_SDK_STORE = (0,
|
|
18999
|
+
CONDUCTOR_DB = (0, import_node_path44.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
19000
|
+
CURSOR_SDK_STORE = (0, import_node_path44.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
18549
19001
|
}
|
|
18550
19002
|
});
|
|
18551
19003
|
|
|
@@ -18612,7 +19064,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
18612
19064
|
let createdWorktree = false;
|
|
18613
19065
|
const trees = await listWorktrees(repoPath);
|
|
18614
19066
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
18615
|
-
if (checkedOut?.path && (0,
|
|
19067
|
+
if (checkedOut?.path && (0, import_node_fs47.existsSync)(checkedOut.path)) {
|
|
18616
19068
|
if (input.reuseExistingWorktree !== false) {
|
|
18617
19069
|
worktreePath = checkedOut.path;
|
|
18618
19070
|
} else {
|
|
@@ -18754,7 +19206,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
18754
19206
|
async function createPrStack(input, onSetupLine) {
|
|
18755
19207
|
await requireAgent(input.agent);
|
|
18756
19208
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
18757
|
-
if (!(0,
|
|
19209
|
+
if (!(0, import_node_fs47.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
18758
19210
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
18759
19211
|
const status = await detectGhStack(repoPath);
|
|
18760
19212
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -18821,7 +19273,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
18821
19273
|
}
|
|
18822
19274
|
}
|
|
18823
19275
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
18824
|
-
if (!claimed.has(bootstrap.worktreePath) && (0,
|
|
19276
|
+
if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs47.existsSync)(bootstrap.worktreePath)) {
|
|
18825
19277
|
try {
|
|
18826
19278
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
18827
19279
|
deleteBranch: bootstrap.branchName
|
|
@@ -18841,11 +19293,11 @@ function stackAgentDefaultsFrom(input) {
|
|
|
18841
19293
|
planMode: input.planMode
|
|
18842
19294
|
};
|
|
18843
19295
|
}
|
|
18844
|
-
var
|
|
19296
|
+
var import_node_fs47;
|
|
18845
19297
|
var init_stack_layers = __esm({
|
|
18846
19298
|
"src/threads/stack-layers.ts"() {
|
|
18847
19299
|
"use strict";
|
|
18848
|
-
|
|
19300
|
+
import_node_fs47 = require("fs");
|
|
18849
19301
|
init_detect();
|
|
18850
19302
|
init_run();
|
|
18851
19303
|
init_stack();
|
|
@@ -18858,7 +19310,7 @@ var init_stack_layers = __esm({
|
|
|
18858
19310
|
|
|
18859
19311
|
// src/diff/diff.ts
|
|
18860
19312
|
async function inspectGitWorktree(worktreePath) {
|
|
18861
|
-
if (!worktreePath || !(0,
|
|
19313
|
+
if (!worktreePath || !(0, import_node_fs48.existsSync)(worktreePath)) return "missing_worktree";
|
|
18862
19314
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
18863
19315
|
reject: false
|
|
18864
19316
|
});
|
|
@@ -18866,7 +19318,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
18866
19318
|
return "ok";
|
|
18867
19319
|
}
|
|
18868
19320
|
async function initializeGitRepository(worktreePath) {
|
|
18869
|
-
if (!worktreePath || !(0,
|
|
19321
|
+
if (!worktreePath || !(0, import_node_fs48.existsSync)(worktreePath)) {
|
|
18870
19322
|
throw new Error("Worktree not found");
|
|
18871
19323
|
}
|
|
18872
19324
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -19000,11 +19452,11 @@ new file mode 100644
|
|
|
19000
19452
|
};
|
|
19001
19453
|
}
|
|
19002
19454
|
async function untrackedPatch(worktreePath, path2, maxHunk) {
|
|
19003
|
-
const abs = (0,
|
|
19455
|
+
const abs = (0, import_node_path45.join)(worktreePath, path2);
|
|
19004
19456
|
try {
|
|
19005
|
-
const st = (0,
|
|
19457
|
+
const st = (0, import_node_fs48.statSync)(abs);
|
|
19006
19458
|
if (st.isFile() && st.size > maxHunk) {
|
|
19007
|
-
const buf = (0,
|
|
19459
|
+
const buf = (0, import_node_fs48.readFileSync)(abs).subarray(0, maxHunk);
|
|
19008
19460
|
return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
|
|
19009
19461
|
}
|
|
19010
19462
|
} catch {
|
|
@@ -19493,8 +19945,8 @@ function isImageRelativePath(relativePath) {
|
|
|
19493
19945
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
19494
19946
|
assertSafeRelativePath(relativePath);
|
|
19495
19947
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
19496
|
-
const abs = (0,
|
|
19497
|
-
const st = (0,
|
|
19948
|
+
const abs = (0, import_node_path45.join)(worktreePath, relativePath);
|
|
19949
|
+
const st = (0, import_node_fs48.statSync)(abs);
|
|
19498
19950
|
if (!st.isFile()) {
|
|
19499
19951
|
throw new Error(`Not a file: ${relativePath}`);
|
|
19500
19952
|
}
|
|
@@ -19503,7 +19955,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
19503
19955
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
19504
19956
|
);
|
|
19505
19957
|
}
|
|
19506
|
-
const buf = (0,
|
|
19958
|
+
const buf = (0, import_node_fs48.readFileSync)(abs);
|
|
19507
19959
|
return {
|
|
19508
19960
|
path: relativePath,
|
|
19509
19961
|
contentBase64: buf.toString("base64"),
|
|
@@ -19513,12 +19965,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
19513
19965
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
19514
19966
|
assertSafeRelativePath(relativePath);
|
|
19515
19967
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
19516
|
-
const abs = (0,
|
|
19517
|
-
const st = (0,
|
|
19968
|
+
const abs = (0, import_node_path45.join)(worktreePath, relativePath);
|
|
19969
|
+
const st = (0, import_node_fs48.statSync)(abs);
|
|
19518
19970
|
if (!st.isFile()) {
|
|
19519
19971
|
throw new Error(`Not a file: ${relativePath}`);
|
|
19520
19972
|
}
|
|
19521
|
-
const buf = (0,
|
|
19973
|
+
const buf = (0, import_node_fs48.readFileSync)(abs);
|
|
19522
19974
|
if (isImageRelativePath(relativePath)) {
|
|
19523
19975
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
19524
19976
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -19561,9 +20013,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
19561
20013
|
}
|
|
19562
20014
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
19563
20015
|
assertSafeRelativePath(relativePath);
|
|
19564
|
-
const abs = (0,
|
|
19565
|
-
(0,
|
|
19566
|
-
(0,
|
|
20016
|
+
const abs = (0, import_node_path45.join)(worktreePath, relativePath);
|
|
20017
|
+
(0, import_node_fs48.mkdirSync)((0, import_node_path45.dirname)(abs), { recursive: true });
|
|
20018
|
+
(0, import_node_fs48.writeFileSync)(abs, content, "utf8");
|
|
19567
20019
|
return { path: relativePath };
|
|
19568
20020
|
}
|
|
19569
20021
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -19580,12 +20032,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
|
19580
20032
|
truncated: full.files.length > maxFiles
|
|
19581
20033
|
};
|
|
19582
20034
|
}
|
|
19583
|
-
var
|
|
20035
|
+
var import_node_fs48, import_node_path45, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
|
|
19584
20036
|
var init_diff = __esm({
|
|
19585
20037
|
"src/diff/diff.ts"() {
|
|
19586
20038
|
"use strict";
|
|
19587
|
-
|
|
19588
|
-
|
|
20039
|
+
import_node_fs48 = require("fs");
|
|
20040
|
+
import_node_path45 = require("path");
|
|
19589
20041
|
init_run();
|
|
19590
20042
|
init_worktree();
|
|
19591
20043
|
mergeBaseCache = /* @__PURE__ */ new Map();
|
|
@@ -19942,7 +20394,7 @@ function parseFrontmatter(content) {
|
|
|
19942
20394
|
}
|
|
19943
20395
|
function readSkill(skillMd, source) {
|
|
19944
20396
|
try {
|
|
19945
|
-
const content = (0,
|
|
20397
|
+
const content = (0, import_node_fs49.readFileSync)(skillMd, "utf8");
|
|
19946
20398
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
19947
20399
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
19948
20400
|
const name = fmName || dirName;
|
|
@@ -19961,19 +20413,19 @@ function readSkill(skillMd, source) {
|
|
|
19961
20413
|
}
|
|
19962
20414
|
}
|
|
19963
20415
|
function scanSkillsDir(dir, source, out) {
|
|
19964
|
-
if (!(0,
|
|
20416
|
+
if (!(0, import_node_fs49.existsSync)(dir)) return;
|
|
19965
20417
|
let entries;
|
|
19966
20418
|
try {
|
|
19967
|
-
entries = (0,
|
|
20419
|
+
entries = (0, import_node_fs49.readdirSync)(dir);
|
|
19968
20420
|
} catch {
|
|
19969
20421
|
return;
|
|
19970
20422
|
}
|
|
19971
20423
|
for (const entry of entries) {
|
|
19972
20424
|
if (entry.startsWith(".")) continue;
|
|
19973
|
-
const skillMd = (0,
|
|
19974
|
-
if (!(0,
|
|
20425
|
+
const skillMd = (0, import_node_path46.join)(dir, entry, "SKILL.md");
|
|
20426
|
+
if (!(0, import_node_fs49.existsSync)(skillMd)) continue;
|
|
19975
20427
|
try {
|
|
19976
|
-
if (!(0,
|
|
20428
|
+
if (!(0, import_node_fs49.statSync)(skillMd).isFile()) continue;
|
|
19977
20429
|
} catch {
|
|
19978
20430
|
continue;
|
|
19979
20431
|
}
|
|
@@ -19982,24 +20434,24 @@ function scanSkillsDir(dir, source, out) {
|
|
|
19982
20434
|
}
|
|
19983
20435
|
}
|
|
19984
20436
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
19985
|
-
if (!(0,
|
|
20437
|
+
if (!(0, import_node_fs49.existsSync)(pluginsRoot)) return;
|
|
19986
20438
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
19987
20439
|
if (depth > 7) return;
|
|
19988
20440
|
let entries;
|
|
19989
20441
|
try {
|
|
19990
|
-
entries = (0,
|
|
20442
|
+
entries = (0, import_node_fs49.readdirSync)(dir);
|
|
19991
20443
|
} catch {
|
|
19992
20444
|
return;
|
|
19993
20445
|
}
|
|
19994
20446
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
19995
|
-
const skill = readSkill((0,
|
|
20447
|
+
const skill = readSkill((0, import_node_path46.join)(dir, "SKILL.md"), "cli");
|
|
19996
20448
|
if (skill) out.push(skill);
|
|
19997
20449
|
}
|
|
19998
20450
|
for (const entry of entries) {
|
|
19999
20451
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
20000
|
-
const full = (0,
|
|
20452
|
+
const full = (0, import_node_path46.join)(dir, entry);
|
|
20001
20453
|
try {
|
|
20002
|
-
if (!(0,
|
|
20454
|
+
if (!(0, import_node_fs49.statSync)(full).isDirectory()) continue;
|
|
20003
20455
|
} catch {
|
|
20004
20456
|
continue;
|
|
20005
20457
|
}
|
|
@@ -20014,20 +20466,20 @@ function scanClaudePluginSkills(pluginsRoot, out) {
|
|
|
20014
20466
|
walk(pluginsRoot, 0, false);
|
|
20015
20467
|
}
|
|
20016
20468
|
function discoverSkills(worktreePath) {
|
|
20017
|
-
const home = (0,
|
|
20469
|
+
const home = (0, import_node_os15.homedir)();
|
|
20018
20470
|
const collected = [];
|
|
20019
20471
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
20020
|
-
scanSkillsDir((0,
|
|
20472
|
+
scanSkillsDir((0, import_node_path46.join)(worktreePath, rel), "workspace", collected);
|
|
20021
20473
|
}
|
|
20022
20474
|
for (const abs of [
|
|
20023
|
-
(0,
|
|
20024
|
-
(0,
|
|
20025
|
-
(0,
|
|
20026
|
-
(0,
|
|
20475
|
+
(0, import_node_path46.join)(home, ".claude/skills"),
|
|
20476
|
+
(0, import_node_path46.join)(home, ".cursor/skills"),
|
|
20477
|
+
(0, import_node_path46.join)(home, ".sideboard/skills"),
|
|
20478
|
+
(0, import_node_path46.join)(home, ".brightsy/skills")
|
|
20027
20479
|
]) {
|
|
20028
20480
|
scanSkillsDir(abs, "user", collected);
|
|
20029
20481
|
}
|
|
20030
|
-
scanClaudePluginSkills((0,
|
|
20482
|
+
scanClaudePluginSkills((0, import_node_path46.join)(home, ".claude/plugins"), collected);
|
|
20031
20483
|
collected.push(...bundledSkills());
|
|
20032
20484
|
const rank = {
|
|
20033
20485
|
workspace: 0,
|
|
@@ -20053,7 +20505,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
20053
20505
|
\u2026(truncated)` : body;
|
|
20054
20506
|
}
|
|
20055
20507
|
}
|
|
20056
|
-
const raw = (0,
|
|
20508
|
+
const raw = (0, import_node_fs49.readFileSync)(skillPath, "utf8");
|
|
20057
20509
|
if (raw.startsWith("---")) {
|
|
20058
20510
|
const end = raw.indexOf("\n---", 3);
|
|
20059
20511
|
if (end >= 0) {
|
|
@@ -20067,13 +20519,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
20067
20519
|
|
|
20068
20520
|
\u2026(truncated)` : raw;
|
|
20069
20521
|
}
|
|
20070
|
-
var
|
|
20522
|
+
var import_node_fs49, import_node_os15, import_node_path46, BUNDLED_SKILL_PREFIX;
|
|
20071
20523
|
var init_discover = __esm({
|
|
20072
20524
|
"src/skills/discover.ts"() {
|
|
20073
20525
|
"use strict";
|
|
20074
|
-
|
|
20075
|
-
|
|
20076
|
-
|
|
20526
|
+
import_node_fs49 = require("fs");
|
|
20527
|
+
import_node_os15 = require("os");
|
|
20528
|
+
import_node_path46 = require("path");
|
|
20077
20529
|
init_long_running();
|
|
20078
20530
|
BUNDLED_SKILL_PREFIX = "bundled:";
|
|
20079
20531
|
}
|
|
@@ -20167,8 +20619,8 @@ var init_expand = __esm({
|
|
|
20167
20619
|
// src/skills/detached-job-path.ts
|
|
20168
20620
|
function detachedJobScriptIn(dir) {
|
|
20169
20621
|
for (const name of DETACHED_JOB_FILENAMES) {
|
|
20170
|
-
const script = (0,
|
|
20171
|
-
if ((0,
|
|
20622
|
+
const script = (0, import_node_path47.join)(dir, "scripts", name);
|
|
20623
|
+
if ((0, import_node_fs50.existsSync)(script)) return script;
|
|
20172
20624
|
}
|
|
20173
20625
|
return null;
|
|
20174
20626
|
}
|
|
@@ -20180,11 +20632,11 @@ function packagedDetachedJobPath() {
|
|
|
20180
20632
|
function resolveDetachedJobScript() {
|
|
20181
20633
|
const packaged = packagedDetachedJobPath();
|
|
20182
20634
|
if (packaged) return packaged;
|
|
20183
|
-
let dir = (0,
|
|
20635
|
+
let dir = (0, import_node_path47.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
|
|
20184
20636
|
for (let i = 0; i < 8; i++) {
|
|
20185
20637
|
const candidate = detachedJobScriptIn(dir);
|
|
20186
20638
|
if (candidate) return candidate;
|
|
20187
|
-
const parent = (0,
|
|
20639
|
+
const parent = (0, import_node_path47.dirname)(dir);
|
|
20188
20640
|
if (parent === dir) break;
|
|
20189
20641
|
dir = parent;
|
|
20190
20642
|
}
|
|
@@ -20195,12 +20647,12 @@ function formatDetachedJobInvoke(scriptPath) {
|
|
|
20195
20647
|
if (resolved) return `node ${JSON.stringify(resolved)}`;
|
|
20196
20648
|
return "node scripts/detached-job.cjs";
|
|
20197
20649
|
}
|
|
20198
|
-
var
|
|
20650
|
+
var import_node_fs50, import_node_path47, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
|
|
20199
20651
|
var init_detached_job_path = __esm({
|
|
20200
20652
|
"src/skills/detached-job-path.ts"() {
|
|
20201
20653
|
"use strict";
|
|
20202
|
-
|
|
20203
|
-
|
|
20654
|
+
import_node_fs50 = require("fs");
|
|
20655
|
+
import_node_path47 = require("path");
|
|
20204
20656
|
import_node_url3 = require("url");
|
|
20205
20657
|
init_packaged_runtime();
|
|
20206
20658
|
import_meta3 = {};
|
|
@@ -20382,9 +20834,9 @@ function formatPrGateDirective() {
|
|
|
20382
20834
|
}
|
|
20383
20835
|
function formatProcessGuideDirective(opts) {
|
|
20384
20836
|
const worktree = opts?.worktreePath?.trim();
|
|
20385
|
-
const hasGraphSkill = !!worktree && (0,
|
|
20386
|
-
const hasReviewSkill = !!worktree && (0,
|
|
20387
|
-
const hasInstallSkill = !!worktree && (0,
|
|
20837
|
+
const hasGraphSkill = !!worktree && (0, import_node_fs51.existsSync)((0, import_node_path48.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
|
|
20838
|
+
const hasReviewSkill = !!worktree && (0, import_node_fs51.existsSync)((0, import_node_path48.join)(worktree, ".claude/skills/review/SKILL.md"));
|
|
20839
|
+
const hasInstallSkill = !!worktree && (0, import_node_fs51.existsSync)((0, import_node_path48.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
|
|
20388
20840
|
return [
|
|
20389
20841
|
"Process guides (recurring work only):",
|
|
20390
20842
|
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,
|
|
@@ -20422,12 +20874,12 @@ function formatArtifactDirective() {
|
|
|
20422
20874
|
function formatUiReminder() {
|
|
20423
20875
|
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.";
|
|
20424
20876
|
}
|
|
20425
|
-
var
|
|
20877
|
+
var import_node_fs51, import_node_path48, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
|
|
20426
20878
|
var init_instructions = __esm({
|
|
20427
20879
|
"src/agents/instructions.ts"() {
|
|
20428
20880
|
"use strict";
|
|
20429
|
-
|
|
20430
|
-
|
|
20881
|
+
import_node_fs51 = require("fs");
|
|
20882
|
+
import_node_path48 = require("path");
|
|
20431
20883
|
init_git_auth_mode();
|
|
20432
20884
|
init_branch_prefix();
|
|
20433
20885
|
init_worktree_labels();
|
|
@@ -20813,40 +21265,40 @@ __export(plan_file_exports, {
|
|
|
20813
21265
|
writePlanFile: () => writePlanFile
|
|
20814
21266
|
});
|
|
20815
21267
|
function ensureAttachmentsGitignore(worktreePath) {
|
|
20816
|
-
const gitignoreAbs = (0,
|
|
20817
|
-
if ((0,
|
|
20818
|
-
(0,
|
|
20819
|
-
(0,
|
|
21268
|
+
const gitignoreAbs = (0, import_node_path49.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
21269
|
+
if ((0, import_node_fs52.existsSync)(gitignoreAbs)) return;
|
|
21270
|
+
(0, import_node_fs52.mkdirSync)((0, import_node_path49.dirname)(gitignoreAbs), { recursive: true });
|
|
21271
|
+
(0, import_node_fs52.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
20820
21272
|
}
|
|
20821
21273
|
function planFileAbs(worktreePath) {
|
|
20822
|
-
return (0,
|
|
21274
|
+
return (0, import_node_path49.join)(worktreePath, PLAN_FILE_REL);
|
|
20823
21275
|
}
|
|
20824
21276
|
function readTextIfPresent2(abs) {
|
|
20825
|
-
if (!(0,
|
|
21277
|
+
if (!(0, import_node_fs52.existsSync)(abs)) return null;
|
|
20826
21278
|
try {
|
|
20827
|
-
const content = (0,
|
|
21279
|
+
const content = (0, import_node_fs52.readFileSync)(abs, "utf8");
|
|
20828
21280
|
return content.trim() ? content : null;
|
|
20829
21281
|
} catch {
|
|
20830
21282
|
return null;
|
|
20831
21283
|
}
|
|
20832
21284
|
}
|
|
20833
21285
|
function readPlanFile(worktreePath) {
|
|
20834
|
-
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0,
|
|
21286
|
+
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));
|
|
20835
21287
|
}
|
|
20836
21288
|
function writePlanFile(worktreePath, content) {
|
|
20837
21289
|
ensureAttachmentsGitignore(worktreePath);
|
|
20838
21290
|
const abs = planFileAbs(worktreePath);
|
|
20839
|
-
(0,
|
|
21291
|
+
(0, import_node_fs52.mkdirSync)((0, import_node_path49.dirname)(abs), { recursive: true });
|
|
20840
21292
|
const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
|
|
20841
|
-
(0,
|
|
21293
|
+
(0, import_node_fs52.writeFileSync)(abs, body, "utf8");
|
|
20842
21294
|
return PLAN_FILE_REL;
|
|
20843
21295
|
}
|
|
20844
|
-
var
|
|
21296
|
+
var import_node_fs52, import_node_path49;
|
|
20845
21297
|
var init_plan_file = __esm({
|
|
20846
21298
|
"src/plan/plan-file.ts"() {
|
|
20847
21299
|
"use strict";
|
|
20848
|
-
|
|
20849
|
-
|
|
21300
|
+
import_node_fs52 = require("fs");
|
|
21301
|
+
import_node_path49 = require("path");
|
|
20850
21302
|
init_workspace_scratch();
|
|
20851
21303
|
init_plan_present();
|
|
20852
21304
|
init_plan_present();
|
|
@@ -20894,13 +21346,13 @@ var init_sync_branch = __esm({
|
|
|
20894
21346
|
|
|
20895
21347
|
// src/agents/cursor-store.ts
|
|
20896
21348
|
function cursorSdkStoreDir(threadId) {
|
|
20897
|
-
const root = (0,
|
|
21349
|
+
const root = (0, import_node_path50.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
|
|
20898
21350
|
const id = sanitizeCursorStoreSegment(threadId);
|
|
20899
21351
|
if (!id) return root;
|
|
20900
|
-
return (0,
|
|
21352
|
+
return (0, import_node_path50.join)(root, "threads", id);
|
|
20901
21353
|
}
|
|
20902
21354
|
function cursorSdkRunsNdjsonPath(threadId) {
|
|
20903
|
-
return (0,
|
|
21355
|
+
return (0, import_node_path50.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
|
|
20904
21356
|
}
|
|
20905
21357
|
function cursorSdkRunsNdjsonSearchPaths(threadId) {
|
|
20906
21358
|
const scoped = cursorSdkRunsNdjsonPath(threadId);
|
|
@@ -20913,11 +21365,11 @@ function cursorSdkRunsNdjsonSearchPaths(threadId) {
|
|
|
20913
21365
|
function sanitizeCursorStoreSegment(threadId) {
|
|
20914
21366
|
return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
20915
21367
|
}
|
|
20916
|
-
var
|
|
21368
|
+
var import_node_path50, CURSOR_SDK_STORE_DIR;
|
|
20917
21369
|
var init_cursor_store = __esm({
|
|
20918
21370
|
"src/agents/cursor-store.ts"() {
|
|
20919
21371
|
"use strict";
|
|
20920
|
-
|
|
21372
|
+
import_node_path50 = require("path");
|
|
20921
21373
|
init_paths();
|
|
20922
21374
|
CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
|
|
20923
21375
|
}
|
|
@@ -20939,9 +21391,9 @@ function recoverFinishedCursorRun(opts) {
|
|
|
20939
21391
|
return best;
|
|
20940
21392
|
}
|
|
20941
21393
|
function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
|
|
20942
|
-
if (!(0,
|
|
21394
|
+
if (!(0, import_node_fs53.existsSync)(runsPath)) return null;
|
|
20943
21395
|
try {
|
|
20944
|
-
const lines = (0,
|
|
21396
|
+
const lines = (0, import_node_fs53.readFileSync)(runsPath, "utf8").split("\n");
|
|
20945
21397
|
let best = null;
|
|
20946
21398
|
for (const line of lines) {
|
|
20947
21399
|
const trimmed = line.trim();
|
|
@@ -20967,11 +21419,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
|
|
|
20967
21419
|
return null;
|
|
20968
21420
|
}
|
|
20969
21421
|
}
|
|
20970
|
-
var
|
|
21422
|
+
var import_node_fs53;
|
|
20971
21423
|
var init_cursor_recover = __esm({
|
|
20972
21424
|
"src/agents/cursor-recover.ts"() {
|
|
20973
21425
|
"use strict";
|
|
20974
|
-
|
|
21426
|
+
import_node_fs53 = require("fs");
|
|
20975
21427
|
init_cursor_store();
|
|
20976
21428
|
}
|
|
20977
21429
|
});
|
|
@@ -21118,13 +21570,13 @@ async function startOrchestration(opts) {
|
|
|
21118
21570
|
}
|
|
21119
21571
|
return updated;
|
|
21120
21572
|
}
|
|
21121
|
-
var import_node_events,
|
|
21573
|
+
var import_node_events, import_node_fs54, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
|
|
21122
21574
|
var init_orchestrator = __esm({
|
|
21123
21575
|
"src/orchestrator/orchestrator.ts"() {
|
|
21124
21576
|
"use strict";
|
|
21125
21577
|
import_node_events = require("events");
|
|
21126
21578
|
init_outbound_watch();
|
|
21127
|
-
|
|
21579
|
+
import_node_fs54 = require("fs");
|
|
21128
21580
|
init_error_detail();
|
|
21129
21581
|
init_run();
|
|
21130
21582
|
init_stale_lock();
|
|
@@ -21298,7 +21750,7 @@ var init_orchestrator = __esm({
|
|
|
21298
21750
|
}
|
|
21299
21751
|
continue;
|
|
21300
21752
|
}
|
|
21301
|
-
if (!(0,
|
|
21753
|
+
if (!(0, import_node_fs54.existsSync)(thread.worktreePath)) {
|
|
21302
21754
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
21303
21755
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
21304
21756
|
continue;
|
|
@@ -21428,8 +21880,8 @@ var init_orchestrator = __esm({
|
|
|
21428
21880
|
await this.send(threadId, QUOTA_RESUME_PROMPT);
|
|
21429
21881
|
}
|
|
21430
21882
|
/**
|
|
21431
|
-
* Host-side continue when
|
|
21432
|
-
*
|
|
21883
|
+
* Host-side continue when any chat hits a provider session/usage limit
|
|
21884
|
+
* (not context size): switch agent (Auto) or wait until reset.
|
|
21433
21885
|
*/
|
|
21434
21886
|
async maybeHandleOrchestrationQuotaFailover(threadId, limitText) {
|
|
21435
21887
|
const thread = findThreadByRef(threadId);
|
|
@@ -21442,7 +21894,7 @@ var init_orchestrator = __esm({
|
|
|
21442
21894
|
setStatus(threadId, "idle", null);
|
|
21443
21895
|
appendMessage(threadId, {
|
|
21444
21896
|
role: "agent",
|
|
21445
|
-
text: `Sideboard will auto-retry this
|
|
21897
|
+
text: `Sideboard will auto-retry this chat around ${plan.resumeAt.toLocaleString()} when the session limit resets.`,
|
|
21446
21898
|
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
21447
21899
|
});
|
|
21448
21900
|
this.emit({
|
|
@@ -23245,7 +23697,7 @@ var init_orchestrator = __esm({
|
|
|
23245
23697
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
23246
23698
|
return restored2;
|
|
23247
23699
|
}
|
|
23248
|
-
if (!(0,
|
|
23700
|
+
if (!(0, import_node_fs54.existsSync)(thread.worktreePath)) {
|
|
23249
23701
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
23250
23702
|
throw new Error(
|
|
23251
23703
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
@@ -23537,6 +23989,7 @@ __export(index_exports, {
|
|
|
23537
23989
|
SlackRelayHub: () => SlackRelayHub,
|
|
23538
23990
|
THINKING_EFFORTS: () => THINKING_EFFORTS,
|
|
23539
23991
|
THINKING_PART_MAX_CHARS: () => THINKING_PART_MAX_CHARS,
|
|
23992
|
+
USAGE_ON_LIMIT_VALUES: () => USAGE_ON_LIMIT_VALUES,
|
|
23540
23993
|
WORKTREE_ABLETIME_MCP_TOOLS: () => WORKTREE_ABLETIME_MCP_TOOLS,
|
|
23541
23994
|
WORKTREE_GITHUB_MCP_TOOLS: () => WORKTREE_GITHUB_MCP_TOOLS,
|
|
23542
23995
|
WORKTREE_LINEAR_MCP_TOOLS: () => WORKTREE_LINEAR_MCP_TOOLS,
|
|
@@ -23618,6 +24071,7 @@ __export(index_exports, {
|
|
|
23618
24071
|
classifyWorktreeColumn: () => classifyWorktreeColumn,
|
|
23619
24072
|
claudeAdapter: () => claudeAdapter,
|
|
23620
24073
|
claudeChromeEnabled: () => claudeChromeEnabled,
|
|
24074
|
+
claudeUsageOverLimitWindows: () => claudeUsageOverLimitWindows,
|
|
23621
24075
|
claudeUserSettingsPath: () => claudeUserSettingsPath,
|
|
23622
24076
|
cleanupOrphanWorktrees: () => cleanupOrphanWorktrees,
|
|
23623
24077
|
clearBoardPins: () => clearBoardPins,
|
|
@@ -23637,6 +24091,7 @@ __export(index_exports, {
|
|
|
23637
24091
|
computeNextRunAt: () => computeNextRunAt,
|
|
23638
24092
|
conductorBundledBinDir: () => conductorBundledBinDir,
|
|
23639
24093
|
conductorDbPath: () => conductorDbPath,
|
|
24094
|
+
confirmClaudeUsageOverLimitEnabled: () => confirmClaudeUsageOverLimitEnabled,
|
|
23640
24095
|
confirmLand: () => confirmLand,
|
|
23641
24096
|
connectBrightsyTeam: () => connectBrightsyTeam,
|
|
23642
24097
|
connectOptionalService: () => connectOptionalService,
|
|
@@ -23736,6 +24191,14 @@ __export(index_exports, {
|
|
|
23736
24191
|
formatAccountProfilePlaybookLine: () => formatAccountProfilePlaybookLine,
|
|
23737
24192
|
formatArtifactDirective: () => formatArtifactDirective,
|
|
23738
24193
|
formatBrightsyFetchError: () => formatBrightsyFetchError,
|
|
24194
|
+
formatClaudeExtraUsageDetail: () => formatClaudeExtraUsageDetail,
|
|
24195
|
+
formatClaudeUsageCompact: () => formatClaudeUsageCompact,
|
|
24196
|
+
formatClaudeUsageFetchedAt: () => formatClaudeUsageFetchedAt,
|
|
24197
|
+
formatClaudeUsageOverLimitConfirm: () => formatClaudeUsageOverLimitConfirm,
|
|
24198
|
+
formatClaudeUsageOverLimitWait: () => formatClaudeUsageOverLimitWait,
|
|
24199
|
+
formatClaudeUsageReset: () => formatClaudeUsageReset,
|
|
24200
|
+
formatClaudeUsageResetClock: () => formatClaudeUsageResetClock,
|
|
24201
|
+
formatClaudeUsageTooltip: () => formatClaudeUsageTooltip,
|
|
23739
24202
|
formatDetachedJobInvoke: () => formatDetachedJobInvoke,
|
|
23740
24203
|
formatFetchError: () => formatFetchError,
|
|
23741
24204
|
formatGhLandError: () => formatGhLandError,
|
|
@@ -23785,6 +24248,7 @@ __export(index_exports, {
|
|
|
23785
24248
|
getAgentSetupInfo: () => getAgentSetupInfo,
|
|
23786
24249
|
getBrightsySession: () => getBrightsySession,
|
|
23787
24250
|
getCaffeinateHold: () => getCaffeinateHold,
|
|
24251
|
+
getClaudePlanUsage: () => getClaudePlanUsage,
|
|
23788
24252
|
getDefaultAgent: () => getDefaultAgent,
|
|
23789
24253
|
getDefaultEffort: () => getDefaultEffort,
|
|
23790
24254
|
getDefaultFast: () => getDefaultFast,
|
|
@@ -23834,6 +24298,7 @@ __export(index_exports, {
|
|
|
23834
24298
|
hasRepoHook: () => hasRepoHook,
|
|
23835
24299
|
hasWorkspaceHook: () => hasWorkspaceHook,
|
|
23836
24300
|
healOrchestrationSoccerTitles: () => healOrchestrationSoccerTitles,
|
|
24301
|
+
hottestClaudeWindow: () => hottestClaudeWindow,
|
|
23837
24302
|
httpFetch: () => httpFetch,
|
|
23838
24303
|
importConductorWorkspace: () => importConductorWorkspace,
|
|
23839
24304
|
importConductorWorkspaceAsync: () => importConductorWorkspaceAsync,
|
|
@@ -23895,6 +24360,7 @@ __export(index_exports, {
|
|
|
23895
24360
|
isThisProcessDesktopHost: () => isThisProcessDesktopHost,
|
|
23896
24361
|
isThreadCaffeinated: () => isThreadCaffeinated,
|
|
23897
24362
|
isThreadRecordFile: () => isThreadRecordFile,
|
|
24363
|
+
isUsageOnLimit: () => isUsageOnLimit,
|
|
23898
24364
|
isWorkspaceScratchPath: () => isWorkspaceScratchPath,
|
|
23899
24365
|
issueAttachmentForAbleTimeTask: () => issueAttachmentForAbleTimeTask,
|
|
23900
24366
|
issueMatchesAssignee: () => issueMatchesAssignee,
|
|
@@ -23997,6 +24463,7 @@ __export(index_exports, {
|
|
|
23997
24463
|
originFetchBranch: () => originFetchBranch,
|
|
23998
24464
|
originGhRepoEnv: () => originGhRepoEnv,
|
|
23999
24465
|
packagedDetachedJobPath: () => packagedDetachedJobPath,
|
|
24466
|
+
parseClaudeUsagePayload: () => parseClaudeUsagePayload,
|
|
24000
24467
|
parseCursorRunnerLine: () => parseCursorRunnerLine,
|
|
24001
24468
|
parseDurationMs: () => parseDurationMs,
|
|
24002
24469
|
parseForceStopMessage: () => parseForceStopMessage,
|
|
@@ -24093,6 +24560,7 @@ __export(index_exports, {
|
|
|
24093
24560
|
resolveSlackListenMode: () => resolveSlackListenMode,
|
|
24094
24561
|
resolveThreadDefaults: () => resolveThreadDefaults,
|
|
24095
24562
|
resolveThreadEffort: () => resolveThreadEffort,
|
|
24563
|
+
resolveUsageOnLimit: () => resolveUsageOnLimit,
|
|
24096
24564
|
resolveVaultKey: () => resolveVaultKey,
|
|
24097
24565
|
resolveViewerProfile: () => resolveViewerProfile,
|
|
24098
24566
|
resolveViewerProfileForRepo: () => resolveViewerProfileForRepo,
|
|
@@ -24207,6 +24675,7 @@ __export(index_exports, {
|
|
|
24207
24675
|
updateProjectProfileSettings: () => updateProjectProfileSettings,
|
|
24208
24676
|
updateSchedule: () => updateSchedule,
|
|
24209
24677
|
updateThread: () => updateThread,
|
|
24678
|
+
usageOnLimit: () => usageOnLimit,
|
|
24210
24679
|
userClaudeMcpConfigPath: () => userClaudeMcpConfigPath,
|
|
24211
24680
|
userCursorMcpConfigPath: () => userCursorMcpConfigPath,
|
|
24212
24681
|
userMcpNamesToDisable: () => userMcpNamesToDisable,
|
|
@@ -26579,7 +27048,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
|
26579
27048
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
26580
27049
|
var import_zod9 = require("zod");
|
|
26581
27050
|
var import_node_crypto14 = require("crypto");
|
|
26582
|
-
var
|
|
27051
|
+
var import_node_path53 = require("path");
|
|
26583
27052
|
init_orchestrator();
|
|
26584
27053
|
init_worktree();
|
|
26585
27054
|
init_global_workspace();
|
|
@@ -28299,27 +28768,27 @@ init_gh_errors();
|
|
|
28299
28768
|
init_git_auth_mode();
|
|
28300
28769
|
|
|
28301
28770
|
// src/board/load-home-board.ts
|
|
28302
|
-
var
|
|
28303
|
-
var
|
|
28771
|
+
var import_node_fs56 = require("fs");
|
|
28772
|
+
var import_node_path52 = require("path");
|
|
28304
28773
|
init_worktree();
|
|
28305
28774
|
init_paths();
|
|
28306
28775
|
|
|
28307
28776
|
// src/board/board-pins.ts
|
|
28308
28777
|
var import_node_crypto13 = require("crypto");
|
|
28309
|
-
var
|
|
28310
|
-
var
|
|
28778
|
+
var import_node_fs55 = require("fs");
|
|
28779
|
+
var import_node_path51 = require("path");
|
|
28311
28780
|
init_paths();
|
|
28312
28781
|
init_home_board();
|
|
28313
28782
|
var FILE = "home-board-pins.json";
|
|
28314
28783
|
var VERSION = 1;
|
|
28315
28784
|
function pinsFile() {
|
|
28316
|
-
return (0,
|
|
28785
|
+
return (0, import_node_path51.join)(appDataDir(), FILE);
|
|
28317
28786
|
}
|
|
28318
28787
|
function readDisk() {
|
|
28319
28788
|
const path2 = pinsFile();
|
|
28320
|
-
if (!(0,
|
|
28789
|
+
if (!(0, import_node_fs55.existsSync)(path2)) return [];
|
|
28321
28790
|
try {
|
|
28322
|
-
const raw = JSON.parse((0,
|
|
28791
|
+
const raw = JSON.parse((0, import_node_fs55.readFileSync)(path2, "utf8"));
|
|
28323
28792
|
if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
|
|
28324
28793
|
return raw.items.filter((item) => item?.id && item.kind && item.ref);
|
|
28325
28794
|
} catch {
|
|
@@ -28327,8 +28796,8 @@ function readDisk() {
|
|
|
28327
28796
|
}
|
|
28328
28797
|
}
|
|
28329
28798
|
function writeDisk(items) {
|
|
28330
|
-
(0,
|
|
28331
|
-
(0,
|
|
28799
|
+
(0, import_node_fs55.mkdirSync)(appDataDir(), { recursive: true });
|
|
28800
|
+
(0, import_node_fs55.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
|
|
28332
28801
|
}
|
|
28333
28802
|
function listBoardPins() {
|
|
28334
28803
|
return readDisk();
|
|
@@ -28380,7 +28849,7 @@ function replaceBoardPins(items) {
|
|
|
28380
28849
|
}
|
|
28381
28850
|
function clearBoardPins() {
|
|
28382
28851
|
try {
|
|
28383
|
-
(0,
|
|
28852
|
+
(0, import_node_fs55.unlinkSync)(pinsFile());
|
|
28384
28853
|
} catch {
|
|
28385
28854
|
}
|
|
28386
28855
|
}
|
|
@@ -28389,7 +28858,7 @@ function clearBoardPins() {
|
|
|
28389
28858
|
init_home_board();
|
|
28390
28859
|
var CACHE_VERSION = 1;
|
|
28391
28860
|
var memory2 = null;
|
|
28392
|
-
var
|
|
28861
|
+
var inflight2 = null;
|
|
28393
28862
|
function errText(err) {
|
|
28394
28863
|
return err instanceof Error ? err.message : String(err);
|
|
28395
28864
|
}
|
|
@@ -28397,7 +28866,7 @@ function homeBoardWorkspaceKey(workspaces) {
|
|
|
28397
28866
|
return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
|
|
28398
28867
|
}
|
|
28399
28868
|
function cacheFile() {
|
|
28400
|
-
return (0,
|
|
28869
|
+
return (0, import_node_path52.join)(appDataDir(), "home-board-cache.json");
|
|
28401
28870
|
}
|
|
28402
28871
|
function emptyInputs() {
|
|
28403
28872
|
return {
|
|
@@ -28423,9 +28892,9 @@ function shouldCacheHomeBoardInputs(inputs) {
|
|
|
28423
28892
|
}
|
|
28424
28893
|
function readDiskCache() {
|
|
28425
28894
|
const path2 = cacheFile();
|
|
28426
|
-
if (!(0,
|
|
28895
|
+
if (!(0, import_node_fs56.existsSync)(path2)) return null;
|
|
28427
28896
|
try {
|
|
28428
|
-
const raw = JSON.parse((0,
|
|
28897
|
+
const raw = JSON.parse((0, import_node_fs56.readFileSync)(path2, "utf8"));
|
|
28429
28898
|
if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
|
|
28430
28899
|
return null;
|
|
28431
28900
|
}
|
|
@@ -28439,20 +28908,20 @@ function readDiskCache() {
|
|
|
28439
28908
|
}
|
|
28440
28909
|
function writeDiskCache(entry) {
|
|
28441
28910
|
try {
|
|
28442
|
-
(0,
|
|
28443
|
-
(0,
|
|
28911
|
+
(0, import_node_fs56.mkdirSync)(appDataDir(), { recursive: true });
|
|
28912
|
+
(0, import_node_fs56.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
|
|
28444
28913
|
} catch {
|
|
28445
28914
|
}
|
|
28446
28915
|
}
|
|
28447
28916
|
function deleteDiskCache() {
|
|
28448
28917
|
try {
|
|
28449
|
-
(0,
|
|
28918
|
+
(0, import_node_fs56.unlinkSync)(cacheFile());
|
|
28450
28919
|
} catch {
|
|
28451
28920
|
}
|
|
28452
28921
|
}
|
|
28453
28922
|
function resetHomeBoardMemory() {
|
|
28454
28923
|
memory2 = null;
|
|
28455
|
-
|
|
28924
|
+
inflight2 = null;
|
|
28456
28925
|
}
|
|
28457
28926
|
function clearHomeBoardCache() {
|
|
28458
28927
|
resetHomeBoardMemory();
|
|
@@ -28551,8 +29020,8 @@ async function getHomeBoardInputs(workspaces, opts) {
|
|
|
28551
29020
|
return asLoaded(best, true);
|
|
28552
29021
|
}
|
|
28553
29022
|
}
|
|
28554
|
-
if (
|
|
28555
|
-
return
|
|
29023
|
+
if (inflight2 && inflight2.key === key) {
|
|
29024
|
+
return inflight2.promise;
|
|
28556
29025
|
}
|
|
28557
29026
|
const promise = (async () => {
|
|
28558
29027
|
const inputs = await loadHomeBoardInputs(workspaces);
|
|
@@ -28572,11 +29041,11 @@ async function getHomeBoardInputs(workspaces, opts) {
|
|
|
28572
29041
|
}
|
|
28573
29042
|
return loaded;
|
|
28574
29043
|
})();
|
|
28575
|
-
|
|
29044
|
+
inflight2 = { key, promise };
|
|
28576
29045
|
try {
|
|
28577
29046
|
return await promise;
|
|
28578
29047
|
} finally {
|
|
28579
|
-
if (
|
|
29048
|
+
if (inflight2?.promise === promise) inflight2 = null;
|
|
28580
29049
|
}
|
|
28581
29050
|
}
|
|
28582
29051
|
|
|
@@ -28796,7 +29265,7 @@ async function startMcpServer() {
|
|
|
28796
29265
|
async () => {
|
|
28797
29266
|
const threads = orch.getThreads(true);
|
|
28798
29267
|
const lines = threads.map((t) => {
|
|
28799
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0,
|
|
29268
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path53.basename)(t.repoPath) || t.repoPath;
|
|
28800
29269
|
const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
|
|
28801
29270
|
const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
|
|
28802
29271
|
const preview = lastMessagePreview(t.messages, 80);
|
|
@@ -31763,9 +32232,9 @@ var import_node_http3 = require("http");
|
|
|
31763
32232
|
var import_ws3 = require("ws");
|
|
31764
32233
|
|
|
31765
32234
|
// src/slack/relay-static.ts
|
|
31766
|
-
var
|
|
32235
|
+
var import_node_fs57 = require("fs");
|
|
31767
32236
|
var import_promises = require("fs/promises");
|
|
31768
|
-
var
|
|
32237
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
31769
32238
|
var TYPES = {
|
|
31770
32239
|
".css": "text/css; charset=utf-8",
|
|
31771
32240
|
".html": "text/html; charset=utf-8",
|
|
@@ -31796,9 +32265,9 @@ function resolveStaticPath(root, requestUrl) {
|
|
|
31796
32265
|
return null;
|
|
31797
32266
|
}
|
|
31798
32267
|
if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
|
|
31799
|
-
const rootResolved =
|
|
31800
|
-
const candidate =
|
|
31801
|
-
if (candidate !== rootResolved && !candidate.startsWith(rootResolved +
|
|
32268
|
+
const rootResolved = import_node_path54.default.resolve(root);
|
|
32269
|
+
const candidate = import_node_path54.default.resolve(rootResolved, `.${pathname}`);
|
|
32270
|
+
if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path54.default.sep)) {
|
|
31802
32271
|
return null;
|
|
31803
32272
|
}
|
|
31804
32273
|
return candidate;
|
|
@@ -31812,7 +32281,7 @@ async function fileSize(file) {
|
|
|
31812
32281
|
}
|
|
31813
32282
|
}
|
|
31814
32283
|
function sendFile(req, res, file, size) {
|
|
31815
|
-
const ext =
|
|
32284
|
+
const ext = import_node_path54.default.extname(file).toLowerCase();
|
|
31816
32285
|
res.writeHead(200, {
|
|
31817
32286
|
"Content-Type": TYPES[ext] ?? "application/octet-stream",
|
|
31818
32287
|
"Content-Length": size,
|
|
@@ -31822,7 +32291,7 @@ function sendFile(req, res, file, size) {
|
|
|
31822
32291
|
res.end();
|
|
31823
32292
|
return true;
|
|
31824
32293
|
}
|
|
31825
|
-
(0,
|
|
32294
|
+
(0, import_node_fs57.createReadStream)(file).pipe(res);
|
|
31826
32295
|
return true;
|
|
31827
32296
|
}
|
|
31828
32297
|
async function tryServeStatic(req, res, root) {
|
|
@@ -31831,7 +32300,7 @@ async function tryServeStatic(req, res, root) {
|
|
|
31831
32300
|
if (!candidate) return false;
|
|
31832
32301
|
const direct = await fileSize(candidate);
|
|
31833
32302
|
if (direct != null) return sendFile(req, res, candidate, direct);
|
|
31834
|
-
const asIndex =
|
|
32303
|
+
const asIndex = import_node_path54.default.join(candidate, "index.html");
|
|
31835
32304
|
const indexSize = await fileSize(asIndex);
|
|
31836
32305
|
if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
|
|
31837
32306
|
return false;
|
|
@@ -32155,6 +32624,7 @@ init_outbound_watch();
|
|
|
32155
32624
|
SlackRelayHub,
|
|
32156
32625
|
THINKING_EFFORTS,
|
|
32157
32626
|
THINKING_PART_MAX_CHARS,
|
|
32627
|
+
USAGE_ON_LIMIT_VALUES,
|
|
32158
32628
|
WORKTREE_ABLETIME_MCP_TOOLS,
|
|
32159
32629
|
WORKTREE_GITHUB_MCP_TOOLS,
|
|
32160
32630
|
WORKTREE_LINEAR_MCP_TOOLS,
|
|
@@ -32236,6 +32706,7 @@ init_outbound_watch();
|
|
|
32236
32706
|
classifyWorktreeColumn,
|
|
32237
32707
|
claudeAdapter,
|
|
32238
32708
|
claudeChromeEnabled,
|
|
32709
|
+
claudeUsageOverLimitWindows,
|
|
32239
32710
|
claudeUserSettingsPath,
|
|
32240
32711
|
cleanupOrphanWorktrees,
|
|
32241
32712
|
clearBoardPins,
|
|
@@ -32255,6 +32726,7 @@ init_outbound_watch();
|
|
|
32255
32726
|
computeNextRunAt,
|
|
32256
32727
|
conductorBundledBinDir,
|
|
32257
32728
|
conductorDbPath,
|
|
32729
|
+
confirmClaudeUsageOverLimitEnabled,
|
|
32258
32730
|
confirmLand,
|
|
32259
32731
|
connectBrightsyTeam,
|
|
32260
32732
|
connectOptionalService,
|
|
@@ -32354,6 +32826,14 @@ init_outbound_watch();
|
|
|
32354
32826
|
formatAccountProfilePlaybookLine,
|
|
32355
32827
|
formatArtifactDirective,
|
|
32356
32828
|
formatBrightsyFetchError,
|
|
32829
|
+
formatClaudeExtraUsageDetail,
|
|
32830
|
+
formatClaudeUsageCompact,
|
|
32831
|
+
formatClaudeUsageFetchedAt,
|
|
32832
|
+
formatClaudeUsageOverLimitConfirm,
|
|
32833
|
+
formatClaudeUsageOverLimitWait,
|
|
32834
|
+
formatClaudeUsageReset,
|
|
32835
|
+
formatClaudeUsageResetClock,
|
|
32836
|
+
formatClaudeUsageTooltip,
|
|
32357
32837
|
formatDetachedJobInvoke,
|
|
32358
32838
|
formatFetchError,
|
|
32359
32839
|
formatGhLandError,
|
|
@@ -32403,6 +32883,7 @@ init_outbound_watch();
|
|
|
32403
32883
|
getAgentSetupInfo,
|
|
32404
32884
|
getBrightsySession,
|
|
32405
32885
|
getCaffeinateHold,
|
|
32886
|
+
getClaudePlanUsage,
|
|
32406
32887
|
getDefaultAgent,
|
|
32407
32888
|
getDefaultEffort,
|
|
32408
32889
|
getDefaultFast,
|
|
@@ -32452,6 +32933,7 @@ init_outbound_watch();
|
|
|
32452
32933
|
hasRepoHook,
|
|
32453
32934
|
hasWorkspaceHook,
|
|
32454
32935
|
healOrchestrationSoccerTitles,
|
|
32936
|
+
hottestClaudeWindow,
|
|
32455
32937
|
httpFetch,
|
|
32456
32938
|
importConductorWorkspace,
|
|
32457
32939
|
importConductorWorkspaceAsync,
|
|
@@ -32513,6 +32995,7 @@ init_outbound_watch();
|
|
|
32513
32995
|
isThisProcessDesktopHost,
|
|
32514
32996
|
isThreadCaffeinated,
|
|
32515
32997
|
isThreadRecordFile,
|
|
32998
|
+
isUsageOnLimit,
|
|
32516
32999
|
isWorkspaceScratchPath,
|
|
32517
33000
|
issueAttachmentForAbleTimeTask,
|
|
32518
33001
|
issueMatchesAssignee,
|
|
@@ -32615,6 +33098,7 @@ init_outbound_watch();
|
|
|
32615
33098
|
originFetchBranch,
|
|
32616
33099
|
originGhRepoEnv,
|
|
32617
33100
|
packagedDetachedJobPath,
|
|
33101
|
+
parseClaudeUsagePayload,
|
|
32618
33102
|
parseCursorRunnerLine,
|
|
32619
33103
|
parseDurationMs,
|
|
32620
33104
|
parseForceStopMessage,
|
|
@@ -32711,6 +33195,7 @@ init_outbound_watch();
|
|
|
32711
33195
|
resolveSlackListenMode,
|
|
32712
33196
|
resolveThreadDefaults,
|
|
32713
33197
|
resolveThreadEffort,
|
|
33198
|
+
resolveUsageOnLimit,
|
|
32714
33199
|
resolveVaultKey,
|
|
32715
33200
|
resolveViewerProfile,
|
|
32716
33201
|
resolveViewerProfileForRepo,
|
|
@@ -32825,6 +33310,7 @@ init_outbound_watch();
|
|
|
32825
33310
|
updateProjectProfileSettings,
|
|
32826
33311
|
updateSchedule,
|
|
32827
33312
|
updateThread,
|
|
33313
|
+
usageOnLimit,
|
|
32828
33314
|
userClaudeMcpConfigPath,
|
|
32829
33315
|
userCursorMcpConfigPath,
|
|
32830
33316
|
userMcpNamesToDisable,
|