@agentvault/grok-bridge 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +115 -59
- package/dist/pending-invite.d.ts +24 -0
- package/dist/service/subcommand.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9,9 +9,54 @@ var __export = (target, all) => {
|
|
|
9
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
// src/pending-invite.ts
|
|
13
|
+
import { existsSync, mkdirSync, chmodSync, readFileSync as readFileSync2, writeFileSync, rmSync } from "node:fs";
|
|
14
|
+
import { join as join5 } from "node:path";
|
|
15
|
+
function pendingInvitePath(dataDir) {
|
|
16
|
+
return join5(dataDir, PENDING_INVITE_FILE);
|
|
17
|
+
}
|
|
18
|
+
function writePendingInvite(dataDir, token) {
|
|
19
|
+
mkdirSync(dataDir, { recursive: true, mode: DIR_MODE2 });
|
|
20
|
+
chmodSync(dataDir, DIR_MODE2);
|
|
21
|
+
const p2 = pendingInvitePath(dataDir);
|
|
22
|
+
writeFileSync(p2, token, { mode: FILE_MODE2 });
|
|
23
|
+
chmodSync(p2, FILE_MODE2);
|
|
24
|
+
}
|
|
25
|
+
function readPendingInvite(dataDir) {
|
|
26
|
+
const p2 = pendingInvitePath(dataDir);
|
|
27
|
+
if (!existsSync(p2)) return void 0;
|
|
28
|
+
try {
|
|
29
|
+
const raw = readFileSync2(p2, "utf-8").trim();
|
|
30
|
+
return raw.length > 0 ? raw : void 0;
|
|
31
|
+
} catch {
|
|
32
|
+
return void 0;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function clearPendingInvite(dataDir) {
|
|
36
|
+
try {
|
|
37
|
+
rmSync(pendingInvitePath(dataDir), { force: true });
|
|
38
|
+
} catch {
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function clearPendingInviteIfConsumed(dataDir, credsExist) {
|
|
42
|
+
if (!existsSync(pendingInvitePath(dataDir))) return false;
|
|
43
|
+
if (!credsExist(dataDir)) return false;
|
|
44
|
+
clearPendingInvite(dataDir);
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
var DIR_MODE2, FILE_MODE2, PENDING_INVITE_FILE;
|
|
48
|
+
var init_pending_invite = __esm({
|
|
49
|
+
"src/pending-invite.ts"() {
|
|
50
|
+
"use strict";
|
|
51
|
+
DIR_MODE2 = 448;
|
|
52
|
+
FILE_MODE2 = 384;
|
|
53
|
+
PENDING_INVITE_FILE = "pending-invite";
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
12
57
|
// src/config.ts
|
|
13
|
-
import { existsSync, readFileSync as
|
|
14
|
-
import { join as
|
|
58
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3, mkdirSync as mkdirSync2, chmodSync as chmodSync2 } from "node:fs";
|
|
59
|
+
import { join as join6, resolve as resolve2, sep, dirname } from "node:path";
|
|
15
60
|
import { tmpdir } from "node:os";
|
|
16
61
|
function parseInfoFlags(argv) {
|
|
17
62
|
return {
|
|
@@ -32,14 +77,14 @@ function assertInstallableEntrypoint(entrypoint) {
|
|
|
32
77
|
}
|
|
33
78
|
function hasRecoverableBackup(dataDir) {
|
|
34
79
|
try {
|
|
35
|
-
const parsed = JSON.parse(
|
|
80
|
+
const parsed = JSON.parse(readFileSync3(join6(dataDir, BACKUP_FILE), "utf-8"));
|
|
36
81
|
return !!(parsed && parsed.deviceId && parsed.deviceJwt && parsed.sessions && Object.keys(parsed.sessions).length > 0);
|
|
37
82
|
} catch {
|
|
38
83
|
return false;
|
|
39
84
|
}
|
|
40
85
|
}
|
|
41
86
|
function hasPersistedCreds(dataDir) {
|
|
42
|
-
if (CRED_FILES.some((f2) =>
|
|
87
|
+
if (CRED_FILES.some((f2) => existsSync2(join6(dataDir, f2)))) return true;
|
|
43
88
|
return hasRecoverableBackup(dataDir);
|
|
44
89
|
}
|
|
45
90
|
function slugify2(name) {
|
|
@@ -47,19 +92,19 @@ function slugify2(name) {
|
|
|
47
92
|
}
|
|
48
93
|
function resolveDataDir(env) {
|
|
49
94
|
if (env.AV_DATA_DIR) return { dataDir: env.AV_DATA_DIR, source: "explicit" };
|
|
50
|
-
const base =
|
|
51
|
-
return { dataDir:
|
|
95
|
+
const base = join6(env.HOME ?? "", ".agentvault", "grok-room-bridge");
|
|
96
|
+
return { dataDir: join6(base, slugify2(env.AV_AGENT_NAME ?? "grok")), source: "per-agent" };
|
|
52
97
|
}
|
|
53
98
|
function loadConfig(env, argv = []) {
|
|
54
99
|
const { dataDir, source: dataDirSource } = resolveDataDir(env);
|
|
55
|
-
const inviteToken = (argv[0] && !argv[0].startsWith("-") ? argv[0] : "") || env.AV_INVITE_TOKEN || "";
|
|
100
|
+
const inviteToken = (argv[0] && !argv[0].startsWith("-") ? argv[0] : "") || env.AV_INVITE_TOKEN || readPendingInvite(dataDir) || "";
|
|
56
101
|
const unknownFlags = argv.filter((a2) => a2.startsWith("-") && !KNOWN_FLAGS.has(a2));
|
|
57
102
|
if (unknownFlags.length) {
|
|
58
103
|
throw new Error(
|
|
59
104
|
`unknown option(s): ${unknownFlags.join(", ")} \u2014 supported flags are ${[...KNOWN_FLAGS].join(", ")}`
|
|
60
105
|
);
|
|
61
106
|
}
|
|
62
|
-
const workspaceDir = env.AV_WORKSPACE_DIR ||
|
|
107
|
+
const workspaceDir = env.AV_WORKSPACE_DIR || join6(dirname(dataDir), "workspaces", slugify2(env.AV_AGENT_NAME ?? "grok"));
|
|
63
108
|
const wsReal = resolve2(workspaceDir);
|
|
64
109
|
const ddReal = resolve2(dataDir);
|
|
65
110
|
if (wsReal === ddReal || wsReal.startsWith(ddReal + sep) || ddReal.startsWith(wsReal + sep)) {
|
|
@@ -68,8 +113,8 @@ function loadConfig(env, argv = []) {
|
|
|
68
113
|
);
|
|
69
114
|
}
|
|
70
115
|
try {
|
|
71
|
-
|
|
72
|
-
|
|
116
|
+
mkdirSync2(workspaceDir, { recursive: true, mode: 448 });
|
|
117
|
+
chmodSync2(workspaceDir, 448);
|
|
73
118
|
} catch (e) {
|
|
74
119
|
throw new Error(
|
|
75
120
|
`Failed to create/secure the agent workspace at ${workspaceDir} (override with AV_WORKSPACE_DIR): ${e.message}`
|
|
@@ -99,7 +144,7 @@ function loadConfig(env, argv = []) {
|
|
|
99
144
|
workspaceDir,
|
|
100
145
|
grokPath: env.AV_GROK_PATH || void 0,
|
|
101
146
|
sandboxProfile: env.GROK_SANDBOX ?? "workspace",
|
|
102
|
-
fenceHome: env.AV_FENCE_HOME ||
|
|
147
|
+
fenceHome: env.AV_FENCE_HOME || join6(dataDir, "fence"),
|
|
103
148
|
apiKey: env.XAI_API_KEY || void 0,
|
|
104
149
|
systemPrompt: env.AV_SYSTEM_PROMPT || void 0
|
|
105
150
|
};
|
|
@@ -108,6 +153,7 @@ var INSTALL_FLAG, VERSION_FLAGS, HELP_FLAGS, KNOWN_FLAGS, CRED_FILES, BACKUP_FIL
|
|
|
108
153
|
var init_config = __esm({
|
|
109
154
|
"src/config.ts"() {
|
|
110
155
|
"use strict";
|
|
156
|
+
init_pending_invite();
|
|
111
157
|
INSTALL_FLAG = "--install";
|
|
112
158
|
VERSION_FLAGS = ["--version", "-v"];
|
|
113
159
|
HELP_FLAGS = ["--help", "-h"];
|
|
@@ -197,7 +243,7 @@ var init_launcher = __esm({
|
|
|
197
243
|
});
|
|
198
244
|
|
|
199
245
|
// src/service/spec.ts
|
|
200
|
-
import { join as
|
|
246
|
+
import { join as join10 } from "node:path";
|
|
201
247
|
function buildServiceSpec(cfg, opts) {
|
|
202
248
|
const env = {
|
|
203
249
|
AV_AGENT_NAME: cfg.agentName,
|
|
@@ -209,7 +255,7 @@ function buildServiceSpec(cfg, opts) {
|
|
|
209
255
|
if (cfg.workspaceDir) env.AV_WORKSPACE_DIR = cfg.workspaceDir;
|
|
210
256
|
if (cfg.roomFilter) env.AV_ROOM_ID = cfg.roomFilter;
|
|
211
257
|
if (cfg.grokPath) env.AV_GROK_PATH = cfg.grokPath;
|
|
212
|
-
const launcherPath =
|
|
258
|
+
const launcherPath = join10(cfg.dataDir, "launch-grok-bridge.sh");
|
|
213
259
|
return {
|
|
214
260
|
label: `dev.agentvault.grok-${slugify2(cfg.agentName)}`,
|
|
215
261
|
programArgs: [launcherPath],
|
|
@@ -217,8 +263,8 @@ function buildServiceSpec(cfg, opts) {
|
|
|
217
263
|
launcherScript: renderLauncher({ installPath: opts.path, entrypoint: opts.entrypoint }),
|
|
218
264
|
env,
|
|
219
265
|
workingDir: cfg.workspaceDir ? cfg.workspaceDir : opts.home,
|
|
220
|
-
logOut:
|
|
221
|
-
logErr:
|
|
266
|
+
logOut: join10(cfg.dataDir, "logs", "grok-bridge.log"),
|
|
267
|
+
logErr: join10(cfg.dataDir, "logs", "grok-bridge.error.log"),
|
|
222
268
|
keepAliveUnlessCleanExit: true,
|
|
223
269
|
runAtLoad: true
|
|
224
270
|
};
|
|
@@ -232,7 +278,7 @@ var init_spec = __esm({
|
|
|
232
278
|
});
|
|
233
279
|
|
|
234
280
|
// src/service/launchd.ts
|
|
235
|
-
import { dirname as dirname3, join as
|
|
281
|
+
import { dirname as dirname3, join as join11 } from "node:path";
|
|
236
282
|
function esc2(s2) {
|
|
237
283
|
return s2.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
238
284
|
}
|
|
@@ -279,7 +325,7 @@ var init_launchd = __esm({
|
|
|
279
325
|
}
|
|
280
326
|
deps;
|
|
281
327
|
plistPath(label) {
|
|
282
|
-
return
|
|
328
|
+
return join11(this.deps.home, "Library", "LaunchAgents", `${label}.plist`);
|
|
283
329
|
}
|
|
284
330
|
domain() {
|
|
285
331
|
return `gui/${this.deps.uid}`;
|
|
@@ -327,7 +373,7 @@ var init_launchd = __esm({
|
|
|
327
373
|
});
|
|
328
374
|
|
|
329
375
|
// src/service/systemd.ts
|
|
330
|
-
import { dirname as dirname4, join as
|
|
376
|
+
import { dirname as dirname4, join as join12 } from "node:path";
|
|
331
377
|
function q2(s2) {
|
|
332
378
|
const esc3 = s2.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t").replace(/%/g, "%%");
|
|
333
379
|
return `"${esc3}"`;
|
|
@@ -364,7 +410,7 @@ var init_systemd = __esm({
|
|
|
364
410
|
}
|
|
365
411
|
deps;
|
|
366
412
|
unitPath(label) {
|
|
367
|
-
return
|
|
413
|
+
return join12(this.deps.home, ".config", "systemd", "user", `${label}.service`);
|
|
368
414
|
}
|
|
369
415
|
install(spec) {
|
|
370
416
|
const path2 = this.unitPath(spec.label);
|
|
@@ -404,7 +450,7 @@ __export(backend_exports, {
|
|
|
404
450
|
selectBackend: () => selectBackend
|
|
405
451
|
});
|
|
406
452
|
import { spawnSync } from "node:child_process";
|
|
407
|
-
import { mkdirSync as
|
|
453
|
+
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync3, rmSync as rmSync2, existsSync as existsSync4, chmodSync as chmodSync5 } from "node:fs";
|
|
408
454
|
import { userInfo } from "node:os";
|
|
409
455
|
function defaultDeps() {
|
|
410
456
|
return {
|
|
@@ -415,11 +461,11 @@ function defaultDeps() {
|
|
|
415
461
|
const r2 = spawnSync(cmd, args, { encoding: "utf8" });
|
|
416
462
|
return { code: r2.status ?? 1, stdout: r2.stdout ?? "" };
|
|
417
463
|
},
|
|
418
|
-
writeFile: (p2, d2) =>
|
|
419
|
-
mkdir: (p2) =>
|
|
420
|
-
chmod: (p2, m2) =>
|
|
421
|
-
rm: (p2) =>
|
|
422
|
-
exists: (p2) =>
|
|
464
|
+
writeFile: (p2, d2) => writeFileSync3(p2, d2),
|
|
465
|
+
mkdir: (p2) => mkdirSync5(p2, { recursive: true }),
|
|
466
|
+
chmod: (p2, m2) => chmodSync5(p2, m2),
|
|
467
|
+
rm: (p2) => rmSync2(p2, { force: true }),
|
|
468
|
+
exists: (p2) => existsSync4(p2)
|
|
423
469
|
};
|
|
424
470
|
}
|
|
425
471
|
function selectBackend(platform, deps) {
|
|
@@ -466,10 +512,9 @@ function maybeRunServiceSubcommand(argv, env, deps) {
|
|
|
466
512
|
try {
|
|
467
513
|
if (cmd === "install") {
|
|
468
514
|
const cfg = loadConfig(env, []);
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
);
|
|
515
|
+
const firstBoot = !hasPersistedCreds(cfg.dataDir) && !!cfg.inviteToken;
|
|
516
|
+
if (firstBoot) {
|
|
517
|
+
writePendingInvite(cfg.dataDir, cfg.inviteToken);
|
|
473
518
|
}
|
|
474
519
|
const spec = buildServiceSpec(cfg, {
|
|
475
520
|
entrypoint,
|
|
@@ -481,6 +526,10 @@ function maybeRunServiceSubcommand(argv, env, deps) {
|
|
|
481
526
|
});
|
|
482
527
|
backend.install(spec);
|
|
483
528
|
log(`installed service ${spec.label} \u2014 logs: ${spec.logErr}`);
|
|
529
|
+
if (firstBoot) {
|
|
530
|
+
log("now APPROVE the device in AgentVault \u2014 the service is waiting to enrol");
|
|
531
|
+
log("if it does not connect within a minute, the log above says why");
|
|
532
|
+
}
|
|
484
533
|
log(`check it with: agentvault-grok-bridge status`);
|
|
485
534
|
} else if (cmd === "uninstall") {
|
|
486
535
|
const label = labelFor(env);
|
|
@@ -509,6 +558,7 @@ var init_subcommand = __esm({
|
|
|
509
558
|
"src/service/subcommand.ts"() {
|
|
510
559
|
"use strict";
|
|
511
560
|
init_config();
|
|
561
|
+
init_pending_invite();
|
|
512
562
|
init_log();
|
|
513
563
|
init_spec();
|
|
514
564
|
init_backend();
|
|
@@ -521,12 +571,12 @@ var install_on_ready_exports = {};
|
|
|
521
571
|
__export(install_on_ready_exports, {
|
|
522
572
|
installOnReady: () => installOnReady
|
|
523
573
|
});
|
|
524
|
-
import { existsSync as
|
|
525
|
-
import { join as
|
|
574
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4 } from "node:fs";
|
|
575
|
+
import { join as join13 } from "node:path";
|
|
526
576
|
function installOnReady(channel, cfg, deps) {
|
|
527
577
|
const hasCreds = deps.hasCreds ?? hasPersistedCreds;
|
|
528
|
-
const readLauncher = deps.readLauncher ?? ((p2) =>
|
|
529
|
-
const fenceAuthExists = deps.fenceAuthExists ?? ((home) =>
|
|
578
|
+
const readLauncher = deps.readLauncher ?? ((p2) => existsSync5(p2) ? readFileSync4(p2, "utf8") : void 0);
|
|
579
|
+
const fenceAuthExists = deps.fenceAuthExists ?? ((home) => existsSync5(join13(home, ".grok", "auth.json")));
|
|
530
580
|
let fired = false;
|
|
531
581
|
channel.on("ready", () => {
|
|
532
582
|
if (fired) return;
|
|
@@ -611,8 +661,8 @@ var init_install_on_ready = __esm({
|
|
|
611
661
|
|
|
612
662
|
// src/index.ts
|
|
613
663
|
import { spawn } from "node:child_process";
|
|
614
|
-
import { mkdirSync as
|
|
615
|
-
import { join as
|
|
664
|
+
import { mkdirSync as mkdirSync6 } from "node:fs";
|
|
665
|
+
import { join as join14 } from "node:path";
|
|
616
666
|
|
|
617
667
|
// ../plugin/dist/index.js
|
|
618
668
|
import * as nc from "node:crypto";
|
|
@@ -98229,28 +98279,29 @@ await init_index();
|
|
|
98229
98279
|
|
|
98230
98280
|
// src/index.ts
|
|
98231
98281
|
init_config();
|
|
98282
|
+
init_pending_invite();
|
|
98232
98283
|
init_log();
|
|
98233
98284
|
|
|
98234
98285
|
// src/fence-auth.ts
|
|
98235
|
-
import { copyFileSync, chmodSync as
|
|
98236
|
-
import { join as
|
|
98286
|
+
import { copyFileSync, chmodSync as chmodSync3, existsSync as existsSync3, mkdirSync as mkdirSync3 } from "node:fs";
|
|
98287
|
+
import { join as join7 } from "node:path";
|
|
98237
98288
|
function seedFenceCredential(opts) {
|
|
98238
98289
|
const log = opts.log ?? (() => {
|
|
98239
98290
|
});
|
|
98240
|
-
const fenceGrok =
|
|
98241
|
-
const fenceAuth =
|
|
98242
|
-
if (
|
|
98291
|
+
const fenceGrok = join7(opts.fenceHome, ".grok");
|
|
98292
|
+
const fenceAuth = join7(fenceGrok, "auth.json");
|
|
98293
|
+
if (existsSync3(fenceAuth)) {
|
|
98243
98294
|
log("[grok-bridge] fence credential already present; leaving it untouched");
|
|
98244
98295
|
return "already-present";
|
|
98245
98296
|
}
|
|
98246
|
-
const hostAuth =
|
|
98247
|
-
if (!
|
|
98297
|
+
const hostAuth = join7(opts.hostHome, ".grok", "auth.json");
|
|
98298
|
+
if (!existsSync3(hostAuth)) {
|
|
98248
98299
|
log("[grok-bridge] no host credential to seed (run `grok login`, or set XAI_API_KEY)");
|
|
98249
98300
|
return "no-host-credential";
|
|
98250
98301
|
}
|
|
98251
|
-
|
|
98302
|
+
mkdirSync3(fenceGrok, { recursive: true });
|
|
98252
98303
|
copyFileSync(hostAuth, fenceAuth);
|
|
98253
|
-
|
|
98304
|
+
chmodSync3(fenceAuth, 384);
|
|
98254
98305
|
log("[grok-bridge] seeded fence credential from the host grok login");
|
|
98255
98306
|
return "seeded";
|
|
98256
98307
|
}
|
|
@@ -98551,14 +98602,14 @@ var AcpConnection = class {
|
|
|
98551
98602
|
};
|
|
98552
98603
|
|
|
98553
98604
|
// src/grok-room-plugin.ts
|
|
98554
|
-
import { mkdirSync as
|
|
98555
|
-
import { join as
|
|
98605
|
+
import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync2, chmodSync as chmodSync4 } from "node:fs";
|
|
98606
|
+
import { join as join8 } from "node:path";
|
|
98556
98607
|
var SERVER_KEY = "room";
|
|
98557
98608
|
var GROK_ROOM_SAY_TOOL_NAME = `${SERVER_KEY}__say`;
|
|
98558
98609
|
function writeRoomPluginHttp(dir, url3) {
|
|
98559
|
-
|
|
98560
|
-
|
|
98561
|
-
|
|
98610
|
+
mkdirSync4(join8(dir, ".claude-plugin"), { recursive: true });
|
|
98611
|
+
writeFileSync2(
|
|
98612
|
+
join8(dir, ".claude-plugin", "plugin.json"),
|
|
98562
98613
|
JSON.stringify(
|
|
98563
98614
|
{
|
|
98564
98615
|
name: "avroom",
|
|
@@ -98570,12 +98621,12 @@ function writeRoomPluginHttp(dir, url3) {
|
|
|
98570
98621
|
2
|
|
98571
98622
|
) + "\n"
|
|
98572
98623
|
);
|
|
98573
|
-
|
|
98574
|
-
|
|
98624
|
+
writeFileSync2(
|
|
98625
|
+
join8(dir, ".mcp.json"),
|
|
98575
98626
|
JSON.stringify({ mcpServers: { [SERVER_KEY]: { type: "http", url: url3 } } }, null, 2) + "\n",
|
|
98576
98627
|
{ mode: 384 }
|
|
98577
98628
|
);
|
|
98578
|
-
|
|
98629
|
+
chmodSync4(join8(dir, ".mcp.json"), 384);
|
|
98579
98630
|
}
|
|
98580
98631
|
|
|
98581
98632
|
// src/grok-driver.ts
|
|
@@ -98710,7 +98761,7 @@ var GrokDriver = class {
|
|
|
98710
98761
|
};
|
|
98711
98762
|
|
|
98712
98763
|
// src/grok-spawn.ts
|
|
98713
|
-
import { join as
|
|
98764
|
+
import { join as join9 } from "node:path";
|
|
98714
98765
|
function grokSpawnArgs(opts) {
|
|
98715
98766
|
const args = ["agent", "--no-leader"];
|
|
98716
98767
|
if (opts.model) args.push("--model", opts.model);
|
|
@@ -98719,7 +98770,7 @@ function grokSpawnArgs(opts) {
|
|
|
98719
98770
|
const env = {
|
|
98720
98771
|
PATH: process.env.PATH,
|
|
98721
98772
|
HOME: opts.fenceHome,
|
|
98722
|
-
GROK_HOME:
|
|
98773
|
+
GROK_HOME: join9(opts.fenceHome, ".grok")
|
|
98723
98774
|
};
|
|
98724
98775
|
if (opts.apiKey) env.XAI_API_KEY = opts.apiKey;
|
|
98725
98776
|
return { command: opts.grokPath ?? "grok", args, env, cwd: opts.workspaceDir };
|
|
@@ -99084,7 +99135,7 @@ async function main() {
|
|
|
99084
99135
|
const info = parseInfoFlags(process.argv.slice(2));
|
|
99085
99136
|
if (info.showVersion || info.showHelp) {
|
|
99086
99137
|
const version2 = buildClientVersion2(
|
|
99087
|
-
true ? "0.
|
|
99138
|
+
true ? "0.3.0" : void 0
|
|
99088
99139
|
);
|
|
99089
99140
|
if (info.showVersion) printLine(version2);
|
|
99090
99141
|
if (info.showHelp) {
|
|
@@ -99128,8 +99179,8 @@ async function main() {
|
|
|
99128
99179
|
const { selectBackend: selectBackend2 } = await Promise.resolve().then(() => (init_backend(), backend_exports));
|
|
99129
99180
|
selectBackend2(process.platform);
|
|
99130
99181
|
}
|
|
99131
|
-
|
|
99132
|
-
|
|
99182
|
+
mkdirSync6(cfg.workspaceDir, { recursive: true });
|
|
99183
|
+
mkdirSync6(cfg.fenceHome, { recursive: true });
|
|
99133
99184
|
seedFenceCredential({
|
|
99134
99185
|
fenceHome: cfg.fenceHome,
|
|
99135
99186
|
hostHome: process.env.HOME ?? "",
|
|
@@ -99142,7 +99193,7 @@ async function main() {
|
|
|
99142
99193
|
agentName: cfg.agentName,
|
|
99143
99194
|
platform: "node",
|
|
99144
99195
|
clientVersion: buildClientVersion2(
|
|
99145
|
-
true ? "0.
|
|
99196
|
+
true ? "0.3.0" : void 0
|
|
99146
99197
|
)
|
|
99147
99198
|
});
|
|
99148
99199
|
channelRef = channel;
|
|
@@ -99163,7 +99214,7 @@ async function main() {
|
|
|
99163
99214
|
},
|
|
99164
99215
|
log: (m2) => logLine(m2)
|
|
99165
99216
|
});
|
|
99166
|
-
const pluginDir =
|
|
99217
|
+
const pluginDir = join14(cfg.fenceHome, "av-room-plugin");
|
|
99167
99218
|
writeRoomPluginHttp(pluginDir, mcp.url);
|
|
99168
99219
|
const spawnSpec = grokSpawnArgs({
|
|
99169
99220
|
grokPath: cfg.grokPath,
|
|
@@ -99228,6 +99279,11 @@ async function main() {
|
|
|
99228
99279
|
log: (m2) => logLine("[grok-bridge] " + m2),
|
|
99229
99280
|
onTerminal: (_reason, o2) => void shutdown(o2.restart ? 1 : 0)
|
|
99230
99281
|
});
|
|
99282
|
+
channel.on("ready", () => {
|
|
99283
|
+
if (clearPendingInviteIfConsumed(cfg.dataDir, hasPersistedCreds)) {
|
|
99284
|
+
logLine("[grok-bridge] enrolled \u2014 pending invite consumed and removed");
|
|
99285
|
+
}
|
|
99286
|
+
});
|
|
99231
99287
|
if (cfg.installAfterEnroll) {
|
|
99232
99288
|
const { installOnReady: installOnReady2 } = await Promise.resolve().then(() => (init_install_on_ready(), install_on_ready_exports));
|
|
99233
99289
|
installOnReady2(channel, cfg, {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare function pendingInvitePath(dataDir: string): string;
|
|
2
|
+
/** Persist the token for the service's first boot. Owner-only, unconditionally. */
|
|
3
|
+
export declare function writePendingInvite(dataDir: string, token: string): void;
|
|
4
|
+
/** The pending token, or undefined when there is none to consume. */
|
|
5
|
+
export declare function readPendingInvite(dataDir: string): string | undefined;
|
|
6
|
+
/** Remove it. Idempotent: nothing to remove is a success, not an error. */
|
|
7
|
+
export declare function clearPendingInvite(dataDir: string): void;
|
|
8
|
+
/**
|
|
9
|
+
* Delete the pending invite once there is EVIDENCE it was consumed — i.e.
|
|
10
|
+
* credentials have actually persisted to the data dir.
|
|
11
|
+
*
|
|
12
|
+
* Timing is the whole design here. Deleting on READ (inside loadConfig) would
|
|
13
|
+
* throw the token away before enrolment finished, so a process that died in
|
|
14
|
+
* between would leave a service that can never enrol and a customer whose
|
|
15
|
+
* single-use invite is gone. Never deleting leaves a credential on disk long
|
|
16
|
+
* after it is useless.
|
|
17
|
+
*
|
|
18
|
+
* `credsExist` is injected so the caller supplies `hasPersistedCreds` and this
|
|
19
|
+
* module stays free of a config import cycle.
|
|
20
|
+
*
|
|
21
|
+
* @returns true when a file was actually removed.
|
|
22
|
+
*/
|
|
23
|
+
export declare function clearPendingInviteIfConsumed(dataDir: string, credsExist: (dataDir: string) => boolean): boolean;
|
|
24
|
+
//# sourceMappingURL=pending-invite.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subcommand.d.ts","sourceRoot":"","sources":["../../src/service/subcommand.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"subcommand.d.ts","sourceRoot":"","sources":["../../src/service/subcommand.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAElE,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAQD;;uFAEuF;AACvF,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,IAAI,CAAC,EAAE,cAAc,GACpB,OAAO,CA6GT"}
|
package/package.json
CHANGED