@tinycloud/cli 1.5.0-beta.2 → 1.5.0-beta.21
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 +59 -0
- package/dist/index.js +21 -5
- package/dist/index.js.map +1 -1
- package/dist/legacy-entry.js +693 -216
- package/dist/legacy-entry.js.map +1 -1
- package/package.json +9 -9
- package/skills/tc-cli/REFERENCE.md +24 -1
- package/skills/tc-cli/SKILL.md +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tinycloud/cli",
|
|
3
|
-
"version": "1.5.0-beta.
|
|
3
|
+
"version": "1.5.0-beta.21",
|
|
4
4
|
"description": "TinyCloud CLI - manage data, delegations, and nodes from the terminal",
|
|
5
5
|
"author": "TinyCloud, Inc.",
|
|
6
6
|
"license": "EGPL",
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
"sync:courier-skill": "rm -rf skills/courier && cp -R ../courier/skills/courier skills/courier"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@tinycloud/share-sdk": "1.4.0",
|
|
37
|
-
"@tinycloud/share-envelope": "1.3.0",
|
|
38
|
-
"@tinycloud/node-sdk": "3.8.0-beta.
|
|
36
|
+
"@tinycloud/share-sdk": "1.4.1-beta.0",
|
|
37
|
+
"@tinycloud/share-envelope": "1.3.1-beta.0",
|
|
38
|
+
"@tinycloud/node-sdk": "3.8.0-beta.15",
|
|
39
39
|
"@tinycloud/node-sdk-wasm": "1.7.8",
|
|
40
|
-
"@tinycloud/sdk-core": "3.
|
|
41
|
-
"@tinycloud/sdk-services": "3.
|
|
42
|
-
"@tinycloud/operations": "0.7.7-beta.
|
|
40
|
+
"@tinycloud/sdk-core": "3.8.0-beta.15",
|
|
41
|
+
"@tinycloud/sdk-services": "3.8.0-beta.9",
|
|
42
|
+
"@tinycloud/operations": "0.7.7-beta.14",
|
|
43
43
|
"chalk": "^5.3.0",
|
|
44
44
|
"commander": "^14.0.0",
|
|
45
45
|
"jsdom": "26.1.0",
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
"siwe": "^3.0.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@tinycloud/courier": "0.3.3-beta.
|
|
52
|
-
"@tinycloud/replica": "0.3
|
|
51
|
+
"@tinycloud/courier": "0.3.3-beta.13",
|
|
52
|
+
"@tinycloud/replica": "0.4.0-beta.3",
|
|
53
53
|
"@types/node": "^20",
|
|
54
54
|
"tsup": "^8.0.0",
|
|
55
55
|
"typescript": "^5.9.3"
|
|
@@ -5,7 +5,7 @@ This release has **Commander coverage tracked, not complete parity**:
|
|
|
5
5
|
|
|
6
6
|
- 4 migrated registration(s).
|
|
7
7
|
- 1 partially migrated registration(s).
|
|
8
|
-
-
|
|
8
|
+
- 137 legacy registration(s) remain Commander-owned.
|
|
9
9
|
|
|
10
10
|
- `auth import [source]` → `tinycloud.auth.import@1` (partial; legacy inputs: v1 delegation artifact, v1 permission artifact without command, bare portable delegation, stored delegation wrapper, cross-user delegation persisted with activated=false).
|
|
11
11
|
- `secrets get <name>` → `tinycloud.secrets.get@1` (migrated).
|
|
@@ -104,6 +104,8 @@ warning that revocation signs you out. After the node confirms that exact CID,
|
|
|
104
104
|
the CLI runs its normal durable logout, removes the restorable session and key,
|
|
105
105
|
and blocks implicit reauthentication. Unrelated CIDs do not sign you out.
|
|
106
106
|
|
|
107
|
+
From a delegate (agent) profile, `delegation list --granted` lists the delegations that profile's own key issued: every page of the node's issued-delegations listing, each with its `status`, sorted by delegation ID rather than by date (the output's `note` says so). A node that does not offer the listing yet answers `ISSUED_DELEGATIONS_UNAVAILABLE` (exit 7). `delegation revoke <cid>` from a delegate profile revokes a delegation its own key issued with a revocation signed by that key, so it needs no revoke grant from the owner. Revoking one that's already revoked also succeeds. A delegation the key did not issue is refused with the node's message (`REVOKE_UNAUTHORIZED`, exit 5). A chain too long for the node to check right now answers `CHAIN_TOO_DEEP` (exit 7); retry later. Owner profiles behave as described above.
|
|
108
|
+
|
|
107
109
|
A grant the owner signed through `auth grant` can be revoked from any of the owner's profiles, including one that never recorded it (another CLI profile or machine). When this profile has no local record of the CID, the CLI reads the owner's delegation records on the node and uses that record's space only if the grant was issued by the signed-in owner (the issuer is the owner or the signed-in session key, or a key that holds a delegation recorded on the node whose own issuer is, in turn, one of those: any holder along such an owner-rooted chain counts, up to 8 hops) and every space it covers is one plain space id (`tinycloud:pkh:eip155:<chain>:<address>:<name>`) that belongs to that owner. The lookup reads at most 5,000 records (pages of 100; a larger page is refused) and refuses rather than decides on a partial list. A CID the node does not list, one issued by someone else, a space the owner does not hold, or an ambiguous record is refused (`RAW_RECAP_RESOURCE_UNSUPPORTED`, "this CLI profile has no record of this grant and the node's record does not match the signed-in owner"). An OpenKey owner uses the same space-scoped request as for a locally recorded grant; OpenKey profiles hold no wallet signer, so there is no wallet-signed revoke for them. After the revoke, the agent's next call is refused (`GRANT_REVOKED`, exit 5, the same as `tc replica`: "This grant was revoked. Ask the owner for a new grant") as soon as the node has recorded it.
|
|
108
110
|
|
|
109
111
|
`tinycloud auth import` stores delegations in `additional-delegations.json`. Every replay path installs only a grant with a locally verified proof and a binding containing its signed authority; unbound and proof-less grants never install, including while migration is deferred. [AUTH.md](AUTH.md#imported-delegations-and-their-request-bindings) covers migration and recovery.
|
|
@@ -181,6 +183,25 @@ printf '%s' "$ANTHROPIC_API_KEY" | "$TC" secrets put ANTHROPIC_API_KEY --stdin
|
|
|
181
183
|
|
|
182
184
|
A missing secret makes `tinycloud secrets get` exit 4 (`NOT_FOUND`). For an identity that is not local, `error.setup` carries the owner's request link; a local identity (or a name/scope no link can express) gets only a hint naming `tinycloud secrets put NAME --stdin`. `tinycloud secrets doctor NAME` hints `tinycloud secrets request NAME` for a missing secret, or `tinycloud secrets put NAME --stdin` for a local identity. `tinycloud secrets get --delegation` follows the same rule, and a delegated read the node refuses (403, a capability 401, `AUTH_UNAUTHORIZED`) exits 5.
|
|
183
185
|
|
|
186
|
+
### Running a command with secrets: `run`
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
"$TC" secrets run NAME... [--map NAME=ENV_VAR]... [--scope S] [--space S] [--delegation SOURCE] [--private-key HEX] -- <command> [args...]
|
|
190
|
+
"$TC" --profile agent secrets run OPENAI_API_KEY -- python train.py
|
|
191
|
+
"$TC" --profile agent secrets run --map ANTHROPIC_KEY=ANTHROPIC_API_KEY -- node server.js
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
`tinycloud secrets run` reads every named secret as `tinycloud secrets get` does, then starts `<command>` directly, without a shell, with each value in its environment: under the secret's name, or under `ENV_VAR` for `--map NAME=ENV_VAR`. A value replaces an inherited variable of the same name. The CLI doesn't pass its own `TC_PRIVATE_KEY` to the command. To give the command a key from a secret, use `--map NAME=TC_PRIVATE_KEY`. Everything after the first `--`, including any further `--`, goes to the command unchanged. The command uses the CLI's stdin, stdout and stderr; the CLI itself writes nothing to stdout, and its own messages go to stderr.
|
|
195
|
+
|
|
196
|
+
- Name at least one secret, as an argument or with `--map`. `ENV_VAR` must match `[A-Za-z_][A-Za-z0-9_]*`; two secrets mapped to the same variable, no `--`, or nothing after it exit 2 (`USAGE_ERROR`) before any read.
|
|
197
|
+
- If any secret cannot be read, the command does not start and the CLI exits with the code and error `tinycloud secrets get` gives for that secret. A value containing a NUL character exits 1 (`SECRET_NOT_EXPORTABLE`) without starting the command.
|
|
198
|
+
- Otherwise the CLI exits with the command's exit code. If the command was ended by SIGINT, SIGTERM, SIGHUP, SIGKILL, SIGALRM or SIGUSR2, the CLI ends by the same signal (or exits with 128 plus the signal number if that signal doesn't end it). If any other signal ended it, such as SIGQUIT or SIGSEGV, the CLI exits with 128 plus the signal number instead, so it does not cause a core dump (SIGUSR1 and SIGPIPE are left out too: Node uses SIGUSR1 for its inspector and ignores SIGPIPE).
|
|
199
|
+
- SIGINT, SIGTERM, SIGHUP and SIGQUIT sent to the CLI go to the command. When the CLI runs in the foreground of a terminal, it doesn't pass on SIGINT, SIGQUIT or SIGHUP: the terminal already sends them (Ctrl-C, Ctrl-\, hangup) to the command, so the command normally gets each one once. The CLI checks whether it's in the foreground using `/proc`, or `ps` where `/proc` isn't available. If neither works, it passes the signals on. When the CLI runs in the background, it passes them on, so a signal sent to the whole job (for example `kill -INT %1`) can reach the command twice.
|
|
200
|
+
- From a script, stop the command by sending SIGTERM to the CLI's process ID. The CLI passes it on, waits for the command to exit, then exits the way the command did (the command's own exit code if it handles SIGTERM itself). If the command ignores SIGTERM, the CLI keeps waiting.
|
|
201
|
+
- A command that does not exist exits 127; one that cannot be executed, or cannot be started for another reason, exits 126. These cases print one plain stderr line even with `--json`: `tinycloud secrets run: <command>: command not found`, `…: permission denied` or `…: cannot run (<error code>)`.
|
|
202
|
+
|
|
203
|
+
Limits: `tinycloud secrets run` keeps values out of the command line, your shell history and the CLI's own output. It doesn't hide them from the command: the command, and anything it starts, receives the values and can print, log or pass them on. Other programs running as the same user can often read a process's environment too.
|
|
204
|
+
|
|
184
205
|
### Asking the owner for a secret: `request`, `wait`, `manage`
|
|
185
206
|
|
|
186
207
|
`/usr/sbin/tc` (iproute2 traffic control) can shadow the older `tc` name on `PATH`, so scripts call the CLI by absolute path:
|
|
@@ -528,6 +549,8 @@ Use `--json` for machine-readable output; interactive commands can render human
|
|
|
528
549
|
|
|
529
550
|
General storage/auth exit codes: 0 success, 1 operation error (including `PROFILE_MIGRATION_REQUIRED` and `PROBE_FAILED`), 2 invalid input, 3 authentication required, 4 not found, 5 permission denied, 6 network error, 7 node error, 8 pending (`tinycloud secrets wait` only), 10 storage full, 130 interrupted (`CANCELLED`). `tinycloud share` uses its own: 1 profile lock timeout, sender-history retry or unconfirmed revocation (`PROFILE_LOCK_TIMEOUT`, `SHARE_HISTORY_RETRY`, `SHARE_REVOKE_UNCONFIRMED`), 3 upload authority required, 4 unavailable, expired, revoked bearer link, upload failed or revocation refused (`SHARE_LINK_UNAVAILABLE`, `SHARE_REVOKED`, `SHARE_REVOKE_REJECTED`), 5 permission denied (`PERMISSION_DENIED`, `SHARE_ISSUER_KEY_UNAVAILABLE`) or verification failed, 6 recipient authorization required or network error, 7 byte limit, 8 output conflict or unsafe filename, 9 partial success, 10 storage full.
|
|
530
551
|
|
|
552
|
+
`tinycloud secrets run` exits with its command's status once the command has started. Before that it uses the codes above, plus 126 (the command cannot be executed or started) and 127 (the command does not exist).
|
|
553
|
+
|
|
531
554
|
For `tinycloud kv get|put|head|list|delete`, `tinycloud space list|host`, `tinycloud sql`, `tinycloud vault`, `tinycloud vars`, `tinycloud duckdb`, `tinycloud secrets list|put|delete`, `tinycloud delegation`, and `tinycloud account`, service-result errors use typed authorization: a plain HTTP 401 is `AUTH_REQUIRED` (exit 3); a 403 is `PERMISSION_DENIED` (exit 5). A 401 with a validated missing capability, or `AUTH_UNAUTHORIZED` without an HTTP status, is `PERMISSION_DENIED` (exit 5); a validated capability also produces a `tinycloud auth request --cap` hint. This changes the former exit 1 for status-less `AUTH_UNAUTHORIZED` in the listed commands. Other HTTP failures retain their service-specific codes. `tinycloud share` has separate exit mappings below.
|
|
532
555
|
|
|
533
556
|
Every command that writes reports full TinyCloud storage the same way: `STORAGE_QUOTA_EXCEEDED` (storage is full) or `STORAGE_LIMIT_REACHED` (this write is larger than what is left), exit 10, with nothing written (`tinycloud sql copy` instead names the table and the rows it had already copied). The hint gives the account totals when the node reports them (`371.7 MiB used of 100 MiB (free plan)`), says reading still works, and links to https://account.tinycloud.xyz/storage. Retrying cannot succeed until the owner frees up space or upgrades.
|
package/skills/tc-cli/SKILL.md
CHANGED
|
@@ -30,6 +30,8 @@ Keep the selected profile, host and space explicit across reads and follow-ups:
|
|
|
30
30
|
|
|
31
31
|
## Sign in
|
|
32
32
|
|
|
33
|
+
To set up a new owner (no profile, or no TinyCloud account yet), run `"$TC" onboard`. It creates the profile and asks for two OpenKey approvals, one per run: the owner's sign-in (or new account) with read and write on the `applications` space, then read-only `spaces/` and `applications/` in the `account` space, each for 30 days. Each run prints JSON; exit 8 means `approvalUrl` is waiting for the owner: send it, then run `"$TC" onboard --code '<code OpenKey shows>'`. Exit 0 means `"onboarded": true`. The step-by-step guide for agents is https://agents.tinycloud.xyz/onboarding.
|
|
34
|
+
|
|
33
35
|
Agents usually run where no browser can reach them. Use device login: the owner approves an explicit permission manifest on their phone. Read [AUTH.md](AUTH.md) before the first login, including how to relay the approval code to the owner.
|
|
34
36
|
|
|
35
37
|
Use a new profile name if it already exists. Keep the user's existing profiles: another app's session may live there, and a login for a different purpose would drop it (the CLI refuses with `SESSION_IN_USE`). Publish from a dedicated profile:
|