@sideboard-ai/core 0.1.314 → 0.1.316
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-T5YSJLNZ.js → abletime-NZ2ABWAL.js} +4 -4
- package/dist/{abletime-SJUVZVRU.js → abletime-TKAFNXCM.js} +4 -4
- package/dist/{abletime-oauth-73TFJME4.js → abletime-oauth-CBFFBINA.js} +3 -3
- package/dist/{abletime-oauth-2TOOZ2FN.js → abletime-oauth-S4AXA4WR.js} +3 -3
- package/dist/{abletime-rest-PNUGH2FS.js → abletime-rest-NSOP72AI.js} +3 -3
- package/dist/{abletime-rest-5TDRIFEV.js → abletime-rest-ORBELZQO.js} +3 -3
- package/dist/{agents-KIC6CNXF.js → agents-5XJ7EHGU.js} +6 -6
- package/dist/{agents-S7VBS5JL.js → agents-Y3M3EKLY.js} +6 -6
- package/dist/{app-settings-CC65VPBL.js → app-settings-CZVFMOI5.js} +3 -1
- package/dist/{app-settings-DZ5AY7N5.js → app-settings-RQAFJZCD.js} +3 -1
- package/dist/{chunk-6EGQPMSR.js → chunk-4ISF5XUA.js} +47 -26
- package/dist/{chunk-EGTCXNQM.js → chunk-53OCOGND.js} +2 -2
- package/dist/{chunk-DLGGLV2M.js → chunk-5CTG5W7S.js} +2 -2
- package/dist/{chunk-YK77HB3W.js → chunk-7BLIY2DD.js} +45 -25
- package/dist/{chunk-CFTOKVQN.js → chunk-7SCVGGF6.js} +5 -5
- package/dist/{chunk-7UP4D5XI.js → chunk-ATSZXRFQ.js} +6 -5
- package/dist/{chunk-BIPXOHZI.js → chunk-BPBDGJ43.js} +2 -2
- package/dist/{chunk-CW4FIIDE.js → chunk-CCUGIVYN.js} +3 -3
- package/dist/{chunk-HG25AYBV.js → chunk-CHUPIJP7.js} +14 -0
- package/dist/{chunk-5QYCCXXQ.js → chunk-DNWO6PQJ.js} +6 -5
- package/dist/{chunk-JWW66PO3.js → chunk-ELBK34TY.js} +5 -5
- package/dist/{chunk-A45QMSVB.js → chunk-FVTR54LY.js} +5 -5
- package/dist/{chunk-PHMFAU35.js → chunk-GCHSJCCX.js} +96 -64
- package/dist/{chunk-ZSVKUOFH.js → chunk-GFM63DTU.js} +8 -5
- package/dist/{chunk-OLSLE3LO.js → chunk-GXSV3X3L.js} +3 -3
- package/dist/{chunk-JARCAPKL.js → chunk-I5CLCWUK.js} +3 -3
- package/dist/{chunk-TO5UL7VN.js → chunk-MBYGWNLQ.js} +1 -1
- package/dist/{chunk-7DBL5AF4.js → chunk-NKVNHBDB.js} +4 -4
- package/dist/{chunk-U4WACWBC.js → chunk-NXNNYY3Q.js} +2 -2
- package/dist/{chunk-NMPQ7GIS.js → chunk-OLYNM52B.js} +2 -2
- package/dist/{chunk-S3KYDK6W.js → chunk-PN32Z4JL.js} +8 -5
- package/dist/{chunk-ZQLZ2A3I.js → chunk-S3U4HR5F.js} +2 -2
- package/dist/{chunk-3UDRWMIM.js → chunk-U35AHE2P.js} +14 -0
- package/dist/{chunk-A2YXQC65.js → chunk-U7PNCYNX.js} +96 -64
- package/dist/{chunk-SZ3XS2WM.js → chunk-VVV7EI6T.js} +3 -2
- package/dist/{chunk-6424BACS.js → chunk-VZAJVX36.js} +3 -2
- package/dist/{conductor-IIDQ2U24.js → conductor-CFLBKVHJ.js} +5 -5
- package/dist/{conductor-G6TKCMIW.js → conductor-NZ4V5CJX.js} +5 -5
- package/dist/{coordinator-prompt-EXJSULAR.js → coordinator-prompt-HUZC4DZ2.js} +4 -4
- package/dist/{coordinator-prompt-5USNNCG6.js → coordinator-prompt-SPOYUZG5.js} +4 -4
- package/dist/{global-workspace-ZGPIGJ6J.js → global-workspace-3NNDDTFD.js} +4 -4
- package/dist/{global-workspace-UDRTONQE.js → global-workspace-SK4JQBPN.js} +4 -4
- package/dist/index.cjs +448 -71
- package/dist/index.d.cts +81 -55
- package/dist/index.d.ts +81 -55
- package/dist/index.js +310 -27
- package/dist/mcp/run-stdio.cjs +152 -63
- package/dist/mcp/run-stdio.js +15 -14
- package/dist/{optional-cli-MLZSE6KW.js → optional-cli-EMSZBYDE.js} +3 -3
- package/dist/{optional-cli-SI4BCPRH.js → optional-cli-LMSRZNH4.js} +4 -4
- package/dist/{orchestrator-AM7VT2BD.js → orchestrator-7342RGRU.js} +9 -9
- package/dist/{orchestrator-V6NLIPLH.js → orchestrator-KXEPWTG5.js} +9 -9
- package/dist/{thread-store-HY22M5A7.js → thread-store-5OF6M6VZ.js} +1 -1
- package/dist/{thread-store-XMUQDO5O.js → thread-store-GOVVXQV2.js} +1 -1
- package/dist/{workspaces-3TTODHKN.js → workspaces-52L6NZ3P.js} +4 -4
- package/dist/{workspaces-TATO466L.js → workspaces-EYNZDL45.js} +4 -4
- package/dist/{worktree-C5VI46RZ.js → worktree-BP5ICYQ2.js} +3 -3
- package/dist/{worktree-FMK57ULT.js → worktree-UCOSAI7J.js} +3 -3
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -975,6 +975,81 @@ var init_orchestrator_capable = __esm({
|
|
|
975
975
|
}
|
|
976
976
|
});
|
|
977
977
|
|
|
978
|
+
// src/store/thread-option-defaults.ts
|
|
979
|
+
function normalizeAutonomy(value) {
|
|
980
|
+
return value === "default" || value === "full" ? value : void 0;
|
|
981
|
+
}
|
|
982
|
+
function getDefaultAgent(settings = loadAppSettings()) {
|
|
983
|
+
return settings.defaults.agent ?? "claude";
|
|
984
|
+
}
|
|
985
|
+
function getDefaultModel(settings = loadAppSettings()) {
|
|
986
|
+
const model = settings.defaults.model?.trim();
|
|
987
|
+
return model || null;
|
|
988
|
+
}
|
|
989
|
+
function getDefaultEffort(settings = loadAppSettings()) {
|
|
990
|
+
return normalizeThinkingEffort(settings.defaults.effort) ?? "high";
|
|
991
|
+
}
|
|
992
|
+
function getDefaultFast(settings = loadAppSettings()) {
|
|
993
|
+
return settings.defaults.fast === true;
|
|
994
|
+
}
|
|
995
|
+
function getDefaultAutonomy(settings = loadAppSettings()) {
|
|
996
|
+
return settings.defaults.autonomy === "default" ? "default" : "full";
|
|
997
|
+
}
|
|
998
|
+
function resolveThreadDefaults(settings = loadAppSettings()) {
|
|
999
|
+
return {
|
|
1000
|
+
agent: getDefaultAgent(settings),
|
|
1001
|
+
model: getDefaultModel(settings),
|
|
1002
|
+
effort: getDefaultEffort(settings),
|
|
1003
|
+
fast: getDefaultFast(settings),
|
|
1004
|
+
autonomy: getDefaultAutonomy(settings)
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
function resolveOrchestratorDefaults(settings = loadAppSettings()) {
|
|
1008
|
+
const account = resolveThreadDefaults(settings);
|
|
1009
|
+
const orch = settings.defaults.orchestrator;
|
|
1010
|
+
const agent = coerceOrchestratorAgent(orch?.agent ?? account.agent);
|
|
1011
|
+
let model = orch ? orch.model?.trim() || null : account.model;
|
|
1012
|
+
if (model && agent !== "cursor" && /^(default|auto)$/i.test(model.trim())) {
|
|
1013
|
+
model = null;
|
|
1014
|
+
}
|
|
1015
|
+
return {
|
|
1016
|
+
agent,
|
|
1017
|
+
model,
|
|
1018
|
+
effort: orch?.effort ?? account.effort,
|
|
1019
|
+
fast: orch?.fast ?? account.fast,
|
|
1020
|
+
autonomy: orch?.autonomy ?? account.autonomy
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
function mergeThreadOptionOverrides(defaults, overrides) {
|
|
1024
|
+
const effort = overrides.effort === void 0 || overrides.effort === null ? defaults.effort : normalizeThinkingEffort(overrides.effort) ?? defaults.effort;
|
|
1025
|
+
const agent = overrides.agent ?? defaults.agent;
|
|
1026
|
+
let model = overrides.model === void 0 ? defaults.model : overrides.model?.trim() || null;
|
|
1027
|
+
if (model && agent !== "cursor" && /^(default|auto)$/i.test(model.trim())) {
|
|
1028
|
+
model = null;
|
|
1029
|
+
}
|
|
1030
|
+
return {
|
|
1031
|
+
agent,
|
|
1032
|
+
model,
|
|
1033
|
+
effort,
|
|
1034
|
+
fast: overrides.fast === void 0 || overrides.fast === null ? defaults.fast : Boolean(overrides.fast),
|
|
1035
|
+
autonomy: overrides.autonomy == null ? defaults.autonomy : normalizeAutonomy(overrides.autonomy) ?? defaults.autonomy
|
|
1036
|
+
};
|
|
1037
|
+
}
|
|
1038
|
+
function resolveNewThreadOptions(overrides = {}, settings = loadAppSettings()) {
|
|
1039
|
+
return mergeThreadOptionOverrides(resolveThreadDefaults(settings), overrides);
|
|
1040
|
+
}
|
|
1041
|
+
function resolveNewOrchestratorOptions(overrides = {}, settings = loadAppSettings()) {
|
|
1042
|
+
return mergeThreadOptionOverrides(resolveOrchestratorDefaults(settings), overrides);
|
|
1043
|
+
}
|
|
1044
|
+
var init_thread_option_defaults = __esm({
|
|
1045
|
+
"src/store/thread-option-defaults.ts"() {
|
|
1046
|
+
"use strict";
|
|
1047
|
+
init_orchestrator_capable();
|
|
1048
|
+
init_thinking_effort();
|
|
1049
|
+
init_app_settings();
|
|
1050
|
+
}
|
|
1051
|
+
});
|
|
1052
|
+
|
|
978
1053
|
// src/hook/nested-electron-env.ts
|
|
979
1054
|
function isNestedElectronEnvKey(key) {
|
|
980
1055
|
return NESTED_ELECTRON_ENV_PREFIXES.some((prefix) => key.startsWith(prefix));
|
|
@@ -2187,6 +2262,7 @@ __export(app_settings_exports, {
|
|
|
2187
2262
|
getAbleTimeAccessToken: () => getAbleTimeAccessToken,
|
|
2188
2263
|
getAbleTimeHost: () => getAbleTimeHost,
|
|
2189
2264
|
getDefaultAgent: () => getDefaultAgent,
|
|
2265
|
+
getDefaultAutonomy: () => getDefaultAutonomy,
|
|
2190
2266
|
getDefaultEffort: () => getDefaultEffort,
|
|
2191
2267
|
getDefaultFast: () => getDefaultFast,
|
|
2192
2268
|
getDefaultModel: () => getDefaultModel,
|
|
@@ -2530,6 +2606,8 @@ function normalizeOrchestratorDefaults(raw) {
|
|
|
2530
2606
|
if (typeof source.fast === "boolean") {
|
|
2531
2607
|
out.fast = source.fast;
|
|
2532
2608
|
}
|
|
2609
|
+
const autonomy = normalizeAutonomy(source.autonomy);
|
|
2610
|
+
if (autonomy) out.autonomy = autonomy;
|
|
2533
2611
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
2534
2612
|
}
|
|
2535
2613
|
function normalizeDefaults(raw) {
|
|
@@ -2549,6 +2627,8 @@ function normalizeDefaults(raw) {
|
|
|
2549
2627
|
if (typeof source.fast === "boolean") {
|
|
2550
2628
|
out.fast = source.fast;
|
|
2551
2629
|
}
|
|
2630
|
+
const autonomy = normalizeAutonomy(source.autonomy);
|
|
2631
|
+
if (autonomy) out.autonomy = autonomy;
|
|
2552
2632
|
const notes = foldLegacyRolesIntoNotes(source.roles, source.role, source.notes);
|
|
2553
2633
|
if (notes) out.notes = notes;
|
|
2554
2634
|
const orchestrator = normalizeOrchestratorDefaults(source.orchestrator);
|
|
@@ -3201,6 +3281,14 @@ function applyOrchestratorDefaultsPatch(current, patch) {
|
|
|
3201
3281
|
next.fast = Boolean(patch.fast);
|
|
3202
3282
|
}
|
|
3203
3283
|
}
|
|
3284
|
+
if ("autonomy" in patch) {
|
|
3285
|
+
if (patch.autonomy == null) {
|
|
3286
|
+
delete next.autonomy;
|
|
3287
|
+
} else {
|
|
3288
|
+
const autonomy = normalizeAutonomy(patch.autonomy);
|
|
3289
|
+
if (autonomy) next.autonomy = autonomy;
|
|
3290
|
+
}
|
|
3291
|
+
}
|
|
3204
3292
|
return Object.keys(next).length > 0 ? next : void 0;
|
|
3205
3293
|
}
|
|
3206
3294
|
function updateDefaultsSettings(patch) {
|
|
@@ -3235,6 +3323,14 @@ function updateDefaultsSettings(patch) {
|
|
|
3235
3323
|
defaults.fast = Boolean(patch.fast);
|
|
3236
3324
|
}
|
|
3237
3325
|
}
|
|
3326
|
+
if ("autonomy" in patch) {
|
|
3327
|
+
if (patch.autonomy == null) {
|
|
3328
|
+
delete defaults.autonomy;
|
|
3329
|
+
} else {
|
|
3330
|
+
const autonomy = normalizeAutonomy(patch.autonomy);
|
|
3331
|
+
if (autonomy) defaults.autonomy = autonomy;
|
|
3332
|
+
}
|
|
3333
|
+
}
|
|
3238
3334
|
if ("notes" in patch) {
|
|
3239
3335
|
const notes = normalizeProfileNotes(patch.notes);
|
|
3240
3336
|
if (!notes) delete defaults.notes;
|
|
@@ -3284,19 +3380,6 @@ function resolveProjectReviewLabel(settings, repoPath) {
|
|
|
3284
3380
|
if (!key) return "";
|
|
3285
3381
|
return settings.projects[key]?.reviewLabel?.trim() || "";
|
|
3286
3382
|
}
|
|
3287
|
-
function getDefaultAgent(settings = loadAppSettings()) {
|
|
3288
|
-
return settings.defaults.agent ?? "claude";
|
|
3289
|
-
}
|
|
3290
|
-
function getDefaultModel(settings = loadAppSettings()) {
|
|
3291
|
-
const model = settings.defaults.model?.trim();
|
|
3292
|
-
return model || null;
|
|
3293
|
-
}
|
|
3294
|
-
function getDefaultEffort(settings = loadAppSettings()) {
|
|
3295
|
-
return normalizeThinkingEffort(settings.defaults.effort) ?? "high";
|
|
3296
|
-
}
|
|
3297
|
-
function getDefaultFast(settings = loadAppSettings()) {
|
|
3298
|
-
return settings.defaults.fast === true;
|
|
3299
|
-
}
|
|
3300
3383
|
function resolveAccountProfileFromSettings(settings = loadAppSettings()) {
|
|
3301
3384
|
return resolveViewerProfile(settings.defaults);
|
|
3302
3385
|
}
|
|
@@ -3359,49 +3442,6 @@ function writeViewerContext(input) {
|
|
|
3359
3442
|
updateDefaultsSettings({ notes: proposed || null });
|
|
3360
3443
|
return { ok: true, scope: "account", context: proposed };
|
|
3361
3444
|
}
|
|
3362
|
-
function resolveThreadDefaults(settings = loadAppSettings()) {
|
|
3363
|
-
return {
|
|
3364
|
-
agent: getDefaultAgent(settings),
|
|
3365
|
-
model: getDefaultModel(settings),
|
|
3366
|
-
effort: getDefaultEffort(settings),
|
|
3367
|
-
fast: getDefaultFast(settings)
|
|
3368
|
-
};
|
|
3369
|
-
}
|
|
3370
|
-
function resolveOrchestratorDefaults(settings = loadAppSettings()) {
|
|
3371
|
-
const account = resolveThreadDefaults(settings);
|
|
3372
|
-
const orch = settings.defaults.orchestrator;
|
|
3373
|
-
const agent = coerceOrchestratorAgent(orch?.agent ?? account.agent);
|
|
3374
|
-
let model = orch ? orch.model?.trim() || null : account.model;
|
|
3375
|
-
if (model && agent !== "cursor" && /^(default|auto)$/i.test(model.trim())) {
|
|
3376
|
-
model = null;
|
|
3377
|
-
}
|
|
3378
|
-
return {
|
|
3379
|
-
agent,
|
|
3380
|
-
model,
|
|
3381
|
-
effort: orch?.effort ?? account.effort,
|
|
3382
|
-
fast: orch?.fast ?? account.fast
|
|
3383
|
-
};
|
|
3384
|
-
}
|
|
3385
|
-
function mergeThreadOptionOverrides(defaults, overrides) {
|
|
3386
|
-
const effort = overrides.effort === void 0 || overrides.effort === null ? defaults.effort : normalizeThinkingEffort(overrides.effort) ?? defaults.effort;
|
|
3387
|
-
const agent = overrides.agent ?? defaults.agent;
|
|
3388
|
-
let model = overrides.model === void 0 ? defaults.model : overrides.model?.trim() || null;
|
|
3389
|
-
if (model && agent !== "cursor" && /^(default|auto)$/i.test(model.trim())) {
|
|
3390
|
-
model = null;
|
|
3391
|
-
}
|
|
3392
|
-
return {
|
|
3393
|
-
agent,
|
|
3394
|
-
model,
|
|
3395
|
-
effort,
|
|
3396
|
-
fast: overrides.fast === void 0 || overrides.fast === null ? defaults.fast : Boolean(overrides.fast)
|
|
3397
|
-
};
|
|
3398
|
-
}
|
|
3399
|
-
function resolveNewThreadOptions(overrides = {}, settings = loadAppSettings()) {
|
|
3400
|
-
return mergeThreadOptionOverrides(resolveThreadDefaults(settings), overrides);
|
|
3401
|
-
}
|
|
3402
|
-
function resolveNewOrchestratorOptions(overrides = {}, settings = loadAppSettings()) {
|
|
3403
|
-
return mergeThreadOptionOverrides(resolveOrchestratorDefaults(settings), overrides);
|
|
3404
|
-
}
|
|
3405
3445
|
function isLinearConnected(settings = loadAppSettings()) {
|
|
3406
3446
|
return hasLinearCredentials(settings.integrations);
|
|
3407
3447
|
}
|
|
@@ -3806,6 +3846,7 @@ var init_app_settings = __esm({
|
|
|
3806
3846
|
import_node_os4 = require("os");
|
|
3807
3847
|
import_node_path11 = require("path");
|
|
3808
3848
|
init_orchestrator_capable();
|
|
3849
|
+
init_thread_option_defaults();
|
|
3809
3850
|
init_thinking_effort();
|
|
3810
3851
|
init_nested_electron_env();
|
|
3811
3852
|
init_account_profile();
|
|
@@ -3820,6 +3861,7 @@ var init_app_settings = __esm({
|
|
|
3820
3861
|
init_managed_accounts();
|
|
3821
3862
|
init_usage_on_limit();
|
|
3822
3863
|
init_issue_source_labels();
|
|
3864
|
+
init_thread_option_defaults();
|
|
3823
3865
|
init_account_profile();
|
|
3824
3866
|
HARNESS_ENV_KEYS = {
|
|
3825
3867
|
claude: "ANTHROPIC_API_KEY",
|
|
@@ -5102,6 +5144,19 @@ function normalizeRunScriptRequest(raw) {
|
|
|
5102
5144
|
error: req.error ?? null
|
|
5103
5145
|
};
|
|
5104
5146
|
}
|
|
5147
|
+
function sanitizeIssueBlockedBy(value) {
|
|
5148
|
+
if (!Array.isArray(value)) return void 0;
|
|
5149
|
+
const out = [];
|
|
5150
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5151
|
+
for (const item of value) {
|
|
5152
|
+
const id = String(item ?? "").trim();
|
|
5153
|
+
const key = id.toLowerCase();
|
|
5154
|
+
if (!id || seen.has(key)) continue;
|
|
5155
|
+
seen.add(key);
|
|
5156
|
+
out.push(id);
|
|
5157
|
+
}
|
|
5158
|
+
return out;
|
|
5159
|
+
}
|
|
5105
5160
|
function normalizeThread(raw) {
|
|
5106
5161
|
return {
|
|
5107
5162
|
...raw,
|
|
@@ -5126,6 +5181,7 @@ function normalizeThread(raw) {
|
|
|
5126
5181
|
prIsInMergeQueue: Boolean(raw.prIsInMergeQueue),
|
|
5127
5182
|
prLabels: Array.isArray(raw.prLabels) ? raw.prLabels : [],
|
|
5128
5183
|
prChecksFailed: typeof raw.prChecksFailed === "boolean" ? raw.prChecksFailed : void 0,
|
|
5184
|
+
issueBlockedBy: sanitizeIssueBlockedBy(raw.issueBlockedBy),
|
|
5129
5185
|
skipAutoArchiveOnMerge: Boolean(raw.skipAutoArchiveOnMerge),
|
|
5130
5186
|
cowboy: Boolean(raw.cowboy),
|
|
5131
5187
|
stackId: raw.stackId ?? null,
|
|
@@ -6971,6 +7027,27 @@ var init_agent_block_view = __esm({
|
|
|
6971
7027
|
}
|
|
6972
7028
|
});
|
|
6973
7029
|
|
|
7030
|
+
// src/board/issue-blocked-view.ts
|
|
7031
|
+
function issueBlockedByIds(group) {
|
|
7032
|
+
const out = [];
|
|
7033
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7034
|
+
for (const thread of group) {
|
|
7035
|
+
for (const raw of thread.issueBlockedBy ?? []) {
|
|
7036
|
+
const id = String(raw ?? "").trim();
|
|
7037
|
+
const key = id.toLowerCase();
|
|
7038
|
+
if (!id || seen.has(key)) continue;
|
|
7039
|
+
seen.add(key);
|
|
7040
|
+
out.push(id);
|
|
7041
|
+
}
|
|
7042
|
+
}
|
|
7043
|
+
return out;
|
|
7044
|
+
}
|
|
7045
|
+
var init_issue_blocked_view = __esm({
|
|
7046
|
+
"src/board/issue-blocked-view.ts"() {
|
|
7047
|
+
"use strict";
|
|
7048
|
+
}
|
|
7049
|
+
});
|
|
7050
|
+
|
|
6974
7051
|
// src/board/pr-state.ts
|
|
6975
7052
|
function isOpenPrState(prUrl, prState) {
|
|
6976
7053
|
if (!prUrl?.trim()) return false;
|
|
@@ -7709,6 +7786,7 @@ function toThreadCard(group) {
|
|
|
7709
7786
|
const thread = group[0];
|
|
7710
7787
|
const withPr = group.find((t) => t.prUrl?.trim()) ?? thread;
|
|
7711
7788
|
const tags = workspaceTagsFromGroup(group);
|
|
7789
|
+
const issueBlockedBy = issueBlockedByIds(group);
|
|
7712
7790
|
return {
|
|
7713
7791
|
kind: "thread",
|
|
7714
7792
|
id: thread.id,
|
|
@@ -7722,6 +7800,7 @@ function toThreadCard(group) {
|
|
|
7722
7800
|
link: `sideboard://chat/${thread.id}`,
|
|
7723
7801
|
...group.length > 1 ? { chatCount: group.length } : {},
|
|
7724
7802
|
...threadCardBlockFields(group) ?? {},
|
|
7803
|
+
...issueBlockedBy.length > 0 ? { issueBlockedBy } : {},
|
|
7725
7804
|
...tags.length > 0 ? { tags } : {}
|
|
7726
7805
|
};
|
|
7727
7806
|
}
|
|
@@ -7805,9 +7884,11 @@ var init_home_board = __esm({
|
|
|
7805
7884
|
init_message_parts();
|
|
7806
7885
|
init_worktree_labels();
|
|
7807
7886
|
init_agent_block_view();
|
|
7887
|
+
init_issue_blocked_view();
|
|
7808
7888
|
init_pr_state();
|
|
7809
7889
|
init_worktree_ownership();
|
|
7810
7890
|
init_worktree_list_badges();
|
|
7891
|
+
init_issue_blocked_view();
|
|
7811
7892
|
init_agent_block_view();
|
|
7812
7893
|
GLOBAL_WORKSPACE_ID = "__global__";
|
|
7813
7894
|
BOARD_COLUMN_DEFS = [
|
|
@@ -7821,7 +7902,7 @@ var init_home_board = __esm({
|
|
|
7821
7902
|
DEFAULT_WORKTREE_SORT = "created";
|
|
7822
7903
|
DEFAULTISH_BRANCH = /^(main|master|develop|development|trunk|default|head)$/;
|
|
7823
7904
|
BOARD_PAGE_SIZE = 40;
|
|
7824
|
-
HOME_BOARD_AGENT_HINT = "Home is a Kanban of workspaces (one card per checkout; sibling chats on a card are separate agents). Do not create a second workspace for a ticket, PR, or named branch that already has a live checkout \u2014 create_workspace / start_board_card return that checkout (alreadyStarted) and its chats. Add another agent with fork_chat. Creating from the default branch still opens a new isolated workspace. Columns are the path to merge: New (no PR) \u2192 Draft (draft PR) \u2192 Review (open PR) \u2192 Approved (approved, not merged) \u2192 Merged. ownership=mine is PRs you authored (or WIP with no PR); ownership=reviewing is someone else's PR (or a review-requested checkout). Viewer login comes from gh, not a setting. Archive removes the card to Settings \u2192 History (list_archive to browse, restore_workspace to bring it back). Queued/running are activity on the card, not columns. blockedReason means an agent on that card is waiting on a person (the question, plan approval, or a reported block) \u2014 read it and do not send_to_chat a check-in. Orchestration chats stay in the sidebar. Do not invent status.";
|
|
7905
|
+
HOME_BOARD_AGENT_HINT = "Home is a Kanban of workspaces (one card per checkout; sibling chats on a card are separate agents). Do not create a second workspace for a ticket, PR, or named branch that already has a live checkout \u2014 create_workspace / start_board_card return that checkout (alreadyStarted) and its chats. Add another agent with fork_chat. Creating from the default branch still opens a new isolated workspace. Columns are the path to merge: New (no PR) \u2192 Draft (draft PR) \u2192 Review (open PR) \u2192 Approved (approved, not merged) \u2192 Merged. ownership=mine is PRs you authored (or WIP with no PR); ownership=reviewing is someone else's PR (or a review-requested checkout). Viewer login comes from gh, not a setting. Archive removes the card to Settings \u2192 History (list_archive to browse, restore_workspace to bring it back). Queued/running are activity on the card, not columns. blockedReason means an agent on that card is waiting on a person (the question, plan approval, or a reported block) \u2014 read it and do not send_to_chat a check-in. issueBlockedBy, when present, lists issues blocking that workspace's source ticket (the tracker dependency, not a person). Orchestration chats stay in the sidebar. Do not invent status.";
|
|
7825
7906
|
}
|
|
7826
7907
|
});
|
|
7827
7908
|
|
|
@@ -12550,7 +12631,8 @@ function createGlobalChat(opts) {
|
|
|
12550
12631
|
agent: opts.agent,
|
|
12551
12632
|
model: opts.model,
|
|
12552
12633
|
effort: opts.effort,
|
|
12553
|
-
fast: opts.fast
|
|
12634
|
+
fast: opts.fast,
|
|
12635
|
+
autonomy: opts.autonomy
|
|
12554
12636
|
});
|
|
12555
12637
|
const agent = assertOrchestratorCapableAgent(resolved.agent);
|
|
12556
12638
|
const worktreePath = globalAgentCwd();
|
|
@@ -12564,7 +12646,7 @@ function createGlobalChat(opts) {
|
|
|
12564
12646
|
worktreePath,
|
|
12565
12647
|
repoPath: GLOBAL_WORKSPACE_ID2,
|
|
12566
12648
|
agent,
|
|
12567
|
-
autonomy:
|
|
12649
|
+
autonomy: resolved.autonomy,
|
|
12568
12650
|
model: resolved.model,
|
|
12569
12651
|
effort: resolved.effort,
|
|
12570
12652
|
fast: resolved.fast,
|
|
@@ -12641,6 +12723,7 @@ function ensureSlackCoordinator(teamId, userId, agent, opts) {
|
|
|
12641
12723
|
if (existing.model !== defaults.model) patch.model = defaults.model;
|
|
12642
12724
|
if (existing.effort !== defaults.effort) patch.effort = defaults.effort;
|
|
12643
12725
|
if (existing.fast !== defaults.fast) patch.fast = defaults.fast;
|
|
12726
|
+
if (existing.autonomy !== defaults.autonomy) patch.autonomy = defaults.autonomy;
|
|
12644
12727
|
}
|
|
12645
12728
|
if (Object.keys(patch).length > 0) {
|
|
12646
12729
|
return updateThread(existing.id, patch);
|
|
@@ -12699,6 +12782,7 @@ function ensureCloudCoordinator(agent) {
|
|
|
12699
12782
|
if (existing.model !== defaults.model) patch.model = defaults.model;
|
|
12700
12783
|
if (existing.effort !== defaults.effort) patch.effort = defaults.effort;
|
|
12701
12784
|
if (existing.fast !== defaults.fast) patch.fast = defaults.fast;
|
|
12785
|
+
if (existing.autonomy !== defaults.autonomy) patch.autonomy = defaults.autonomy;
|
|
12702
12786
|
}
|
|
12703
12787
|
if (Object.keys(patch).length > 0) {
|
|
12704
12788
|
return updateThread(existing.id, patch);
|
|
@@ -20691,6 +20775,7 @@ function worktreeBindingFrom(from) {
|
|
|
20691
20775
|
prIsInMergeQueue: from.prIsInMergeQueue,
|
|
20692
20776
|
prLabels: from.prLabels,
|
|
20693
20777
|
prChecksFailed: from.prChecksFailed,
|
|
20778
|
+
issueBlockedBy: from.issueBlockedBy,
|
|
20694
20779
|
skipAutoArchiveOnMerge: from.skipAutoArchiveOnMerge,
|
|
20695
20780
|
stackId: from.stackId,
|
|
20696
20781
|
stackLayer: from.stackLayer,
|
|
@@ -23832,6 +23917,7 @@ function restTaskToRaw(raw, users) {
|
|
|
23832
23917
|
projectId: asString(rec.projectId),
|
|
23833
23918
|
categoryId: asString(rec.projectCategoryId) || asString(rec.categoryId),
|
|
23834
23919
|
parentId: asString(rec.parentTaskId) || asString(rec.parentId),
|
|
23920
|
+
depends_on: rec.dependencyParentTimeflowTaskId ?? null,
|
|
23835
23921
|
tags: rec.tags,
|
|
23836
23922
|
comments,
|
|
23837
23923
|
attachments: rec.attachments ?? rec.files ?? rec.media,
|
|
@@ -25275,7 +25361,8 @@ async function createThread(input, _onSetupLine) {
|
|
|
25275
25361
|
agent: input.agent,
|
|
25276
25362
|
model: input.model,
|
|
25277
25363
|
effort: input.effort,
|
|
25278
|
-
fast: input.fast
|
|
25364
|
+
fast: input.fast,
|
|
25365
|
+
autonomy: input.autonomy
|
|
25279
25366
|
});
|
|
25280
25367
|
await requireAgent(resolved.agent);
|
|
25281
25368
|
if (input.cowboy) {
|
|
@@ -25314,7 +25401,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
25314
25401
|
worktreePath: repoPath,
|
|
25315
25402
|
repoPath,
|
|
25316
25403
|
agent: resolved.agent,
|
|
25317
|
-
autonomy:
|
|
25404
|
+
autonomy: resolved.autonomy,
|
|
25318
25405
|
model: resolved.model,
|
|
25319
25406
|
effort: resolved.effort,
|
|
25320
25407
|
fast: resolved.fast,
|
|
@@ -25428,7 +25515,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
25428
25515
|
worktreePath,
|
|
25429
25516
|
repoPath,
|
|
25430
25517
|
agent: resolved.agent,
|
|
25431
|
-
autonomy:
|
|
25518
|
+
autonomy: resolved.autonomy,
|
|
25432
25519
|
model: resolved.model,
|
|
25433
25520
|
effort: resolved.effort,
|
|
25434
25521
|
fast: resolved.fast,
|
|
@@ -26607,7 +26694,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
26607
26694
|
worktreePath,
|
|
26608
26695
|
repoPath,
|
|
26609
26696
|
agent: input.agent,
|
|
26610
|
-
autonomy: input.autonomy ??
|
|
26697
|
+
autonomy: input.autonomy ?? getDefaultAutonomy(),
|
|
26611
26698
|
model: input.model ?? null,
|
|
26612
26699
|
effort: input.effort ?? "high",
|
|
26613
26700
|
fast: Boolean(input.fast),
|
|
@@ -26816,6 +26903,7 @@ var init_stack_layers = __esm({
|
|
|
26816
26903
|
init_worktree();
|
|
26817
26904
|
init_conductor();
|
|
26818
26905
|
init_thread_store();
|
|
26906
|
+
init_app_settings();
|
|
26819
26907
|
init_workspaces();
|
|
26820
26908
|
}
|
|
26821
26909
|
});
|
|
@@ -33115,6 +33203,7 @@ __export(index_exports, {
|
|
|
33115
33203
|
getCaffeinateHold: () => getCaffeinateHold,
|
|
33116
33204
|
getClaudePlanUsage: () => getClaudePlanUsage,
|
|
33117
33205
|
getDefaultAgent: () => getDefaultAgent,
|
|
33206
|
+
getDefaultAutonomy: () => getDefaultAutonomy,
|
|
33118
33207
|
getDefaultEffort: () => getDefaultEffort,
|
|
33119
33208
|
getDefaultFast: () => getDefaultFast,
|
|
33120
33209
|
getDefaultModel: () => getDefaultModel,
|
|
@@ -33463,6 +33552,7 @@ __export(index_exports, {
|
|
|
33463
33552
|
recordSlackOutboundWatch: () => recordSlackOutboundWatch,
|
|
33464
33553
|
refreshBrightsyAccessToken: () => refreshBrightsyAccessToken,
|
|
33465
33554
|
refreshGitHubAuth: () => refreshGitHubAuth,
|
|
33555
|
+
refreshWorktreeIssueBlocked: () => refreshWorktreeIssueBlocked,
|
|
33466
33556
|
registerBrightsyOAuthClient: () => registerBrightsyOAuthClient,
|
|
33467
33557
|
registerPackagedUserMcpClients: () => registerPackagedUserMcpClients,
|
|
33468
33558
|
releaseCaffeinateHoldForThread: () => releaseCaffeinateHoldForThread,
|
|
@@ -34836,7 +34926,8 @@ function row(resolved) {
|
|
|
34836
34926
|
agent: resolved.agent,
|
|
34837
34927
|
model: resolved.model,
|
|
34838
34928
|
effort: resolved.effort,
|
|
34839
|
-
fast: resolved.fast
|
|
34929
|
+
fast: resolved.fast,
|
|
34930
|
+
autonomy: resolved.autonomy
|
|
34840
34931
|
};
|
|
34841
34932
|
}
|
|
34842
34933
|
function phoneAccountDefaults() {
|
|
@@ -35403,15 +35494,13 @@ function listPhoneSidebar(viewerLogin = phoneViewerLogin()) {
|
|
|
35403
35494
|
path: path2,
|
|
35404
35495
|
worktrees: groupHomeBoardWorktrees(repoThreads).map((group) => {
|
|
35405
35496
|
const tags = workspaceTagsFromGroup(group);
|
|
35406
|
-
const badge = classifyWorktreeListBadges(
|
|
35407
|
-
|
|
35408
|
-
viewerLogin,
|
|
35409
|
-
resolveProjectReviewLabel(settings, path2)
|
|
35410
|
-
)[0];
|
|
35497
|
+
const badge = classifyWorktreeListBadges(group, viewerLogin, resolveProjectReviewLabel(settings, path2))[0];
|
|
35498
|
+
const blockedBy = issueBlockedByIds(group);
|
|
35411
35499
|
return {
|
|
35412
35500
|
label: worktreeDisplayLabelForGroup(group),
|
|
35413
35501
|
chats: group.map(summarize),
|
|
35414
35502
|
...tags.length > 0 ? { tags } : {},
|
|
35503
|
+
...blockedBy.length > 0 ? { blockedBy } : {},
|
|
35415
35504
|
...badge ? { badge: { id: badge.id, label: badge.label, title: badge.title, ...badge.conflict ? { conflict: true } : {} } } : {}
|
|
35416
35505
|
};
|
|
35417
35506
|
})
|
|
@@ -35507,7 +35596,7 @@ function draftAgentOptions(draft, defaults) {
|
|
|
35507
35596
|
effort: draft?.effort ?? defaults.effort,
|
|
35508
35597
|
fast: draft?.fast ?? defaults.fast,
|
|
35509
35598
|
planMode: Boolean(draft?.planMode),
|
|
35510
|
-
autonomy: draft?.autonomy
|
|
35599
|
+
autonomy: draft?.autonomy ?? defaults.autonomy
|
|
35511
35600
|
};
|
|
35512
35601
|
}
|
|
35513
35602
|
function createPhoneChat(agent) {
|
|
@@ -38835,7 +38924,7 @@ function phoneBoardKey(sidebar) {
|
|
|
38835
38924
|
const orchestration = sidebar.orchestration.map(chatKey).join("\n");
|
|
38836
38925
|
const projects = sidebar.projects.map((project) => {
|
|
38837
38926
|
const trees = project.worktrees.map(
|
|
38838
|
-
(tree) => `${tree.label} ${tree.badge?.id ?? ""} ${(tree.tags ?? []).join(",")} ${tree.chats.map(chatKey).join("\n")}`
|
|
38927
|
+
(tree) => `${tree.label} ${tree.badge?.id ?? ""} ${(tree.tags ?? []).join(",")} ${(tree.blockedBy ?? []).join(",")} ${tree.chats.map(chatKey).join("\n")}`
|
|
38839
38928
|
).join("\n");
|
|
38840
38929
|
return `${project.path} ${project.name}
|
|
38841
38930
|
${trees}`;
|
|
@@ -42013,6 +42102,7 @@ async function createOrchChildThread(orch, args, resolveNewThreadOptions2) {
|
|
|
42013
42102
|
model: opts.model,
|
|
42014
42103
|
effort: opts.effort,
|
|
42015
42104
|
fast: opts.fast,
|
|
42105
|
+
autonomy: opts.autonomy,
|
|
42016
42106
|
repoPath: args.repoPath,
|
|
42017
42107
|
title: args.title,
|
|
42018
42108
|
parentThreadId: parentId || null,
|
|
@@ -45422,6 +45512,291 @@ init_pilot_tools();
|
|
|
45422
45512
|
// src/index.ts
|
|
45423
45513
|
init_profile();
|
|
45424
45514
|
init_home_board();
|
|
45515
|
+
|
|
45516
|
+
// src/integrations/abletime-blocked.ts
|
|
45517
|
+
init_abletime_mcp();
|
|
45518
|
+
init_abletime_rest();
|
|
45519
|
+
function asRecord18(value) {
|
|
45520
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
45521
|
+
}
|
|
45522
|
+
function asString5(value) {
|
|
45523
|
+
return typeof value === "string" ? value.trim() : "";
|
|
45524
|
+
}
|
|
45525
|
+
function firstString5(record, keys) {
|
|
45526
|
+
if (!record) return "";
|
|
45527
|
+
for (const key of keys) {
|
|
45528
|
+
const value = asString5(record[key]);
|
|
45529
|
+
if (value) return value;
|
|
45530
|
+
}
|
|
45531
|
+
return "";
|
|
45532
|
+
}
|
|
45533
|
+
function firstRecord2(record, keys) {
|
|
45534
|
+
if (!record) return null;
|
|
45535
|
+
for (const key of keys) {
|
|
45536
|
+
const value = asRecord18(record[key]);
|
|
45537
|
+
if (value) return value;
|
|
45538
|
+
}
|
|
45539
|
+
return null;
|
|
45540
|
+
}
|
|
45541
|
+
function identifierFromUnknown(value) {
|
|
45542
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
45543
|
+
const id2 = String(value).trim();
|
|
45544
|
+
return id2 ? [id2] : [];
|
|
45545
|
+
}
|
|
45546
|
+
if (Array.isArray(value)) return value.flatMap(identifierFromUnknown);
|
|
45547
|
+
const rec = asRecord18(value);
|
|
45548
|
+
if (!rec) return [];
|
|
45549
|
+
for (const key of ["nodes", "data", "tasks", "items"]) {
|
|
45550
|
+
if (Array.isArray(rec[key])) return identifierFromUnknown(rec[key]);
|
|
45551
|
+
}
|
|
45552
|
+
const id = firstString5(rec, ["identifier", "reference", "ref", "key", "code", "number", "id"]);
|
|
45553
|
+
return id ? [id] : [];
|
|
45554
|
+
}
|
|
45555
|
+
function ableTimeBlockedByIdentifiers(raw) {
|
|
45556
|
+
const record = asRecord18(raw);
|
|
45557
|
+
const nested = firstRecord2(record, ["task", "data"]) ?? record;
|
|
45558
|
+
if (!nested) return [];
|
|
45559
|
+
const value = nested.blocked_by ?? nested.blockedBy ?? nested.depends_on ?? nested.dependsOn ?? nested.dependencyParentTimeflowTaskId ?? nested.wait_on ?? nested.waitOn;
|
|
45560
|
+
const out = [];
|
|
45561
|
+
const seen = /* @__PURE__ */ new Set();
|
|
45562
|
+
for (const id of identifierFromUnknown(value)) {
|
|
45563
|
+
const key = id.toLowerCase();
|
|
45564
|
+
if (seen.has(key)) continue;
|
|
45565
|
+
seen.add(key);
|
|
45566
|
+
out.push(id);
|
|
45567
|
+
}
|
|
45568
|
+
return out;
|
|
45569
|
+
}
|
|
45570
|
+
function taskReference(raw) {
|
|
45571
|
+
const record = asRecord18(raw);
|
|
45572
|
+
const nested = firstRecord2(record, ["task", "data"]) ?? record;
|
|
45573
|
+
return firstString5(nested, ["taskRef", "reference", "identifier"]);
|
|
45574
|
+
}
|
|
45575
|
+
async function getAbleTimeIssueBlockedBy(id, opts) {
|
|
45576
|
+
const taskId = id.trim();
|
|
45577
|
+
if (!taskId) throw new Error("AbleTime task id is required");
|
|
45578
|
+
const raw = await callAbleTimeTool("get_task", { id: taskId, task_id: taskId }, opts);
|
|
45579
|
+
const out = [];
|
|
45580
|
+
for (const blockerId of ableTimeBlockedByIdentifiers(raw)) {
|
|
45581
|
+
if (!looksLikeAbleTimeUlid(blockerId)) {
|
|
45582
|
+
out.push(blockerId);
|
|
45583
|
+
continue;
|
|
45584
|
+
}
|
|
45585
|
+
const parent = await callAbleTimeTool("get_task", { id: blockerId, task_id: blockerId }, opts);
|
|
45586
|
+
const ref = taskReference(parent);
|
|
45587
|
+
if (!ref || looksLikeAbleTimeUlid(ref)) {
|
|
45588
|
+
throw new Error(`AbleTime blocker has no reference: ${blockerId}`);
|
|
45589
|
+
}
|
|
45590
|
+
out.push(ref);
|
|
45591
|
+
}
|
|
45592
|
+
return out;
|
|
45593
|
+
}
|
|
45594
|
+
|
|
45595
|
+
// src/integrations/github-blocked.ts
|
|
45596
|
+
init_run();
|
|
45597
|
+
function githubBlockedByIdentifiers(payload) {
|
|
45598
|
+
const root = payload && typeof payload === "object" && !Array.isArray(payload) ? payload : null;
|
|
45599
|
+
const data = root?.data && typeof root.data === "object" && !Array.isArray(root.data) ? root.data : root;
|
|
45600
|
+
const repository = data?.repository && typeof data.repository === "object" ? data.repository : null;
|
|
45601
|
+
const issue = repository?.issue && typeof repository.issue === "object" ? repository.issue : null;
|
|
45602
|
+
const blocked = issue?.blockedBy && typeof issue.blockedBy === "object" ? issue.blockedBy : null;
|
|
45603
|
+
const nodes = Array.isArray(blocked?.nodes) ? blocked.nodes : Array.isArray(root?.blockedBy) ? root.blockedBy : [];
|
|
45604
|
+
const out = [];
|
|
45605
|
+
const seen = /* @__PURE__ */ new Set();
|
|
45606
|
+
for (const node of nodes) {
|
|
45607
|
+
const rec = node && typeof node === "object" && !Array.isArray(node) ? node : null;
|
|
45608
|
+
const number = Number(rec?.number ?? node);
|
|
45609
|
+
if (!Number.isFinite(number) || number <= 0) continue;
|
|
45610
|
+
const id = `#${number}`;
|
|
45611
|
+
const key = id.toLowerCase();
|
|
45612
|
+
if (seen.has(key)) continue;
|
|
45613
|
+
seen.add(key);
|
|
45614
|
+
out.push(id);
|
|
45615
|
+
}
|
|
45616
|
+
return out;
|
|
45617
|
+
}
|
|
45618
|
+
var GITHUB_BLOCKED_BY_QUERY = `
|
|
45619
|
+
query($owner: String!, $name: String!, $number: Int!) {
|
|
45620
|
+
repository(owner: $owner, name: $name) {
|
|
45621
|
+
issue(number: $number) {
|
|
45622
|
+
blockedBy(first: 25) { nodes { number } }
|
|
45623
|
+
}
|
|
45624
|
+
}
|
|
45625
|
+
}
|
|
45626
|
+
`;
|
|
45627
|
+
async function getGitHubIssueBlockedBy(id, opts) {
|
|
45628
|
+
const number = parseGitHubIssueNumber(id);
|
|
45629
|
+
const { cwd, slug } = await resolveGitHubIssueRepo(opts?.repoPath);
|
|
45630
|
+
const [owner, name] = (slug ?? "").split("/");
|
|
45631
|
+
if (!owner || !name) throw new Error("GitHub repo is not connected");
|
|
45632
|
+
const result = await gh(
|
|
45633
|
+
[
|
|
45634
|
+
"api",
|
|
45635
|
+
"graphql",
|
|
45636
|
+
"-f",
|
|
45637
|
+
`query=${GITHUB_BLOCKED_BY_QUERY}`,
|
|
45638
|
+
"-f",
|
|
45639
|
+
`owner=${owner}`,
|
|
45640
|
+
"-f",
|
|
45641
|
+
`name=${name}`,
|
|
45642
|
+
"-F",
|
|
45643
|
+
`number=${number}`
|
|
45644
|
+
],
|
|
45645
|
+
cwd,
|
|
45646
|
+
{ reject: false }
|
|
45647
|
+
);
|
|
45648
|
+
if (result.exitCode !== 0) {
|
|
45649
|
+
const detail = (result.stderr || result.stdout).trim() || "gh failed";
|
|
45650
|
+
throw new Error(`GitHub issue #${number} blocked-by: ${detail}`);
|
|
45651
|
+
}
|
|
45652
|
+
let parsed;
|
|
45653
|
+
try {
|
|
45654
|
+
parsed = JSON.parse(result.stdout);
|
|
45655
|
+
} catch {
|
|
45656
|
+
throw new Error(`GitHub issue #${number} blocked-by: gh returned non-JSON`);
|
|
45657
|
+
}
|
|
45658
|
+
const errors = parsed && typeof parsed === "object" && Array.isArray(parsed.errors) ? parsed.errors : [];
|
|
45659
|
+
if (errors.length > 0) {
|
|
45660
|
+
throw new Error(
|
|
45661
|
+
`GitHub issue #${number} blocked-by: ${errors.map((e) => e.message ?? "GitHub error").join("; ")}`
|
|
45662
|
+
);
|
|
45663
|
+
}
|
|
45664
|
+
const issue = parsed.data?.repository?.issue;
|
|
45665
|
+
if (!issue) throw new Error(`GitHub issue not found: #${number}`);
|
|
45666
|
+
return githubBlockedByIdentifiers(parsed);
|
|
45667
|
+
}
|
|
45668
|
+
|
|
45669
|
+
// src/integrations/linear-blocked.ts
|
|
45670
|
+
var ISSUE_BLOCKED_BY_QUERY = `
|
|
45671
|
+
query SideboardIssueBlockedBy($id: String!) {
|
|
45672
|
+
issue(id: $id) {
|
|
45673
|
+
identifier
|
|
45674
|
+
relations(first: 25) {
|
|
45675
|
+
nodes { id type relatedIssue { id identifier } }
|
|
45676
|
+
}
|
|
45677
|
+
inverseRelations(first: 25) {
|
|
45678
|
+
nodes { id type issue { id identifier } }
|
|
45679
|
+
}
|
|
45680
|
+
}
|
|
45681
|
+
}
|
|
45682
|
+
`;
|
|
45683
|
+
function linearBlockedByIdentifiers(relations) {
|
|
45684
|
+
const out = [];
|
|
45685
|
+
const seen = /* @__PURE__ */ new Set();
|
|
45686
|
+
for (const rel of relations) {
|
|
45687
|
+
const type = (rel.type ?? "").trim().toLowerCase().replace(/[\s_-]+/g, "");
|
|
45688
|
+
if (type !== "blockedby" && type !== "blocked") continue;
|
|
45689
|
+
const id = (rel.issue?.identifier || rel.issue?.id || "").trim();
|
|
45690
|
+
const key = id.toLowerCase();
|
|
45691
|
+
if (!id || seen.has(key)) continue;
|
|
45692
|
+
seen.add(key);
|
|
45693
|
+
out.push(id);
|
|
45694
|
+
}
|
|
45695
|
+
return out;
|
|
45696
|
+
}
|
|
45697
|
+
function linearBlockedByRelations(issue) {
|
|
45698
|
+
const out = [];
|
|
45699
|
+
for (const rel of issue.relations?.nodes ?? []) {
|
|
45700
|
+
out.push({ type: String(rel.type ?? "related"), issue: rel.relatedIssue });
|
|
45701
|
+
}
|
|
45702
|
+
for (const rel of issue.inverseRelations?.nodes ?? []) {
|
|
45703
|
+
out.push({
|
|
45704
|
+
type: flipLinearRelationType(String(rel.type ?? "related")),
|
|
45705
|
+
issue: rel.issue
|
|
45706
|
+
});
|
|
45707
|
+
}
|
|
45708
|
+
return out;
|
|
45709
|
+
}
|
|
45710
|
+
async function getLinearIssueBlockedBy(id, opts) {
|
|
45711
|
+
const issueId = id.trim();
|
|
45712
|
+
if (!issueId) throw new Error("Linear issue id is required (uuid or ENG-123)");
|
|
45713
|
+
const json = await linearGraphql(
|
|
45714
|
+
ISSUE_BLOCKED_BY_QUERY,
|
|
45715
|
+
{ id: issueId },
|
|
45716
|
+
opts
|
|
45717
|
+
);
|
|
45718
|
+
if (!json.issue) throw new Error(`Linear issue not found: ${issueId}`);
|
|
45719
|
+
return linearBlockedByIdentifiers(linearBlockedByRelations(json.issue));
|
|
45720
|
+
}
|
|
45721
|
+
|
|
45722
|
+
// src/board/issue-blocked-sync.ts
|
|
45723
|
+
init_app_settings();
|
|
45724
|
+
init_thread_store();
|
|
45725
|
+
init_chat_tabs();
|
|
45726
|
+
function sourceTicketRef(thread) {
|
|
45727
|
+
if (thread.sourceType !== "ticket") return null;
|
|
45728
|
+
const ref = (thread.sourceRef ?? "").trim();
|
|
45729
|
+
return ref || null;
|
|
45730
|
+
}
|
|
45731
|
+
function sameIssueBlockedBy(current, next) {
|
|
45732
|
+
const left = new Set(
|
|
45733
|
+
(current ?? []).map((id) => id.trim().toLowerCase()).filter(Boolean)
|
|
45734
|
+
);
|
|
45735
|
+
const right = [...new Set(next.map((id) => id.trim().toLowerCase()).filter(Boolean))];
|
|
45736
|
+
if (left.size !== right.length) return false;
|
|
45737
|
+
return right.every((id) => left.has(id));
|
|
45738
|
+
}
|
|
45739
|
+
var TRACKER_KEY = /^[A-Za-z][A-Za-z0-9]+-\d+$/;
|
|
45740
|
+
function isGitHubIssueRef(ref) {
|
|
45741
|
+
return /^#?\d+$/.test(ref) || /^gh-\d+$/i.test(ref) || /github\.com\/[^/]+\/[^/]+\/issues\/\d+/i.test(ref);
|
|
45742
|
+
}
|
|
45743
|
+
function trackerForSourceTicket(ref, preferred, connected) {
|
|
45744
|
+
const trimmed = ref.trim();
|
|
45745
|
+
if (!trimmed) return null;
|
|
45746
|
+
if (isGitHubIssueRef(trimmed)) return "github";
|
|
45747
|
+
if (TRACKER_KEY.test(trimmed)) {
|
|
45748
|
+
if (preferred === "abletime" && connected.abletime) return "abletime";
|
|
45749
|
+
if (connected.linear) return "linear";
|
|
45750
|
+
if (connected.abletime) return "abletime";
|
|
45751
|
+
return null;
|
|
45752
|
+
}
|
|
45753
|
+
if (preferred === "linear" && connected.linear) return "linear";
|
|
45754
|
+
if (preferred === "abletime" && connected.abletime) return "abletime";
|
|
45755
|
+
if (preferred === "github") return "github";
|
|
45756
|
+
return null;
|
|
45757
|
+
}
|
|
45758
|
+
function defaultIssueBlockedLookup() {
|
|
45759
|
+
return {
|
|
45760
|
+
preferredSource: () => resolveEffectiveIssueSource(),
|
|
45761
|
+
linearConnected: () => isLinearConnected(),
|
|
45762
|
+
abletimeConnected: () => isAbleTimeConnected(),
|
|
45763
|
+
linear: (id) => getLinearIssueBlockedBy(id),
|
|
45764
|
+
github: (id, repoPath) => getGitHubIssueBlockedBy(id, { repoPath }),
|
|
45765
|
+
abletime: (id) => getAbleTimeIssueBlockedBy(id)
|
|
45766
|
+
};
|
|
45767
|
+
}
|
|
45768
|
+
async function lookupIssueBlockedBy(thread, lookup = defaultIssueBlockedLookup()) {
|
|
45769
|
+
const ref = sourceTicketRef(thread);
|
|
45770
|
+
if (!ref) return null;
|
|
45771
|
+
const tracker = trackerForSourceTicket(ref, lookup.preferredSource(), {
|
|
45772
|
+
linear: lookup.linearConnected(),
|
|
45773
|
+
abletime: lookup.abletimeConnected()
|
|
45774
|
+
});
|
|
45775
|
+
if (!tracker) return null;
|
|
45776
|
+
try {
|
|
45777
|
+
if (tracker === "linear") return await lookup.linear(ref);
|
|
45778
|
+
if (tracker === "abletime") return await lookup.abletime(ref);
|
|
45779
|
+
const repo = (thread.repoPath || thread.worktreePath || "").trim();
|
|
45780
|
+
return await lookup.github(ref, repo);
|
|
45781
|
+
} catch {
|
|
45782
|
+
return null;
|
|
45783
|
+
}
|
|
45784
|
+
}
|
|
45785
|
+
async function refreshWorktreeIssueBlocked(threadRef) {
|
|
45786
|
+
const thread = readThread(threadRef) ?? findThreadByRef(threadRef);
|
|
45787
|
+
if (!thread) throw new Error(`Thread not found: ${threadRef}`);
|
|
45788
|
+
const ids = await lookupIssueBlockedBy(thread);
|
|
45789
|
+
if (ids == null) return null;
|
|
45790
|
+
const siblings = thread.worktreePath ? threadsSharingWorktree(thread.worktreePath) : [];
|
|
45791
|
+
const targets = siblings.length > 0 ? siblings : [thread];
|
|
45792
|
+
for (const t of targets) {
|
|
45793
|
+
if (sameIssueBlockedBy(t.issueBlockedBy, ids)) continue;
|
|
45794
|
+
updateThread(t.id, { issueBlockedBy: ids });
|
|
45795
|
+
}
|
|
45796
|
+
return ids;
|
|
45797
|
+
}
|
|
45798
|
+
|
|
45799
|
+
// src/index.ts
|
|
45425
45800
|
init_config();
|
|
45426
45801
|
|
|
45427
45802
|
// src/brightsy/api.ts
|
|
@@ -47830,6 +48205,7 @@ async function pollSlackOutboundWatches(opts) {
|
|
|
47830
48205
|
getCaffeinateHold,
|
|
47831
48206
|
getClaudePlanUsage,
|
|
47832
48207
|
getDefaultAgent,
|
|
48208
|
+
getDefaultAutonomy,
|
|
47833
48209
|
getDefaultEffort,
|
|
47834
48210
|
getDefaultFast,
|
|
47835
48211
|
getDefaultModel,
|
|
@@ -48178,6 +48554,7 @@ async function pollSlackOutboundWatches(opts) {
|
|
|
48178
48554
|
recordSlackOutboundWatch,
|
|
48179
48555
|
refreshBrightsyAccessToken,
|
|
48180
48556
|
refreshGitHubAuth,
|
|
48557
|
+
refreshWorktreeIssueBlocked,
|
|
48181
48558
|
registerBrightsyOAuthClient,
|
|
48182
48559
|
registerPackagedUserMcpClients,
|
|
48183
48560
|
releaseCaffeinateHoldForThread,
|