@sideboard-ai/core 0.1.280 → 0.1.281
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-VCVPSLSU.js → abletime-WLDBJJUI.js} +3 -3
- package/dist/{abletime-VRATUMDO.js → abletime-X64E3GUJ.js} +3 -3
- package/dist/{abletime-oauth-4K7MICAD.js → abletime-oauth-AXR676W5.js} +2 -2
- package/dist/{abletime-oauth-4C4G2J3R.js → abletime-oauth-UWOCEICP.js} +2 -2
- package/dist/{abletime-rest-PIBCNHF3.js → abletime-rest-LPUDJUEP.js} +2 -2
- package/dist/{abletime-rest-6N63ZVQ3.js → abletime-rest-S4XWEXV2.js} +2 -2
- package/dist/{agents-DYCFLDNL.js → agents-2IE4HKHA.js} +5 -5
- package/dist/{agents-RXP5NZBC.js → agents-XA2E64AW.js} +5 -5
- package/dist/{chunk-DK4DKQ2H.js → chunk-2KNO2GJQ.js} +722 -139
- package/dist/{chunk-TZ5JHIYK.js → chunk-2SJXQ4UX.js} +68 -21
- package/dist/{chunk-K7MWJLR7.js → chunk-5MGLNVNK.js} +6 -906
- package/dist/{chunk-RK5PIWCW.js → chunk-ADXVTKLC.js} +12 -4
- package/dist/{chunk-Y7JPL4WA.js → chunk-BDAUPNHL.js} +3 -4
- package/dist/{chunk-R7HLXD4I.js → chunk-BS3QLVPL.js} +93 -57
- package/dist/{chunk-2P75E243.js → chunk-BYZ7F2BQ.js} +707 -128
- package/dist/{chunk-2J34G3WJ.js → chunk-DGPROCE5.js} +93 -57
- package/dist/{chunk-HQXBBUQX.js → chunk-DQZPF6WL.js} +12 -11
- package/dist/{chunk-YDXNCBA2.js → chunk-EIEAR62M.js} +12 -11
- package/dist/{chunk-XKZAVGTT.js → chunk-I6HSGKMZ.js} +1 -1
- package/dist/chunk-JPH7PYSK.js +1241 -0
- package/dist/{chunk-IPPY3FG5.js → chunk-K5XSTHHP.js} +6 -906
- package/dist/chunk-N5UGX3JL.js +1239 -0
- package/dist/{chunk-HNNS25SG.js → chunk-OCUIZD4Y.js} +14 -4
- package/dist/{chunk-IJDQKC5A.js → chunk-PY4UCMRI.js} +4 -4
- package/dist/{chunk-NQ7JMVSU.js → chunk-U7HAVAGJ.js} +1 -1
- package/dist/{chunk-PZURG3XN.js → chunk-VA55JG2I.js} +4 -4
- package/dist/{chunk-CPA43FBK.js → chunk-W7HIK2A6.js} +3 -4
- package/dist/{chunk-SKSOCIJT.js → chunk-WY2IAB7J.js} +68 -21
- package/dist/{chunk-QINJKNLR.js → chunk-XTPQEZZA.js} +2 -2
- package/dist/{conductor-J6WDOXWM.js → conductor-CNSCOC54.js} +5 -5
- package/dist/{conductor-OW6NAK3N.js → conductor-U776JSXQ.js} +5 -5
- package/dist/{coordinator-prompt-Z2D32HWK.js → coordinator-prompt-4DJIHSE6.js} +3 -3
- package/dist/{coordinator-prompt-ERTHREGJ.js → coordinator-prompt-SVVGU6AZ.js} +3 -3
- package/dist/{global-workspace-5PJXO45Z.js → global-workspace-UPUDWIS6.js} +3 -3
- package/dist/{global-workspace-AK5PSPQ2.js → global-workspace-XON4YZXE.js} +3 -3
- package/dist/index.cjs +3690 -2912
- package/dist/index.d.cts +101 -28
- package/dist/index.d.ts +101 -28
- package/dist/index.js +1013 -1001
- package/dist/mcp/run-stdio.cjs +1975 -1259
- package/dist/mcp/run-stdio.js +743 -785
- package/dist/{orchestrator-XEKODYDQ.js → orchestrator-FPGVKEID.js} +7 -7
- package/dist/{orchestrator-K66OMTQO.js → orchestrator-HWJHK5NL.js} +7 -7
- package/dist/{thread-store-B3ZM4QEZ.js → thread-store-7XBOUQ5K.js} +1 -1
- package/dist/{thread-store-SHCUBWB3.js → thread-store-ZQZDREVH.js} +1 -1
- package/dist/{workspaces-UP6DQ3WL.js → workspaces-7AJ5RZ3P.js} +7 -3
- package/dist/{workspaces-WU2RNLDV.js → workspaces-F76BWCSI.js} +7 -3
- package/dist/{worktree-L57T3KH7.js → worktree-NKLNVNXX.js} +20 -15
- package/dist/{worktree-Q6UJHG25.js → worktree-YTZC3UQN.js} +14 -9
- package/package.json +1 -1
- package/dist/chunk-FWNL62VA.js +0 -308
- package/dist/chunk-JANCPF7Z.js +0 -310
|
@@ -9,16 +9,16 @@ import {
|
|
|
9
9
|
looksLikeSkillBody,
|
|
10
10
|
skillCommandFromBody,
|
|
11
11
|
withEventParentId
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-BDAUPNHL.js";
|
|
13
13
|
import {
|
|
14
14
|
isOrchestratorThread
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-WY2IAB7J.js";
|
|
16
16
|
import {
|
|
17
17
|
codexUnattendedGitConfigArgs,
|
|
18
18
|
mergeAgentGitAuthEnv,
|
|
19
19
|
resolveAgentGitAuthEnv,
|
|
20
20
|
resolveCodexGitWritableRoots
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-K5XSTHHP.js";
|
|
22
22
|
import {
|
|
23
23
|
loadBrightsyConfig
|
|
24
24
|
} from "./chunk-ROPGQRPU.js";
|
|
@@ -641,8 +641,12 @@ var WORKTREE_MCP_TOOLS = [
|
|
|
641
641
|
"stop_dev_script",
|
|
642
642
|
"get_run_log",
|
|
643
643
|
"notify_orchestrator",
|
|
644
|
+
"set_workspace_tags",
|
|
644
645
|
"get_viewer_context",
|
|
645
646
|
"update_viewer_context",
|
|
647
|
+
"list_env",
|
|
648
|
+
"set_env",
|
|
649
|
+
"delete_env",
|
|
646
650
|
"list_schedules",
|
|
647
651
|
"create_schedule",
|
|
648
652
|
"update_schedule",
|
|
@@ -651,6 +655,7 @@ var WORKTREE_MCP_TOOLS = [
|
|
|
651
655
|
];
|
|
652
656
|
var WORKTREE_GITHUB_MCP_TOOLS = [
|
|
653
657
|
"github_search_issues",
|
|
658
|
+
"github_list_projects",
|
|
654
659
|
"github_get_issue",
|
|
655
660
|
"github_download_attachment",
|
|
656
661
|
"github_comment",
|
|
@@ -659,6 +664,7 @@ var WORKTREE_GITHUB_MCP_TOOLS = [
|
|
|
659
664
|
];
|
|
660
665
|
var WORKTREE_LINEAR_MCP_TOOLS = [
|
|
661
666
|
"linear_list_teams",
|
|
667
|
+
"linear_list_projects",
|
|
662
668
|
"linear_search_issues",
|
|
663
669
|
"linear_get_issue",
|
|
664
670
|
"linear_download_attachment",
|
|
@@ -700,8 +706,12 @@ var SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS = [
|
|
|
700
706
|
"mcp__sideboard__stop_dev_script",
|
|
701
707
|
"mcp__sideboard__get_run_log",
|
|
702
708
|
"mcp__sideboard__notify_orchestrator",
|
|
709
|
+
"mcp__sideboard__set_workspace_tags",
|
|
703
710
|
"mcp__sideboard__get_viewer_context",
|
|
704
711
|
"mcp__sideboard__update_viewer_context",
|
|
712
|
+
"mcp__sideboard__list_env",
|
|
713
|
+
"mcp__sideboard__set_env",
|
|
714
|
+
"mcp__sideboard__delete_env",
|
|
705
715
|
"mcp__sideboard__list_schedules",
|
|
706
716
|
"mcp__sideboard__create_schedule",
|
|
707
717
|
"mcp__sideboard__update_schedule",
|
|
@@ -1745,7 +1755,7 @@ var claudeAdapter = {
|
|
|
1745
1755
|
);
|
|
1746
1756
|
}
|
|
1747
1757
|
const mode = permissionMode(thread);
|
|
1748
|
-
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-
|
|
1758
|
+
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-XON4YZXE.js");
|
|
1749
1759
|
const isOrchestrator = isOrchestratorThread2(thread);
|
|
1750
1760
|
const rpc = worktreeAgentRpc(isOrchestrator);
|
|
1751
1761
|
const injectedServers = await buildInjectedMcpServers({
|
|
@@ -155,7 +155,7 @@ function textsFromUnknown(value) {
|
|
|
155
155
|
return "";
|
|
156
156
|
}
|
|
157
157
|
async function abletimeMcpRequest(method, params, opts) {
|
|
158
|
-
const rawToken = opts?.token ?? await import("./abletime-oauth-
|
|
158
|
+
const rawToken = opts?.token ?? await import("./abletime-oauth-AXR676W5.js").then((m) => m.ensureAbleTimeAccessToken());
|
|
159
159
|
if (!rawToken?.trim()) {
|
|
160
160
|
throw new Error("AbleTime is not connected \u2014 paste a personal access token in Account settings");
|
|
161
161
|
}
|
|
@@ -226,9 +226,9 @@ async function callAbleTimeTool(name, args = {}, opts) {
|
|
|
226
226
|
if (!opts?.token && !isAbleTimeConnected()) {
|
|
227
227
|
throw new Error("AbleTime is not connected \u2014 paste a personal access token in Account settings");
|
|
228
228
|
}
|
|
229
|
-
const rawToken = opts?.token ?? await import("./abletime-oauth-
|
|
229
|
+
const rawToken = opts?.token ?? await import("./abletime-oauth-AXR676W5.js").then((m) => m.ensureAbleTimeAccessToken());
|
|
230
230
|
if (rawToken && ableTimeUsesRest(rawToken)) {
|
|
231
|
-
const { callAbleTimeRestTool } = await import("./abletime-rest-
|
|
231
|
+
const { callAbleTimeRestTool } = await import("./abletime-rest-LPUDJUEP.js");
|
|
232
232
|
return callAbleTimeRestTool(name, args, { ...opts, token: rawToken });
|
|
233
233
|
}
|
|
234
234
|
const requestOpts = { ...opts, pm: opts?.pm ?? abletimeToolUsesPm(name) };
|
|
@@ -244,7 +244,7 @@ async function callAbleTimeTool(name, args = {}, opts) {
|
|
|
244
244
|
return await call();
|
|
245
245
|
}
|
|
246
246
|
if (rawToken && ableTimeUsesRest(rawToken) && isAbleTimeRejectedCredential(message)) {
|
|
247
|
-
const { callAbleTimeRestTool } = await import("./abletime-rest-
|
|
247
|
+
const { callAbleTimeRestTool } = await import("./abletime-rest-LPUDJUEP.js");
|
|
248
248
|
return callAbleTimeRestTool(name, args, { ...opts, token: rawToken });
|
|
249
249
|
}
|
|
250
250
|
throw err instanceof Error ? new Error(rewriteAbleTimeError(err.message)) : err;
|
|
@@ -153,7 +153,7 @@ function textsFromUnknown(value) {
|
|
|
153
153
|
return "";
|
|
154
154
|
}
|
|
155
155
|
async function abletimeMcpRequest(method, params, opts) {
|
|
156
|
-
const rawToken = opts?.token ?? await import("./abletime-oauth-
|
|
156
|
+
const rawToken = opts?.token ?? await import("./abletime-oauth-UWOCEICP.js").then((m) => m.ensureAbleTimeAccessToken());
|
|
157
157
|
if (!rawToken?.trim()) {
|
|
158
158
|
throw new Error("AbleTime is not connected \u2014 paste a personal access token in Account settings");
|
|
159
159
|
}
|
|
@@ -224,9 +224,9 @@ async function callAbleTimeTool(name, args = {}, opts) {
|
|
|
224
224
|
if (!opts?.token && !isAbleTimeConnected()) {
|
|
225
225
|
throw new Error("AbleTime is not connected \u2014 paste a personal access token in Account settings");
|
|
226
226
|
}
|
|
227
|
-
const rawToken = opts?.token ?? await import("./abletime-oauth-
|
|
227
|
+
const rawToken = opts?.token ?? await import("./abletime-oauth-UWOCEICP.js").then((m) => m.ensureAbleTimeAccessToken());
|
|
228
228
|
if (rawToken && ableTimeUsesRest(rawToken)) {
|
|
229
|
-
const { callAbleTimeRestTool } = await import("./abletime-rest-
|
|
229
|
+
const { callAbleTimeRestTool } = await import("./abletime-rest-S4XWEXV2.js");
|
|
230
230
|
return callAbleTimeRestTool(name, args, { ...opts, token: rawToken });
|
|
231
231
|
}
|
|
232
232
|
const requestOpts = { ...opts, pm: opts?.pm ?? abletimeToolUsesPm(name) };
|
|
@@ -242,7 +242,7 @@ async function callAbleTimeTool(name, args = {}, opts) {
|
|
|
242
242
|
return await call();
|
|
243
243
|
}
|
|
244
244
|
if (rawToken && ableTimeUsesRest(rawToken) && isAbleTimeRejectedCredential(message)) {
|
|
245
|
-
const { callAbleTimeRestTool } = await import("./abletime-rest-
|
|
245
|
+
const { callAbleTimeRestTool } = await import("./abletime-rest-S4XWEXV2.js");
|
|
246
246
|
return callAbleTimeRestTool(name, args, { ...opts, token: rawToken });
|
|
247
247
|
}
|
|
248
248
|
throw err instanceof Error ? new Error(rewriteAbleTimeError(err.message)) : err;
|
|
@@ -541,6 +541,8 @@ function toolDescription(name, input) {
|
|
|
541
541
|
return str(input?.name) ? `Read ${str(input?.name)} log` : "Read Dev log";
|
|
542
542
|
}
|
|
543
543
|
if (/notify_orchestrator$/i.test(name)) return "Notify orchestrator";
|
|
544
|
+
else if (/set_workspace_tags$/i.test(name)) return "Set workspace tags";
|
|
545
|
+
if (/(?:list|set|delete)_env$/i.test(name)) return /list_env$/i.test(name) ? "List env vars" : /set_env$/i.test(name) ? "Set env var" : "Delete env var";
|
|
544
546
|
if (/list_schedules$/i.test(name)) return "List schedules";
|
|
545
547
|
if (/create_schedule$/i.test(name)) {
|
|
546
548
|
return str(input?.name) ? `Schedule ${str(input?.name)}` : "Create schedule";
|
|
@@ -554,10 +556,7 @@ function toolDescription(name, input) {
|
|
|
554
556
|
}
|
|
555
557
|
if (isCompactToolName(name)) {
|
|
556
558
|
const trigger = str(input?.trigger);
|
|
557
|
-
|
|
558
|
-
return `Summarized conversation (${trigger})`;
|
|
559
|
-
}
|
|
560
|
-
return "Summarized conversation";
|
|
559
|
+
return trigger && !/^auto$/i.test(trigger) && trigger !== "injected" ? `Summarized conversation (${trigger})` : "Summarized conversation";
|
|
561
560
|
}
|
|
562
561
|
if (isSubagentToolName(name)) {
|
|
563
562
|
const desc = str(input?.description);
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
|
-
allocateTeamName,
|
|
3
2
|
canonicalizeRepoPath,
|
|
4
3
|
ensureGhPreferOrigin,
|
|
5
4
|
resolveGithubRepoSlug,
|
|
6
|
-
resolveRepoRoot
|
|
7
|
-
|
|
8
|
-
teamSlugFromName
|
|
9
|
-
} from "./chunk-IPPY3FG5.js";
|
|
5
|
+
resolveRepoRoot
|
|
6
|
+
} from "./chunk-K5XSTHHP.js";
|
|
10
7
|
import {
|
|
8
|
+
allocateTeamName,
|
|
11
9
|
createEmptyThread,
|
|
12
10
|
listThreads,
|
|
11
|
+
takenSlugsFromThread,
|
|
12
|
+
teamSlugFromName,
|
|
13
13
|
updateThread,
|
|
14
14
|
writeThread
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-N5UGX3JL.js";
|
|
16
16
|
import {
|
|
17
17
|
ATTACHMENTS_DIR,
|
|
18
18
|
attachmentsGitignoreBody
|
|
@@ -386,21 +386,23 @@ var COORDINATOR_TOOL_PLAYBOOK = [
|
|
|
386
386
|
`- list_branches / list_prs / list_issues \u2014 pass repoPath from list_projects. Review is PRs (the surface for assigned ticket work), not the tickets: "Get me N tickets to review" \u2192 list_prs(queue=review, limit=N) then create_workspace sourceType=pr. That is open non-draft PRs labeled with this project's ready-for-review GitHub label (Settings \u2192 Projects; default eng-review) with no individual user reviewer yet. A team request (engineering-team) is not a claim \u2014 the viewer is on that team and can pick it up; claimed means an individual account is the reviewer. Bots ignored. Use Settings \u2192 Agents / Projects context (roles, teams, labels \u2014 freeform text; project adds to account) to prefer the right queues. queue=mine is review-requested:@me; queue=approved|changes uses those labels. Also: state, label, reviewer=me|unassigned|login, query, limit default 40 max 250; raise limit or tighten when truncated. list_issues (query, assignee=me|unassigned|all|user, limit default 40 max 250) lists Linear, AbleTime, or GitHub tickets \u2014 do not use it for that review-inbox ask. When they ask for tickets to work on, follow their context (assignee=me or unassigned as it says).`,
|
|
387
387
|
"- Find work: when they ask to find work, pick up tickets, or list reviews, use Settings \u2192 Agents (account) plus Settings \u2192 Projects (per-repo) context. Tickets \u2192 Sideboard list_issues / linear_* (Account Linear). Reviews \u2192 list_prs(queue=review). Do not call Claude Linear MCP or any other vendor Linear MCP \u2014 those HTTP connectors hang or flap on the first turn. If a vendor MCP is down or reconnecting, ignore it and keep going with Sideboard tools. Show the options \u2014 do not create_workspace or start unless they also asked to start (e.g. \u201Cfind me work and start it\u201D). Do not start this unprompted. To change that context, show the proposed text, ask_user (Save this context / Do not save), wait, then update_viewer_context with confirmed=true. Never write it without confirmation.",
|
|
388
388
|
"- Ticket updates: list_issues / linear_search_issues / github_search_issues with updatedSince (yesterday, 2d, or ISO). One call returns new assignments, ticket edits, and new comments \u2014 do not get_issue every ticket just to check for comments. kind=created vs updated distinguishes new tickets from existing ones.",
|
|
389
|
-
"- linear_* (when Linear is connected) \u2014 list_teams for team key/states; get/create/update/comment with ENG-123. Worktree agents have the same Account tools \u2014 prefer they comment, update status, and create spin-offs (parent=) on their own ticket when they were asked to do the work. When reviewing a PR or ticket, do not comment or update until the user types a next step \u2014 they should work through the feedback in chat first. Do not tell the child to ask_user after the review. Scope errors: reconnect Linear in Account settings. Prefer these over any Linear MCP the CLI may still list.",
|
|
390
|
-
"- github_* \u2014 get/comment/update/create GitHub issues via Account `gh` (#123). Worktree agents have these too. Prefer over any vendor GitHub MCP. Pass parent= for spin-offs. When reviewing a PR or ticket, do not comment, submit `gh pr review`, or update the PR/ticket until the user types a next step.",
|
|
391
|
-
"- abletime_* (when AbleTime is connected) \u2014 orientation first; get/comment/update/create (parent= for spin-offs); ensure_task when work has no ticket (or create_workspace from the default branch auto-creates one). Worktree agents have the same Account tools. Same review-write gate as Linear/GitHub.",
|
|
392
|
-
"- Optional connectors (Vercel, Supabase, PostHog, Sentry) in Settings \u2192 Connectors inject tokens into worktree agent env when connected. Prefer official CLIs (`vercel`, `supabase`, `sentry-cli`) with those env vars. PostHog has no first-class CLI \u2014 use the HTTP API (`POSTHOG_PERSONAL_API_KEY`). Tell any worktree agent (Claude / Cursor / Codex / OpenCode) to write CLI output to `.context/cli/` (not `.context/attachments/`) and read a slice \u2014 never stream raw `--json` / `--expand` into a tool result (that crashes the turn). They can `stop_job` if a detached fetch hangs. If a CLI is missing, the user can Install CLI on that row (not auto-installed on Connect). Do not add vendor MCPs or ask the user to paste tokens again. Git (`gh`) stays Settings \u2192 Git; issue tracking stays Settings \u2192 Issues. The phone remote is Settings \u2192 Remote \u2014 do not look up Slack users.",
|
|
389
|
+
"- linear_* (when Linear is connected) \u2014 list_teams for team key/states; linear_list_projects for project names; get/search include the project a ticket is on; get/create/update/comment with ENG-123. Worktree agents have the same Account tools \u2014 prefer they comment, update status, and create spin-offs (parent=) on their own ticket when they were asked to do the work. When reviewing a PR or ticket, do not comment or update until the user types a next step \u2014 they should work through the feedback in chat first. Do not tell the child to ask_user after the review. Scope errors: reconnect Linear in Account settings. Prefer these over any Linear MCP the CLI may still list.",
|
|
390
|
+
"- github_* \u2014 get/comment/update/create GitHub issues via Account `gh` (#123). github_list_projects and get/search include GitHub Projects. projectsError or a missing read:project scope \u2192 `gh auth refresh -s read:project`. Worktree agents have these too. Prefer over any vendor GitHub MCP. Pass parent= for spin-offs. When reviewing a PR or ticket, do not comment, submit `gh pr review`, or update the PR/ticket until the user types a next step.",
|
|
391
|
+
"- abletime_* (when AbleTime is connected) \u2014 orientation first; abletime_list_projects lists projects; get/list include the project a task is on; get/comment/update/create (parent= for spin-offs); ensure_task when work has no ticket (or create_workspace from the default branch auto-creates one). Worktree agents have the same Account tools. Same review-write gate as Linear/GitHub.",
|
|
392
|
+
"- Optional connectors (Vercel, Supabase, PostHog, Sentry) in Settings \u2192 Connectors inject tokens into worktree agent env when connected. Prefer official CLIs (`vercel`, `supabase`, `sentry-cli`) with those env vars. PostHog has no first-class CLI \u2014 use the HTTP API (`POSTHOG_PERSONAL_API_KEY`). If a connector MCP is listed but needsAuth or unauthorized, do not sign in \u2014 check that native CLI or HTTP API. Tell any worktree agent (Claude / Cursor / Codex / OpenCode) to write CLI output to `.context/cli/` (not `.context/attachments/`) and read a slice \u2014 never stream raw `--json` / `--expand` into a tool result (that crashes the turn). They can `stop_job` if a detached fetch hangs. If a CLI is missing, the user can Install CLI on that row (not auto-installed on Connect). Do not add vendor MCPs or ask the user to paste tokens again. Git (`gh`) stays Settings \u2192 Git; issue tracking stays Settings \u2192 Issues. The phone remote is Settings \u2192 Remote \u2014 do not look up Slack users.",
|
|
393
393
|
"- get_pr_stack / open_pr_stack_layers / add_stack_layer / create_pr_stack \u2014 GitHub stacked PRs (`gh stack`); one worktree per layer",
|
|
394
394
|
"- list_models \u2014 only when you need a specific model (rare); otherwise omit model so Account defaults apply",
|
|
395
395
|
"- list_chats / get_chat \u2014 live thread list (parent id + last message preview). get_chat on this orchestration chat lists child worktree agents (status + lastText). blockedReason is why that agent is waiting on a person. Also includes usage / lastTurnUsage.",
|
|
396
396
|
"- ask_user \u2014 composer multiple-choice only when blocked on a concrete choice (approach fork, which API, Save this context / Do not save). Never for hellos, check-ins, invented \u201Cwhat should we do?\u201D menus, or after a review \u2014 reply in chat. Explain options first, description on every option, then wait.",
|
|
397
397
|
"- get_viewer_context / update_viewer_context \u2014 read or replace Settings \u2192 Agents (account) and Settings \u2192 Projects (per-repo) context. You can update a project: pass scope=project and repoPath from list_projects (this cwd is not a project). update_viewer_context requires confirmed=true after ask_user. Never write context unprompted.",
|
|
398
|
+
"- list_env / set_env / delete_env \u2014 Settings \u2192 Environment. scope=project requires repoPath from list_projects and stores the key under that project prefix (the project name, uppercased, plus _). APPLE_ID for sideboard is SIDEBOARD_APPLE_ID. scope=account is shared by every project and is not prefixed. list_env returns names only.",
|
|
398
399
|
"- set_caffeinate \u2014 keep this Mac awake across turns (macOS caffeinate). Turn on for phone remote / away-from-keyboard work, overnight schedules, or when the user will be away. Turn OFF when they say they are done, wrapping up, going to sleep, or no longer need the machine awake. Closing this chat also releases it.",
|
|
399
400
|
"- list_schedules / create_schedule / update_schedule / delete_schedule / run_schedule \u2014 local jobs that send a prompt to a chat (chatId or self) or start a new Global chat (omit chatId). One-shot `at`, interval `every` (15m/1h/6h/1d), or 5-field `cron`. Recurring jobs without chatId open a new chat each run. Worktree agents have the same tools (`chatId=self` continues that coding chat). Jobs fire only while Sideboard.app is running; sleep skips until wake. Creating or enabling a future job turns on Settings \u2192 Advanced \u2192 Caffeinate while schedules are enabled (or call set_caffeinate).",
|
|
400
401
|
"Projects:",
|
|
401
402
|
"- add_project / remove_project \u2014 register or unregister a git repo",
|
|
402
403
|
"Workspaces and chats:",
|
|
403
|
-
|
|
404
|
+
'- create_workspace \u2014 create a workspace (isolated checkout + first chat) from branch | pr | ticket (appears on Home). A ticket, PR, or named branch has one checkout: a second call returns that workspace (alreadyStarted=true) and chats for every agent already on it. That is not one agent. To put another agent on that checkout, fork_chat. send_to_chat only the chat that should do this job. Creating from the default branch still opens a new isolated workspace. Pass repoPath + parentChatId; omit agent and model so Sideboard applies Settings \u2192 Default agent, model & effort (never pass your own agent or agent=cursor). Pass the same tags (short labels, e.g. "phone-sync") on every workspace you open for one task so they group in the sidebar; reusing a checkout adds those tags. If the repo has a setup script, Sideboard runs it in the background (does not block send_to_chat). Nested Codex (you are Codex and the child would be Codex) can deadlock on ~/.codex locks \u2014 omit agent; Sideboard switches the child to Cursor when a CURSOR_API_KEY is set, otherwise keeps the Account default',
|
|
405
|
+
"- set_workspace_tags \u2014 set, add, or remove labels on a workspace after create. Pass any chat id on that checkout. Same tags on every workspace from one task. Worktree agents can update tags on their own checkout (they omit ref).",
|
|
404
406
|
"- start_board_card \u2014 same as create_workspace for a ticket/PR/named branch (attaches issue text when resolvable). Then send_to_chat.",
|
|
405
407
|
"- fork_workspace \u2014 fork a worktree chat into a NEW git worktree + chat (transcript attached); optional agent; leave model unset (Auto) unless you have a reason. Not for orchestration chats.",
|
|
406
408
|
"- fork_chat \u2014 add another agent on the SAME workspace (same files, Run, and git), or fork a Global orchestration chat into a new tab. Pass agent when it should be a different harness. Leave model unset (Auto) unless you have a reason. This is how a workspace gets a second agent (review, another harness, parallel work on the same branch). Do not create_workspace again for that. Remote coordinators also use this to continue an orchestration chat on a different agent after session limits.",
|
|
@@ -858,20 +860,55 @@ function writeRemoved(paths) {
|
|
|
858
860
|
mkdirSync3(appDataDir(), { recursive: true });
|
|
859
861
|
writeFileSync3(removedWorkspacesFile(), JSON.stringify([...paths].sort(), null, 2), "utf8");
|
|
860
862
|
}
|
|
863
|
+
function canonicalWorkspacePath(repoPath) {
|
|
864
|
+
return canonicalizeRepoPath(repoPath);
|
|
865
|
+
}
|
|
866
|
+
function sameWorkspacePath(a, b) {
|
|
867
|
+
if (!a || !b) return false;
|
|
868
|
+
const left = canonicalWorkspacePath(a);
|
|
869
|
+
const right = canonicalWorkspacePath(b);
|
|
870
|
+
if (left === right) return true;
|
|
871
|
+
const primaryA = primaryCheckoutFromLinkedWorktree(a);
|
|
872
|
+
const primaryB = primaryCheckoutFromLinkedWorktree(b);
|
|
873
|
+
if (primaryA && (primaryA === right || primaryA === primaryB)) return true;
|
|
874
|
+
if (primaryB && primaryB === left) return true;
|
|
875
|
+
return false;
|
|
876
|
+
}
|
|
877
|
+
function removedMatches(saved, repoPath) {
|
|
878
|
+
if (saved === repoPath || sameWorkspacePath(saved, repoPath)) return true;
|
|
879
|
+
const primary = primaryCheckoutFromLinkedWorktree(repoPath);
|
|
880
|
+
return Boolean(primary && sameWorkspacePath(saved, primary));
|
|
881
|
+
}
|
|
882
|
+
function isRemovedWorkspace(repoPath) {
|
|
883
|
+
if (!repoPath) return false;
|
|
884
|
+
for (const saved of readRemoved()) {
|
|
885
|
+
if (removedMatches(saved, repoPath)) return true;
|
|
886
|
+
}
|
|
887
|
+
return false;
|
|
888
|
+
}
|
|
861
889
|
function rememberRemoved(repoPath) {
|
|
862
890
|
const next = readRemoved();
|
|
863
|
-
next.
|
|
864
|
-
|
|
891
|
+
const before = next.size;
|
|
892
|
+
const canon = canonicalWorkspacePath(repoPath);
|
|
893
|
+
next.add(canon);
|
|
894
|
+
const raw = repoPath.replace(/\/+$/, "");
|
|
895
|
+
if (raw && raw !== canon) next.add(raw);
|
|
896
|
+
if (next.size !== before) writeRemoved(next);
|
|
865
897
|
}
|
|
866
898
|
function forgetRemoved(repoPath) {
|
|
867
899
|
const next = readRemoved();
|
|
868
|
-
|
|
869
|
-
|
|
900
|
+
let changed = false;
|
|
901
|
+
for (const saved of [...next]) {
|
|
902
|
+
if (!removedMatches(saved, repoPath)) continue;
|
|
903
|
+
next.delete(saved);
|
|
904
|
+
changed = true;
|
|
905
|
+
}
|
|
906
|
+
if (changed) writeRemoved(next);
|
|
870
907
|
}
|
|
871
908
|
function listWorkspaces() {
|
|
872
909
|
const all = readAll();
|
|
873
910
|
const valid = all.filter(
|
|
874
|
-
(w) => Boolean(w.path) && w.path !== "/" && w.path !== "." && !isGlobalRepoPath(w.path)
|
|
911
|
+
(w) => Boolean(w.path) && w.path !== "/" && w.path !== "." && !isGlobalRepoPath(w.path) && !isRemovedWorkspace(w.path)
|
|
875
912
|
);
|
|
876
913
|
if (valid.length !== all.length) writeAll(valid);
|
|
877
914
|
return valid.sort((a, b) => a.name.localeCompare(b.name));
|
|
@@ -916,6 +953,9 @@ async function addWorkspace(repoPath) {
|
|
|
916
953
|
if (!root || root === "/") throw new Error(`Invalid repo path: ${repoPath}`);
|
|
917
954
|
if (!existsSync2(root)) throw new Error(`Repo not found: ${root}`);
|
|
918
955
|
forgetRemoved(root);
|
|
956
|
+
return registerWorkspace(root);
|
|
957
|
+
}
|
|
958
|
+
async function registerWorkspace(root) {
|
|
919
959
|
await ensureGhPreferOrigin(root);
|
|
920
960
|
const current = readAll();
|
|
921
961
|
const existing = current.find((w) => w.path === root);
|
|
@@ -930,21 +970,26 @@ async function addWorkspace(repoPath) {
|
|
|
930
970
|
return next;
|
|
931
971
|
}
|
|
932
972
|
function removeWorkspace(repoPath) {
|
|
933
|
-
writeAll(readAll().filter((w) => w.path !== repoPath));
|
|
934
973
|
rememberRemoved(repoPath);
|
|
974
|
+
const canon = canonicalWorkspacePath(repoPath);
|
|
975
|
+
writeAll(readAll().filter((w) => !sameWorkspacePath(w.path, canon)));
|
|
935
976
|
}
|
|
936
977
|
async function ensureWorkspace(repoPath) {
|
|
937
|
-
|
|
978
|
+
const root = await resolveRepoRoot(repoPath);
|
|
979
|
+
if (!root || root === "/" || !existsSync2(root)) {
|
|
980
|
+
throw new Error(`Invalid repo path: ${repoPath}`);
|
|
981
|
+
}
|
|
982
|
+
if (isRemovedWorkspace(root)) throw new Error(`Project was removed: ${root}`);
|
|
983
|
+
return registerWorkspace(root);
|
|
938
984
|
}
|
|
939
985
|
function syncWorkspacesFromThreads(repoPaths) {
|
|
940
986
|
const current = readAll();
|
|
941
|
-
const removed = readRemoved();
|
|
942
987
|
const byPath = /* @__PURE__ */ new Map();
|
|
943
988
|
let dirty = false;
|
|
944
989
|
for (const w of current) {
|
|
945
990
|
const resolved = resolveSyncWorkspacePath(w.path) ?? w.path;
|
|
946
991
|
if (resolved !== w.path) dirty = true;
|
|
947
|
-
if (!resolved || resolved === "/" || isGlobalRepoPath(resolved) ||
|
|
992
|
+
if (!resolved || resolved === "/" || isGlobalRepoPath(resolved) || isRemovedWorkspace(resolved)) {
|
|
948
993
|
dirty = true;
|
|
949
994
|
continue;
|
|
950
995
|
}
|
|
@@ -957,7 +1002,7 @@ function syncWorkspacesFromThreads(repoPaths) {
|
|
|
957
1002
|
}
|
|
958
1003
|
for (const raw of repoPaths) {
|
|
959
1004
|
const path = resolveSyncWorkspacePath(raw);
|
|
960
|
-
if (!path || path === "/" || isGlobalRepoPath(path) || byPath.has(path) ||
|
|
1005
|
+
if (!path || path === "/" || isGlobalRepoPath(path) || byPath.has(path) || isRemovedWorkspace(path)) {
|
|
961
1006
|
continue;
|
|
962
1007
|
}
|
|
963
1008
|
if (!existsSync2(path)) continue;
|
|
@@ -997,6 +1042,8 @@ export {
|
|
|
997
1042
|
attachmentsFromBuffers,
|
|
998
1043
|
persistPendingFileAttachments,
|
|
999
1044
|
attachmentsFromWorktreePaths,
|
|
1045
|
+
sameWorkspacePath,
|
|
1046
|
+
isRemovedWorkspace,
|
|
1000
1047
|
listWorkspaces,
|
|
1001
1048
|
primaryCheckoutFromLinkedWorktree,
|
|
1002
1049
|
addWorkspace,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DEFAULT_ABLETIME_HOST,
|
|
3
3
|
normalizeAbleTimeHost
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VA55JG2I.js";
|
|
5
5
|
import {
|
|
6
6
|
httpFetch
|
|
7
7
|
} from "./chunk-N7WZ6NIN.js";
|
|
@@ -280,7 +280,7 @@ async function startAbleTimeOAuth(opts) {
|
|
|
280
280
|
persistAbleTimeTokens(data, { host });
|
|
281
281
|
const token = data.access_token.trim();
|
|
282
282
|
try {
|
|
283
|
-
const { getAbleTimeOrientation } = await import("./abletime-
|
|
283
|
+
const { getAbleTimeOrientation } = await import("./abletime-X64E3GUJ.js");
|
|
284
284
|
const orientation = await getAbleTimeOrientation({ token, host });
|
|
285
285
|
return saveAbleTimeConnection({
|
|
286
286
|
accessToken: token,
|
|
@@ -33,10 +33,10 @@ import {
|
|
|
33
33
|
tryReservePort,
|
|
34
34
|
tryReservePorts,
|
|
35
35
|
worktreeRunPortsPath
|
|
36
|
-
} from "./chunk-
|
|
37
|
-
import "./chunk-
|
|
38
|
-
import "./chunk-
|
|
39
|
-
import "./chunk-
|
|
36
|
+
} from "./chunk-EIEAR62M.js";
|
|
37
|
+
import "./chunk-W7HIK2A6.js";
|
|
38
|
+
import "./chunk-2SJXQ4UX.js";
|
|
39
|
+
import "./chunk-5MGLNVNK.js";
|
|
40
40
|
import "./chunk-N2WW62LF.js";
|
|
41
41
|
import "./chunk-DD67JWTN.js";
|
|
42
42
|
import "./chunk-2UG25RMK.js";
|
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
} from "./chunk-WWUABK6B.js";
|
|
48
48
|
import "./chunk-FJZWM2ON.js";
|
|
49
49
|
import "./chunk-UN5Q7POQ.js";
|
|
50
|
-
import "./chunk-
|
|
50
|
+
import "./chunk-JPH7PYSK.js";
|
|
51
51
|
import "./chunk-4RZRHTSZ.js";
|
|
52
52
|
import "./chunk-KGZBYWZ3.js";
|
|
53
53
|
import {
|
|
@@ -31,11 +31,11 @@ import {
|
|
|
31
31
|
tryReservePort,
|
|
32
32
|
tryReservePorts,
|
|
33
33
|
worktreeRunPortsPath
|
|
34
|
-
} from "./chunk-
|
|
35
|
-
import "./chunk-
|
|
36
|
-
import "./chunk-
|
|
37
|
-
import "./chunk-
|
|
38
|
-
import "./chunk-
|
|
34
|
+
} from "./chunk-DQZPF6WL.js";
|
|
35
|
+
import "./chunk-BDAUPNHL.js";
|
|
36
|
+
import "./chunk-WY2IAB7J.js";
|
|
37
|
+
import "./chunk-K5XSTHHP.js";
|
|
38
|
+
import "./chunk-N5UGX3JL.js";
|
|
39
39
|
import "./chunk-2P4XKWV2.js";
|
|
40
40
|
import "./chunk-K2S33ZCB.js";
|
|
41
41
|
import "./chunk-6K64FJDD.js";
|
|
@@ -7,9 +7,9 @@ import {
|
|
|
7
7
|
enrichWorkspacesWithGithub,
|
|
8
8
|
ensureGlobalCoordinatorCwd,
|
|
9
9
|
formatWorkspaceInventory
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-WY2IAB7J.js";
|
|
11
|
+
import "./chunk-K5XSTHHP.js";
|
|
12
|
+
import "./chunk-N5UGX3JL.js";
|
|
13
13
|
import "./chunk-2P4XKWV2.js";
|
|
14
14
|
import "./chunk-6K64FJDD.js";
|
|
15
15
|
import "./chunk-UWQ6UCIB.js";
|
|
@@ -9,8 +9,8 @@ import {
|
|
|
9
9
|
enrichWorkspacesWithGithub,
|
|
10
10
|
ensureGlobalCoordinatorCwd,
|
|
11
11
|
formatWorkspaceInventory
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-2SJXQ4UX.js";
|
|
13
|
+
import "./chunk-5MGLNVNK.js";
|
|
14
14
|
import "./chunk-N2WW62LF.js";
|
|
15
15
|
import "./chunk-DD67JWTN.js";
|
|
16
16
|
import "./chunk-2UG25RMK.js";
|
|
@@ -19,7 +19,7 @@ import "./chunk-NSTQ6QKD.js";
|
|
|
19
19
|
import "./chunk-WWUABK6B.js";
|
|
20
20
|
import "./chunk-FJZWM2ON.js";
|
|
21
21
|
import "./chunk-UN5Q7POQ.js";
|
|
22
|
-
import "./chunk-
|
|
22
|
+
import "./chunk-JPH7PYSK.js";
|
|
23
23
|
import "./chunk-4RZRHTSZ.js";
|
|
24
24
|
import "./chunk-KGZBYWZ3.js";
|
|
25
25
|
import "./chunk-H5XL4KUS.js";
|
|
@@ -20,8 +20,8 @@ import {
|
|
|
20
20
|
remoteCoordinatorSourceRef,
|
|
21
21
|
slackCoordinatorSourceRef,
|
|
22
22
|
takenTeamSlugsForOrchestration
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-2SJXQ4UX.js";
|
|
24
|
+
import "./chunk-5MGLNVNK.js";
|
|
25
25
|
import "./chunk-N2WW62LF.js";
|
|
26
26
|
import "./chunk-DD67JWTN.js";
|
|
27
27
|
import "./chunk-2UG25RMK.js";
|
|
@@ -30,7 +30,7 @@ import "./chunk-NSTQ6QKD.js";
|
|
|
30
30
|
import "./chunk-WWUABK6B.js";
|
|
31
31
|
import "./chunk-FJZWM2ON.js";
|
|
32
32
|
import "./chunk-UN5Q7POQ.js";
|
|
33
|
-
import "./chunk-
|
|
33
|
+
import "./chunk-JPH7PYSK.js";
|
|
34
34
|
import "./chunk-4RZRHTSZ.js";
|
|
35
35
|
import "./chunk-KGZBYWZ3.js";
|
|
36
36
|
import {
|
|
@@ -18,9 +18,9 @@ import {
|
|
|
18
18
|
remoteCoordinatorSourceRef,
|
|
19
19
|
slackCoordinatorSourceRef,
|
|
20
20
|
takenTeamSlugsForOrchestration
|
|
21
|
-
} from "./chunk-
|
|
22
|
-
import "./chunk-
|
|
23
|
-
import "./chunk-
|
|
21
|
+
} from "./chunk-WY2IAB7J.js";
|
|
22
|
+
import "./chunk-K5XSTHHP.js";
|
|
23
|
+
import "./chunk-N5UGX3JL.js";
|
|
24
24
|
import "./chunk-2P4XKWV2.js";
|
|
25
25
|
import "./chunk-6K64FJDD.js";
|
|
26
26
|
import "./chunk-UWQ6UCIB.js";
|