@relaymessenger/cli 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.
Files changed (74) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +139 -0
  3. package/claude-plugin/marketplace/.claude-plugin/marketplace.json +14 -0
  4. package/claude-plugin/marketplace/plugins/relay/.claude-plugin/plugin.json +18 -0
  5. package/claude-plugin/marketplace/plugins/relay/LICENSE +21 -0
  6. package/claude-plugin/marketplace/plugins/relay/README.md +173 -0
  7. package/claude-plugin/marketplace/plugins/relay/commands/configure.md +71 -0
  8. package/claude-plugin/marketplace/plugins/relay/runtime/server.mjs +26107 -0
  9. package/dist/api.d.ts +74 -0
  10. package/dist/api.d.ts.map +1 -0
  11. package/dist/api.js +129 -0
  12. package/dist/api.js.map +1 -0
  13. package/dist/claude-settings.d.ts +14 -0
  14. package/dist/claude-settings.d.ts.map +1 -0
  15. package/dist/claude-settings.js +47 -0
  16. package/dist/claude-settings.js.map +1 -0
  17. package/dist/cli.d.ts +3 -0
  18. package/dist/cli.d.ts.map +1 -0
  19. package/dist/cli.js +162 -0
  20. package/dist/cli.js.map +1 -0
  21. package/dist/codex.d.ts +25 -0
  22. package/dist/codex.d.ts.map +1 -0
  23. package/dist/codex.js +227 -0
  24. package/dist/codex.js.map +1 -0
  25. package/dist/doctor.d.ts +2 -0
  26. package/dist/doctor.d.ts.map +1 -0
  27. package/dist/doctor.js +122 -0
  28. package/dist/doctor.js.map +1 -0
  29. package/dist/engine/acp.d.ts +69 -0
  30. package/dist/engine/acp.d.ts.map +1 -0
  31. package/dist/engine/acp.js +402 -0
  32. package/dist/engine/acp.js.map +1 -0
  33. package/dist/engine/catalog.d.ts +26 -0
  34. package/dist/engine/catalog.d.ts.map +1 -0
  35. package/dist/engine/catalog.js +41 -0
  36. package/dist/engine/catalog.js.map +1 -0
  37. package/dist/engine/process.d.ts +12 -0
  38. package/dist/engine/process.d.ts.map +1 -0
  39. package/dist/engine/process.js +54 -0
  40. package/dist/engine/process.js.map +1 -0
  41. package/dist/engine/types.d.ts +57 -0
  42. package/dist/engine/types.d.ts.map +1 -0
  43. package/dist/engine/types.js +8 -0
  44. package/dist/engine/types.js.map +1 -0
  45. package/dist/flags.d.ts +9 -0
  46. package/dist/flags.d.ts.map +1 -0
  47. package/dist/flags.js +34 -0
  48. package/dist/flags.js.map +1 -0
  49. package/dist/install.d.ts +69 -0
  50. package/dist/install.d.ts.map +1 -0
  51. package/dist/install.js +510 -0
  52. package/dist/install.js.map +1 -0
  53. package/dist/mcp.d.ts +16 -0
  54. package/dist/mcp.d.ts.map +1 -0
  55. package/dist/mcp.js +127 -0
  56. package/dist/mcp.js.map +1 -0
  57. package/dist/pair.d.ts +20 -0
  58. package/dist/pair.d.ts.map +1 -0
  59. package/dist/pair.js +135 -0
  60. package/dist/pair.js.map +1 -0
  61. package/dist/permissions.d.ts +87 -0
  62. package/dist/permissions.d.ts.map +1 -0
  63. package/dist/permissions.js +342 -0
  64. package/dist/permissions.js.map +1 -0
  65. package/dist/receive.d.ts +54 -0
  66. package/dist/receive.d.ts.map +1 -0
  67. package/dist/receive.js +353 -0
  68. package/dist/receive.js.map +1 -0
  69. package/dist/store.d.ts +260 -0
  70. package/dist/store.d.ts.map +1 -0
  71. package/dist/store.js +550 -0
  72. package/dist/store.js.map +1 -0
  73. package/openclaw-plugin/relaymessenger-openclaw-plugin-0.1.0.tgz +0 -0
  74. package/package.json +51 -0
package/dist/api.d.ts ADDED
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Thin client for the Relay public API (https://docs.relayapp.im).
3
+ * Wire shapes follow Relay's public OpenAPI contract at
4
+ * https://docs.relayapp.im/api-reference/openapi.yaml.
5
+ */
6
+ import type { RelayEvent, RelayMessage } from "./store.js";
7
+ export declare const PRODUCTION_ORIGIN = "https://api.relayapp.im";
8
+ /**
9
+ * Bearer tokens may only leave over HTTPS. Plain HTTP is accepted solely for
10
+ * explicit loopback development servers, and base URLs cannot smuggle a path,
11
+ * query, credentials, or fragment into request construction.
12
+ */
13
+ export declare function normalizeApiOrigin(value: string): string;
14
+ /**
15
+ * Development/testing override for the Relay API origin. Production stays the
16
+ * default; when RELAY_API_ORIGIN is set it passes normalizeApiOrigin, so the
17
+ * loopback carve-out there remains the only place plain HTTP is accepted.
18
+ */
19
+ export declare function resolveApiOrigin(fallback?: string): string;
20
+ export declare class RelayApiError extends Error {
21
+ readonly status: number;
22
+ readonly code: string | undefined;
23
+ constructor(status: number, code: string | undefined, message: string);
24
+ }
25
+ export interface PairingCreated {
26
+ pairing_id: string;
27
+ code: string;
28
+ url: string;
29
+ poll_token: string;
30
+ expires_in: number;
31
+ }
32
+ export type PairingStatus = {
33
+ status: "pending";
34
+ } | {
35
+ status: "claimed";
36
+ agent_token: string;
37
+ agent?: Record<string, unknown>;
38
+ };
39
+ export interface EventsPage {
40
+ events: RelayEvent[];
41
+ next_cursor: number;
42
+ }
43
+ export interface PostMessageBody {
44
+ conversation_id: string;
45
+ parts: Array<Record<string, unknown>>;
46
+ suggestions?: Array<{
47
+ text: string;
48
+ }>;
49
+ reply_to?: {
50
+ message_id: string;
51
+ part_index?: number;
52
+ };
53
+ }
54
+ export declare class RelayClient {
55
+ private readonly token?;
56
+ private readonly fetchImpl;
57
+ readonly origin: string;
58
+ constructor(origin: string, token?: string | undefined, fetchImpl?: typeof fetch);
59
+ private request;
60
+ createPairing(deviceName: string, engine?: string): Promise<PairingCreated>;
61
+ waitPairing(pairingId: string, pollToken: string): Promise<PairingStatus>;
62
+ getMe(): Promise<Record<string, unknown>>;
63
+ getEvents(cursor: number, timeoutS?: number, limit?: number): Promise<EventsPage>;
64
+ postMessage(body: PostMessageBody, idempotencyKey: string): Promise<{
65
+ message_id: string;
66
+ message: RelayMessage;
67
+ }>;
68
+ listMessages(conversationId: string, limit?: number): Promise<{
69
+ messages: RelayMessage[];
70
+ }>;
71
+ setTyping(conversationId: string, started: boolean, label?: string): Promise<void>;
72
+ markRead(conversationId: string, messageId: string): Promise<void>;
73
+ }
74
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
package/dist/api.js ADDED
@@ -0,0 +1,129 @@
1
+ export const PRODUCTION_ORIGIN = "https://api.relayapp.im";
2
+ function isLoopbackHost(hostname) {
3
+ const host = hostname.toLowerCase();
4
+ return host === "localhost" || host.endsWith(".localhost") || host === "::1" || host === "[::1]" || /^127\./.test(host);
5
+ }
6
+ /**
7
+ * Bearer tokens may only leave over HTTPS. Plain HTTP is accepted solely for
8
+ * explicit loopback development servers, and base URLs cannot smuggle a path,
9
+ * query, credentials, or fragment into request construction.
10
+ */
11
+ export function normalizeApiOrigin(value) {
12
+ let url;
13
+ try {
14
+ url = new URL(value);
15
+ }
16
+ catch {
17
+ throw new Error(`Invalid Relay API origin: ${value}`);
18
+ }
19
+ if (url.username || url.password || url.search || url.hash || (url.pathname && url.pathname !== "/")) {
20
+ throw new Error("Relay API origin must contain only scheme and host (no credentials, path, query, or fragment)");
21
+ }
22
+ if (url.protocol !== "https:" && !(url.protocol === "http:" && isLoopbackHost(url.hostname))) {
23
+ throw new Error("Relay API origin must use HTTPS (plain HTTP is allowed only on loopback)");
24
+ }
25
+ return url.origin;
26
+ }
27
+ /**
28
+ * Development/testing override for the Relay API origin. Production stays the
29
+ * default; when RELAY_API_ORIGIN is set it passes normalizeApiOrigin, so the
30
+ * loopback carve-out there remains the only place plain HTTP is accepted.
31
+ */
32
+ export function resolveApiOrigin(fallback = PRODUCTION_ORIGIN) {
33
+ const override = process.env.RELAY_API_ORIGIN?.trim();
34
+ if (!override)
35
+ return fallback;
36
+ return normalizeApiOrigin(override);
37
+ }
38
+ export class RelayApiError extends Error {
39
+ status;
40
+ code;
41
+ constructor(status, code, message) {
42
+ super(message);
43
+ this.status = status;
44
+ this.code = code;
45
+ this.name = "RelayApiError";
46
+ }
47
+ }
48
+ export class RelayClient {
49
+ token;
50
+ fetchImpl;
51
+ origin;
52
+ constructor(origin, token, fetchImpl = fetch) {
53
+ this.token = token;
54
+ this.fetchImpl = fetchImpl;
55
+ this.origin = normalizeApiOrigin(origin);
56
+ }
57
+ async request(method, path, opts = {}) {
58
+ const headers = { ...opts.headers };
59
+ const bearer = opts.bearer ?? this.token;
60
+ if (bearer)
61
+ headers.authorization = `Bearer ${bearer}`;
62
+ let body;
63
+ if (opts.body !== undefined) {
64
+ headers["content-type"] = "application/json";
65
+ body = JSON.stringify(opts.body);
66
+ }
67
+ const res = await this.fetchImpl(`${this.origin}${path}`, {
68
+ method,
69
+ headers,
70
+ body,
71
+ signal: AbortSignal.timeout(opts.timeoutMs ?? 30_000),
72
+ });
73
+ const text = await res.text();
74
+ let json;
75
+ try {
76
+ json = text.length > 0 ? JSON.parse(text) : undefined;
77
+ }
78
+ catch {
79
+ json = undefined;
80
+ }
81
+ const okStatuses = opts.expectStatus ?? [200, 201, 202, 204];
82
+ if (!okStatuses.includes(res.status)) {
83
+ const code = json?.error?.code ?? json?.code;
84
+ const message = json?.error?.message ?? json?.message ?? text.slice(0, 300) ?? res.statusText;
85
+ throw new RelayApiError(res.status, code, `${method} ${path} → ${res.status}: ${message}`);
86
+ }
87
+ return json;
88
+ }
89
+ // — Pairing (unauthenticated create; poll_token bearer for polling) —
90
+ createPairing(deviceName, engine) {
91
+ return this.request("POST", "/v1/pairings", {
92
+ body: { device_name: deviceName, ...(engine ? { engine } : {}) },
93
+ });
94
+ }
95
+ waitPairing(pairingId, pollToken) {
96
+ return this.request("GET", `/v1/pairings/${pairingId}?wait=true`, {
97
+ bearer: pollToken,
98
+ timeoutMs: 45_000,
99
+ });
100
+ }
101
+ // — Agent-authenticated surface —
102
+ getMe() {
103
+ return this.request("GET", "/v1/agents/me");
104
+ }
105
+ getEvents(cursor, timeoutS = 25, limit = 100) {
106
+ const qs = `cursor=${cursor}&timeout=${timeoutS}&limit=${limit}`;
107
+ return this.request("GET", `/v1/events?${qs}`, { timeoutMs: (timeoutS + 15) * 1000 });
108
+ }
109
+ postMessage(body, idempotencyKey) {
110
+ return this.request("POST", "/v1/messages", {
111
+ body,
112
+ headers: { "idempotency-key": idempotencyKey },
113
+ });
114
+ }
115
+ listMessages(conversationId, limit = 20) {
116
+ return this.request("GET", `/v1/conversations/${conversationId}/messages?limit=${limit}`);
117
+ }
118
+ setTyping(conversationId, started, label) {
119
+ return this.request("POST", `/v1/conversations/${conversationId}/typing`, {
120
+ body: { started, ...(label ? { label } : {}) },
121
+ });
122
+ }
123
+ markRead(conversationId, messageId) {
124
+ return this.request("POST", `/v1/conversations/${conversationId}/read`, {
125
+ body: { message_id: messageId },
126
+ });
127
+ }
128
+ }
129
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface ResolvedDefaultMode {
2
+ mode: string;
3
+ /** Settings file the winning value came from. */
4
+ source: string;
5
+ }
6
+ /**
7
+ * Resolve permissions.defaultMode the way Claude Code does, highest
8
+ * precedence first: project .claude/settings.local.json, then project
9
+ * .claude/settings.json, then user ~/.claude/settings.json.
10
+ */
11
+ export declare function resolveClaudeDefaultMode(projectDir?: string, home?: string): ResolvedDefaultMode | undefined;
12
+ /** One-line warning when phone approvals cannot fire, else undefined. */
13
+ export declare function claudeBypassWarning(projectDir?: string, home?: string): string | undefined;
14
+ //# sourceMappingURL=claude-settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-settings.d.ts","sourceRoot":"","sources":["../src/claude-settings.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;CAChB;AAYD;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,GAAE,MAAsB,EAClC,IAAI,GAAE,MAAkB,GACvB,mBAAmB,GAAG,SAAS,CAWjC;AAED,yEAAyE;AACzE,wBAAgB,mBAAmB,CACjC,UAAU,CAAC,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE,MAAM,GACZ,MAAM,GAAG,SAAS,CAOpB"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Best-effort read of the Claude Code permission mode that
3
+ * @agentclientprotocol/claude-agent-acp inherits. When the resolved
4
+ * permissions.defaultMode is bypassPermissions, the engine never sends
5
+ * session/request_permission, so Relay's phone Allow/Deny cards silently
6
+ * disappear. Missing or unreadable settings files are ignored (silent).
7
+ */
8
+ import { readFileSync } from "node:fs";
9
+ import { homedir } from "node:os";
10
+ import { join } from "node:path";
11
+ function readDefaultMode(path) {
12
+ try {
13
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
14
+ const mode = parsed?.permissions?.defaultMode;
15
+ return typeof mode === "string" ? mode : undefined;
16
+ }
17
+ catch {
18
+ return undefined;
19
+ }
20
+ }
21
+ /**
22
+ * Resolve permissions.defaultMode the way Claude Code does, highest
23
+ * precedence first: project .claude/settings.local.json, then project
24
+ * .claude/settings.json, then user ~/.claude/settings.json.
25
+ */
26
+ export function resolveClaudeDefaultMode(projectDir = process.cwd(), home = homedir()) {
27
+ const candidates = [
28
+ join(projectDir, ".claude", "settings.local.json"),
29
+ join(projectDir, ".claude", "settings.json"),
30
+ join(home, ".claude", "settings.json"),
31
+ ];
32
+ for (const path of candidates) {
33
+ const mode = readDefaultMode(path);
34
+ if (mode !== undefined)
35
+ return { mode, source: path };
36
+ }
37
+ return undefined;
38
+ }
39
+ /** One-line warning when phone approvals cannot fire, else undefined. */
40
+ export function claudeBypassWarning(projectDir, home) {
41
+ const resolved = resolveClaudeDefaultMode(projectDir, home);
42
+ if (resolved?.mode !== "bypassPermissions")
43
+ return undefined;
44
+ return (`Claude permissions.defaultMode=bypassPermissions (${resolved.source}) — ` +
45
+ "the engine never asks for approval, so Relay's phone Allow/Deny cards will not appear");
46
+ }
47
+ //# sourceMappingURL=claude-settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-settings.js","sourceRoot":"","sources":["../src/claude-settings.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAQjC,SAAS,eAAe,CAAC,IAAY;IACnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QACtD,MAAM,IAAI,GAAG,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC;QAC9C,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CACtC,aAAqB,OAAO,CAAC,GAAG,EAAE,EAClC,OAAe,OAAO,EAAE;IAExB,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,qBAAqB,CAAC;QAClD,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,eAAe,CAAC;QAC5C,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,eAAe,CAAC;KACvC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACxD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,mBAAmB,CACjC,UAAmB,EACnB,IAAa;IAEb,MAAM,QAAQ,GAAG,wBAAwB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC5D,IAAI,QAAQ,EAAE,IAAI,KAAK,mBAAmB;QAAE,OAAO,SAAS,CAAC;IAC7D,OAAO,CACL,qDAAqD,QAAQ,CAAC,MAAM,MAAM;QAC1E,uFAAuF,CACxF,CAAC;AACJ,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,162 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * relaymessenger — bridge your local coding agent to Relay.
4
+ *
5
+ * relaymessenger pair [--engine <preset>] [--name <device-name>]
6
+ * relaymessenger start [--engine <preset>] [--dir <path>]
7
+ * relaymessenger install-codex
8
+ * relaymessenger install-claude
9
+ * relaymessenger install-openclaw
10
+ * relaymessenger doctor
11
+ *
12
+ * Internal entrypoints (wired by install-codex): notify, mcp,
13
+ * hook permission-request.
14
+ */
15
+ import { resolveApiOrigin, RelayClient } from "./api.js";
16
+ import { claudeBypassWarning } from "./claude-settings.js";
17
+ import { notifyCommand, permissionRequestHook } from "./codex.js";
18
+ import { doctor } from "./doctor.js";
19
+ import { AcpEngine } from "./engine/acp.js";
20
+ import { ENGINE_HELP, enginePermissionTimeoutMs } from "./engine/catalog.js";
21
+ import { installClaude, installCodex, installOpenClaw } from "./install.js";
22
+ import { parseFlags } from "./flags.js";
23
+ import { mcpServe } from "./mcp.js";
24
+ import { pair } from "./pair.js";
25
+ import { PermissionBroker } from "./permissions.js";
26
+ import { ReceiveLoop } from "./receive.js";
27
+ import { ApprovalStore, ConfigStore, resolveOwnerUserId, RuntimeLock, runtimeHomeForConfig, SessionStore, StateStore, } from "./store.js";
28
+ const USAGE = `relaymessenger — bridge your local coding agent to Relay (https://relayapp.im)
29
+
30
+ relaymessenger pair pair this machine with the Relay app (QR + code)
31
+ relaymessenger start receive messages and drive the engine
32
+ --engine <preset> (default claude)
33
+ presets: ${ENGINE_HELP}
34
+ --dir <path> working directory for engine sessions
35
+ relaymessenger install-codex wire Codex notify + phone approvals + MCP server
36
+ relaymessenger install-claude point at the Claude Code channel plugin
37
+ relaymessenger install-openclaw install and configure the bundled OpenClaw plugin
38
+ relaymessenger doctor health checks
39
+
40
+ Docs: https://docs.relayapp.im/quickstart`;
41
+ async function main() {
42
+ const [command, ...restArgv] = process.argv.slice(2);
43
+ const flags = parseFlags(restArgv);
44
+ const log = (line) => console.error(`[relaymessenger] ${line}`);
45
+ switch (command) {
46
+ case "pair": {
47
+ // RELAY_API_ORIGIN is a development/testing override; production default.
48
+ const origin = resolveApiOrigin();
49
+ await pair({ origin, engine: flags.engine, deviceName: flags.name });
50
+ return 0;
51
+ }
52
+ case "start": {
53
+ const config = new ConfigStore().load();
54
+ if (!config?.agent_token) {
55
+ console.error("Not paired. Run `relaymessenger pair` first.");
56
+ return 1;
57
+ }
58
+ const ownerUserId = resolveOwnerUserId(config); // fail closed without a pinned owner
59
+ // RELAY_API_ORIGIN (development/testing) overrides the paired origin.
60
+ const origin = resolveApiOrigin(config.api_origin);
61
+ const client = new RelayClient(origin, config.agent_token);
62
+ // Scope durable state to the effective origin so an override never
63
+ // replays or advances the paired production cursor/ledgers.
64
+ const runtimeHome = runtimeHomeForConfig({ ...config, api_origin: origin });
65
+ if (flags.engine === "claude") {
66
+ const bypass = claudeBypassWarning(flags.dir ?? process.cwd());
67
+ if (bypass)
68
+ log(`warning: ${bypass}`);
69
+ }
70
+ const runtimeLock = new RuntimeLock(runtimeHome);
71
+ // Acquire before any state/session/approval object can read or rewrite
72
+ // whole-file ledgers for this paired identity.
73
+ runtimeLock.acquire();
74
+ try {
75
+ const state = new StateStore(runtimeHome);
76
+ const sessions = new SessionStore(runtimeHome);
77
+ const approvals = new ApprovalStore(runtimeHome);
78
+ const engine = new AcpEngine(flags.engine, sessions, log);
79
+ const broker = new PermissionBroker(client, approvals, enginePermissionTimeoutMs(flags.engine), log);
80
+ const loop = new ReceiveLoop(client, state, engine, broker, {
81
+ ownerUserId,
82
+ cwd: flags.dir ?? process.cwd(),
83
+ log,
84
+ });
85
+ let shuttingDown;
86
+ const shutdown = () => {
87
+ if (shuttingDown)
88
+ return shuttingDown;
89
+ shuttingDown = (async () => {
90
+ log("shutting down…");
91
+ loop.stop();
92
+ // Dispose first: this rejects/aborts any live engine turn so settle()
93
+ // cannot wait forever on a child process we intend to terminate.
94
+ await engine.dispose();
95
+ await loop.settle();
96
+ runtimeLock.release();
97
+ process.exit(0);
98
+ })();
99
+ return shuttingDown;
100
+ };
101
+ process.on("SIGINT", shutdown);
102
+ process.on("SIGTERM", shutdown);
103
+ log(`bridge running: engine=${flags.engine} dir=${flags.dir ?? process.cwd()} api=${origin}`);
104
+ try {
105
+ await loop.run();
106
+ }
107
+ finally {
108
+ // Fatal loop exits (409/401 throws) must not leave a detached engine
109
+ // process group running without its bridge.
110
+ loop.stop();
111
+ await engine.dispose().catch(() => { });
112
+ }
113
+ return 0;
114
+ }
115
+ finally {
116
+ runtimeLock.release();
117
+ }
118
+ }
119
+ case "install-codex":
120
+ installCodex();
121
+ return 0;
122
+ case "install-claude":
123
+ installClaude();
124
+ return 0;
125
+ case "install-openclaw":
126
+ installOpenClaw();
127
+ return 0;
128
+ case "doctor":
129
+ return (await doctor()) ? 0 : 1;
130
+ case "notify":
131
+ await notifyCommand(restArgv);
132
+ return 0;
133
+ case "mcp":
134
+ await mcpServe();
135
+ return 0;
136
+ case "hook": {
137
+ if (flags.rest[0] !== "permission-request") {
138
+ console.error(`unknown hook: ${flags.rest[0] ?? "(none)"}`);
139
+ return 1;
140
+ }
141
+ return await permissionRequestHook();
142
+ }
143
+ case undefined:
144
+ case "help":
145
+ case "--help":
146
+ case "-h":
147
+ console.log(USAGE);
148
+ return 0;
149
+ default:
150
+ console.error(`unknown command: ${command}\n`);
151
+ console.log(USAGE);
152
+ return 1;
153
+ }
154
+ }
155
+ main().then((code) => {
156
+ if (code !== 0)
157
+ process.exitCode = code;
158
+ }, (error) => {
159
+ console.error(`relaymessenger: ${error?.message ?? error}`);
160
+ process.exitCode = 1;
161
+ });
162
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EACL,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EACpB,YAAY,EACZ,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,MAAM,KAAK,GAAG;;;;;iBAKG,WAAW;;;;;;;0CAOc,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,MAAM,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC;IAExE,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,0EAA0E;YAC1E,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;YAClC,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YACrE,OAAO,CAAC,CAAC;QACX,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;YACxC,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;gBACzB,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;gBAC9D,OAAO,CAAC,CAAC;YACX,CAAC;YACD,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,qCAAqC;YACrF,sEAAsE;YACtE,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;YAC3D,mEAAmE;YACnE,4DAA4D;YAC5D,MAAM,WAAW,GAAG,oBAAoB,CAAC,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;YAC5E,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAC9B,MAAM,MAAM,GAAG,mBAAmB,CAAC,KAAK,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;gBAC/D,IAAI,MAAM;oBAAE,GAAG,CAAC,YAAY,MAAM,EAAE,CAAC,CAAC;YACxC,CAAC;YACD,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,WAAW,CAAC,CAAC;YACjD,uEAAuE;YACvE,+CAA+C;YAC/C,WAAW,CAAC,OAAO,EAAE,CAAC;YACtB,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;gBAC1C,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,WAAW,CAAC,CAAC;gBAC/C,MAAM,SAAS,GAAG,IAAI,aAAa,CAAC,WAAW,CAAC,CAAC;gBACjD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAC1D,MAAM,MAAM,GAAG,IAAI,gBAAgB,CACjC,MAAM,EACN,SAAS,EACT,yBAAyB,CAAC,KAAK,CAAC,MAAM,CAAC,EACvC,GAAG,CACJ,CAAC;gBACF,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE;oBAC1D,WAAW;oBACX,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE;oBAC/B,GAAG;iBACJ,CAAC,CAAC;gBACH,IAAI,YAAuC,CAAC;gBAC5C,MAAM,QAAQ,GAAG,GAAG,EAAE;oBACpB,IAAI,YAAY;wBAAE,OAAO,YAAY,CAAC;oBACtC,YAAY,GAAG,CAAC,KAAK,IAAI,EAAE;wBACzB,GAAG,CAAC,gBAAgB,CAAC,CAAC;wBACtB,IAAI,CAAC,IAAI,EAAE,CAAC;wBACZ,sEAAsE;wBACtE,iEAAiE;wBACjE,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;wBACvB,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;wBACpB,WAAW,CAAC,OAAO,EAAE,CAAC;wBACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAClB,CAAC,CAAC,EAAE,CAAC;oBACL,OAAO,YAAY,CAAC;gBACtB,CAAC,CAAC;gBACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;gBAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;gBAChC,GAAG,CAAC,0BAA0B,KAAK,CAAC,MAAM,QAAQ,KAAK,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,QAAQ,MAAM,EAAE,CAAC,CAAC;gBAC9F,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;gBACnB,CAAC;wBAAS,CAAC;oBACT,qEAAqE;oBACrE,4CAA4C;oBAC5C,IAAI,CAAC,IAAI,EAAE,CAAC;oBACZ,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBACzC,CAAC;gBACD,OAAO,CAAC,CAAC;YACX,CAAC;oBAAS,CAAC;gBACT,WAAW,CAAC,OAAO,EAAE,CAAC;YACxB,CAAC;QACH,CAAC;QACD,KAAK,eAAe;YAClB,YAAY,EAAE,CAAC;YACf,OAAO,CAAC,CAAC;QACX,KAAK,gBAAgB;YACnB,aAAa,EAAE,CAAC;YAChB,OAAO,CAAC,CAAC;QACX,KAAK,kBAAkB;YACrB,eAAe,EAAE,CAAC;YAClB,OAAO,CAAC,CAAC;QACX,KAAK,QAAQ;YACX,OAAO,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,KAAK,QAAQ;YACX,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC9B,OAAO,CAAC,CAAC;QACX,KAAK,KAAK;YACR,MAAM,QAAQ,EAAE,CAAC;YACjB,OAAO,CAAC,CAAC;QACX,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,oBAAoB,EAAE,CAAC;gBAC3C,OAAO,CAAC,KAAK,CAAC,iBAAiB,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC;gBAC5D,OAAO,CAAC,CAAC;YACX,CAAC;YACD,OAAO,MAAM,qBAAqB,EAAE,CAAC;QACvC,CAAC;QACD,KAAK,SAAS,CAAC;QACf,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ,CAAC;QACd,KAAK,IAAI;YACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACnB,OAAO,CAAC,CAAC;QACX;YACE,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,IAAI,CAAC,CAAC;YAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACnB,OAAO,CAAC,CAAC;IACb,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,IAAI,CACT,CAAC,IAAI,EAAE,EAAE;IACP,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;AAC1C,CAAC,EACD,CAAC,KAAK,EAAE,EAAE;IACR,OAAO,CAAC,KAAK,CAAC,mBAAmB,KAAK,EAAE,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC;IAC5D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CACF,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { RelayClient } from "./api.js";
2
+ import { CodexNotifyPolicyStore, ConfigStore } from "./store.js";
3
+ export declare function requireClient(config?: ConfigStore): {
4
+ client: RelayClient;
5
+ ownerUserId?: string;
6
+ conversationId?: string;
7
+ projectRoot: string;
8
+ runtimeHome: string;
9
+ apiOrigin: string;
10
+ accountIdentity: string;
11
+ };
12
+ export interface NotifyCommandDependencies {
13
+ config?: ConfigStore;
14
+ policy?: CodexNotifyPolicyStore;
15
+ client?: RelayClient;
16
+ }
17
+ export declare function notifyCommand(argv: string[], out?: (line: string) => void, dependencies?: NotifyCommandDependencies): Promise<void>;
18
+ export declare function permissionRequestHook(write?: (json: unknown) => void): Promise<number>;
19
+ /**
20
+ * Exact PermissionRequest hook envelope from the Codex hooks reference:
21
+ * hookSpecificOutput.hookEventName is required — without it Codex treats the
22
+ * output as invalid and the phone decision is dropped.
23
+ */
24
+ export declare function decisionJson(allow: boolean): unknown;
25
+ //# sourceMappingURL=codex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../src/codex.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,OAAO,EAEL,sBAAsB,EACtB,WAAW,EAMZ,MAAM,YAAY,CAAC;AAEpB,wBAAgB,aAAa,CAAC,MAAM,cAAoB,GAAG;IACzD,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;CACzB,CA4BA;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,sBAAsB,CAAC;IAChC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAkB,EACzC,YAAY,GAAE,yBAA8B,GAC3C,OAAO,CAAC,IAAI,CAAC,CA0Cf;AAUD,wBAAsB,qBAAqB,CACzC,KAAK,GAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAkE,GAC3F,OAAO,CAAC,MAAM,CAAC,CA+GjB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CASpD"}