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.
- package/dist/assimilate-cmd.d.ts.map +1 -1
- package/dist/assimilate-cmd.js +8 -3
- package/dist/assimilate-cmd.js.map +1 -1
- package/dist/claude.d.ts.map +1 -1
- package/dist/claude.js +11 -4
- package/dist/claude.js.map +1 -1
- package/dist/config-utils.d.ts +13 -12
- package/dist/config-utils.d.ts.map +1 -1
- package/dist/config-utils.js +150 -27
- package/dist/config-utils.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/opencode-drone.d.ts +10 -8
- package/dist/opencode-drone.d.ts.map +1 -1
- package/dist/opencode-drone.js +56 -46
- package/dist/opencode-drone.js.map +1 -1
- package/dist/opencode-launch-trust.d.ts +13 -0
- package/dist/opencode-launch-trust.d.ts.map +1 -0
- package/dist/opencode-launch-trust.js +40 -0
- package/dist/opencode-launch-trust.js.map +1 -0
- package/dist/opencode-plugin.d.ts +3 -0
- package/dist/opencode-plugin.d.ts.map +1 -1
- package/dist/opencode-plugin.js +26 -1
- package/dist/opencode-plugin.js.map +1 -1
- package/dist/setup-confirm.d.ts +1 -1
- package/dist/setup-confirm.js +3 -3
- package/dist/setup-confirm.js.map +1 -1
- package/package.json +1 -1
- package/src/assimilate-cmd.ts +13 -3
- package/src/claude.ts +16 -4
- package/src/config-utils.ts +147 -23
- package/src/index.ts +7 -0
- package/src/opencode-drone.ts +71 -54
- package/src/opencode-launch-trust.ts +46 -0
- package/src/opencode-plugin.ts +31 -1
- package/src/setup-confirm.ts +3 -3
|
@@ -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;
|
|
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"}
|
package/dist/opencode-plugin.js
CHANGED
|
@@ -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
|
-
|
|
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":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,uEAAuE;IACvE,0EAA0E;IAC1E,wEAAwE;IACxE,2EAA2E;IAC3E,+EAA+E;IAC/E,QAAQ,EAAE,SAAS;IACnB,GAAG,EAAE,SAAS;CACN,CAAC;AAEX,MAAM,gBAAgB,GACpB,qEAAqE;IACrE,kEAAkE,CAAC;AACrE,MAAM,CAAC,MAAM,oCAAoC,GAAG,2BAA2B,CAAC;AAChF,MAAM,CAAC,MAAM,mCAAmC,GAAG,0BAA0B,CAAC;AAC9E,MAAM,CAAC,MAAM,8BAA8B,GAAG,gCAAgC,CAAC;AAC/E,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"opencode-plugin.js","sourceRoot":"","sources":["../src/opencode-plugin.ts"],"names":[],"mappings":"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"}
|
package/dist/setup-confirm.d.ts
CHANGED
|
@@ -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/
|
|
29
|
+
* OpenCode: effective global config under ~/.config/opencode/ (MCP server)
|
|
30
30
|
*/
|
|
31
31
|
export declare function configMutationTargets(deps: {
|
|
32
32
|
claude: boolean;
|
package/dist/setup-confirm.js
CHANGED
|
@@ -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/
|
|
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/
|
|
50
|
-
change: '
|
|
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,
|
|
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
package/src/assimilate-cmd.ts
CHANGED
|
@@ -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
|
|
2174
|
-
//
|
|
2175
|
-
//
|
|
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 = {
|
|
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
|
|
630
|
-
//
|
|
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[];
|
package/src/config-utils.ts
CHANGED
|
@@ -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
|
|
1166
|
-
* config
|
|
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
|
|
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
|
-
|
|
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.
|
|
1190
|
-
*
|
|
1191
|
-
* identified by its non-empty expected-seat
|
|
1192
|
-
*
|
|
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 =
|
|
1320
|
+
const borgServer = (readOpenCodeGlobalConfig(configPath) as any).mcp?.borg;
|
|
1202
1321
|
const environment = borgServer?.environment ?? borgServer?.env;
|
|
1203
|
-
|
|
1204
|
-
|
|
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
|
|
1282
|
-
* for the launch-scoped expected seat. OpenCode resolves
|
|
1283
|
-
* own launch environment before starting the MCP child,
|
|
1284
|
-
*
|
|
1285
|
-
*
|
|
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,
|