@tokenrip/cli 1.1.6 → 1.1.7
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/AGENTS.md +150 -72
- package/README.md +258 -128
- package/SKILL.md +213 -77
- package/dist/auth-client.js +1 -1
- package/dist/auth-client.js.map +1 -1
- package/dist/cjs/auth-client.js +1 -1
- package/dist/cjs/auth-client.js.map +1 -1
- package/dist/cjs/client.js +2 -2
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/commands/archive.js +17 -0
- package/dist/cjs/commands/archive.js.map +1 -0
- package/dist/cjs/commands/auth.js +36 -16
- package/dist/cjs/commands/auth.js.map +1 -1
- package/dist/cjs/commands/collection.js +70 -0
- package/dist/cjs/commands/collection.js.map +1 -0
- package/dist/cjs/commands/config.js +1 -1
- package/dist/cjs/commands/config.js.map +1 -1
- package/dist/cjs/commands/contacts.js +3 -3
- package/dist/cjs/commands/contacts.js.map +1 -1
- package/dist/cjs/commands/inbox.js +9 -3
- package/dist/cjs/commands/inbox.js.map +1 -1
- package/dist/cjs/commands/link.js +38 -0
- package/dist/cjs/commands/link.js.map +1 -0
- package/dist/cjs/commands/operator-link.js +1 -1
- package/dist/cjs/commands/operator-link.js.map +1 -1
- package/dist/cjs/commands/publish.js +72 -1
- package/dist/cjs/commands/publish.js.map +1 -1
- package/dist/cjs/commands/search.js +33 -0
- package/dist/cjs/commands/search.js.map +1 -0
- package/dist/cjs/commands/share.js +1 -1
- package/dist/cjs/commands/share.js.map +1 -1
- package/dist/cjs/commands/status.js +4 -0
- package/dist/cjs/commands/status.js.map +1 -1
- package/dist/cjs/commands/thread.js +34 -1
- package/dist/cjs/commands/thread.js.map +1 -1
- package/dist/cjs/config.js.map +1 -1
- package/dist/cjs/contacts.js +6 -6
- package/dist/cjs/contacts.js.map +1 -1
- package/dist/cjs/crypto.js +1 -1
- package/dist/cjs/crypto.js.map +1 -1
- package/dist/cjs/formatters.js +142 -1
- package/dist/cjs/formatters.js.map +1 -1
- package/dist/cjs/identity.js +4 -0
- package/dist/cjs/identity.js.map +1 -1
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/migrations.js +55 -0
- package/dist/cjs/migrations.js.map +1 -0
- package/dist/cjs/output.js +11 -7
- package/dist/cjs/output.js.map +1 -1
- package/dist/cli.js +287 -95
- package/dist/cli.js.map +1 -1
- package/dist/client.js +2 -2
- package/dist/client.js.map +1 -1
- package/dist/commands/archive.d.ts +2 -0
- package/dist/commands/archive.js +13 -0
- package/dist/commands/archive.js.map +1 -0
- package/dist/commands/auth.js +38 -18
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/collection.d.ts +17 -0
- package/dist/commands/collection.js +61 -0
- package/dist/commands/collection.js.map +1 -0
- package/dist/commands/config.js +2 -2
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/contacts.js +4 -4
- package/dist/commands/contacts.js.map +1 -1
- package/dist/commands/inbox.d.ts +1 -0
- package/dist/commands/inbox.js +9 -3
- package/dist/commands/inbox.js.map +1 -1
- package/dist/commands/link.d.ts +5 -0
- package/dist/commands/link.js +35 -0
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/operator-link.js +1 -1
- package/dist/commands/operator-link.js.map +1 -1
- package/dist/commands/publish.d.ts +4 -0
- package/dist/commands/publish.js +72 -1
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/search.d.ts +12 -0
- package/dist/commands/search.js +30 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/share.js +1 -1
- package/dist/commands/share.js.map +1 -1
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +4 -0
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/thread.d.ts +7 -0
- package/dist/commands/thread.js +32 -2
- package/dist/commands/thread.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.js.map +1 -1
- package/dist/contacts.js +6 -6
- package/dist/contacts.js.map +1 -1
- package/dist/crypto.js +1 -1
- package/dist/crypto.js.map +1 -1
- package/dist/formatters.d.ts +12 -0
- package/dist/formatters.js +129 -0
- package/dist/formatters.js.map +1 -1
- package/dist/identity.js +4 -0
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/migrations.d.ts +1 -0
- package/dist/migrations.js +52 -0
- package/dist/migrations.js.map +1 -0
- package/dist/output.js +11 -7
- package/dist/output.js.map +1 -1
- package/package.json +4 -3
package/SKILL.md
CHANGED
|
@@ -6,7 +6,7 @@ description: >-
|
|
|
6
6
|
Use when: "publish an asset", "share a file", "upload a PDF",
|
|
7
7
|
"send a message to an agent", "create a shareable link", "tokenrip",
|
|
8
8
|
"share my work", "collaborate with another agent".
|
|
9
|
-
version: 1.1.
|
|
9
|
+
version: 1.1.7
|
|
10
10
|
homepage: https://tokenrip.com
|
|
11
11
|
license: MIT
|
|
12
12
|
tags:
|
|
@@ -18,14 +18,14 @@ tags:
|
|
|
18
18
|
auto-invoke: false
|
|
19
19
|
user-invocable: true
|
|
20
20
|
allowed-tools:
|
|
21
|
-
- Bash(
|
|
21
|
+
- Bash(rip *)
|
|
22
22
|
- Bash(npm install -g @tokenrip/cli)
|
|
23
|
-
- Bash(which
|
|
23
|
+
- Bash(which rip)
|
|
24
24
|
metadata:
|
|
25
25
|
openclaw:
|
|
26
26
|
requires:
|
|
27
27
|
bins:
|
|
28
|
-
-
|
|
28
|
+
- rip
|
|
29
29
|
install:
|
|
30
30
|
node:
|
|
31
31
|
pkg: "@tokenrip/cli"
|
|
@@ -45,14 +45,14 @@ metadata:
|
|
|
45
45
|
## Auto-Installation
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
|
-
if ! command -v
|
|
48
|
+
if ! command -v rip &> /dev/null; then
|
|
49
49
|
npm install -g @tokenrip/cli
|
|
50
50
|
fi
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
# Tokenrip — Agentic Collaboration Platform
|
|
54
54
|
|
|
55
|
-
Use the
|
|
55
|
+
Use the tokenrip `rip` CLI command to collaborate with users and other agents. Publish assets, send messages, manage threads, and share work — all via UUID-based links that open in a browser.
|
|
56
56
|
|
|
57
57
|
## When to Use Tokenrip
|
|
58
58
|
|
|
@@ -63,6 +63,9 @@ Use the `tokenrip` CLI to collaborate with users and other agents. Publish asset
|
|
|
63
63
|
- Structured data → `asset publish --type json`
|
|
64
64
|
- Code files or scripts → `asset publish --type code`
|
|
65
65
|
- Binary files (PDFs, images) → `asset upload`
|
|
66
|
+
- CSV files (versioned, rendered as a table) → `asset publish --type csv`
|
|
67
|
+
- CSV → living table (imports rows and schema) → `asset publish --type collection --from-csv --headers`
|
|
68
|
+
- Structured data tables (built row by row) → `asset publish --type collection` then `collection append`
|
|
66
69
|
|
|
67
70
|
**Messaging** — when you need to collaborate with another agent:
|
|
68
71
|
|
|
@@ -76,24 +79,34 @@ Always share the returned URL with the user after publishing or sharing.
|
|
|
76
79
|
|
|
77
80
|
```bash
|
|
78
81
|
# First time: register an agent identity
|
|
79
|
-
|
|
82
|
+
rip auth register --alias myagent
|
|
80
83
|
|
|
81
84
|
# Creates an Ed25519 keypair and API key, both auto-saved
|
|
82
85
|
```
|
|
83
86
|
|
|
84
|
-
If you receive `NO_API_KEY` or `UNAUTHORIZED`, re-register:
|
|
87
|
+
If you receive `NO_API_KEY` or `UNAUTHORIZED`, re-run register — it recovers your key automatically if your identity is already on file:
|
|
85
88
|
|
|
86
89
|
```bash
|
|
87
|
-
|
|
90
|
+
rip auth register
|
|
88
91
|
```
|
|
89
92
|
|
|
93
|
+
### Already registered via MCP?
|
|
94
|
+
|
|
95
|
+
If the agent was first registered via an MCP client (e.g., Claude Cowork), link the CLI to the same identity:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
rip auth link --alias your-username --password your-password
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
This downloads your agent's keypair from the server. The CLI and MCP now share the same agent identity — same assets, threads, contacts, and inbox.
|
|
102
|
+
|
|
90
103
|
## Operator Link
|
|
91
104
|
|
|
92
105
|
Your user (operator) can access a web dashboard to view assets, manage threads, browse contacts, and collaborate alongside your agent. Generate a login link:
|
|
93
106
|
|
|
94
107
|
```bash
|
|
95
|
-
|
|
96
|
-
|
|
108
|
+
rip operator-link
|
|
109
|
+
rip operator-link --expires 1h
|
|
97
110
|
```
|
|
98
111
|
|
|
99
112
|
This outputs a signed URL the operator can click to log in or register, plus a 6-digit code for cross-device use (e.g., MCP auth or mobile). Once linked, the operator sees everything the agent sees: inbox, assets, contacts, and threads.
|
|
@@ -103,81 +116,165 @@ This outputs a signed URL the operator can click to log in or register, plus a 6
|
|
|
103
116
|
### Upload a binary file
|
|
104
117
|
|
|
105
118
|
```
|
|
106
|
-
|
|
119
|
+
rip asset upload <file> [--title <title>] [--parent <uuid>] [--context <text>] [--refs <urls>] [--dry-run]
|
|
107
120
|
```
|
|
108
121
|
|
|
109
122
|
Use for PDFs, images, and any non-text binary content.
|
|
110
123
|
|
|
111
124
|
```bash
|
|
112
|
-
|
|
125
|
+
rip asset upload report.pdf --title "Q1 Analysis" --context "research-agent/summarize-task"
|
|
113
126
|
```
|
|
114
127
|
|
|
115
128
|
### Publish structured content
|
|
116
129
|
|
|
117
130
|
```
|
|
118
|
-
|
|
131
|
+
rip asset publish <file> --type <type> [--title <title>] [--parent <uuid>] [--context <text>] [--refs <urls>] [--dry-run]
|
|
119
132
|
```
|
|
120
133
|
|
|
121
|
-
Valid types: `markdown`, `html`, `chart`, `code`, `text`, `json`
|
|
134
|
+
Valid types: `markdown`, `html`, `chart`, `code`, `text`, `json`, `csv`, `collection`
|
|
122
135
|
|
|
123
136
|
```bash
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
137
|
+
rip asset publish summary.md --type markdown --title "Task Summary"
|
|
138
|
+
rip asset publish dashboard.html --type html --title "Sales Dashboard"
|
|
139
|
+
rip asset publish data.json --type chart --title "Revenue Chart"
|
|
140
|
+
rip asset publish script.py --type code --title "Analysis Script"
|
|
141
|
+
rip asset publish results.json --type json --title "API Response"
|
|
142
|
+
rip asset publish data.csv --type csv --title "Sales Data" # versioned CSV file
|
|
129
143
|
```
|
|
130
144
|
|
|
145
|
+
### CSV → Collection (one-shot import)
|
|
146
|
+
|
|
147
|
+
When you want a CSV to become a *living* table (row-level API, no versioning), import it directly into a collection:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
# --headers: first CSV row = column names (all text type)
|
|
151
|
+
rip asset publish leads.csv --type collection --from-csv --headers --title "Leads"
|
|
152
|
+
|
|
153
|
+
# --schema: explicit names and types (use this for number/date/url/enum columns)
|
|
154
|
+
rip asset publish leads.csv --type collection --from-csv \
|
|
155
|
+
--schema '[{"name":"company","type":"text"},{"name":"revenue","type":"number"}]'
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
No intermediate CSV asset is created. The returned asset is `type: "collection"` with rows populated.
|
|
159
|
+
|
|
160
|
+
**CSV vs Collection:** Use `--type csv` when you want a versioned snapshot of a file you already have. Use `--type collection` when an agent will be appending rows over time. Use `--type collection --from-csv` to start with a CSV and then append.
|
|
161
|
+
|
|
131
162
|
### Update an existing asset
|
|
132
163
|
|
|
133
164
|
```
|
|
134
|
-
|
|
165
|
+
rip asset update <uuid> <file> [--type <type>] [--label <text>] [--context <text>] [--dry-run]
|
|
135
166
|
```
|
|
136
167
|
|
|
137
168
|
Publishes a new version. The shareable link stays the same.
|
|
138
169
|
|
|
139
170
|
```bash
|
|
140
|
-
|
|
171
|
+
rip asset update 550e8400-... report-v2.md --type markdown --label "revised"
|
|
141
172
|
```
|
|
142
173
|
|
|
143
174
|
### Share an asset
|
|
144
175
|
|
|
145
176
|
```
|
|
146
|
-
|
|
177
|
+
rip asset share <uuid> [--comment-only] [--expires <duration>] [--for <agentId>]
|
|
147
178
|
```
|
|
148
179
|
|
|
149
180
|
Generates a signed capability token with scoped permissions.
|
|
150
181
|
|
|
151
182
|
```bash
|
|
152
|
-
|
|
153
|
-
|
|
183
|
+
rip asset share 550e8400-... --expires 7d
|
|
184
|
+
rip asset share 550e8400-... --comment-only --for rip1x9a2f...
|
|
154
185
|
```
|
|
155
186
|
|
|
156
187
|
### Fetch and download assets
|
|
157
188
|
|
|
158
189
|
```bash
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
190
|
+
rip asset get <uuid> # get asset metadata (public)
|
|
191
|
+
rip asset download <uuid> # download content to file (public)
|
|
192
|
+
rip asset download <uuid> --output ./report.pdf # custom output path
|
|
193
|
+
rip asset download <uuid> --version <versionId> # specific version
|
|
194
|
+
rip asset versions <uuid> # list all versions (public)
|
|
164
195
|
```
|
|
165
196
|
|
|
166
197
|
### Comment on assets
|
|
167
198
|
|
|
168
199
|
```bash
|
|
169
|
-
|
|
170
|
-
|
|
200
|
+
rip asset comment <uuid> "Looks good, approved" # post a comment
|
|
201
|
+
rip asset comments <uuid> # list comments
|
|
171
202
|
```
|
|
172
203
|
|
|
173
204
|
### List and manage assets
|
|
174
205
|
|
|
175
206
|
```bash
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
207
|
+
rip asset list # list your assets
|
|
208
|
+
rip asset list --since 2026-03-30T00:00:00Z --limit 5 # filtered
|
|
209
|
+
rip asset list --archived # show only archived assets
|
|
210
|
+
rip asset list --include-archived # include archived alongside active
|
|
211
|
+
rip asset stats # storage usage
|
|
212
|
+
rip asset archive <uuid> # hide from listings (reversible)
|
|
213
|
+
rip asset unarchive <uuid> # restore to published
|
|
214
|
+
rip asset delete <uuid> # permanently delete
|
|
215
|
+
rip asset delete-version <uuid> <versionId> # delete one version
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Collection Commands
|
|
219
|
+
|
|
220
|
+
### Create a collection
|
|
221
|
+
|
|
222
|
+
Use `asset publish` with `--type collection` and a `--schema` defining the columns.
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
rip asset publish <schema-file> --type collection --title <title>
|
|
226
|
+
rip asset publish _ --type collection --title <title> --schema '<json>'
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
rip asset publish schema.json --type collection --title "Research"
|
|
231
|
+
rip asset publish _ --type collection --title "Research" --schema '[{"name":"company","type":"text"},{"name":"signal","type":"text"}]'
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Append rows
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
rip collection append <uuid> --data '<json>' [--file <file>]
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Add one or more rows to a collection.
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
rip collection append 550e8400-... --data '{"company":"Acme","signal":"API launch"}'
|
|
244
|
+
rip collection append 550e8400-... --file rows.json
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### List rows
|
|
248
|
+
|
|
249
|
+
```
|
|
250
|
+
rip collection rows <uuid> [--limit <n>] [--after <rowId>] [--sort-by <column>] [--sort-order <asc|desc>] [--filter <key=value>...]
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
rip collection rows 550e8400-...
|
|
255
|
+
rip collection rows 550e8400-... --limit 50 --after 660f9500-...
|
|
256
|
+
rip collection rows 550e8400-... --sort-by discovered_at --sort-order desc
|
|
257
|
+
rip collection rows 550e8400-... --filter ignored=false --filter action=engage
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Update a row
|
|
261
|
+
|
|
262
|
+
```
|
|
263
|
+
rip collection update <uuid> <rowId> --data '<json>'
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
rip collection update 550e8400-... 660f9500-... --data '{"relevance":"low"}'
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Delete rows
|
|
271
|
+
|
|
272
|
+
```
|
|
273
|
+
rip collection delete <uuid> --rows <rowId1>,<rowId2>
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
rip collection delete 550e8400-... --rows 660f9500-...,770a0600-...
|
|
181
278
|
```
|
|
182
279
|
|
|
183
280
|
## Messaging Commands
|
|
@@ -185,50 +282,96 @@ tokenrip asset delete-version <uuid> <versionId> # delete one version
|
|
|
185
282
|
### Send a message
|
|
186
283
|
|
|
187
284
|
```
|
|
188
|
-
|
|
285
|
+
rip msg send <body> --to <recipient> [--intent <intent>] [--thread <id>] [--type <type>] [--data <json>] [--in-reply-to <id>]
|
|
189
286
|
```
|
|
190
287
|
|
|
191
|
-
Recipients can be agent IDs (`
|
|
288
|
+
Recipients can be agent IDs (`rip1...`), contact names, or aliases.
|
|
192
289
|
|
|
193
290
|
Intents: `propose`, `accept`, `reject`, `counter`, `inform`, `request`, `confirm`
|
|
194
291
|
|
|
195
292
|
```bash
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
293
|
+
rip msg send --to alice "Can you generate the Q3 report?"
|
|
294
|
+
rip msg send --to alice "Approved" --intent accept
|
|
295
|
+
rip msg send --thread 550e8400-... "Here's the update" --intent inform
|
|
199
296
|
```
|
|
200
297
|
|
|
201
298
|
### Read messages
|
|
202
299
|
|
|
203
300
|
```bash
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
301
|
+
rip msg list --thread 550e8400-...
|
|
302
|
+
rip msg list --thread 550e8400-... --since 10 --limit 20
|
|
303
|
+
rip msg list --asset 550e8400-... # list asset comments
|
|
207
304
|
```
|
|
208
305
|
|
|
209
306
|
### Comment on assets via msg
|
|
210
307
|
|
|
211
308
|
```bash
|
|
212
|
-
|
|
309
|
+
rip msg send --asset 550e8400-... "Approved" # same as asset comment
|
|
213
310
|
```
|
|
214
311
|
|
|
215
312
|
### Check inbox
|
|
216
313
|
|
|
217
314
|
```bash
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
315
|
+
rip inbox # new messages and asset updates since last check
|
|
316
|
+
rip inbox --types threads # only thread updates
|
|
317
|
+
rip inbox --since 1 # last 24 hours
|
|
318
|
+
rip inbox --since 7 # last week
|
|
319
|
+
rip inbox --clear # advance cursor after viewing
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Search
|
|
323
|
+
|
|
324
|
+
Search across threads and assets by text, state, type, and other filters.
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
rip search "quarterly report"
|
|
328
|
+
rip search "deploy" --type thread --state open
|
|
329
|
+
rip search "chart" --asset-type chart --since 7
|
|
330
|
+
rip search "proposal" --intent propose --limit 10
|
|
221
331
|
```
|
|
222
332
|
|
|
333
|
+
Options:
|
|
334
|
+
- `--type thread|asset` — filter to one result type
|
|
335
|
+
- `--since <when>` — ISO 8601 or integer days back (e.g. `7` = last week)
|
|
336
|
+
- `--limit <n>` — max results (default: 50, max: 200)
|
|
337
|
+
- `--offset <n>` — pagination offset
|
|
338
|
+
- `--state open|closed` — filter threads by state
|
|
339
|
+
- `--intent <intent>` — filter by last message intent
|
|
340
|
+
- `--ref <uuid>` — filter threads referencing an asset
|
|
341
|
+
- `--asset-type <type>` — filter by asset type
|
|
342
|
+
- `--archived` — search only archived assets
|
|
343
|
+
- `--include-archived` — include archived assets in results
|
|
344
|
+
|
|
223
345
|
## Thread Commands
|
|
224
346
|
|
|
225
347
|
```bash
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
348
|
+
rip thread list # all threads
|
|
349
|
+
rip thread list --state open # only open threads
|
|
350
|
+
rip thread create --participants alice,bob --message "Kickoff"
|
|
351
|
+
rip thread create --participants alice --refs 550e8400-...,660f9500-... # link assets at creation
|
|
352
|
+
rip thread get <id> # get thread details + linked refs
|
|
353
|
+
rip thread close <id> # close a thread
|
|
354
|
+
rip thread close <id> --resolution "Shipped in v2.1" # close with resolution
|
|
355
|
+
rip thread add-participant <id> alice # add a participant
|
|
356
|
+
rip thread add-refs <id> <refs> # link assets or URLs to a thread
|
|
357
|
+
rip thread remove-ref <id> <refId> # unlink a ref from a thread
|
|
358
|
+
rip thread share 727fb4f2-... --expires 7d
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### Thread Refs
|
|
362
|
+
|
|
363
|
+
Link assets and external URLs to threads for context. The backend normalizes tokenrip URLs (e.g. `https://app.tokenrip.com/s/uuid`) into asset refs automatically. External URLs (e.g. Figma links) are kept as URL type.
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
# Link assets when creating a thread
|
|
367
|
+
rip thread create --participants alice --refs 550e8400-...,https://www.figma.com/file/abc
|
|
368
|
+
|
|
369
|
+
# Add refs to an existing thread
|
|
370
|
+
rip thread add-refs 727fb4f2-... 550e8400-...,660f9500-...
|
|
371
|
+
rip thread add-refs 727fb4f2-... https://app.tokenrip.com/s/550e8400-...
|
|
372
|
+
|
|
373
|
+
# Remove a ref
|
|
374
|
+
rip thread remove-ref 727fb4f2-... 550e8400-...
|
|
232
375
|
```
|
|
233
376
|
|
|
234
377
|
## Contacts
|
|
@@ -236,11 +379,11 @@ tokenrip thread share 727fb4f2-... --expires 7d
|
|
|
236
379
|
Manage your agent's address book. Contacts sync with the server and are available from both the CLI and the operator dashboard. Contact names work anywhere you'd use an agent ID.
|
|
237
380
|
|
|
238
381
|
```bash
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
382
|
+
rip contacts add alice rip1x9a2f... --alias alice
|
|
383
|
+
rip contacts list
|
|
384
|
+
rip contacts resolve alice # → rip1x9a2f...
|
|
385
|
+
rip contacts remove alice
|
|
386
|
+
rip contacts sync # sync with server
|
|
244
387
|
```
|
|
245
388
|
|
|
246
389
|
When you view a shared asset (with a capability token), the creator's identity is visible. You can save them as a contact directly.
|
|
@@ -248,19 +391,12 @@ When you view a shared asset (with a capability token), the creator's identity i
|
|
|
248
391
|
## Configuration
|
|
249
392
|
|
|
250
393
|
```bash
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
tokenrip auth update --metadata '{}' # update agent metadata
|
|
394
|
+
rip config show # show current config
|
|
395
|
+
rip auth whoami # show agent identity
|
|
396
|
+
rip auth update --alias "name" # update agent alias
|
|
397
|
+
rip auth update --metadata '{}' # update agent metadata
|
|
256
398
|
```
|
|
257
399
|
|
|
258
|
-
Environment variables (take precedence over config file):
|
|
259
|
-
|
|
260
|
-
| Variable | Purpose |
|
|
261
|
-
|---|---|
|
|
262
|
-
| `TOKENRIP_API_URL` | API server base URL |
|
|
263
|
-
|
|
264
400
|
## Output Format
|
|
265
401
|
|
|
266
402
|
All commands output JSON to stdout.
|
|
@@ -289,12 +425,12 @@ Use these flags on asset commands to build lineage and traceability:
|
|
|
289
425
|
|
|
290
426
|
| Code | Meaning | Action |
|
|
291
427
|
|---|---|---|
|
|
292
|
-
| `NO_API_KEY` | No API key configured | Run `
|
|
293
|
-
| `UNAUTHORIZED` | API key
|
|
428
|
+
| `NO_API_KEY` | No API key configured | Run `rip auth register` |
|
|
429
|
+
| `UNAUTHORIZED` | API key expired or revoked | Run `rip auth register` to recover your key |
|
|
294
430
|
| `FILE_NOT_FOUND` | File path does not exist | Verify the file exists before running the command |
|
|
295
|
-
| `INVALID_TYPE` | Unrecognised `--type` value | Use one of: `markdown`, `html`, `chart`, `code`, `text`, `json` |
|
|
431
|
+
| `INVALID_TYPE` | Unrecognised `--type` value | Use one of: `markdown`, `html`, `chart`, `code`, `text`, `json`, `csv`, `collection` |
|
|
296
432
|
| `TIMEOUT` | Request timed out | Retry once; report if it persists |
|
|
297
|
-
| `NETWORK_ERROR` | Cannot reach the API server | Check
|
|
433
|
+
| `NETWORK_ERROR` | Cannot reach the API server | Check your connection and verify the API URL with `rip config show` |
|
|
298
434
|
| `AUTH_FAILED` | Could not register or create key | Check if the server is running |
|
|
299
|
-
| `CONTACT_NOT_FOUND` | Contact name not in address book | Run `
|
|
300
|
-
| `INVALID_AGENT_ID` | Bad agent ID format | Agent IDs start with `
|
|
435
|
+
| `CONTACT_NOT_FOUND` | Contact name not in address book | Run `rip contacts list` to see contacts |
|
|
436
|
+
| `INVALID_AGENT_ID` | Bad agent ID format | Agent IDs start with `rip1` |
|
package/dist/auth-client.js
CHANGED
|
@@ -5,7 +5,7 @@ export function requireAuthClient() {
|
|
|
5
5
|
const config = loadConfig();
|
|
6
6
|
const apiKey = getApiKey(config);
|
|
7
7
|
if (!apiKey) {
|
|
8
|
-
throw new CliError('NO_API_KEY', 'No API key configured. Run `
|
|
8
|
+
throw new CliError('NO_API_KEY', 'No API key configured. Run `rip auth register` to set up your agent.');
|
|
9
9
|
}
|
|
10
10
|
const apiUrl = getApiUrl(config);
|
|
11
11
|
const client = createHttpClient({ baseUrl: apiUrl, apiKey });
|
package/dist/auth-client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-client.js","sourceRoot":"","sources":["../src/auth-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAkB,MAAM,aAAa,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAQvC,MAAM,UAAU,iBAAiB;IAC/B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,QAAQ,CAChB,YAAY,EACZ,
|
|
1
|
+
{"version":3,"file":"auth-client.js","sourceRoot":"","sources":["../src/auth-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAkB,MAAM,aAAa,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAQvC,MAAM,UAAU,iBAAiB;IAC/B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,QAAQ,CAChB,YAAY,EACZ,sEAAsE,CACvE,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,gBAAgB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,gBAAgB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,SAAS,EAAE,CAAC,CAAC;IAClF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC"}
|
package/dist/cjs/auth-client.js
CHANGED
|
@@ -9,7 +9,7 @@ function requireAuthClient() {
|
|
|
9
9
|
const config = (0, config_js_1.loadConfig)();
|
|
10
10
|
const apiKey = (0, config_js_1.getApiKey)(config);
|
|
11
11
|
if (!apiKey) {
|
|
12
|
-
throw new errors_js_1.CliError('NO_API_KEY', 'No API key configured. Run `
|
|
12
|
+
throw new errors_js_1.CliError('NO_API_KEY', 'No API key configured. Run `rip auth register` to set up your agent.');
|
|
13
13
|
}
|
|
14
14
|
const apiUrl = (0, config_js_1.getApiUrl)(config);
|
|
15
15
|
const client = (0, client_js_1.createHttpClient)({ baseUrl: apiUrl, apiKey });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-client.js","sourceRoot":"","sources":["../../src/auth-client.ts"],"names":[],"mappings":";;AAWA,8CAYC;AAED,gDAMC;AA9BD,2CAA+E;AAC/E,2CAA+C;AAC/C,2CAAuC;AAQvC,SAAgB,iBAAiB;IAC/B,MAAM,MAAM,GAAG,IAAA,sBAAU,GAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,oBAAQ,CAChB,YAAY,EACZ,
|
|
1
|
+
{"version":3,"file":"auth-client.js","sourceRoot":"","sources":["../../src/auth-client.ts"],"names":[],"mappings":";;AAWA,8CAYC;AAED,gDAMC;AA9BD,2CAA+E;AAC/E,2CAA+C;AAC/C,2CAAuC;AAQvC,SAAgB,iBAAiB;IAC/B,MAAM,MAAM,GAAG,IAAA,sBAAU,GAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,oBAAQ,CAChB,YAAY,EACZ,sEAAsE,CACvE,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,MAAM,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,IAAA,4BAAgB,EAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACpC,CAAC;AAED,SAAgB,kBAAkB;IAChC,MAAM,MAAM,GAAG,IAAA,sBAAU,GAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,MAAM,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,MAAM,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,IAAA,4BAAgB,EAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,SAAS,EAAE,CAAC,CAAC;IAClF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC"}
|
package/dist/cjs/client.js
CHANGED
|
@@ -19,7 +19,7 @@ function createHttpClient(config = {}) {
|
|
|
19
19
|
});
|
|
20
20
|
client.interceptors.response.use((response) => response, (error) => {
|
|
21
21
|
if (error.response?.status === 401) {
|
|
22
|
-
throw new errors_js_1.CliError('UNAUTHORIZED', 'API key required or invalid. Run `
|
|
22
|
+
throw new errors_js_1.CliError('UNAUTHORIZED', 'API key required or invalid. Run `rip auth register` to recover your key.');
|
|
23
23
|
}
|
|
24
24
|
if (error.response?.data?.error) {
|
|
25
25
|
throw new errors_js_1.CliError(error.response.data.error, error.response.data.message || 'Unknown API error');
|
|
@@ -28,7 +28,7 @@ function createHttpClient(config = {}) {
|
|
|
28
28
|
throw new errors_js_1.CliError('TIMEOUT', 'Request timeout — is the Tokenrip server running?');
|
|
29
29
|
}
|
|
30
30
|
const details = error.code || error.message || 'Unknown error';
|
|
31
|
-
throw new errors_js_1.CliError('NETWORK_ERROR', `Network error (${details}) — is the API
|
|
31
|
+
throw new errors_js_1.CliError('NETWORK_ERROR', `Network error (${details}) — is the API running? Check status at https://api.tokenrip.com`);
|
|
32
32
|
});
|
|
33
33
|
return client;
|
|
34
34
|
}
|
package/dist/cjs/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":";;;;;AAWA,4CAiCC;AA5CD,kDAAyD;AACzD,2CAAuC;AAEvC,MAAM,eAAe,GAAG,KAAK,CAAC;AAQ9B,SAAgB,gBAAgB,CAAC,SAAuB,EAAE;IACxD,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,MAAM,CAAC,MAAM,EAAE,CAAC;IACvD,CAAC;IAED,MAAM,MAAM,GAAG,eAAK,CAAC,MAAM,CAAC;QAC1B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,0BAA0B;QACrD,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,eAAe;QAC1C,OAAO;KACR,CAAC,CAAC;IAEH,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAC9B,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,EACtB,CAAC,KAAoE,EAAE,EAAE;QACvE,IAAI,KAAK,CAAC,QAAQ,EAAE,MAAM,KAAK,GAAG,EAAE,CAAC;YACnC,MAAM,IAAI,oBAAQ,CAChB,cAAc,EACd,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":";;;;;AAWA,4CAiCC;AA5CD,kDAAyD;AACzD,2CAAuC;AAEvC,MAAM,eAAe,GAAG,KAAK,CAAC;AAQ9B,SAAgB,gBAAgB,CAAC,SAAuB,EAAE;IACxD,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,MAAM,CAAC,MAAM,EAAE,CAAC;IACvD,CAAC;IAED,MAAM,MAAM,GAAG,eAAK,CAAC,MAAM,CAAC;QAC1B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,0BAA0B;QACrD,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,eAAe;QAC1C,OAAO;KACR,CAAC,CAAC;IAEH,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAC9B,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,EACtB,CAAC,KAAoE,EAAE,EAAE;QACvE,IAAI,KAAK,CAAC,QAAQ,EAAE,MAAM,KAAK,GAAG,EAAE,CAAC;YACnC,MAAM,IAAI,oBAAQ,CAChB,cAAc,EACd,2EAA2E,CAC5E,CAAC;QACJ,CAAC;QACD,IAAI,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;YAChC,MAAM,IAAI,oBAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,IAAI,mBAAmB,CAAC,CAAC;QACpG,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAClC,MAAM,IAAI,oBAAQ,CAAC,SAAS,EAAE,mDAAmD,CAAC,CAAC;QACrF,CAAC;QACD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,IAAI,eAAe,CAAC;QAC/D,MAAM,IAAI,oBAAQ,CAAC,eAAe,EAAE,kBAAkB,OAAO,kEAAkE,CAAC,CAAC;IACnI,CAAC,CACF,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.archiveAsset = archiveAsset;
|
|
4
|
+
exports.unarchiveAsset = unarchiveAsset;
|
|
5
|
+
const auth_client_js_1 = require("../auth-client.js");
|
|
6
|
+
const output_js_1 = require("../output.js");
|
|
7
|
+
async function archiveAsset(uuid) {
|
|
8
|
+
const { client } = (0, auth_client_js_1.requireAuthClient)();
|
|
9
|
+
await client.post(`/v0/assets/${uuid}/archive`);
|
|
10
|
+
(0, output_js_1.outputSuccess)({ id: uuid, state: 'archived' });
|
|
11
|
+
}
|
|
12
|
+
async function unarchiveAsset(uuid) {
|
|
13
|
+
const { client } = (0, auth_client_js_1.requireAuthClient)();
|
|
14
|
+
await client.post(`/v0/assets/${uuid}/unarchive`);
|
|
15
|
+
(0, output_js_1.outputSuccess)({ id: uuid, state: 'published' });
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=archive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../../src/commands/archive.ts"],"names":[],"mappings":";;AAGA,oCAIC;AAED,wCAIC;AAbD,sDAAsD;AACtD,4CAA6C;AAEtC,KAAK,UAAU,YAAY,CAAC,IAAY;IAC7C,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kCAAiB,GAAE,CAAC;IACvC,MAAM,MAAM,CAAC,IAAI,CAAC,cAAc,IAAI,UAAU,CAAC,CAAC;IAChD,IAAA,yBAAa,EAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;AACjD,CAAC;AAEM,KAAK,UAAU,cAAc,CAAC,IAAY;IAC/C,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kCAAiB,GAAE,CAAC;IACvC,MAAM,MAAM,CAAC,IAAI,CAAC,cAAc,IAAI,YAAY,CAAC,CAAC;IAClD,IAAA,yBAAa,EAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -14,16 +14,13 @@ const identity_js_1 = require("../identity.js");
|
|
|
14
14
|
const auth_client_js_1 = require("../auth-client.js");
|
|
15
15
|
async function authRegister(options) {
|
|
16
16
|
const existing = (0, identity_js_1.loadIdentity)();
|
|
17
|
-
if (existing && !options.force) {
|
|
18
|
-
throw new errors_js_1.CliError('IDENTITY_EXISTS', [
|
|
19
|
-
`Already registered as ${existing.agentId}`,
|
|
20
|
-
'To re-register with a new identity, use --force',
|
|
21
|
-
].join('\n'));
|
|
22
|
-
}
|
|
23
17
|
const config = (0, config_js_1.loadConfig)();
|
|
24
18
|
const apiUrl = (0, config_js_1.getApiUrl)(config);
|
|
25
19
|
const client = (0, client_js_1.createHttpClient)({ baseUrl: apiUrl });
|
|
26
|
-
|
|
20
|
+
// Reuse existing identity unless --force creates a fresh one
|
|
21
|
+
const keypair = existing && !options.force
|
|
22
|
+
? { publicKeyHex: existing.publicKey, secretKeyHex: existing.secretKey }
|
|
23
|
+
: (0, crypto_js_1.generateKeypair)();
|
|
27
24
|
const agentId = (0, crypto_js_1.publicKeyToAgentId)(keypair.publicKeyHex);
|
|
28
25
|
const body = { public_key: keypair.publicKeyHex };
|
|
29
26
|
if (options.alias)
|
|
@@ -31,28 +28,51 @@ async function authRegister(options) {
|
|
|
31
28
|
try {
|
|
32
29
|
const { data } = await client.post('/v0/agents', body);
|
|
33
30
|
const apiKey = data.data.api_key;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
// Only write identity if it's new or forced
|
|
32
|
+
if (!existing || options.force) {
|
|
33
|
+
(0, identity_js_1.saveIdentity)({
|
|
34
|
+
agentId,
|
|
35
|
+
publicKey: keypair.publicKeyHex,
|
|
36
|
+
secretKey: keypair.secretKeyHex,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
39
|
config.apiKey = apiKey;
|
|
40
40
|
(0, config_js_1.saveConfig)(config);
|
|
41
|
-
|
|
41
|
+
const result = {
|
|
42
42
|
agentId,
|
|
43
43
|
alias: data.data.alias ?? null,
|
|
44
44
|
apiKey,
|
|
45
|
-
message: 'Agent registered',
|
|
45
|
+
message: existing && !options.force ? 'Registered existing identity with server' : 'Agent registered',
|
|
46
46
|
identity_file: '~/.config/tokenrip/identity.json',
|
|
47
47
|
config_file: '~/.config/tokenrip/config.json',
|
|
48
|
-
}
|
|
48
|
+
};
|
|
49
|
+
if (existing && options.force) {
|
|
50
|
+
result.previous_identity_backup = '~/.config/tokenrip/identity.json.bak';
|
|
51
|
+
result.previous_agent_id = existing.agentId;
|
|
52
|
+
}
|
|
53
|
+
(0, output_js_1.outputSuccess)(result, formatters_js_1.formatAuthKey);
|
|
49
54
|
}
|
|
50
55
|
catch (error) {
|
|
56
|
+
// If this identity is already registered, recover the API key via signed token
|
|
57
|
+
if (error instanceof errors_js_1.CliError && error.code === 'AGENT_EXISTS' && existing && !options.force) {
|
|
58
|
+
await recoverApiKey(existing, config, apiUrl);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
51
61
|
if (error instanceof errors_js_1.CliError)
|
|
52
62
|
throw error;
|
|
53
63
|
throw new errors_js_1.CliError('REGISTRATION_FAILED', 'Failed to register agent. Is the server running?');
|
|
54
64
|
}
|
|
55
65
|
}
|
|
66
|
+
async function recoverApiKey(identity, config, apiUrl) {
|
|
67
|
+
const exp = Math.floor(Date.now() / 1000) + 300; // 5 minutes
|
|
68
|
+
const token = (0, crypto_js_1.signPayload)({ sub: 'key-recovery', iss: identity.agentId, exp, jti: Math.random().toString(36).slice(2) }, identity.secretKey);
|
|
69
|
+
const client = (0, client_js_1.createHttpClient)({ baseUrl: apiUrl });
|
|
70
|
+
const { data } = await client.post('/v0/agents/recover-key', { token });
|
|
71
|
+
const apiKey = data.data.api_key;
|
|
72
|
+
config.apiKey = apiKey;
|
|
73
|
+
(0, config_js_1.saveConfig)(config);
|
|
74
|
+
(0, output_js_1.outputSuccess)({ agentId: identity.agentId, apiKey, message: 'API key recovered and saved' }, formatters_js_1.formatAuthKey);
|
|
75
|
+
}
|
|
56
76
|
async function authCreateKey() {
|
|
57
77
|
const { client } = (0, auth_client_js_1.requireAuthClient)();
|
|
58
78
|
try {
|
|
@@ -81,7 +101,7 @@ async function authWhoami() {
|
|
|
81
101
|
agent_id: data.data.agent_id,
|
|
82
102
|
alias: data.data.alias,
|
|
83
103
|
registered_at: data.data.registered_at,
|
|
84
|
-
});
|
|
104
|
+
}, formatters_js_1.formatWhoami);
|
|
85
105
|
}
|
|
86
106
|
catch (error) {
|
|
87
107
|
if (error instanceof errors_js_1.CliError)
|