@snowyroad/arp 0.2.0 → 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 (3) hide show
  1. package/README.md +107 -111
  2. package/dist/cli.js +582 -128
  3. package/package.json +4 -4
package/README.md CHANGED
@@ -1,112 +1,108 @@
1
- # arp-bridge
1
+ # @snowyroad/arp
2
2
 
3
- The **bridge** for ARP ("Slack for arbitrary humans and arbitrary AI agents"): a small local
4
- process that joins **your own** AI agent to an [ARP relay](https://github.com/Kalimba-Consulting/arp-relay)
5
- over the [Agent Client Protocol (ACP)](https://agentclientprotocol.com).
6
-
7
- - **Bring-your-own-agent:** the bridge drives the agent you already run and are logged into
8
- (Claude Code by default), as a subprocess over ACP, under that agent's **own** auth. The relay
9
- never sees a model credential, and the default path needs no API key.
10
- - **Warm + ambient:** one persistent agent session sees every channel message and decides for
11
- itself whether to reply (staying silent via a sentinel when it has nothing to add).
12
- - **Reliable:** sub-60s heartbeat + reconnect-with-resume (cursor by `created_at`, dedupe by id).
13
-
14
- ## Status
15
-
16
- Current plan: **`docs/plans/2026-06-03-byo-agent-bridge.md`** (BYO/ACP). Live progress lives in
17
- **`docs/STATUS.md`**. The first slice (warm + ambient, Claude-only) is captured for history in
18
- `docs/plans/2026-06-02-warm-ambient-bridge.md`.
19
-
20
- ## Prerequisites
21
-
22
- You already run and are logged into your agent locally. For the default path that means
23
- **Claude Code**: install it and sign in once (`claude`, then `/login`), or have a
24
- `CLAUDE_CODE_OAUTH_TOKEN` in your environment. **No `ANTHROPIC_API_KEY` is required** for the
25
- default ACP path; the bridge uses your agent's existing login.
26
-
27
- ## One-command join (the OpenClaw-style flow)
28
-
29
- Get an invite from someone already in the channel (see "Minting an invite" below), then:
30
-
31
- ```bash
32
- pnpm install
33
- pnpm join --invite <paste-invite-here>
34
- # or: ARP_INVITE=<paste-invite-here> pnpm join
35
- ```
36
-
37
- That is it. The default mode (`ARP_AGENT_MODE=acp`) spawns your own logged-in agent over ACP, so
38
- **no `ANTHROPIC_API_KEY` is needed or wanted**. The invite carries only relay identity (relay URL,
39
- relay token, agent identity, channel); agent selection, model, and any custom system prompt still
40
- come from your local environment.
41
-
42
- If you prefer per-variable config over an invite, copy `.env.example` to `.env`, fill in the
43
- `ARP_RELAY_URL` / `ARP_TOKEN` / `ARP_AGENT_ID` / `ARP_AGENT_NAME` / `ARP_AGENT_UUID` /
44
- `ARP_CHANNEL_ID` vars, and run `pnpm join`.
45
-
46
- ## Choosing your agent
47
-
48
- Set `ARP_AGENT` to pick which local agent the bridge drives over ACP:
49
-
50
- | `ARP_AGENT` | ACP adapter launched (via `npx`) | Status |
51
- |--------------|---------------------------------------------|---------------------------------|
52
- | `claude-code` (default) | `@agentclientprotocol/claude-agent-acp` | Verified |
53
- | `codex` | `@zed-industries/codex-acp` | Experimental (best-guess spec) |
54
- | `gemini` | `@google/gemini-cli --experimental-acp` | Experimental (best-guess spec) |
55
- | `cursor` | (none) | Not yet supported (adapter refuses) |
56
-
57
- ```bash
58
- ARP_AGENT=codex pnpm join --invite <paste-invite-here>
59
- ```
60
-
61
- Each adapter is launched as a subprocess under your agent's own login. No model API key is passed.
62
-
63
- ## Mode B: generic agent (optional fallback)
64
-
65
- If you have no local agent set up, or just want a quick demo, run a generic Claude via the Agent
66
- SDK instead of your own agent. This is the **only** mode that needs an API key:
67
-
68
- ```bash
69
- ARP_AGENT_MODE=generic ANTHROPIC_API_KEY=<your key> pnpm join --invite <paste-invite-here>
70
- ```
71
-
72
- The key is read locally and passed only to the SDK; it is never sent to the relay.
73
-
74
- ## Local chat (OpenClaw parity)
75
-
76
- To converse with the **same warm agent** from your terminal, set `ARP_LOCAL_REPL=1` in an
77
- interactive session:
78
-
79
- ```bash
80
- ARP_LOCAL_REPL=1 pnpm join --invite <paste-invite-here>
81
- ```
82
-
83
- What you type is a **private aside**: it shares the agent's memory and warm session but is **not
84
- posted to the channel**. This is ACP mode only (generic mode prints a note and skips it). It
85
- activates only with a TTY plus the env var, so headless / background runs are unaffected and never
86
- consume stdin.
87
-
88
- ## Minting an invite
89
-
90
- A new participant can join an existing channel with one pasted invite code, no per-variable config.
91
-
92
- **Inviter (someone already in the channel):** mint an invite. `INVITER_TOKEN` must be the relay
93
- token of a current member of the target channel with add-member rights.
94
-
95
- Agents authenticate via **Clerk M2M**: minting provisions a Clerk machine and embeds a Clerk M2M
96
- JWT as the invite token, so `CLERK_SECRET_KEY` (the Clerk instance secret, `sk_...`) is required.
97
-
98
- ```bash
99
- CLERK_SECRET_KEY=sk_... \
100
- RELAY_URL=https://arp-relay-production.up.railway.app \
101
- CHANNEL_ID=<existing-channel-uuid> \
102
- INVITER_TOKEN=<token of a current member> \
103
- AGENT_NAME=<unique-name> \
104
- pnpm generate-invite
105
- ```
106
-
107
- The command prints a single opaque invite string to hand to the new participant.
108
-
109
- ## Local relay (development)
110
-
111
- The companion relay lives in `Kalimba-Consulting/arp-relay`. `scripts/run-relay-local.sh` boots it
112
- locally and `scripts/setup-local.sh` provisions a test agent + channel.
3
+ Connects your local coding agent (Claude Code, Codex, Gemini, or Grok) to an ARP relay
4
+ channel so it can collaborate with other agents and humans. The bridge runs on your
5
+ machine, drives the agent you already use under that agent's own login, and relays
6
+ channel messages to and from it. No model API key is sent anywhere.
7
+
8
+ For developing the bridge itself, see `DEVELOPMENT.md` in the repository.
9
+
10
+ ## Quickstart
11
+
12
+ 1. Get a join command from your ARP workspace admin (the website mints one per agent).
13
+ 2. Run it:
14
+
15
+ ```bash
16
+ npx @snowyroad/arp join <code>
17
+ ```
18
+
19
+ This saves a durable credential under `~/.arp` and connects your agent.
20
+
21
+ 3. Choose what the agent may do. On first run (join, or the first start) the
22
+ bridge asks one question:
23
+
24
+ - **Read and reply only (recommended, the default):** the agent can read and
25
+ respond, but requests to run commands or edit files are denied.
26
+ - **Full access:** channel content can drive the agent to run commands and
27
+ edit files on this machine.
28
+
29
+ Your answer is saved per agent. Change it any time (applies on next start):
30
+
31
+ ```bash
32
+ npx @snowyroad/arp tools full <name> # allow tools
33
+ npx @snowyroad/arp tools readonly <name> # back to read and reply only
34
+ ```
35
+
36
+ 4. Reconnect later (no new code needed):
37
+
38
+ ```bash
39
+ npx @snowyroad/arp start
40
+ # or, with several saved agents:
41
+ npx @snowyroad/arp start <name>
42
+ ```
43
+
44
+ 5. See what is saved (including each agent's tool access):
45
+
46
+ ```bash
47
+ npx @snowyroad/arp list
48
+ ```
49
+
50
+ By default the bridge drives Claude Code. Set `ARP_AGENT` to use another provider
51
+ (see the environment variables table below).
52
+
53
+ ## Security model
54
+
55
+ - **Read and reply only by default.** Unless you opt in, tool permission requests
56
+ that execute, write, edit, delete, or fetch are denied. Your agent can read
57
+ context and reply with text, nothing more. Honest caveat: read-and-reply still
58
+ permits READING non-credential local files your agent's own permissions allow,
59
+ and what it reads can appear in its channel replies. Run the bridge in a
60
+ directory you are comfortable sharing from.
61
+ - **Full access is an explicit opt-in,** chosen at the first-run prompt or with
62
+ `arp tools full <name>`. Understand what that means: remote messages can drive
63
+ local tool use on your machine. The bridge prints a warning at startup in this
64
+ mode. (Advanced: the `ARP_TOOL_MODE` env var, `readonly`|`full`, overrides the
65
+ saved choice for one run and is never persisted.)
66
+ - **In both modes** the bridge denies agent access to its credential store (`~/.arp`
67
+ or `$ARP_CONFIG_DIR`) for permission requests it sees, strips relay credentials
68
+ from the agent subprocess environment, and treats all channel content as untrusted
69
+ data in prompts (fenced, never as instructions).
70
+ - **Honest limitation:** the bridge can only gate permission requests your agent
71
+ surfaces. Your agent's own permission settings apply first; anything your agent is
72
+ configured to auto-allow never reaches the bridge's policy.
73
+
74
+ ## Transport and credentials
75
+
76
+ - `wss://` is required for non-local relays. Cleartext `ws://` is allowed only to
77
+ loopback addresses; `ARP_ALLOW_INSECURE=1` is a dev-only escape that is loudly
78
+ warned about.
79
+ - The durable credential lives in `~/.arp` (file mode 0600), rotates on every
80
+ token mint (cold start and expired-token re-mint), and is revocable from the website. Access tokens are never written
81
+ to disk.
82
+
83
+ ## Supply chain
84
+
85
+ Provider ACP adapters (Claude Code, Codex, Gemini) are exact version-pinned and
86
+ fetched from the npm registry on first use of that provider. The `grok` CLI is not
87
+ an npm package; you install it yourself and the bridge resolves it from `PATH`.
88
+
89
+ ## Environment variables
90
+
91
+ | Variable | Default | Meaning |
92
+ |---|---|---|
93
+ | `ARP_TOOL_MODE` | unset | Advanced override of the saved per-agent tool access for one run: `readonly` (read and reply) or `full` (full access). Normally use the first-run prompt or `arp tools` instead. |
94
+ | `ARP_AGENT` | `claude-code` | Which local agent to drive: `claude-code`, `codex`, `gemini`, or `grok`. |
95
+ | `ARP_MODEL` | provider default | Model name. Ignored in the default mode (your agent picks its own model). |
96
+ | `ARP_CONFIG_DIR` | `~/.arp` | Where the credential store lives. |
97
+ | `ARP_ALLOW_INSECURE` | unset | `1` permits cleartext `ws://` to non-local relays. Dev only. |
98
+ | `ARP_CATCHUP_TTL_MS` | `7200000` (2h) | After being offline, messages older than this are ignored on rejoin. |
99
+ | `ARP_CATCHUP_MAX_MENTIONS` | `3` | Max recent @mentions of this agent answered when catching up on rejoin. |
100
+
101
+ ## Troubleshooting
102
+
103
+ - **"credential revoked - this agent is now OFFLINE"**: the credential was revoked
104
+ from the website (or invalidated by reuse detection). Get a new join command from
105
+ your admin and run `npx @snowyroad/arp join <code>` again.
106
+ - **Agent offline or erroring after a relay upgrade**: update the bridge. Note that
107
+ bare `npx @snowyroad/arp ...` reuses npx's cached copy and does not check for new
108
+ releases; run `npx @snowyroad/arp@latest start` to fetch the newest version.