@sideboard-ai/core 0.1.19 → 0.1.23
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/{agents-2XMZO3CY.js → agents-LJJRPW4Y.js} +1 -1
- package/dist/{chunk-SNHWAARD.js → chunk-BMB7WCGF.js} +8 -10
- package/dist/{chunk-WWBC56EL.js → chunk-JNMLRJ3D.js} +160 -50
- package/dist/{chunk-LIUV5ONW.js → chunk-PER4N6LS.js} +2 -2
- package/dist/{chunk-LXHSRNJJ.js → chunk-UFWEANLU.js} +373 -7
- package/dist/{chunk-JQJZTL2Q.js → chunk-WK6AK7NK.js} +32 -8
- package/dist/{chunk-5263JXQY.js → chunk-Y2EWQ4TL.js} +2 -2
- package/dist/{coordinator-prompt-QPTX6YCW.js → coordinator-prompt-QH35ES7Y.js} +2 -2
- package/dist/{global-workspace-IV6LIDTO.js → global-workspace-LM4AA4RO.js} +3 -3
- package/dist/index.cjs +623 -65
- package/dist/index.d.cts +74 -10
- package/dist/index.d.ts +74 -10
- package/dist/index.js +60 -6
- package/dist/mcp/run-stdio.cjs +568 -65
- package/dist/mcp/run-stdio.js +6 -6
- package/dist/{workspaces-JBWIRU55.js → workspaces-23GHLR7I.js} +4 -4
- package/dist/{worktree-TYI2SANE.js → worktree-RYTBDHHP.js} +3 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveGithubRepoSlug
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-UFWEANLU.js";
|
|
4
4
|
import {
|
|
5
5
|
globalAgentCwd,
|
|
6
6
|
sideboardReposDir
|
|
@@ -31,7 +31,7 @@ function coordinatorGreenfieldPlaybook(reposDir) {
|
|
|
31
31
|
"- Examples:",
|
|
32
32
|
` - Clone: \`git clone <url> ${reposDir}/<name>\``,
|
|
33
33
|
` - New GitHub repo: \`gh repo create <owner>/<name> --private --clone -- ${reposDir}/<name>\` (or mkdir + git init + gh repo create + remote add + push)`,
|
|
34
|
-
"- Then: add_workspace with that absolute path \u2192 create_thread (repoPath + parentThreadId) \u2192 send_to_thread (build) \u2192 wait_for_turn \u2192 send_to_thread (`gh pr create --draft -R <origin-owner/name>`)
|
|
34
|
+
"- Then: add_workspace with that absolute path \u2192 create_thread (repoPath + parentThreadId) \u2192 send_to_thread (build) \u2192 wait_for_turn \u2192 send_to_thread (`gh pr create --draft -R <origin-owner/name>`).",
|
|
35
35
|
"- Always target the child worktree's **origin** (`github:` slug from list_workspaces / `git remote get-url origin` in that worktree). Never open PRs against `upstream`.",
|
|
36
36
|
"- Do coding work in the child worktree thread, not by editing files in this home cwd."
|
|
37
37
|
].join("\n");
|
|
@@ -56,10 +56,8 @@ var COORDINATOR_TOOL_PLAYBOOK = [
|
|
|
56
56
|
"- list_run_scripts / run_dev_script / stop_dev_script \u2014 start/stop named run scripts",
|
|
57
57
|
"Inspect / PRs:",
|
|
58
58
|
"- get_diff \u2014 compact diff summary",
|
|
59
|
-
"-
|
|
60
|
-
"-
|
|
61
|
-
"- create_draft_pr \u2014 fallback: commit (if dirty), push to origin, open/update a DRAFT PR from the orchestrator (always against origin)",
|
|
62
|
-
"Human-only (do not attempt): ready-for-review confirm_land, purge_thread.",
|
|
59
|
+
"- Ask the worktree agent via send_to_thread to open a draft PR with `gh pr create --draft -R <origin-owner/name>` (workspace `github:` slug / that worktree's origin \u2014 never upstream). Do not open PRs from the orchestrator yourself.",
|
|
60
|
+
"Human-only (do not attempt): merge, ready-for-review land, purge_thread.",
|
|
63
61
|
"Thread links in replies: when mentioning a chat/thread for the user, include a markdown link `[Title](sideboard://thread/<id>)` using the full id (or the link field from create_thread / list_threads). Sideboard renders these as clickable opens.",
|
|
64
62
|
"Bash / Read / etc: allowed for (1) inspecting target worktrees / registered repo paths from MCP, and (2) greenfield setup under ~/sideboard/repos (git clone, gh repo create, git init+remote). Never git init/clone *inside* this synthetic home cwd \u2014 emptiness here is expected, not a bug."
|
|
65
63
|
].join("\n");
|
|
@@ -98,8 +96,8 @@ function ensureGlobalCoordinatorCwd() {
|
|
|
98
96
|
"",
|
|
99
97
|
"When creating threads, pass `repoPath` from `list_workspaces` (or the path you just registered) and `parentThreadId` for children.",
|
|
100
98
|
"Typical flow (existing): list_workspaces \u2192 list_branches|list_prs|list_issues \u2192 create_thread \u2192 send_to_thread \u2192 wait_for_turn.",
|
|
101
|
-
"Typical flow (new app): Bash create/clone under repos dir \u2192 add_workspace \u2192 create_thread \u2192 send_to_thread (implement) \u2192 wait_for_turn \u2192 draft PR.",
|
|
102
|
-
"
|
|
99
|
+
"Typical flow (new app): Bash create/clone under repos dir \u2192 add_workspace \u2192 create_thread \u2192 send_to_thread (implement) \u2192 wait_for_turn \u2192 draft PR via worktree agent.",
|
|
100
|
+
"Always ask worktree agents to open draft PRs (`send_to_thread` + `gh pr create --draft -R <origin>`); never open PRs from the orchestrator."
|
|
103
101
|
].join("\n");
|
|
104
102
|
writeFileSync(join(dir, "CLAUDE.md"), `${body}
|
|
105
103
|
`, "utf8");
|
|
@@ -124,8 +122,8 @@ function coordinatorSystemPrompt(opts) {
|
|
|
124
122
|
COORDINATOR_TOOL_PLAYBOOK,
|
|
125
123
|
coordinatorGreenfieldPlaybook(reposDir),
|
|
126
124
|
"When creating threads, pass the correct repoPath for the target workspace and parentThreadId for children.",
|
|
127
|
-
"Typical flow (existing): list_workspaces \u2192 list_branches|list_prs|list_issues \u2192 create_thread \u2192 send_to_thread (implement) \u2192 wait_for_turn \u2192 send_to_thread (ask for `gh pr create --draft -R <origin-owner/name>` using the workspace github slug) \u2192 wait_for_turn.
|
|
128
|
-
"Typical flow (new app): Bash under repos dir (clone or gh repo create) \u2192 add_workspace \u2192 create_thread \u2192 send_to_thread \u2192 wait_for_turn \u2192 draft PR.",
|
|
125
|
+
"Typical flow (existing): list_workspaces \u2192 list_branches|list_prs|list_issues \u2192 create_thread \u2192 send_to_thread (implement) \u2192 wait_for_turn \u2192 send_to_thread (ask for `gh pr create --draft -R <origin-owner/name>` using the workspace github slug) \u2192 wait_for_turn. Never target upstream. Never open PRs from the orchestrator.",
|
|
126
|
+
"Typical flow (new app): Bash under repos dir (clone or gh repo create) \u2192 add_workspace \u2192 create_thread \u2192 send_to_thread \u2192 wait_for_turn \u2192 draft PR via worktree agent.",
|
|
129
127
|
`Goal: ${opts.goal}`,
|
|
130
128
|
`Parent thread id (pass as parentThreadId when creating children): ${opts.parentId}`,
|
|
131
129
|
"Registered workspaces:",
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
ensureWorkspace,
|
|
4
4
|
removeWorkspace,
|
|
5
5
|
syncWorkspacesFromThreads
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PER4N6LS.js";
|
|
7
7
|
import {
|
|
8
8
|
GLOBAL_WORKSPACE_ID,
|
|
9
9
|
createGlobalChat,
|
|
@@ -13,19 +13,19 @@ import {
|
|
|
13
13
|
isGlobalThread,
|
|
14
14
|
isOrchestratorThread,
|
|
15
15
|
orchestratorSessionPoisonedByBuiltins
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-Y2EWQ4TL.js";
|
|
17
17
|
import {
|
|
18
18
|
coordinatorSystemPrompt,
|
|
19
19
|
coordinatorTurnReminder,
|
|
20
20
|
enrichWorkspacesWithGithub,
|
|
21
21
|
ensureGlobalCoordinatorCwd
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-BMB7WCGF.js";
|
|
23
23
|
import {
|
|
24
24
|
PLAN_MODE_INSTRUCTION,
|
|
25
25
|
allAdapters,
|
|
26
26
|
getAdapter,
|
|
27
27
|
parseBrightsyCliLine
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-WK6AK7NK.js";
|
|
29
29
|
import {
|
|
30
30
|
childEnvWithAppSettings,
|
|
31
31
|
getLinearApiKey,
|
|
@@ -64,7 +64,7 @@ import {
|
|
|
64
64
|
takenSlugsFromThread,
|
|
65
65
|
threadDisplayLabel,
|
|
66
66
|
worktreeNameFromPath
|
|
67
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-UFWEANLU.js";
|
|
68
68
|
import {
|
|
69
69
|
appendMessage,
|
|
70
70
|
createEmptyThread,
|
|
@@ -248,6 +248,18 @@ function toolDescription(name, input) {
|
|
|
248
248
|
if (/connectedAgentRequest/i.test(name)) {
|
|
249
249
|
return str(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
|
|
250
250
|
}
|
|
251
|
+
if (/present_artifact$/i.test(name)) {
|
|
252
|
+
return str(input?.title) ? `Present ${str(input?.title)}` : "Present artifact";
|
|
253
|
+
}
|
|
254
|
+
if (/present_schema$/i.test(name)) {
|
|
255
|
+
return str(input?.title) ? `Schema ${str(input?.title)}` : "Present schema";
|
|
256
|
+
}
|
|
257
|
+
if (/present_files$/i.test(name)) {
|
|
258
|
+
return str(input?.title) ? `Files ${str(input?.title)}` : "Present files";
|
|
259
|
+
}
|
|
260
|
+
if (/^(create|update)_artifact$/i.test(name.replace(/^mcp__[^_]+__/, ""))) {
|
|
261
|
+
return str(input?.title) ? `Artifact ${str(input?.title)}` : "Artifact";
|
|
262
|
+
}
|
|
251
263
|
if (!input) return n;
|
|
252
264
|
if (/bash|shell|terminal/i.test(name) && str(input.command)) {
|
|
253
265
|
const cmd = str(input.command);
|
|
@@ -432,9 +444,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
432
444
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
433
445
|
);
|
|
434
446
|
}
|
|
435
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
447
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-LM4AA4RO.js");
|
|
436
448
|
if (isGlobalThread2(thread)) {
|
|
437
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
449
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-QH35ES7Y.js");
|
|
438
450
|
ensureGlobalCoordinatorCwd2();
|
|
439
451
|
}
|
|
440
452
|
const adapter = getAdapter(thread.agent);
|
|
@@ -606,6 +618,26 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
606
618
|
}
|
|
607
619
|
return lines.join("\n");
|
|
608
620
|
}
|
|
621
|
+
function formatArtifactDirective() {
|
|
622
|
+
return [
|
|
623
|
+
"Sideboard side column (desktop UI):",
|
|
624
|
+
"claude.ai\u2019s \u201CArtifact\u201D tool does NOT exist in Claude Code. That is expected.",
|
|
625
|
+
"Documents (HTML/SVG/markdown):",
|
|
626
|
+
"1) Emit a fenced code block tagged `html` (preferred), `svg`, or `markdown` with the FULL document \u2014 Sideboard opens a side column. Example:",
|
|
627
|
+
"```html",
|
|
628
|
+
"<!DOCTYPE html><html><head><title>Demo</title></head><body><h1>Hi</h1></body></html>",
|
|
629
|
+
"```",
|
|
630
|
+
"2) Or call Sideboard MCP `present_artifact` with title, type (html|svg|markdown), and content.",
|
|
631
|
+
"CMS / JSON Schema forms & tables (Brightsy or any schema+schemaUi source):",
|
|
632
|
+
"3) Call Sideboard MCP `present_schema` with title, mode (table|form), and either:",
|
|
633
|
+
" - datasource=brightsy + resource_id (record type UUID) after fetching types via Brightsy MCP, or",
|
|
634
|
+
" - datasource=inline + resource: { id, title, schema, schemaUi } and optional records/record.",
|
|
635
|
+
"Files / media browser (CMS file manager column):",
|
|
636
|
+
"4) Call Sideboard MCP `present_files` with optional title, path, and datasource (brightsy|memory).",
|
|
637
|
+
" Opens the Files column for browse/upload/pick. Do NOT say a file manager UI is missing.",
|
|
638
|
+
"Never say artifacts, CMS UI, or the Files column are unavailable. Prefer present_schema for list/edit/publish; present_files for storage UI; html fences for standalone pages."
|
|
639
|
+
].join("\n");
|
|
640
|
+
}
|
|
609
641
|
var FILES_BY_AGENT = {
|
|
610
642
|
claude: [
|
|
611
643
|
"CLAUDE.md",
|
|
@@ -1473,6 +1505,27 @@ function isImageRelativePath(relativePath) {
|
|
|
1473
1505
|
const ext = base.includes(".") ? base.split(".").pop() || "" : "";
|
|
1474
1506
|
return IMAGE_EXTENSIONS.has(ext);
|
|
1475
1507
|
}
|
|
1508
|
+
var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
|
|
1509
|
+
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
1510
|
+
assertSafeRelativePath(relativePath);
|
|
1511
|
+
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
1512
|
+
const abs = join4(worktreePath, relativePath);
|
|
1513
|
+
const st = statSync2(abs);
|
|
1514
|
+
if (!st.isFile()) {
|
|
1515
|
+
throw new Error(`Not a file: ${relativePath}`);
|
|
1516
|
+
}
|
|
1517
|
+
if (st.size > maxBytes) {
|
|
1518
|
+
throw new Error(
|
|
1519
|
+
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
1520
|
+
);
|
|
1521
|
+
}
|
|
1522
|
+
const buf = readFileSync4(abs);
|
|
1523
|
+
return {
|
|
1524
|
+
path: relativePath,
|
|
1525
|
+
contentBase64: buf.toString("base64"),
|
|
1526
|
+
size: buf.length
|
|
1527
|
+
};
|
|
1528
|
+
}
|
|
1476
1529
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
1477
1530
|
assertSafeRelativePath(relativePath);
|
|
1478
1531
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
@@ -2273,7 +2326,7 @@ async function createThread(input, onSetupLine) {
|
|
|
2273
2326
|
return readThread(thread.id) ?? thread;
|
|
2274
2327
|
}
|
|
2275
2328
|
async function listLinearIssues(agent, repoPath) {
|
|
2276
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
2329
|
+
const { getAdapter: getAdapter2 } = await import("./agents-LJJRPW4Y.js");
|
|
2277
2330
|
await requireAgent(agent, { requireLinear: true });
|
|
2278
2331
|
const adapter = getAdapter2(agent);
|
|
2279
2332
|
if (!adapter.listLinearIssues) {
|
|
@@ -2489,7 +2542,7 @@ async function adoptThread(input) {
|
|
|
2489
2542
|
messages: input.messages ?? []
|
|
2490
2543
|
});
|
|
2491
2544
|
writeThread(thread);
|
|
2492
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
2545
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-23GHLR7I.js");
|
|
2493
2546
|
await ensureWorkspace2(repoPath);
|
|
2494
2547
|
return thread;
|
|
2495
2548
|
}
|
|
@@ -3189,9 +3242,18 @@ var Orchestrator = class {
|
|
|
3189
3242
|
parentId: threadId,
|
|
3190
3243
|
goal: thread.sourceRef || thread.title
|
|
3191
3244
|
}) : null;
|
|
3245
|
+
const artifactReminder = thread.agent !== "brightsy" ? [
|
|
3246
|
+
"Sideboard side column (important):",
|
|
3247
|
+
"There is no claude.ai Artifact tool here \u2014 that is normal.",
|
|
3248
|
+
"HTML/SVG/markdown: ```html fence or MCP present_artifact.",
|
|
3249
|
+
"CMS forms/tables: MCP present_schema (Brightsy resource_id or inline schema+schemaUi).",
|
|
3250
|
+
"Files column: MCP present_files (brightsy account storage or memory).",
|
|
3251
|
+
"Do not say artifacts/CMS UI are unavailable."
|
|
3252
|
+
].join(" ") : null;
|
|
3192
3253
|
const agentPrompt = [
|
|
3193
3254
|
thread.planMode ? PLAN_MODE_INSTRUCTION : null,
|
|
3194
3255
|
orchestrationReminder,
|
|
3256
|
+
artifactReminder,
|
|
3195
3257
|
expandedPrompt
|
|
3196
3258
|
].filter(Boolean).join("\n\n");
|
|
3197
3259
|
const instructionFiles = loadAgentInstructions(thread.worktreePath, thread.agent);
|
|
@@ -3216,6 +3278,7 @@ var Orchestrator = class {
|
|
|
3216
3278
|
() => null
|
|
3217
3279
|
)
|
|
3218
3280
|
});
|
|
3281
|
+
const artifactDirective = isBrightsy ? null : formatArtifactDirective();
|
|
3219
3282
|
const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
|
|
3220
3283
|
const { autoRenameBranchEnabled } = await import("./app-settings-BDMLWCWI.js");
|
|
3221
3284
|
const renameBranchDirective = !isBrightsy && !isOrchestration && autoRenameBranchEnabled() ? formatRenameBranchDirective(fresh, {
|
|
@@ -3243,6 +3306,7 @@ var Orchestrator = class {
|
|
|
3243
3306
|
const cachedPrefix = [
|
|
3244
3307
|
coordinatorDirective,
|
|
3245
3308
|
worktreeDirective,
|
|
3309
|
+
artifactDirective,
|
|
3246
3310
|
renameBranchDirective,
|
|
3247
3311
|
...fresh.agent === "claude" && fresh.sessionId ? [] : [instructions, seed]
|
|
3248
3312
|
].filter(Boolean).join("\n\n---\n\n");
|
|
@@ -3663,6 +3727,13 @@ var Orchestrator = class {
|
|
|
3663
3727
|
}
|
|
3664
3728
|
return readWorktreeFile(thread.worktreePath, relativePath);
|
|
3665
3729
|
}
|
|
3730
|
+
async readFileForUpload(threadRef, relativePath) {
|
|
3731
|
+
const thread = this.requireThread(threadRef);
|
|
3732
|
+
if (relativePath.includes("..") || relativePath.startsWith("/")) {
|
|
3733
|
+
throw new Error("Invalid path");
|
|
3734
|
+
}
|
|
3735
|
+
return readWorktreeFileForUpload(thread.worktreePath, relativePath);
|
|
3736
|
+
}
|
|
3666
3737
|
async writeFile(threadRef, relativePath, content) {
|
|
3667
3738
|
const thread = this.requireThread(threadRef);
|
|
3668
3739
|
if (relativePath.includes("..") || relativePath.startsWith("/")) {
|
|
@@ -3859,7 +3930,7 @@ var Orchestrator = class {
|
|
|
3859
3930
|
return setStatus(thread.id, "idle");
|
|
3860
3931
|
}
|
|
3861
3932
|
if (!existsSync10(thread.worktreePath)) {
|
|
3862
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
3933
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-RYTBDHHP.js");
|
|
3863
3934
|
const { execa: execa6 } = await import("execa");
|
|
3864
3935
|
const slug = thread.worktreePath.split("/").pop();
|
|
3865
3936
|
const dest = thread.worktreePath;
|
|
@@ -3936,7 +4007,7 @@ async function startOrchestration(opts) {
|
|
|
3936
4007
|
sourceRef: "default",
|
|
3937
4008
|
...createOpts
|
|
3938
4009
|
}).catch(async () => {
|
|
3939
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
4010
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-RYTBDHHP.js");
|
|
3940
4011
|
const repo = await resolveRepoRoot2(repoPath);
|
|
3941
4012
|
const def = await resolveDefaultBranch2(repo);
|
|
3942
4013
|
return createThread({
|
|
@@ -4038,6 +4109,82 @@ async function startMcpServer() {
|
|
|
4038
4109
|
return { content: [{ type: "text", text: JSON.stringify(summary, null, 2) }] };
|
|
4039
4110
|
}
|
|
4040
4111
|
);
|
|
4112
|
+
server.tool(
|
|
4113
|
+
"present_artifact",
|
|
4114
|
+
"Show an HTML, SVG, or markdown document in Sideboard\u2019s Claude-style side column (desktop). Use instead of claude.ai\u2019s artifact tool \u2014 pass the full document content. Prefer type=html for interactive pages.",
|
|
4115
|
+
{
|
|
4116
|
+
title: z.string().describe("Short title shown in the artifact pane header"),
|
|
4117
|
+
type: z.enum(["html", "svg", "markdown"]).describe("Artifact kind \u2014 html opens an iframe preview"),
|
|
4118
|
+
content: z.string().describe("Full document body (complete HTML page, SVG markup, or markdown)"),
|
|
4119
|
+
artifact_id: z.string().optional().describe("Stable id when updating the same artifact across turns")
|
|
4120
|
+
},
|
|
4121
|
+
async ({ title, type, content, artifact_id }) => {
|
|
4122
|
+
const id = artifact_id?.trim() || `artifact_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
|
|
4123
|
+
const payload = {
|
|
4124
|
+
ok: true,
|
|
4125
|
+
artifact_id: id,
|
|
4126
|
+
title,
|
|
4127
|
+
type,
|
|
4128
|
+
content,
|
|
4129
|
+
message: "Artifact accepted. Sideboard desktop opens it in the side column beside chat."
|
|
4130
|
+
};
|
|
4131
|
+
return { content: [{ type: "text", text: JSON.stringify(payload) }] };
|
|
4132
|
+
}
|
|
4133
|
+
);
|
|
4134
|
+
server.tool(
|
|
4135
|
+
"present_schema",
|
|
4136
|
+
"Open Sideboard\u2019s schema-driven CMS side column (filterable table and/or form). Pass JSON Schema + schemaUi (Brightsy extensions supported). Use datasource=brightsy with resource_id (record type UUID) when logged into Brightsy; use datasource=inline with embedded resource/records for any other source.",
|
|
4137
|
+
{
|
|
4138
|
+
title: z.string().describe("Pane title"),
|
|
4139
|
+
mode: z.enum(["table", "form"]).optional().describe("table = list/filter records; form = edit one record"),
|
|
4140
|
+
datasource: z.enum(["brightsy", "inline"]).optional().describe("brightsy resolves via login; inline uses embedded resource/records"),
|
|
4141
|
+
resource_id: z.string().optional().describe("Brightsy record type UUID (or generic resource id)"),
|
|
4142
|
+
record_id: z.string().optional().describe("Record id when opening form mode"),
|
|
4143
|
+
resource: z.record(z.unknown()).optional().describe("Inline { id, title, schema, schemaUi?, slug? }"),
|
|
4144
|
+
record: z.record(z.unknown()).optional().describe("Inline record { id, data, published_at? }"),
|
|
4145
|
+
records: z.array(z.record(z.unknown())).optional().describe("Inline records for table mode"),
|
|
4146
|
+
pane_id: z.string().optional().describe("Stable pane id across updates")
|
|
4147
|
+
},
|
|
4148
|
+
async (args) => {
|
|
4149
|
+
const id = args.pane_id?.trim() || `schema_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
|
|
4150
|
+
const payload = {
|
|
4151
|
+
ok: true,
|
|
4152
|
+
pane_id: id,
|
|
4153
|
+
title: args.title,
|
|
4154
|
+
mode: args.mode ?? (args.record_id || args.record ? "form" : "table"),
|
|
4155
|
+
datasource: args.datasource ?? (args.resource ? "inline" : "brightsy"),
|
|
4156
|
+
resource_id: args.resource_id,
|
|
4157
|
+
record_id: args.record_id,
|
|
4158
|
+
resource: args.resource,
|
|
4159
|
+
record: args.record,
|
|
4160
|
+
records: args.records,
|
|
4161
|
+
message: "Schema pane accepted. Sideboard desktop opens the CMS column beside chat."
|
|
4162
|
+
};
|
|
4163
|
+
return { content: [{ type: "text", text: JSON.stringify(payload) }] };
|
|
4164
|
+
}
|
|
4165
|
+
);
|
|
4166
|
+
server.tool(
|
|
4167
|
+
"present_files",
|
|
4168
|
+
"Open Sideboard\u2019s Files column (CMS-style file manager: browse, upload, pick). Use datasource=brightsy when the user is logged into Brightsy account storage; datasource=memory for a session-local demo store. Prefer this over claiming a file manager UI is unavailable. Pair with present_schema when editing records that need media.",
|
|
4169
|
+
{
|
|
4170
|
+
title: z.string().optional().describe("Pane title (default: Files)"),
|
|
4171
|
+
datasource: z.enum(["brightsy", "memory"]).optional().describe("brightsy = account storage via login; memory = session demo store"),
|
|
4172
|
+
path: z.string().optional().describe("Initial folder path (e.g. public)"),
|
|
4173
|
+
pane_id: z.string().optional().describe("Stable pane id across updates")
|
|
4174
|
+
},
|
|
4175
|
+
async (args) => {
|
|
4176
|
+
const id = args.pane_id?.trim() || `files_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
|
|
4177
|
+
const payload = {
|
|
4178
|
+
ok: true,
|
|
4179
|
+
pane_id: id,
|
|
4180
|
+
title: args.title?.trim() || "Files",
|
|
4181
|
+
datasource: args.datasource ?? "brightsy",
|
|
4182
|
+
path: args.path,
|
|
4183
|
+
message: "Files pane accepted. Sideboard desktop opens the Files column beside chat."
|
|
4184
|
+
};
|
|
4185
|
+
return { content: [{ type: "text", text: JSON.stringify(payload) }] };
|
|
4186
|
+
}
|
|
4187
|
+
);
|
|
4041
4188
|
server.tool(
|
|
4042
4189
|
"create_thread",
|
|
4043
4190
|
"Create a new worktree thread (chat) from branch, pr, or ticket. Pass repoPath from list_workspaces and parentThreadId when spawning from an orchestrator. Then use send_to_thread to chat.",
|
|
@@ -4379,45 +4526,6 @@ async function startMcpServer() {
|
|
|
4379
4526
|
};
|
|
4380
4527
|
}
|
|
4381
4528
|
);
|
|
4382
|
-
server.tool(
|
|
4383
|
-
"preview_land",
|
|
4384
|
-
"Preview push+PR land (does NOT push). Use before create_draft_pr.",
|
|
4385
|
-
{ ref: z.string() },
|
|
4386
|
-
async ({ ref }) => {
|
|
4387
|
-
const preview = await orch.previewLand(ref);
|
|
4388
|
-
return { content: [{ type: "text", text: JSON.stringify(preview, null, 2) }] };
|
|
4389
|
-
}
|
|
4390
|
-
);
|
|
4391
|
-
server.tool(
|
|
4392
|
-
"create_draft_pr",
|
|
4393
|
-
"Commit dirty changes if needed, push the thread branch to origin, and create/update a DRAFT GitHub PR against that worktree's origin (never upstream). Ready-for-review / non-draft land stays human-only (CLI/app confirm_land). Prefer this when the orchestrator should open a PR itself; alternatively send_to_thread asking the worktree agent to run `gh pr create --draft -R <origin-owner/name>`.",
|
|
4394
|
-
{ ref: z.string() },
|
|
4395
|
-
async ({ ref }) => {
|
|
4396
|
-
try {
|
|
4397
|
-
const result = await orch.confirmLand(ref, { draft: true });
|
|
4398
|
-
return {
|
|
4399
|
-
content: [
|
|
4400
|
-
{
|
|
4401
|
-
type: "text",
|
|
4402
|
-
text: JSON.stringify(
|
|
4403
|
-
{
|
|
4404
|
-
prUrl: result.prUrl,
|
|
4405
|
-
pushed: result.pushed,
|
|
4406
|
-
committed: result.committed,
|
|
4407
|
-
draft: true
|
|
4408
|
-
},
|
|
4409
|
-
null,
|
|
4410
|
-
2
|
|
4411
|
-
)
|
|
4412
|
-
}
|
|
4413
|
-
]
|
|
4414
|
-
};
|
|
4415
|
-
} catch (err) {
|
|
4416
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
4417
|
-
return { content: [{ type: "text", text: message }], isError: true };
|
|
4418
|
-
}
|
|
4419
|
-
}
|
|
4420
|
-
);
|
|
4421
4529
|
server.tool(
|
|
4422
4530
|
"list_branches",
|
|
4423
4531
|
"List git branches in a registered workspace. Pass repoPath from list_workspaces (unmerged into the default branch by default \u2014 for create_thread sourceType=branch).",
|
|
@@ -4504,6 +4612,7 @@ export {
|
|
|
4504
4612
|
spawnAgentTurn,
|
|
4505
4613
|
formatRenameBranchDirective,
|
|
4506
4614
|
formatWorktreeDirective,
|
|
4615
|
+
formatArtifactDirective,
|
|
4507
4616
|
loadAgentInstructions,
|
|
4508
4617
|
formatAgentInstructions,
|
|
4509
4618
|
withAgentInstructions,
|
|
@@ -4531,6 +4640,7 @@ export {
|
|
|
4531
4640
|
listBranchCommits,
|
|
4532
4641
|
getDiff,
|
|
4533
4642
|
listWorktreeFiles,
|
|
4643
|
+
readWorktreeFileForUpload,
|
|
4534
4644
|
readWorktreeFile,
|
|
4535
4645
|
writeWorktreeFile,
|
|
4536
4646
|
getDiffSummary,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isGlobalRepoPath
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-Y2EWQ4TL.js";
|
|
4
4
|
import {
|
|
5
5
|
ensureGhPreferOrigin,
|
|
6
6
|
resolveRepoRoot
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-UFWEANLU.js";
|
|
8
8
|
import {
|
|
9
9
|
appDataDir
|
|
10
10
|
} from "./chunk-M37RITA6.js";
|