@tinycloud/cli 1.0.1-beta.5 → 1.1.0-beta.6
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/dist/index.js +2091 -1800
- package/dist/index.js.map +1 -1
- package/dist/legacy-entry.js +1682 -262
- package/dist/legacy-entry.js.map +1 -1
- package/package.json +5 -5
- package/skills/tc-cli/REFERENCE.md +14 -6
- package/skills/tc-cli/SKILL.md +5 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tinycloud/cli",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0-beta.6",
|
|
4
4
|
"description": "TinyCloud CLI - manage data, delegations, and nodes from the terminal",
|
|
5
5
|
"author": "TinyCloud, Inc.",
|
|
6
6
|
"license": "EGPL",
|
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
"check:skill-pack": "node scripts/check-skill-pack.mjs"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@tinycloud/share-sdk": "1.0
|
|
32
|
+
"@tinycloud/share-sdk": "1.1.0-beta.1",
|
|
33
33
|
"@tinycloud/share-envelope": "1.1.0-beta.0",
|
|
34
|
-
"@tinycloud/node-sdk": "3.1.0-beta.
|
|
34
|
+
"@tinycloud/node-sdk": "3.1.0-beta.4",
|
|
35
35
|
"@tinycloud/node-sdk-wasm": "1.7.6",
|
|
36
|
-
"@tinycloud/sdk-core": "3.1.0-beta.
|
|
37
|
-
"@tinycloud/operations": "0.3.4-beta.
|
|
36
|
+
"@tinycloud/sdk-core": "3.1.0-beta.4",
|
|
37
|
+
"@tinycloud/operations": "0.3.4-beta.6",
|
|
38
38
|
"chalk": "^5.3.0",
|
|
39
39
|
"commander": "^14.0.0",
|
|
40
40
|
"open": "^11.0.0",
|
|
@@ -166,9 +166,10 @@ Publishing needs the publishing scope on a dedicated profile (`tc --profile publ
|
|
|
166
166
|
|
|
167
167
|
```bash
|
|
168
168
|
tc share publish ./note.md --json # bearer link
|
|
169
|
-
tc share publish ./note.md --to email:alice@example.com --notify # addressed: exact email, emailed invitation
|
|
169
|
+
tc share publish ./note.md --to email:alice@example.com --notify # addressed: exact email, emailed invitation (read required)
|
|
170
170
|
tc share publish ./note.md --to did:pkh:eip155:1:0xRecipient... # addressed: one DID
|
|
171
171
|
tc share publish ./note.md --to domain:example.com # addressed: any verified address at the domain
|
|
172
|
+
tc share publish ./note.md --to domain:example.com --notify --notify-to alice@example.com # invite one matching mailbox; node 1.17.3+
|
|
172
173
|
cat note.md | tc share publish - --name note.md
|
|
173
174
|
|
|
174
175
|
printf '%s' "$SHARE_URL" | tc share inspect - --json # verify, print safe metadata
|
|
@@ -177,13 +178,19 @@ printf '%s' "$SHARE_URL" | tc share receive - --output .
|
|
|
177
178
|
|
|
178
179
|
tc share list --json # sender history, no complete URLs
|
|
179
180
|
tc share show <id> [--reveal-link]
|
|
180
|
-
tc share notify <id> --to alice@example.com # retry email delivery
|
|
181
|
+
tc share notify <id> --to alice@example.com # retry email delivery within 5 minutes of publication
|
|
181
182
|
tc share revoke <id>
|
|
182
183
|
```
|
|
183
184
|
|
|
184
|
-
**Bearer vs addressed.** A bearer link (default, `--to anyone`) is `/viewer#tc1=<TinyCloud delegation>`: anyone holding the complete URL can read the file until it expires, and revocation cannot recall copies already received. Addressed links (`--to email:`, `--to did:`, `--to domain:`) are `/s/inline#v=2&p=<sealed Policy/v3 envelope>`: the content is encrypted and only the named recipient can open it after proving their email or DID in Share. `tc share receive` returns the bytes of a bearer link; for an addressed link it exits 6 with `CLAIM_REQUIRED` because the recipient claims it in Share. `--notify`
|
|
185
|
+
**Bearer vs addressed.** A bearer link (default, `--to anyone`) is `/viewer#tc1=<TinyCloud delegation>`: anyone holding the complete URL can read the file until it expires, and revocation cannot recall copies already received. Addressed links (`--to email:`, `--to did:`, `--to domain:`) are `/s/inline#v=2&p=<sealed Policy/v3 envelope>`: the content is encrypted and only the named recipient can open it after proving their email or DID in Share. `tc share receive` returns the bytes of a bearer link; for an addressed link it exits 6 with `CLAIM_REQUIRED` because the recipient claims it in Share. `--notify` requires the `read` action: exact-email targets invite the matched mailbox; domain targets need `--notify-to` naming one canonical mailbox at that exact domain and a node reporting version 1.17.3 or later. The CLI refuses unsupported domain invitations before uploading or registering a share. A session-only publisher can deliver its own domain policy when the invoking DID matches its signed owner DID; a different sender DID cannot. `tc share notify <id> --to <mailbox>` can address another mailbox in a domain share under the same node and sender-DID requirements; it refuses stored shares without `read` or on an unsupported node before sending.
|
|
185
186
|
|
|
186
|
-
The fragment after `#` is the read authority. It never reaches a server in a query string or HTTP request; keep complete URLs out of logs. Human publish output is exactly one URL. Inspect never prints plaintext or secret-bearing fields. Receive uses a sanitized single-segment filename and refuses overwrite unless `--force`. `revoke` revokes addressed shares at the owner node and reports bearer retention honestly. Pre-cutover blob-backed and plaintext `?tc2` links are not accepted.
|
|
187
|
+
The fragment after `#` is the read authority. It never reaches a server in a query string or HTTP request; keep complete URLs out of logs. Human publish output is exactly one URL. JSON publish output retains the redacted publication fields and adds `notification` (the `ShareNotifyResult`, including `state`, `attempts`, and optional failure `reason`) when `--notify` was requested. Inspect never prints plaintext or secret-bearing fields. Receive uses a sanitized single-segment filename and refuses overwrite unless `--force`. `revoke` revokes addressed shares at the owner node and reports bearer retention honestly. Pre-cutover blob-backed and plaintext `?tc2` links are not accepted.
|
|
188
|
+
|
|
189
|
+
**Notification window.** The CLI requests a stable signed delivery authorization until the earlier of share expiry and 5 minutes after its sender-history `registeredAt` timestamp. The node allows an authorization no more than 5 minutes in the future; keeping the expiry stable also makes idempotent retries use the same request. After the window, `tc share notify` prints `partial-failure` (exit 9; JSON `retryable: false`, `reason: "delivery-window-expired"`) and explains that the sender must publish a new share and invite the recipient then. `share publish --notify --json` includes the same failure under `notification`. A confirmed repeat within the window prints `already-delivered`; an unconfirmed failed attempt remains retryable until the window closes. If the sender history cannot record a successful delivery confirmation, the CLI warns on stderr but preserves the successful publish/notify result; a later repeat can report `delivered` again.
|
|
190
|
+
|
|
191
|
+
**History and node preflight.** Post-publication sender-history writes wait up to 45 seconds for another process's profile lock (including stale-lock recovery). If the first history write still fails, the CLI warns but prints the published link with its normal exit status; a later `share list`, `share notify <id>`, or `share revoke <id>` cannot find that share by ID. An immediate `--notify` can still deliver using the in-process record. Other share-command profile-lock timeouts report `PROFILE_LOCK_TIMEOUT` with a retry hint. Standalone domain notification validates the recipient and expired delivery window locally before contacting `/info`: an expired window remains exit 9 even if the node is unavailable. A node-info transport failure, including a stalled response body, is `UNAVAILABLE` (exit 4); a completed but unsupported or malformed version is `INVALID_ARGUMENT` (exit 2). Publish-time refusals say nothing was shared and no invitation was sent; standalone notify refusals say no invitation was sent.
|
|
192
|
+
|
|
193
|
+
**Concurrent history changes.** A Share command resolves its profile once for authentication and every sender-history operation, including retries; a later default-profile change cannot redirect a share link into another profile. If a write waits more than about 2 seconds to acquire the profile lock, the CLI writes one waiting notice to stderr naming that profile. A profile removed after an earlier history read or during an operation, or repeated key/salt changes, returns `SHARE_HISTORY_RETRY` (exit 1) with a retry hint; a profile missing from the outset still returns `PROFILE_NOT_FOUND` with the setup hint. If a history retry follows a revoke, check the node state before trying again: revocation might already have succeeded even though sender history could not record it.
|
|
187
194
|
|
|
188
195
|
Share publication without `--expires` requests a seven-day lifetime. For a session-only profile, the CLI clamps that request to the verified SIWE session expiry, prints a notice to stderr, and reports `"expiryClamped": true` in JSON. Explicit lifetimes beyond the session end, or with less than 60 seconds left after second-precision rounding, fail with `SESSION_LIFETIME_EXCEEDED`. Expired/invalid restored sessions and missing owner authority return `AUTH_REQUIRED`; rejected KV upload or delegation scopes return `PERMISSION_DENIED`. A session-only profile whose authority for an anyone-with-link share carries signed restrictions (caveats) is refused with `PERMISSION_DENIED` before anything is stored, because the link's delegation cannot carry the caveats; approve Share publishing without restrictions on a new profile (`tc init --name publisher --key-only && tc --profile publisher enable share`). A full storage quota returns `STORAGE_QUOTA_EXCEEDED`, with the used and limit sizes when the node reports them, and any other failed upload returns `UPLOAD_FAILED`; nothing is shared in either case. A filename that has characters other than `A-Z a-z 0-9 . _ -`, starts with anything but a letter or digit, contains `..`, or is longer than 128 characters is stored under a readable URI-safe name. It keeps its extension when that is 1-16 ASCII letters or digits (`Q3 plan (draft).md` is stored as `Q3-plan-draft.md`, `.env` as `share.env`); otherwise its dots become dashes, so it never gains one. Bearer links show the stored name and `receive` writes it, while addressed links keep the original. JSON publish output includes `expiryClamped: false` when no clamp was needed.
|
|
189
196
|
|
|
@@ -194,7 +201,8 @@ Share publication without `--expires` requests a seven-day lifetime. For a sessi
|
|
|
194
201
|
| `files` | One or more files, or `-` for bounded stdin | required |
|
|
195
202
|
| `--name <filename>` | Safe filename for stdin | `stdin.md` |
|
|
196
203
|
| `--to <target>` | `anyone`, recipient DID, email, or `domain:<name>` | `anyone` |
|
|
197
|
-
| `--notify` |
|
|
204
|
+
| `--notify` | Email the exact-email recipient, or one domain mailbox with `--notify-to`; requires `read` | off |
|
|
205
|
+
| `--notify-to <email>` | Canonical mailbox at the `--to domain:<name>` target (node 1.17.3+) | required for domain `--notify` |
|
|
198
206
|
| `--expires <duration>` | Duration: `1h`, `7d`, `1w`, or ISO date | implicit `7d`, clamped for session-only profiles |
|
|
199
207
|
| `--media-type <type>` | Media type for a single input | inferred |
|
|
200
208
|
| `--action <actions...>` | Addressed permission: `read`, `list`, or `edit` | `read` |
|
|
@@ -232,4 +240,4 @@ KV keys cannot contain spaces or control characters: the SDK sends keys unescape
|
|
|
232
240
|
|
|
233
241
|
Use `--json` for machine-readable output; interactive commands can render human output. General command errors go to stderr as `{error: {code, message, hint?}}`. Inspect the structured code, not only the exit status.
|
|
234
242
|
|
|
235
|
-
General storage/auth exit codes: 0 success, 1 operation error, 2 invalid input, 3 authentication required, 4 not found, 5 permission denied, 6 network error, 7 node error. `tc share` uses its own: 3 upload authority required, 4 unavailable, expired, storage quota exceeded or upload failed, 5 permission denied (`PERMISSION_DENIED`) or verification failed, 6 recipient authorization required or network error, 7 byte limit, 8 output conflict or unsafe filename, 9 partial success.
|
|
243
|
+
General storage/auth exit codes: 0 success, 1 operation error, 2 invalid input, 3 authentication required, 4 not found, 5 permission denied, 6 network error, 7 node error. `tc share` uses its own: 1 profile lock timeout or sender-history retry (`PROFILE_LOCK_TIMEOUT`, `SHARE_HISTORY_RETRY`), 3 upload authority required, 4 unavailable, expired, storage quota exceeded or upload failed, 5 permission denied (`PERMISSION_DENIED`) or verification failed, 6 recipient authorization required or network error, 7 byte limit, 8 output conflict or unsafe filename, 9 partial success.
|
package/skills/tc-cli/SKILL.md
CHANGED
|
@@ -62,7 +62,11 @@ tc --profile publisher share publish ./note.md --json
|
|
|
62
62
|
tc --profile publisher share publish ./note.md --to email:alice@example.com --notify --json
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
Without `--to`, publish creates a bearer link: anyone holding the complete URL can read it. `--to email:`, `--to did:` and `--to domain:` create addressed links that only the named recipient can open after proving who they are. Keep complete URLs, including the `#` fragment, out of logs. The default lifetime is seven days, clamped to the verified session expiry; JSON output reports `expiryClamped`. Explicit `--expires` values beyond the session end fail instead of being silently shortened. See [REFERENCE.md](REFERENCE.md) for inspect, receive, list, show and revoke.
|
|
65
|
+
Without `--to`, publish creates a bearer link: anyone holding the complete URL can read it. `--to email:`, `--to did:` and `--to domain:` create addressed links that only the named recipient can open after proving who they are. Keep complete URLs, including the `#` fragment, out of logs. `--notify` requires `read`; domain invitations also require `--notify-to <email>` at the exact domain, a matching sender/owner DID and node 1.17.3+. Session-only publishers can notify their own domain policies. Standalone `tc share notify <id> --to <email>` refuses records without `read` and domain delivery on unsupported nodes before sending. It retries within 5 minutes of publication; after that it reports a non-retryable `partial-failure` (exit 9), and the sender must publish a new share to invite again. A confirmed repeat reports `already-delivered`; a failed history confirmation warns without hiding a successful delivery. Human publish prints only the URL; with `--notify --json`, the redacted publication JSON also contains `notification` with delivery status and attempts. The default lifetime is seven days, clamped to the verified session expiry; JSON output reports `expiryClamped`. Explicit `--expires` values beyond the session end fail instead of being silently shortened. See [REFERENCE.md](REFERENCE.md) for inspect, receive, list, show and revoke.
|
|
66
|
+
|
|
67
|
+
After a share is published, a profile-lock or history-write failure warns without hiding the published link; later `share list`, `share notify <id>`, and `share revoke <id>` cannot find an unrecorded share. Standalone domain notification checks the recipient and local five-minute window before probing the node; an expired window stays a non-retryable partial failure even when `/info` is unreachable.
|
|
68
|
+
|
|
69
|
+
Share commands pin one profile for authentication and all history writes, even when the default changes. History writes name that profile on stderr after about 2 seconds waiting for its lock. If a previously observed profile disappears, including between reading a share and recording its revocation, or its signing key keeps changing, `SHARE_HISTORY_RETRY` gives a retry hint; a profile that never existed instead reports `PROFILE_NOT_FOUND` with a setup hint. After a revoke reports a history retry, check the node's state before trying again because revocation may already have completed.
|
|
66
70
|
|
|
67
71
|
## Other operations
|
|
68
72
|
|