@tinycloud/cli 1.5.0-beta.9 → 1.5.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/README.md +479 -103
- package/bin/tinycloud +9 -0
- package/dist/courier-entry.js +10179 -503
- package/dist/courier-entry.js.map +1 -1
- package/dist/index.js +1877 -101
- package/dist/index.js.map +1 -1
- package/dist/legacy-entry.js +6279 -2752
- package/dist/legacy-entry.js.map +1 -1
- package/package.json +10 -10
- package/skills/courier/SKILL.md +21 -0
- package/skills/courier/start.md +17 -0
- package/skills/{tc-cli → tinycloud-cli}/AUTH.md +23 -27
- package/skills/tinycloud-cli/INSTALL.md +36 -0
- package/skills/{tc-cli → tinycloud-cli}/REFERENCE.md +117 -97
- package/skills/{tc-cli → tinycloud-cli}/SDK.md +1 -1
- package/skills/{tc-cli → tinycloud-cli}/SKILL.md +34 -48
- package/skills/{tc-cli → tinycloud-cli}/release.json +1 -1
- package/skills/tc-cli/INSTALL.md +0 -35
package/README.md
CHANGED
|
@@ -1,51 +1,50 @@
|
|
|
1
1
|
# @tinycloud/cli
|
|
2
2
|
|
|
3
|
-
Self-sovereign storage from the terminal. `
|
|
3
|
+
Self-sovereign storage from the terminal. `tinycloud` is the command-line interface for [TinyCloud](https://tinycloud.xyz) — manage data, delegations, spaces, and nodes without leaving your shell.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install -g @tinycloud/cli
|
|
8
|
+
npm install -g @tinycloud/cli@1.5.0-beta.20
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
Requires Node.js >= 20.
|
|
11
|
+
Requires Node.js >= 20; TinyCloud's agent guides use Node.js 22.20 or later.
|
|
12
|
+
Agents: start at https://agents.tinycloud.xyz/onboarding.
|
|
12
13
|
|
|
13
|
-
The package
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
install. Run `hash -r` if `tc` already ran in the same shell. Verify with
|
|
20
|
-
`command -v tc`, or call `"$(npm prefix --global)/bin/tc"` when in doubt.
|
|
14
|
+
The package exposes `tinycloud` as its preferred command and keeps `tc` as a
|
|
15
|
+
deprecated compatibility alias at the same entry. Both names accept the same
|
|
16
|
+
commands and flags, with identical exit codes and stdout. A POSIX `tc` executable
|
|
17
|
+
link emits one deprecation notice on stderr, never stdout. On Linux,
|
|
18
|
+
`/usr/sbin/tc` is iproute2's traffic-control tool. Verify the pinned install
|
|
19
|
+
with `tinycloud --version`.
|
|
21
20
|
|
|
22
21
|
## Agent skills
|
|
23
22
|
|
|
24
|
-
The package ships the general `
|
|
25
|
-
`skills/
|
|
26
|
-
See [skill installation](skills/
|
|
27
|
-
pinned, cross-agent installation
|
|
28
|
-
[authentication](skills/
|
|
23
|
+
The package ships the general `tinycloud-cli` skill and its references in
|
|
24
|
+
`skills/tinycloud-cli`, and the `courier` skill for `tinycloud courier` in `skills/courier`.
|
|
25
|
+
See [skill installation](skills/tinycloud-cli/INSTALL.md) for a
|
|
26
|
+
pinned, cross-agent installation for any agent, and
|
|
27
|
+
[authentication](skills/tinycloud-cli/AUTH.md) for device login and relaying the
|
|
29
28
|
approval code to the owner.
|
|
30
29
|
|
|
31
30
|
## Courier
|
|
32
31
|
|
|
33
|
-
`
|
|
32
|
+
`tinycloud courier …` runs [Courier](https://github.com/TinyCloudLabs/js-sdk/tree/master/packages/courier#readme), agent-to-agent threads
|
|
34
33
|
over TinyCloud, bundled from `@tinycloud/courier` (beta). It takes the same
|
|
35
34
|
arguments as the standalone `courier` bin and keeps its own agent identity in
|
|
36
|
-
`$COURIER_HOME` (default `~/.courier`), not in a
|
|
35
|
+
`$COURIER_HOME` (default `~/.courier`), not in a tinycloud profile, so put every flag
|
|
37
36
|
after `courier`:
|
|
38
37
|
|
|
39
38
|
```bash
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
tinycloud courier init --paste --handle alice # the owner approves in OpenKey; paste the XXXX-XXXX code
|
|
40
|
+
tinycloud courier inbox
|
|
41
|
+
tinycloud courier --help
|
|
43
42
|
```
|
|
44
43
|
|
|
45
44
|
## Operations coverage
|
|
46
45
|
|
|
47
|
-
The migrated `
|
|
48
|
-
uses delegated authority by default. `
|
|
46
|
+
The migrated `tinycloud secrets get` path is owned by `@tinycloud/operations` and
|
|
47
|
+
uses delegated authority by default. `tinycloud auth import` is partially migrated:
|
|
49
48
|
the request-bound active-session v1 path is canonical, while legacy delegation
|
|
50
49
|
and permission input forms remain Commander-owned. The complete registration
|
|
51
50
|
ledger is checked in `../operations/coverage.json` and checked against the
|
|
@@ -61,104 +60,471 @@ fallback for delegated execution.
|
|
|
61
60
|
|
|
62
61
|
```bash
|
|
63
62
|
# Set up a profile and generate keys
|
|
64
|
-
|
|
63
|
+
tinycloud init
|
|
65
64
|
|
|
66
65
|
# Authenticate via browser
|
|
67
|
-
|
|
66
|
+
tinycloud auth login
|
|
68
67
|
|
|
69
68
|
# Authenticate on a remote/headless machine: the owner approves an explicit
|
|
70
69
|
# manifest on their phone (URL + code printed to stderr). Use a new profile
|
|
71
70
|
# name if it already exists; keep the user's existing profiles.
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
tinycloud init --name publisher --key-only
|
|
72
|
+
tinycloud --profile publisher auth login --device --manifest builtin:share-publishing
|
|
74
73
|
|
|
75
74
|
# Same Share publishing scope, as a shortcut (on the dedicated profile)
|
|
76
|
-
|
|
75
|
+
tinycloud --profile publisher enable share
|
|
77
76
|
|
|
78
77
|
# Selected profile, owner, host and space (JSON; does not test access)
|
|
79
|
-
|
|
78
|
+
tinycloud context
|
|
80
79
|
|
|
81
80
|
# Store and retrieve data
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
tinycloud kv put greeting "Hello, world"
|
|
82
|
+
tinycloud kv get greeting
|
|
83
|
+
tinycloud kv list
|
|
85
84
|
|
|
86
85
|
# Manage network-encrypted secrets on the default network
|
|
87
|
-
|
|
88
|
-
printf '%s' "$ANTHROPIC_API_KEY" |
|
|
89
|
-
|
|
86
|
+
tinycloud secrets network init
|
|
87
|
+
printf '%s' "$ANTHROPIC_API_KEY" | tinycloud secrets put ANTHROPIC_API_KEY --stdin
|
|
88
|
+
tinycloud secrets get ANTHROPIC_API_KEY
|
|
89
|
+
tinycloud secrets run ANTHROPIC_API_KEY -- python train.py # the value only in the command's environment
|
|
90
90
|
|
|
91
91
|
# Ask the owner for a secret an agent needs, then wait for it
|
|
92
|
-
# (call TinyCloud's CLI by absolute path: a bare
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
"$TC_BIN" --profile agent secrets wait OPENAI_API_KEY --timeout 9m --json # 0 ready, 8 pending
|
|
92
|
+
# (call TinyCloud's CLI by absolute path when using tc: a bare tc can be iproute2's /usr/sbin/tc)
|
|
93
|
+
tinycloud --profile agent secrets request OPENAI_API_KEY --json # offline; prints the owner's link
|
|
94
|
+
tinycloud --profile agent secrets wait OPENAI_API_KEY --timeout 9m --json # 0 ready, 8 pending
|
|
96
95
|
|
|
97
96
|
# Manage spaces
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
tinycloud space list
|
|
98
|
+
tinycloud space create
|
|
100
99
|
|
|
101
100
|
# Grant access to another user
|
|
102
|
-
|
|
101
|
+
tinycloud delegation create --to did:pkh:eip155:1:0x...
|
|
103
102
|
```
|
|
104
103
|
|
|
104
|
+
## Home feed
|
|
105
|
+
|
|
106
|
+
`tinycloud feed` uses separate owner-provisioned SQLite databases for each agent's
|
|
107
|
+
cards/handling and the owner's append-only responses. Owner registry and view
|
|
108
|
+
state live separately. SDK consumers use the same contract from
|
|
109
|
+
`@tinycloud/sdk-services/feed` with existing SQL database handles; see the
|
|
110
|
+
[canonical types](../sdk-services/src/feed/types.ts).
|
|
111
|
+
|
|
112
|
+
Use an authenticated **owner-openkey or local-owner-key** profile for `connect`.
|
|
113
|
+
That owner needs SQL read/write/schema authority for
|
|
114
|
+
`xyz.tinycloud.tinychat/home_feed` and the `xyz.tinycloud.tinychat/feed/`
|
|
115
|
+
namespace, plus authority to delegate the exact agent grants below. The trailing
|
|
116
|
+
slash denotes a database namespace, not an individual database.
|
|
117
|
+
|
|
118
|
+
Create a separate agent profile and set `AGENT_DID` to its printed DID. Use the
|
|
119
|
+
same node as the owner:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
tinycloud profile create feed-agent --posture delegate-session --operator agent
|
|
123
|
+
tinycloud --profile owner feed connect --agent writer --to "$AGENT_DID" --label Writer \
|
|
124
|
+
--space applications > feed-grant.json
|
|
125
|
+
tinycloud --profile feed-agent auth import feed-grant.json
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
`connect` reserves a stable token/DID/resource binding, provisions both schemas,
|
|
129
|
+
and activates one bundled delegation through the existing SDK. It registers
|
|
130
|
+
actual grant provenance only after activation; a failed activation may be
|
|
131
|
+
retried with the same DID and resources. The agent receives read/write on
|
|
132
|
+
`xyz.tinycloud.tinychat/feed/feed_output_writer`, read on
|
|
133
|
+
`xyz.tinycloud.tinychat/feed/feed_responses_writer`, and hook subscription on
|
|
134
|
+
`sql/xyz.tinycloud.tinychat/feed/feed_responses_writer`. Agents do not receive
|
|
135
|
+
response-write or schema authority. Display labels and tokens select resources;
|
|
136
|
+
the signed grants determine access.
|
|
137
|
+
|
|
138
|
+
Publish `card.json` from the agent profile:
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{"cardId":"card-draft-01","revision":1,"issuanceId":"issuance-draft-01","kind":"decision","needsResponse":true,"title":"Create draft?","body":"Create a reversible draft only.","choices":[{"id":"create","label":"Create draft"}],"urgency":1,"createdAt":"2026-10-29T00:00:00Z"}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
tinycloud --profile feed-agent feed publish --agent writer --file card.json
|
|
146
|
+
tinycloud --profile feed-agent feed watch --agent writer --recipient agent-runtime \
|
|
147
|
+
--runner '["node","agent-handler.js"]'
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Run `watch` in the agent terminal, then save `response.json` from the owner
|
|
151
|
+
profile in another terminal, or answer the card through Home:
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{"responseId":"response-draft-01","cardId":"card-draft-01","revision":1,"issuanceId":"issuance-draft-01","kind":"answer","choiceId":"create","createdAt":"2026-10-29T00:01:00Z"}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
tinycloud --profile owner feed respond --agent writer --file response.json
|
|
159
|
+
tinycloud --profile feed-agent feed responses --agent writer --after 0
|
|
160
|
+
tinycloud --profile feed-agent feed handling --agent writer --file handling.json
|
|
161
|
+
tinycloud --profile owner feed show card-draft-01 --agent writer
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
For an explicit outbound note to that agent, save a separate `message.json`:
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{"responseId":"message-draft-01","cardId":"card-draft-01","revision":1,"issuanceId":"issuance-draft-01","kind":"message","text":"Please explain the draft before I answer.","createdAt":"2026-10-29T00:02:00Z"}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
tinycloud --profile owner feed message --agent writer --file message.json
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Messages also work on information cards with `needsResponse: false`. They do not
|
|
175
|
+
answer a card, clear Needs action, or replace its current answer or handling.
|
|
176
|
+
`choiceId` and `supersedesResponseId` are refused on messages. Agent response pages
|
|
177
|
+
and watch include messages, with acknowledgements/outcomes tied to their own full
|
|
178
|
+
response IDs. Private owner notes, task ticks, and seen state remain owner-only
|
|
179
|
+
registry data; they are not outbound messages.
|
|
180
|
+
|
|
181
|
+
For a new response with private structured data, `payload.json` is a versioned
|
|
182
|
+
JSON envelope, for example:
|
|
183
|
+
|
|
184
|
+
```json
|
|
185
|
+
{"type":"example.private-action","version":1,"data":{"code":"SYNTHETIC-ONLY"}}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Include it on the **first** save, instead of the plain `respond` command above:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
tinycloud --profile owner feed respond --agent writer --file response.json --payload-file payload.json
|
|
192
|
+
tinycloud --profile feed-agent feed payload --agent writer --response response-draft-01 \
|
|
193
|
+
--card card-draft-01 --revision 1 --issuance issuance-draft-01
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
The header and payload commit atomically in the same owner-response database.
|
|
197
|
+
Retries of the same response ID must include the same header and payload; a
|
|
198
|
+
changed, omitted, or later-added payload is refused. `feed payload` verifies the
|
|
199
|
+
full response/card/revision/issuance identity, returning its envelope, or `null`
|
|
200
|
+
for a known response without a payload. Unknown or mismatched identities fail.
|
|
201
|
+
Keep approval codes in `payload.data`, never the normal response text.
|
|
202
|
+
|
|
203
|
+
Default `list`, `show`, `responses`, and `watch` output contains only response
|
|
204
|
+
headers and optional `payloadType`/`payloadVersion` metadata, not payload data.
|
|
205
|
+
The SDK equivalents are the optional fourth `appendFeedResponse` or
|
|
206
|
+
`appendFeedMessage` argument and the explicit `readFeedResponsePayload` method.
|
|
207
|
+
`feed message` accepts the same `--payload-file` option on its first save.
|
|
208
|
+
Owner schema initialization adds `feed_response_payloads`; existing response-read
|
|
209
|
+
authority also authorizes an explicit payload read. “Private” here means excluded
|
|
210
|
+
from notification copies, not a new authorization boundary against an agent already
|
|
211
|
+
granted database read.
|
|
212
|
+
|
|
213
|
+
`readFeedResponseHandling(output, identity)` reads acknowledgement and outcome for
|
|
214
|
+
one full response/card/revision/issuance identity, including historical answers or
|
|
215
|
+
messages after later arrivals. Unknown or mismatched handling returns `NOT_FOUND`,
|
|
216
|
+
not a synthetic empty receipt. Known acknowledgement-only or outcome-only history
|
|
217
|
+
retains the other slot as `null`. `getFeedCardState` selects only the current
|
|
218
|
+
answer/follow-up; a saved answer without handling still has `null` receipt slots.
|
|
219
|
+
|
|
220
|
+
Retain the full response ID on a retry. Reusing it with different content is
|
|
221
|
+
refused. Responses bind the full card ID, revision, and issuance; corrections
|
|
222
|
+
are new follow-up records, optionally naming `supersedesResponseId`. Short card
|
|
223
|
+
references work only when unambiguous. Handling records carry their own
|
|
224
|
+
`handlingId`, the response/card identities, `createdAt`, and `phase`:
|
|
225
|
+
`acknowledged`, `succeeded`, or `failed`, with optional structured `detail`.
|
|
226
|
+
Acknowledgement history and the terminal outcome are retained independently.
|
|
227
|
+
|
|
228
|
+
**Saved, delivered, acknowledged, and completed are different states.**
|
|
229
|
+
The runner receives allowlisted response-header JSON and optional payload
|
|
230
|
+
type/version metadata on stdin through an argv array, never shell interpolation.
|
|
231
|
+
Exit zero must mean durable acceptance of that response ID, not completion of
|
|
232
|
+
its action. The agent publishes acknowledgement and outcome through `handling`.
|
|
233
|
+
|
|
234
|
+
`watch` requires **Bun or Node.js 22.13+** for its durable local SQLite ledger;
|
|
235
|
+
other commands keep the CLI's Node.js 20 requirement. By default the ledger is
|
|
236
|
+
stored under the selected profile; `--handoff` selects another durable file.
|
|
237
|
+
The listener subscribes before draining and reconciles on readiness, writes,
|
|
238
|
+
reconnects, and five-minute renewal, without a rapid idle query loop.
|
|
239
|
+
|
|
240
|
+
Before attempting a send, the ledger records `unconfirmed`. A crash, uncertain
|
|
241
|
+
runtime result, or interruption leaves that identity unconfirmed rather than
|
|
242
|
+
automatically sending again. A `prepared` record can resume only before an
|
|
243
|
+
attempt began. Ctrl-C/SIGTERM stops the watcher and forcibly terminates its
|
|
244
|
+
current runner; an already-started action may still have happened. Keep response
|
|
245
|
+
IDs as downstream idempotency keys where supported. Exactly-once external
|
|
246
|
+
execution is not promised.
|
|
247
|
+
|
|
248
|
+
### Prepared FORMAT1 owner import
|
|
249
|
+
|
|
250
|
+
`feed import` accepts an already-resolved FORMAT1 JSON bundle, not the raw snapshot
|
|
251
|
+
written by `feed export`. Supply the full target space explicitly:
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
tinycloud --profile owner feed import \
|
|
255
|
+
--space tinycloud:pkh:eip155:1:0x2222222222222222222222222222222222222222:applications \
|
|
256
|
+
--file ./prepared-owner-bundle.json
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
The authenticated owner needs SQL read/write/schema authority for
|
|
260
|
+
`xyz.tinycloud.tinychat/home_feed` and the registered per-agent database pairs.
|
|
261
|
+
The command initializes the owner archive and uses the canonical SDK to initialize
|
|
262
|
+
the current pair schemas. Agent response-read grants are insufficient. Import neither
|
|
263
|
+
registers agents nor broadens their grants.
|
|
264
|
+
|
|
265
|
+
Before writing, the importer validates versions, raw base64/SHA-256 proofs, full
|
|
266
|
+
source references and card/response identities. Publisher agent IDs, DIDs, and
|
|
267
|
+
resource pairs must match actual `feed_agents` rows and the canonical feed resource
|
|
268
|
+
convention, with distinct database basenames. Labels and stored provenance do not
|
|
269
|
+
replace signed node authority. The importer does not classify legacy data, choose
|
|
270
|
+
current answers, resolve recipient names, or recalculate expiry.
|
|
271
|
+
|
|
272
|
+
The complete prepared JSON value stays in owner-only
|
|
273
|
+
`home_feed.feed_owner_imports`, immutable under
|
|
274
|
+
`(source_space_id, namespace, snapshot_id)`. A declared `previousSnapshotId` must
|
|
275
|
+
already exist in that same scope. Reusing a snapshot ID with changed content is
|
|
276
|
+
refused. Raw source rows, original receipts, owner-only state and other archival
|
|
277
|
+
metadata are not copied to agent databases; deletion records are data, not SQL
|
|
278
|
+
deletes. Only envelopes declared `restoreTarget: "agent-response"` are restored
|
|
279
|
+
remotely, using their supplied complete canonical cards and optional private
|
|
280
|
+
response payloads.
|
|
281
|
+
|
|
282
|
+
Remote delivery recipients come only from explicit `runtimeTarget.agentId`
|
|
283
|
+
mappings. Configure `feed watch --recipient` with that same runtime ID, not a
|
|
284
|
+
logical recipient key, legacy name, or label. Partial mappings retain unresolved
|
|
285
|
+
names in the owner archive. Multiple logical keys for one runtime retain all
|
|
286
|
+
evidence, including conflicts; the default-deny delivery policy below still applies.
|
|
287
|
+
Private payloads retain the response-read boundary described above.
|
|
288
|
+
|
|
289
|
+
The archive and per-agent databases do not share a transaction. An identical
|
|
290
|
+
snapshot replay can finish partial progress without replacing existing content.
|
|
291
|
+
Replay is not exactly-once external delivery; runtime durable acceptance,
|
|
292
|
+
deduplication, and deadline checks remain necessary. Import does not pause source
|
|
293
|
+
writers, install a write fence, or establish a live-source cutover.
|
|
294
|
+
|
|
295
|
+
### Owner SDK restore and delivery policy
|
|
296
|
+
|
|
297
|
+
The generic restore API is exported from `@tinycloud/sdk-services/feed`; the
|
|
298
|
+
prepared importer above uses it. Call `initializeFeedDatabases({ output, responses })`
|
|
299
|
+
with owner-authorized SQL handles to initialize the current pair's tables before
|
|
300
|
+
restoring or listening. Agents retain read-only access to responses and cannot
|
|
301
|
+
initialize or restore that database. Missing import/policy tables fail closed.
|
|
302
|
+
|
|
303
|
+
`restoreFeedRecords({ output, responses }, preparedRecords, { signal })` accepts
|
|
304
|
+
complete `FeedCard` records and response headers with optional private payloads,
|
|
305
|
+
source references, and minimal delivery evidence. It does not interpret legacy
|
|
306
|
+
records, choose current answers, or resolve recipients. Historical responses
|
|
307
|
+
bypass live-submission eligibility only; they still require the full published
|
|
308
|
+
card/revision/issuance identity. Existing live response IDs cannot be reclassified
|
|
309
|
+
as imported. Replays must preserve header/payload content and source bindings.
|
|
310
|
+
Valid literal JSON payload keys are preserved; unknown card-envelope fields are
|
|
311
|
+
still refused. Completed query or batch failures retain their classification if
|
|
312
|
+
caller cancellation races completion or later readback. Without cancellation, an
|
|
313
|
+
identical concurrent restore can still recover through complete content and policy readback.
|
|
314
|
+
|
|
315
|
+
Cards are stored first. Each imported response atomically stores its content-bound
|
|
316
|
+
claim, header, optional private payload, origins, and delivery policies in the
|
|
317
|
+
response database. There is no transaction across the two databases; a repeated
|
|
318
|
+
prepared restore can complete partial progress without replacing existing content.
|
|
319
|
+
|
|
320
|
+
Every import origin has a default `*` deny policy. Dispatch requires each origin
|
|
321
|
+
to have consistent evidence for the exact recipient: `state: "pending"`,
|
|
322
|
+
`dispatch: "resolved-pending"`, `resolvedOwnerMapping: true`, and a required
|
|
323
|
+
`dispatchBefore` containing a valid future timestamp or explicit `null` for no
|
|
324
|
+
absolute cutoff. Held, delivered, unconfirmed, refused, unknown, or conflicting
|
|
325
|
+
evidence does not dispatch. Missing or malformed metadata fails the page rather
|
|
326
|
+
than treating it as live data. Policy fields record owner decisions, not grants.
|
|
327
|
+
Keep raw receipts and complete legacy ledgers in owner-only storage; remote policy
|
|
328
|
+
rows contain only source references, state, mapping evidence, and the cutoff.
|
|
329
|
+
|
|
330
|
+
`listFeedResponseDeliveries(responses, { recipient, afterSequence, limit, signal })`
|
|
331
|
+
reads dispatch-eligible headers; `listFeedResponses` alone is history access, not
|
|
332
|
+
dispatch authority. `listenFeedResponses` applies the policy before local handoff.
|
|
333
|
+
Safe notification JSON carries the validated cutoff but no private payload data.
|
|
334
|
+
The SDK checks the cutoff before handoff and again before invoking the runner.
|
|
335
|
+
A queued runtime must check it immediately before acting. Expiry after a durable
|
|
336
|
+
claim leaves the handoff unconfirmed, without automatic resend. Runtime durable
|
|
337
|
+
acceptance and deduplication are still required; exactly-once external execution
|
|
338
|
+
is not guaranteed.
|
|
339
|
+
|
|
340
|
+
### Card issuance history
|
|
341
|
+
|
|
342
|
+
`listFeedCardHistory(output, { afterIdentity, limit, signal })` from
|
|
343
|
+
`@tinycloud/sdk-services/feed` reads full stored card issuances and their payloads,
|
|
344
|
+
including earlier revisions and distinct issuances of the same revision.
|
|
345
|
+
Validation preserves literal JSON payload keys, including an own `"__proto__"` key;
|
|
346
|
+
it does not substitute a reconstructed payload or change its prototype.
|
|
347
|
+
Pages use the full `(cardId, revision, issuanceId)` cursor in SQLite BINARY order
|
|
348
|
+
for IDs and numeric order for revision, with default limit 100 and maximum 1000.
|
|
349
|
+
The result is `{ cards, nextIdentity, hasMore }`; `nextIdentity` is the last
|
|
350
|
+
returned full tuple, or `null` for an empty page.
|
|
351
|
+
|
|
352
|
+
This snapshot cursor is not a durable publication tail: new IDs can sort before
|
|
353
|
+
an existing cursor. Start each full reconciliation without `afterIdentity`.
|
|
354
|
+
`listFeedCards` still returns only the latest published issuance per card.
|
|
355
|
+
History reads use the existing output read capability and perform no DDL or writes.
|
|
356
|
+
|
|
357
|
+
### Raw owner-only source export
|
|
358
|
+
|
|
359
|
+
`feed export` captures raw KV source bytes, not resolved Home cards or a restore plan.
|
|
360
|
+
Supply the full approved source space, a space-relative namespace ending in `/`,
|
|
361
|
+
and an unused output path. There is no installed-legacy or production default:
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
tinycloud --profile owner feed export \
|
|
365
|
+
--source-space tinycloud:pkh:eip155:1:0x1111111111111111111111111111111111111111:applications \
|
|
366
|
+
--prefix example/legacy/ --out ./raw-owner-snapshot.json \
|
|
367
|
+
--sidecars ./raw-sidecars.json
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
The selected profile must already hold source `tinycloud.kv/get` and explicit
|
|
371
|
+
`tinycloud.kv/sync` authority on that namespace. Normal per-agent SQL feed grants
|
|
372
|
+
do not authorize this export. The command does not broaden grants or fall back
|
|
373
|
+
to LIST when sync is denied.
|
|
374
|
+
|
|
375
|
+
`--sidecars` is optional. Its JSON array explicitly names every local file to
|
|
376
|
+
include; relative paths resolve beside that configuration file:
|
|
377
|
+
|
|
378
|
+
```json
|
|
379
|
+
[
|
|
380
|
+
{"sourceKey":"owner/watch/hold-actions","sourceArea":"watch-state","path":"hold-actions.json"},
|
|
381
|
+
{"sourceKey":"owner/watch/thread","sourceArea":"thread-watch-state","path":"thread-state.json"},
|
|
382
|
+
{"sourceKey":"owner/expiry","sourceArea":"expiry-state","path":"expiry-state.json"}
|
|
383
|
+
]
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
Sidecar files are read as exact bytes, including malformed JSON or binary data.
|
|
387
|
+
No watcher is discovered or executed. Duplicate or conflicting full source keys
|
|
388
|
+
are refused rather than overwritten.
|
|
389
|
+
|
|
390
|
+
The owner-only versioned snapshot retains full KV keys, base64 bytes, SHA-256,
|
|
391
|
+
strong ETags, change metadata, tombstones, opaque cursors, and node source/authority
|
|
392
|
+
attestations. It bootstraps every change-feed page and verifies each binary network
|
|
393
|
+
read against its ETag. One empty final tail at the end cursor is required before
|
|
394
|
+
`completePrefixSnapshot: true` can be published. Source changes, cursor gaps,
|
|
395
|
+
scope drift, or mismatches fail the capture. The exporter does not restart a changed
|
|
396
|
+
capture or create a write fence; SDK requests retain their own transport behavior.
|
|
397
|
+
|
|
398
|
+
The complete file is fsynced and published exclusively with mode `0600`; an existing
|
|
399
|
+
path is never silently replaced. Keep this archive private: it can contain answers
|
|
400
|
+
or codes. Normal command output is only the snapshot ID, output path, and counts.
|
|
401
|
+
The output directory must belong to the effective user and forbid group/world
|
|
402
|
+
writes. Ancestors must belong to that user or root; writable shared ancestors
|
|
403
|
+
require sticky-bit protection of the next trusted-owned child. Unverifiable paths
|
|
404
|
+
are refused. Mode `0600` protects contents, not the staging pathname's identity:
|
|
405
|
+
the directory precondition prevents another UID from replacing that entry.
|
|
406
|
+
The same UID and root remain trusted OS principals, not isolated adversaries.
|
|
407
|
+
Validation includes every intermediate directory-alias target, not only the spelled
|
|
408
|
+
path and its final resolved destination.
|
|
409
|
+
Export does not classify records, choose current answers, resolve recipients,
|
|
410
|
+
evaluate legacy expiry, restore state, or dispatch pending responses.
|
|
411
|
+
|
|
105
412
|
## Commands
|
|
106
413
|
|
|
107
414
|
| Command | Description |
|
|
108
415
|
|---------|-------------|
|
|
109
|
-
| `
|
|
110
|
-
| `
|
|
111
|
-
| `
|
|
112
|
-
| `
|
|
113
|
-
| `
|
|
114
|
-
| `
|
|
115
|
-
| `
|
|
116
|
-
| `
|
|
117
|
-
| `
|
|
118
|
-
| `
|
|
119
|
-
| `
|
|
120
|
-
| `
|
|
121
|
-
| `
|
|
122
|
-
| `
|
|
123
|
-
| `
|
|
124
|
-
| `
|
|
125
|
-
| `
|
|
126
|
-
| `
|
|
127
|
-
| `
|
|
128
|
-
| `
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
| `
|
|
133
|
-
| `
|
|
134
|
-
| `
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
138
|
-
| `
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
144
|
-
| `
|
|
145
|
-
| `
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
416
|
+
| `tinycloud init` | Set up a profile and generate keys |
|
|
417
|
+
| `tinycloud auth login` | Authenticate via browser |
|
|
418
|
+
| `tinycloud auth login --device --manifest <file>` | Approve exactly a manifest's permissions on another device (phone) |
|
|
419
|
+
| `tinycloud auth login --manifest <file>` | Browser OpenKey login scoped to a manifest |
|
|
420
|
+
| `tinycloud enable share` | Device login with the built-in Share publishing manifest (use a dedicated profile) |
|
|
421
|
+
| `tinycloud context` | Show the selected profile, owner, host, space and session state |
|
|
422
|
+
| `tinycloud auth status` | Show authentication status |
|
|
423
|
+
| `tinycloud auth whoami` | Show current identity |
|
|
424
|
+
| `tinycloud auth request --preset apps-agent [--app <id>]... [--write]` | Request access for an agent to the user's installed apps: read-only by default, for one app, several, or all. `--write --app <id>` also lets the agent change that app's data: write its `knowledge/` and `prefs/` files and add, change or delete its table rows. For the Health Log app's catalog database, it can also create, change and drop tables (nodes before 1.21.6 do not enforce that split). It cannot change the app's code, manifest or install record |
|
|
425
|
+
| `tinycloud knowledge list` | List the installed apps that have a knowledge bundle |
|
|
426
|
+
| `tinycloud knowledge read <app_id> [concept]` | Read an app's knowledge index, or one concept with its frontmatter parsed |
|
|
427
|
+
| `tinycloud apps install <app_id>` | Install a pinned catalog app into the applications space of the profile it runs under (the owner's, for a delegate profile, through its grant): each file is verified against its pinned digest, the pinned DDL runs only if every statement is allowed, and knowledge notes are created create-only. Notes you have edited are left as they are and reported (exit 0) |
|
|
428
|
+
| `tinycloud kv get <key>` | Retrieve a value |
|
|
429
|
+
| `tinycloud kv put <key> <value>` | Store a value |
|
|
430
|
+
| `tinycloud kv list` | List all keys |
|
|
431
|
+
| `tinycloud sql query <sql>` | Run a SQLite SELECT query |
|
|
432
|
+
| `tinycloud sql execute <sql>` | Run a SQLite write or schema statement |
|
|
433
|
+
| `tinycloud sql export` | Export a SQLite database file |
|
|
434
|
+
| `tinycloud feed` | Connect an agent, publish cards, save responses, record handling, and watch for runtime handoff; see [Home feed](#home-feed) |
|
|
435
|
+
| `tinycloud space list` | List your spaces |
|
|
436
|
+
| `tinycloud space create` | Create a new space |
|
|
437
|
+
| `tinycloud delegation create` | Grant access to another user |
|
|
438
|
+
| `tinycloud delegation list` | List delegations |
|
|
439
|
+
| `tinycloud delegation revoke <cid>` | Revoke a delegation. From a delegate profile, revoke one its own key issued. |
|
|
440
|
+
| `tinycloud share` | Share data with another user |
|
|
441
|
+
| `tinycloud node` | Manage TinyCloud nodes |
|
|
442
|
+
| `tinycloud profile list` | List profiles |
|
|
443
|
+
| `tinycloud profile show` | Show profile details |
|
|
444
|
+
| `tinycloud profile create` | Create a new profile |
|
|
445
|
+
| `tinycloud vault` | Manage encrypted KV vaults |
|
|
446
|
+
| `tinycloud secrets` | Manage network-encrypted secrets |
|
|
447
|
+
| `tinycloud secrets network show` | Show a secrets decryption network |
|
|
448
|
+
| `tinycloud secrets network init` | Create or fetch the default secrets network |
|
|
449
|
+
| `tinycloud secrets network grant` | Grant `tinycloud.encryption/decrypt` on a secrets network |
|
|
450
|
+
| `tinycloud secrets run` | Run a command with secrets in its environment |
|
|
451
|
+
| `tinycloud secrets request` | Print a Secret Manager link asking the owner to add secrets (offline) |
|
|
452
|
+
| `tinycloud secrets wait` | Wait until secrets exist and are readable (never signs in; needs a stored session; exit 8 pending, 130 interrupted) |
|
|
453
|
+
| `tinycloud secrets manage` | Print or open the Secret Manager page, `{url, opened}` |
|
|
454
|
+
| `tinycloud vars` | Manage environment variables |
|
|
455
|
+
| `tinycloud doctor` | Run diagnostic checks |
|
|
456
|
+
| `tinycloud completion` | Generate shell completions |
|
|
457
|
+
| `tinycloud courier` | Agent-to-agent threads over TinyCloud (beta; see [Courier](#courier)) |
|
|
148
458
|
|
|
149
459
|
Secret names are env-style uppercase identifiers such as `FIREFLIES_API_KEY`.
|
|
150
|
-
`
|
|
151
|
-
`urn:tinycloud:encryption:<ownerDid>:<network>` identifier. `
|
|
460
|
+
`tinycloud secrets network show` accepts either a short network name or a full
|
|
461
|
+
`urn:tinycloud:encryption:<ownerDid>:<network>` identifier. `tinycloud secrets
|
|
152
462
|
network grant` takes the short name, resolves the network, and grants
|
|
153
463
|
`tinycloud.encryption/decrypt`.
|
|
154
464
|
|
|
155
|
-
`
|
|
465
|
+
`tinycloud apps install` re-creates the pinned views on every run (reported as
|
|
156
466
|
`viewsRecreated`). Knowledge notes whose bytes differ from the pinned version
|
|
157
467
|
are left as you edited them and listed under `conflicts` (JSON); the command
|
|
158
468
|
still exits 0 and installs the rest. If the schema fails after notes were
|
|
159
469
|
written, it says "notes saved; tables not set up: run again"; running it again
|
|
160
470
|
is safe.
|
|
161
471
|
|
|
472
|
+
### Running a command with secrets
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
tinycloud secrets run NAME... [--map NAME=ENV_VAR]... [--scope S] [--space S] [--delegation SOURCE] [--private-key HEX] -- <command> [args...]
|
|
476
|
+
|
|
477
|
+
tinycloud secrets run ANTHROPIC_API_KEY OPENAI_API_KEY -- python train.py
|
|
478
|
+
tinycloud secrets run --map ANTHROPIC_KEY=ANTHROPIC_API_KEY -- node server.js
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
`tinycloud secrets run` reads every named secret as `tinycloud secrets get` does, then
|
|
482
|
+
starts `<command>` directly, without a shell, with each value in its
|
|
483
|
+
environment: under the secret's name, or under `ENV_VAR` for `--map
|
|
484
|
+
NAME=ENV_VAR`. A value replaces an inherited variable of the same name.
|
|
485
|
+
tinycloud doesn't pass its own `TC_PRIVATE_KEY` to the command. To give the command
|
|
486
|
+
a key from a secret, use `--map NAME=TC_PRIVATE_KEY`.
|
|
487
|
+
Everything after the first `--`, including any further `--`, goes to the
|
|
488
|
+
command unchanged. The command uses tinycloud's stdin, stdout and stderr; tinycloud itself
|
|
489
|
+
writes nothing to stdout, and its own messages go to stderr.
|
|
490
|
+
|
|
491
|
+
Name at least one secret, as an argument or with `--map`. `ENV_VAR` must
|
|
492
|
+
match `[A-Za-z_][A-Za-z0-9_]*`, and two secrets cannot be mapped to the same
|
|
493
|
+
variable (exit 2). If any secret cannot be read, the command does not start
|
|
494
|
+
and tinycloud exits with the code and error `tinycloud secrets get` gives for that secret.
|
|
495
|
+
Otherwise tinycloud exits with the command's exit code. If the command was ended by
|
|
496
|
+
SIGINT, SIGTERM, SIGHUP, SIGKILL, SIGALRM or SIGUSR2, tinycloud ends by the same
|
|
497
|
+
signal (or exits with 128 plus the signal number if that signal doesn't end
|
|
498
|
+
tinycloud). If any other signal ended it, such as SIGQUIT or SIGSEGV, tinycloud exits with
|
|
499
|
+
128 plus the signal number instead, so tinycloud does not cause a core dump
|
|
500
|
+
(SIGUSR1 and SIGPIPE are left out too: Node uses SIGUSR1 for its inspector
|
|
501
|
+
and ignores SIGPIPE).
|
|
502
|
+
|
|
503
|
+
SIGINT, SIGTERM, SIGHUP and SIGQUIT sent to tinycloud go to the command. When tinycloud
|
|
504
|
+
runs in the foreground of a terminal, it doesn't pass on SIGINT, SIGQUIT or
|
|
505
|
+
SIGHUP: the terminal already sends them (Ctrl-C, Ctrl-\, hangup) to the
|
|
506
|
+
command, so the command normally gets each one once. tinycloud checks whether it's
|
|
507
|
+
in the foreground using `/proc`, or `ps` where `/proc` isn't available. If
|
|
508
|
+
neither works, it passes the signals on. When tinycloud runs in the background, it
|
|
509
|
+
passes them on, so a signal sent to the whole job (for example `kill -INT
|
|
510
|
+
%1`) can reach the command twice.
|
|
511
|
+
|
|
512
|
+
From a script, stop the command by sending SIGTERM to tinycloud's process ID. tinycloud
|
|
513
|
+
passes it on, waits for the command to exit, then exits the way the command
|
|
514
|
+
did (the command's own exit code if it handles SIGTERM itself). If the
|
|
515
|
+
command ignores SIGTERM, tinycloud keeps waiting.
|
|
516
|
+
|
|
517
|
+
A command that does not exist exits 127; one that cannot be executed, or
|
|
518
|
+
cannot be started for another reason, exits 126. These cases print one plain
|
|
519
|
+
line on stderr, even with `--json`: `tinycloud secrets run: <command>: command not
|
|
520
|
+
found`, `…: permission denied` or `…: cannot run (<error code>)`.
|
|
521
|
+
|
|
522
|
+
Limits: `tinycloud secrets run` keeps values out of the command line, your shell
|
|
523
|
+
history and tinycloud's own output. It doesn't hide them from the command: the
|
|
524
|
+
command, and anything it starts, receives the values and can print, log or
|
|
525
|
+
pass them on. Other programs running as the same user can often read a
|
|
526
|
+
process's environment too.
|
|
527
|
+
|
|
162
528
|
## Global Options
|
|
163
529
|
|
|
164
530
|
```
|
|
@@ -176,7 +542,7 @@ is safe.
|
|
|
176
542
|
Replication is off by default. `--replication` enables it for one invocation;
|
|
177
543
|
`--no-replication` overrides `TC_REPLICATION=1`, and `--replication-debug`
|
|
178
544
|
writes diagnostics to stderr. Save explicit login prefixes with
|
|
179
|
-
`
|
|
545
|
+
`tinycloud auth login --replication-prefix notes/`; saved prefixes are reapplied on
|
|
180
546
|
later logins and rotation. Prefixes are folders (`notes/`) or `/` for the
|
|
181
547
|
whole space. Whole-space replication requires `kv-sync-root` support and
|
|
182
548
|
`--replication-allow-secrets`, because it includes `vault/`. Replication needs
|
|
@@ -197,7 +563,7 @@ Chromium browsers that enforce Local Network Access without granting it (headles
|
|
|
197
563
|
Chromium cannot show the prompt), may block the HTTPS page's plain-HTTP loopback
|
|
198
564
|
callback: use an interactive CLI terminal and paste the same one-line code shown
|
|
199
565
|
by OpenKey, or start with
|
|
200
|
-
`
|
|
566
|
+
`tinycloud auth login --method openkey --replication-prefix notes/ --owner DID --paste`
|
|
201
567
|
for a headless terminal. Non-TTY `--no-popup` cannot accept a paste; if that
|
|
202
568
|
callback fails, it exits nonzero at the five-minute expiry with a `--paste`
|
|
203
569
|
retry hint and discards the candidate key. Restarting requires a new approval
|
|
@@ -205,10 +571,20 @@ and cannot reuse the old signed code. Ctrl-C, SIGINT or SIGTERM before approval
|
|
|
205
571
|
arrives cancels the OpenKey handoff (best effort) and exits 130 `CANCELLED`
|
|
206
572
|
without saving a key or session.
|
|
207
573
|
|
|
208
|
-
|
|
574
|
+
Normal OpenKey login prints a short approval link on stderr and waits. Relay it
|
|
575
|
+
to the owner from a headless or remote CLI; no localhost callback or pasted code
|
|
576
|
+
is needed. `--no-popup` skips opening a local browser, not automatic result
|
|
577
|
+
retrieval. The CLI verifies the encrypted result, durably saves it, then
|
|
578
|
+
acknowledges delivery. Re-run the same command after an interruption to resume.
|
|
579
|
+
The one-hour request expiry is independent of the requested grant lifetime and
|
|
580
|
+
result retention. Normal login keeps its seven-day default; onboarding requests
|
|
581
|
+
30 days explicitly. `--paste` remains an explicit manual fallback with a
|
|
582
|
+
five-minute, single-use return code, not the automatic short-link transport.
|
|
583
|
+
|
|
584
|
+
Use `tinycloud replica report` for read-only aggregates of persisted replication events
|
|
209
585
|
and identity partitions. Live replica status is unavailable there. Report
|
|
210
586
|
`--purge` and `--clear-pending` refuse with exit 2 `REPORT_READ_ONLY`.
|
|
211
|
-
`
|
|
587
|
+
`tinycloud replica reset --replica <name> --purge` is a partial alternative for a
|
|
212
588
|
named local replica only. Flag-owned purge and pending clearing have no
|
|
213
589
|
equivalent yet (TC-1309). On macOS and Windows, `replica reset --purge` and
|
|
214
590
|
`auth logout` with a legacy `replicas/` tree refuse local removal rather than
|
|
@@ -247,7 +623,7 @@ flag-owned replicas untouched; startup finishes the legacy removal if it is
|
|
|
247
623
|
interrupted. If an earlier sign-out was interrupted, logout reports it and a
|
|
248
624
|
second `auth logout` completes it. A gate that no longer matches its logout
|
|
249
625
|
record (for example, restored from an older copy) refuses logout; switch the
|
|
250
|
-
default profile if needed, then run `
|
|
626
|
+
default profile if needed, then run `tinycloud profile delete <name>` and sign in
|
|
251
627
|
again.
|
|
252
628
|
|
|
253
629
|
`auth logout`, `auth rotate`, and replica-enabled `auth login` that replaces the
|
|
@@ -256,20 +632,20 @@ unexpired shares, or cannot be read, the command refuses with exit 5
|
|
|
256
632
|
(`SHARE_HISTORY_UNEXPIRED` or `SHARE_HISTORY_UNAVAILABLE`) and changes nothing.
|
|
257
633
|
Pass `--force` to proceed anyway; `auth logout --revoke` also skips the check. A
|
|
258
634
|
plain re-login that keeps the key is not checked, and local-owner profiles are not
|
|
259
|
-
checked. `
|
|
635
|
+
checked. `tinycloud share history recover` moves an unreadable history file aside to
|
|
260
636
|
`share-history-v2.json.unreadable-<UTC timestamp>` and reports the new path. It
|
|
261
637
|
never deletes or overwrites a file. If the file exists but cannot be read,
|
|
262
638
|
recover exits 1 with `SHARE_HISTORY_RECOVER_FAILED` and moves nothing.
|
|
263
639
|
|
|
264
|
-
`
|
|
265
|
-
`
|
|
640
|
+
`tinycloud auth grants list` labels the signed-in delegation CID `(current session)`.
|
|
641
|
+
`tinycloud delegation revoke <cid>` still accepts any eligible exact CID, but when
|
|
266
642
|
`<cid>` is the current session it requires `--yes` or an interactive confirmation
|
|
267
643
|
before contacting the node. An exact-CID success then runs the same durable
|
|
268
644
|
local sign-out and key shred as `auth logout`; revoking another CID leaves the
|
|
269
645
|
session intact.
|
|
270
646
|
|
|
271
647
|
B-int release acceptance must
|
|
272
|
-
verify the OpenKey `
|
|
648
|
+
verify the OpenKey `tinycloud auth request --grant` fallback against a real OpenKey
|
|
273
649
|
using a test account and no production writes: approve the request, confirm the
|
|
274
650
|
grant is stored, start a fresh process, and verify the saved prefixes are
|
|
275
651
|
replayed and the covered read is served locally. If OpenKey rejects explicit
|
|
@@ -277,7 +653,7 @@ replayed and the covered read is served locally. If OpenKey rejects explicit
|
|
|
277
653
|
|
|
278
654
|
## Output Modes
|
|
279
655
|
|
|
280
|
-
`
|
|
656
|
+
`tinycloud` auto-detects your terminal:
|
|
281
657
|
|
|
282
658
|
- **Interactive (TTY)** — human-friendly output with colors, tables, and status icons
|
|
283
659
|
- **Piped / redirected** — structured JSON for scripting
|
|
@@ -285,29 +661,29 @@ replayed and the covered read is served locally. If OpenKey rejects explicit
|
|
|
285
661
|
|
|
286
662
|
```bash
|
|
287
663
|
# Human-friendly table
|
|
288
|
-
|
|
664
|
+
tinycloud kv list
|
|
289
665
|
|
|
290
666
|
# JSON for scripting
|
|
291
|
-
|
|
292
|
-
|
|
667
|
+
tinycloud kv list --json
|
|
668
|
+
tinycloud kv list | jq '.[]'
|
|
293
669
|
```
|
|
294
670
|
|
|
295
671
|
## Diagnostics
|
|
296
672
|
|
|
297
673
|
```bash
|
|
298
|
-
|
|
674
|
+
tinycloud doctor
|
|
299
675
|
```
|
|
300
676
|
|
|
301
677
|
Checks Node.js version, profile configuration, keys, session status, node connectivity (with latency), and space availability. Outputs actionable guidance for any failing checks.
|
|
302
678
|
|
|
303
679
|
## Profiles
|
|
304
680
|
|
|
305
|
-
`
|
|
681
|
+
`tinycloud` supports multiple profiles for different environments:
|
|
306
682
|
|
|
307
683
|
```bash
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
684
|
+
tinycloud profile create staging --host https://staging.tinycloud.xyz
|
|
685
|
+
tinycloud profile list
|
|
686
|
+
tinycloud kv list --profile staging
|
|
311
687
|
```
|
|
312
688
|
|
|
313
689
|
### Pointing a profile at a self-hosted OpenKey
|
|
@@ -325,7 +701,7 @@ profile JSON directly:
|
|
|
325
701
|
}
|
|
326
702
|
```
|
|
327
703
|
|
|
328
|
-
`
|
|
704
|
+
`tinycloud auth login --method openkey` and `tinycloud auth request` honor this for the
|
|
329
705
|
profile. Set `TC_OPENKEY_HOST` to override per invocation without editing the
|
|
330
706
|
file.
|
|
331
707
|
|