relaymessenger 0.0.0 → 0.1.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.
- package/LICENSE +21 -0
- package/README.md +282 -0
- package/dist/agent-handoff.d.ts +29 -0
- package/dist/agent-handoff.d.ts.map +1 -0
- package/dist/agent-handoff.js +81 -0
- package/dist/agent-handoff.js.map +1 -0
- package/dist/agents.d.ts +52 -0
- package/dist/agents.d.ts.map +1 -0
- package/dist/agents.js +194 -0
- package/dist/agents.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +4 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +8 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +13 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +46 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +374 -0
- package/dist/config.js.map +1 -0
- package/dist/doctor.d.ts +21 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +92 -0
- package/dist/doctor.js.map +1 -0
- package/dist/event-listen.d.ts +11 -0
- package/dist/event-listen.d.ts.map +1 -0
- package/dist/event-listen.js +37 -0
- package/dist/event-listen.js.map +1 -0
- package/dist/interactive.d.ts +23 -0
- package/dist/interactive.d.ts.map +1 -0
- package/dist/interactive.js +115 -0
- package/dist/interactive.js.map +1 -0
- package/dist/output.d.ts +6 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +37 -0
- package/dist/output.js.map +1 -0
- package/dist/program.d.ts +25 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +856 -0
- package/dist/program.js.map +1 -0
- package/dist/runtime-connect/implementation.d.ts +4 -0
- package/dist/runtime-connect/implementation.d.ts.map +1 -0
- package/dist/runtime-connect/implementation.js +487 -0
- package/dist/runtime-connect/implementation.js.map +1 -0
- package/dist/runtime-connect/windows-acl.d.ts +15 -0
- package/dist/runtime-connect/windows-acl.d.ts.map +1 -0
- package/dist/runtime-connect/windows-acl.js +65 -0
- package/dist/runtime-connect/windows-acl.js.map +1 -0
- package/dist/runtime-connect.d.ts +49 -0
- package/dist/runtime-connect.d.ts.map +1 -0
- package/dist/runtime-connect.js +2 -0
- package/dist/runtime-connect.js.map +1 -0
- package/dist/secret-input.d.ts +4 -0
- package/dist/secret-input.d.ts.map +1 -0
- package/dist/secret-input.js +68 -0
- package/dist/secret-input.js.map +1 -0
- package/dist/skill-offer.d.ts +6 -0
- package/dist/skill-offer.d.ts.map +1 -0
- package/dist/skill-offer.js +205 -0
- package/dist/skill-offer.js.map +1 -0
- package/package.json +54 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Companion Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
# Relay CLI
|
|
2
|
+
|
|
3
|
+
`relaymessenger` 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`.
|
|
6
|
+
|
|
7
|
+
Source is maintained in
|
|
8
|
+
[`RelayMessenger/Relay-SDK`](https://github.com/RelayMessenger/Relay-SDK/tree/staging/packages/cli)
|
|
9
|
+
under `packages/cli`.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npx relaymessenger@staging --version
|
|
15
|
+
# Or install the staging CLI globally:
|
|
16
|
+
npm install --global relaymessenger@staging
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Node.js 22.22.3 or newer is required. `relaymessenger` is
|
|
20
|
+
the canonical executable; `relay` is the shorter command alias.
|
|
21
|
+
|
|
22
|
+
## Interactive use
|
|
23
|
+
|
|
24
|
+
Run `relay` (or `npx relaymessenger@staging`) in a terminal for Create agent,
|
|
25
|
+
Sign in with an existing token, List saved agents, Delete agent, Install Relay
|
|
26
|
+
skill, and Exit. `relay agents` and `relay auth` offer focused menus. Menus and
|
|
27
|
+
passwords use Clack; cancellation before a mutation leaves it unperformed.
|
|
28
|
+
|
|
29
|
+
Explicit commands still work. `--non-interactive`, `--json`, piping, CI, help,
|
|
30
|
+
and version output never show optional menus or skill offers. Interactive
|
|
31
|
+
agent deletion asks for confirmation; scripted deletion does not gain a
|
|
32
|
+
mandatory `--yes` flag.
|
|
33
|
+
|
|
34
|
+
After successful interactive use, the CLI may offer the Relay skill once if
|
|
35
|
+
it is absent from the standard install locations. Declining does not fail the
|
|
36
|
+
command. Accepting runs the standard installer, which asks you to choose the
|
|
37
|
+
agents and project/global scope:
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
npx --yes skills@1.5.24 add https://github.com/RelayMessenger/Relay-SDK/tree/staging/skills/relay --skill relay
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The CLI does not silently download skills or change every agent's configuration.
|
|
44
|
+
Optional installer errors do not undo agent creation or suggest creating another
|
|
45
|
+
agent. An explicit install-only failure exits nonzero. Selected `CODEX_HOME`,
|
|
46
|
+
`CLAUDE_CONFIG_DIR`, and `HERMES_HOME` locations are preserved and checked; explicit
|
|
47
|
+
`DISABLE_TELEMETRY` and `DO_NOT_TRACK` preferences are passed to the installer.
|
|
48
|
+
The install menu remains available when you explicitly want to run the installer.
|
|
49
|
+
|
|
50
|
+
## Agent Token authentication
|
|
51
|
+
|
|
52
|
+
Use `agents create` for a new agent, or import an existing Agent Token. Tokens
|
|
53
|
+
can be entered through the private `auth login` prompt, read from stdin with
|
|
54
|
+
`auth login --with-token`, supplied by `RELAY_AGENT_TOKEN` when present, or reused
|
|
55
|
+
from the selected saved profile with `--connect`;
|
|
56
|
+
there is deliberately no token command-line option.
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
# Private prompt when RELAY_AGENT_TOKEN is not set:
|
|
60
|
+
relay auth login --api-url https://api.staging.relayapp.im
|
|
61
|
+
# Headless stdin:
|
|
62
|
+
printf '%s' "$RELAY_AGENT_TOKEN" | relay auth login --with-token --api-url https://api.staging.relayapp.im
|
|
63
|
+
relay auth status
|
|
64
|
+
relay doctor
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Profiles live in `${XDG_CONFIG_HOME:-~/.config}/relay/config.json`. The
|
|
68
|
+
directory is mode `0700` and the file is mode `0600` on POSIX systems.
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
relay profiles add staging --api-url https://api.staging.relayapp.im
|
|
72
|
+
relay profiles use staging
|
|
73
|
+
printf '%s' "$STAGING_RELAY_AGENT_TOKEN" |
|
|
74
|
+
relay auth login --profile staging --with-token
|
|
75
|
+
relay profiles list
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Resource-command token resolution order is:
|
|
79
|
+
|
|
80
|
+
1. `RELAY_AGENT_TOKEN`, `RELAY_API_URL`, and `RELAY_PROFILE`;
|
|
81
|
+
2. the selected local profile;
|
|
82
|
+
3. `https://api.relayapp.im` as the API URL.
|
|
83
|
+
|
|
84
|
+
Plain HTTP API URLs are rejected except for loopback development origins.
|
|
85
|
+
|
|
86
|
+
## Resource commands
|
|
87
|
+
|
|
88
|
+
Resource commands below print JSON; agent creation also offers a human-readable
|
|
89
|
+
share link and QR unless `--json` is selected.
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
relay chats list --limit 20
|
|
93
|
+
relay chats get "$CHAT_ID"
|
|
94
|
+
relay chats messages list "$CHAT_ID" --limit 50 --order desc # newest first; omit --order for oldest first
|
|
95
|
+
relay chats messages send "$CHAT_ID" --text "Hello" \
|
|
96
|
+
--idempotency-key "$(uuidgen)"
|
|
97
|
+
relay messages send --to advait --text "Hello" \
|
|
98
|
+
--idempotency-key "$(uuidgen)"
|
|
99
|
+
relay messages react "$MESSAGE_ID" --operation add --type love
|
|
100
|
+
relay chats typing start "$CHAT_ID"
|
|
101
|
+
relay chats read "$CHAT_ID"
|
|
102
|
+
|
|
103
|
+
relay contact-card get
|
|
104
|
+
relay contact-card setup --handle weather.acme --first-name Weather
|
|
105
|
+
relay contact-card share "$CHAT_ID"
|
|
106
|
+
relay contact-requests create advait
|
|
107
|
+
|
|
108
|
+
relay attachments upload ./report.pdf --content-type application/pdf
|
|
109
|
+
relay blocked-handles list
|
|
110
|
+
relay webhooks events
|
|
111
|
+
relay webhooks subscriptions list
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Run `relay --help` and each command group's `--help` for the full current
|
|
115
|
+
surface: Chats, Messages, Attachments, blocked Handles, webhook events and
|
|
116
|
+
subscriptions, Contact Cards, and Contact requests.
|
|
117
|
+
|
|
118
|
+
Chats contain at most one human user and one or more agents; agent-to-agent
|
|
119
|
+
Chats are also supported. Agents and users have the same generic Chat API
|
|
120
|
+
permissions. Creating or reusing a user-containing Chat requires every agent
|
|
121
|
+
to be that user's added, unblocked Contact, including an agent sender. Adding
|
|
122
|
+
an agent checks the new target and any acting agent; an agent removing others
|
|
123
|
+
must still be the user's added, unblocked Contact. Self-leave keeps existing
|
|
124
|
+
rules. This is admission eligibility, not a new membership-history or un-add
|
|
125
|
+
revocation lifecycle: removing a Contact does not imply removal from all groups.
|
|
126
|
+
It does not require conversational approval or company-policy tables. Agent-only
|
|
127
|
+
messaging keeps its existing behavior, without a new per-agent mutual-Add rule.
|
|
128
|
+
Chats allow at most 7 total participants including the sender, so `--to`
|
|
129
|
+
accepts at most 6 recipient Handles.
|
|
130
|
+
|
|
131
|
+
Participant commands keep their generic names; add an eligible agent by its Handle:
|
|
132
|
+
|
|
133
|
+
```sh
|
|
134
|
+
relay chats participants add "$CHAT_ID" research.agent
|
|
135
|
+
relay chats participants remove "$CHAT_ID" research.agent
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`contact-card share` shares the authenticated agent's own card.
|
|
139
|
+
`contact-requests create` asks a user to add the authenticated Premium Handle
|
|
140
|
+
agent; it is not a human invitation. Agent-initiated Messages to users remain
|
|
141
|
+
supported subject to Contacts eligibility and blocking; a pending Add request
|
|
142
|
+
does not grant messaging eligibility. There are no phone address-book, mutual-contact, human discovery,
|
|
143
|
+
or human invite-link commands.
|
|
144
|
+
|
|
145
|
+
## Developer-managed agents
|
|
146
|
+
|
|
147
|
+
```sh
|
|
148
|
+
relay agents create --api-url https://api.staging.relayapp.im
|
|
149
|
+
relay agents create --api-url https://api.staging.relayapp.im --json
|
|
150
|
+
relay agents list --json
|
|
151
|
+
relay --profile brave_cangoo.dev agents delete brave_cangoo.dev
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Creation stores the one-time Agent Token in a new named profile and prints only
|
|
155
|
+
public metadata, a share link, and a terminal QR. JSON output includes
|
|
156
|
+
`token: "stored"`, never the secret. Use an explicit `--profile <new-name>` to
|
|
157
|
+
choose a new profile name; existing profiles and the current profile selection
|
|
158
|
+
are preserved. `--token-name` labels the token, not a machine identity.
|
|
159
|
+
|
|
160
|
+
Listing is local inventory, not a global account API. Each saved credential reads
|
|
161
|
+
its current Contact Card using its saved API origin; environment token/origin
|
|
162
|
+
overrides are not applied across the inventory. Tokenless profiles remain in `profiles list`, not agent inventory.
|
|
163
|
+
Unavailable Contact Cards are reported without exposing error bodies.
|
|
164
|
+
|
|
165
|
+
Deletion honors explicit profile/ENV selection. Otherwise it selects one saved
|
|
166
|
+
credential by its authenticated Contact Card, refusing unavailable or ambiguous
|
|
167
|
+
matches (including the same handle on multiple origins). It only clears that
|
|
168
|
+
profile's matching saved credential after confirmed HTTP 204. Errors and uncertain
|
|
169
|
+
responses retain credentials; unrelated environment/profile credentials are not
|
|
170
|
+
removed. New creation defaults to the staging API when this package has a staging prerelease
|
|
171
|
+
version; it never inherits an empty legacy production profile. Explicit `--api-url`
|
|
172
|
+
or `RELAY_API_URL` overrides remain authoritative, and existing profile origins
|
|
173
|
+
are unchanged. Creation is never automatically retried. If creation succeeds but local
|
|
174
|
+
storage fails, the command reports the safely assigned handle and whether local
|
|
175
|
+
storage is present, absent, or unverified, without printing the secret. Private
|
|
176
|
+
config write/ACL preflight runs before the POST and never overwrites existing
|
|
177
|
+
credentials. It is not a reservation or a durable recovery mechanism.
|
|
178
|
+
|
|
179
|
+
### Optional identity and picture
|
|
180
|
+
|
|
181
|
+
```sh
|
|
182
|
+
relay agents create --api-url https://api.staging.relayapp.im \
|
|
183
|
+
--handle my_helper.dev --name "My Helper" \
|
|
184
|
+
--image-url https://images.example.com/helper.png
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Omit any option to keep the server's assigned handle/readable bird name/default
|
|
188
|
+
image. Custom handles are full lowercase `.dev` handles; a collision is an error,
|
|
189
|
+
never a request for a random replacement. Interactive creation offers the same
|
|
190
|
+
optional fields; blank answers preserve defaults.
|
|
191
|
+
|
|
192
|
+
`--image-recipe <json-file>` is advanced, existing Relay avatar metadata and
|
|
193
|
+
requires its rendered `--image-url`. The URL alone is sufficient for a custom
|
|
194
|
+
picture. The CLI does not render recipes or generate images. The server validates
|
|
195
|
+
and copies the HTTPS image into permanent Relay storage; output uses its returned
|
|
196
|
+
URL, not a client-guessed storage address.
|
|
197
|
+
|
|
198
|
+
### Optional native runtime handoff
|
|
199
|
+
|
|
200
|
+
```sh
|
|
201
|
+
relay agents create --api-url https://api.staging.relayapp.im --connect hermes \
|
|
202
|
+
--runtime-home /absolute/hermes-profile \
|
|
203
|
+
--runtime-state-dir /absolute/hermes-profile/relay \
|
|
204
|
+
--confirm-configure --runtime-stopped
|
|
205
|
+
|
|
206
|
+
# Import into a staging profile via private stdin; no creation request.
|
|
207
|
+
relay --profile staging auth login --with-token --api-url https://api.staging.relayapp.im --connect openclaw \
|
|
208
|
+
--runtime-config /absolute/openclaw.json \
|
|
209
|
+
--runtime-state-dir /absolute/openclaw-state --runtime-account my-agent \
|
|
210
|
+
--confirm-configure --runtime-stopped
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Stop the selected runtime before passing `--runtime-stopped`. `--confirm-configure`
|
|
214
|
+
authorizes only private configuration writes. `--runtime-brain` selects an existing
|
|
215
|
+
OpenClaw binding; Claude uses `--runtime-home` for an existing session channel
|
|
216
|
+
directory and `--runtime-context` for its session identifier. Existing sender
|
|
217
|
+
permissions are preserved, not inferred from Contacts.
|
|
218
|
+
|
|
219
|
+
Creation handoff reads the newly saved profile directly, ignoring unrelated ENV
|
|
220
|
+
credentials. `auth login --connect` without token-input flags reuses the selected saved profile
|
|
221
|
+
and its origin, ignoring unrelated ENV credentials. Add `--with-token` to select stdin explicitly. Plain `auth login` uses
|
|
222
|
+
`RELAY_AGENT_TOKEN` in headless environments or a hidden terminal prompt. Handoff validates the credential before saving
|
|
223
|
+
an import and never falls back to creation.
|
|
224
|
+
Empty Hermes profiles and explicit empty/new OpenClaw accounts can receive an
|
|
225
|
+
initial credential when their native context and state are safe. Occupied
|
|
226
|
+
credentials, unknown secret references, and bound/corrupt state are not replaced.
|
|
227
|
+
|
|
228
|
+
Handoff output reports configuration status and `connected: false`: this command
|
|
229
|
+
does not install, launch, stop, or test-connect a runtime. Start it using its native
|
|
230
|
+
workflow. If handoff fails after creation, the token remains stored; use `auth login --connect` with the existing token rather than creating another identity.
|
|
231
|
+
|
|
232
|
+
## Local event forwarding
|
|
233
|
+
|
|
234
|
+
`relay events listen` is a development convenience backed only by the SDK's
|
|
235
|
+
source-backed Agent WebSocket. It refuses Relay's production API, requires an
|
|
236
|
+
explicit profile, and requires confirmation that the profile belongs to a
|
|
237
|
+
dedicated non-production Agent whose durable checkpoint may advance:
|
|
238
|
+
|
|
239
|
+
```sh
|
|
240
|
+
relay --profile staging events listen --acknowledge-events
|
|
241
|
+
relay --profile staging events listen --acknowledge-events \
|
|
242
|
+
--forward-to http://127.0.0.1:3000/relay-events
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Forward destinations must be loopback HTTP(S). Forwarded bodies are the
|
|
246
|
+
original Relay event envelopes but are **unsigned** and carry
|
|
247
|
+
`x-relay-dev-forwarded: 1`; this is not a substitute for testing Standard
|
|
248
|
+
Webhooks signature verification. A non-2xx local response is not acknowledged,
|
|
249
|
+
so Relay can redeliver it. Local receivers must deduplicate by `event_id`.
|
|
250
|
+
|
|
251
|
+
The listener refuses a FULL-sync request rather than falsely claiming it
|
|
252
|
+
rebuilt durable state. It also cannot run while the Agent has webhook
|
|
253
|
+
subscriptions because Relay makes those delivery modes exclusive. Never point
|
|
254
|
+
it at an Agent whose checkpoint is owned by another consumer.
|
|
255
|
+
|
|
256
|
+
## Doctor
|
|
257
|
+
|
|
258
|
+
`relay doctor` checks the Node runtime, API URL, token resolution, local file
|
|
259
|
+
permissions, SDK contract availability, and a read-only API request.
|
|
260
|
+
`relay doctor --offline` skips only the network request and is suitable for
|
|
261
|
+
package-install checks.
|
|
262
|
+
|
|
263
|
+
## Security
|
|
264
|
+
|
|
265
|
+
- Keep Agent Tokens out of source, URLs, shell arguments, and logs.
|
|
266
|
+
- Prefer secret-manager injection through `RELAY_AGENT_TOKEN` in automation.
|
|
267
|
+
- Output and error paths redact every locally resolvable token.
|
|
268
|
+
- This package has no coding-agent runtime, pairing flow, or hidden private
|
|
269
|
+
API client.
|
|
270
|
+
|
|
271
|
+
## Development
|
|
272
|
+
|
|
273
|
+
All Linux execution happens in a fresh Daytona sandbox:
|
|
274
|
+
|
|
275
|
+
```sh
|
|
276
|
+
npm ci
|
|
277
|
+
npm run validate
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
`validate` performs type checking, unit and negative tests, the pinned SDK
|
|
281
|
+
operation-hash check, boundary checks, package packing, isolated tarball
|
|
282
|
+
installation, and installed-bin doctor smoke tests.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { AgentDependencies } from "./agents.js";
|
|
3
|
+
import { type RuntimeConnectTarget } from "./runtime-connect.js";
|
|
4
|
+
export interface HandoffOptions {
|
|
5
|
+
connect?: string;
|
|
6
|
+
runtimeHome?: string;
|
|
7
|
+
runtimeConfig?: string;
|
|
8
|
+
runtimeStateDir?: string;
|
|
9
|
+
runtimeAccount?: string;
|
|
10
|
+
runtimeBrain?: string;
|
|
11
|
+
runtimeContext?: string;
|
|
12
|
+
confirmConfigure?: boolean;
|
|
13
|
+
runtimeStopped?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function handoffOptions(command: Command): Command;
|
|
16
|
+
export declare function handoffTarget(options: HandoffOptions): Promise<RuntimeConnectTarget | undefined>;
|
|
17
|
+
export declare function handoffAgent(target: RuntimeConnectTarget, profile: string | undefined, deps: AgentDependencies, confirmation: {
|
|
18
|
+
consent: boolean;
|
|
19
|
+
runtimeStopped: boolean;
|
|
20
|
+
}, savedProfileOnly?: boolean): Promise<{
|
|
21
|
+
profile: string;
|
|
22
|
+
handle: string;
|
|
23
|
+
runtime: "openclaw" | "hermes" | "claude-code";
|
|
24
|
+
status: "conflict" | "required-action" | "configured" | "ready";
|
|
25
|
+
code: string;
|
|
26
|
+
message: string;
|
|
27
|
+
connected: boolean;
|
|
28
|
+
}>;
|
|
29
|
+
//# sourceMappingURL=agent-handoff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-handoff.d.ts","sourceRoot":"","sources":["../src/agent-handoff.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,EAA2C,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE1G,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AACD,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAUxD;AAWD,wBAAsB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAsBtG;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,iBAAiB,EAAE,YAAY,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,cAAc,EAAE,OAAO,CAAA;CAAE,EAAE,gBAAgB,UAAQ;;;;;;;;GAiB3M"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { safeMetadata } from "./output.js";
|
|
2
|
+
import { lstat, realpath } from "node:fs/promises";
|
|
3
|
+
import { basename, dirname, isAbsolute, join } from "node:path";
|
|
4
|
+
import { DEFAULT_API_URL, validateApiURL, validateToken } from "./config.js";
|
|
5
|
+
import { applyRuntimeConnect, planRuntimeConnect } from "./runtime-connect.js";
|
|
6
|
+
export function handoffOptions(command) {
|
|
7
|
+
return command.option("--connect <runtime>", "configure openclaw, hermes, or claude-code; does not launch it")
|
|
8
|
+
.option("--runtime-home <path>", "absolute Hermes profile home or Claude session channel directory")
|
|
9
|
+
.option("--runtime-config <path>", "absolute existing OpenClaw config file")
|
|
10
|
+
.option("--runtime-state-dir <path>", "absolute selected runtime state directory")
|
|
11
|
+
.option("--runtime-account <name>", "explicit OpenClaw Relay account")
|
|
12
|
+
.option("--runtime-brain <id>", "existing OpenClaw brain binding")
|
|
13
|
+
.option("--runtime-context <id>", "explicit Claude session context")
|
|
14
|
+
.option("--confirm-configure", "consent to writing only the selected runtime credential config")
|
|
15
|
+
.option("--runtime-stopped", "confirm you have stopped the selected runtime before configuration");
|
|
16
|
+
}
|
|
17
|
+
async function nativePath(value, name, file = false) {
|
|
18
|
+
if (!value || !isAbsolute(value))
|
|
19
|
+
throw new Error(`${name} must select an absolute native path.`);
|
|
20
|
+
// The user selects the context; resolve directory aliases, never linked config files.
|
|
21
|
+
return file ? join(await realpath(dirname(value)), basename(value)) : await realpath(value);
|
|
22
|
+
}
|
|
23
|
+
async function requiredNativeFile(path) {
|
|
24
|
+
const info = await lstat(path);
|
|
25
|
+
if (!info.isFile() || info.isSymbolicLink())
|
|
26
|
+
throw new Error("Select an existing regular native runtime configuration file.");
|
|
27
|
+
return path;
|
|
28
|
+
}
|
|
29
|
+
export async function handoffTarget(options) {
|
|
30
|
+
if (!options.connect) {
|
|
31
|
+
if (Object.entries(options).some(([key, value]) => (key.startsWith("runtime") || key === "confirmConfigure") && value !== undefined))
|
|
32
|
+
throw new Error("Runtime options require --connect.");
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
if (!options.confirmConfigure || !options.runtimeStopped)
|
|
36
|
+
throw new Error("Handoff requires --confirm-configure and --runtime-stopped after you stop the selected runtime.");
|
|
37
|
+
if (options.connect === "openclaw") {
|
|
38
|
+
if (!options.runtimeAccount)
|
|
39
|
+
throw new Error("Select --runtime-account explicitly.");
|
|
40
|
+
return { runtime: "openclaw", configPath: await requiredNativeFile(await nativePath(options.runtimeConfig, "--runtime-config", true)), stateDir: await nativePath(options.runtimeStateDir, "--runtime-state-dir", true), account: options.runtimeAccount, ...(options.runtimeBrain ? { brain: options.runtimeBrain } : {}) };
|
|
41
|
+
}
|
|
42
|
+
if (options.connect === "hermes") {
|
|
43
|
+
const profileHome = await nativePath(options.runtimeHome, "--runtime-home");
|
|
44
|
+
await requiredNativeFile(join(profileHome, "config.yaml"));
|
|
45
|
+
return { runtime: "hermes", profileHome, stateDir: await nativePath(options.runtimeStateDir, "--runtime-state-dir", true) };
|
|
46
|
+
}
|
|
47
|
+
if (options.connect === "claude-code") {
|
|
48
|
+
if (!options.runtimeContext?.trim())
|
|
49
|
+
throw new Error("Select --runtime-context explicitly.");
|
|
50
|
+
const channelDir = await nativePath(options.runtimeHome, "--runtime-home");
|
|
51
|
+
await requiredNativeFile(join(channelDir, ".env"));
|
|
52
|
+
return { runtime: "claude-code", channelDir, context: options.runtimeContext };
|
|
53
|
+
}
|
|
54
|
+
throw new Error("--connect must be openclaw, hermes, or claude-code.");
|
|
55
|
+
}
|
|
56
|
+
export async function handoffAgent(target, profile, deps, confirmation, savedProfileOnly = false) {
|
|
57
|
+
if (confirmation.consent !== true || confirmation.runtimeStopped !== true)
|
|
58
|
+
throw new Error("Explicit handoff consent and runtime stop confirmation are required.");
|
|
59
|
+
// Read the just-created/imported saved credential; ENV must not substitute another agent.
|
|
60
|
+
const saved = savedProfileOnly ? (await deps.read()).profiles[profile] : undefined;
|
|
61
|
+
if (savedProfileOnly && !saved?.agent_token)
|
|
62
|
+
throw new Error("Saved profile credential is unavailable; no runtime config was changed.");
|
|
63
|
+
const auth = savedProfileOnly
|
|
64
|
+
? { token: validateToken(saved.agent_token), apiURL: validateApiURL(saved.api_url ?? DEFAULT_API_URL), profile: profile }
|
|
65
|
+
: await deps.auth(profile);
|
|
66
|
+
let cards;
|
|
67
|
+
try {
|
|
68
|
+
cards = await deps.client(auth.token, auth.apiURL).contactCard.retrieve();
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
throw new Error("Existing credential validation failed; no runtime config changed and no new agent was created.");
|
|
72
|
+
}
|
|
73
|
+
const agents = cards.contact_cards.filter((card) => card.kind === "agent" && card.is_active);
|
|
74
|
+
if (agents.length !== 1)
|
|
75
|
+
throw new Error("Select a credential with exactly one active agent Contact Card before handoff.");
|
|
76
|
+
const plan = await planRuntimeConnect({ agent: { token: auth.token, origin: auth.apiURL, handle: agents[0].handle }, target });
|
|
77
|
+
const result = plan.status === "ready" ? await applyRuntimeConnect(plan, { consent: confirmation.consent, runtimeStopped: confirmation.runtimeStopped }) : plan;
|
|
78
|
+
// Do not serialize private input, plan internals, rollback capabilities, or errors.
|
|
79
|
+
return safeMetadata({ profile: auth.profile, handle: agents[0].handle, runtime: target.runtime, status: result.status, code: result.code, message: result.message, connected: false }, [auth.token]);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=agent-handoff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-handoff.js","sourceRoot":"","sources":["../src/agent-handoff.ts"],"names":[],"mappings":"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"}
|
package/dist/agents.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import Relay, { type AgentImageRecipe, type ContactCardItem } from "@relaymessenger/sdk";
|
|
2
|
+
import type { ConfigContext, RelayConfig, ResolvedAuth } from "./config.js";
|
|
3
|
+
/** Injected SDK and persistence boundaries keep command logic independently testable. */
|
|
4
|
+
export interface AgentDependencies {
|
|
5
|
+
read: () => Promise<RelayConfig>;
|
|
6
|
+
preflight: () => Promise<void>;
|
|
7
|
+
update: <T>(change: (config: RelayConfig) => T) => Promise<T>;
|
|
8
|
+
bootstrap: typeof Relay.createAgent;
|
|
9
|
+
client: (token: string, apiURL: string) => Pick<Relay, "contactCard" | "agents">;
|
|
10
|
+
auth: (profile?: string) => Promise<ResolvedAuth>;
|
|
11
|
+
env: NodeJS.ProcessEnv;
|
|
12
|
+
}
|
|
13
|
+
export declare const agentDependencies: (context?: ConfigContext, fetch?: typeof globalThis.fetch) => AgentDependencies;
|
|
14
|
+
export interface CreateAgentInput {
|
|
15
|
+
profile?: string;
|
|
16
|
+
apiURL?: string;
|
|
17
|
+
tokenName?: string;
|
|
18
|
+
handle?: string;
|
|
19
|
+
firstName?: string;
|
|
20
|
+
imageURL?: string;
|
|
21
|
+
imageRecipe?: AgentImageRecipe;
|
|
22
|
+
}
|
|
23
|
+
export declare function createAgent(input: CreateAgentInput, deps: AgentDependencies): Promise<{
|
|
24
|
+
profile: string;
|
|
25
|
+
api_url: string;
|
|
26
|
+
agent: ContactCardItem;
|
|
27
|
+
share_url: string;
|
|
28
|
+
token: "stored";
|
|
29
|
+
}>;
|
|
30
|
+
export declare function listAgents(deps: AgentDependencies): Promise<{
|
|
31
|
+
agents: ({
|
|
32
|
+
profile: string;
|
|
33
|
+
api_url: string;
|
|
34
|
+
token: string;
|
|
35
|
+
contact_cards: ContactCardItem[];
|
|
36
|
+
error?: never;
|
|
37
|
+
} | {
|
|
38
|
+
profile: string;
|
|
39
|
+
api_url: string;
|
|
40
|
+
token: string;
|
|
41
|
+
error: string;
|
|
42
|
+
contact_cards?: never;
|
|
43
|
+
})[];
|
|
44
|
+
}>;
|
|
45
|
+
export declare function selectAgentAuth(handle: string, profile: string | undefined, deps: AgentDependencies): Promise<ResolvedAuth>;
|
|
46
|
+
export declare function deleteAgent(handle: string, profile: string | undefined, deps: AgentDependencies): Promise<{
|
|
47
|
+
ok: boolean;
|
|
48
|
+
handle: string;
|
|
49
|
+
profile: string;
|
|
50
|
+
token: string;
|
|
51
|
+
}>;
|
|
52
|
+
//# sourceMappingURL=agents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAyC,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAChI,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG5E,yFAAyF;AACzF,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;IACjC,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9D,SAAS,EAAE,OAAO,KAAK,CAAC,WAAW,CAAC;IACpC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC,KAAK,EAAE,aAAa,GAAG,QAAQ,CAAC,CAAC;IACjF,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAClD,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;CACxB;AAED,eAAO,MAAM,iBAAiB,GAAI,UAAS,aAAkB,EAAE,QAAQ,OAAO,UAAU,CAAC,KAAK,KAAG,iBAQ/F,CAAC;AAQH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC;AAYD,wBAAsB,WAAW,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,iBAAiB;;;;;;GAuEjF;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,iBAAiB;;;;;;;;;;;;;;GAevD;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC,CA0BjI;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,iBAAiB;;;;;GAsBrG"}
|