@factiii/runner 0.12.0 → 0.12.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/cli.js +72 -48
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -6499,7 +6499,7 @@ var require_websocket = __commonJS({
|
|
|
6499
6499
|
var http = require("http");
|
|
6500
6500
|
var net3 = require("net");
|
|
6501
6501
|
var tls = require("tls");
|
|
6502
|
-
var { randomBytes, createHash: createHash2 } = require("crypto");
|
|
6502
|
+
var { randomBytes: randomBytes2, createHash: createHash2 } = require("crypto");
|
|
6503
6503
|
var { Duplex, Readable } = require("stream");
|
|
6504
6504
|
var { URL: URL2 } = require("url");
|
|
6505
6505
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -7037,7 +7037,7 @@ var require_websocket = __commonJS({
|
|
|
7037
7037
|
}
|
|
7038
7038
|
}
|
|
7039
7039
|
const defaultPort = isSecure ? 443 : 80;
|
|
7040
|
-
const key =
|
|
7040
|
+
const key = randomBytes2(16).toString("base64");
|
|
7041
7041
|
const request = isSecure ? https.request : http.request;
|
|
7042
7042
|
const protocolSet = /* @__PURE__ */ new Set();
|
|
7043
7043
|
let perMessageDeflate;
|
|
@@ -13805,6 +13805,7 @@ async function teardownSession(s, target) {
|
|
|
13805
13805
|
|
|
13806
13806
|
// ../../shared/all/helpers/board-agent-core/exec.ts
|
|
13807
13807
|
var import_child_process2 = require("child_process");
|
|
13808
|
+
var import_crypto = require("crypto");
|
|
13808
13809
|
var import_fs2 = require("fs");
|
|
13809
13810
|
var import_promises2 = __toESM(require("fs/promises"));
|
|
13810
13811
|
var import_net = __toESM(require("net"));
|
|
@@ -13845,6 +13846,22 @@ async function allocateSpacePorts(spaceDir) {
|
|
|
13845
13846
|
await import_promises2.default.writeFile(portsFilePath(spaceDir), ports.join(","), "utf-8");
|
|
13846
13847
|
return ports;
|
|
13847
13848
|
}
|
|
13849
|
+
var SECRET_FILE = ".secret";
|
|
13850
|
+
function spaceSecret(spaceDir) {
|
|
13851
|
+
const file = import_path4.default.join(spaceDir, SECRET_FILE);
|
|
13852
|
+
try {
|
|
13853
|
+
const existing = (0, import_fs2.readFileSync)(file, "utf-8").trim();
|
|
13854
|
+
if (existing) return existing;
|
|
13855
|
+
} catch {
|
|
13856
|
+
}
|
|
13857
|
+
const secret = (0, import_crypto.randomBytes)(24).toString("hex");
|
|
13858
|
+
try {
|
|
13859
|
+
(0, import_fs2.mkdirSync)(spaceDir, { recursive: true });
|
|
13860
|
+
(0, import_fs2.writeFileSync)(file, secret, { encoding: "utf-8", mode: 384 });
|
|
13861
|
+
} catch {
|
|
13862
|
+
}
|
|
13863
|
+
return secret;
|
|
13864
|
+
}
|
|
13848
13865
|
function readSpacePorts(spaceDir) {
|
|
13849
13866
|
try {
|
|
13850
13867
|
return (0, import_fs2.readFileSync)(portsFilePath(spaceDir), "utf-8").split(",").map((p) => Number(p.trim())).filter((p) => Number.isInteger(p) && p > 0);
|
|
@@ -16903,7 +16920,7 @@ ${buildPrompt(prompts_default.implement)}`;
|
|
|
16903
16920
|
};
|
|
16904
16921
|
|
|
16905
16922
|
// ../../shared/all/helpers/terminal-ai/terminal-mode.ts
|
|
16906
|
-
var
|
|
16923
|
+
var import_crypto4 = require("crypto");
|
|
16907
16924
|
|
|
16908
16925
|
// ../../shared/all/helpers/board-agent-core/boardTerminal.ts
|
|
16909
16926
|
function boardTerminalKey(spaceSlug) {
|
|
@@ -16959,12 +16976,12 @@ function drainStateMessages(buffer) {
|
|
|
16959
16976
|
}
|
|
16960
16977
|
|
|
16961
16978
|
// ../../shared/all/helpers/terminal-ai/digest.ts
|
|
16962
|
-
var
|
|
16979
|
+
var import_crypto3 = __toESM(require("crypto"));
|
|
16963
16980
|
var import_promises8 = require("fs/promises");
|
|
16964
16981
|
var import_path10 = __toESM(require("path"));
|
|
16965
16982
|
|
|
16966
16983
|
// ../../shared/all/helpers/board-agent-core/plugin.ts
|
|
16967
|
-
var
|
|
16984
|
+
var import_crypto2 = __toESM(require("crypto"));
|
|
16968
16985
|
var import_fs4 = require("fs");
|
|
16969
16986
|
var import_promises7 = require("fs/promises");
|
|
16970
16987
|
var import_os3 = __toESM(require("os"));
|
|
@@ -17013,7 +17030,7 @@ async function treeFiles(dir) {
|
|
|
17013
17030
|
return files.sort();
|
|
17014
17031
|
}
|
|
17015
17032
|
async function fingerprint(source, url2, version = "") {
|
|
17016
|
-
const hash =
|
|
17033
|
+
const hash = import_crypto2.default.createHash("sha256").update(url2).update(version);
|
|
17017
17034
|
for (const file of await treeFiles(source)) {
|
|
17018
17035
|
hash.update(import_path9.default.relative(source, file));
|
|
17019
17036
|
hash.update(await (0, import_promises7.readFile)(file));
|
|
@@ -17131,7 +17148,7 @@ async function pluginContribution() {
|
|
|
17131
17148
|
return value2;
|
|
17132
17149
|
}
|
|
17133
17150
|
async function terminalDigest(target) {
|
|
17134
|
-
const hash =
|
|
17151
|
+
const hash = import_crypto3.default.createHash("sha256").update(TMUX_CONF).update(terminalPrelude(CWD_PLACEHOLDER, target.paths.bin));
|
|
17135
17152
|
const env = target.stateEnv();
|
|
17136
17153
|
for (const key of Object.keys(env).sort()) {
|
|
17137
17154
|
if (VOLATILE_ENV_KEYS.has(key)) continue;
|
|
@@ -18330,7 +18347,7 @@ var TerminalModeEngine = class {
|
|
|
18330
18347
|
}
|
|
18331
18348
|
const safeExt = (ext || "png").toLowerCase().replace(/[^a-z0-9]/g, "") || "png";
|
|
18332
18349
|
const oneShot = !dropId;
|
|
18333
|
-
const safeId2 = oneShot ? (0,
|
|
18350
|
+
const safeId2 = oneShot ? (0, import_crypto4.randomUUID)() : dropId.toLowerCase().replace(/[^a-z0-9-]/g, "");
|
|
18334
18351
|
if (!safeId2) throw new Error("Invalid drop id.");
|
|
18335
18352
|
const dropsDir = `${target.paths.root}/drops`;
|
|
18336
18353
|
const abs = `${dropsDir}/${safeId2}.${safeExt}`;
|
|
@@ -18531,15 +18548,7 @@ var TerminalModeEngine = class {
|
|
|
18531
18548
|
`${tmuxCli(target)} list-panes -a -F '${TAB_LIST_FORMAT}' 2>/dev/null || true`
|
|
18532
18549
|
);
|
|
18533
18550
|
const rows = parseTerminalTabs(stdout, prefix);
|
|
18534
|
-
|
|
18535
|
-
return rows.map(({ id, name, fp, dead }) => ({
|
|
18536
|
-
id,
|
|
18537
|
-
name,
|
|
18538
|
-
// No stamp means a session older than the stamp, as blind to the
|
|
18539
|
-
// current build as a mismatched one.
|
|
18540
|
-
stale: !!current && fp !== current,
|
|
18541
|
-
dead
|
|
18542
|
-
}));
|
|
18551
|
+
return rows.map(({ id, name, dead }) => ({ id, name, dead }));
|
|
18543
18552
|
} catch {
|
|
18544
18553
|
return [];
|
|
18545
18554
|
}
|
|
@@ -19195,7 +19204,7 @@ async function listGithubBranches(token, fullName) {
|
|
|
19195
19204
|
var import_path13 = __toESM(require("path"));
|
|
19196
19205
|
|
|
19197
19206
|
// ../../shared/all/helpers/board-agent-core/secrets-gate.ts
|
|
19198
|
-
var
|
|
19207
|
+
var import_crypto5 = __toESM(require("crypto"));
|
|
19199
19208
|
var DEPLOY_ORIGIN = "Deploy run";
|
|
19200
19209
|
var UNATTRIBUTED = "This runner did not start the session that asked, so the request was refused. `factiii-secrets` only works inside a session the runner spawned.";
|
|
19201
19210
|
var SecretsGate = class {
|
|
@@ -19220,7 +19229,14 @@ var SecretsGate = class {
|
|
|
19220
19229
|
/** Mint a token for one session, labelled with what the owner should see on
|
|
19221
19230
|
* the prompt - the label is most of the decision, so name the session. */
|
|
19222
19231
|
issueToken(origin) {
|
|
19223
|
-
const token =
|
|
19232
|
+
const token = import_crypto5.default.randomBytes(24).toString("hex");
|
|
19233
|
+
this.tokens.set(token, origin);
|
|
19234
|
+
return token;
|
|
19235
|
+
}
|
|
19236
|
+
/** Register a durable token the caller already holds, instead of minting a
|
|
19237
|
+
* fresh one. For the space token: terminals outlive this process, so a
|
|
19238
|
+
* minted one leaves them unattributed after a restart. Idempotent. */
|
|
19239
|
+
adoptToken(token, origin) {
|
|
19224
19240
|
this.tokens.set(token, origin);
|
|
19225
19241
|
return token;
|
|
19226
19242
|
}
|
|
@@ -19244,7 +19260,7 @@ var SecretsGate = class {
|
|
|
19244
19260
|
return new Promise((resolve2) => {
|
|
19245
19261
|
this.waiting = {
|
|
19246
19262
|
request: {
|
|
19247
|
-
id:
|
|
19263
|
+
id: import_crypto5.default.randomUUID(),
|
|
19248
19264
|
command: opts.command,
|
|
19249
19265
|
keys: opts.keys,
|
|
19250
19266
|
origin: opts.origin,
|
|
@@ -19288,7 +19304,7 @@ var import_path12 = __toESM(require("path"));
|
|
|
19288
19304
|
|
|
19289
19305
|
// ../../shared/all/helpers/board-agent-core/host-secrets.ts
|
|
19290
19306
|
var import_child_process4 = require("child_process");
|
|
19291
|
-
var
|
|
19307
|
+
var import_crypto6 = __toESM(require("crypto"));
|
|
19292
19308
|
var import_promises9 = __toESM(require("fs/promises"));
|
|
19293
19309
|
var import_path11 = __toESM(require("path"));
|
|
19294
19310
|
var import_util6 = require("util");
|
|
@@ -19316,7 +19332,7 @@ async function assertBinaries() {
|
|
|
19316
19332
|
}
|
|
19317
19333
|
}
|
|
19318
19334
|
function deriveKey(password, salt) {
|
|
19319
|
-
return
|
|
19335
|
+
return import_crypto6.default.scryptSync(password, salt, 32, {
|
|
19320
19336
|
N: SCRYPT_N,
|
|
19321
19337
|
maxmem: 64 * 1024 * 1024
|
|
19322
19338
|
});
|
|
@@ -19345,9 +19361,9 @@ async function initSecrets(configDir, password) {
|
|
|
19345
19361
|
if (!identity || !recipient) {
|
|
19346
19362
|
throw new Error("age-keygen returned no usable keypair.");
|
|
19347
19363
|
}
|
|
19348
|
-
const salt =
|
|
19349
|
-
const iv =
|
|
19350
|
-
const cipher =
|
|
19364
|
+
const salt = import_crypto6.default.randomBytes(16);
|
|
19365
|
+
const iv = import_crypto6.default.randomBytes(12);
|
|
19366
|
+
const cipher = import_crypto6.default.createCipheriv(
|
|
19351
19367
|
"aes-256-gcm",
|
|
19352
19368
|
deriveKey(password, salt),
|
|
19353
19369
|
iv
|
|
@@ -19372,7 +19388,7 @@ async function initSecrets(configDir, password) {
|
|
|
19372
19388
|
return { success: true };
|
|
19373
19389
|
}
|
|
19374
19390
|
function decryptIdentity(box, password) {
|
|
19375
|
-
const decipher =
|
|
19391
|
+
const decipher = import_crypto6.default.createDecipheriv(
|
|
19376
19392
|
"aes-256-gcm",
|
|
19377
19393
|
deriveKey(password, Buffer.from(box.salt, "base64")),
|
|
19378
19394
|
Buffer.from(box.iv, "base64")
|
|
@@ -20037,6 +20053,7 @@ var SpaceCore = class {
|
|
|
20037
20053
|
this.runnerToken = options.runnerToken;
|
|
20038
20054
|
this.serverUrl = options.serverUrl;
|
|
20039
20055
|
this.mcp = options.mcp;
|
|
20056
|
+
this.mcpToken = options.mcpToken;
|
|
20040
20057
|
this.requestSudo = options.requestSudo;
|
|
20041
20058
|
this.activity = new ActivityTracker(this.emitter);
|
|
20042
20059
|
this.gate.subscribe(() => {
|
|
@@ -20131,7 +20148,11 @@ var SpaceCore = class {
|
|
|
20131
20148
|
* that DOES know itself - the deploy run - mints its own and overrides this.
|
|
20132
20149
|
*/
|
|
20133
20150
|
secretsToken() {
|
|
20134
|
-
this.spaceSecretsToken
|
|
20151
|
+
if (this.spaceSecretsToken) return this.spaceSecretsToken;
|
|
20152
|
+
this.spaceSecretsToken = this.gate.adoptToken(
|
|
20153
|
+
spaceSecret(this.spaceDir()),
|
|
20154
|
+
"A session on this board"
|
|
20155
|
+
);
|
|
20135
20156
|
return this.spaceSecretsToken;
|
|
20136
20157
|
}
|
|
20137
20158
|
readConfig() {
|
|
@@ -20142,7 +20163,8 @@ var SpaceCore = class {
|
|
|
20142
20163
|
target() {
|
|
20143
20164
|
this.execTarget ??= hostTarget(this.spaceDir(), () => {
|
|
20144
20165
|
const env = {};
|
|
20145
|
-
|
|
20166
|
+
const onedrive = this.mcpToken?.();
|
|
20167
|
+
if (onedrive) env[MCP_TOKEN_ENV] = onedrive;
|
|
20146
20168
|
const board = this.boardMcp();
|
|
20147
20169
|
if (board) env[BOARD_MCP_TOKEN_ENV] = board.token;
|
|
20148
20170
|
env.FACTIII_SECRETS_TOKEN = this.secretsToken();
|
|
@@ -22306,7 +22328,7 @@ ${c.content.trim() || "(no description)"}`
|
|
|
22306
22328
|
|
|
22307
22329
|
// ../../shared/all/helpers/board-agent-core/index-service.ts
|
|
22308
22330
|
var import_child_process5 = require("child_process");
|
|
22309
|
-
var
|
|
22331
|
+
var import_crypto7 = require("crypto");
|
|
22310
22332
|
var import_fs5 = require("fs");
|
|
22311
22333
|
var import_promises11 = __toESM(require("fs/promises"));
|
|
22312
22334
|
var import_net3 = require("net");
|
|
@@ -22324,7 +22346,7 @@ var IndexService = class {
|
|
|
22324
22346
|
/** Per-space bearer for MCP + file, derived from the control token (the
|
|
22325
22347
|
* service computes the same). */
|
|
22326
22348
|
bearerToken(spaceSlug) {
|
|
22327
|
-
return (0,
|
|
22349
|
+
return (0, import_crypto7.createHmac)("sha256", this.opts.controlToken).update(`mcp:${spaceSlug}`).digest("hex");
|
|
22328
22350
|
}
|
|
22329
22351
|
/** MCP bridge for a space. Null until the service is up (which it kicks
|
|
22330
22352
|
* off), so a bad :0 URL is never baked in; provisionMcpLane re-runs. */
|
|
@@ -22602,13 +22624,13 @@ var import_os6 = __toESM(require("os"));
|
|
|
22602
22624
|
var import_path21 = __toESM(require("path"));
|
|
22603
22625
|
|
|
22604
22626
|
// src/secureFile.ts
|
|
22605
|
-
var
|
|
22627
|
+
var import_crypto10 = __toESM(require("crypto"));
|
|
22606
22628
|
var import_fs8 = __toESM(require("fs"));
|
|
22607
22629
|
var import_path20 = __toESM(require("path"));
|
|
22608
22630
|
|
|
22609
22631
|
// src/keychain.ts
|
|
22610
22632
|
var import_child_process7 = require("child_process");
|
|
22611
|
-
var
|
|
22633
|
+
var import_crypto8 = __toESM(require("crypto"));
|
|
22612
22634
|
var import_fs6 = __toESM(require("fs"));
|
|
22613
22635
|
var import_os4 = __toESM(require("os"));
|
|
22614
22636
|
var import_path17 = __toESM(require("path"));
|
|
@@ -22860,7 +22882,7 @@ function resolve() {
|
|
|
22860
22882
|
cached = { key: null, status: diagnose() };
|
|
22861
22883
|
return cached;
|
|
22862
22884
|
}
|
|
22863
|
-
const fresh =
|
|
22885
|
+
const fresh = import_crypto8.default.randomBytes(32);
|
|
22864
22886
|
writeKey(fresh);
|
|
22865
22887
|
const verify = readKey();
|
|
22866
22888
|
if (verify.state !== "found" || !verify.key.equals(fresh)) {
|
|
@@ -22882,7 +22904,7 @@ function keychainStatus() {
|
|
|
22882
22904
|
}
|
|
22883
22905
|
|
|
22884
22906
|
// src/secureStore.ts
|
|
22885
|
-
var
|
|
22907
|
+
var import_crypto9 = __toESM(require("crypto"));
|
|
22886
22908
|
var import_fs7 = __toESM(require("fs"));
|
|
22887
22909
|
var import_path19 = __toESM(require("path"));
|
|
22888
22910
|
|
|
@@ -22925,7 +22947,7 @@ function requireKeychainKey() {
|
|
|
22925
22947
|
);
|
|
22926
22948
|
}
|
|
22927
22949
|
function passwordKey(password, salt) {
|
|
22928
|
-
return
|
|
22950
|
+
return import_crypto9.default.scryptSync(password, salt, 32, {
|
|
22929
22951
|
N: SCRYPT_N2,
|
|
22930
22952
|
maxmem: 64 * 1024 * 1024
|
|
22931
22953
|
});
|
|
@@ -22933,7 +22955,7 @@ function passwordKey(password, salt) {
|
|
|
22933
22955
|
function wrapKey(machineKey, pwKey) {
|
|
22934
22956
|
const ikm = pwKey ? Buffer.concat([machineKey, pwKey]) : machineKey;
|
|
22935
22957
|
return Buffer.from(
|
|
22936
|
-
|
|
22958
|
+
import_crypto9.default.hkdfSync(
|
|
22937
22959
|
"sha256",
|
|
22938
22960
|
ikm,
|
|
22939
22961
|
Buffer.alloc(0),
|
|
@@ -22943,8 +22965,8 @@ function wrapKey(machineKey, pwKey) {
|
|
|
22943
22965
|
);
|
|
22944
22966
|
}
|
|
22945
22967
|
function seal(plaintext, key) {
|
|
22946
|
-
const iv =
|
|
22947
|
-
const cipher =
|
|
22968
|
+
const iv = import_crypto9.default.randomBytes(12);
|
|
22969
|
+
const cipher = import_crypto9.default.createCipheriv("aes-256-gcm", key, iv);
|
|
22948
22970
|
const data = Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
22949
22971
|
return {
|
|
22950
22972
|
iv: iv.toString("base64"),
|
|
@@ -22954,7 +22976,7 @@ function seal(plaintext, key) {
|
|
|
22954
22976
|
}
|
|
22955
22977
|
function unseal(box, key) {
|
|
22956
22978
|
try {
|
|
22957
|
-
const decipher =
|
|
22979
|
+
const decipher = import_crypto9.default.createDecipheriv(
|
|
22958
22980
|
"aes-256-gcm",
|
|
22959
22981
|
key,
|
|
22960
22982
|
Buffer.from(box.iv, "base64")
|
|
@@ -22987,7 +23009,7 @@ function writeVaultFile(file) {
|
|
|
22987
23009
|
}
|
|
22988
23010
|
var unlockedDek = null;
|
|
22989
23011
|
function createVault(machineKey) {
|
|
22990
|
-
const dek =
|
|
23012
|
+
const dek = import_crypto9.default.randomBytes(32);
|
|
22991
23013
|
writeVaultFile({
|
|
22992
23014
|
v: 1,
|
|
22993
23015
|
passwordEnabled: false,
|
|
@@ -23082,7 +23104,7 @@ function enablePassword(password) {
|
|
|
23082
23104
|
);
|
|
23083
23105
|
}
|
|
23084
23106
|
const dek = dataKey();
|
|
23085
|
-
const salt =
|
|
23107
|
+
const salt = import_crypto9.default.randomBytes(16);
|
|
23086
23108
|
writeVaultFile({
|
|
23087
23109
|
v: 1,
|
|
23088
23110
|
passwordEnabled: true,
|
|
@@ -23110,7 +23132,7 @@ function changePassword(current, next) {
|
|
|
23110
23132
|
"The current password is not correct."
|
|
23111
23133
|
);
|
|
23112
23134
|
}
|
|
23113
|
-
const salt =
|
|
23135
|
+
const salt = import_crypto9.default.randomBytes(16);
|
|
23114
23136
|
writeVaultFile({
|
|
23115
23137
|
v: 1,
|
|
23116
23138
|
passwordEnabled: true,
|
|
@@ -23187,8 +23209,8 @@ function storeStatus() {
|
|
|
23187
23209
|
// src/secureFile.ts
|
|
23188
23210
|
var MAGIC = "FACTIII1";
|
|
23189
23211
|
function encrypt(plain, key, version) {
|
|
23190
|
-
const iv =
|
|
23191
|
-
const cipher =
|
|
23212
|
+
const iv = import_crypto10.default.randomBytes(12);
|
|
23213
|
+
const cipher = import_crypto10.default.createCipheriv("aes-256-gcm", key, iv);
|
|
23192
23214
|
const data = Buffer.concat([cipher.update(plain), cipher.final()]);
|
|
23193
23215
|
const envelope = {
|
|
23194
23216
|
v: version,
|
|
@@ -23199,7 +23221,7 @@ function encrypt(plain, key, version) {
|
|
|
23199
23221
|
return `${MAGIC}${JSON.stringify(envelope)}`;
|
|
23200
23222
|
}
|
|
23201
23223
|
function decrypt(envelope, key) {
|
|
23202
|
-
const decipher =
|
|
23224
|
+
const decipher = import_crypto10.default.createDecipheriv(
|
|
23203
23225
|
"aes-256-gcm",
|
|
23204
23226
|
key,
|
|
23205
23227
|
Buffer.from(envelope.iv, "base64")
|
|
@@ -23457,7 +23479,7 @@ function installLatest() {
|
|
|
23457
23479
|
var import_node_child_process2 = require("node:child_process");
|
|
23458
23480
|
|
|
23459
23481
|
// src/daemon.ts
|
|
23460
|
-
var
|
|
23482
|
+
var import_crypto11 = require("crypto");
|
|
23461
23483
|
var import_fs11 = __toESM(require("fs"));
|
|
23462
23484
|
var import_node_datachannel = require("node-datachannel");
|
|
23463
23485
|
var import_path23 = __toESM(require("path"));
|
|
@@ -27372,7 +27394,7 @@ async function startDaemon(config) {
|
|
|
27372
27394
|
];
|
|
27373
27395
|
const indexDir = indexCandidates.find((p) => import_fs11.default.existsSync(p)) ?? indexCandidates[0];
|
|
27374
27396
|
const odIndex = new IndexService({
|
|
27375
|
-
controlToken: (0,
|
|
27397
|
+
controlToken: (0, import_crypto11.createHash)("sha256").update(config.authToken).digest("hex"),
|
|
27376
27398
|
embedUrl: () => config.serverUrl,
|
|
27377
27399
|
indexDir,
|
|
27378
27400
|
dataDir: import_path23.default.join(CONFIG_DIR, "index-data")
|
|
@@ -27472,7 +27494,9 @@ async function startDaemon(config) {
|
|
|
27472
27494
|
// Board MCP is server-hosted, so the base URL is all it needs.
|
|
27473
27495
|
serverUrl: config.serverUrl,
|
|
27474
27496
|
// Point the agent at the index MCP endpoint (lazy for the port).
|
|
27475
|
-
mcp: () => odIndex.mcpBridge(spaceSlug)
|
|
27497
|
+
mcp: () => odIndex.mcpBridge(spaceSlug),
|
|
27498
|
+
// The bearer alone, available before the service has a port for a URL.
|
|
27499
|
+
mcpToken: () => odIndex.bearerToken(spaceSlug)
|
|
27476
27500
|
});
|
|
27477
27501
|
engines.set(spaceSlug, engine);
|
|
27478
27502
|
void engine.reattachAndHydrate();
|
package/package.json
CHANGED