crewx-bridge 0.1.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.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +102 -0
  3. package/dist/api.d.ts +16 -0
  4. package/dist/api.d.ts.map +1 -0
  5. package/dist/api.js +157 -0
  6. package/dist/api.js.map +1 -0
  7. package/dist/config.d.ts +83 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +233 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/constants.d.ts +7 -0
  12. package/dist/constants.d.ts.map +1 -0
  13. package/dist/constants.js +13 -0
  14. package/dist/constants.js.map +1 -0
  15. package/dist/daemon.d.ts +36 -0
  16. package/dist/daemon.d.ts.map +1 -0
  17. package/dist/daemon.js +313 -0
  18. package/dist/daemon.js.map +1 -0
  19. package/dist/errors.d.ts +8 -0
  20. package/dist/errors.d.ts.map +1 -0
  21. package/dist/errors.js +32 -0
  22. package/dist/errors.js.map +1 -0
  23. package/dist/folders.d.ts +13 -0
  24. package/dist/folders.d.ts.map +1 -0
  25. package/dist/folders.js +63 -0
  26. package/dist/folders.js.map +1 -0
  27. package/dist/index.d.ts +15 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +322 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/journal.d.ts +76 -0
  32. package/dist/journal.d.ts.map +1 -0
  33. package/dist/journal.js +106 -0
  34. package/dist/journal.js.map +1 -0
  35. package/dist/policy.d.ts +4 -0
  36. package/dist/policy.d.ts.map +1 -0
  37. package/dist/policy.js +19 -0
  38. package/dist/policy.js.map +1 -0
  39. package/dist/service.d.ts +45 -0
  40. package/dist/service.d.ts.map +1 -0
  41. package/dist/service.js +221 -0
  42. package/dist/service.js.map +1 -0
  43. package/dist/supervisor.d.ts +23 -0
  44. package/dist/supervisor.d.ts.map +1 -0
  45. package/dist/supervisor.js +149 -0
  46. package/dist/supervisor.js.map +1 -0
  47. package/package.json +52 -0
package/dist/index.js ADDED
@@ -0,0 +1,322 @@
1
+ #!/usr/bin/env node
2
+ import { realpathSync } from "node:fs";
3
+ import { hostname } from "node:os";
4
+ import { resolve } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ import { Command, InvalidArgumentError } from "commander";
7
+ import { BridgeApi, enrollMachine } from "./api.js";
8
+ import { BRIDGE_VERSION } from "./constants.js";
9
+ import { bridgeConfigPath, normalizeServerUrl, readBridgeConfig, saveBridgeConfig, } from "./config.js";
10
+ import { policySummary, probeCapabilities, runBridge, supportedAdapters, } from "./daemon.js";
11
+ import { BridgeError, errorMessage, redactSecrets } from "./errors.js";
12
+ import { folderDescriptors, registerFolder, removeFolder, } from "./folders.js";
13
+ import { installService, serviceStatus, uninstallService, } from "./service.js";
14
+ function positiveInteger(value) {
15
+ const parsed = Number(value);
16
+ if (!Number.isSafeInteger(parsed) || parsed <= 0) {
17
+ throw new InvalidArgumentError("must be a positive integer");
18
+ }
19
+ return parsed;
20
+ }
21
+ function commaSeparated(value) {
22
+ return [...new Set(value.split(",").map((item) => item.trim()).filter(Boolean))];
23
+ }
24
+ function printJson(value) {
25
+ process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
26
+ }
27
+ async function syncFolders(config) {
28
+ await new BridgeApi(config).syncFolders({
29
+ folders: folderDescriptors(config),
30
+ });
31
+ }
32
+ export function createProgram() {
33
+ const program = new Command();
34
+ program
35
+ .name("crewx-bridge")
36
+ .description("Securely connect a macOS or Linux machine to a CrewX workspace.")
37
+ .version(BRIDGE_VERSION)
38
+ .showHelpAfterError()
39
+ .configureHelp({ sortOptions: true, sortSubcommands: true });
40
+ program
41
+ .command("enroll")
42
+ .description("Enroll this machine with a one-time workspace code")
43
+ .requiredOption("--url <url>", "CrewX server URL")
44
+ .requiredOption("--code <code>", "single-use Bridge enrollment code")
45
+ .option("--name <name>", "machine name shown in CrewX", hostname())
46
+ .action(async (options) => {
47
+ if (!["darwin", "linux"].includes(process.platform)) {
48
+ throw new BridgeError("unsupported_platform", "CrewX Bridge currently supports macOS and Linux.");
49
+ }
50
+ if (typeof process.getuid === "function" && process.getuid() === 0) {
51
+ throw new BridgeError("root_refused", "CrewX Bridge refuses to enroll as root.");
52
+ }
53
+ const capabilities = await probeCapabilities();
54
+ const response = await enrollMachine(options.url, {
55
+ protocol_version: 1,
56
+ code: options.code,
57
+ name: options.name,
58
+ hostname: hostname(),
59
+ platform: process.platform === "darwin" ? "darwin" : "linux",
60
+ arch: process.arch,
61
+ client_version: BRIDGE_VERSION,
62
+ capabilities,
63
+ policy: {
64
+ allowed_adapters: [...supportedAdapters()],
65
+ allowed_permissions: ["read_only", "standard"],
66
+ allow_full_access: false,
67
+ max_concurrent_runs: 2,
68
+ },
69
+ });
70
+ const config = {
71
+ version: 1,
72
+ url: normalizeServerUrl(options.url),
73
+ token: response.token,
74
+ machineId: response.machine_id,
75
+ machineName: options.name.trim(),
76
+ workspace: response.workspace,
77
+ heartbeatInterval: response.heartbeat_interval,
78
+ policy: {
79
+ allowedAdapters: [...supportedAdapters()],
80
+ allowedPermissions: ["read_only", "standard"],
81
+ allowFullAccess: false,
82
+ maxConcurrentRuns: 2,
83
+ shutdownGraceMs: 10_000,
84
+ },
85
+ folders: [],
86
+ };
87
+ const path = await saveBridgeConfig(config);
88
+ console.log("✓ CrewX Bridge enrolled");
89
+ console.log(` Machine ${config.machineName}`);
90
+ console.log(` Workspace ${config.workspace.slug}`);
91
+ console.log(` Config ${path} (mode 0600)`);
92
+ console.log("\nAdd a project with `crewx-bridge folder add <path>`.");
93
+ console.log("Then run `crewx-bridge service install`.");
94
+ });
95
+ program
96
+ .command("status")
97
+ .description("Show local enrollment and user-service state")
98
+ .option("--json", "print machine-readable JSON")
99
+ .action(async (options) => {
100
+ const config = await readBridgeConfig();
101
+ const service = await serviceStatus();
102
+ const result = {
103
+ enrolled: true,
104
+ machine_id: config.machineId,
105
+ machine_name: config.machineName,
106
+ workspace: config.workspace,
107
+ url: config.url,
108
+ folders: folderDescriptors(config),
109
+ service,
110
+ config_path: bridgeConfigPath(),
111
+ };
112
+ if (options.json) {
113
+ printJson(result);
114
+ return;
115
+ }
116
+ console.log(`Machine ${config.machineName}`);
117
+ console.log(`Workspace ${config.workspace.slug}`);
118
+ console.log(`Server ${config.url}`);
119
+ console.log(`Folders ${config.folders.length}`);
120
+ console.log(`Service ${service.running ? "running" : "not running"}`);
121
+ });
122
+ program
123
+ .command("doctor")
124
+ .description("Check protected state, agent runtimes, and CrewX connectivity")
125
+ .option("--json", "print machine-readable JSON")
126
+ .action(async (options) => {
127
+ const config = await readBridgeConfig();
128
+ const capabilities = await probeCapabilities();
129
+ let reachable = true;
130
+ let connectionError;
131
+ try {
132
+ await new BridgeApi(config).heartbeat({
133
+ protocol_version: 1,
134
+ client_version: BRIDGE_VERSION,
135
+ hostname: hostname(),
136
+ platform: process.platform === "darwin" ? "darwin" : "linux",
137
+ arch: process.arch,
138
+ capabilities,
139
+ policy: policySummary(config),
140
+ runs: [],
141
+ });
142
+ }
143
+ catch (error) {
144
+ reachable = false;
145
+ connectionError = redactSecrets(errorMessage(error), [config.token]);
146
+ }
147
+ const result = {
148
+ node: process.version,
149
+ platform: process.platform,
150
+ config: bridgeConfigPath(),
151
+ reachable,
152
+ ...(connectionError ? { connection_error: connectionError } : {}),
153
+ capabilities,
154
+ policy: policySummary(config),
155
+ };
156
+ if (options.json) {
157
+ printJson(result);
158
+ return;
159
+ }
160
+ console.log("CrewX Bridge doctor");
161
+ console.log(` Config ✓ ${bridgeConfigPath()}`);
162
+ console.log(` API ${reachable ? "✓ reachable" : `✗ ${connectionError}`}`);
163
+ for (const runtime of capabilities.runtimes) {
164
+ console.log(` ${runtime.adapter.padEnd(9)} ${runtime.available ? "✓" : "–"} ${runtime.version ?? "not found"}`);
165
+ }
166
+ });
167
+ const folder = program
168
+ .command("folder")
169
+ .description("Manage folders explicitly allowed for Bridge launches");
170
+ folder
171
+ .command("add")
172
+ .argument("<path>", "existing project directory")
173
+ .option("--name <name>", "display name shown in CrewX")
174
+ .action(async (path, options) => {
175
+ const config = await readBridgeConfig();
176
+ const registered = await registerFolder(config, resolve(path), options.name);
177
+ await saveBridgeConfig(registered.config);
178
+ await syncFolders(registered.config);
179
+ console.log(`✓ Added ${registered.folder.name}`);
180
+ console.log(` ID ${registered.folder.id}`);
181
+ console.log(` Path ${registered.folder.path}`);
182
+ });
183
+ folder
184
+ .command("list")
185
+ .option("--json", "print machine-readable JSON")
186
+ .action(async (options) => {
187
+ const config = await readBridgeConfig();
188
+ if (options.json) {
189
+ printJson(config.folders);
190
+ return;
191
+ }
192
+ if (config.folders.length === 0) {
193
+ console.log("No folders are registered.");
194
+ return;
195
+ }
196
+ for (const entry of config.folders) {
197
+ console.log(`${entry.id} ${entry.name} ${entry.path}`);
198
+ }
199
+ });
200
+ folder
201
+ .command("remove")
202
+ .argument("<folder-id>", "opaque folder ID from `folder list`")
203
+ .action(async (folderId) => {
204
+ const config = removeFolder(await readBridgeConfig(), folderId);
205
+ await saveBridgeConfig(config);
206
+ await syncFolders(config);
207
+ console.log("✓ Folder removed.");
208
+ });
209
+ program
210
+ .command("policy")
211
+ .description("Set the machine-owner-enforced launch policy")
212
+ .option("--adapters <list>", "comma-separated allowed runtimes")
213
+ .option("--permissions <list>", "comma-separated permission presets")
214
+ .option("--max-runs <count>", "maximum concurrent agent processes", positiveInteger)
215
+ .option("--allow-full-access", "explicitly allow full_access launches", false)
216
+ .option("--deny-full-access", "disable full_access launches", false)
217
+ .action(async (options) => {
218
+ if (options.allowFullAccess && options.denyFullAccess) {
219
+ throw new BridgeError("invalid_policy", "Choose either --allow-full-access or --deny-full-access.");
220
+ }
221
+ const config = await readBridgeConfig();
222
+ const allowedAdapters = options.adapters
223
+ ? commaSeparated(options.adapters)
224
+ : config.policy.allowedAdapters;
225
+ const allowedPermissions = options.permissions
226
+ ? commaSeparated(options.permissions)
227
+ : config.policy.allowedPermissions;
228
+ const updated = {
229
+ ...config,
230
+ policy: {
231
+ ...config.policy,
232
+ allowedAdapters,
233
+ allowedPermissions,
234
+ allowFullAccess: options.allowFullAccess
235
+ ? true
236
+ : options.denyFullAccess
237
+ ? false
238
+ : config.policy.allowFullAccess,
239
+ maxConcurrentRuns: options.maxRuns ?? config.policy.maxConcurrentRuns,
240
+ },
241
+ };
242
+ const path = await saveBridgeConfig(updated);
243
+ console.log(`✓ Policy saved to ${path}.`);
244
+ });
245
+ program
246
+ .command("serve")
247
+ .description("Run the foreground Bridge control loop")
248
+ .option("--once", "perform one claim cycle and exit")
249
+ .action(async (options) => {
250
+ const controller = new AbortController();
251
+ const stop = () => controller.abort();
252
+ process.once("SIGINT", stop);
253
+ process.once("SIGTERM", stop);
254
+ try {
255
+ await runBridge({
256
+ config: await readBridgeConfig(),
257
+ once: options.once ?? false,
258
+ signal: controller.signal,
259
+ log: (message) => console.log(`[crewx-bridge] ${message}`),
260
+ });
261
+ }
262
+ finally {
263
+ process.removeListener("SIGINT", stop);
264
+ process.removeListener("SIGTERM", stop);
265
+ }
266
+ });
267
+ const service = program
268
+ .command("service")
269
+ .description("Manage the per-user launchd or systemd service");
270
+ service.command("install").action(async () => {
271
+ await readBridgeConfig();
272
+ const path = await installService();
273
+ console.log(`✓ CrewX Bridge service installed at ${path}.`);
274
+ });
275
+ service.command("uninstall").action(async () => {
276
+ const path = await uninstallService();
277
+ console.log(`✓ CrewX Bridge service removed from ${path}.`);
278
+ });
279
+ service.command("status").action(async () => {
280
+ const status = await serviceStatus();
281
+ console.log(status.running ? "● CrewX Bridge is running" : "○ CrewX Bridge is not running");
282
+ if (status.detail)
283
+ console.log(status.detail);
284
+ if (!status.running && process.platform === "linux") {
285
+ console.log("For unattended VPS use, ask an administrator to enable systemd user lingering.");
286
+ }
287
+ });
288
+ return program;
289
+ }
290
+ export async function main(argv = process.argv) {
291
+ try {
292
+ await createProgram().parseAsync(argv);
293
+ }
294
+ catch (error) {
295
+ console.error(`Error: ${redactSecrets(errorMessage(error))}`);
296
+ process.exitCode = error instanceof BridgeError ? error.exitCode : 1;
297
+ }
298
+ }
299
+ export function isMainModule(moduleUrl, invokedPath = process.argv[1]) {
300
+ if (!invokedPath)
301
+ return false;
302
+ try {
303
+ return (realpathSync.native(fileURLToPath(moduleUrl)) ===
304
+ realpathSync.native(resolve(invokedPath)));
305
+ }
306
+ catch {
307
+ return false;
308
+ }
309
+ }
310
+ if (isMainModule(import.meta.url)) {
311
+ await main();
312
+ }
313
+ export { BridgeApi, enrollMachine } from "./api.js";
314
+ export { bridgeConfigPath, bridgeJournalPath, normalizeServerUrl, readBridgeConfig, saveBridgeConfig, } from "./config.js";
315
+ export { BridgeDaemon, runBridge } from "./daemon.js";
316
+ export { BridgeError, redactSecrets } from "./errors.js";
317
+ export { registerFolder, removeFolder, verifyLaunchFolder } from "./folders.js";
318
+ export { BridgeJournal } from "./journal.js";
319
+ export { validateStartPolicy } from "./policy.js";
320
+ export { installService, launchdDefinition, servicePath, serviceStatus, systemdDefinition, uninstallService, } from "./service.js";
321
+ export { minimalChildEnvironment, ProcessSupervisor, resolveAgentCliEntrypoint, } from "./supervisor.js";
322
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ import { type BridgeRunStatus } from "crewx-agent-protocol";
2
+ import { z } from "zod";
3
+ import { type BridgePathEnvironment } from "./config.js";
4
+ declare const JournalCommandSchema: z.ZodObject<{
5
+ state: z.ZodEnum<{
6
+ accepted: "accepted";
7
+ succeeded: "succeeded";
8
+ failed: "failed";
9
+ }>;
10
+ runId: z.ZodUUID;
11
+ type: z.ZodEnum<{
12
+ start_agent: "start_agent";
13
+ stop_agent: "stop_agent";
14
+ }>;
15
+ result: z.ZodOptional<z.ZodObject<{
16
+ run_status: z.ZodOptional<z.ZodEnum<{
17
+ running: "running";
18
+ failed: "failed";
19
+ stopping: "stopping";
20
+ stopped: "stopped";
21
+ starting: "starting";
22
+ lost: "lost";
23
+ }>>;
24
+ pid: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
25
+ exit_code: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
26
+ signal: z.ZodOptional<z.ZodNullable<z.ZodString>>;
27
+ }, z.core.$strict>>;
28
+ errorCode: z.ZodOptional<z.ZodString>;
29
+ updatedAt: z.ZodISODateTime;
30
+ }, z.core.$strict>;
31
+ export type JournalCommand = z.infer<typeof JournalCommandSchema>;
32
+ declare const JournalRunSchema: z.ZodObject<{
33
+ status: z.ZodEnum<{
34
+ running: "running";
35
+ failed: "failed";
36
+ stopping: "stopping";
37
+ stopped: "stopped";
38
+ starting: "starting";
39
+ lost: "lost";
40
+ }>;
41
+ pid: z.ZodNullable<z.ZodNumber>;
42
+ adapter: z.ZodEnum<{
43
+ codex: "codex";
44
+ claude: "claude";
45
+ pi: "pi";
46
+ hermes: "hermes";
47
+ openclaw: "openclaw";
48
+ }>;
49
+ folderId: z.ZodUUID;
50
+ startedAt: z.ZodNullable<z.ZodISODateTime>;
51
+ }, z.core.$strict>;
52
+ export type JournalRun = z.infer<typeof JournalRunSchema>;
53
+ export declare class BridgeJournal {
54
+ readonly path: string;
55
+ private state;
56
+ private writes;
57
+ constructor(environment?: BridgePathEnvironment, platform?: NodeJS.Platform);
58
+ load(): Promise<void>;
59
+ getCommand(commandId: string): JournalCommand | undefined;
60
+ getRun(runId: string): JournalRun | undefined;
61
+ activeRuns(): Array<{
62
+ id: string;
63
+ } & JournalRun>;
64
+ recordCommand(commandId: string, command: Omit<JournalCommand, "updatedAt">): Promise<void>;
65
+ recordRun(runId: string, run: {
66
+ status: BridgeRunStatus;
67
+ pid: number | null;
68
+ adapter: JournalRun["adapter"];
69
+ folderId: string;
70
+ startedAt: string | null;
71
+ }): Promise<void>;
72
+ private current;
73
+ private persist;
74
+ }
75
+ export {};
76
+ //# sourceMappingURL=journal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal.d.ts","sourceRoot":"","sources":["../src/journal.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAEL,KAAK,qBAAqB,EAG3B,MAAM,aAAa,CAAC;AAGrB,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;kBAiBf,CAAC;AACZ,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;kBAQX,CAAC;AACZ,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAiB1D,qBAAa,aAAa;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,MAAM,CAAoC;gBAGhD,WAAW,GAAE,qBAAmC,EAChD,QAAQ,kBAAmB;IAKvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAwB3B,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAIzD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAI7C,UAAU,IAAI,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU,CAAC;IAQ1C,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,GACzC,OAAO,CAAC,IAAI,CAAC;IAQV,SAAS,CACb,KAAK,EAAE,MAAM,EACb,GAAG,EAAE;QACH,MAAM,EAAE,eAAe,CAAC;QACxB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QACnB,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC;QAC/B,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,GACA,OAAO,CAAC,IAAI,CAAC;IAKhB,OAAO,CAAC,OAAO;YAUD,OAAO;CAOtB"}
@@ -0,0 +1,106 @@
1
+ import { AgentAdapterSchema, BridgeRunStatusSchema, } from "crewx-agent-protocol";
2
+ import { z } from "zod";
3
+ import { bridgeJournalPath, readSecureText, writeSecureText, } from "./config.js";
4
+ import { BridgeError } from "./errors.js";
5
+ const JournalCommandSchema = z
6
+ .object({
7
+ state: z.enum(["accepted", "succeeded", "failed"]),
8
+ runId: z.uuid(),
9
+ type: z.enum(["start_agent", "stop_agent"]),
10
+ result: z
11
+ .object({
12
+ run_status: BridgeRunStatusSchema.optional(),
13
+ pid: z.number().int().positive().nullable().optional(),
14
+ exit_code: z.number().int().nullable().optional(),
15
+ signal: z.string().max(32).nullable().optional(),
16
+ })
17
+ .strict()
18
+ .optional(),
19
+ errorCode: z.string().max(80).optional(),
20
+ updatedAt: z.iso.datetime({ offset: true }),
21
+ })
22
+ .strict();
23
+ const JournalRunSchema = z
24
+ .object({
25
+ status: BridgeRunStatusSchema,
26
+ pid: z.number().int().positive().nullable(),
27
+ adapter: AgentAdapterSchema,
28
+ folderId: z.uuid(),
29
+ startedAt: z.iso.datetime({ offset: true }).nullable(),
30
+ })
31
+ .strict();
32
+ const JournalSchema = z
33
+ .object({
34
+ version: z.literal(1),
35
+ commands: z.record(z.string(), JournalCommandSchema),
36
+ runs: z.record(z.string(), JournalRunSchema),
37
+ })
38
+ .strict();
39
+ const EMPTY_JOURNAL = {
40
+ version: 1,
41
+ commands: {},
42
+ runs: {},
43
+ };
44
+ export class BridgeJournal {
45
+ path;
46
+ state;
47
+ writes = Promise.resolve();
48
+ constructor(environment = process.env, platform = process.platform) {
49
+ this.path = bridgeJournalPath(environment, platform);
50
+ }
51
+ async load() {
52
+ const raw = await readSecureText(this.path);
53
+ if (!raw) {
54
+ this.state = structuredClone(EMPTY_JOURNAL);
55
+ return;
56
+ }
57
+ let parsed;
58
+ try {
59
+ parsed = JSON.parse(raw);
60
+ }
61
+ catch (error) {
62
+ throw new BridgeError("invalid_journal", "The local Bridge journal is invalid JSON.", 1, {
63
+ cause: error,
64
+ });
65
+ }
66
+ const result = JournalSchema.safeParse(parsed);
67
+ if (!result.success) {
68
+ throw new BridgeError("invalid_journal", "The local Bridge journal has an unsupported or unsafe shape.");
69
+ }
70
+ this.state = result.data;
71
+ }
72
+ getCommand(commandId) {
73
+ return this.current().commands[commandId];
74
+ }
75
+ getRun(runId) {
76
+ return this.current().runs[runId];
77
+ }
78
+ activeRuns() {
79
+ return Object.entries(this.current().runs)
80
+ .filter(([, run]) => ["starting", "running", "stopping"].includes(run.status))
81
+ .map(([id, run]) => ({ id, ...run }));
82
+ }
83
+ async recordCommand(commandId, command) {
84
+ this.current().commands[commandId] = {
85
+ ...command,
86
+ updatedAt: new Date().toISOString(),
87
+ };
88
+ await this.persist();
89
+ }
90
+ async recordRun(runId, run) {
91
+ this.current().runs[runId] = JournalRunSchema.parse(run);
92
+ await this.persist();
93
+ }
94
+ current() {
95
+ if (!this.state) {
96
+ throw new BridgeError("journal_not_loaded", "The Bridge journal must be loaded before use.");
97
+ }
98
+ return this.state;
99
+ }
100
+ async persist() {
101
+ const snapshot = JSON.stringify(JournalSchema.parse(this.current()), null, 2);
102
+ this.writes = this.writes.then(() => writeSecureText(this.path, `${snapshot}\n`));
103
+ await this.writes;
104
+ }
105
+ }
106
+ //# sourceMappingURL=journal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal.js","sourceRoot":"","sources":["../src/journal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type BridgeStartAgentPayload } from "crewx-agent-protocol";
2
+ import { type BridgeConfig } from "./config.js";
3
+ export declare function validateStartPolicy(config: BridgeConfig, rawPayload: unknown, activeRunCount: number): BridgeStartAgentPayload;
4
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,YAAY,EACpB,UAAU,EAAE,OAAO,EACnB,cAAc,EAAE,MAAM,GACrB,uBAAuB,CA2BzB"}
package/dist/policy.js ADDED
@@ -0,0 +1,19 @@
1
+ import { BridgeStartAgentPayloadSchema, } from "crewx-agent-protocol";
2
+ import { BridgeError } from "./errors.js";
3
+ export function validateStartPolicy(config, rawPayload, activeRunCount) {
4
+ const payload = BridgeStartAgentPayloadSchema.parse(rawPayload);
5
+ if (!config.policy.allowedAdapters.includes(payload.adapter)) {
6
+ throw new BridgeError("policy_adapter_denied", `The local policy does not allow the ${payload.adapter} runtime.`);
7
+ }
8
+ if (!config.policy.allowedPermissions.includes(payload.permission)) {
9
+ throw new BridgeError("policy_permission_denied", `The local policy does not allow ${payload.permission}.`);
10
+ }
11
+ if (payload.permission === "full_access" && !config.policy.allowFullAccess) {
12
+ throw new BridgeError("policy_full_access_denied", "Full access is disabled by the machine owner.");
13
+ }
14
+ if (activeRunCount >= config.policy.maxConcurrentRuns) {
15
+ throw new BridgeError("policy_concurrency_exceeded", "The local concurrent-run limit has been reached.");
16
+ }
17
+ return payload;
18
+ }
19
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,GAE9B,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,UAAU,mBAAmB,CACjC,MAAoB,EACpB,UAAmB,EACnB,cAAsB;IAEtB,MAAM,OAAO,GAAG,6BAA6B,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAChE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,WAAW,CACnB,uBAAuB,EACvB,uCAAuC,OAAO,CAAC,OAAO,WAAW,CAClE,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACnE,MAAM,IAAI,WAAW,CACnB,0BAA0B,EAC1B,mCAAmC,OAAO,CAAC,UAAU,GAAG,CACzD,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,KAAK,aAAa,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3E,MAAM,IAAI,WAAW,CACnB,2BAA2B,EAC3B,+CAA+C,CAChD,CAAC;IACJ,CAAC;IACD,IAAI,cAAc,IAAI,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;QACtD,MAAM,IAAI,WAAW,CACnB,6BAA6B,EAC7B,kDAAkD,CACnD,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { type BridgePathEnvironment } from "./config.js";
2
+ export type ServiceExecutor = (file: string, args: readonly string[]) => Promise<{
3
+ stdout: string;
4
+ stderr: string;
5
+ }>;
6
+ export declare function bridgeServiceEntrypoint(): string;
7
+ export declare function launchdDefinition(options: {
8
+ nodePath: string;
9
+ entrypoint: string;
10
+ stdoutPath: string;
11
+ stderrPath: string;
12
+ pathEnvironment?: string;
13
+ }): string;
14
+ export declare function systemdDefinition(options: {
15
+ nodePath: string;
16
+ entrypoint: string;
17
+ pathEnvironment?: string;
18
+ }): string;
19
+ export declare function servicePath(platform?: NodeJS.Platform, userHome?: string): string;
20
+ export declare function installService(options?: {
21
+ platform?: NodeJS.Platform;
22
+ userHome?: string;
23
+ uid?: number;
24
+ effectiveUid?: number;
25
+ environment?: BridgePathEnvironment;
26
+ executor?: ServiceExecutor;
27
+ nodePath?: string;
28
+ entrypoint?: string;
29
+ }): Promise<string>;
30
+ export declare function uninstallService(options?: {
31
+ platform?: NodeJS.Platform;
32
+ userHome?: string;
33
+ uid?: number;
34
+ effectiveUid?: number;
35
+ executor?: ServiceExecutor;
36
+ }): Promise<string>;
37
+ export declare function serviceStatus(options?: {
38
+ platform?: NodeJS.Platform;
39
+ uid?: number;
40
+ executor?: ServiceExecutor;
41
+ }): Promise<{
42
+ running: boolean;
43
+ detail: string;
44
+ }>;
45
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAOA,OAAO,EAGL,KAAK,qBAAqB,EAE3B,MAAM,aAAa,CAAC;AAKrB,MAAM,MAAM,eAAe,GAAG,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,SAAS,MAAM,EAAE,KACpB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AA+BjD,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAG,MAAM,CAmCT;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAG,MAAM,CAwBT;AAkBD,wBAAgB,WAAW,CACzB,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,QAAQ,SAAY,GACnB,MAAM,CAWR;AAcD,wBAAsB,cAAc,CAAC,OAAO,GAAE;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoDvB;AAED,wBAAsB,gBAAgB,CAAC,OAAO,GAAE;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,eAAe,CAAC;CACvB,GAAG,OAAO,CAAC,MAAM,CAAC,CAkCvB;AAED,wBAAsB,aAAa,CAAC,OAAO,GAAE;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,eAAe,CAAC;CACvB,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAgCrD"}