@sideboard-ai/core 0.1.203 → 0.1.204
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-JFGZBDHH.js → abletime-S3UHQZVW.js} +3 -3
- package/dist/{abletime-SISJEPJ3.js → abletime-TONBQP4O.js} +3 -3
- package/dist/{abletime-oauth-7TD5Z2QV.js → abletime-oauth-AVCEO2DY.js} +54 -5
- package/dist/{abletime-oauth-OSQYFB3E.js → abletime-oauth-SD4SZY5U.js} +14 -2
- package/dist/{abletime-rest-QPJTDLKX.js → abletime-rest-6ODSXV7G.js} +2 -2
- package/dist/{abletime-rest-ZJGWYALM.js → abletime-rest-J2OBB4VA.js} +2 -2
- package/dist/agents/cursor-runner.js +1 -1
- package/dist/{agents-ZMWL43SP.js → agents-67K4BQFJ.js} +3 -3
- package/dist/{agents-3755WYQM.js → agents-BVOJNHV6.js} +4 -4
- package/dist/{chunk-6VEIKW5C.js → chunk-3K257PCS.js} +6 -3
- package/dist/{chunk-LCU6GBZP.js → chunk-5SMS6QTO.js} +1 -1
- package/dist/{chunk-MHPINQKY.js → chunk-6Q7DFVDQ.js} +54 -5
- package/dist/{chunk-3PYH2RLA.js → chunk-CYLDJWRK.js} +6 -3
- package/dist/{chunk-FZ6IBUKY.js → chunk-FO2NTJ7L.js} +3 -3
- package/dist/{chunk-2DVCCLII.js → chunk-FO45DMJ5.js} +60 -60
- package/dist/{chunk-CQ5R3VPP.js → chunk-KZ7PI7FE.js} +18 -0
- package/dist/{chunk-FZYYEMET.js → chunk-QAVWH2RQ.js} +3 -3
- package/dist/{chunk-QSEF2YVQ.js → chunk-QUW5D62C.js} +33 -19
- package/dist/{chunk-PJHFNFXA.js → chunk-SGUVAK66.js} +27 -8
- package/dist/{chunk-TZNJKZ2A.js → chunk-ULZLWQBS.js} +58 -58
- package/dist/{chunk-TNDUTGDV.js → chunk-VIPA75ZA.js} +1 -1
- package/dist/{chunk-BFEBFGCS.js → chunk-W6VM36YO.js} +30 -8
- package/dist/{chunk-X2TFUFIS.js → chunk-WF33LOP4.js} +43 -5
- package/dist/{chunk-CMGRV36E.js → chunk-WVATAIF4.js} +33 -19
- package/dist/{chunk-5IXJTUST.js → chunk-YOSTWSNC.js} +26 -6
- package/dist/{coordinator-prompt-U4PEZDAW.js → coordinator-prompt-NPT555BO.js} +2 -2
- package/dist/{coordinator-prompt-2B2JA2IE.js → coordinator-prompt-WEPXXLLX.js} +2 -2
- package/dist/{global-workspace-JPJ3FKKY.js → global-workspace-2I2T7FL5.js} +2 -2
- package/dist/{global-workspace-PU7ZS3LS.js → global-workspace-NSILADOM.js} +2 -2
- package/dist/index.cjs +237 -83
- package/dist/index.d.cts +33 -11
- package/dist/index.d.ts +33 -11
- package/dist/index.js +39 -9
- package/dist/mcp/run-stdio.cjs +192 -78
- package/dist/mcp/run-stdio.js +7 -7
- package/dist/{orchestrator-3A6KUTNI.js → orchestrator-CMAVNELS.js} +5 -5
- package/dist/{orchestrator-Q33M24ZJ.js → orchestrator-I7GFXLHF.js} +4 -4
- package/dist/{workspaces-IMG7ZRUQ.js → workspaces-BOC6M7BW.js} +2 -2
- package/dist/{workspaces-U6P6DB44.js → workspaces-RFGZBUAR.js} +2 -2
- package/dist/{worktree-JSCDJPBU.js → worktree-G3ZLM4DC.js} +3 -1
- package/dist/{worktree-FL3UIUKQ.js → worktree-WSUQMMK4.js} +3 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3298,6 +3298,9 @@ function humanizeAgentFailDetail(detail) {
|
|
|
3298
3298
|
if (/\[resource_exhausted\]|resource_exhausted|findfileswithripgrep/.test(lower)) {
|
|
3299
3299
|
return "Cursor local file search failed (ripgrep / resource_exhausted). Wait a minute and retry; if it keeps happening, check Cursor usage.";
|
|
3300
3300
|
}
|
|
3301
|
+
if (looksLikeCodexMcpError(raw)) {
|
|
3302
|
+
return `${raw} \u2014 skip that vendor MCP and continue (PostHog: Settings \u2192 Connectors + HTTP API).`;
|
|
3303
|
+
}
|
|
3301
3304
|
if (/invalid user api key|invalid api key|not logged in|not authenticated|unauthorized|authentication|please run.*login|codex login|claude auth|cursor api/.test(
|
|
3302
3305
|
lower
|
|
3303
3306
|
)) {
|
|
@@ -3355,9 +3358,24 @@ function turnFailChatText(opts) {
|
|
|
3355
3358
|
|
|
3356
3359
|
${fail6}`;
|
|
3357
3360
|
}
|
|
3361
|
+
function looksLikeCodexMcpError(text7) {
|
|
3362
|
+
const t = text7.trim().toLowerCase();
|
|
3363
|
+
if (!t) return false;
|
|
3364
|
+
if (/authrequired|authorization required/.test(t) && /mcp|posthog|rmcp|connector|plugin/.test(t)) {
|
|
3365
|
+
return true;
|
|
3366
|
+
}
|
|
3367
|
+
if (/\bposthog\b/.test(t) && /mcp|oauth|auth|unauthorized|401|plugin|app/.test(t)) {
|
|
3368
|
+
return true;
|
|
3369
|
+
}
|
|
3370
|
+
if (/\brmcp\b/.test(t) && /fatal|quit|transport|error|died|kill|auth/.test(t)) {
|
|
3371
|
+
return true;
|
|
3372
|
+
}
|
|
3373
|
+
return /mcp[_ -]?(server|tool|error|transport|client)/.test(t) && /fail|error|timeout|disconnect|auth|unauthorized/.test(t);
|
|
3374
|
+
}
|
|
3358
3375
|
function shouldFeedErrorBackToAgent(opts) {
|
|
3359
3376
|
const detail = opts.detail.trim();
|
|
3360
3377
|
const chat = (opts.assistantText ?? "").trim();
|
|
3378
|
+
if (looksLikeCodexMcpError(detail)) return true;
|
|
3361
3379
|
if (looksLikeAgentFailureMessage(detail) || looksLikeAgentFailureMessage(chat)) {
|
|
3362
3380
|
return false;
|
|
3363
3381
|
}
|
|
@@ -7728,6 +7746,7 @@ __export(worktree_exports, {
|
|
|
7728
7746
|
canonicalizeRepoPath: () => canonicalizeRepoPath,
|
|
7729
7747
|
collectTakenTeamSlugs: () => collectTakenTeamSlugs,
|
|
7730
7748
|
commitAll: () => commitAll,
|
|
7749
|
+
connectedPrSelectors: () => connectedPrSelectors,
|
|
7731
7750
|
countUnpushedVsOrigin: () => countUnpushedVsOrigin,
|
|
7732
7751
|
createExistingBranchWorktree: () => createExistingBranchWorktree,
|
|
7733
7752
|
createOrUpdatePr: () => createOrUpdatePr,
|
|
@@ -8061,26 +8080,21 @@ function resolvePrSelectors(thread) {
|
|
|
8061
8080
|
function resolvePrSelector(thread) {
|
|
8062
8081
|
return resolvePrSelectors(thread)[0] ?? null;
|
|
8063
8082
|
}
|
|
8083
|
+
function connectedPrSelectors(thread, currentHeadPrUrl) {
|
|
8084
|
+
const out = [];
|
|
8085
|
+
const push = (value) => {
|
|
8086
|
+
const v = value?.trim();
|
|
8087
|
+
if (!v || out.includes(v)) return;
|
|
8088
|
+
out.push(v);
|
|
8089
|
+
};
|
|
8090
|
+
push(currentHeadPrUrl);
|
|
8091
|
+
for (const selector of resolvePrSelectors(thread)) push(selector);
|
|
8092
|
+
return out;
|
|
8093
|
+
}
|
|
8064
8094
|
async function getPrForHeadBranch(repoPath, branch) {
|
|
8065
8095
|
const head = normalizeGitBranchName(branch);
|
|
8066
8096
|
if (!head || isDefaultishSourceRef(head)) return null;
|
|
8067
8097
|
const slug = await resolveGithubRepoSlug(repoPath);
|
|
8068
|
-
const viewArgs = [
|
|
8069
|
-
"pr",
|
|
8070
|
-
"view",
|
|
8071
|
-
head,
|
|
8072
|
-
"--json",
|
|
8073
|
-
"number,title,headRefName,url,isCrossRepository,author"
|
|
8074
|
-
];
|
|
8075
|
-
if (slug) viewArgs.push("--repo", slug);
|
|
8076
|
-
const viewed = await gh(viewArgs, repoPath, { reject: false });
|
|
8077
|
-
if (viewed.exitCode === 0 && viewed.stdout.trim()) {
|
|
8078
|
-
try {
|
|
8079
|
-
return JSON.parse(viewed.stdout);
|
|
8080
|
-
} catch {
|
|
8081
|
-
return null;
|
|
8082
|
-
}
|
|
8083
|
-
}
|
|
8084
8098
|
const listHead = slug ? ghHeadRef(slug, head) : head;
|
|
8085
8099
|
const listArgs = [
|
|
8086
8100
|
"pr",
|
|
@@ -8096,10 +8110,28 @@ async function getPrForHeadBranch(repoPath, branch) {
|
|
|
8096
8110
|
];
|
|
8097
8111
|
if (slug) listArgs.push("--repo", slug);
|
|
8098
8112
|
const listed = await gh(listArgs, repoPath, { reject: false });
|
|
8099
|
-
if (listed.exitCode
|
|
8113
|
+
if (listed.exitCode === 0 && listed.stdout.trim()) {
|
|
8114
|
+
try {
|
|
8115
|
+
const rows = JSON.parse(listed.stdout);
|
|
8116
|
+
if (rows[0]) return rows[0];
|
|
8117
|
+
} catch {
|
|
8118
|
+
}
|
|
8119
|
+
}
|
|
8120
|
+
const viewArgs = [
|
|
8121
|
+
"pr",
|
|
8122
|
+
"view",
|
|
8123
|
+
head,
|
|
8124
|
+
"--json",
|
|
8125
|
+
"number,title,headRefName,url,isCrossRepository,author,state"
|
|
8126
|
+
];
|
|
8127
|
+
if (slug) viewArgs.push("--repo", slug);
|
|
8128
|
+
const viewed = await gh(viewArgs, repoPath, { reject: false });
|
|
8129
|
+
if (viewed.exitCode !== 0 || !viewed.stdout.trim()) return null;
|
|
8100
8130
|
try {
|
|
8101
|
-
const
|
|
8102
|
-
|
|
8131
|
+
const info = JSON.parse(viewed.stdout);
|
|
8132
|
+
const state = (info.state ?? "OPEN").trim().toUpperCase();
|
|
8133
|
+
if (state !== "OPEN") return null;
|
|
8134
|
+
return info;
|
|
8103
8135
|
} catch {
|
|
8104
8136
|
return null;
|
|
8105
8137
|
}
|
|
@@ -12869,7 +12901,18 @@ function toCodexDisableUserMcpArgs(names) {
|
|
|
12869
12901
|
return args;
|
|
12870
12902
|
}
|
|
12871
12903
|
function toCodexUnattendedAppsArgs() {
|
|
12872
|
-
return [
|
|
12904
|
+
return [
|
|
12905
|
+
"-c",
|
|
12906
|
+
"features.apps=false",
|
|
12907
|
+
"-c",
|
|
12908
|
+
"apps._default.enabled=false",
|
|
12909
|
+
"-c",
|
|
12910
|
+
"apps.posthog.enabled=false",
|
|
12911
|
+
"-c",
|
|
12912
|
+
"features.plugins=false",
|
|
12913
|
+
"-c",
|
|
12914
|
+
"mcp_servers.posthog.enabled=false"
|
|
12915
|
+
];
|
|
12873
12916
|
}
|
|
12874
12917
|
var import_node_fs32, import_node_os11, import_node_path33, import_smol_toml2;
|
|
12875
12918
|
var init_orch_mcp_isolation = __esm({
|
|
@@ -14620,11 +14663,14 @@ function staleOk(now) {
|
|
|
14620
14663
|
if (now - lastGood.at > CLAUDE_USAGE_STALE_OK_MS) return null;
|
|
14621
14664
|
return lastGood.value;
|
|
14622
14665
|
}
|
|
14666
|
+
function reuseLast() {
|
|
14667
|
+
return lastGood?.value ?? null;
|
|
14668
|
+
}
|
|
14623
14669
|
async function getClaudePlanUsage(opts = {}) {
|
|
14624
14670
|
const now = opts.now ?? Date.now();
|
|
14671
|
+
if (now < errorUntil) return reuseLast() ?? staleOk(now);
|
|
14625
14672
|
if (!opts.force) {
|
|
14626
14673
|
if (cache && now - cache.at < CLAUDE_USAGE_TTL_MS) return cache.value;
|
|
14627
|
-
if (now < errorUntil) return staleOk(now);
|
|
14628
14674
|
}
|
|
14629
14675
|
if (inflight) return inflight;
|
|
14630
14676
|
inflight = (async () => {
|
|
@@ -14655,6 +14701,12 @@ async function getClaudePlanUsage(opts = {}) {
|
|
|
14655
14701
|
cache = { at: now, value: null };
|
|
14656
14702
|
return null;
|
|
14657
14703
|
}
|
|
14704
|
+
if (res.status === 429) {
|
|
14705
|
+
errorUntil = now + CLAUDE_USAGE_ERROR_TTL_MS;
|
|
14706
|
+
const last = reuseLast();
|
|
14707
|
+
if (last) cache = { at: now, value: last };
|
|
14708
|
+
return last;
|
|
14709
|
+
}
|
|
14658
14710
|
if (!res.ok) {
|
|
14659
14711
|
errorUntil = now + CLAUDE_USAGE_ERROR_TTL_MS;
|
|
14660
14712
|
return staleOk(now);
|
|
@@ -15415,6 +15467,33 @@ var init_agent_git_actions = __esm({
|
|
|
15415
15467
|
function normalizePrState(state) {
|
|
15416
15468
|
return (state ?? "").trim().toUpperCase();
|
|
15417
15469
|
}
|
|
15470
|
+
function sameLoginList(a, b) {
|
|
15471
|
+
const left = [...a ?? []].map((s) => s.trim().toLowerCase()).filter(Boolean).sort();
|
|
15472
|
+
const right = [...b ?? []].map((s) => s.trim().toLowerCase()).filter(Boolean).sort();
|
|
15473
|
+
return left.length === right.length && left.every((login, i) => login === right[i]);
|
|
15474
|
+
}
|
|
15475
|
+
function threadPrMetaPatch(thread, meta) {
|
|
15476
|
+
const prevState = normalizePrState(thread.prState);
|
|
15477
|
+
const nextState = normalizePrState(meta.state);
|
|
15478
|
+
const patch = {};
|
|
15479
|
+
if (meta.url && meta.url !== thread.prUrl) patch.prUrl = meta.url;
|
|
15480
|
+
if (meta.title && meta.title !== thread.prTitle) patch.prTitle = meta.title;
|
|
15481
|
+
if (nextState && nextState !== prevState) patch.prState = nextState;
|
|
15482
|
+
const nextDraft = Boolean(meta.isDraft) && nextState !== "MERGED" && nextState !== "CLOSED";
|
|
15483
|
+
if (nextDraft !== Boolean(thread.prIsDraft)) patch.prIsDraft = nextDraft;
|
|
15484
|
+
const nextAuthor = meta.authorLogin?.trim() || "";
|
|
15485
|
+
if (nextAuthor && nextAuthor !== (thread.prAuthorLogin ?? "").trim()) {
|
|
15486
|
+
patch.prAuthorLogin = nextAuthor;
|
|
15487
|
+
}
|
|
15488
|
+
const nextReviewers = meta.reviewerLogins ?? [];
|
|
15489
|
+
if (!sameLoginList(nextReviewers, thread.prReviewerLogins)) {
|
|
15490
|
+
patch.prReviewerLogins = nextReviewers;
|
|
15491
|
+
}
|
|
15492
|
+
if (thread.skipAutoArchiveOnMerge && nextState && nextState !== "MERGED" && nextState !== "CLOSED") {
|
|
15493
|
+
patch.skipAutoArchiveOnMerge = false;
|
|
15494
|
+
}
|
|
15495
|
+
return patch;
|
|
15496
|
+
}
|
|
15418
15497
|
function shouldAutoArchiveOnPrMerge(opts) {
|
|
15419
15498
|
if (!opts.autoArchiveEnabled) return false;
|
|
15420
15499
|
if (opts.isGlobal) return false;
|
|
@@ -17497,21 +17576,67 @@ var init_detect = __esm({
|
|
|
17497
17576
|
// src/integrations/abletime-oauth.ts
|
|
17498
17577
|
var abletime_oauth_exports = {};
|
|
17499
17578
|
__export(abletime_oauth_exports, {
|
|
17579
|
+
ABLETIME_OAUTH_CALLBACK_PATH: () => ABLETIME_OAUTH_CALLBACK_PATH,
|
|
17500
17580
|
ABLETIME_OAUTH_CANCELLED: () => ABLETIME_OAUTH_CANCELLED,
|
|
17581
|
+
ABLETIME_OAUTH_LOCAL_CALLBACK: () => ABLETIME_OAUTH_LOCAL_CALLBACK,
|
|
17501
17582
|
ABLETIME_OAUTH_PORT: () => ABLETIME_OAUTH_PORT,
|
|
17502
17583
|
ABLETIME_OAUTH_REDIRECT: () => ABLETIME_OAUTH_REDIRECT,
|
|
17503
17584
|
ABLETIME_OAUTH_RESOURCE: () => ABLETIME_OAUTH_RESOURCE,
|
|
17504
17585
|
AbleTimeOAuthCancelledError: () => AbleTimeOAuthCancelledError,
|
|
17505
17586
|
BAKED_ABLETIME_OAUTH_CLIENT_ID: () => BAKED_ABLETIME_OAUTH_CLIENT_ID,
|
|
17506
17587
|
ableTimeOAuthAuthorizeUrl: () => ableTimeOAuthAuthorizeUrl,
|
|
17588
|
+
ableTimeOAuthBouncePage: () => ableTimeOAuthBouncePage,
|
|
17507
17589
|
ableTimeOAuthClientId: () => ableTimeOAuthClientId,
|
|
17590
|
+
ableTimeOAuthLocalBounceUrl: () => ableTimeOAuthLocalBounceUrl,
|
|
17591
|
+
ableTimeOAuthRedirectUri: () => ableTimeOAuthRedirectUri,
|
|
17508
17592
|
ableTimeOAuthResource: () => ableTimeOAuthResource,
|
|
17509
17593
|
createAbleTimePkce: () => createAbleTimePkce,
|
|
17510
17594
|
ensureAbleTimeAccessToken: () => ensureAbleTimeAccessToken,
|
|
17511
17595
|
hasBakedAbleTimeOAuth: () => hasBakedAbleTimeOAuth,
|
|
17512
17596
|
isAbleTimeOAuthCancelled: () => isAbleTimeOAuthCancelled,
|
|
17597
|
+
parseAbleTimeOAuthCallbackUrl: () => parseAbleTimeOAuthCallbackUrl,
|
|
17513
17598
|
startAbleTimeOAuth: () => startAbleTimeOAuth
|
|
17514
17599
|
});
|
|
17600
|
+
function ableTimeOAuthRedirectUri() {
|
|
17601
|
+
return process.env.SIDEBOARD_ABLETIME_OAUTH_REDIRECT?.trim() || ABLETIME_OAUTH_REDIRECT;
|
|
17602
|
+
}
|
|
17603
|
+
function parseAbleTimeOAuthCallbackUrl(reqUrl) {
|
|
17604
|
+
let url;
|
|
17605
|
+
try {
|
|
17606
|
+
url = new URL(reqUrl, ABLETIME_OAUTH_REDIRECT);
|
|
17607
|
+
} catch {
|
|
17608
|
+
return null;
|
|
17609
|
+
}
|
|
17610
|
+
if (url.pathname !== ABLETIME_OAUTH_CALLBACK_PATH) return null;
|
|
17611
|
+
return url;
|
|
17612
|
+
}
|
|
17613
|
+
function ableTimeOAuthLocalBounceUrl(reqUrl) {
|
|
17614
|
+
const url = parseAbleTimeOAuthCallbackUrl(reqUrl);
|
|
17615
|
+
if (!url) return null;
|
|
17616
|
+
const dest = new URL(ABLETIME_OAUTH_LOCAL_CALLBACK);
|
|
17617
|
+
for (const key of BOUNCE_QUERY_KEYS) {
|
|
17618
|
+
const value = url.searchParams.get(key);
|
|
17619
|
+
if (value) dest.searchParams.set(key, value);
|
|
17620
|
+
}
|
|
17621
|
+
return dest.toString();
|
|
17622
|
+
}
|
|
17623
|
+
function escapeHtml(value) {
|
|
17624
|
+
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
17625
|
+
}
|
|
17626
|
+
function ableTimeOAuthBouncePage(localUrl) {
|
|
17627
|
+
const safe = escapeHtml(localUrl);
|
|
17628
|
+
return `<!doctype html><html><head><meta charset="utf-8">
|
|
17629
|
+
<meta http-equiv="refresh" content="0;url=${safe}">
|
|
17630
|
+
<title>Returning to Sideboard</title>
|
|
17631
|
+
<script>location.replace(${JSON.stringify(localUrl)})</script>
|
|
17632
|
+
<style>body{font-family:ui-sans-serif,system-ui,sans-serif;padding:48px 24px;max-width:36rem;margin:0 auto;color:#1a1a1a}
|
|
17633
|
+
h1{font-size:1.25rem}p{line-height:1.5;color:#444}a{color:#0f7ed4}</style>
|
|
17634
|
+
</head><body>
|
|
17635
|
+
<h1>Returning to Sideboard</h1>
|
|
17636
|
+
<p>AbleTime authorized. Opening the app\u2026</p>
|
|
17637
|
+
<p><a href="${safe}">Open Sideboard</a> if it does not appear.</p>
|
|
17638
|
+
</body></html>`;
|
|
17639
|
+
}
|
|
17515
17640
|
function hasBakedAbleTimeOAuth() {
|
|
17516
17641
|
return Boolean(BAKED_ABLETIME_OAUTH_CLIENT_ID.trim());
|
|
17517
17642
|
}
|
|
@@ -17531,7 +17656,7 @@ function ableTimeOAuthAuthorizeUrl(clientId, state, codeChallenge, host) {
|
|
|
17531
17656
|
const params = new URLSearchParams({
|
|
17532
17657
|
response_type: "code",
|
|
17533
17658
|
client_id: clientId,
|
|
17534
|
-
redirect_uri:
|
|
17659
|
+
redirect_uri: ableTimeOAuthRedirectUri(),
|
|
17535
17660
|
code_challenge: codeChallenge,
|
|
17536
17661
|
code_challenge_method: "S256",
|
|
17537
17662
|
state,
|
|
@@ -17703,7 +17828,7 @@ async function startAbleTimeOAuth(opts) {
|
|
|
17703
17828
|
const body = new URLSearchParams({
|
|
17704
17829
|
grant_type: "authorization_code",
|
|
17705
17830
|
code,
|
|
17706
|
-
redirect_uri:
|
|
17831
|
+
redirect_uri: ableTimeOAuthRedirectUri(),
|
|
17707
17832
|
client_id: clientId,
|
|
17708
17833
|
code_verifier: pkce.verifier,
|
|
17709
17834
|
resource: ableTimeOAuthResource(host)
|
|
@@ -17725,7 +17850,7 @@ async function startAbleTimeOAuth(opts) {
|
|
|
17725
17850
|
return loadAppSettings();
|
|
17726
17851
|
}
|
|
17727
17852
|
}
|
|
17728
|
-
var import_node_crypto10, import_node_http, ABLETIME_OAUTH_PORT, ABLETIME_OAUTH_REDIRECT, BAKED_ABLETIME_OAUTH_CLIENT_ID, ABLETIME_OAUTH_RESOURCE, REFRESH_SKEW_MS2, refreshInFlight, ABLETIME_OAUTH_CANCELLED, AbleTimeOAuthCancelledError;
|
|
17853
|
+
var import_node_crypto10, import_node_http, ABLETIME_OAUTH_CALLBACK_PATH, ABLETIME_OAUTH_PORT, ABLETIME_OAUTH_LOCAL_CALLBACK, ABLETIME_OAUTH_REDIRECT, BOUNCE_QUERY_KEYS, BAKED_ABLETIME_OAUTH_CLIENT_ID, ABLETIME_OAUTH_RESOURCE, REFRESH_SKEW_MS2, refreshInFlight, ABLETIME_OAUTH_CANCELLED, AbleTimeOAuthCancelledError;
|
|
17729
17854
|
var init_abletime_oauth = __esm({
|
|
17730
17855
|
"src/integrations/abletime-oauth.ts"() {
|
|
17731
17856
|
"use strict";
|
|
@@ -17734,8 +17859,11 @@ var init_abletime_oauth = __esm({
|
|
|
17734
17859
|
init_fetch();
|
|
17735
17860
|
init_app_settings();
|
|
17736
17861
|
init_abletime_mcp();
|
|
17862
|
+
ABLETIME_OAUTH_CALLBACK_PATH = "/oauth/abletime/callback";
|
|
17737
17863
|
ABLETIME_OAUTH_PORT = 19849;
|
|
17738
|
-
|
|
17864
|
+
ABLETIME_OAUTH_LOCAL_CALLBACK = `http://127.0.0.1:${ABLETIME_OAUTH_PORT}/callback`;
|
|
17865
|
+
ABLETIME_OAUTH_REDIRECT = `https://www.sideboard.cloud${ABLETIME_OAUTH_CALLBACK_PATH}`;
|
|
17866
|
+
BOUNCE_QUERY_KEYS = ["code", "state", "error", "error_description"];
|
|
17739
17867
|
BAKED_ABLETIME_OAUTH_CLIENT_ID = "https://www.sideboard.cloud/oauth/abletime-client.json";
|
|
17740
17868
|
ABLETIME_OAUTH_RESOURCE = `${DEFAULT_ABLETIME_HOST}/api/public/v2/mcp`;
|
|
17741
17869
|
REFRESH_SKEW_MS2 = 5 * 6e4;
|
|
@@ -17989,8 +18117,11 @@ function firstStringArg(args, keys) {
|
|
|
17989
18117
|
}
|
|
17990
18118
|
async function callAbleTimeRestTool(name, args = {}, opts) {
|
|
17991
18119
|
const token = normalizeAbleTimeCredential(opts?.token ?? getAbleTimeAccessToken() ?? "");
|
|
17992
|
-
if (
|
|
17993
|
-
throw new Error("AbleTime
|
|
18120
|
+
if (!token) {
|
|
18121
|
+
throw new Error("AbleTime is not connected \u2014 paste an API key or connect via browser");
|
|
18122
|
+
}
|
|
18123
|
+
if (ableTimeCredentialKind(token) === "pat") {
|
|
18124
|
+
throw new Error("AbleTime REST transport is for organization keys and OAuth tokens, not apt_\u2026");
|
|
17994
18125
|
}
|
|
17995
18126
|
const requestOpts = { ...opts, token };
|
|
17996
18127
|
switch (name) {
|
|
@@ -18150,11 +18281,25 @@ function normalizeAbleTimeCredential(raw) {
|
|
|
18150
18281
|
return raw.trim().replace(/^bearer\s+/i, "").trim();
|
|
18151
18282
|
}
|
|
18152
18283
|
function ableTimeCredentialKind(raw) {
|
|
18153
|
-
const token = normalizeAbleTimeCredential(raw)
|
|
18154
|
-
|
|
18155
|
-
if (
|
|
18284
|
+
const token = normalizeAbleTimeCredential(raw);
|
|
18285
|
+
const lower = token.toLowerCase();
|
|
18286
|
+
if (lower.startsWith(ABLETIME_PAT_PREFIX)) return "pat";
|
|
18287
|
+
if (lower.startsWith(ABLETIME_ORG_KEY_PREFIX)) return "org";
|
|
18288
|
+
if (lower.startsWith(ABLETIME_OAUTH_TOKEN_PREFIX) || token.startsWith("eyJ")) return "oauth";
|
|
18156
18289
|
return "unknown";
|
|
18157
18290
|
}
|
|
18291
|
+
function ableTimeUsesRest(raw) {
|
|
18292
|
+
const token = normalizeAbleTimeCredential(raw);
|
|
18293
|
+
const kind = ableTimeCredentialKind(token);
|
|
18294
|
+
if (kind === "org") return true;
|
|
18295
|
+
if (kind === "oauth") return token.startsWith("eyJ");
|
|
18296
|
+
return kind === "unknown";
|
|
18297
|
+
}
|
|
18298
|
+
function isAbleTimeRejectedCredential(message) {
|
|
18299
|
+
return /INTEGRATION_KEY_INVALID|INTEGRATION_KEY_MISSING|INTEGRATION_PAT_REQUIRED|\b401\b/i.test(
|
|
18300
|
+
message
|
|
18301
|
+
);
|
|
18302
|
+
}
|
|
18158
18303
|
function assertAbleTimeMcpCredential(raw) {
|
|
18159
18304
|
const token = normalizeAbleTimeCredential(raw);
|
|
18160
18305
|
if (!token) {
|
|
@@ -18316,7 +18461,7 @@ async function callAbleTimeTool(name, args = {}, opts) {
|
|
|
18316
18461
|
throw new Error("AbleTime is not connected \u2014 paste a personal access token in Account settings");
|
|
18317
18462
|
}
|
|
18318
18463
|
const rawToken = opts?.token ?? await Promise.resolve().then(() => (init_abletime_oauth(), abletime_oauth_exports)).then((m) => m.ensureAbleTimeAccessToken());
|
|
18319
|
-
if (rawToken &&
|
|
18464
|
+
if (rawToken && ableTimeUsesRest(rawToken)) {
|
|
18320
18465
|
const { callAbleTimeRestTool: callAbleTimeRestTool2 } = await Promise.resolve().then(() => (init_abletime_rest(), abletime_rest_exports));
|
|
18321
18466
|
return callAbleTimeRestTool2(name, args, { ...opts, token: rawToken });
|
|
18322
18467
|
}
|
|
@@ -18332,10 +18477,14 @@ async function callAbleTimeTool(name, args = {}, opts) {
|
|
|
18332
18477
|
await initializeIfNeeded(requestOpts);
|
|
18333
18478
|
return await call();
|
|
18334
18479
|
}
|
|
18480
|
+
if (rawToken && ableTimeUsesRest(rawToken) && isAbleTimeRejectedCredential(message)) {
|
|
18481
|
+
const { callAbleTimeRestTool: callAbleTimeRestTool2 } = await Promise.resolve().then(() => (init_abletime_rest(), abletime_rest_exports));
|
|
18482
|
+
return callAbleTimeRestTool2(name, args, { ...opts, token: rawToken });
|
|
18483
|
+
}
|
|
18335
18484
|
throw err instanceof Error ? new Error(rewriteAbleTimeError(err.message)) : err;
|
|
18336
18485
|
}
|
|
18337
18486
|
}
|
|
18338
|
-
var DEFAULT_ABLETIME_HOST, ABLETIME_MCP_PATH, ABLETIME_MCP_PM_PATH, MCP_PROTOCOL_VERSION, ABLETIME_PM_TOOL_NAMES, ABLETIME_PAT_PREFIX, ABLETIME_ORG_KEY_PREFIX, ORG_KEY_HINT, REJECTED_CREDENTIAL_HINT, REWRITE_APPLIED;
|
|
18487
|
+
var DEFAULT_ABLETIME_HOST, ABLETIME_MCP_PATH, ABLETIME_MCP_PM_PATH, MCP_PROTOCOL_VERSION, ABLETIME_PM_TOOL_NAMES, ABLETIME_PAT_PREFIX, ABLETIME_ORG_KEY_PREFIX, ABLETIME_OAUTH_TOKEN_PREFIX, ORG_KEY_HINT, REJECTED_CREDENTIAL_HINT, REWRITE_APPLIED;
|
|
18339
18488
|
var init_abletime_mcp = __esm({
|
|
18340
18489
|
"src/integrations/abletime-mcp.ts"() {
|
|
18341
18490
|
"use strict";
|
|
@@ -18359,8 +18508,9 @@ var init_abletime_mcp = __esm({
|
|
|
18359
18508
|
];
|
|
18360
18509
|
ABLETIME_PAT_PREFIX = "apt_";
|
|
18361
18510
|
ABLETIME_ORG_KEY_PREFIX = "atk_";
|
|
18511
|
+
ABLETIME_OAUTH_TOKEN_PREFIX = "acn_";
|
|
18362
18512
|
ORG_KEY_HINT = "AbleTime MCP needs a personal access token (apt_\u2026) from Edit Profile \u2192 API Access, not an organization API key (atk_\u2026) from Settings \u2192 Integrations \u2192 API Keys.";
|
|
18363
|
-
REJECTED_CREDENTIAL_HINT = "AbleTime rejected this credential (unknown, revoked, or expired).
|
|
18513
|
+
REJECTED_CREDENTIAL_HINT = "AbleTime rejected this credential (unknown, revoked, or expired). Reconnect via browser, or paste a personal access token (apt_\u2026) from Edit Profile \u2192 API Access. Organization API keys (atk_\u2026) use REST, not MCP.";
|
|
18364
18514
|
REWRITE_APPLIED = /— Enable Agent access \(MCP\)|— AbleTime MCP needs a personal access token|— AbleTime plan does not include API access|— AbleTime rejected this credential/;
|
|
18365
18515
|
}
|
|
18366
18516
|
});
|
|
@@ -18542,7 +18692,7 @@ function isOpenTask(task) {
|
|
|
18542
18692
|
async function getAbleTimeOrientation(opts) {
|
|
18543
18693
|
const raw = await callAbleTimeTool("orientation", {}, opts);
|
|
18544
18694
|
const record = asRecord7(raw);
|
|
18545
|
-
const viewerRec = firstRecord(record, ["viewer", "user", "actor", "me", "person"]) ?? record;
|
|
18695
|
+
const viewerRec = firstRecord(record, ["viewer", "principal", "user", "actor", "me", "person"]) ?? record;
|
|
18546
18696
|
const viewer = {
|
|
18547
18697
|
id: firstString(viewerRec, ["id", "user_id"]) || void 0,
|
|
18548
18698
|
name: firstString(viewerRec, ["name", "display_name", "full_name"]) || firstString(record, ["name"]) || void 0
|
|
@@ -22237,11 +22387,6 @@ function isPidAlive(pid) {
|
|
|
22237
22387
|
return false;
|
|
22238
22388
|
}
|
|
22239
22389
|
}
|
|
22240
|
-
function sameLoginList(a, b) {
|
|
22241
|
-
const left = [...a ?? []].map((s) => s.trim().toLowerCase()).filter(Boolean).sort();
|
|
22242
|
-
const right = [...b ?? []].map((s) => s.trim().toLowerCase()).filter(Boolean).sort();
|
|
22243
|
-
return left.length === right.length && left.every((login, i) => login === right[i]);
|
|
22244
|
-
}
|
|
22245
22390
|
async function waitForPidExit(pid, timeoutMs) {
|
|
22246
22391
|
const start = Date.now();
|
|
22247
22392
|
while (isPidAlive(pid)) {
|
|
@@ -24080,12 +24225,18 @@ var init_orchestrator = __esm({
|
|
|
24080
24225
|
/** Resolve PR selectors and optionally persist `prUrl` when found. */
|
|
24081
24226
|
async withPrSelector(threadRef) {
|
|
24082
24227
|
const thread = this.requireThread(threadRef);
|
|
24083
|
-
const selectors = resolvePrSelectors(thread);
|
|
24084
24228
|
const cwd = thread.worktreePath;
|
|
24085
24229
|
if (!cwd?.trim()) {
|
|
24086
24230
|
throw new Error(`Thread ${threadRef} has no worktreePath`);
|
|
24087
24231
|
}
|
|
24088
|
-
|
|
24232
|
+
let headUrl = null;
|
|
24233
|
+
try {
|
|
24234
|
+
const head = await getPrForHeadBranch(cwd, thread.branchName);
|
|
24235
|
+
headUrl = head?.url?.trim() || null;
|
|
24236
|
+
} catch {
|
|
24237
|
+
headUrl = null;
|
|
24238
|
+
}
|
|
24239
|
+
return { thread, selectors: connectedPrSelectors(thread, headUrl), cwd };
|
|
24089
24240
|
}
|
|
24090
24241
|
async getPrChecks(threadRef) {
|
|
24091
24242
|
const { selectors, cwd } = await this.withPrSelector(threadRef);
|
|
@@ -24113,29 +24264,16 @@ var init_orchestrator = __esm({
|
|
|
24113
24264
|
async persistPrMetaAndMaybeArchive(thread, meta) {
|
|
24114
24265
|
const prevState = normalizePrState(thread.prState);
|
|
24115
24266
|
const nextState = normalizePrState(meta.state);
|
|
24116
|
-
const
|
|
24117
|
-
|
|
24118
|
-
|
|
24119
|
-
|
|
24120
|
-
|
|
24121
|
-
|
|
24122
|
-
const nextAuthor = meta.authorLogin?.trim() || "";
|
|
24123
|
-
if (nextAuthor && nextAuthor !== (thread.prAuthorLogin ?? "").trim()) {
|
|
24124
|
-
patch.prAuthorLogin = nextAuthor;
|
|
24125
|
-
}
|
|
24126
|
-
const nextReviewers = meta.reviewerLogins ?? [];
|
|
24127
|
-
if (!sameLoginList(nextReviewers, thread.prReviewerLogins)) {
|
|
24128
|
-
patch.prReviewerLogins = nextReviewers;
|
|
24267
|
+
const siblings = threadsSharingWorktree(thread.worktreePath);
|
|
24268
|
+
const targets = siblings.length > 0 ? siblings : [thread];
|
|
24269
|
+
for (const t of targets) {
|
|
24270
|
+
const patch = threadPrMetaPatch(t, meta);
|
|
24271
|
+
if (Object.keys(patch).length === 0) continue;
|
|
24272
|
+
updateThread(t.id, patch);
|
|
24129
24273
|
}
|
|
24130
|
-
|
|
24131
|
-
|
|
24132
|
-
|
|
24133
|
-
if (Object.keys(patch).length > 0) {
|
|
24134
|
-
updateThread(thread.id, patch);
|
|
24135
|
-
const latest2 = this.requireThread(thread.id);
|
|
24136
|
-
if (!latest2.userSetTitle && meta.title && latest2.title !== meta.title) {
|
|
24137
|
-
updateThread(thread.id, { title: meta.title });
|
|
24138
|
-
}
|
|
24274
|
+
const titled = this.requireThread(thread.id);
|
|
24275
|
+
if (!titled.userSetTitle && meta.title && titled.title !== meta.title) {
|
|
24276
|
+
updateThread(thread.id, { title: meta.title });
|
|
24139
24277
|
}
|
|
24140
24278
|
const { autoArchiveOnMergeEnabled: autoArchiveOnMergeEnabled2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
|
|
24141
24279
|
const latest = this.requireThread(thread.id);
|
|
@@ -24149,22 +24287,7 @@ var init_orchestrator = __esm({
|
|
|
24149
24287
|
})) {
|
|
24150
24288
|
return;
|
|
24151
24289
|
}
|
|
24152
|
-
const
|
|
24153
|
-
for (const t of siblings) {
|
|
24154
|
-
const sibPatch = { prState: "MERGED", prIsDraft: false };
|
|
24155
|
-
if (meta.url && meta.url !== t.prUrl) sibPatch.prUrl = meta.url;
|
|
24156
|
-
if (meta.title && meta.title !== t.prTitle) sibPatch.prTitle = meta.title;
|
|
24157
|
-
const sibAuthor = meta.authorLogin?.trim() || "";
|
|
24158
|
-
if (sibAuthor && sibAuthor !== (t.prAuthorLogin ?? "").trim()) {
|
|
24159
|
-
sibPatch.prAuthorLogin = sibAuthor;
|
|
24160
|
-
}
|
|
24161
|
-
const sibReviewers = meta.reviewerLogins ?? [];
|
|
24162
|
-
if (!sameLoginList(sibReviewers, t.prReviewerLogins)) {
|
|
24163
|
-
sibPatch.prReviewerLogins = sibReviewers;
|
|
24164
|
-
}
|
|
24165
|
-
if (Object.keys(sibPatch).length > 0) updateThread(t.id, sibPatch);
|
|
24166
|
-
}
|
|
24167
|
-
for (const t of siblings) {
|
|
24290
|
+
for (const t of threadsSharingWorktree(latest.worktreePath)) {
|
|
24168
24291
|
if (this.requireThread(t.id).status === "archived") continue;
|
|
24169
24292
|
await this.archive(t.id);
|
|
24170
24293
|
}
|
|
@@ -24682,10 +24805,13 @@ var index_exports = {};
|
|
|
24682
24805
|
__export(index_exports, {
|
|
24683
24806
|
ABLETIME_MCP_PATH: () => ABLETIME_MCP_PATH,
|
|
24684
24807
|
ABLETIME_MCP_PM_PATH: () => ABLETIME_MCP_PM_PATH,
|
|
24808
|
+
ABLETIME_OAUTH_CALLBACK_PATH: () => ABLETIME_OAUTH_CALLBACK_PATH,
|
|
24685
24809
|
ABLETIME_OAUTH_CANCELLED: () => ABLETIME_OAUTH_CANCELLED,
|
|
24810
|
+
ABLETIME_OAUTH_LOCAL_CALLBACK: () => ABLETIME_OAUTH_LOCAL_CALLBACK,
|
|
24686
24811
|
ABLETIME_OAUTH_PORT: () => ABLETIME_OAUTH_PORT,
|
|
24687
24812
|
ABLETIME_OAUTH_REDIRECT: () => ABLETIME_OAUTH_REDIRECT,
|
|
24688
24813
|
ABLETIME_OAUTH_RESOURCE: () => ABLETIME_OAUTH_RESOURCE,
|
|
24814
|
+
ABLETIME_OAUTH_TOKEN_PREFIX: () => ABLETIME_OAUTH_TOKEN_PREFIX,
|
|
24689
24815
|
ABLETIME_ORG_KEY_PREFIX: () => ABLETIME_ORG_KEY_PREFIX,
|
|
24690
24816
|
ABLETIME_PAT_PREFIX: () => ABLETIME_PAT_PREFIX,
|
|
24691
24817
|
ABLETIME_PM_TOOL_NAMES: () => ABLETIME_PM_TOOL_NAMES,
|
|
@@ -24785,8 +24911,12 @@ __export(index_exports, {
|
|
|
24785
24911
|
ableTimeCredentialKind: () => ableTimeCredentialKind,
|
|
24786
24912
|
ableTimeDependencyTarget: () => ableTimeDependencyTarget,
|
|
24787
24913
|
ableTimeOAuthAuthorizeUrl: () => ableTimeOAuthAuthorizeUrl,
|
|
24914
|
+
ableTimeOAuthBouncePage: () => ableTimeOAuthBouncePage,
|
|
24788
24915
|
ableTimeOAuthClientId: () => ableTimeOAuthClientId,
|
|
24916
|
+
ableTimeOAuthLocalBounceUrl: () => ableTimeOAuthLocalBounceUrl,
|
|
24917
|
+
ableTimeOAuthRedirectUri: () => ableTimeOAuthRedirectUri,
|
|
24789
24918
|
ableTimeOAuthResource: () => ableTimeOAuthResource,
|
|
24919
|
+
ableTimeUsesRest: () => ableTimeUsesRest,
|
|
24790
24920
|
abletimeMcpRequest: () => abletimeMcpRequest,
|
|
24791
24921
|
abletimeMcpUrl: () => abletimeMcpUrl,
|
|
24792
24922
|
abletimeToolUsesPm: () => abletimeToolUsesPm,
|
|
@@ -24891,6 +25021,7 @@ __export(index_exports, {
|
|
|
24891
25021
|
connectOptionalService: () => connectOptionalService,
|
|
24892
25022
|
connectSlackToken: () => connectSlackToken,
|
|
24893
25023
|
connectedOptionalServices: () => connectedOptionalServices,
|
|
25024
|
+
connectedPrSelectors: () => connectedPrSelectors,
|
|
24894
25025
|
contextTokens: () => contextTokens,
|
|
24895
25026
|
coordinatorSystemPrompt: () => coordinatorSystemPrompt,
|
|
24896
25027
|
coordinatorTurnReminder: () => coordinatorTurnReminder,
|
|
@@ -25111,6 +25242,7 @@ __export(index_exports, {
|
|
|
25111
25242
|
invalidateThreadRecord: () => invalidateThreadRecord,
|
|
25112
25243
|
isAbleTimeConnected: () => isAbleTimeConnected,
|
|
25113
25244
|
isAbleTimeOAuthCancelled: () => isAbleTimeOAuthCancelled,
|
|
25245
|
+
isAbleTimeRejectedCredential: () => isAbleTimeRejectedCredential,
|
|
25114
25246
|
isAskUserToolName: () => isAskUserToolName,
|
|
25115
25247
|
isBrightsyConnected: () => isBrightsyConnected,
|
|
25116
25248
|
isBrightsyNdjsonLine: () => isBrightsyNdjsonLine,
|
|
@@ -25263,6 +25395,7 @@ __export(index_exports, {
|
|
|
25263
25395
|
originFetchBranch: () => originFetchBranch,
|
|
25264
25396
|
originGhRepoEnv: () => originGhRepoEnv,
|
|
25265
25397
|
packagedDetachedJobPath: () => packagedDetachedJobPath,
|
|
25398
|
+
parseAbleTimeOAuthCallbackUrl: () => parseAbleTimeOAuthCallbackUrl,
|
|
25266
25399
|
parseClaudeUsagePayload: () => parseClaudeUsagePayload,
|
|
25267
25400
|
parseCursorRunnerLine: () => parseCursorRunnerLine,
|
|
25268
25401
|
parseDurationMs: () => parseDurationMs,
|
|
@@ -31496,11 +31629,11 @@ var SLACK_OAUTH_REDIRECT = `https://relay.sideboard.cloud${SLACK_OAUTH_CALLBACK_
|
|
|
31496
31629
|
function slackOAuthRedirectUri() {
|
|
31497
31630
|
return process.env.SIDEBOARD_SLACK_OAUTH_REDIRECT?.trim() || SLACK_OAUTH_REDIRECT;
|
|
31498
31631
|
}
|
|
31499
|
-
function
|
|
31632
|
+
function escapeHtml2(value) {
|
|
31500
31633
|
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
31501
31634
|
}
|
|
31502
31635
|
function slackOAuthHtmlPage(title, body) {
|
|
31503
|
-
return `<!doctype html><html><head><meta charset="utf-8"><title>${
|
|
31636
|
+
return `<!doctype html><html><head><meta charset="utf-8"><title>${escapeHtml2(title)}</title>
|
|
31504
31637
|
<style>body{font-family:ui-sans-serif,system-ui,sans-serif;padding:48px 24px;max-width:36rem;margin:0 auto;color:#1a1a1a}
|
|
31505
31638
|
h1{font-size:1.25rem}p{line-height:1.5;color:#444}</style></head><body>${body}</body></html>`;
|
|
31506
31639
|
}
|
|
@@ -33184,6 +33317,7 @@ async function tryServeStatic(req, res, root) {
|
|
|
33184
33317
|
}
|
|
33185
33318
|
|
|
33186
33319
|
// src/slack/relay-server.ts
|
|
33320
|
+
init_abletime_oauth();
|
|
33187
33321
|
function sendHtml(res, status, title, body) {
|
|
33188
33322
|
res.writeHead(status, { "Content-Type": "text/html; charset=utf-8" });
|
|
33189
33323
|
res.end(slackOAuthHtmlPage(title, body));
|
|
@@ -33218,7 +33352,7 @@ async function startSlackRelayServer(opts) {
|
|
|
33218
33352
|
res,
|
|
33219
33353
|
400,
|
|
33220
33354
|
"Slack",
|
|
33221
|
-
`<h1>Authorization cancelled</h1><p>${
|
|
33355
|
+
`<h1>Authorization cancelled</h1><p>${escapeHtml2(error)}</p>`
|
|
33222
33356
|
);
|
|
33223
33357
|
return true;
|
|
33224
33358
|
}
|
|
@@ -33257,7 +33391,7 @@ async function startSlackRelayServer(opts) {
|
|
|
33257
33391
|
} catch (err) {
|
|
33258
33392
|
const message = err instanceof Error ? err.message : String(err);
|
|
33259
33393
|
pending.put(state, { ok: false, error: message });
|
|
33260
|
-
sendHtml(res, 400, "Slack", `<h1>Could not connect Slack</h1><p>${
|
|
33394
|
+
sendHtml(res, 400, "Slack", `<h1>Could not connect Slack</h1><p>${escapeHtml2(message)}</p>`);
|
|
33261
33395
|
}
|
|
33262
33396
|
return true;
|
|
33263
33397
|
};
|
|
@@ -33282,6 +33416,16 @@ async function startSlackRelayServer(opts) {
|
|
|
33282
33416
|
const reqUrl = req.url || "/";
|
|
33283
33417
|
if (await handleCallback(reqUrl, res)) return;
|
|
33284
33418
|
if (handleResult(reqUrl, res)) return;
|
|
33419
|
+
const ableTimeBounce = ableTimeOAuthLocalBounceUrl(reqUrl);
|
|
33420
|
+
if (ableTimeBounce && (req.method === "GET" || req.method === "HEAD")) {
|
|
33421
|
+
res.writeHead(200, {
|
|
33422
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
33423
|
+
"Cache-Control": "no-store",
|
|
33424
|
+
Refresh: `0;url=${ableTimeBounce}`
|
|
33425
|
+
});
|
|
33426
|
+
res.end(req.method === "HEAD" ? "" : ableTimeOAuthBouncePage(ableTimeBounce));
|
|
33427
|
+
return;
|
|
33428
|
+
}
|
|
33285
33429
|
if (req.url === "/health") {
|
|
33286
33430
|
sendJson(res, 200, {
|
|
33287
33431
|
ok: true,
|
|
@@ -33414,10 +33558,13 @@ init_outbound_watch();
|
|
|
33414
33558
|
0 && (module.exports = {
|
|
33415
33559
|
ABLETIME_MCP_PATH,
|
|
33416
33560
|
ABLETIME_MCP_PM_PATH,
|
|
33561
|
+
ABLETIME_OAUTH_CALLBACK_PATH,
|
|
33417
33562
|
ABLETIME_OAUTH_CANCELLED,
|
|
33563
|
+
ABLETIME_OAUTH_LOCAL_CALLBACK,
|
|
33418
33564
|
ABLETIME_OAUTH_PORT,
|
|
33419
33565
|
ABLETIME_OAUTH_REDIRECT,
|
|
33420
33566
|
ABLETIME_OAUTH_RESOURCE,
|
|
33567
|
+
ABLETIME_OAUTH_TOKEN_PREFIX,
|
|
33421
33568
|
ABLETIME_ORG_KEY_PREFIX,
|
|
33422
33569
|
ABLETIME_PAT_PREFIX,
|
|
33423
33570
|
ABLETIME_PM_TOOL_NAMES,
|
|
@@ -33517,8 +33664,12 @@ init_outbound_watch();
|
|
|
33517
33664
|
ableTimeCredentialKind,
|
|
33518
33665
|
ableTimeDependencyTarget,
|
|
33519
33666
|
ableTimeOAuthAuthorizeUrl,
|
|
33667
|
+
ableTimeOAuthBouncePage,
|
|
33520
33668
|
ableTimeOAuthClientId,
|
|
33669
|
+
ableTimeOAuthLocalBounceUrl,
|
|
33670
|
+
ableTimeOAuthRedirectUri,
|
|
33521
33671
|
ableTimeOAuthResource,
|
|
33672
|
+
ableTimeUsesRest,
|
|
33522
33673
|
abletimeMcpRequest,
|
|
33523
33674
|
abletimeMcpUrl,
|
|
33524
33675
|
abletimeToolUsesPm,
|
|
@@ -33623,6 +33774,7 @@ init_outbound_watch();
|
|
|
33623
33774
|
connectOptionalService,
|
|
33624
33775
|
connectSlackToken,
|
|
33625
33776
|
connectedOptionalServices,
|
|
33777
|
+
connectedPrSelectors,
|
|
33626
33778
|
contextTokens,
|
|
33627
33779
|
coordinatorSystemPrompt,
|
|
33628
33780
|
coordinatorTurnReminder,
|
|
@@ -33843,6 +33995,7 @@ init_outbound_watch();
|
|
|
33843
33995
|
invalidateThreadRecord,
|
|
33844
33996
|
isAbleTimeConnected,
|
|
33845
33997
|
isAbleTimeOAuthCancelled,
|
|
33998
|
+
isAbleTimeRejectedCredential,
|
|
33846
33999
|
isAskUserToolName,
|
|
33847
34000
|
isBrightsyConnected,
|
|
33848
34001
|
isBrightsyNdjsonLine,
|
|
@@ -33995,6 +34148,7 @@ init_outbound_watch();
|
|
|
33995
34148
|
originFetchBranch,
|
|
33996
34149
|
originGhRepoEnv,
|
|
33997
34150
|
packagedDetachedJobPath,
|
|
34151
|
+
parseAbleTimeOAuthCallbackUrl,
|
|
33998
34152
|
parseClaudeUsagePayload,
|
|
33999
34153
|
parseCursorRunnerLine,
|
|
34000
34154
|
parseDurationMs,
|