@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/mcp/run-stdio.cjs
CHANGED
|
@@ -3478,6 +3478,30 @@ var init_branch_prefix = __esm({
|
|
|
3478
3478
|
}
|
|
3479
3479
|
});
|
|
3480
3480
|
|
|
3481
|
+
// src/store/usage-on-limit.ts
|
|
3482
|
+
function isUsageOnLimit(value) {
|
|
3483
|
+
return value === "keep_going" || value === "confirm" || value === "switch_agent" || value === "wait_reset";
|
|
3484
|
+
}
|
|
3485
|
+
function resolveUsageOnLimit(advanced = {}) {
|
|
3486
|
+
if (isUsageOnLimit(advanced.usageOnLimit)) return advanced.usageOnLimit;
|
|
3487
|
+
if (advanced.confirmClaudeUsageOverLimit) return "confirm";
|
|
3488
|
+
if (advanced.orchestrationQuotaOnLimit === "wait_reset") return "wait_reset";
|
|
3489
|
+
if (advanced.orchestrationQuotaOnLimit === "switch_agent") return "switch_agent";
|
|
3490
|
+
return "keep_going";
|
|
3491
|
+
}
|
|
3492
|
+
var USAGE_ON_LIMIT_VALUES;
|
|
3493
|
+
var init_usage_on_limit = __esm({
|
|
3494
|
+
"src/store/usage-on-limit.ts"() {
|
|
3495
|
+
"use strict";
|
|
3496
|
+
USAGE_ON_LIMIT_VALUES = [
|
|
3497
|
+
"keep_going",
|
|
3498
|
+
"confirm",
|
|
3499
|
+
"switch_agent",
|
|
3500
|
+
"wait_reset"
|
|
3501
|
+
];
|
|
3502
|
+
}
|
|
3503
|
+
});
|
|
3504
|
+
|
|
3481
3505
|
// src/store/issue-source-labels.ts
|
|
3482
3506
|
function issueSourceLabel(source) {
|
|
3483
3507
|
if (source && source in ISSUE_SOURCE_LABELS) {
|
|
@@ -3506,6 +3530,7 @@ __export(app_settings_exports, {
|
|
|
3506
3530
|
HARNESS_ENV_KEYS: () => HARNESS_ENV_KEYS,
|
|
3507
3531
|
ISSUE_SOURCE_LABELS: () => ISSUE_SOURCE_LABELS,
|
|
3508
3532
|
PROFILE_NOTES_MAX: () => PROFILE_NOTES_MAX,
|
|
3533
|
+
USAGE_ON_LIMIT_VALUES: () => USAGE_ON_LIMIT_VALUES,
|
|
3509
3534
|
appSettingsPath: () => appSettingsPath,
|
|
3510
3535
|
applyAppEnvironment: () => applyAppEnvironment,
|
|
3511
3536
|
autoArchiveOnMergeEnabled: () => autoArchiveOnMergeEnabled,
|
|
@@ -3522,6 +3547,7 @@ __export(app_settings_exports, {
|
|
|
3522
3547
|
childEnvWithAppSettings: () => childEnvWithAppSettings,
|
|
3523
3548
|
claudeChromeEnabled: () => claudeChromeEnabled,
|
|
3524
3549
|
claudeUserSettingsPath: () => claudeUserSettingsPath,
|
|
3550
|
+
confirmClaudeUsageOverLimitEnabled: () => confirmClaudeUsageOverLimitEnabled,
|
|
3525
3551
|
cowboyModeEnabled: () => cowboyModeEnabled,
|
|
3526
3552
|
deleteBranchOnPurgeEnabled: () => deleteBranchOnPurgeEnabled,
|
|
3527
3553
|
disconnectAbleTimeConnection: () => disconnectAbleTimeConnection,
|
|
@@ -3551,6 +3577,7 @@ __export(app_settings_exports, {
|
|
|
3551
3577
|
isAbleTimeConnected: () => isAbleTimeConnected,
|
|
3552
3578
|
isIssueSourceConnected: () => isIssueSourceConnected,
|
|
3553
3579
|
isLinearConnected: () => isLinearConnected,
|
|
3580
|
+
isUsageOnLimit: () => isUsageOnLimit,
|
|
3554
3581
|
issueSourceLabel: () => issueSourceLabel,
|
|
3555
3582
|
loadAppSettings: () => loadAppSettings,
|
|
3556
3583
|
maxConcurrentAgents: () => maxConcurrentAgents,
|
|
@@ -3566,6 +3593,7 @@ __export(app_settings_exports, {
|
|
|
3566
3593
|
resolveNewThreadOptions: () => resolveNewThreadOptions,
|
|
3567
3594
|
resolveOrchestratorDefaults: () => resolveOrchestratorDefaults,
|
|
3568
3595
|
resolveThreadDefaults: () => resolveThreadDefaults,
|
|
3596
|
+
resolveUsageOnLimit: () => resolveUsageOnLimit,
|
|
3569
3597
|
resolveViewerProfile: () => resolveViewerProfile,
|
|
3570
3598
|
resolveViewerProfileForRepo: () => resolveViewerProfileForRepo,
|
|
3571
3599
|
saveAbleTimeConnection: () => saveAbleTimeConnection,
|
|
@@ -3585,6 +3613,7 @@ __export(app_settings_exports, {
|
|
|
3585
3613
|
updateIntegrationsSettings: () => updateIntegrationsSettings,
|
|
3586
3614
|
updateOpencodeSettings: () => updateOpencodeSettings,
|
|
3587
3615
|
updateProjectProfileSettings: () => updateProjectProfileSettings,
|
|
3616
|
+
usageOnLimit: () => usageOnLimit,
|
|
3588
3617
|
writeViewerContext: () => writeViewerContext
|
|
3589
3618
|
});
|
|
3590
3619
|
function emptyPublicIntegrations() {
|
|
@@ -3949,6 +3978,12 @@ function normalizeAdvanced(raw) {
|
|
|
3949
3978
|
if (typeof source.showCost === "boolean") {
|
|
3950
3979
|
out.showCost = source.showCost;
|
|
3951
3980
|
}
|
|
3981
|
+
if (isUsageOnLimit(source.usageOnLimit)) {
|
|
3982
|
+
out.usageOnLimit = source.usageOnLimit;
|
|
3983
|
+
}
|
|
3984
|
+
if (typeof source.confirmClaudeUsageOverLimit === "boolean") {
|
|
3985
|
+
out.confirmClaudeUsageOverLimit = source.confirmClaudeUsageOverLimit;
|
|
3986
|
+
}
|
|
3952
3987
|
if (typeof source.autoArchiveOnMerge === "boolean") {
|
|
3953
3988
|
out.autoArchiveOnMerge = source.autoArchiveOnMerge;
|
|
3954
3989
|
}
|
|
@@ -4811,6 +4846,17 @@ function updateAdvancedSettings(patch) {
|
|
|
4811
4846
|
if (typeof patch.showCost === "boolean") {
|
|
4812
4847
|
advanced.showCost = patch.showCost;
|
|
4813
4848
|
}
|
|
4849
|
+
if (isUsageOnLimit(patch.usageOnLimit)) {
|
|
4850
|
+
advanced.usageOnLimit = patch.usageOnLimit;
|
|
4851
|
+
advanced.confirmClaudeUsageOverLimit = patch.usageOnLimit === "confirm";
|
|
4852
|
+
if (patch.usageOnLimit === "switch_agent" || patch.usageOnLimit === "wait_reset") {
|
|
4853
|
+
advanced.orchestrationQuotaOnLimit = patch.usageOnLimit;
|
|
4854
|
+
}
|
|
4855
|
+
} else if (typeof patch.confirmClaudeUsageOverLimit === "boolean") {
|
|
4856
|
+
advanced.confirmClaudeUsageOverLimit = patch.confirmClaudeUsageOverLimit;
|
|
4857
|
+
if (patch.confirmClaudeUsageOverLimit) advanced.usageOnLimit = "confirm";
|
|
4858
|
+
else if (advanced.usageOnLimit === "confirm") advanced.usageOnLimit = "keep_going";
|
|
4859
|
+
}
|
|
4814
4860
|
if (typeof patch.autoArchiveOnMerge === "boolean") {
|
|
4815
4861
|
advanced.autoArchiveOnMerge = patch.autoArchiveOnMerge;
|
|
4816
4862
|
}
|
|
@@ -4873,14 +4919,21 @@ function cowboyModeEnabled(settings = loadAppSettings()) {
|
|
|
4873
4919
|
function showCostEnabled(settings = loadAppSettings()) {
|
|
4874
4920
|
return Boolean(settings.advanced.showCost);
|
|
4875
4921
|
}
|
|
4922
|
+
function confirmClaudeUsageOverLimitEnabled(settings = loadAppSettings()) {
|
|
4923
|
+
return usageOnLimit(settings) === "confirm";
|
|
4924
|
+
}
|
|
4876
4925
|
function autoArchiveOnMergeEnabled(settings = loadAppSettings()) {
|
|
4877
4926
|
return Boolean(settings.advanced.autoArchiveOnMerge);
|
|
4878
4927
|
}
|
|
4879
4928
|
function autoCleanupOrphansEnabled(settings = loadAppSettings()) {
|
|
4880
4929
|
return Boolean(settings.advanced.autoCleanupOrphans);
|
|
4881
4930
|
}
|
|
4931
|
+
function usageOnLimit(settings = loadAppSettings()) {
|
|
4932
|
+
return resolveUsageOnLimit(settings.advanced);
|
|
4933
|
+
}
|
|
4882
4934
|
function orchestrationQuotaOnLimit(settings = loadAppSettings()) {
|
|
4883
|
-
|
|
4935
|
+
const action = usageOnLimit(settings);
|
|
4936
|
+
return action === "wait_reset" ? "wait_reset" : "switch_agent";
|
|
4884
4937
|
}
|
|
4885
4938
|
function orchestrationQuotaFallbackAgent(settings = loadAppSettings()) {
|
|
4886
4939
|
const preferred = settings.advanced.orchestrationQuotaFallbackAgent;
|
|
@@ -4995,6 +5048,8 @@ var init_app_settings = __esm({
|
|
|
4995
5048
|
init_private_file();
|
|
4996
5049
|
init_secret_vault();
|
|
4997
5050
|
init_branch_prefix();
|
|
5051
|
+
init_usage_on_limit();
|
|
5052
|
+
init_usage_on_limit();
|
|
4998
5053
|
init_issue_source_labels();
|
|
4999
5054
|
init_account_profile();
|
|
5000
5055
|
HARNESS_ENV_KEYS = {
|
|
@@ -12189,6 +12244,30 @@ var init_session_quota = __esm({
|
|
|
12189
12244
|
}
|
|
12190
12245
|
});
|
|
12191
12246
|
|
|
12247
|
+
// src/agents/claude-usage.ts
|
|
12248
|
+
var init_claude_usage = __esm({
|
|
12249
|
+
"src/agents/claude-usage.ts"() {
|
|
12250
|
+
"use strict";
|
|
12251
|
+
}
|
|
12252
|
+
});
|
|
12253
|
+
|
|
12254
|
+
// src/agents/claude-usage-client.ts
|
|
12255
|
+
var import_node_fs33, import_node_os13, import_node_path33, CLAUDE_USAGE_ERROR_TTL_MS, CLAUDE_USAGE_STALE_OK_MS;
|
|
12256
|
+
var init_claude_usage_client = __esm({
|
|
12257
|
+
"src/agents/claude-usage-client.ts"() {
|
|
12258
|
+
"use strict";
|
|
12259
|
+
import_node_fs33 = require("fs");
|
|
12260
|
+
import_node_os13 = require("os");
|
|
12261
|
+
import_node_path33 = require("path");
|
|
12262
|
+
init_run();
|
|
12263
|
+
init_fetch();
|
|
12264
|
+
init_app_settings();
|
|
12265
|
+
init_claude_usage();
|
|
12266
|
+
CLAUDE_USAGE_ERROR_TTL_MS = 5 * 6e4;
|
|
12267
|
+
CLAUDE_USAGE_STALE_OK_MS = 30 * 6e4;
|
|
12268
|
+
}
|
|
12269
|
+
});
|
|
12270
|
+
|
|
12192
12271
|
// src/agents/install.ts
|
|
12193
12272
|
var init_install = __esm({
|
|
12194
12273
|
"src/agents/install.ts"() {
|
|
@@ -12223,6 +12302,8 @@ var init_agents = __esm({
|
|
|
12223
12302
|
init_opencode();
|
|
12224
12303
|
init_list_models();
|
|
12225
12304
|
init_session_quota();
|
|
12305
|
+
init_claude_usage();
|
|
12306
|
+
init_claude_usage_client();
|
|
12226
12307
|
init_orchestrator_capable();
|
|
12227
12308
|
init_path();
|
|
12228
12309
|
init_install();
|
|
@@ -12238,15 +12319,15 @@ var init_agents = __esm({
|
|
|
12238
12319
|
|
|
12239
12320
|
// src/hook/worktree-pkg-cache.ts
|
|
12240
12321
|
function worktreePkgCacheRoot(worktreePath) {
|
|
12241
|
-
return (0,
|
|
12322
|
+
return (0, import_node_path34.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
|
|
12242
12323
|
}
|
|
12243
12324
|
function worktreePkgCacheEnv(worktreePath) {
|
|
12244
12325
|
const root = worktreePkgCacheRoot(worktreePath);
|
|
12245
|
-
const store = (0,
|
|
12246
|
-
const pnpmCache = (0,
|
|
12247
|
-
const npmCache = (0,
|
|
12248
|
-
const nodeGyp = (0,
|
|
12249
|
-
const electron = (0,
|
|
12326
|
+
const store = (0, import_node_path34.join)(root, "pnpm-store");
|
|
12327
|
+
const pnpmCache = (0, import_node_path34.join)(root, "pnpm");
|
|
12328
|
+
const npmCache = (0, import_node_path34.join)(root, "npm");
|
|
12329
|
+
const nodeGyp = (0, import_node_path34.join)(root, "node-gyp");
|
|
12330
|
+
const electron = (0, import_node_path34.join)(root, "electron");
|
|
12250
12331
|
return {
|
|
12251
12332
|
npm_config_store_dir: store,
|
|
12252
12333
|
PNPM_STORE_DIR: store,
|
|
@@ -12268,8 +12349,8 @@ function fillGroup(env, keys, values) {
|
|
|
12268
12349
|
}
|
|
12269
12350
|
}
|
|
12270
12351
|
function ensureWorktreePkgCacheDirs(worktreePath) {
|
|
12271
|
-
if (!(0,
|
|
12272
|
-
(0,
|
|
12352
|
+
if (!(0, import_node_fs34.existsSync)(worktreePath)) return;
|
|
12353
|
+
(0, import_node_fs34.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
|
|
12273
12354
|
}
|
|
12274
12355
|
function applyWorktreePkgCacheEnv(env, worktreePath) {
|
|
12275
12356
|
const cwd = worktreePath.trim();
|
|
@@ -12282,12 +12363,12 @@ function applyWorktreePkgCacheEnv(env, worktreePath) {
|
|
|
12282
12363
|
fillGroup(env, ["electron_config_cache"], next);
|
|
12283
12364
|
ensureWorktreePkgCacheDirs(cwd);
|
|
12284
12365
|
}
|
|
12285
|
-
var
|
|
12366
|
+
var import_node_fs34, import_node_path34, WORKTREE_PKG_CACHE_REL;
|
|
12286
12367
|
var init_worktree_pkg_cache = __esm({
|
|
12287
12368
|
"src/hook/worktree-pkg-cache.ts"() {
|
|
12288
12369
|
"use strict";
|
|
12289
|
-
|
|
12290
|
-
|
|
12370
|
+
import_node_fs34 = require("fs");
|
|
12371
|
+
import_node_path34 = require("path");
|
|
12291
12372
|
WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
|
|
12292
12373
|
}
|
|
12293
12374
|
});
|
|
@@ -13403,21 +13484,21 @@ function shouldRefreshReviewRequestTemplate(content) {
|
|
|
13403
13484
|
return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
|
|
13404
13485
|
}
|
|
13405
13486
|
function readTextIfPresent(abs) {
|
|
13406
|
-
if (!(0,
|
|
13487
|
+
if (!(0, import_node_fs35.existsSync)(abs)) return null;
|
|
13407
13488
|
try {
|
|
13408
|
-
const content = (0,
|
|
13489
|
+
const content = (0, import_node_fs35.readFileSync)(abs, "utf8");
|
|
13409
13490
|
return content.trim() ? content : null;
|
|
13410
13491
|
} catch {
|
|
13411
13492
|
return null;
|
|
13412
13493
|
}
|
|
13413
13494
|
}
|
|
13414
13495
|
function readLocalGuidelines(worktreePath) {
|
|
13415
|
-
const localAbs = (0,
|
|
13496
|
+
const localAbs = (0, import_node_path35.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
13416
13497
|
const localContent = readTextIfPresent(localAbs);
|
|
13417
13498
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
13418
13499
|
return { path: REVIEW_REQUEST_PATH, content: localContent };
|
|
13419
13500
|
}
|
|
13420
|
-
const legacyAbs = (0,
|
|
13501
|
+
const legacyAbs = (0, import_node_path35.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
|
|
13421
13502
|
const legacyContent = readTextIfPresent(legacyAbs);
|
|
13422
13503
|
if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
|
|
13423
13504
|
return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
|
|
@@ -13441,27 +13522,27 @@ function contextGuidelines(content, source) {
|
|
|
13441
13522
|
};
|
|
13442
13523
|
}
|
|
13443
13524
|
function writeContextGuidelines(worktreePath, content) {
|
|
13444
|
-
const abs = (0,
|
|
13445
|
-
(0,
|
|
13525
|
+
const abs = (0, import_node_path35.join)(worktreePath, CONTEXT_REVIEW_PATH);
|
|
13526
|
+
(0, import_node_fs35.mkdirSync)((0, import_node_path35.dirname)(abs), { recursive: true });
|
|
13446
13527
|
const body = content.endsWith("\n") ? content : `${content}
|
|
13447
13528
|
`;
|
|
13448
|
-
(0,
|
|
13529
|
+
(0, import_node_fs35.writeFileSync)(abs, body, "utf8");
|
|
13449
13530
|
return body;
|
|
13450
13531
|
}
|
|
13451
13532
|
function readSideboardReview(worktreePath, repoPath) {
|
|
13452
|
-
const fromWorktree = readTextIfPresent((0,
|
|
13533
|
+
const fromWorktree = readTextIfPresent((0, import_node_path35.join)(worktreePath, REPO_REVIEW_PATH));
|
|
13453
13534
|
if (fromWorktree) return fromWorktree;
|
|
13454
13535
|
const repo = repoPath?.replace(/\/+$/, "");
|
|
13455
13536
|
const wt = worktreePath.replace(/\/+$/, "");
|
|
13456
13537
|
if (!repo || repo === wt) return null;
|
|
13457
|
-
return readTextIfPresent((0,
|
|
13538
|
+
return readTextIfPresent((0, import_node_path35.join)(repo, REPO_REVIEW_PATH));
|
|
13458
13539
|
}
|
|
13459
13540
|
function ensureReviewGuidelinesFile(worktreePath, repoPath) {
|
|
13460
|
-
const skillContent = readTextIfPresent((0,
|
|
13541
|
+
const skillContent = readTextIfPresent((0, import_node_path35.join)(worktreePath, REVIEW_SKILL_PATH));
|
|
13461
13542
|
if (skillContent) {
|
|
13462
13543
|
return { ...skillGuidelines(skillContent, "skill"), wrote: false };
|
|
13463
13544
|
}
|
|
13464
|
-
const contextContent = readTextIfPresent((0,
|
|
13545
|
+
const contextContent = readTextIfPresent((0, import_node_path35.join)(worktreePath, CONTEXT_REVIEW_PATH));
|
|
13465
13546
|
if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
|
|
13466
13547
|
return { ...contextGuidelines(contextContent, "local"), wrote: false };
|
|
13467
13548
|
}
|
|
@@ -13516,13 +13597,13 @@ async function requestReview(threadRef, send) {
|
|
|
13516
13597
|
const started = await send(tab.id, REVIEW_REQUEST_PREFILL);
|
|
13517
13598
|
return { tab: started, from };
|
|
13518
13599
|
}
|
|
13519
|
-
var import_node_crypto7,
|
|
13600
|
+
var import_node_crypto7, import_node_fs35, import_node_path35, 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;
|
|
13520
13601
|
var init_request_review = __esm({
|
|
13521
13602
|
"src/review/request-review.ts"() {
|
|
13522
13603
|
"use strict";
|
|
13523
13604
|
import_node_crypto7 = require("crypto");
|
|
13524
|
-
|
|
13525
|
-
|
|
13605
|
+
import_node_fs35 = require("fs");
|
|
13606
|
+
import_node_path35 = require("path");
|
|
13526
13607
|
init_global_workspace();
|
|
13527
13608
|
init_chat_tabs();
|
|
13528
13609
|
init_thread_store();
|
|
@@ -13548,9 +13629,9 @@ function matchSimpleGlob(pattern, name) {
|
|
|
13548
13629
|
return new RegExp(`^${escaped}$`).test(name);
|
|
13549
13630
|
}
|
|
13550
13631
|
function readWorktreeInclude(repoPath) {
|
|
13551
|
-
const path = (0,
|
|
13552
|
-
if (!(0,
|
|
13553
|
-
return (0,
|
|
13632
|
+
const path = (0, import_node_path36.join)(repoPath, ".worktreeinclude");
|
|
13633
|
+
if (!(0, import_node_fs36.existsSync)(path)) return [];
|
|
13634
|
+
return (0, import_node_fs36.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
13554
13635
|
}
|
|
13555
13636
|
function resolveFilesToCopy(repoPath) {
|
|
13556
13637
|
const fromInclude = readWorktreeInclude(repoPath);
|
|
@@ -13560,10 +13641,10 @@ function resolveFilesToCopy(repoPath) {
|
|
|
13560
13641
|
if (settings?.fileIncludeGlobs?.length) {
|
|
13561
13642
|
const matched = [];
|
|
13562
13643
|
try {
|
|
13563
|
-
for (const entry of (0,
|
|
13644
|
+
for (const entry of (0, import_node_fs36.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
13564
13645
|
if (!entry.isFile()) continue;
|
|
13565
13646
|
for (const glob of settings.fileIncludeGlobs) {
|
|
13566
|
-
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0,
|
|
13647
|
+
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path36.basename)(glob), entry.name)) {
|
|
13567
13648
|
matched.push(entry.name);
|
|
13568
13649
|
break;
|
|
13569
13650
|
}
|
|
@@ -13575,7 +13656,7 @@ function resolveFilesToCopy(repoPath) {
|
|
|
13575
13656
|
}
|
|
13576
13657
|
const defaults = [];
|
|
13577
13658
|
try {
|
|
13578
|
-
for (const entry of (0,
|
|
13659
|
+
for (const entry of (0, import_node_fs36.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
13579
13660
|
if (entry.isFile() && entry.name.startsWith(".env")) {
|
|
13580
13661
|
defaults.push(entry.name);
|
|
13581
13662
|
}
|
|
@@ -13589,11 +13670,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
|
|
|
13589
13670
|
const patterns = resolveFilesToCopy(repoPath);
|
|
13590
13671
|
const copied = [];
|
|
13591
13672
|
for (const rel of patterns) {
|
|
13592
|
-
const src = (0,
|
|
13593
|
-
if (!(0,
|
|
13594
|
-
const dest = (0,
|
|
13595
|
-
(0,
|
|
13596
|
-
(0,
|
|
13673
|
+
const src = (0, import_node_path36.join)(repoPath, rel);
|
|
13674
|
+
if (!(0, import_node_fs36.existsSync)(src)) continue;
|
|
13675
|
+
const dest = (0, import_node_path36.join)(worktreePath, rel);
|
|
13676
|
+
(0, import_node_fs36.mkdirSync)((0, import_node_path36.dirname)(dest), { recursive: true });
|
|
13677
|
+
(0, import_node_fs36.copyFileSync)(src, dest);
|
|
13597
13678
|
copied.push(rel);
|
|
13598
13679
|
}
|
|
13599
13680
|
return copied;
|
|
@@ -13628,7 +13709,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
|
13628
13709
|
const env = stripNestedElectronEnv({
|
|
13629
13710
|
...baseEnv ?? process.env
|
|
13630
13711
|
});
|
|
13631
|
-
const name = opts.workspaceName ?? (0,
|
|
13712
|
+
const name = opts.workspaceName ?? (0, import_node_path36.basename)(opts.worktreePath);
|
|
13632
13713
|
const ports = opts.ports ?? [];
|
|
13633
13714
|
const primary = ports[0];
|
|
13634
13715
|
env.SIDEBOARD_WORKSPACE_NAME = name;
|
|
@@ -13891,13 +13972,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
13891
13972
|
done: handle.done
|
|
13892
13973
|
};
|
|
13893
13974
|
}
|
|
13894
|
-
var
|
|
13975
|
+
var import_node_fs36, import_node_net, import_node_path36, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
|
|
13895
13976
|
var init_conductor = __esm({
|
|
13896
13977
|
"src/hook/conductor.ts"() {
|
|
13897
13978
|
"use strict";
|
|
13898
|
-
|
|
13979
|
+
import_node_fs36 = require("fs");
|
|
13899
13980
|
import_node_net = require("net");
|
|
13900
|
-
|
|
13981
|
+
import_node_path36 = require("path");
|
|
13901
13982
|
import_execa4 = require("execa");
|
|
13902
13983
|
import_node_readline3 = require("readline");
|
|
13903
13984
|
init_settings();
|
|
@@ -13924,7 +14005,7 @@ ${line}` : line;
|
|
|
13924
14005
|
return nl >= 0 && nl < cut.length - 1 ? cut.slice(nl + 1) : cut;
|
|
13925
14006
|
}
|
|
13926
14007
|
function setupLogPath(threadId) {
|
|
13927
|
-
return (0,
|
|
14008
|
+
return (0, import_node_path37.join)(threadsDir(), `${threadId}.setup.log.json`);
|
|
13928
14009
|
}
|
|
13929
14010
|
function setupLogKeyForWorktree(worktreePath) {
|
|
13930
14011
|
const norm = normalizeWorktreePath(worktreePath);
|
|
@@ -13945,7 +14026,7 @@ function persistNow(threadId) {
|
|
|
13945
14026
|
const snap = memory.get(threadId);
|
|
13946
14027
|
if (!snap) return;
|
|
13947
14028
|
try {
|
|
13948
|
-
(0,
|
|
14029
|
+
(0, import_node_fs37.writeFileSync)(setupLogPath(threadId), `${JSON.stringify(snap)}
|
|
13949
14030
|
`, "utf8");
|
|
13950
14031
|
} catch {
|
|
13951
14032
|
}
|
|
@@ -13962,9 +14043,9 @@ function schedulePersist(threadId) {
|
|
|
13962
14043
|
}
|
|
13963
14044
|
function loadFromDisk(threadId) {
|
|
13964
14045
|
const path = setupLogPath(threadId);
|
|
13965
|
-
if (!(0,
|
|
14046
|
+
if (!(0, import_node_fs37.existsSync)(path)) return null;
|
|
13966
14047
|
try {
|
|
13967
|
-
const raw = JSON.parse((0,
|
|
14048
|
+
const raw = JSON.parse((0, import_node_fs37.readFileSync)(path, "utf8"));
|
|
13968
14049
|
return {
|
|
13969
14050
|
output: typeof raw.output === "string" ? raw.output : "",
|
|
13970
14051
|
running: Boolean(raw.running),
|
|
@@ -14019,13 +14100,13 @@ function finishSetupLog(threadId, exitCode, source) {
|
|
|
14019
14100
|
persistNow(threadId);
|
|
14020
14101
|
return clone(snap);
|
|
14021
14102
|
}
|
|
14022
|
-
var import_node_crypto8,
|
|
14103
|
+
var import_node_crypto8, import_node_fs37, import_node_path37, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers;
|
|
14023
14104
|
var init_setup_log = __esm({
|
|
14024
14105
|
"src/store/setup-log.ts"() {
|
|
14025
14106
|
"use strict";
|
|
14026
14107
|
import_node_crypto8 = require("crypto");
|
|
14027
|
-
|
|
14028
|
-
|
|
14108
|
+
import_node_fs37 = require("fs");
|
|
14109
|
+
import_node_path37 = require("path");
|
|
14029
14110
|
init_worktree_labels();
|
|
14030
14111
|
init_paths();
|
|
14031
14112
|
EMPTY = {
|
|
@@ -14051,9 +14132,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
14051
14132
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
14052
14133
|
);
|
|
14053
14134
|
const homeRoot = sideboardWorkspacesDir();
|
|
14054
|
-
if ((0,
|
|
14135
|
+
if ((0, import_node_fs38.existsSync)(homeRoot)) {
|
|
14055
14136
|
try {
|
|
14056
|
-
for (const entry of (0,
|
|
14137
|
+
for (const entry of (0, import_node_fs38.readdirSync)(homeRoot, { withFileTypes: true })) {
|
|
14057
14138
|
if (!entry.isDirectory()) continue;
|
|
14058
14139
|
void entry;
|
|
14059
14140
|
}
|
|
@@ -14063,7 +14144,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
14063
14144
|
const orphans = [];
|
|
14064
14145
|
const seen = /* @__PURE__ */ new Set();
|
|
14065
14146
|
for (const repoPath of repos) {
|
|
14066
|
-
if (!repoPath || !(0,
|
|
14147
|
+
if (!repoPath || !(0, import_node_fs38.existsSync)(repoPath)) continue;
|
|
14067
14148
|
try {
|
|
14068
14149
|
const wts = await listWorktrees(repoPath);
|
|
14069
14150
|
for (const wt of wts) {
|
|
@@ -14074,7 +14155,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
14074
14155
|
seen.add(path);
|
|
14075
14156
|
let mtimeMs = 0;
|
|
14076
14157
|
try {
|
|
14077
|
-
mtimeMs = (0,
|
|
14158
|
+
mtimeMs = (0, import_node_fs38.statSync)(path).mtimeMs;
|
|
14078
14159
|
} catch {
|
|
14079
14160
|
mtimeMs = 0;
|
|
14080
14161
|
}
|
|
@@ -14084,16 +14165,16 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
14084
14165
|
}
|
|
14085
14166
|
try {
|
|
14086
14167
|
const root = worktreesRoot(repoPath);
|
|
14087
|
-
if ((0,
|
|
14088
|
-
for (const entry of (0,
|
|
14168
|
+
if ((0, import_node_fs38.existsSync)(root)) {
|
|
14169
|
+
for (const entry of (0, import_node_fs38.readdirSync)(root, { withFileTypes: true })) {
|
|
14089
14170
|
if (!entry.isDirectory()) continue;
|
|
14090
|
-
const path = (0,
|
|
14171
|
+
const path = (0, import_node_path38.join)(root, entry.name).replace(/\/$/, "");
|
|
14091
14172
|
if (known.has(path) || seen.has(path)) continue;
|
|
14092
|
-
if (!(0,
|
|
14173
|
+
if (!(0, import_node_fs38.existsSync)((0, import_node_path38.join)(path, ".git"))) continue;
|
|
14093
14174
|
seen.add(path);
|
|
14094
14175
|
let mtimeMs = 0;
|
|
14095
14176
|
try {
|
|
14096
|
-
mtimeMs = (0,
|
|
14177
|
+
mtimeMs = (0, import_node_fs38.statSync)(path).mtimeMs;
|
|
14097
14178
|
} catch {
|
|
14098
14179
|
mtimeMs = Date.now();
|
|
14099
14180
|
}
|
|
@@ -14145,12 +14226,12 @@ function shouldRunWorktreeCleanup(settings = loadAppSettings()) {
|
|
|
14145
14226
|
const elapsed = Date.now() - Date.parse(last);
|
|
14146
14227
|
return elapsed >= intervalHours * 36e5;
|
|
14147
14228
|
}
|
|
14148
|
-
var
|
|
14229
|
+
var import_node_fs38, import_node_path38;
|
|
14149
14230
|
var init_orphan_cleanup = __esm({
|
|
14150
14231
|
"src/git/orphan-cleanup.ts"() {
|
|
14151
14232
|
"use strict";
|
|
14152
|
-
|
|
14153
|
-
|
|
14233
|
+
import_node_fs38 = require("fs");
|
|
14234
|
+
import_node_path38 = require("path");
|
|
14154
14235
|
init_worktree();
|
|
14155
14236
|
init_thread_store();
|
|
14156
14237
|
init_paths();
|
|
@@ -14253,12 +14334,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
14253
14334
|
if (!url) throw new Error("Clone URL is required");
|
|
14254
14335
|
let name = opts.name?.trim();
|
|
14255
14336
|
if (!name) {
|
|
14256
|
-
const leaf = (0,
|
|
14337
|
+
const leaf = (0, import_node_path39.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
|
|
14257
14338
|
name = leaf || "repo";
|
|
14258
14339
|
}
|
|
14259
14340
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
14260
|
-
const dest = (0,
|
|
14261
|
-
if ((0,
|
|
14341
|
+
const dest = (0, import_node_path39.join)(sideboardReposDir(), name);
|
|
14342
|
+
if ((0, import_node_fs39.existsSync)(dest)) {
|
|
14262
14343
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
14263
14344
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
14264
14345
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -14273,12 +14354,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
14273
14354
|
const workspace = await ensureWorkspace(repoPath);
|
|
14274
14355
|
return { repoPath, workspace };
|
|
14275
14356
|
}
|
|
14276
|
-
var
|
|
14357
|
+
var import_node_fs39, import_node_path39, import_execa6;
|
|
14277
14358
|
var init_clone_repo = __esm({
|
|
14278
14359
|
"src/git/clone-repo.ts"() {
|
|
14279
14360
|
"use strict";
|
|
14280
|
-
|
|
14281
|
-
|
|
14361
|
+
import_node_fs39 = require("fs");
|
|
14362
|
+
import_node_path39 = require("path");
|
|
14282
14363
|
import_execa6 = require("execa");
|
|
14283
14364
|
init_paths();
|
|
14284
14365
|
init_workspaces2();
|
|
@@ -14288,11 +14369,11 @@ var init_clone_repo = __esm({
|
|
|
14288
14369
|
|
|
14289
14370
|
// src/store/desktop-host.ts
|
|
14290
14371
|
function desktopHostPidPath() {
|
|
14291
|
-
return (0,
|
|
14372
|
+
return (0, import_node_path40.join)(appDataDir(), "desktop-host.pid");
|
|
14292
14373
|
}
|
|
14293
14374
|
function readDesktopHostPid() {
|
|
14294
14375
|
try {
|
|
14295
|
-
const pid = Number.parseInt((0,
|
|
14376
|
+
const pid = Number.parseInt((0, import_node_fs40.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
|
|
14296
14377
|
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
14297
14378
|
return pid;
|
|
14298
14379
|
} catch {
|
|
@@ -14318,12 +14399,12 @@ function thisProcessShouldDrainAgentQueues() {
|
|
|
14318
14399
|
if (isThisProcessDesktopHost()) return true;
|
|
14319
14400
|
return !isDesktopHostAlive();
|
|
14320
14401
|
}
|
|
14321
|
-
var
|
|
14402
|
+
var import_node_fs40, import_node_path40;
|
|
14322
14403
|
var init_desktop_host = __esm({
|
|
14323
14404
|
"src/store/desktop-host.ts"() {
|
|
14324
14405
|
"use strict";
|
|
14325
|
-
|
|
14326
|
-
|
|
14406
|
+
import_node_fs40 = require("fs");
|
|
14407
|
+
import_node_path40 = require("path");
|
|
14327
14408
|
init_paths();
|
|
14328
14409
|
}
|
|
14329
14410
|
});
|
|
@@ -14438,24 +14519,24 @@ function jobTreeAlive(pid) {
|
|
|
14438
14519
|
return jobAlive(pid) || processGroupAlive(pid);
|
|
14439
14520
|
}
|
|
14440
14521
|
function readIntFile(file) {
|
|
14441
|
-
if (!(0,
|
|
14442
|
-
const n = Number.parseInt((0,
|
|
14522
|
+
if (!(0, import_node_fs41.existsSync)(file)) return null;
|
|
14523
|
+
const n = Number.parseInt((0, import_node_fs41.readFileSync)(file, "utf8").trim(), 10);
|
|
14443
14524
|
return Number.isInteger(n) ? n : null;
|
|
14444
14525
|
}
|
|
14445
14526
|
function jobDir(root, id, legacy = false) {
|
|
14446
|
-
return (0,
|
|
14527
|
+
return (0, import_node_path41.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
|
|
14447
14528
|
}
|
|
14448
14529
|
function resolveJobDir(root, id) {
|
|
14449
14530
|
const modern = jobDir(root, id, false);
|
|
14450
|
-
if ((0,
|
|
14531
|
+
if ((0, import_node_fs41.existsSync)(modern)) return modern;
|
|
14451
14532
|
const legacy = jobDir(root, id, true);
|
|
14452
|
-
if ((0,
|
|
14533
|
+
if ((0, import_node_fs41.existsSync)(legacy)) return legacy;
|
|
14453
14534
|
return modern;
|
|
14454
14535
|
}
|
|
14455
14536
|
function listJobIdsIn(root, rel) {
|
|
14456
|
-
const dir = (0,
|
|
14457
|
-
if (!(0,
|
|
14458
|
-
return (0,
|
|
14537
|
+
const dir = (0, import_node_path41.join)(root, rel);
|
|
14538
|
+
if (!(0, import_node_fs41.existsSync)(dir)) return [];
|
|
14539
|
+
return (0, import_node_fs41.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
|
|
14459
14540
|
}
|
|
14460
14541
|
function listRunningDetachedJobs(worktreePath) {
|
|
14461
14542
|
const root = worktreePath.trim();
|
|
@@ -14467,7 +14548,7 @@ function listRunningDetachedJobs(worktreePath) {
|
|
|
14467
14548
|
const running = [];
|
|
14468
14549
|
for (const id of ids) {
|
|
14469
14550
|
const dir = resolveJobDir(root, id);
|
|
14470
|
-
const pid = readIntFile((0,
|
|
14551
|
+
const pid = readIntFile((0, import_node_path41.join)(dir, "pid"));
|
|
14471
14552
|
if (jobTreeAlive(pid)) running.push(id);
|
|
14472
14553
|
}
|
|
14473
14554
|
return running.sort();
|
|
@@ -14549,8 +14630,8 @@ function planJobContinue(opts) {
|
|
|
14549
14630
|
return { action: "none" };
|
|
14550
14631
|
}
|
|
14551
14632
|
function tailProgress(logFile, maxLines = 12) {
|
|
14552
|
-
if (!(0,
|
|
14553
|
-
const lines = (0,
|
|
14633
|
+
if (!(0, import_node_fs41.existsSync)(logFile)) return "(no log yet)";
|
|
14634
|
+
const lines = (0, import_node_fs41.readFileSync)(logFile, "utf8").split("\n");
|
|
14554
14635
|
return lines.slice(-maxLines).join("\n");
|
|
14555
14636
|
}
|
|
14556
14637
|
function lastProgressLine(progress) {
|
|
@@ -14558,8 +14639,8 @@ function lastProgressLine(progress) {
|
|
|
14558
14639
|
return last ? last.slice(0, 72) : void 0;
|
|
14559
14640
|
}
|
|
14560
14641
|
function readLogLines(file) {
|
|
14561
|
-
if (!(0,
|
|
14562
|
-
const lines = (0,
|
|
14642
|
+
if (!(0, import_node_fs41.existsSync)(file)) return [];
|
|
14643
|
+
const lines = (0, import_node_fs41.readFileSync)(file, "utf8").split("\n");
|
|
14563
14644
|
if (lines.length && lines[lines.length - 1] === "") lines.pop();
|
|
14564
14645
|
return lines;
|
|
14565
14646
|
}
|
|
@@ -14570,15 +14651,15 @@ function takeDelta(logFile, cursorFile) {
|
|
|
14570
14651
|
return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
|
|
14571
14652
|
}
|
|
14572
14653
|
function snapshotJob(dir) {
|
|
14573
|
-
const pid = readIntFile((0,
|
|
14654
|
+
const pid = readIntFile((0, import_node_path41.join)(dir, "pid"));
|
|
14574
14655
|
const running = jobTreeAlive(pid);
|
|
14575
14656
|
return {
|
|
14576
14657
|
pid,
|
|
14577
14658
|
running,
|
|
14578
|
-
exitCode: readIntFile((0,
|
|
14579
|
-
log: (0,
|
|
14580
|
-
cursor: (0,
|
|
14581
|
-
progress: tailProgress((0,
|
|
14659
|
+
exitCode: readIntFile((0, import_node_path41.join)(dir, "exit")),
|
|
14660
|
+
log: (0, import_node_path41.join)(dir, "log"),
|
|
14661
|
+
cursor: (0, import_node_path41.join)(dir, "present.cursor"),
|
|
14662
|
+
progress: tailProgress((0, import_node_path41.join)(dir, "log"))
|
|
14582
14663
|
};
|
|
14583
14664
|
}
|
|
14584
14665
|
function toResult(id, snap, extra) {
|
|
@@ -14587,8 +14668,8 @@ function toResult(id, snap, extra) {
|
|
|
14587
14668
|
const stillRunning = snap.running && !ok;
|
|
14588
14669
|
const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
|
|
14589
14670
|
try {
|
|
14590
|
-
(0,
|
|
14591
|
-
(0,
|
|
14671
|
+
(0, import_node_fs41.mkdirSync)((0, import_node_path41.dirname)(snap.cursor), { recursive: true });
|
|
14672
|
+
(0, import_node_fs41.writeFileSync)(snap.cursor, `${nextCursor}
|
|
14592
14673
|
`);
|
|
14593
14674
|
} catch {
|
|
14594
14675
|
}
|
|
@@ -14617,7 +14698,7 @@ async function waitForDetachedJob(cwd, id, opts) {
|
|
|
14617
14698
|
const dir = resolveJobDir(root, jobId);
|
|
14618
14699
|
const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
|
|
14619
14700
|
const sleep = opts?.sleep ?? sleepMs;
|
|
14620
|
-
if (!(0,
|
|
14701
|
+
if (!(0, import_node_fs41.existsSync)(dir)) {
|
|
14621
14702
|
return {
|
|
14622
14703
|
stillRunning: false,
|
|
14623
14704
|
ok: false,
|
|
@@ -14663,10 +14744,10 @@ function killProcessTree(pid, signal) {
|
|
|
14663
14744
|
}
|
|
14664
14745
|
function appendJobLog(logFile, line) {
|
|
14665
14746
|
try {
|
|
14666
|
-
(0,
|
|
14747
|
+
(0, import_node_fs41.mkdirSync)((0, import_node_path41.dirname)(logFile), { recursive: true });
|
|
14667
14748
|
const body = line.endsWith("\n") ? line : `${line}
|
|
14668
14749
|
`;
|
|
14669
|
-
(0,
|
|
14750
|
+
(0, import_node_fs41.appendFileSync)(logFile, body);
|
|
14670
14751
|
} catch {
|
|
14671
14752
|
}
|
|
14672
14753
|
}
|
|
@@ -14676,7 +14757,7 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
14676
14757
|
const dir = resolveJobDir(root, jobId);
|
|
14677
14758
|
const sleep = opts?.sleep ?? sleepMs;
|
|
14678
14759
|
const why = opts?.reason?.trim() ?? "";
|
|
14679
|
-
if (!(0,
|
|
14760
|
+
if (!(0, import_node_fs41.existsSync)(dir)) {
|
|
14680
14761
|
return {
|
|
14681
14762
|
stillRunning: false,
|
|
14682
14763
|
ok: false,
|
|
@@ -14712,10 +14793,10 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
14712
14793
|
killProcessTree(targetPid, "SIGKILL");
|
|
14713
14794
|
await sleep(100);
|
|
14714
14795
|
}
|
|
14715
|
-
const exitFile = (0,
|
|
14716
|
-
if (!(0,
|
|
14796
|
+
const exitFile = (0, import_node_path41.join)(dir, "exit");
|
|
14797
|
+
if (!(0, import_node_fs41.existsSync)(exitFile)) {
|
|
14717
14798
|
try {
|
|
14718
|
-
(0,
|
|
14799
|
+
(0, import_node_fs41.writeFileSync)(exitFile, "1\n");
|
|
14719
14800
|
} catch {
|
|
14720
14801
|
}
|
|
14721
14802
|
}
|
|
@@ -14735,12 +14816,12 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
14735
14816
|
hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
|
|
14736
14817
|
};
|
|
14737
14818
|
}
|
|
14738
|
-
var
|
|
14819
|
+
var import_node_fs41, import_node_path41, 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;
|
|
14739
14820
|
var init_wait_for_job = __esm({
|
|
14740
14821
|
"src/mcp/wait-for-job.ts"() {
|
|
14741
14822
|
"use strict";
|
|
14742
|
-
|
|
14743
|
-
|
|
14823
|
+
import_node_fs41 = require("fs");
|
|
14824
|
+
import_node_path41 = require("path");
|
|
14744
14825
|
init_workspace_scratch();
|
|
14745
14826
|
init_wait_for_turn();
|
|
14746
14827
|
MAX_JOB_CONTINUES = 8;
|
|
@@ -15986,7 +16067,7 @@ function reuseLiveThread(input, repoPath, match) {
|
|
|
15986
16067
|
}
|
|
15987
16068
|
async function createThread(input, _onSetupLine) {
|
|
15988
16069
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
15989
|
-
if (!(0,
|
|
16070
|
+
if (!(0, import_node_fs42.existsSync)(repoPath)) {
|
|
15990
16071
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
15991
16072
|
}
|
|
15992
16073
|
const reused = reuseLiveThread(input, repoPath, {
|
|
@@ -16162,11 +16243,11 @@ async function createThread(input, _onSetupLine) {
|
|
|
16162
16243
|
await ensureWorkspace(repoPath);
|
|
16163
16244
|
return readThread(thread.id) ?? thread;
|
|
16164
16245
|
}
|
|
16165
|
-
var
|
|
16246
|
+
var import_node_fs42;
|
|
16166
16247
|
var init_create = __esm({
|
|
16167
16248
|
"src/threads/create.ts"() {
|
|
16168
16249
|
"use strict";
|
|
16169
|
-
|
|
16250
|
+
import_node_fs42 = require("fs");
|
|
16170
16251
|
init_detect();
|
|
16171
16252
|
init_worktree();
|
|
16172
16253
|
init_home_board();
|
|
@@ -16286,20 +16367,20 @@ function writeTurnLive(threadId, progress) {
|
|
|
16286
16367
|
const path = threadLivePath(threadId);
|
|
16287
16368
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
16288
16369
|
try {
|
|
16289
|
-
(0,
|
|
16290
|
-
(0,
|
|
16370
|
+
(0, import_node_fs43.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
|
|
16371
|
+
(0, import_node_fs43.renameSync)(tmp, path);
|
|
16291
16372
|
} catch {
|
|
16292
16373
|
try {
|
|
16293
|
-
(0,
|
|
16374
|
+
(0, import_node_fs43.unlinkSync)(tmp);
|
|
16294
16375
|
} catch {
|
|
16295
16376
|
}
|
|
16296
16377
|
}
|
|
16297
16378
|
}
|
|
16298
16379
|
function readTurnLive(threadId) {
|
|
16299
16380
|
const path = threadLivePath(threadId);
|
|
16300
|
-
if (!(0,
|
|
16381
|
+
if (!(0, import_node_fs43.existsSync)(path)) return null;
|
|
16301
16382
|
try {
|
|
16302
|
-
const raw = JSON.parse((0,
|
|
16383
|
+
const raw = JSON.parse((0, import_node_fs43.readFileSync)(path, "utf8"));
|
|
16303
16384
|
if (!raw || typeof raw.summary !== "string") return null;
|
|
16304
16385
|
return raw;
|
|
16305
16386
|
} catch {
|
|
@@ -16311,17 +16392,17 @@ function clearTurnLive(threadId) {
|
|
|
16311
16392
|
if (buf?.timer) clearTimeout(buf.timer);
|
|
16312
16393
|
buffers.delete(threadId);
|
|
16313
16394
|
const path = threadLivePath(threadId);
|
|
16314
|
-
if (!(0,
|
|
16395
|
+
if (!(0, import_node_fs43.existsSync)(path)) return;
|
|
16315
16396
|
try {
|
|
16316
|
-
(0,
|
|
16397
|
+
(0, import_node_fs43.unlinkSync)(path);
|
|
16317
16398
|
} catch {
|
|
16318
16399
|
}
|
|
16319
16400
|
}
|
|
16320
|
-
var
|
|
16401
|
+
var import_node_fs43, buffers, FLUSH_MS, MAX_PARTS;
|
|
16321
16402
|
var init_turn_live = __esm({
|
|
16322
16403
|
"src/store/turn-live.ts"() {
|
|
16323
16404
|
"use strict";
|
|
16324
|
-
|
|
16405
|
+
import_node_fs43 = require("fs");
|
|
16325
16406
|
init_message_parts();
|
|
16326
16407
|
init_paths();
|
|
16327
16408
|
buffers = /* @__PURE__ */ new Map();
|
|
@@ -16421,12 +16502,18 @@ var init_fork_worktree = __esm({
|
|
|
16421
16502
|
|
|
16422
16503
|
// src/orchestrator/quota-failover.ts
|
|
16423
16504
|
function planOrchestrationQuotaFailover(thread, limitText, opts) {
|
|
16424
|
-
if (!isOrchestratorThread(thread)) return null;
|
|
16425
16505
|
if (!isSessionQuotaLimit(limitText)) return null;
|
|
16426
|
-
const onLimit = opts?.onLimit ??
|
|
16506
|
+
const onLimit = opts?.onLimit ?? usageOnLimit();
|
|
16427
16507
|
const resumeAt = parseSessionQuotaResetAt(limitText, opts?.now);
|
|
16508
|
+
if (onLimit === "keep_going" || onLimit === "confirm") {
|
|
16509
|
+
return {
|
|
16510
|
+
action: "none",
|
|
16511
|
+
reason: onLimit === "confirm" ? "Settings: confirm with user; no automatic continue." : "Settings: keep going; no automatic continue.",
|
|
16512
|
+
limitText
|
|
16513
|
+
};
|
|
16514
|
+
}
|
|
16428
16515
|
if (thread.quotaContinuedFromId) {
|
|
16429
|
-
if (resumeAt) {
|
|
16516
|
+
if (onLimit === "switch_agent" && resumeAt) {
|
|
16430
16517
|
return {
|
|
16431
16518
|
action: "wait_reset",
|
|
16432
16519
|
reason: "Already continued once; waiting for quota reset instead.",
|
|
@@ -16436,7 +16523,7 @@ function planOrchestrationQuotaFailover(thread, limitText, opts) {
|
|
|
16436
16523
|
}
|
|
16437
16524
|
return {
|
|
16438
16525
|
action: "none",
|
|
16439
|
-
reason: "Already continued once; no
|
|
16526
|
+
reason: "Already continued once; no further automatic continue.",
|
|
16440
16527
|
limitText
|
|
16441
16528
|
};
|
|
16442
16529
|
}
|
|
@@ -16473,8 +16560,19 @@ function buildQuotaHandoffAttachment(from, limitText, fallbackAgent) {
|
|
|
16473
16560
|
const text7 = m.text.trim().replace(/\s+/g, " ").slice(0, 280);
|
|
16474
16561
|
return text7 ? `- ${role}: ${text7}` : null;
|
|
16475
16562
|
}).filter(Boolean);
|
|
16563
|
+
const orch = isOrchestratorThread(from);
|
|
16564
|
+
const instructions = orch ? [
|
|
16565
|
+
"- Continue fleet orchestration from this handoff.",
|
|
16566
|
+
"- Prefer Sideboard MCP (list_board, list_threads, get_thread, send_to_thread, \u2026) for live status.",
|
|
16567
|
+
"- Leave model Auto unless there is a specific reason to pin one.",
|
|
16568
|
+
`- Do not wait on the limited ${from.agent} account; keep going on ${fallbackAgent}.`
|
|
16569
|
+
] : [
|
|
16570
|
+
"- Continue this worktree chat from the handoff.",
|
|
16571
|
+
"- Leave model Auto unless there is a specific reason to pin one.",
|
|
16572
|
+
`- Do not wait on the limited ${from.agent} account; keep going on ${fallbackAgent}.`
|
|
16573
|
+
];
|
|
16476
16574
|
const body = [
|
|
16477
|
-
`# Orchestration handoff`,
|
|
16575
|
+
`# ${orch ? "Orchestration" : "Chat"} handoff`,
|
|
16478
16576
|
"",
|
|
16479
16577
|
`Previous chat: ${from.title} (\`${from.id}\`) on **${from.agent}** hit a session/usage limit.`,
|
|
16480
16578
|
`Limit: ${limitText.trim()}`,
|
|
@@ -16490,14 +16588,11 @@ function buildQuotaHandoffAttachment(from, limitText, fallbackAgent) {
|
|
|
16490
16588
|
recent.length ? recent.join("\n") : "(none)",
|
|
16491
16589
|
"",
|
|
16492
16590
|
`## Instructions`,
|
|
16493
|
-
|
|
16494
|
-
`- Prefer Sideboard MCP (list_board, list_threads, get_thread, send_to_thread, \u2026) for live status.`,
|
|
16495
|
-
`- Leave model Auto unless there is a specific reason to pin one.`,
|
|
16496
|
-
`- Do not wait on the limited ${from.agent} account; keep going on ${fallbackAgent}.`
|
|
16591
|
+
...instructions
|
|
16497
16592
|
].join("\n");
|
|
16498
16593
|
return {
|
|
16499
16594
|
id: (0, import_node_crypto9.randomUUID)(),
|
|
16500
|
-
name: "Orchestration quota handoff.md",
|
|
16595
|
+
name: orch ? "Orchestration quota handoff.md" : "Quota handoff.md",
|
|
16501
16596
|
kind: "transcript",
|
|
16502
16597
|
content: body
|
|
16503
16598
|
};
|
|
@@ -16510,12 +16605,15 @@ function createQuotaFailoverChat(from, fallbackAgent, limitText) {
|
|
|
16510
16605
|
model: null,
|
|
16511
16606
|
attachments: [handoff]
|
|
16512
16607
|
});
|
|
16513
|
-
|
|
16514
|
-
parentThreadId: from.id,
|
|
16608
|
+
const patch = {
|
|
16515
16609
|
quotaContinuedFromId: from.id,
|
|
16516
|
-
sourceRef: from.sourceRef
|
|
16517
|
-
|
|
16518
|
-
|
|
16610
|
+
sourceRef: from.sourceRef
|
|
16611
|
+
};
|
|
16612
|
+
if (isOrchestratorThread(from)) {
|
|
16613
|
+
patch.parentThreadId = from.id;
|
|
16614
|
+
patch.sourceType = "orchestration";
|
|
16615
|
+
}
|
|
16616
|
+
return updateThread(tab.id, patch);
|
|
16519
16617
|
}
|
|
16520
16618
|
var import_node_crypto9, QUOTA_CONTINUE_PROMPT, QUOTA_RESUME_PROMPT;
|
|
16521
16619
|
var init_quota_failover = __esm({
|
|
@@ -16528,17 +16626,17 @@ var init_quota_failover = __esm({
|
|
|
16528
16626
|
init_thread_store();
|
|
16529
16627
|
init_chat_tabs();
|
|
16530
16628
|
QUOTA_CONTINUE_PROMPT = (fromAgent, fallback) => [
|
|
16531
|
-
`${fromAgent} hit a session/usage limit. Continue this
|
|
16532
|
-
"
|
|
16629
|
+
`${fromAgent} hit a session/usage limit. Continue this chat on ${fallback} using the attached handoff.`,
|
|
16630
|
+
"Proceed with the goal. Leave model Auto unless needed."
|
|
16533
16631
|
].join(" ");
|
|
16534
|
-
QUOTA_RESUME_PROMPT = "Session/usage limit window should have reset. Continue
|
|
16632
|
+
QUOTA_RESUME_PROMPT = "Session/usage limit window should have reset. Continue this chat from where you left off.";
|
|
16535
16633
|
}
|
|
16536
16634
|
});
|
|
16537
16635
|
|
|
16538
16636
|
// src/threads/adopt.ts
|
|
16539
16637
|
function thisModuleFile() {
|
|
16540
16638
|
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
16541
|
-
return cjsFile || process.argv[1] || (0,
|
|
16639
|
+
return cjsFile || process.argv[1] || (0, import_node_path42.join)(process.cwd(), "package.json");
|
|
16542
16640
|
}
|
|
16543
16641
|
function openReadonlySqlite(file) {
|
|
16544
16642
|
const req = (0, import_node_module4.createRequire)(thisModuleFile());
|
|
@@ -16556,21 +16654,21 @@ function mapAgentType(raw) {
|
|
|
16556
16654
|
return null;
|
|
16557
16655
|
}
|
|
16558
16656
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
16559
|
-
if (!workspacePath || !(0,
|
|
16657
|
+
if (!workspacePath || !(0, import_node_fs44.existsSync)(CURSOR_SDK_STORE)) return null;
|
|
16560
16658
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
16561
16659
|
let best = null;
|
|
16562
16660
|
let hashes;
|
|
16563
16661
|
try {
|
|
16564
|
-
hashes = (0,
|
|
16662
|
+
hashes = (0, import_node_fs44.readdirSync)(CURSOR_SDK_STORE);
|
|
16565
16663
|
} catch {
|
|
16566
16664
|
return null;
|
|
16567
16665
|
}
|
|
16568
16666
|
for (const hash of hashes) {
|
|
16569
|
-
const agentsFile = (0,
|
|
16570
|
-
if (!(0,
|
|
16667
|
+
const agentsFile = (0, import_node_path42.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
16668
|
+
if (!(0, import_node_fs44.existsSync)(agentsFile)) continue;
|
|
16571
16669
|
let text7;
|
|
16572
16670
|
try {
|
|
16573
|
-
text7 = (0,
|
|
16671
|
+
text7 = (0, import_node_fs44.readFileSync)(agentsFile, "utf8");
|
|
16574
16672
|
} catch {
|
|
16575
16673
|
continue;
|
|
16576
16674
|
}
|
|
@@ -16594,7 +16692,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
16594
16692
|
return best?.agentId ?? null;
|
|
16595
16693
|
}
|
|
16596
16694
|
async function adoptThread(input) {
|
|
16597
|
-
if (!(0,
|
|
16695
|
+
if (!(0, import_node_fs44.existsSync)(input.worktreePath)) {
|
|
16598
16696
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
16599
16697
|
}
|
|
16600
16698
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -16620,18 +16718,18 @@ async function adoptThread(input) {
|
|
|
16620
16718
|
return thread;
|
|
16621
16719
|
}
|
|
16622
16720
|
function listConductorWorkspaces() {
|
|
16623
|
-
if (!(0,
|
|
16721
|
+
if (!(0, import_node_fs44.existsSync)(CONDUCTOR_DB)) {
|
|
16624
16722
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
16625
16723
|
}
|
|
16626
|
-
const tmp = (0,
|
|
16627
|
-
const snapshot = (0,
|
|
16724
|
+
const tmp = (0, import_node_fs44.mkdtempSync)((0, import_node_path42.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
|
|
16725
|
+
const snapshot = (0, import_node_path42.join)(tmp, "conductor.db");
|
|
16628
16726
|
try {
|
|
16629
|
-
(0,
|
|
16727
|
+
(0, import_node_fs44.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
16630
16728
|
for (const suffix of ["-wal", "-shm"]) {
|
|
16631
16729
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
16632
|
-
if ((0,
|
|
16730
|
+
if ((0, import_node_fs44.existsSync)(src)) {
|
|
16633
16731
|
try {
|
|
16634
|
-
(0,
|
|
16732
|
+
(0, import_node_fs44.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
16635
16733
|
} catch {
|
|
16636
16734
|
}
|
|
16637
16735
|
}
|
|
@@ -16707,22 +16805,22 @@ function listConductorWorkspaces() {
|
|
|
16707
16805
|
db.close();
|
|
16708
16806
|
}
|
|
16709
16807
|
} finally {
|
|
16710
|
-
(0,
|
|
16808
|
+
(0, import_node_fs44.rmSync)(tmp, { recursive: true, force: true });
|
|
16711
16809
|
}
|
|
16712
16810
|
}
|
|
16713
16811
|
function importConductorWorkspace(workspaceId) {
|
|
16714
|
-
if (!(0,
|
|
16812
|
+
if (!(0, import_node_fs44.existsSync)(CONDUCTOR_DB)) {
|
|
16715
16813
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
16716
16814
|
}
|
|
16717
|
-
const tmp = (0,
|
|
16718
|
-
const snapshot = (0,
|
|
16815
|
+
const tmp = (0, import_node_fs44.mkdtempSync)((0, import_node_path42.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
|
|
16816
|
+
const snapshot = (0, import_node_path42.join)(tmp, "conductor.db");
|
|
16719
16817
|
try {
|
|
16720
|
-
(0,
|
|
16818
|
+
(0, import_node_fs44.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
16721
16819
|
for (const suffix of ["-wal", "-shm"]) {
|
|
16722
16820
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
16723
|
-
if ((0,
|
|
16821
|
+
if ((0, import_node_fs44.existsSync)(src)) {
|
|
16724
16822
|
try {
|
|
16725
|
-
(0,
|
|
16823
|
+
(0, import_node_fs44.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
16726
16824
|
} catch {
|
|
16727
16825
|
}
|
|
16728
16826
|
}
|
|
@@ -16740,7 +16838,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
16740
16838
|
).get(workspaceId);
|
|
16741
16839
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
16742
16840
|
const worktreePath = String(row.workspacePath);
|
|
16743
|
-
if (!(0,
|
|
16841
|
+
if (!(0, import_node_fs44.existsSync)(worktreePath)) {
|
|
16744
16842
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
16745
16843
|
}
|
|
16746
16844
|
let sessionId = null;
|
|
@@ -16803,31 +16901,31 @@ function importConductorWorkspace(workspaceId) {
|
|
|
16803
16901
|
db.close();
|
|
16804
16902
|
}
|
|
16805
16903
|
} finally {
|
|
16806
|
-
(0,
|
|
16904
|
+
(0, import_node_fs44.rmSync)(tmp, { recursive: true, force: true });
|
|
16807
16905
|
}
|
|
16808
16906
|
}
|
|
16809
16907
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
16810
16908
|
return importConductorWorkspace(workspaceId);
|
|
16811
16909
|
}
|
|
16812
|
-
var import_node_child_process4,
|
|
16910
|
+
var import_node_child_process4, import_node_fs44, import_node_os14, import_node_path42, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
|
|
16813
16911
|
var init_adopt = __esm({
|
|
16814
16912
|
"src/threads/adopt.ts"() {
|
|
16815
16913
|
"use strict";
|
|
16816
16914
|
import_node_child_process4 = require("child_process");
|
|
16817
|
-
|
|
16818
|
-
|
|
16819
|
-
|
|
16915
|
+
import_node_fs44 = require("fs");
|
|
16916
|
+
import_node_os14 = require("os");
|
|
16917
|
+
import_node_path42 = require("path");
|
|
16820
16918
|
import_node_module4 = require("module");
|
|
16821
16919
|
init_worktree();
|
|
16822
16920
|
init_thread_store();
|
|
16823
|
-
CONDUCTOR_APP_SUPPORT = (0,
|
|
16921
|
+
CONDUCTOR_APP_SUPPORT = (0, import_node_path42.join)(
|
|
16824
16922
|
process.env.HOME ?? "",
|
|
16825
16923
|
"Library",
|
|
16826
16924
|
"Application Support",
|
|
16827
16925
|
"com.conductor.app"
|
|
16828
16926
|
);
|
|
16829
|
-
CONDUCTOR_DB = (0,
|
|
16830
|
-
CURSOR_SDK_STORE = (0,
|
|
16927
|
+
CONDUCTOR_DB = (0, import_node_path42.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
16928
|
+
CURSOR_SDK_STORE = (0, import_node_path42.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
16831
16929
|
}
|
|
16832
16930
|
});
|
|
16833
16931
|
|
|
@@ -16894,7 +16992,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
16894
16992
|
let createdWorktree = false;
|
|
16895
16993
|
const trees = await listWorktrees(repoPath);
|
|
16896
16994
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
16897
|
-
if (checkedOut?.path && (0,
|
|
16995
|
+
if (checkedOut?.path && (0, import_node_fs45.existsSync)(checkedOut.path)) {
|
|
16898
16996
|
if (input.reuseExistingWorktree !== false) {
|
|
16899
16997
|
worktreePath = checkedOut.path;
|
|
16900
16998
|
} else {
|
|
@@ -17036,7 +17134,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
17036
17134
|
async function createPrStack(input, onSetupLine) {
|
|
17037
17135
|
await requireAgent(input.agent);
|
|
17038
17136
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
17039
|
-
if (!(0,
|
|
17137
|
+
if (!(0, import_node_fs45.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
17040
17138
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
17041
17139
|
const status = await detectGhStack(repoPath);
|
|
17042
17140
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -17103,7 +17201,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
17103
17201
|
}
|
|
17104
17202
|
}
|
|
17105
17203
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
17106
|
-
if (!claimed.has(bootstrap.worktreePath) && (0,
|
|
17204
|
+
if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs45.existsSync)(bootstrap.worktreePath)) {
|
|
17107
17205
|
try {
|
|
17108
17206
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
17109
17207
|
deleteBranch: bootstrap.branchName
|
|
@@ -17113,11 +17211,11 @@ async function createPrStack(input, onSetupLine) {
|
|
|
17113
17211
|
}
|
|
17114
17212
|
return { stack, threads, createdThreadIds };
|
|
17115
17213
|
}
|
|
17116
|
-
var
|
|
17214
|
+
var import_node_fs45;
|
|
17117
17215
|
var init_stack_layers = __esm({
|
|
17118
17216
|
"src/threads/stack-layers.ts"() {
|
|
17119
17217
|
"use strict";
|
|
17120
|
-
|
|
17218
|
+
import_node_fs45 = require("fs");
|
|
17121
17219
|
init_detect();
|
|
17122
17220
|
init_run();
|
|
17123
17221
|
init_stack();
|
|
@@ -17130,7 +17228,7 @@ var init_stack_layers = __esm({
|
|
|
17130
17228
|
|
|
17131
17229
|
// src/diff/diff.ts
|
|
17132
17230
|
async function inspectGitWorktree(worktreePath) {
|
|
17133
|
-
if (!worktreePath || !(0,
|
|
17231
|
+
if (!worktreePath || !(0, import_node_fs46.existsSync)(worktreePath)) return "missing_worktree";
|
|
17134
17232
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
17135
17233
|
reject: false
|
|
17136
17234
|
});
|
|
@@ -17138,7 +17236,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
17138
17236
|
return "ok";
|
|
17139
17237
|
}
|
|
17140
17238
|
async function initializeGitRepository(worktreePath) {
|
|
17141
|
-
if (!worktreePath || !(0,
|
|
17239
|
+
if (!worktreePath || !(0, import_node_fs46.existsSync)(worktreePath)) {
|
|
17142
17240
|
throw new Error("Worktree not found");
|
|
17143
17241
|
}
|
|
17144
17242
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -17272,11 +17370,11 @@ new file mode 100644
|
|
|
17272
17370
|
};
|
|
17273
17371
|
}
|
|
17274
17372
|
async function untrackedPatch(worktreePath, path, maxHunk) {
|
|
17275
|
-
const abs = (0,
|
|
17373
|
+
const abs = (0, import_node_path43.join)(worktreePath, path);
|
|
17276
17374
|
try {
|
|
17277
|
-
const st = (0,
|
|
17375
|
+
const st = (0, import_node_fs46.statSync)(abs);
|
|
17278
17376
|
if (st.isFile() && st.size > maxHunk) {
|
|
17279
|
-
const buf = (0,
|
|
17377
|
+
const buf = (0, import_node_fs46.readFileSync)(abs).subarray(0, maxHunk);
|
|
17280
17378
|
return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
|
|
17281
17379
|
}
|
|
17282
17380
|
} catch {
|
|
@@ -17765,8 +17863,8 @@ function isImageRelativePath(relativePath) {
|
|
|
17765
17863
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
17766
17864
|
assertSafeRelativePath(relativePath);
|
|
17767
17865
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
17768
|
-
const abs = (0,
|
|
17769
|
-
const st = (0,
|
|
17866
|
+
const abs = (0, import_node_path43.join)(worktreePath, relativePath);
|
|
17867
|
+
const st = (0, import_node_fs46.statSync)(abs);
|
|
17770
17868
|
if (!st.isFile()) {
|
|
17771
17869
|
throw new Error(`Not a file: ${relativePath}`);
|
|
17772
17870
|
}
|
|
@@ -17775,7 +17873,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
17775
17873
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
17776
17874
|
);
|
|
17777
17875
|
}
|
|
17778
|
-
const buf = (0,
|
|
17876
|
+
const buf = (0, import_node_fs46.readFileSync)(abs);
|
|
17779
17877
|
return {
|
|
17780
17878
|
path: relativePath,
|
|
17781
17879
|
contentBase64: buf.toString("base64"),
|
|
@@ -17785,12 +17883,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
17785
17883
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
17786
17884
|
assertSafeRelativePath(relativePath);
|
|
17787
17885
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
17788
|
-
const abs = (0,
|
|
17789
|
-
const st = (0,
|
|
17886
|
+
const abs = (0, import_node_path43.join)(worktreePath, relativePath);
|
|
17887
|
+
const st = (0, import_node_fs46.statSync)(abs);
|
|
17790
17888
|
if (!st.isFile()) {
|
|
17791
17889
|
throw new Error(`Not a file: ${relativePath}`);
|
|
17792
17890
|
}
|
|
17793
|
-
const buf = (0,
|
|
17891
|
+
const buf = (0, import_node_fs46.readFileSync)(abs);
|
|
17794
17892
|
if (isImageRelativePath(relativePath)) {
|
|
17795
17893
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
17796
17894
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -17833,9 +17931,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
17833
17931
|
}
|
|
17834
17932
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
17835
17933
|
assertSafeRelativePath(relativePath);
|
|
17836
|
-
const abs = (0,
|
|
17837
|
-
(0,
|
|
17838
|
-
(0,
|
|
17934
|
+
const abs = (0, import_node_path43.join)(worktreePath, relativePath);
|
|
17935
|
+
(0, import_node_fs46.mkdirSync)((0, import_node_path43.dirname)(abs), { recursive: true });
|
|
17936
|
+
(0, import_node_fs46.writeFileSync)(abs, content, "utf8");
|
|
17839
17937
|
return { path: relativePath };
|
|
17840
17938
|
}
|
|
17841
17939
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -17852,12 +17950,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
|
17852
17950
|
truncated: full.files.length > maxFiles
|
|
17853
17951
|
};
|
|
17854
17952
|
}
|
|
17855
|
-
var
|
|
17953
|
+
var import_node_fs46, import_node_path43, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
|
|
17856
17954
|
var init_diff = __esm({
|
|
17857
17955
|
"src/diff/diff.ts"() {
|
|
17858
17956
|
"use strict";
|
|
17859
|
-
|
|
17860
|
-
|
|
17957
|
+
import_node_fs46 = require("fs");
|
|
17958
|
+
import_node_path43 = require("path");
|
|
17861
17959
|
init_run();
|
|
17862
17960
|
init_worktree();
|
|
17863
17961
|
mergeBaseCache = /* @__PURE__ */ new Map();
|
|
@@ -18214,7 +18312,7 @@ function parseFrontmatter(content) {
|
|
|
18214
18312
|
}
|
|
18215
18313
|
function readSkill(skillMd, source) {
|
|
18216
18314
|
try {
|
|
18217
|
-
const content = (0,
|
|
18315
|
+
const content = (0, import_node_fs47.readFileSync)(skillMd, "utf8");
|
|
18218
18316
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
18219
18317
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
18220
18318
|
const name = fmName || dirName;
|
|
@@ -18233,19 +18331,19 @@ function readSkill(skillMd, source) {
|
|
|
18233
18331
|
}
|
|
18234
18332
|
}
|
|
18235
18333
|
function scanSkillsDir(dir, source, out) {
|
|
18236
|
-
if (!(0,
|
|
18334
|
+
if (!(0, import_node_fs47.existsSync)(dir)) return;
|
|
18237
18335
|
let entries;
|
|
18238
18336
|
try {
|
|
18239
|
-
entries = (0,
|
|
18337
|
+
entries = (0, import_node_fs47.readdirSync)(dir);
|
|
18240
18338
|
} catch {
|
|
18241
18339
|
return;
|
|
18242
18340
|
}
|
|
18243
18341
|
for (const entry of entries) {
|
|
18244
18342
|
if (entry.startsWith(".")) continue;
|
|
18245
|
-
const skillMd = (0,
|
|
18246
|
-
if (!(0,
|
|
18343
|
+
const skillMd = (0, import_node_path44.join)(dir, entry, "SKILL.md");
|
|
18344
|
+
if (!(0, import_node_fs47.existsSync)(skillMd)) continue;
|
|
18247
18345
|
try {
|
|
18248
|
-
if (!(0,
|
|
18346
|
+
if (!(0, import_node_fs47.statSync)(skillMd).isFile()) continue;
|
|
18249
18347
|
} catch {
|
|
18250
18348
|
continue;
|
|
18251
18349
|
}
|
|
@@ -18254,24 +18352,24 @@ function scanSkillsDir(dir, source, out) {
|
|
|
18254
18352
|
}
|
|
18255
18353
|
}
|
|
18256
18354
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
18257
|
-
if (!(0,
|
|
18355
|
+
if (!(0, import_node_fs47.existsSync)(pluginsRoot)) return;
|
|
18258
18356
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
18259
18357
|
if (depth > 7) return;
|
|
18260
18358
|
let entries;
|
|
18261
18359
|
try {
|
|
18262
|
-
entries = (0,
|
|
18360
|
+
entries = (0, import_node_fs47.readdirSync)(dir);
|
|
18263
18361
|
} catch {
|
|
18264
18362
|
return;
|
|
18265
18363
|
}
|
|
18266
18364
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
18267
|
-
const skill = readSkill((0,
|
|
18365
|
+
const skill = readSkill((0, import_node_path44.join)(dir, "SKILL.md"), "cli");
|
|
18268
18366
|
if (skill) out.push(skill);
|
|
18269
18367
|
}
|
|
18270
18368
|
for (const entry of entries) {
|
|
18271
18369
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
18272
|
-
const full = (0,
|
|
18370
|
+
const full = (0, import_node_path44.join)(dir, entry);
|
|
18273
18371
|
try {
|
|
18274
|
-
if (!(0,
|
|
18372
|
+
if (!(0, import_node_fs47.statSync)(full).isDirectory()) continue;
|
|
18275
18373
|
} catch {
|
|
18276
18374
|
continue;
|
|
18277
18375
|
}
|
|
@@ -18286,20 +18384,20 @@ function scanClaudePluginSkills(pluginsRoot, out) {
|
|
|
18286
18384
|
walk(pluginsRoot, 0, false);
|
|
18287
18385
|
}
|
|
18288
18386
|
function discoverSkills(worktreePath) {
|
|
18289
|
-
const home = (0,
|
|
18387
|
+
const home = (0, import_node_os15.homedir)();
|
|
18290
18388
|
const collected = [];
|
|
18291
18389
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
18292
|
-
scanSkillsDir((0,
|
|
18390
|
+
scanSkillsDir((0, import_node_path44.join)(worktreePath, rel), "workspace", collected);
|
|
18293
18391
|
}
|
|
18294
18392
|
for (const abs of [
|
|
18295
|
-
(0,
|
|
18296
|
-
(0,
|
|
18297
|
-
(0,
|
|
18298
|
-
(0,
|
|
18393
|
+
(0, import_node_path44.join)(home, ".claude/skills"),
|
|
18394
|
+
(0, import_node_path44.join)(home, ".cursor/skills"),
|
|
18395
|
+
(0, import_node_path44.join)(home, ".sideboard/skills"),
|
|
18396
|
+
(0, import_node_path44.join)(home, ".brightsy/skills")
|
|
18299
18397
|
]) {
|
|
18300
18398
|
scanSkillsDir(abs, "user", collected);
|
|
18301
18399
|
}
|
|
18302
|
-
scanClaudePluginSkills((0,
|
|
18400
|
+
scanClaudePluginSkills((0, import_node_path44.join)(home, ".claude/plugins"), collected);
|
|
18303
18401
|
collected.push(...bundledSkills());
|
|
18304
18402
|
const rank = {
|
|
18305
18403
|
workspace: 0,
|
|
@@ -18325,7 +18423,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
18325
18423
|
\u2026(truncated)` : body;
|
|
18326
18424
|
}
|
|
18327
18425
|
}
|
|
18328
|
-
const raw = (0,
|
|
18426
|
+
const raw = (0, import_node_fs47.readFileSync)(skillPath, "utf8");
|
|
18329
18427
|
if (raw.startsWith("---")) {
|
|
18330
18428
|
const end = raw.indexOf("\n---", 3);
|
|
18331
18429
|
if (end >= 0) {
|
|
@@ -18339,13 +18437,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
18339
18437
|
|
|
18340
18438
|
\u2026(truncated)` : raw;
|
|
18341
18439
|
}
|
|
18342
|
-
var
|
|
18440
|
+
var import_node_fs47, import_node_os15, import_node_path44, BUNDLED_SKILL_PREFIX;
|
|
18343
18441
|
var init_discover = __esm({
|
|
18344
18442
|
"src/skills/discover.ts"() {
|
|
18345
18443
|
"use strict";
|
|
18346
|
-
|
|
18347
|
-
|
|
18348
|
-
|
|
18444
|
+
import_node_fs47 = require("fs");
|
|
18445
|
+
import_node_os15 = require("os");
|
|
18446
|
+
import_node_path44 = require("path");
|
|
18349
18447
|
init_long_running();
|
|
18350
18448
|
BUNDLED_SKILL_PREFIX = "bundled:";
|
|
18351
18449
|
}
|
|
@@ -18439,8 +18537,8 @@ var init_expand = __esm({
|
|
|
18439
18537
|
// src/skills/detached-job-path.ts
|
|
18440
18538
|
function detachedJobScriptIn(dir) {
|
|
18441
18539
|
for (const name of DETACHED_JOB_FILENAMES) {
|
|
18442
|
-
const script = (0,
|
|
18443
|
-
if ((0,
|
|
18540
|
+
const script = (0, import_node_path45.join)(dir, "scripts", name);
|
|
18541
|
+
if ((0, import_node_fs48.existsSync)(script)) return script;
|
|
18444
18542
|
}
|
|
18445
18543
|
return null;
|
|
18446
18544
|
}
|
|
@@ -18452,11 +18550,11 @@ function packagedDetachedJobPath() {
|
|
|
18452
18550
|
function resolveDetachedJobScript() {
|
|
18453
18551
|
const packaged = packagedDetachedJobPath();
|
|
18454
18552
|
if (packaged) return packaged;
|
|
18455
|
-
let dir = (0,
|
|
18553
|
+
let dir = (0, import_node_path45.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
|
|
18456
18554
|
for (let i = 0; i < 8; i++) {
|
|
18457
18555
|
const candidate = detachedJobScriptIn(dir);
|
|
18458
18556
|
if (candidate) return candidate;
|
|
18459
|
-
const parent = (0,
|
|
18557
|
+
const parent = (0, import_node_path45.dirname)(dir);
|
|
18460
18558
|
if (parent === dir) break;
|
|
18461
18559
|
dir = parent;
|
|
18462
18560
|
}
|
|
@@ -18467,12 +18565,12 @@ function formatDetachedJobInvoke(scriptPath) {
|
|
|
18467
18565
|
if (resolved) return `node ${JSON.stringify(resolved)}`;
|
|
18468
18566
|
return "node scripts/detached-job.cjs";
|
|
18469
18567
|
}
|
|
18470
|
-
var
|
|
18568
|
+
var import_node_fs48, import_node_path45, import_node_url3, import_meta3, DETACHED_JOB_FILENAMES;
|
|
18471
18569
|
var init_detached_job_path = __esm({
|
|
18472
18570
|
"src/skills/detached-job-path.ts"() {
|
|
18473
18571
|
"use strict";
|
|
18474
|
-
|
|
18475
|
-
|
|
18572
|
+
import_node_fs48 = require("fs");
|
|
18573
|
+
import_node_path45 = require("path");
|
|
18476
18574
|
import_node_url3 = require("url");
|
|
18477
18575
|
init_packaged_runtime();
|
|
18478
18576
|
import_meta3 = {};
|
|
@@ -18632,9 +18730,9 @@ function formatPrGateDirective() {
|
|
|
18632
18730
|
}
|
|
18633
18731
|
function formatProcessGuideDirective(opts) {
|
|
18634
18732
|
const worktree = opts?.worktreePath?.trim();
|
|
18635
|
-
const hasGraphSkill = !!worktree && (0,
|
|
18636
|
-
const hasReviewSkill = !!worktree && (0,
|
|
18637
|
-
const hasInstallSkill = !!worktree && (0,
|
|
18733
|
+
const hasGraphSkill = !!worktree && (0, import_node_fs49.existsSync)((0, import_node_path46.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
|
|
18734
|
+
const hasReviewSkill = !!worktree && (0, import_node_fs49.existsSync)((0, import_node_path46.join)(worktree, ".claude/skills/review/SKILL.md"));
|
|
18735
|
+
const hasInstallSkill = !!worktree && (0, import_node_fs49.existsSync)((0, import_node_path46.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
|
|
18638
18736
|
return [
|
|
18639
18737
|
"Process guides (recurring work only):",
|
|
18640
18738
|
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,
|
|
@@ -18672,12 +18770,12 @@ function formatArtifactDirective() {
|
|
|
18672
18770
|
function formatUiReminder() {
|
|
18673
18771
|
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.";
|
|
18674
18772
|
}
|
|
18675
|
-
var
|
|
18773
|
+
var import_node_fs49, import_node_path46, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
|
|
18676
18774
|
var init_instructions = __esm({
|
|
18677
18775
|
"src/agents/instructions.ts"() {
|
|
18678
18776
|
"use strict";
|
|
18679
|
-
|
|
18680
|
-
|
|
18777
|
+
import_node_fs49 = require("fs");
|
|
18778
|
+
import_node_path46 = require("path");
|
|
18681
18779
|
init_git_auth_mode();
|
|
18682
18780
|
init_branch_prefix();
|
|
18683
18781
|
init_worktree_labels();
|
|
@@ -18901,40 +18999,40 @@ __export(plan_file_exports, {
|
|
|
18901
18999
|
writePlanFile: () => writePlanFile
|
|
18902
19000
|
});
|
|
18903
19001
|
function ensureAttachmentsGitignore(worktreePath) {
|
|
18904
|
-
const gitignoreAbs = (0,
|
|
18905
|
-
if ((0,
|
|
18906
|
-
(0,
|
|
18907
|
-
(0,
|
|
19002
|
+
const gitignoreAbs = (0, import_node_path47.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
19003
|
+
if ((0, import_node_fs50.existsSync)(gitignoreAbs)) return;
|
|
19004
|
+
(0, import_node_fs50.mkdirSync)((0, import_node_path47.dirname)(gitignoreAbs), { recursive: true });
|
|
19005
|
+
(0, import_node_fs50.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
18908
19006
|
}
|
|
18909
19007
|
function planFileAbs(worktreePath) {
|
|
18910
|
-
return (0,
|
|
19008
|
+
return (0, import_node_path47.join)(worktreePath, PLAN_FILE_REL);
|
|
18911
19009
|
}
|
|
18912
19010
|
function readTextIfPresent2(abs) {
|
|
18913
|
-
if (!(0,
|
|
19011
|
+
if (!(0, import_node_fs50.existsSync)(abs)) return null;
|
|
18914
19012
|
try {
|
|
18915
|
-
const content = (0,
|
|
19013
|
+
const content = (0, import_node_fs50.readFileSync)(abs, "utf8");
|
|
18916
19014
|
return content.trim() ? content : null;
|
|
18917
19015
|
} catch {
|
|
18918
19016
|
return null;
|
|
18919
19017
|
}
|
|
18920
19018
|
}
|
|
18921
19019
|
function readPlanFile(worktreePath) {
|
|
18922
|
-
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0,
|
|
19020
|
+
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path47.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path47.join)(worktreePath, LEGACY_PLAN_FILE_REL));
|
|
18923
19021
|
}
|
|
18924
19022
|
function writePlanFile(worktreePath, content) {
|
|
18925
19023
|
ensureAttachmentsGitignore(worktreePath);
|
|
18926
19024
|
const abs = planFileAbs(worktreePath);
|
|
18927
|
-
(0,
|
|
19025
|
+
(0, import_node_fs50.mkdirSync)((0, import_node_path47.dirname)(abs), { recursive: true });
|
|
18928
19026
|
const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
|
|
18929
|
-
(0,
|
|
19027
|
+
(0, import_node_fs50.writeFileSync)(abs, body, "utf8");
|
|
18930
19028
|
return PLAN_FILE_REL;
|
|
18931
19029
|
}
|
|
18932
|
-
var
|
|
19030
|
+
var import_node_fs50, import_node_path47;
|
|
18933
19031
|
var init_plan_file = __esm({
|
|
18934
19032
|
"src/plan/plan-file.ts"() {
|
|
18935
19033
|
"use strict";
|
|
18936
|
-
|
|
18937
|
-
|
|
19034
|
+
import_node_fs50 = require("fs");
|
|
19035
|
+
import_node_path47 = require("path");
|
|
18938
19036
|
init_workspace_scratch();
|
|
18939
19037
|
init_plan_present();
|
|
18940
19038
|
init_plan_present();
|
|
@@ -18994,7 +19092,7 @@ function setCaffeinateHoldHooks(next) {
|
|
|
18994
19092
|
hooks = next;
|
|
18995
19093
|
}
|
|
18996
19094
|
function caffeinateHoldPath() {
|
|
18997
|
-
return (0,
|
|
19095
|
+
return (0, import_node_path48.join)(appDataDir(), "caffeinate-hold.json");
|
|
18998
19096
|
}
|
|
18999
19097
|
function processAlive(pid) {
|
|
19000
19098
|
if (hooks.processAlive) return hooks.processAlive(pid);
|
|
@@ -19028,9 +19126,9 @@ function uniqueIds(ids) {
|
|
|
19028
19126
|
}
|
|
19029
19127
|
function readHold() {
|
|
19030
19128
|
const path = caffeinateHoldPath();
|
|
19031
|
-
if (!(0,
|
|
19129
|
+
if (!(0, import_node_fs51.existsSync)(path)) return null;
|
|
19032
19130
|
try {
|
|
19033
|
-
const parsed = JSON.parse((0,
|
|
19131
|
+
const parsed = JSON.parse((0, import_node_fs51.readFileSync)(path, "utf8"));
|
|
19034
19132
|
if (typeof parsed?.pid === "number" && parsed.pid > 0) {
|
|
19035
19133
|
return {
|
|
19036
19134
|
pid: parsed.pid,
|
|
@@ -19052,7 +19150,7 @@ function writeHold(pid, threadIds) {
|
|
|
19052
19150
|
}
|
|
19053
19151
|
function clearHold() {
|
|
19054
19152
|
try {
|
|
19055
|
-
(0,
|
|
19153
|
+
(0, import_node_fs51.unlinkSync)(caffeinateHoldPath());
|
|
19056
19154
|
} catch {
|
|
19057
19155
|
}
|
|
19058
19156
|
}
|
|
@@ -19137,13 +19235,13 @@ function releaseCaffeinateHoldForThread(threadId) {
|
|
|
19137
19235
|
}
|
|
19138
19236
|
return setCaffeinateHold(false, { threadId: id });
|
|
19139
19237
|
}
|
|
19140
|
-
var import_node_child_process5,
|
|
19238
|
+
var import_node_child_process5, import_node_fs51, import_node_path48, hooks;
|
|
19141
19239
|
var init_caffeinate_hold = __esm({
|
|
19142
19240
|
"src/store/caffeinate-hold.ts"() {
|
|
19143
19241
|
"use strict";
|
|
19144
19242
|
import_node_child_process5 = require("child_process");
|
|
19145
|
-
|
|
19146
|
-
|
|
19243
|
+
import_node_fs51 = require("fs");
|
|
19244
|
+
import_node_path48 = require("path");
|
|
19147
19245
|
init_paths();
|
|
19148
19246
|
init_private_file();
|
|
19149
19247
|
hooks = {};
|
|
@@ -19152,7 +19250,7 @@ var init_caffeinate_hold = __esm({
|
|
|
19152
19250
|
|
|
19153
19251
|
// src/store/schedules.ts
|
|
19154
19252
|
function schedulesPath() {
|
|
19155
|
-
return (0,
|
|
19253
|
+
return (0, import_node_path49.join)(appDataDir(), "schedules.json");
|
|
19156
19254
|
}
|
|
19157
19255
|
function parseDurationMs(every) {
|
|
19158
19256
|
const m = every.trim().match(DURATION_RE);
|
|
@@ -19252,9 +19350,9 @@ function normalizeTask(raw) {
|
|
|
19252
19350
|
}
|
|
19253
19351
|
function readAll2() {
|
|
19254
19352
|
const path = schedulesPath();
|
|
19255
|
-
if (!(0,
|
|
19353
|
+
if (!(0, import_node_fs52.existsSync)(path)) return [];
|
|
19256
19354
|
try {
|
|
19257
|
-
const parsed = JSON.parse((0,
|
|
19355
|
+
const parsed = JSON.parse((0, import_node_fs52.readFileSync)(path, "utf8"));
|
|
19258
19356
|
if (!Array.isArray(parsed)) return [];
|
|
19259
19357
|
return parsed.map((row) => {
|
|
19260
19358
|
try {
|
|
@@ -19366,13 +19464,13 @@ function recordScheduleRun(id, result) {
|
|
|
19366
19464
|
writeAll2(rows);
|
|
19367
19465
|
return next;
|
|
19368
19466
|
}
|
|
19369
|
-
var import_node_crypto10,
|
|
19467
|
+
var import_node_crypto10, import_node_fs52, import_node_path49, import_croner, DURATION_RE, UNIT_MS;
|
|
19370
19468
|
var init_schedules = __esm({
|
|
19371
19469
|
"src/store/schedules.ts"() {
|
|
19372
19470
|
"use strict";
|
|
19373
19471
|
import_node_crypto10 = require("crypto");
|
|
19374
|
-
|
|
19375
|
-
|
|
19472
|
+
import_node_fs52 = require("fs");
|
|
19473
|
+
import_node_path49 = require("path");
|
|
19376
19474
|
import_croner = require("croner");
|
|
19377
19475
|
init_orchestrator_capable();
|
|
19378
19476
|
init_paths();
|
|
@@ -19514,13 +19612,13 @@ var init_schedule_runner = __esm({
|
|
|
19514
19612
|
|
|
19515
19613
|
// src/agents/cursor-store.ts
|
|
19516
19614
|
function cursorSdkStoreDir(threadId) {
|
|
19517
|
-
const root = (0,
|
|
19615
|
+
const root = (0, import_node_path50.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
|
|
19518
19616
|
const id = sanitizeCursorStoreSegment(threadId);
|
|
19519
19617
|
if (!id) return root;
|
|
19520
|
-
return (0,
|
|
19618
|
+
return (0, import_node_path50.join)(root, "threads", id);
|
|
19521
19619
|
}
|
|
19522
19620
|
function cursorSdkRunsNdjsonPath(threadId) {
|
|
19523
|
-
return (0,
|
|
19621
|
+
return (0, import_node_path50.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
|
|
19524
19622
|
}
|
|
19525
19623
|
function cursorSdkRunsNdjsonSearchPaths(threadId) {
|
|
19526
19624
|
const scoped = cursorSdkRunsNdjsonPath(threadId);
|
|
@@ -19533,11 +19631,11 @@ function cursorSdkRunsNdjsonSearchPaths(threadId) {
|
|
|
19533
19631
|
function sanitizeCursorStoreSegment(threadId) {
|
|
19534
19632
|
return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
19535
19633
|
}
|
|
19536
|
-
var
|
|
19634
|
+
var import_node_path50, CURSOR_SDK_STORE_DIR;
|
|
19537
19635
|
var init_cursor_store = __esm({
|
|
19538
19636
|
"src/agents/cursor-store.ts"() {
|
|
19539
19637
|
"use strict";
|
|
19540
|
-
|
|
19638
|
+
import_node_path50 = require("path");
|
|
19541
19639
|
init_paths();
|
|
19542
19640
|
CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
|
|
19543
19641
|
}
|
|
@@ -19559,9 +19657,9 @@ function recoverFinishedCursorRun(opts) {
|
|
|
19559
19657
|
return best;
|
|
19560
19658
|
}
|
|
19561
19659
|
function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
|
|
19562
|
-
if (!(0,
|
|
19660
|
+
if (!(0, import_node_fs53.existsSync)(runsPath)) return null;
|
|
19563
19661
|
try {
|
|
19564
|
-
const lines = (0,
|
|
19662
|
+
const lines = (0, import_node_fs53.readFileSync)(runsPath, "utf8").split("\n");
|
|
19565
19663
|
let best = null;
|
|
19566
19664
|
for (const line of lines) {
|
|
19567
19665
|
const trimmed = line.trim();
|
|
@@ -19587,11 +19685,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
|
|
|
19587
19685
|
return null;
|
|
19588
19686
|
}
|
|
19589
19687
|
}
|
|
19590
|
-
var
|
|
19688
|
+
var import_node_fs53;
|
|
19591
19689
|
var init_cursor_recover = __esm({
|
|
19592
19690
|
"src/agents/cursor-recover.ts"() {
|
|
19593
19691
|
"use strict";
|
|
19594
|
-
|
|
19692
|
+
import_node_fs53 = require("fs");
|
|
19595
19693
|
init_cursor_store();
|
|
19596
19694
|
}
|
|
19597
19695
|
});
|
|
@@ -19738,13 +19836,13 @@ async function startOrchestration(opts) {
|
|
|
19738
19836
|
}
|
|
19739
19837
|
return updated;
|
|
19740
19838
|
}
|
|
19741
|
-
var import_node_events,
|
|
19839
|
+
var import_node_events, import_node_fs54, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
|
|
19742
19840
|
var init_orchestrator = __esm({
|
|
19743
19841
|
"src/orchestrator/orchestrator.ts"() {
|
|
19744
19842
|
"use strict";
|
|
19745
19843
|
import_node_events = require("events");
|
|
19746
19844
|
init_outbound_watch();
|
|
19747
|
-
|
|
19845
|
+
import_node_fs54 = require("fs");
|
|
19748
19846
|
init_error_detail();
|
|
19749
19847
|
init_run();
|
|
19750
19848
|
init_stale_lock();
|
|
@@ -19918,7 +20016,7 @@ var init_orchestrator = __esm({
|
|
|
19918
20016
|
}
|
|
19919
20017
|
continue;
|
|
19920
20018
|
}
|
|
19921
|
-
if (!(0,
|
|
20019
|
+
if (!(0, import_node_fs54.existsSync)(thread.worktreePath)) {
|
|
19922
20020
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
19923
20021
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
19924
20022
|
continue;
|
|
@@ -20048,8 +20146,8 @@ var init_orchestrator = __esm({
|
|
|
20048
20146
|
await this.send(threadId, QUOTA_RESUME_PROMPT);
|
|
20049
20147
|
}
|
|
20050
20148
|
/**
|
|
20051
|
-
* Host-side continue when
|
|
20052
|
-
*
|
|
20149
|
+
* Host-side continue when any chat hits a provider session/usage limit
|
|
20150
|
+
* (not context size): switch agent (Auto) or wait until reset.
|
|
20053
20151
|
*/
|
|
20054
20152
|
async maybeHandleOrchestrationQuotaFailover(threadId, limitText) {
|
|
20055
20153
|
const thread = findThreadByRef(threadId);
|
|
@@ -20062,7 +20160,7 @@ var init_orchestrator = __esm({
|
|
|
20062
20160
|
setStatus(threadId, "idle", null);
|
|
20063
20161
|
appendMessage(threadId, {
|
|
20064
20162
|
role: "agent",
|
|
20065
|
-
text: `Sideboard will auto-retry this
|
|
20163
|
+
text: `Sideboard will auto-retry this chat around ${plan.resumeAt.toLocaleString()} when the session limit resets.`,
|
|
20066
20164
|
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
20067
20165
|
});
|
|
20068
20166
|
this.emit({
|
|
@@ -21865,7 +21963,7 @@ var init_orchestrator = __esm({
|
|
|
21865
21963
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
21866
21964
|
return restored2;
|
|
21867
21965
|
}
|
|
21868
|
-
if (!(0,
|
|
21966
|
+
if (!(0, import_node_fs54.existsSync)(thread.worktreePath)) {
|
|
21869
21967
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
21870
21968
|
throw new Error(
|
|
21871
21969
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
@@ -21949,7 +22047,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
|
21949
22047
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
21950
22048
|
var import_zod9 = require("zod");
|
|
21951
22049
|
var import_node_crypto13 = require("crypto");
|
|
21952
|
-
var
|
|
22050
|
+
var import_node_path53 = require("path");
|
|
21953
22051
|
init_orchestrator();
|
|
21954
22052
|
init_worktree();
|
|
21955
22053
|
|
|
@@ -25352,27 +25450,27 @@ init_gh_errors();
|
|
|
25352
25450
|
init_git_auth_mode();
|
|
25353
25451
|
|
|
25354
25452
|
// src/board/load-home-board.ts
|
|
25355
|
-
var
|
|
25356
|
-
var
|
|
25453
|
+
var import_node_fs56 = require("fs");
|
|
25454
|
+
var import_node_path52 = require("path");
|
|
25357
25455
|
init_worktree();
|
|
25358
25456
|
init_paths();
|
|
25359
25457
|
|
|
25360
25458
|
// src/board/board-pins.ts
|
|
25361
25459
|
var import_node_crypto12 = require("crypto");
|
|
25362
|
-
var
|
|
25363
|
-
var
|
|
25460
|
+
var import_node_fs55 = require("fs");
|
|
25461
|
+
var import_node_path51 = require("path");
|
|
25364
25462
|
init_paths();
|
|
25365
25463
|
init_home_board();
|
|
25366
25464
|
var FILE = "home-board-pins.json";
|
|
25367
25465
|
var VERSION = 1;
|
|
25368
25466
|
function pinsFile() {
|
|
25369
|
-
return (0,
|
|
25467
|
+
return (0, import_node_path51.join)(appDataDir(), FILE);
|
|
25370
25468
|
}
|
|
25371
25469
|
function readDisk() {
|
|
25372
25470
|
const path = pinsFile();
|
|
25373
|
-
if (!(0,
|
|
25471
|
+
if (!(0, import_node_fs55.existsSync)(path)) return [];
|
|
25374
25472
|
try {
|
|
25375
|
-
const raw = JSON.parse((0,
|
|
25473
|
+
const raw = JSON.parse((0, import_node_fs55.readFileSync)(path, "utf8"));
|
|
25376
25474
|
if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
|
|
25377
25475
|
return raw.items.filter((item) => item?.id && item.kind && item.ref);
|
|
25378
25476
|
} catch {
|
|
@@ -25380,8 +25478,8 @@ function readDisk() {
|
|
|
25380
25478
|
}
|
|
25381
25479
|
}
|
|
25382
25480
|
function writeDisk(items) {
|
|
25383
|
-
(0,
|
|
25384
|
-
(0,
|
|
25481
|
+
(0, import_node_fs55.mkdirSync)(appDataDir(), { recursive: true });
|
|
25482
|
+
(0, import_node_fs55.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
|
|
25385
25483
|
}
|
|
25386
25484
|
function listBoardPins() {
|
|
25387
25485
|
return readDisk();
|
|
@@ -25402,7 +25500,7 @@ function homeBoardWorkspaceKey(workspaces) {
|
|
|
25402
25500
|
return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
|
|
25403
25501
|
}
|
|
25404
25502
|
function cacheFile() {
|
|
25405
|
-
return (0,
|
|
25503
|
+
return (0, import_node_path52.join)(appDataDir(), "home-board-cache.json");
|
|
25406
25504
|
}
|
|
25407
25505
|
function emptyInputs() {
|
|
25408
25506
|
return {
|
|
@@ -25428,9 +25526,9 @@ function shouldCacheHomeBoardInputs(inputs) {
|
|
|
25428
25526
|
}
|
|
25429
25527
|
function readDiskCache() {
|
|
25430
25528
|
const path = cacheFile();
|
|
25431
|
-
if (!(0,
|
|
25529
|
+
if (!(0, import_node_fs56.existsSync)(path)) return null;
|
|
25432
25530
|
try {
|
|
25433
|
-
const raw = JSON.parse((0,
|
|
25531
|
+
const raw = JSON.parse((0, import_node_fs56.readFileSync)(path, "utf8"));
|
|
25434
25532
|
if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
|
|
25435
25533
|
return null;
|
|
25436
25534
|
}
|
|
@@ -25444,8 +25542,8 @@ function readDiskCache() {
|
|
|
25444
25542
|
}
|
|
25445
25543
|
function writeDiskCache(entry) {
|
|
25446
25544
|
try {
|
|
25447
|
-
(0,
|
|
25448
|
-
(0,
|
|
25545
|
+
(0, import_node_fs56.mkdirSync)(appDataDir(), { recursive: true });
|
|
25546
|
+
(0, import_node_fs56.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
|
|
25449
25547
|
} catch {
|
|
25450
25548
|
}
|
|
25451
25549
|
}
|
|
@@ -25832,7 +25930,7 @@ async function startMcpServer() {
|
|
|
25832
25930
|
async () => {
|
|
25833
25931
|
const threads = orch.getThreads(true);
|
|
25834
25932
|
const lines = threads.map((t) => {
|
|
25835
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0,
|
|
25933
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path53.basename)(t.repoPath) || t.repoPath;
|
|
25836
25934
|
const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
|
|
25837
25935
|
const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
|
|
25838
25936
|
const preview = lastMessagePreview(t.messages, 80);
|