@snowyroad/braid 0.97.0 → 0.98.1
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/README.md +23 -1
- package/dist/{chunk-2OHYN3KD.js → chunk-3SHZYLWH.js} +112 -4
- package/dist/cli.js +1297 -129
- package/dist/{http-7LMCYNHB.js → http-7QNDIXBN.js} +1 -1
- package/dist/mcp/server.js +120 -2
- package/package.json +1 -1
- package/service-shrinkwrap.json +2 -2
package/dist/mcp/server.js
CHANGED
|
@@ -34,7 +34,7 @@ function brokerClient(socketPath, token) {
|
|
|
34
34
|
}
|
|
35
35
|
);
|
|
36
36
|
req.on("error", reject);
|
|
37
|
-
req.setTimeout(1e4, () => {
|
|
37
|
+
req.setTimeout(route.startsWith("/git/") ? 3e5 : 1e4, () => {
|
|
38
38
|
req.destroy(new Error("broker timeout"));
|
|
39
39
|
});
|
|
40
40
|
req.write(data);
|
|
@@ -559,10 +559,74 @@ ${lines.join("\n")}`;
|
|
|
559
559
|
} catch (e) {
|
|
560
560
|
return canvasErrorMessage(e, brokerStatus);
|
|
561
561
|
}
|
|
562
|
-
}
|
|
562
|
+
},
|
|
563
563
|
// ── End channel canvas tools ───────────────────────────────────────────────
|
|
564
|
+
// ── Git gateway tools (2026-10-06 D6/D7) ──────────────────────────────────
|
|
565
|
+
// No argument names the repo: the bridge takes it from the owner's grant. A
|
|
566
|
+
// refusal's text (what to ask the owner for) is returned to the agent verbatim.
|
|
567
|
+
async braidGitStatus(args) {
|
|
568
|
+
return gitCall(call, "/git/status", withPath(args, {}));
|
|
569
|
+
},
|
|
570
|
+
async braidGitFetch(args) {
|
|
571
|
+
return gitCall(call, "/git/fetch", withPath(args, {}));
|
|
572
|
+
},
|
|
573
|
+
async braidGitPush(args) {
|
|
574
|
+
const body = branchBody(args);
|
|
575
|
+
if (typeof body === "string") return body;
|
|
576
|
+
const sha = nonEmpty(args?.sha);
|
|
577
|
+
if (sha) body.sha = sha;
|
|
578
|
+
return gitCall(call, "/git/push", withPath(args, body));
|
|
579
|
+
},
|
|
580
|
+
async braidOpenPr(args) {
|
|
581
|
+
const body = branchBody(args);
|
|
582
|
+
if (typeof body === "string") return body;
|
|
583
|
+
const title = nonEmpty(args?.title);
|
|
584
|
+
if (!title) return "Error: title is required.";
|
|
585
|
+
body.title = title;
|
|
586
|
+
if (typeof args?.body === "string") body.body = args.body;
|
|
587
|
+
const base = nonEmpty(args?.base);
|
|
588
|
+
if (base) body.base = base;
|
|
589
|
+
return gitCall(call, "/git/pr/open", withPath(args, body));
|
|
590
|
+
},
|
|
591
|
+
async braidMergePr(args) {
|
|
592
|
+
const raw = args?.number;
|
|
593
|
+
const num = typeof raw === "number" ? raw : typeof raw === "string" && raw.trim() !== "" ? Number(raw) : NaN;
|
|
594
|
+
if (!Number.isFinite(num) || !Number.isInteger(num)) return "Error: number is required (the pull request number, an integer).";
|
|
595
|
+
const body = { number: num };
|
|
596
|
+
const method = nonEmpty(args?.method);
|
|
597
|
+
if (method) body.method = method;
|
|
598
|
+
return gitCall(call, "/git/pr/merge", body);
|
|
599
|
+
}
|
|
600
|
+
// ── End git gateway tools ──────────────────────────────────────────────────
|
|
564
601
|
};
|
|
565
602
|
}
|
|
603
|
+
function nonEmpty(v) {
|
|
604
|
+
return typeof v === "string" && v.trim() !== "" ? v : void 0;
|
|
605
|
+
}
|
|
606
|
+
function branchBody(args) {
|
|
607
|
+
const branch = nonEmpty(args?.branch);
|
|
608
|
+
return branch ? { branch } : "Error: branch is required.";
|
|
609
|
+
}
|
|
610
|
+
function withPath(args, body) {
|
|
611
|
+
const p = nonEmpty(args?.path);
|
|
612
|
+
return p ? { ...body, path: p } : body;
|
|
613
|
+
}
|
|
614
|
+
async function gitCall(call, route, body) {
|
|
615
|
+
try {
|
|
616
|
+
const res = await call(route, body);
|
|
617
|
+
return typeof res?.text === "string" && res.text ? res.text : "Done.";
|
|
618
|
+
} catch (e) {
|
|
619
|
+
const parsed = e?.body && typeof e.body === "object" ? e.body : (() => {
|
|
620
|
+
try {
|
|
621
|
+
return JSON.parse(String(e?.message ?? "").replace(/^broker \d+:\s*/, ""));
|
|
622
|
+
} catch {
|
|
623
|
+
return null;
|
|
624
|
+
}
|
|
625
|
+
})();
|
|
626
|
+
if (parsed && typeof parsed.text === "string" && parsed.text) return parsed.text;
|
|
627
|
+
return "The git operation could not be completed right now. Try again, or ask the owner if it keeps failing.";
|
|
628
|
+
}
|
|
629
|
+
}
|
|
566
630
|
|
|
567
631
|
// src/mcp/server.ts
|
|
568
632
|
async function main() {
|
|
@@ -903,6 +967,60 @@ async function main() {
|
|
|
903
967
|
},
|
|
904
968
|
async (args) => ({ content: [{ type: "text", text: await tools.appendCanvasSection(args) }] })
|
|
905
969
|
);
|
|
970
|
+
const gitPath = z.string().optional().describe("Worktree path; defaults to the session directory");
|
|
971
|
+
server.registerTool(
|
|
972
|
+
"braid_git_status",
|
|
973
|
+
{
|
|
974
|
+
description: "Show the GitHub repository this agent may act on through Braid (granted by its owner), the autonomy mode, the current branch and HEAD, and how far it is from the remote. Read-only. Use before braid_git_push.",
|
|
975
|
+
inputSchema: { path: gitPath }
|
|
976
|
+
},
|
|
977
|
+
async (args) => ({ content: [{ type: "text", text: await tools.braidGitStatus(args) }] })
|
|
978
|
+
);
|
|
979
|
+
server.registerTool(
|
|
980
|
+
"braid_git_fetch",
|
|
981
|
+
{
|
|
982
|
+
description: "Fetch the granted repository's branches into the current worktree under refs/remotes/braid/* (for example braid/main). Braid runs git outside the sandbox with a credential you never see.",
|
|
983
|
+
inputSchema: { path: gitPath }
|
|
984
|
+
},
|
|
985
|
+
async (args) => ({ content: [{ type: "text", text: await tools.braidGitFetch(args) }] })
|
|
986
|
+
);
|
|
987
|
+
server.registerTool(
|
|
988
|
+
"braid_git_push",
|
|
989
|
+
{
|
|
990
|
+
description: "Push a local commit (default HEAD of the worktree) to a branch of the granted repository. Braid runs the push outside the sandbox with a credential you never see and enforces the owner's rules: fast-forward only, no deletes or tags; in pr-only mode only branches under braid/<agent>/ and never the default branch; .github/workflows changes only if the owner allowed them. On refusal the text tells you what to ask the owner for.",
|
|
991
|
+
inputSchema: {
|
|
992
|
+
path: gitPath,
|
|
993
|
+
branch: z.string(),
|
|
994
|
+
sha: z.string().optional()
|
|
995
|
+
}
|
|
996
|
+
},
|
|
997
|
+
async (args) => ({ content: [{ type: "text", text: await tools.braidGitPush(args) }] })
|
|
998
|
+
);
|
|
999
|
+
server.registerTool(
|
|
1000
|
+
"braid_open_pr",
|
|
1001
|
+
{
|
|
1002
|
+
description: "Open a pull request from a branch you pushed to the granted repository (draft in pr-only mode). Returns the PR number and URL.",
|
|
1003
|
+
inputSchema: {
|
|
1004
|
+
path: gitPath,
|
|
1005
|
+
branch: z.string(),
|
|
1006
|
+
title: z.string(),
|
|
1007
|
+
body: z.string().optional(),
|
|
1008
|
+
base: z.string().optional()
|
|
1009
|
+
}
|
|
1010
|
+
},
|
|
1011
|
+
async (args) => ({ content: [{ type: "text", text: await tools.braidOpenPr(args) }] })
|
|
1012
|
+
);
|
|
1013
|
+
server.registerTool(
|
|
1014
|
+
"braid_merge_pr",
|
|
1015
|
+
{
|
|
1016
|
+
description: "Merge a pull request in the granted repository. Allowed only when the owner set autonomous mode; in pr-only mode a human merges. method is squash (default), merge, or rebase.",
|
|
1017
|
+
inputSchema: {
|
|
1018
|
+
number: z.number().int(),
|
|
1019
|
+
method: z.enum(["merge", "squash", "rebase"]).optional()
|
|
1020
|
+
}
|
|
1021
|
+
},
|
|
1022
|
+
async (args) => ({ content: [{ type: "text", text: await tools.braidMergePr(args) }] })
|
|
1023
|
+
);
|
|
906
1024
|
await server.connect(new StdioServerTransport());
|
|
907
1025
|
}
|
|
908
1026
|
main().catch((err) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@snowyroad/braid",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.98.1",
|
|
4
4
|
"description": "Braid: connect your own coding agent (Claude Code, Codex, Gemini, Grok) to a Braid channel and collaborate with other agents and humans.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"author": "SnowyRoad",
|
package/service-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@snowyroad/braid",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.98.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@snowyroad/braid",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.98.1",
|
|
10
10
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@agentclientprotocol/sdk": "0.25.1",
|