borgmcp 3.11.0 → 3.11.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode-launch-trust.d.ts","sourceRoot":"","sources":["../src/opencode-launch-trust.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,wBAAwB,aAAa,CAAC;AACnD,eAAO,MAAM,4BAA4B,6BAA6B,CAAC;AACvE,eAAO,MAAM,4BAA4B,6BAA6B,CAAC;AACvE,eAAO,MAAM,oCAAoC,qCAAqC,CAAC;AACvF,eAAO,MAAM,kCAAkC,mCAA0C,CAAC;AAE1F,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAMD,wBAAgB,yBAAyB,CAAC,SAAS,GAAE,OAAO,CAAC,mBAAmB,CAAM,GAAG,mBAAmB,CAY3G;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAQxE;AAED,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,GAAG,IAAI,CAIhF"}
@@ -0,0 +1,40 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ export const OPENCODE_SERVER_USERNAME = 'opencode';
3
+ export const OPENCODE_SERVER_USERNAME_ENV = 'OPENCODE_SERVER_USERNAME';
4
+ export const OPENCODE_SERVER_PASSWORD_ENV = 'OPENCODE_SERVER_PASSWORD';
5
+ export const BORG_OPENCODE_LAUNCH_CORRELATION_ENV = 'BORG_OPENCODE_LAUNCH_CORRELATION';
6
+ export const OPENCODE_SERVER_PASSWORD_REFERENCE = `{env:${OPENCODE_SERVER_PASSWORD_ENV}}`;
7
+ function random256BitIdentity() {
8
+ return randomBytes(32).toString('base64url');
9
+ }
10
+ export function createOpenCodeLaunchTrust(overrides = {}) {
11
+ const trust = {
12
+ apiPassword: overrides.apiPassword ?? random256BitIdentity(),
13
+ correlationIdentity: overrides.correlationIdentity ?? random256BitIdentity(),
14
+ };
15
+ if (!isOpenCode256BitIdentity(trust.apiPassword) || !isOpenCode256BitIdentity(trust.correlationIdentity)) {
16
+ throw new Error('OpenCode launch trust must contain independent 256-bit identities');
17
+ }
18
+ if (trust.apiPassword === trust.correlationIdentity) {
19
+ throw new Error('OpenCode API password and correlation identity must be independent');
20
+ }
21
+ return trust;
22
+ }
23
+ export function isOpenCode256BitIdentity(value) {
24
+ if (typeof value !== 'string' || value.length === 0)
25
+ return false;
26
+ try {
27
+ const decoded = Buffer.from(value, 'base64url');
28
+ return decoded.length === 32 && decoded.toString('base64url') === value;
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ }
34
+ export function openCodeApiPasswordFromEnv(env) {
35
+ if (env[OPENCODE_SERVER_USERNAME_ENV] !== OPENCODE_SERVER_USERNAME)
36
+ return null;
37
+ const password = env[OPENCODE_SERVER_PASSWORD_ENV];
38
+ return isOpenCode256BitIdentity(password) ? password : null;
39
+ }
40
+ //# sourceMappingURL=opencode-launch-trust.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode-launch-trust.js","sourceRoot":"","sources":["../src/opencode-launch-trust.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,CAAC,MAAM,wBAAwB,GAAG,UAAU,CAAC;AACnD,MAAM,CAAC,MAAM,4BAA4B,GAAG,0BAA0B,CAAC;AACvE,MAAM,CAAC,MAAM,4BAA4B,GAAG,0BAA0B,CAAC;AACvE,MAAM,CAAC,MAAM,oCAAoC,GAAG,kCAAkC,CAAC;AACvF,MAAM,CAAC,MAAM,kCAAkC,GAAG,QAAQ,4BAA4B,GAAG,CAAC;AAO1F,SAAS,oBAAoB;IAC3B,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,YAA0C,EAAE;IACpF,MAAM,KAAK,GAAG;QACZ,WAAW,EAAE,SAAS,CAAC,WAAW,IAAI,oBAAoB,EAAE;QAC5D,mBAAmB,EAAE,SAAS,CAAC,mBAAmB,IAAI,oBAAoB,EAAE;KAC7E,CAAC;IACF,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACzG,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;IACvF,CAAC;IACD,IAAI,KAAK,CAAC,WAAW,KAAK,KAAK,CAAC,mBAAmB,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;IACxF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAc;IACrD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAClE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAChD,OAAO,OAAO,CAAC,MAAM,KAAK,EAAE,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,KAAK,CAAC;IAC1E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,GAAsB;IAC/D,IAAI,GAAG,CAAC,4BAA4B,CAAC,KAAK,wBAAwB;QAAE,OAAO,IAAI,CAAC;IAChF,MAAM,QAAQ,GAAG,GAAG,CAAC,4BAA4B,CAAC,CAAC;IACnD,OAAO,wBAAwB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9D,CAAC"}
@@ -5,6 +5,7 @@ export declare const OPENCODE_COMPATIBILITY: {
5
5
  export declare const OPENCODE_INJECTED_ENTRY_METADATA_KEY = "borgOpenCodeInjectedEntry";
6
6
  export declare const OPENCODE_WAKE_IDENTITY_METADATA_KEY = "borgOpenCodeWakeIdentity";
7
7
  export declare const OPENCODE_RECOVERY_METADATA_KEY = "borgOpenCodeSessionOrientation";
8
+ export declare const OPENCODE_LAUNCH_CORRELATION_METADATA_KEY = "borgOpenCodeLaunchCorrelation";
8
9
  export interface OpenCodePluginCoreDeps {
9
10
  defer(task: () => Promise<void>): void;
10
11
  wait(milliseconds: number): Promise<void>;
@@ -22,6 +23,8 @@ export interface OpenCodePluginCoreOptions {
22
23
  confirmationPollAttempts: number;
23
24
  pollDelayMs: number;
24
25
  compactFallback: string;
26
+ launchCorrelationMetadataKey: string;
27
+ launchCorrelationIdentity: string;
25
28
  }
26
29
  /** Pure, dependency-injected behavior core. Its emitted JavaScript function
27
30
  * body is also embedded in the installed self-contained plugin. */
@@ -1 +1 @@
1
- {"version":3,"file":"opencode-plugin.d.ts","sourceRoot":"","sources":["../src/opencode-plugin.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,sBAAsB;;;CAQzB,CAAC;AAKX,eAAO,MAAM,oCAAoC,8BAA8B,CAAC;AAChF,eAAO,MAAM,mCAAmC,6BAA6B,CAAC;AAC9E,eAAO,MAAM,8BAA8B,mCAAmC,CAAC;AAG/E,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACvC,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAChD,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChE,YAAY,CACV,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,MAAM,EACvB,YAAY,EAAE,MAAM,OAAO,GAC1B,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB,KAAK,CAAC,QAAQ,EAAE,SAAS,GAAG,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC;CAChD;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,wBAAwB,EAAE,MAAM,CAAC;IACjC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,wBAAwB,EAAE,MAAM,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;mEACmE;AACnE,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,sBAAsB,EAC5B,OAAO,EAAE,yBAAyB;uBAsDP,GAAG,KAAG,OAAO,CAAC,IAAI,CAAC;gDAQlC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,UACrB;QAAE,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,KAC5B,OAAO,CAAC,IAAI,CAAC;4BAUP;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,UACpB;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,GAAG,EAAE,CAAA;KAAE,KACzC,OAAO,CAAC,IAAI,CAAC;EA6BnB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAmD7D;AAED,eAAO,MAAM,kBAAkB,QAA6C,CAAC;AAE7E,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,MAAuB,GAAG,MAAM,CAE3E;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CACb,GAAG,IAAI,CAsBZ"}
1
+ {"version":3,"file":"opencode-plugin.d.ts","sourceRoot":"","sources":["../src/opencode-plugin.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,sBAAsB;;;CAQzB,CAAC;AAKX,eAAO,MAAM,oCAAoC,8BAA8B,CAAC;AAChF,eAAO,MAAM,mCAAmC,6BAA6B,CAAC;AAC9E,eAAO,MAAM,8BAA8B,mCAAmC,CAAC;AAC/E,eAAO,MAAM,wCAAwC,kCAAkC,CAAC;AAGxF,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACvC,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAChD,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChE,YAAY,CACV,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,MAAM,EACvB,YAAY,EAAE,MAAM,OAAO,GAC1B,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB,KAAK,CAAC,QAAQ,EAAE,SAAS,GAAG,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC;CAChD;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,wBAAwB,EAAE,MAAM,CAAC;IACjC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,wBAAwB,EAAE,MAAM,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,4BAA4B,EAAE,MAAM,CAAC;IACrC,yBAAyB,EAAE,MAAM,CAAC;CACnC;AAED;mEACmE;AACnE,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,sBAAsB,EAC5B,OAAO,EAAE,yBAAyB;uBAuDP,GAAG,KAAG,OAAO,CAAC,IAAI,CAAC;gDAQlC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,UACrB;QAAE,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,KAC5B,OAAO,CAAC,IAAI,CAAC;4BAUP;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,UACpB;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,GAAG,EAAE,CAAA;KAAE,KACzC,OAAO,CAAC,IAAI,CAAC;EAkDnB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAwD7D;AAED,eAAO,MAAM,kBAAkB,QAA6C,CAAC;AAE7E,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,MAAuB,GAAG,MAAM,CAE3E;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CACb,GAAG,IAAI,CAsBZ"}
@@ -17,12 +17,14 @@ const COMPACT_FALLBACK = '## Borg Cube\nYou are in a Borg MCP multi-agent coordi
17
17
  export const OPENCODE_INJECTED_ENTRY_METADATA_KEY = 'borgOpenCodeInjectedEntry';
18
18
  export const OPENCODE_WAKE_IDENTITY_METADATA_KEY = 'borgOpenCodeWakeIdentity';
19
19
  export const OPENCODE_RECOVERY_METADATA_KEY = 'borgOpenCodeSessionOrientation';
20
+ export const OPENCODE_LAUNCH_CORRELATION_METADATA_KEY = 'borgOpenCodeLaunchCorrelation';
20
21
  const PLUGIN_REL_PATH = path.join('.config', 'opencode', 'plugins', 'borg-orient.js');
21
22
  /** Pure, dependency-injected behavior core. Its emitted JavaScript function
22
23
  * body is also embedded in the installed self-contained plugin. */
23
24
  export function createOpenCodePluginCore(deps, options) {
24
25
  const claimedSessions = new Set();
25
26
  const humanPromptSessions = new Set();
27
+ let launchCorrelationAttached = false;
26
28
  const textParts = (message) => Array.isArray(message?.parts)
27
29
  ? message.parts.filter((part) => part?.type === 'text' && typeof part.text === 'string')
28
30
  : [];
@@ -93,7 +95,25 @@ export function createOpenCodePluginCore(deps, options) {
93
95
  'chat.message': async (input, output) => {
94
96
  if (!options.enabled)
95
97
  return;
96
- const current = { info: { role: 'user' }, parts: [...output.parts] };
98
+ let current = { info: { role: 'user' }, parts: [...output.parts] };
99
+ if (!launchCorrelationAttached &&
100
+ options.launchCorrelationIdentity &&
101
+ !isInjectedEntry(current) &&
102
+ !isOwnedRecovery(current)) {
103
+ const index = output.parts.findIndex((part) => part?.type === 'text' && typeof part.text === 'string');
104
+ if (index >= 0) {
105
+ const part = output.parts[index];
106
+ output.parts[index] = {
107
+ ...part,
108
+ metadata: {
109
+ ...(part.metadata && typeof part.metadata === 'object' ? part.metadata : {}),
110
+ [options.launchCorrelationMetadataKey]: options.launchCorrelationIdentity,
111
+ },
112
+ };
113
+ launchCorrelationAttached = true;
114
+ current = { info: { role: 'user' }, parts: [...output.parts] };
115
+ }
116
+ }
97
117
  if (!isInjectedEntry(current) && !isOwnedRecovery(current)) {
98
118
  // chat.message fires before the user message is persisted. Record the
99
119
  // human turn synchronously so recovery cannot race that short gap.
@@ -128,6 +148,7 @@ export function buildBorgPluginSource(version) {
128
148
  const createCore = ${createOpenCodePluginCore.toString()};
129
149
  const evaluateAudit = ${evaluateLogAudit.toString()};
130
150
  export default async function (ctx) {
151
+ const launchCorrelationIdentity = process.env.BORG_OPENCODE_LAUNCH_CORRELATION || '';
131
152
  const runRegen = async (source) => {
132
153
  const input = JSON.stringify({ source });
133
154
  const result = await ctx.$\`printf '%s' \${input} | borg-regen\`.quiet().nothrow();
@@ -167,8 +188,12 @@ export default async function (ctx) {
167
188
  confirmationPollAttempts: 6,
168
189
  pollDelayMs: 200,
169
190
  compactFallback: COMPACT_FALLBACK,
191
+ launchCorrelationMetadataKey: OPENCODE_LAUNCH_CORRELATION_METADATA_KEY,
170
192
  })},
171
193
  enabled: process.env.BORG_SESSION === '1',
194
+ launchCorrelationIdentity: /^[A-Za-z0-9_-]{43}$/.test(launchCorrelationIdentity)
195
+ ? launchCorrelationIdentity
196
+ : '',
172
197
  });
173
198
  }
174
199
  `;
@@ -1 +1 @@
1
- {"version":3,"file":"opencode-plugin.js","sourceRoot":"","sources":["../src/opencode-plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"opencode-plugin.js","sourceRoot":"","sources":["../src/opencode-plugin.ts"],"names":[],"mappings":"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"}
@@ -26,7 +26,7 @@ export interface ConfigMutationTarget {
26
26
  * agent CLIs. Paths mirror `config-utils.ts`:
27
27
  * Claude Code: ~/.claude.json (MCP server) + ~/.claude/settings.json (hook)
28
28
  * Codex: ~/.codex/config.toml (MCP server) + ~/.codex/hooks.json (hooks)
29
- * OpenCode: ~/.config/opencode/opencode.json (MCP server)
29
+ * OpenCode: effective global config under ~/.config/opencode/ (MCP server)
30
30
  */
31
31
  export declare function configMutationTargets(deps: {
32
32
  claude: boolean;
@@ -20,7 +20,7 @@
20
20
  * agent CLIs. Paths mirror `config-utils.ts`:
21
21
  * Claude Code: ~/.claude.json (MCP server) + ~/.claude/settings.json (hook)
22
22
  * Codex: ~/.codex/config.toml (MCP server) + ~/.codex/hooks.json (hooks)
23
- * OpenCode: ~/.config/opencode/opencode.json (MCP server)
23
+ * OpenCode: effective global config under ~/.config/opencode/ (MCP server)
24
24
  */
25
25
  export function configMutationTargets(deps) {
26
26
  const targets = [];
@@ -46,8 +46,8 @@ export function configMutationTargets(deps) {
46
46
  }
47
47
  if (deps.opencode) {
48
48
  targets.push({
49
- file: '~/.config/opencode/opencode.json',
50
- change: 'registers the borg MCP server (with BORG_SESSION activation)',
49
+ file: '~/.config/opencode/',
50
+ change: 'updates the effective global OpenCode configuration to register the borg MCP server (with BORG_SESSION activation)',
51
51
  });
52
52
  }
53
53
  return targets;
@@ -1 +1 @@
1
- {"version":3,"file":"setup-confirm.js","sourceRoot":"","sources":["../src/setup-confirm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAIrC;IACC,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,gBAAgB;YACtB,MAAM,EAAE,+BAA+B;SACxC,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,yBAAyB;YAC/B,MAAM,EAAE,8BAA8B;SACvC,CAAC,CAAC;IACL,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,sBAAsB;YAC5B,MAAM,EAAE,+BAA+B;SACxC,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,qBAAqB;YAC3B,MAAM,EAAE,4CAA4C;SACrD,CAAC,CAAC;IACL,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,kCAAkC;YACxC,MAAM,EAAE,8DAA8D;SACvE,CAAC,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,8BAA8B,CAC5C,OAA+B;IAE/B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;IACjF,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAC7C,CAAC;IACD,KAAK,CAAC,IAAI,CACR,gFAAgF,CACjF,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAiBD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAA+B;IAE/B,IAAI,CAAC,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC,CAAC,gCAAgC;IACnE,IAAI,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC,CAAC,2BAA2B;IAC3D,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,+BAA+B;IAChE,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAc;IACzC,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,oBAAoB,CAAC,IASpC;IACC,OAAO,CACL,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACtE,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACnE,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAC/C,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"setup-confirm.js","sourceRoot":"","sources":["../src/setup-confirm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAIrC;IACC,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,gBAAgB;YACtB,MAAM,EAAE,+BAA+B;SACxC,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,yBAAyB;YAC/B,MAAM,EAAE,8BAA8B;SACvC,CAAC,CAAC;IACL,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,sBAAsB;YAC5B,MAAM,EAAE,+BAA+B;SACxC,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,qBAAqB;YAC3B,MAAM,EAAE,4CAA4C;SACrD,CAAC,CAAC;IACL,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,qBAAqB;YAC3B,MAAM,EAAE,oHAAoH;SAC7H,CAAC,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,8BAA8B,CAC5C,OAA+B;IAE/B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;IACjF,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAC7C,CAAC;IACD,KAAK,CAAC,IAAI,CACR,gFAAgF,CACjF,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAiBD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAA+B;IAE/B,IAAI,CAAC,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC,CAAC,gCAAgC;IACnE,IAAI,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC,CAAC,2BAA2B;IAC3D,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,+BAA+B;IAChE,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAc;IACzC,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,oBAAoB,CAAC,IASpC;IACC,OAAO,CACL,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACtE,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACnE,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAC/C,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "borgmcp",
3
- "version": "3.11.0",
3
+ "version": "3.11.1",
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",
@@ -45,6 +45,12 @@ import {
45
45
  } from './gc-orphan-inboxes.js';
46
46
  import { installBorgPlugin } from './opencode-plugin.js';
47
47
  import { allocateOpenCodePort, connectOpenCodeDrone, createOpenCodeLaunchKickoff, injectInitialKickoff } from './opencode-drone.js';
48
+ import {
49
+ BORG_OPENCODE_LAUNCH_CORRELATION_ENV,
50
+ OPENCODE_SERVER_PASSWORD_ENV,
51
+ OPENCODE_SERVER_USERNAME,
52
+ OPENCODE_SERVER_USERNAME_ENV,
53
+ } from './opencode-launch-trust.js';
48
54
  import { ensureCliMcpConfigured } from './ensure-mcp-config.js';
49
55
  import { normalizeServerEndpoint } from './server-endpoint.js';
50
56
  import { DEFAULT_LOCAL_SERVER_ORIGIN } from './server-handshake.js';
@@ -2170,9 +2176,9 @@ export async function runAssimilate(
2170
2176
  monitorClause,
2171
2177
  codexWakePathClause,
2172
2178
  });
2173
- // Keep Claude and Codex on the unmodified shared kickoff. Only OpenCode
2174
- // receives a nonce-bearing copy so the later MCP connection can identify
2175
- // this exact launch among same-text sessions.
2179
+ // Keep launch trust separate from the shared kickoff. OpenCode receives the
2180
+ // same prompt text; its plugin adds the correlation identity to hidden
2181
+ // TextPart metadata instead of argv or prompt content.
2176
2182
  let openCodeKickoff: ReturnType<typeof createOpenCodeLaunchKickoff> | null = null;
2177
2183
  let dronePort: number | undefined;
2178
2184
  launchArgs = [kickoff];
@@ -2202,6 +2208,9 @@ export async function runAssimilate(
2202
2208
  installBorgPlugin();
2203
2209
  const cwd = agentCwd;
2204
2210
  openCodeKickoff = createOpenCodeLaunchKickoff(kickoff);
2211
+ childEnv[OPENCODE_SERVER_USERNAME_ENV] = OPENCODE_SERVER_USERNAME;
2212
+ childEnv[OPENCODE_SERVER_PASSWORD_ENV] = openCodeKickoff.apiPassword;
2213
+ childEnv[BORG_OPENCODE_LAUNCH_CORRELATION_ENV] = openCodeKickoff.correlationIdentity;
2205
2214
  launchArgs = buildOpenCodeLaunchArgs(cwd, dronePort, openCodeKickoff.prompt);
2206
2215
  }
2207
2216
  // gh#673 P1: mark the launched agent session as borg-launched so the
@@ -2231,6 +2240,7 @@ export async function runAssimilate(
2231
2240
  const serverUrl = `http://127.0.0.1:${dronePort}`;
2232
2241
  connectOpenCodeDrone({
2233
2242
  serverUrl,
2243
+ apiPassword: launchKickoff.apiPassword,
2234
2244
  directory: agentCwd,
2235
2245
  droneLabel: result.drone_label,
2236
2246
  cubeName: cubeDetail.name,
package/src/claude.ts CHANGED
@@ -108,6 +108,12 @@ import { ensureCliMcpConfigured } from './ensure-mcp-config.js';
108
108
  import { configureResolvedCli } from './resolved-cli-config.js';
109
109
  import { installBorgPlugin } from './opencode-plugin.js';
110
110
  import { allocateOpenCodePort, connectOpenCodeDrone, createOpenCodeLaunchKickoff, injectInitialKickoff, openCodeLaunchBinding } from './opencode-drone.js';
111
+ import {
112
+ BORG_OPENCODE_LAUNCH_CORRELATION_ENV,
113
+ OPENCODE_SERVER_PASSWORD_ENV,
114
+ OPENCODE_SERVER_USERNAME,
115
+ OPENCODE_SERVER_USERNAME_ENV,
116
+ } from './opencode-launch-trust.js';
111
117
  import { buildOpenCodeLaunchArgs, defaultApprovalIo, resolveLaunchBorgApprovals } from './cli-tool-approval.js';
112
118
  import { isClientOwnedCubeInitArgv, runEarlyServerFacade } from './server-facade.js';
113
119
  import { runEarlyUpdate } from './update-cmd.js';
@@ -159,7 +165,13 @@ export function launchOpenCodeProcess(options: {
159
165
  process: ReturnType<typeof spawn>;
160
166
  } {
161
167
  const plan = createOpenCodeLaunchPlan(options.cwd, options.port, options.prompt, options.passthroughArgs);
162
- const launchEnv = { ...options.env, BORG_OPENCODE_PORT: plan.envPort };
168
+ const launchEnv = {
169
+ ...options.env,
170
+ BORG_OPENCODE_PORT: plan.envPort,
171
+ [OPENCODE_SERVER_USERNAME_ENV]: OPENCODE_SERVER_USERNAME,
172
+ [OPENCODE_SERVER_PASSWORD_ENV]: options.kickoff.apiPassword,
173
+ [BORG_OPENCODE_LAUNCH_CORRELATION_ENV]: options.kickoff.correlationIdentity,
174
+ };
163
175
  // OpenCode's bind can still race this allocation; client#298 tracks the
164
176
  // residual pre-bind window outside this slice.
165
177
  const child = (options.spawnProcess ?? spawn)('opencode', plan.launchArgs, {
@@ -169,6 +181,7 @@ export function launchOpenCodeProcess(options: {
169
181
  });
170
182
  (options.connect ?? connectOpenCodeDrone)({
171
183
  serverUrl: plan.serverUrl,
184
+ apiPassword: options.kickoff.apiPassword,
172
185
  directory: options.cwd,
173
186
  droneLabel: options.droneLabel,
174
187
  cubeName: options.cubeName,
@@ -626,9 +639,8 @@ async function main() {
626
639
  monitorClause,
627
640
  codexWakePathClause,
628
641
  });
629
- // This stays separate from the shared kickoff so Claude and Codex preserve
630
- // their existing launch prompts. OpenCode records this nonce-bearing copy
631
- // and later uses the nonce to bind its separately spawned MCP child.
642
+ // This stays separate from the shared kickoff so OpenCode can carry
643
+ // launch-only API and correlation identities outside argv and prompt text.
632
644
  let openCodeKickoff: ReturnType<typeof createOpenCodeLaunchKickoff> | null = null;
633
645
  let openCodePort: number | undefined;
634
646
  let launchArgs: string[];
@@ -24,6 +24,10 @@ import { shellEscape } from './shell-escape.js';
24
24
  import { BORG_STATE_ROOT_ENV, borgAgentConfigEnv, borgHomeRoot } from './private-root.js';
25
25
  import type { LaunchAccessPaths } from './launch-access.js';
26
26
  import { BORG_LAUNCH_EXPECTED_SEAT_ENV } from './cubes.js';
27
+ import {
28
+ OPENCODE_SERVER_PASSWORD_ENV,
29
+ OPENCODE_SERVER_PASSWORD_REFERENCE,
30
+ } from './opencode-launch-trust.js';
27
31
 
28
32
  // Get __dirname equivalent in ESM
29
33
  const __filename = fileURLToPath(import.meta.url);
@@ -53,6 +57,7 @@ const CLAUDE_CONFIG_PATH = path.join(CONFIG_HOME, '.claude.json');
53
57
  const CODEX_CONFIG_PATH = path.join(CONFIG_HOME, '.codex', 'config.toml');
54
58
  const CODEX_HOOKS_PATH = path.join(CONFIG_HOME, '.codex', 'hooks.json');
55
59
  const OPENCODE_CONFIG_PATH = path.join(CONFIG_HOME, '.config', 'opencode', 'opencode.json');
60
+ const OPENCODE_GLOBAL_CONFIG_FILENAMES = ['config.json', 'opencode.json', 'opencode.jsonc'] as const;
56
61
  const MCP_SERVER_NAME = 'borg';
57
62
 
58
63
  function settingsPath(): string {
@@ -80,6 +85,125 @@ function readJsonFile(p: string): any {
80
85
  return JSON.parse(text);
81
86
  }
82
87
 
88
+ function parseJsonc(text: string): unknown {
89
+ let stripped = '';
90
+ let inString = false;
91
+ let escaped = false;
92
+ let lineComment = false;
93
+ let blockComment = false;
94
+
95
+ for (let index = 0; index < text.length; index++) {
96
+ const char = text[index];
97
+ const next = text[index + 1];
98
+ if (lineComment) {
99
+ if (char === '\n' || char === '\r') {
100
+ lineComment = false;
101
+ stripped += char;
102
+ } else {
103
+ stripped += ' ';
104
+ }
105
+ continue;
106
+ }
107
+ if (blockComment) {
108
+ if (char === '*' && next === '/') {
109
+ stripped += ' ';
110
+ index++;
111
+ blockComment = false;
112
+ } else {
113
+ stripped += char === '\n' || char === '\r' ? char : ' ';
114
+ }
115
+ continue;
116
+ }
117
+ if (inString) {
118
+ stripped += char;
119
+ if (escaped) escaped = false;
120
+ else if (char === '\\') escaped = true;
121
+ else if (char === '"') inString = false;
122
+ continue;
123
+ }
124
+ if (char === '"') {
125
+ inString = true;
126
+ stripped += char;
127
+ continue;
128
+ }
129
+ if (char === '/' && next === '/') {
130
+ stripped += ' ';
131
+ index++;
132
+ lineComment = true;
133
+ continue;
134
+ }
135
+ if (char === '/' && next === '*') {
136
+ stripped += ' ';
137
+ index++;
138
+ blockComment = true;
139
+ continue;
140
+ }
141
+ stripped += char;
142
+ }
143
+
144
+ if (inString || blockComment) throw new SyntaxError('unterminated JSONC token');
145
+
146
+ let withoutTrailingCommas = '';
147
+ inString = false;
148
+ escaped = false;
149
+ for (let index = 0; index < stripped.length; index++) {
150
+ const char = stripped[index];
151
+ if (inString) {
152
+ withoutTrailingCommas += char;
153
+ if (escaped) escaped = false;
154
+ else if (char === '\\') escaped = true;
155
+ else if (char === '"') inString = false;
156
+ continue;
157
+ }
158
+ if (char === '"') {
159
+ inString = true;
160
+ withoutTrailingCommas += char;
161
+ continue;
162
+ }
163
+ if (char === ',') {
164
+ let lookahead = index + 1;
165
+ while (/\s/.test(stripped[lookahead] ?? '')) lookahead++;
166
+ if (stripped[lookahead] === '}' || stripped[lookahead] === ']') continue;
167
+ }
168
+ withoutTrailingCommas += char;
169
+ }
170
+
171
+ return JSON.parse(withoutTrailingCommas.replace(/^\uFEFF/, ''));
172
+ }
173
+
174
+ function isPlainRecord(value: unknown): value is Record<string, unknown> {
175
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
176
+ }
177
+
178
+ function mergeOpenCodeConfigValue(target: unknown, source: unknown): unknown {
179
+ if (!isPlainRecord(target) || !isPlainRecord(source)) return source;
180
+ const merged = Object.assign(Object.create(null) as Record<string, unknown>, target);
181
+ for (const [key, value] of Object.entries(source)) {
182
+ merged[key] = key in merged ? mergeOpenCodeConfigValue(merged[key], value) : value;
183
+ }
184
+ return merged;
185
+ }
186
+
187
+ function readOpenCodeGlobalConfig(configPath: string): Record<string, unknown> {
188
+ const basename = path.basename(configPath);
189
+ const paths = OPENCODE_GLOBAL_CONFIG_FILENAMES.includes(
190
+ basename as typeof OPENCODE_GLOBAL_CONFIG_FILENAMES[number],
191
+ )
192
+ ? OPENCODE_GLOBAL_CONFIG_FILENAMES.map((filename) => path.join(path.dirname(configPath), filename))
193
+ : [configPath];
194
+ let merged: unknown = {};
195
+ for (const candidate of paths) {
196
+ if (!fs.existsSync(candidate)) continue;
197
+ const text = fs.readFileSync(candidate, 'utf-8');
198
+ if (text.length === 0) continue;
199
+ const parsed = parseJsonc(text);
200
+ if (!isPlainRecord(parsed)) throw new TypeError(`OpenCode config is not an object: ${candidate}`);
201
+ merged = mergeOpenCodeConfigValue(merged, parsed);
202
+ }
203
+ if (!isPlainRecord(merged)) throw new TypeError('OpenCode global config is not an object');
204
+ return merged;
205
+ }
206
+
83
207
  function writeJsonFile(p: string, data: any): void {
84
208
  fs.mkdirSync(path.dirname(p), { recursive: true });
85
209
  fs.writeFileSync(p, JSON.stringify(data, null, 2) + '\n', 'utf-8');
@@ -1162,22 +1286,18 @@ export function isCodexUserPromptSubmitHookRegistered(hooksPath: string = CODEX_
1162
1286
  // ─── OpenCode MCP integration ────────────────────────────────────────────
1163
1287
 
1164
1288
  /**
1165
- * Detect whether the borg MCP server is already registered in the opencode
1166
- * config (`~/.config/opencode/opencode.json` `mcp.borg`).
1289
+ * Detect whether the borg MCP server is registered in OpenCode's effective
1290
+ * global config. OpenCode 1.18.15 loads `config.json`, `opencode.json`, then
1291
+ * `opencode.jsonc`, merging later files over earlier ones.
1167
1292
  *
1168
- * Reads the config as JSON and checks for a `mcp.borg` entry with
1293
+ * Reads JSON or JSONC and checks the effective `mcp.borg` entry for
1169
1294
  * `type: "local"`. Safe-default: any read error returns `false`.
1170
1295
  */
1171
1296
  export function isOpenCodeMcpServerConfigured(
1172
1297
  configPath: string = path.join(borgHomeRoot(), '.config', 'opencode', 'opencode.json')
1173
1298
  ): boolean {
1174
1299
  try {
1175
- if (!fs.existsSync(configPath)) return false;
1176
- const text = fs.readFileSync(configPath, 'utf-8');
1177
- if (!text.trim()) return false;
1178
- const parsed = JSON.parse(text);
1179
- if (!parsed || typeof parsed !== 'object') return false;
1180
- const borgServer = (parsed as any).mcp?.borg;
1300
+ const borgServer = (readOpenCodeGlobalConfig(configPath) as any).mcp?.borg;
1181
1301
  if (!borgServer || typeof borgServer !== 'object') return false;
1182
1302
  return borgServer.type === 'local';
1183
1303
  } catch {
@@ -1186,22 +1306,24 @@ export function isOpenCodeMcpServerConfigured(
1186
1306
  }
1187
1307
 
1188
1308
  /**
1189
- * Launch-time OpenCode registration check. Ordinary launches retain the
1190
- * existing configured/not-configured behavior. A targeted `borg launch`,
1191
- * identified by its non-empty expected-seat marker, additionally requires the
1192
- * config substitution that carries that marker into OpenCode's MCP child.
1309
+ * Launch-time OpenCode registration check. Every launch requires the exact
1310
+ * password substitution that carries its ephemeral credential into OpenCode's
1311
+ * MCP child. A targeted `borg launch`, identified by its non-empty expected-seat
1312
+ * marker, additionally requires the substitution that carries that marker.
1193
1313
  */
1194
1314
  export function isOpenCodeMcpServerConfiguredForLaunch(
1195
1315
  configPath: string = path.join(borgHomeRoot(), '.config', 'opencode', 'opencode.json'),
1196
1316
  env: NodeJS.ProcessEnv = process.env,
1197
1317
  ): boolean {
1198
1318
  if (!isOpenCodeMcpServerConfigured(configPath)) return false;
1199
- if (!env[BORG_LAUNCH_EXPECTED_SEAT_ENV]) return true;
1200
1319
  try {
1201
- const borgServer = readJsonFile(configPath)?.mcp?.borg;
1320
+ const borgServer = (readOpenCodeGlobalConfig(configPath) as any).mcp?.borg;
1202
1321
  const environment = borgServer?.environment ?? borgServer?.env;
1203
- return environment?.[BORG_LAUNCH_EXPECTED_SEAT_ENV] ===
1204
- OPENCODE_LAUNCH_EXPECTED_SEAT_REFERENCE;
1322
+ if (environment?.[OPENCODE_SERVER_PASSWORD_ENV] !== OPENCODE_SERVER_PASSWORD_REFERENCE) {
1323
+ return false;
1324
+ }
1325
+ if (!env[BORG_LAUNCH_EXPECTED_SEAT_ENV]) return true;
1326
+ return environment?.[BORG_LAUNCH_EXPECTED_SEAT_ENV] === OPENCODE_LAUNCH_EXPECTED_SEAT_REFERENCE;
1205
1327
  } catch {
1206
1328
  return false;
1207
1329
  }
@@ -1278,11 +1400,11 @@ export function addOpenCodeLaunchAccess(
1278
1400
 
1279
1401
  /**
1280
1402
  * Add borg MCP server to OpenCode using `opencode mcp add` CLI.
1281
- * Pins activation and agent-kind signals plus an OpenCode config substitution
1282
- * for the launch-scoped expected seat. OpenCode resolves `{env:NAME}` from its
1283
- * own launch environment before starting the MCP child, so `borg launch`
1284
- * reaches the identity check without persisting one launch's value. Existing
1285
- * configs with BORG_OPENCODE remain supported by the runtime fallback.
1403
+ * Pins activation and agent-kind signals plus OpenCode config substitutions
1404
+ * for the launch-scoped password and expected seat. OpenCode resolves
1405
+ * `{env:NAME}` from its own launch environment before starting the MCP child,
1406
+ * so no launch credential is persisted. Existing configs with BORG_OPENCODE
1407
+ * remain supported by the runtime fallback after launch-time self-healing.
1286
1408
  */
1287
1409
  export function addOpenCodeMcpServer(): void {
1288
1410
  try {
@@ -1295,8 +1417,10 @@ export function addOpenCodeMcpServer(): void {
1295
1417
  : '';
1296
1418
  const launchExpectedSeatEnvArg =
1297
1419
  ` --env ${BORG_LAUNCH_EXPECTED_SEAT_ENV}=${shellQuote(OPENCODE_LAUNCH_EXPECTED_SEAT_REFERENCE)}`;
1420
+ const apiPasswordEnvArg =
1421
+ ` --env ${OPENCODE_SERVER_PASSWORD_ENV}=${shellQuote(OPENCODE_SERVER_PASSWORD_REFERENCE)}`;
1298
1422
  execSync(
1299
- `opencode mcp add borg --env BORG_SESSION=1 --env BORG_AGENT_KIND=opencode --env BORG_OPENCODE=1${apiUrlEnvArg}${stateRootEnvArg}${launchExpectedSeatEnvArg} -- ${shellQuote(MCP_COMMAND)}`,
1423
+ `opencode mcp add borg --env BORG_SESSION=1 --env BORG_AGENT_KIND=opencode --env BORG_OPENCODE=1${apiUrlEnvArg}${stateRootEnvArg}${launchExpectedSeatEnvArg}${apiPasswordEnvArg} -- ${shellQuote(MCP_COMMAND)}`,
1300
1424
  { stdio: 'inherit', env: borgAgentConfigEnv(process.env) }
1301
1425
  );
1302
1426
  } catch (error: any) {
package/src/index.ts CHANGED
@@ -139,6 +139,7 @@ import {
139
139
  openCodeLaunchBinding,
140
140
  } from './opencode-drone.js';
141
141
  import { installBorgPlugin } from './opencode-plugin.js';
142
+ import { openCodeApiPasswordFromEnv } from './opencode-launch-trust.js';
142
143
  import { setModuleInjectOpenCode } from './log-stream.js';
143
144
  import {
144
145
  lifecycleSignalForMessage,
@@ -261,9 +262,15 @@ export async function connectOpenCodeRuntime(
261
262
  console.error(OPEN_CODE_PORT_MISSING_DIAGNOSTIC);
262
263
  return false;
263
264
  }
265
+ const apiPassword = openCodeApiPasswordFromEnv(env);
266
+ if (apiPassword === null) {
267
+ console.error('OpenCode API credential is missing or unverifiable; skipping OpenCode entry injection. Relaunch through borg.');
268
+ return false;
269
+ }
264
270
  const binding = openCodeLaunchBinding(configuredPort);
265
271
  await (deps.connect ?? connectOpenCodeDrone)({
266
272
  serverUrl: binding.serverUrl,
273
+ apiPassword,
267
274
  directory: active.worktree ?? findProjectRoot(),
268
275
  droneLabel: active.droneLabel,
269
276
  cubeName: active.name,