@snowyroad/braid 0.96.8 → 0.98.0
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 +28 -4
- package/dist/{chunk-QHWKKDPN.js → chunk-3SHZYLWH.js} +205 -8
- package/dist/cli.js +1259 -132
- package/dist/{http-3WYFRJZR.js → http-7QNDIXBN.js} +1 -1
- package/dist/mcp/server.js +120 -2
- package/package.json +1 -1
- package/service-shrinkwrap.json +19 -19
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.0",
|
|
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.0",
|
|
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.0",
|
|
10
10
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@agentclientprotocol/sdk": "0.25.1",
|
|
@@ -1394,9 +1394,9 @@
|
|
|
1394
1394
|
}
|
|
1395
1395
|
},
|
|
1396
1396
|
"node_modules/acorn": {
|
|
1397
|
-
"version": "8.
|
|
1398
|
-
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.
|
|
1399
|
-
"integrity": "sha512-
|
|
1397
|
+
"version": "8.19.0",
|
|
1398
|
+
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz",
|
|
1399
|
+
"integrity": "sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==",
|
|
1400
1400
|
"dev": true,
|
|
1401
1401
|
"license": "MIT",
|
|
1402
1402
|
"bin": {
|
|
@@ -2144,9 +2144,9 @@
|
|
|
2144
2144
|
}
|
|
2145
2145
|
},
|
|
2146
2146
|
"node_modules/express-rate-limit": {
|
|
2147
|
-
"version": "8.7.
|
|
2148
|
-
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.7.
|
|
2149
|
-
"integrity": "sha512-
|
|
2147
|
+
"version": "8.7.1",
|
|
2148
|
+
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.7.1.tgz",
|
|
2149
|
+
"integrity": "sha512-2FXbqkygil3mZiXzEtM0IjE/UBmBNot0J1GEVrJT4JbrvwOSoEtqtO+wHbiMQELWe1eNvHoYRg2dkjOid+6JkA==",
|
|
2150
2150
|
"license": "MIT",
|
|
2151
2151
|
"dependencies": {
|
|
2152
2152
|
"debug": "^4.4.3",
|
|
@@ -2369,9 +2369,9 @@
|
|
|
2369
2369
|
}
|
|
2370
2370
|
},
|
|
2371
2371
|
"node_modules/hono": {
|
|
2372
|
-
"version": "4.13.
|
|
2373
|
-
"resolved": "https://registry.npmjs.org/hono/-/hono-4.13.
|
|
2374
|
-
"integrity": "sha512-
|
|
2372
|
+
"version": "4.13.13",
|
|
2373
|
+
"resolved": "https://registry.npmjs.org/hono/-/hono-4.13.13.tgz",
|
|
2374
|
+
"integrity": "sha512-CQ46U0ZkAGmbT/4UxdzzGJpacP2IeKgY4a5/tOI9AABbpOMfK739wfDXmv1usCk+3RkKj1hQy4/fjhiwa2xlrA==",
|
|
2375
2375
|
"license": "MIT",
|
|
2376
2376
|
"engines": {
|
|
2377
2377
|
"node": ">=16.9.0"
|
|
@@ -2745,9 +2745,9 @@
|
|
|
2745
2745
|
}
|
|
2746
2746
|
},
|
|
2747
2747
|
"node_modules/nanoid": {
|
|
2748
|
-
"version": "3.3.
|
|
2749
|
-
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.
|
|
2750
|
-
"integrity": "sha512-
|
|
2748
|
+
"version": "3.3.20",
|
|
2749
|
+
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz",
|
|
2750
|
+
"integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==",
|
|
2751
2751
|
"dev": true,
|
|
2752
2752
|
"funding": [
|
|
2753
2753
|
{
|
|
@@ -2964,9 +2964,9 @@
|
|
|
2964
2964
|
}
|
|
2965
2965
|
},
|
|
2966
2966
|
"node_modules/postcss": {
|
|
2967
|
-
"version": "8.5.
|
|
2968
|
-
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.
|
|
2969
|
-
"integrity": "sha512-
|
|
2967
|
+
"version": "8.5.29",
|
|
2968
|
+
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.29.tgz",
|
|
2969
|
+
"integrity": "sha512-49cGhUbXj8Qenv0iTMxA1cFBzxXoctpC9Ujd77t1WcbJIr6nF/eI7g/8MgxrYldFRuAXvja7xQRwavoW7kgrxQ==",
|
|
2970
2970
|
"dev": true,
|
|
2971
2971
|
"funding": [
|
|
2972
2972
|
{
|
|
@@ -2984,9 +2984,9 @@
|
|
|
2984
2984
|
],
|
|
2985
2985
|
"license": "MIT",
|
|
2986
2986
|
"dependencies": {
|
|
2987
|
-
"nanoid": "^3.3.
|
|
2987
|
+
"nanoid": "^3.3.19",
|
|
2988
2988
|
"picocolors": "^1.1.1",
|
|
2989
|
-
"source-map-js": "^1.2.
|
|
2989
|
+
"source-map-js": "^1.2.2"
|
|
2990
2990
|
},
|
|
2991
2991
|
"engines": {
|
|
2992
2992
|
"node": "^10 || ^12 || >=14"
|