borgmcp 2.0.8 → 2.0.9

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.
@@ -32,6 +32,8 @@ export interface NonClobberSyncResult {
32
32
  rejectedConflicts: string[];
33
33
  unmatchedDecisions?: string[];
34
34
  }
35
+ /** Escape cube-controlled text before it reaches Markdown or a terminal. */
36
+ export declare function escapeSyncDisplay(value: string): string;
35
37
  /**
36
38
  * Render a `NonClobberSyncResult` as an operator-facing markdown report.
37
39
  *
@@ -1 +1 @@
1
- {"version":3,"file":"sync-roles-render.d.ts","sourceRoot":"","sources":["../src/sync-roles-render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,WAAW,GAAG,UAAU,CAAC;AAE5D,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,KAAK,GAAG,UAAU,GAAG,gBAAgB,CAAC;QAC9C,SAAS,EAAE,YAAY,EAAE,CAAC;KAC3B,CAAC,CAAC;IACH,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,iBAAiB,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC1D,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAG5B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AASD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,oBAAoB,EAC5B,YAAY,EAAE,MAAM,GACnB,MAAM,CA2GR"}
1
+ {"version":3,"file":"sync-roles-render.d.ts","sourceRoot":"","sources":["../src/sync-roles-render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,WAAW,GAAG,UAAU,CAAC;AAI5D,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,KAAK,GAAG,UAAU,GAAG,gBAAgB,CAAC;QAC9C,SAAS,EAAE,YAAY,EAAE,CAAC;KAC3B,CAAC,CAAC;IACH,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,iBAAiB,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC1D,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAG5B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAYvD;AASD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,oBAAoB,EAC5B,YAAY,EAAE,MAAM,GACnB,MAAM,CA2GR"}
@@ -9,11 +9,30 @@
9
9
  *
10
10
  * The shape mirrors the worker's `NonClobberSyncResult`.
11
11
  */
12
+ const BIDI_CONTROL_RE = /\p{Bidi_Control}/u;
13
+ /** Escape cube-controlled text before it reaches Markdown or a terminal. */
14
+ export function escapeSyncDisplay(value) {
15
+ return [...value].map((char) => {
16
+ const code = char.codePointAt(0);
17
+ if (code === 0x0a)
18
+ return '⏎';
19
+ if (code < 0x20 || (code >= 0x7f && code <= 0x9f))
20
+ return `\\u{${code.toString(16)}}`;
21
+ if (BIDI_CONTROL_RE.test(char) || code === 0x2028 || code === 0x2029) {
22
+ return `\\u{${code.toString(16)}}`;
23
+ }
24
+ if (char === '`')
25
+ return '\\u{60}';
26
+ if ('\\*_[]()<>&#|~'.includes(char))
27
+ return `\\${char}`;
28
+ return char;
29
+ }).join('');
30
+ }
12
31
  /** Truncate long fragment bodies for at-a-glance diffs. */
13
32
  function trunc(s, n = 200) {
14
33
  if (s == null)
15
34
  return '(absent)';
16
- const flat = s.replace(/\n/g, '⏎');
35
+ const flat = escapeSyncDisplay(s);
17
36
  return flat.length > n ? flat.slice(0, n) + '…' : flat;
18
37
  }
19
38
  /**
@@ -45,7 +64,7 @@ export function renderSyncRolesResult(result, templateName) {
45
64
  const mode = result.dryRun
46
65
  ? '**DRY RUN** (review conflicts below; re-run with `apply: true` + a `decisions` map to commit)'
47
66
  : '**APPLIED**';
48
- const lines = [`## borg_sync-roles — ${mode}`, `Template: ${templateName}`, ''];
67
+ const lines = [`## borg_sync-roles — ${mode}`, `Template: ${escapeSyncDisplay(templateName)}`, ''];
49
68
  // Gather all fragments across roles + taxonomy for tallying.
50
69
  const allFragments = [
51
70
  ...result.roles.flatMap((r) => r.fragments),
@@ -74,7 +93,7 @@ export function renderSyncRolesResult(result, templateName) {
74
93
  : applied
75
94
  ? '✓ accepted — template version applied'
76
95
  : '↩ kept your version';
77
- lines.push(`- **${f.label}** \`${f.key}\` ${status}`);
96
+ lines.push(`- **${escapeSyncDisplay(f.label)}** \`${escapeSyncDisplay(f.key)}\` ${status}`);
78
97
  lines.push(` - cube (current): "${trunc(f.cubeValue)}"`);
79
98
  lines.push(` - template (new): "${trunc(f.templateValue)}"`);
80
99
  }
@@ -87,7 +106,7 @@ export function renderSyncRolesResult(result, templateName) {
87
106
  lines.push('These keys in your `decisions` map did not correspond to any classified conflict this run ' +
88
107
  '(typo or stale key) — their intended accept had NO effect. Check the exact keys against the conflicts above:');
89
108
  for (const k of unmatched) {
90
- lines.push(`- \`${k}\``);
109
+ lines.push(`- \`${escapeSyncDisplay(k)}\``);
91
110
  }
92
111
  lines.push('');
93
112
  }
@@ -96,17 +115,17 @@ export function renderSyncRolesResult(result, templateName) {
96
115
  lines.push(`### Additions (safe — auto-applied, zero clobber risk)`);
97
116
  for (const r of newRoles) {
98
117
  const note = result.dryRun ? '(new role — would be created)' : '✓ created';
99
- lines.push(`- new role **${r.name}** ${note}`);
118
+ lines.push(`- new role **${escapeSyncDisplay(r.name)}** ${note}`);
100
119
  }
101
120
  for (const f of adds) {
102
121
  const note = result.dryRun ? '(would be added)' : '✓ added';
103
- lines.push(`- **${f.label}** \`${f.key}\` ${note}`);
122
+ lines.push(`- **${escapeSyncDisplay(f.label)}** \`${escapeSyncDisplay(f.key)}\` ${note}`);
104
123
  }
105
124
  lines.push('');
106
125
  }
107
126
  // ── Custom roles (never touched) ──
108
127
  if (customRoles.length > 0) {
109
- lines.push(`### Custom roles (untouched): ${customRoles.map((r) => r.name).join(', ')}`);
128
+ lines.push(`### Custom roles (untouched): ${customRoles.map((r) => escapeSyncDisplay(r.name)).join(', ')}`);
110
129
  lines.push('');
111
130
  }
112
131
  // ── Clean no-op ──
@@ -1 +1 @@
1
- {"version":3,"file":"sync-roles-render.js","sourceRoot":"","sources":["../src/sync-roles-render.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sync-roles-render.js","sourceRoot":"","sources":["../src/sync-roles-render.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@ The extraction copied the monorepo's `client/src/` production boundary and top-l
8
8
 
9
9
  ## Deliberate Transformations
10
10
 
11
- - Replaced the monorepo dependency on `borgmcp-shared` with the exact audited registry release `borgmcp-shared@0.5.0` and a fresh standalone lockfile.
11
+ - Replaced the monorepo dependency on `borgmcp-shared` with the exact audited registry release `borgmcp-shared@0.5.1` and a fresh standalone lockfile.
12
12
  - Replaced local template, role-section, drone-address, and log high-water-mark implementations with `borgmcp-shared` exports.
13
13
  - Removed monorepo-only website anti-drift tests and re-anchored remaining filesystem tests to this repository.
14
14
  - Removed consumer lifecycle hooks, parent-directory deployment scripts, minification, and private integration-environment configuration.
@@ -21,8 +21,9 @@ The extraction copied the monorepo's `client/src/` production boundary and top-l
21
21
  lightweight release tag failed before packaging. The reviewed `2.0.1`
22
22
  recovery, `2.0.2`, `2.0.3`, `2.0.4`, `2.0.5`, and `2.0.6` successors were
23
23
  published and registry-verified. The immutable `2.0.7` workflow failed before
24
- package creation or npm publication, so the next candidate identity is `2.0.8`.
25
- Extraction and versioning do not authorize publication.
24
+ package creation or npm publication. The `2.0.8` successor was published and
25
+ registry-verified, so the next candidate identity is `2.0.9`. Extraction and
26
+ versioning do not authorize publication.
26
27
 
27
28
  ## Review Holds
28
29
 
@@ -37,9 +38,9 @@ artifact reaches no hosted authority.
37
38
  Local enrollment now uses the reviewed client-generated credential/retry
38
39
  contract, with a pre-request `PENDING` record in the local 0600-permission seat
39
40
  store, exact-tuple ambiguous retry, and verified activation. The contract now
40
- resolves to the audited registry `borgmcp-shared@0.5.0`. The matching
41
+ resolves to the audited registry `borgmcp-shared@0.5.1`. The matching
41
42
  `borgmcp-server@0.1.8` release is published and registry-verified. Client
42
- `borgmcp@2.0.6` is published and registry-verified. The immutable `v2.0.7`
43
+ `borgmcp@2.0.8` is published and registry-verified. The immutable `v2.0.7`
43
44
  attempt failed before publication and remains preserved. Publication of the next
44
- candidate remains gated by reviewed `v2.0.8` source, a fresh annotated tag, and
45
+ candidate remains gated by reviewed `v2.0.9` source, a fresh annotated tag, and
45
46
  exact registry integrity and signature verification.
@@ -139,7 +139,7 @@ The default discovery endpoint is `https://127.0.0.1:7091`. Explicit `--host` va
139
139
 
140
140
  ## Release status
141
141
 
142
- This self-hosted path consumes the published `borgmcp-shared@0.5.0` v3 registry
142
+ This self-hosted path consumes the published `borgmcp-shared@0.5.1` v3 registry
143
143
  release. The matching server owner-enrollment, cube-create, attach, restart, log,
144
144
  and SSE implementation must also pass the full process-level local dogfood gate.
145
145
  Until that gate opens the self-hosted path remains preview-only, and the client
package/docs/RELEASING.md CHANGED
@@ -76,6 +76,15 @@ rerun that tag, version, or workflow. The next candidate uses the unused
76
76
  `v2.0.8` identity from a fresh reviewed protected-main commit and requires the
77
77
  complete release gate again.
78
78
 
79
+ The annotated `v2.0.8` tag object
80
+ `7b5a4929534abfa97a65e278df230adfdb842d8f` peels to protected-main commit
81
+ `8bc796d8fc4e307dca593138fb080984662c7d62`. Workflow run `30012098601`, attempt 1,
82
+ successfully published that exact source as `borgmcp@2.0.8`; the registry records integrity
83
+ `sha512-az1IKG4VNwAF/8PKEVK88gdRoFFBqgtl6ObXX+CcJadavNqkwJ9UFeP8LOJ2js911mIiXEm8c4xDf6MnO0GOng==`.
84
+ Never move, replace, reuse, or rerun that tag or workflow. The next candidate
85
+ uses the unused `v2.0.9` identity from a fresh reviewed protected-main commit
86
+ and requires the complete release gate again.
87
+
79
88
  ## Release Prerequisites
80
89
 
81
90
  The standalone client was extracted from private-monorepo commit
@@ -85,7 +94,7 @@ Before creating the release tag, independently verify all of these conditions:
85
94
  - the extraction review confirms no private backend secrets, deployment
86
95
  configuration, customer data, local state, or duplicated shared contracts
87
96
  entered the public package;
88
- - the exact audited registry dependency `borgmcp-shared@0.5.0` remains locked to
97
+ - the exact audited registry dependency `borgmcp-shared@0.5.1` remains locked to
89
98
  its canonical tarball and integrity;
90
99
  - the client and matching server pass the complete local dogfood gate;
91
100
  - the selected stable client version is unused and the exact release commit is
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "borgmcp",
3
- "version": "2.0.8",
3
+ "version": "2.0.9",
4
4
  "description": "Coordinate AI coding agents in shared cubes. Works with Claude Code, Codex, and OpenCode.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -68,7 +68,7 @@
68
68
  },
69
69
  "dependencies": {
70
70
  "@modelcontextprotocol/sdk": "^1.0.4",
71
- "borgmcp-shared": "0.5.0",
71
+ "borgmcp-shared": "0.5.1",
72
72
  "chalk": "^5.3.0",
73
73
  "prompts": "^2.4.2",
74
74
  "which": "^4.0.0"
package/src/index.ts CHANGED
@@ -43,11 +43,14 @@ import {
43
43
  patchTaxonomyClass,
44
44
  deleteRole,
45
45
  getCube,
46
+ getCubeForManagement,
47
+ resolveLocalManageAuthority,
46
48
  listRoles,
47
49
  syncRoles,
48
50
  applyTemplate,
49
51
  whoami,
50
52
  roleRationale,
53
+ type LocalManageAuthority,
51
54
  } from './remote-client.js';
52
55
  import {
53
56
  getTemplate,
@@ -142,9 +145,38 @@ import {
142
145
  */
143
146
  async function applyTemplateToCube(
144
147
  cubeId: string,
145
- template: Template
148
+ template: Template,
149
+ authority?: LocalManageAuthority,
146
150
  ): Promise<{ created: number; updated: number }> {
147
- return await applyTemplate(cubeId, template.name);
151
+ return await applyTemplate(cubeId, template.name, authority);
152
+ }
153
+
154
+ export async function runApplyTemplateTool(
155
+ cubeId: string,
156
+ template: Template,
157
+ authority: LocalManageAuthority,
158
+ deps: {
159
+ applyTemplate?: typeof applyTemplate;
160
+ getCubeForManagement?: typeof getCubeForManagement;
161
+ updateCube?: typeof updateCube;
162
+ } = {},
163
+ ): Promise<{ summary: { created: number; updated: number }; cubeDirectiveNote: string }> {
164
+ const apply = deps.applyTemplate ?? applyTemplate;
165
+ const read = deps.getCubeForManagement ?? getCubeForManagement;
166
+ const update = deps.updateCube ?? updateCube;
167
+ const summary = await apply(cubeId, template.name, authority);
168
+ const cubeForRules = await read(cubeId, {
169
+ operation: `read template target ${JSON.stringify(template.name)}`,
170
+ cubeName: cubeId === authority.active.cubeId ? authority.active.name : cubeId,
171
+ noMutation: 'No template fragments were changed.',
172
+ }, authority.active, authority.connection);
173
+ const newCubeDirective = resolveCubeDirectiveForApply(cubeForRules.cube_directive, template);
174
+ if (newCubeDirective === null) return { summary, cubeDirectiveNote: '' };
175
+ await update(cubeId, { cube_directive: newCubeDirective }, authority.active, authority.connection);
176
+ return {
177
+ summary,
178
+ cubeDirectiveNote: ' Template cube directive applied (cube directive was empty).',
179
+ };
148
180
  }
149
181
 
150
182
  /**
@@ -1119,18 +1151,13 @@ export async function main() {
1119
1151
  if (!template) {
1120
1152
  throw new Error(`Unknown template "${templateName}". Available: ${listTemplateNames().join(', ')}`);
1121
1153
  }
1122
- const summary = await applyTemplateToCube(cubeId, template);
1123
-
1124
- // Sprint 14: optionally write template's cube_directive to the
1125
- // cube. No-clobber discipline only fills empty directives,
1126
- // never overwrites operator-customized text.
1127
- let cubeDirectiveNote = '';
1128
- const cubeForRules = await getCube(cubeId);
1129
- const newCubeDirective = resolveCubeDirectiveForApply(cubeForRules.cube_directive, template);
1130
- if (newCubeDirective !== null) {
1131
- await updateCube(cubeId, { cube_directive: newCubeDirective });
1132
- cubeDirectiveNote = ' Template cube directive applied (cube directive was empty).';
1133
- }
1154
+ const active = await requireActiveCube();
1155
+ const authority = await resolveLocalManageAuthority(active, {
1156
+ operation: `apply template ${JSON.stringify(templateName)}`,
1157
+ cubeName: cubeId === active.cubeId ? active.name : cubeId,
1158
+ noMutation: 'No template fragments were changed.',
1159
+ });
1160
+ const { summary, cubeDirectiveNote } = await runApplyTemplateTool(cubeId, template, authority);
1134
1161
 
1135
1162
  return { content: [{ type: 'text', text: `Applied template **${templateName}** to cube ${cubeId} — ${summary.created} role(s) created, ${summary.updated} updated.${cubeDirectiveNote}` }] };
1136
1163
  }