@relaymessenger/cli 0.4.4 → 0.5.0-staging.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 (91) hide show
  1. package/README.md +108 -118
  2. package/dist/cli.js +2 -172
  3. package/dist/cli.js.map +1 -1
  4. package/dist/client.d.ts +8 -0
  5. package/dist/client.d.ts.map +1 -0
  6. package/dist/client.js +13 -0
  7. package/dist/client.js.map +1 -0
  8. package/dist/config.d.ts +39 -0
  9. package/dist/config.d.ts.map +1 -0
  10. package/dist/config.js +206 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/doctor.d.ts +20 -1
  13. package/dist/doctor.d.ts.map +1 -1
  14. package/dist/doctor.js +73 -112
  15. package/dist/doctor.js.map +1 -1
  16. package/dist/event-listen.d.ts +11 -0
  17. package/dist/event-listen.d.ts.map +1 -0
  18. package/dist/event-listen.js +37 -0
  19. package/dist/event-listen.js.map +1 -0
  20. package/dist/output.d.ts +4 -0
  21. package/dist/output.d.ts.map +1 -0
  22. package/dist/output.js +26 -0
  23. package/dist/output.js.map +1 -0
  24. package/dist/program.d.ts +14 -0
  25. package/dist/program.d.ts.map +1 -0
  26. package/dist/program.js +655 -0
  27. package/dist/program.js.map +1 -0
  28. package/package.json +31 -37
  29. package/claude-plugin/marketplace/.claude-plugin/marketplace.json +0 -14
  30. package/claude-plugin/marketplace/plugins/relay/.claude-plugin/plugin.json +0 -27
  31. package/claude-plugin/marketplace/plugins/relay/LICENSE +0 -21
  32. package/claude-plugin/marketplace/plugins/relay/README.md +0 -173
  33. package/claude-plugin/marketplace/plugins/relay/commands/configure.md +0 -71
  34. package/claude-plugin/marketplace/plugins/relay/runtime/server.mjs +0 -26197
  35. package/dist/api.d.ts +0 -114
  36. package/dist/api.d.ts.map +0 -1
  37. package/dist/api.js +0 -162
  38. package/dist/api.js.map +0 -1
  39. package/dist/claude-settings.d.ts +0 -14
  40. package/dist/claude-settings.d.ts.map +0 -1
  41. package/dist/claude-settings.js +0 -47
  42. package/dist/claude-settings.js.map +0 -1
  43. package/dist/codex.d.ts +0 -25
  44. package/dist/codex.d.ts.map +0 -1
  45. package/dist/codex.js +0 -237
  46. package/dist/codex.js.map +0 -1
  47. package/dist/engine/acp.d.ts +0 -74
  48. package/dist/engine/acp.d.ts.map +0 -1
  49. package/dist/engine/acp.js +0 -413
  50. package/dist/engine/acp.js.map +0 -1
  51. package/dist/engine/catalog.d.ts +0 -26
  52. package/dist/engine/catalog.d.ts.map +0 -1
  53. package/dist/engine/catalog.js +0 -41
  54. package/dist/engine/catalog.js.map +0 -1
  55. package/dist/engine/process.d.ts +0 -12
  56. package/dist/engine/process.d.ts.map +0 -1
  57. package/dist/engine/process.js +0 -54
  58. package/dist/engine/process.js.map +0 -1
  59. package/dist/engine/types.d.ts +0 -57
  60. package/dist/engine/types.d.ts.map +0 -1
  61. package/dist/engine/types.js +0 -8
  62. package/dist/engine/types.js.map +0 -1
  63. package/dist/flags.d.ts +0 -9
  64. package/dist/flags.d.ts.map +0 -1
  65. package/dist/flags.js +0 -34
  66. package/dist/flags.js.map +0 -1
  67. package/dist/install.d.ts +0 -69
  68. package/dist/install.d.ts.map +0 -1
  69. package/dist/install.js +0 -513
  70. package/dist/install.js.map +0 -1
  71. package/dist/mcp.d.ts +0 -16
  72. package/dist/mcp.d.ts.map +0 -1
  73. package/dist/mcp.js +0 -127
  74. package/dist/mcp.js.map +0 -1
  75. package/dist/pair.d.ts +0 -20
  76. package/dist/pair.d.ts.map +0 -1
  77. package/dist/pair.js +0 -135
  78. package/dist/pair.js.map +0 -1
  79. package/dist/permissions.d.ts +0 -90
  80. package/dist/permissions.d.ts.map +0 -1
  81. package/dist/permissions.js +0 -361
  82. package/dist/permissions.js.map +0 -1
  83. package/dist/receive.d.ts +0 -113
  84. package/dist/receive.d.ts.map +0 -1
  85. package/dist/receive.js +0 -596
  86. package/dist/receive.js.map +0 -1
  87. package/dist/store.d.ts +0 -301
  88. package/dist/store.d.ts.map +0 -1
  89. package/dist/store.js +0 -551
  90. package/dist/store.js.map +0 -1
  91. package/openclaw-plugin/relaymessenger-openclaw-plugin-0.3.3.tgz +0 -0
package/README.md CHANGED
@@ -1,139 +1,129 @@
1
- # relaymessenger
1
+ # Relay CLI
2
2
 
3
- Message your local coding agent from your phone. `relaymessenger` bridges a Relay
4
- agent conversation to Claude Code, Codex, or Hermes Agent running on this
5
- machine. It also installs native Relay channels for Claude Code and OpenClaw.
6
- Texts become prompts, replies come back as messages, and tool approvals arrive
7
- as Allow/Deny cards you answer with a tap.
3
+ `@relaymessenger/cli` is the official terminal client for the current Relay
4
+ v1 Agent API. It delegates all Relay calls and response types to
5
+ `@relaymessenger/sdk`.
8
6
 
9
- Relay is the messenger for AI agents: https://relayapp.im. API reference:
10
- https://docs.relayapp.im.
7
+ ## Install
11
8
 
12
- ## Quickstart
9
+ ```sh
10
+ npm install --global @relaymessenger/cli
11
+ relay --version
12
+ ```
13
+
14
+ Node.js 22.22.3 or newer is required. `relaymessenger` remains an executable
15
+ alias for existing installs.
16
+
17
+ ## Authenticate
18
+
19
+ Create Agent Tokens in Relay Console. Tokens are accepted only from stdin,
20
+ the `RELAY_AGENT_TOKEN` environment variable, or an owner-only local profile;
21
+ there is deliberately no token command-line option.
13
22
 
14
23
  ```sh
15
- npm install -g @relaymessenger/cli
24
+ printf '%s' "$RELAY_AGENT_TOKEN" | relay auth login --token-stdin
25
+ relay auth status
26
+ relay doctor
27
+ ```
16
28
 
17
- # 1. Pair this machine with the Relay app (QR + short code, ~30 s)
18
- relaymessenger pair
29
+ Profiles live in `${XDG_CONFIG_HOME:-~/.config}/relay/config.json`. The
30
+ directory is mode `0700` and the file is mode `0600` on POSIX systems.
19
31
 
20
- # 2. Start the bridge in the repo you want the agent to work in
21
- cd ~/code/my-project
22
- relaymessenger start --engine claude # or: --engine codex | --engine hermes
32
+ ```sh
33
+ relay profiles add staging --api-url https://api.staging.relayapp.im
34
+ relay profiles use staging
35
+ printf '%s' "$STAGING_RELAY_AGENT_TOKEN" |
36
+ relay auth login --profile staging --token-stdin
37
+ relay profiles list
23
38
  ```
24
39
 
25
- Now text the agent from the Relay app. Each message (or quick burst of
26
- messages) becomes one engine turn; the bridge shows a typing indicator while
27
- the engine works and posts one finalized reply per turn.
40
+ Resolution order is:
28
41
 
29
- ## Commands
42
+ 1. `RELAY_AGENT_TOKEN`, `RELAY_API_URL`, and `RELAY_PROFILE`;
43
+ 2. the selected local profile;
44
+ 3. `https://api.relayapp.im` as the API URL.
30
45
 
31
- | Command | What it does |
32
- | --- | --- |
33
- | `relaymessenger pair` | `POST /v1/pairings`, shows a terminal QR + code, long-polls until you claim it in the app, stores the Agent Token in `~/.relaymessenger/config.json` (chmod 600) and pins your user id as the bridge owner (from `GET /v1/agents/me`; override with `RELAY_OWNER_USER_ID`). If owner lookup is interrupted after the token is saved, running the command again resumes that saved token without creating another agent. The token never appears on the phone. |
34
- | `relaymessenger start` | Receive loop: long-polls `GET /v1/events`, drives the engine over ACP, replies via `POST /v1/messages` with an `Idempotency-Key`. Flags: `--engine claude\|codex\|hermes`, `--dir <path>`. Claude and Codex adapters are bundled; Hermes must already be installed and pass `hermes acp --check`. |
35
- | `relaymessenger install-codex` | Run from a project root to opt in that project only. Merges, never clobbers, `[mcp_servers.relay]` + `notify` into `~/.codex/config.toml` (comments preserved; a `.bak` of the original is kept) and a `PermissionRequest` hook into `~/.codex/hooks.json`. Other projects are suppressed until installed separately. Codex gates untrusted hook handlers: the first run may ask you to trust the relaymessenger handler. |
36
- | `relaymessenger install-claude` | After pairing, strictly validates the Claude plugin bundled in the installed npm package, persists its local marketplace under the paired account's private runtime directory, installs `relay@relaymessenger-bundled`, and writes the token/API origin/owner pin to `~/.claude/channels/relay/.env` with mode 600 without printing the token. It refuses to overwrite a different configured identity. |
37
- | `relaymessenger install-openclaw` | After pairing, persists the OpenClaw plugin archive bundled in the npm package and installs it through OpenClaw's managed `npm-pack:` path, adds only Relay's plugin/channel fields to `~/.openclaw/openclaw.json`, and writes the paired token to an owner-only file. Existing unrelated config is preserved and a different configured identity is refused. |
38
- | `relaymessenger doctor` | Checks Node, pairing, token file permissions, API reachability, installed adapter pins, and durable-state health. |
46
+ Plain HTTP API URLs are rejected except for loopback development origins.
39
47
 
40
- ## How the wire works
48
+ ## Resource commands
41
49
 
42
- Everything rides Relay's public agent API, the same surface you can drive
43
- with curl:
50
+ Every command prints JSON.
44
51
 
45
52
  ```sh
46
- # what the bridge polls (agent bearer auth; long-poll, cursor acks ≤ N)
47
- curl -H "Authorization: Bearer $AGENT_TOKEN" \
48
- "https://api.relayapp.im/v1/events?cursor=0&timeout=25"
49
-
50
- # what the bridge sends per finished turn
51
- curl -X POST https://api.relayapp.im/v1/messages \
52
- -H "Authorization: Bearer $AGENT_TOKEN" \
53
- -H "Idempotency-Key: relay-turn-<sha256(conversation,event-id-batch)>" \
54
- -H "Content-Type: application/json" \
55
- -d '{"conversation_id":"cnv_…","parts":[{"type":"text","text":"done"}]}'
53
+ relay chats list --limit 20
54
+ relay chats get "$CHAT_ID"
55
+ relay chats messages list "$CHAT_ID" --limit 50
56
+ relay chats messages send "$CHAT_ID" --text "Hello" \
57
+ --idempotency-key "$(uuidgen)"
58
+ relay messages send --to advait --text "Hello" \
59
+ --idempotency-key "$(uuidgen)"
60
+ relay messages react "$MESSAGE_ID" --operation add --type love
61
+ relay chats typing start "$CHAT_ID"
62
+ relay chats read "$CHAT_ID"
63
+
64
+ relay contact-card get
65
+ relay contact-card setup --handle weather.acme --first-name Weather
66
+ relay contact-card share "$CHAT_ID"
67
+ relay contact-requests create advait
68
+
69
+ relay attachments upload ./report.pdf --content-type application/pdf
70
+ relay blocked-handles list
71
+ relay webhooks events
72
+ relay webhooks subscriptions list
56
73
  ```
57
74
 
58
- - **Engines**: Claude and Codex are spawned as ACP adapters over
59
- stdio (`@agentclientprotocol/claude-agent-acp`,
60
- `@agentclientprotocol/codex-acp`). Both adapters are exact runtime
61
- dependencies resolved from the installed package; the bridge never runs
62
- mutable registry `latest` code. Adapter subprocesses receive platform and
63
- engine/provider variables, not the complete parent environment. Hermes is
64
- launched shell-free through its installed `hermes acp` stdio server and is
65
- checked with `hermes acp --check`. Conversation → session bindings persist
66
- in the paired account's runtime directory, so a conversation keeps its
67
- engine context. OpenClaw is deliberately separate: `install-openclaw`
68
- installs a native channel plugin into OpenClaw rather than pretending it is
69
- an ACP coding-engine preset.
70
- - **Approvals**: an engine `session/request_permission` becomes a Relay
71
- message with a text part plus an `agent_permission_request` data part
72
- (origin-tagged Allow/Deny options). Tap an option or text
73
- `yes <id>` / `no <id>`. The full security-relevant tool input and affected
74
- paths must fit in the card; an operation that cannot be represented in full
75
- is denied instead of shown partially. No answer within 10 minutes → deny.
76
- - **Owner gate**: only the user pinned at pair time can prompt the engine or
77
- answer an approval card; messages from anyone else are ignored before their
78
- content is interpreted.
79
- - **Reliability**: the receive cursor advances only in the same atomic
80
- (fsync + rename) write that persists the event queue
81
- (`~/.relaymessenger/accounts/<origin-agent-hash>/state.json`), event ids are deduped, rapid messages debounce
82
- ~800 ms into one turn, and the poll loop restarts with capped exponential
83
- backoff + jitter. Each pending approval is its own create-once file under
84
- that account's `approvals/`, so a bridge restart cannot lose one and no two
85
- processes ever rewrite a shared snapshot. Engine/tool turns are at-most-once:
86
- an attempt marker is durable before execution, so a crash never silently
87
- repeats a deploy, deletion, command, or external send. Completed replies use
88
- a durable outbox and stable idempotency key, so delivery can retry without
89
- rerunning those tools. An interrupted turn is reported and must be retried
90
- explicitly by the owner.
91
- - Long-poll is exclusive: an enabled webhook endpoint or a second poller gets
92
- `409` (Telegram semantics). One consumer per token. A `401` stops the loop
93
- with re-pair guidance instead of retrying.
94
- - **Codex notification privacy**: `install-codex` stores an explicit local
95
- allowlist entry for the current project root in
96
- `~/.relaymessenger/codex-notify.json`. A completed turn from any other project is
97
- suppressed. For an allowed project, Relay receives the project directory's
98
- basename plus Codex's complete `last-assistant-message`; input messages and
99
- the absolute working-directory path are not sent. That text is retained in
100
- Relay message history. There is no global-all-projects opt-in; run
101
- `install-codex` in each
102
- project you choose to disclose.
103
- - **Codex MCP sends**: `relay_send_message` requires a caller-chosen stable
104
- `send_id`. Reuse the same `send_id`, conversation, and text only after an
105
- unknown outcome; a changed payload is rejected. The mapping and
106
- idempotency key live in the paired account's private runtime directory, so
107
- a process restart cannot turn one logical send into two messages.
108
-
109
- ## Development and testing
110
-
111
- - `RELAY_API_ORIGIN` points `pair`, `start`, and `doctor` at a
112
- non-production Relay API origin, e.g. a local dev server:
113
- `RELAY_API_ORIGIN=http://127.0.0.1:8787 relaymessenger pair`. This is a
114
- development/testing mechanism only, production
115
- (`https://api.relayapp.im`) stays the default, the value must be an
116
- origin with no path/query/credentials, and plain HTTP is accepted only
117
- for loopback hosts (same rule as every other origin the bridge uses).
118
- Durable bridge state is scoped per effective origin, so an override
119
- never replays or advances production cursors and ledgers.
120
- - With `--engine claude`, the bundled adapter inherits your Claude Code
121
- settings. If the resolved `permissions.defaultMode` is
122
- `bypassPermissions`, the engine never asks for approval, so phone
123
- Allow/Deny cards will not appear; `relaymessenger start` and `relaymessenger doctor`
124
- print a warning when they detect this.
125
-
126
- ## Files
75
+ Run `relay --help` and each command group's `--help` for the full current
76
+ surface: Chats, Messages, Attachments, blocked Handles, webhook events and
77
+ subscriptions, Contact Cards, and Contact requests.
78
+
79
+ ## Local event forwarding
127
80
 
81
+ `relay events listen` is a development convenience backed only by the SDK's
82
+ source-backed Agent WebSocket. It refuses Relay's production API, requires an
83
+ explicit profile, and requires confirmation that the profile belongs to a
84
+ dedicated non-production Agent whose durable checkpoint may advance:
85
+
86
+ ```sh
87
+ relay --profile staging events listen --acknowledge-events
88
+ relay --profile staging events listen --acknowledge-events \
89
+ --forward-to http://127.0.0.1:3000/relay-events
128
90
  ```
129
- ~/.relaymessenger/config.json agent token, API origin, pinned owner (chmod 600)
130
- ~/.relaymessenger/codex-notify.json locally allowed Codex project roots (not sent)
131
- ~/.relaymessenger/accounts/<hash>/state.json cursor, queued events/replies,
132
- owner conversation (start-only)
133
- ~/.relaymessenger/accounts/<hash>/approvals/ one file per pending approval
134
- ~/.relaymessenger/accounts/<hash>/sessions.json conversation session bindings
135
- ~/.relaymessenger/accounts/<hash>/mcp-sends/ durable Codex MCP logical sends
136
- ~/.relaymessenger/accounts/<hash>/installed-plugins/ stable bundled plugin sources
91
+
92
+ Forward destinations must be loopback HTTP(S). Forwarded bodies are the
93
+ original Relay event envelopes but are **unsigned** and carry
94
+ `x-relay-dev-forwarded: 1`; this is not a substitute for testing Standard
95
+ Webhooks signature verification. A non-2xx local response is not acknowledged,
96
+ so Relay can redeliver it. Local receivers must deduplicate by `event_id`.
97
+
98
+ The listener refuses a FULL-sync request rather than falsely claiming it
99
+ rebuilt durable state. It also cannot run while the Agent has webhook
100
+ subscriptions because Relay makes those delivery modes exclusive. Never point
101
+ it at an Agent whose checkpoint is owned by another consumer.
102
+
103
+ ## Doctor
104
+
105
+ `relay doctor` checks the Node runtime, API URL, token resolution, local file
106
+ permissions, SDK contract availability, and a read-only API request.
107
+ `relay doctor --offline` skips only the network request and is suitable for
108
+ package-install checks.
109
+
110
+ ## Security
111
+
112
+ - Keep Agent Tokens out of source, URLs, shell arguments, and logs.
113
+ - Prefer secret-manager injection through `RELAY_AGENT_TOKEN` in automation.
114
+ - Output and error paths redact every locally resolvable token.
115
+ - This package has no coding-agent runtime, pairing flow, or hidden private
116
+ API client.
117
+
118
+ ## Development
119
+
120
+ All Linux execution happens in a fresh Daytona sandbox:
121
+
122
+ ```sh
123
+ npm ci
124
+ npm run validate
137
125
  ```
138
126
 
139
- Requires Node >= 22.18.
127
+ `validate` performs type checking, unit and negative tests, the pinned SDK
128
+ operation-hash check, boundary checks, package packing, isolated tarball
129
+ installation, and installed-bin doctor smoke tests.
package/dist/cli.js CHANGED
@@ -1,174 +1,4 @@
1
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
- relaymessenger version print the installed version
40
-
41
- Docs: https://docs.relayapp.im/quickstart`;
42
- async function main() {
43
- const [command, ...restArgv] = process.argv.slice(2);
44
- const flags = parseFlags(restArgv);
45
- const log = (line) => console.error(`[relaymessenger] ${line}`);
46
- switch (command) {
47
- case "pair": {
48
- // RELAY_API_ORIGIN is a development/testing override; production default.
49
- const origin = resolveApiOrigin();
50
- await pair({ origin, engine: flags.engine, deviceName: flags.name });
51
- return 0;
52
- }
53
- case "start": {
54
- const config = new ConfigStore().load();
55
- if (!config?.agent_token) {
56
- console.error("Not paired. Run `relaymessenger pair` first.");
57
- return 1;
58
- }
59
- const ownerUserId = resolveOwnerUserId(config); // fail closed without a pinned owner
60
- // RELAY_API_ORIGIN (development/testing) overrides the paired origin.
61
- const origin = resolveApiOrigin(config.api_origin);
62
- const client = new RelayClient(origin, config.agent_token);
63
- // Scope durable state to the effective origin so an override never
64
- // replays or advances the paired production cursor/ledgers.
65
- const runtimeHome = runtimeHomeForConfig({ ...config, api_origin: origin });
66
- if (flags.engine === "claude") {
67
- const bypass = claudeBypassWarning(flags.dir ?? process.cwd());
68
- if (bypass)
69
- log(`warning: ${bypass}`);
70
- }
71
- const runtimeLock = new RuntimeLock(runtimeHome);
72
- // Acquire before any state/session/approval object can read or rewrite
73
- // whole-file ledgers for this paired identity.
74
- runtimeLock.acquire();
75
- try {
76
- const state = new StateStore(runtimeHome);
77
- const sessions = new SessionStore(runtimeHome);
78
- const approvals = new ApprovalStore(runtimeHome);
79
- const engine = new AcpEngine(flags.engine, sessions, log);
80
- const broker = new PermissionBroker(client, approvals, enginePermissionTimeoutMs(flags.engine), log);
81
- const loop = new ReceiveLoop(client, state, engine, broker, {
82
- ownerUserId,
83
- cwd: flags.dir ?? process.cwd(),
84
- log,
85
- });
86
- let shuttingDown;
87
- const shutdown = () => {
88
- if (shuttingDown)
89
- return shuttingDown;
90
- shuttingDown = (async () => {
91
- log("shutting down…");
92
- loop.stop();
93
- // Dispose first: this rejects/aborts any live engine turn so settle()
94
- // cannot wait forever on a child process we intend to terminate.
95
- await engine.dispose();
96
- await loop.settle();
97
- runtimeLock.release();
98
- process.exit(0);
99
- })();
100
- return shuttingDown;
101
- };
102
- process.on("SIGINT", shutdown);
103
- process.on("SIGTERM", shutdown);
104
- log(`bridge running: engine=${flags.engine} dir=${flags.dir ?? process.cwd()} api=${origin}`);
105
- try {
106
- await loop.run();
107
- }
108
- finally {
109
- // Fatal loop exits (409/401 throws) must not leave a detached engine
110
- // process group running without its bridge.
111
- loop.stop();
112
- await engine.dispose().catch(() => { });
113
- }
114
- return 0;
115
- }
116
- finally {
117
- runtimeLock.release();
118
- }
119
- }
120
- case "install-codex":
121
- installCodex();
122
- return 0;
123
- case "install-claude":
124
- installClaude();
125
- return 0;
126
- case "install-openclaw":
127
- installOpenClaw();
128
- return 0;
129
- case "doctor":
130
- return (await doctor()) ? 0 : 1;
131
- case "notify":
132
- await notifyCommand(restArgv);
133
- return 0;
134
- case "mcp":
135
- await mcpServe();
136
- return 0;
137
- case "hook": {
138
- if (flags.rest[0] !== "permission-request") {
139
- console.error(`unknown hook: ${flags.rest[0] ?? "(none)"}`);
140
- return 1;
141
- }
142
- return await permissionRequestHook();
143
- }
144
- case "version":
145
- case "--version":
146
- case "-v": {
147
- // A published CLI that cannot state its own version leaves a bug report
148
- // with nothing to anchor on. Read the manifest rather than a constant, so
149
- // it cannot drift from what npm actually installed.
150
- const { createRequire } = await import("node:module");
151
- const manifest = createRequire(import.meta.url)("../package.json");
152
- console.log(manifest.version);
153
- return 0;
154
- }
155
- case undefined:
156
- case "help":
157
- case "--help":
158
- case "-h":
159
- console.log(USAGE);
160
- return 0;
161
- default:
162
- console.error(`unknown command: ${command}\n`);
163
- console.log(USAGE);
164
- return 1;
165
- }
166
- }
167
- main().then((code) => {
168
- if (code !== 0)
169
- process.exitCode = code;
170
- }, (error) => {
171
- console.error(`relaymessenger: ${error?.message ?? error}`);
172
- process.exitCode = 1;
173
- });
2
+ import { runCLI } from "./program.js";
3
+ process.exitCode = await runCLI(process.argv.slice(2));
174
4
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +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;;;;;;;;0CAQc,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,EAAE,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,EAAE,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,EAAE,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,WAAW,CAAC;QACjB,KAAK,IAAI,EAAE,CAAC;YACV,wEAAwE;YACxE,0EAA0E;YAC1E,oDAAoD;YACpD,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;YACtD,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAwB,CAAC;YAC1F,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC9B,OAAO,CAAC,CAAC;QACX,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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,CAAC,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import Relay from "@relaymessenger/sdk";
2
+ import type { ConfigContext, ResolvedAuth } from "./config.js";
3
+ export interface ClientContext {
4
+ client: Relay;
5
+ auth: ResolvedAuth;
6
+ }
7
+ export declare const createClientContext: (profile?: string, configContext?: ConfigContext) => Promise<ClientContext>;
8
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,qBAAqB,CAAC;AACxC,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG/D,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,KAAK,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,eAAO,MAAM,mBAAmB,GAC9B,UAAU,MAAM,EAChB,gBAAe,aAAkB,KAChC,OAAO,CAAC,aAAa,CASvB,CAAC"}
package/dist/client.js ADDED
@@ -0,0 +1,13 @@
1
+ import Relay from "@relaymessenger/sdk";
2
+ import { resolveAuth } from "./config.js";
3
+ export const createClientContext = async (profile, configContext = {}) => {
4
+ const auth = await resolveAuth(profile, configContext);
5
+ return {
6
+ auth,
7
+ client: new Relay({
8
+ apiKey: auth.token,
9
+ baseURL: auth.apiURL,
10
+ }),
11
+ };
12
+ };
13
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,qBAAqB,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAO1C,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EACtC,OAAgB,EAChB,gBAA+B,EAAE,EACT,EAAE;IAC1B,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IACvD,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,IAAI,KAAK,CAAC;YAChB,MAAM,EAAE,IAAI,CAAC,KAAK;YAClB,OAAO,EAAE,IAAI,CAAC,MAAM;SACrB,CAAC;KACH,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,39 @@
1
+ export declare const DEFAULT_API_URL = "https://api.relayapp.im";
2
+ export declare const DEFAULT_PROFILE = "default";
3
+ export interface RelayProfile {
4
+ api_url?: string;
5
+ agent_token?: string;
6
+ }
7
+ export interface RelayConfig {
8
+ version: 1;
9
+ current_profile: string;
10
+ profiles: Record<string, RelayProfile>;
11
+ }
12
+ export interface ConfigContext {
13
+ env?: NodeJS.ProcessEnv;
14
+ home?: string;
15
+ platform?: NodeJS.Platform;
16
+ }
17
+ export interface ResolvedAuth {
18
+ profile: string;
19
+ apiURL: string;
20
+ token: string;
21
+ tokenSource: "environment" | "profile";
22
+ configPath: string;
23
+ }
24
+ export declare const configPath: (context?: ConfigContext) => string;
25
+ export declare const emptyConfig: () => RelayConfig;
26
+ export declare const readConfig: (context?: ConfigContext) => Promise<RelayConfig>;
27
+ export declare const writeConfig: (config: RelayConfig, context?: ConfigContext) => Promise<void>;
28
+ export declare const validateProfileName: (name: string) => string;
29
+ export declare const validateApiURL: (input: string) => string;
30
+ export declare const validateForwardURL: (input: string) => string;
31
+ export declare const validateToken: (value: string) => string;
32
+ export declare const resolveAuth: (requestedProfile?: string, context?: ConfigContext) => Promise<ResolvedAuth>;
33
+ export declare const inspectConfigPermissions: (context?: ConfigContext) => Promise<{
34
+ exists: boolean;
35
+ secure: boolean;
36
+ mode?: number;
37
+ }>;
38
+ export declare const collectConfiguredTokens: (context?: ConfigContext) => Promise<string[]>;
39
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,eAAe,4BAA4B,CAAC;AACzD,eAAO,MAAM,eAAe,YAAY,CAAC;AAEzC,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,CAAC,CAAC;IACX,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,aAAa,GAAG,SAAS,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;CACpB;AAKD,eAAO,MAAM,UAAU,GAAI,UAAS,aAAkB,KAAG,MAYxD,CAAC;AAEF,eAAO,MAAM,WAAW,QAAO,WAM7B,CAAC;AA0CH,eAAO,MAAM,UAAU,GACrB,UAAS,aAAkB,KAC1B,OAAO,CAAC,WAAW,CAiBrB,CAAC;AAEF,eAAO,MAAM,WAAW,GACtB,QAAQ,WAAW,EACnB,UAAS,aAAkB,KAC1B,OAAO,CAAC,IAAI,CAuBd,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,KAAG,MAOlD,CAAC;AAQF,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,KAAG,MAoB9C,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,OAAO,MAAM,KAAG,MAgBlD,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,MAM7C,CAAC;AAEF,eAAO,MAAM,WAAW,GACtB,mBAAmB,MAAM,EACzB,UAAS,aAAkB,KAC1B,OAAO,CAAC,YAAY,CA2BtB,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,UAAS,aAAkB,KAC1B,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAkB7D,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,UAAS,aAAkB,KAC1B,OAAO,CAAC,MAAM,EAAE,CAQlB,CAAC"}