@tinycloud/cli 1.3.0-beta.18 → 1.3.0-beta.20

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinycloud/cli",
3
- "version": "1.3.0-beta.18",
3
+ "version": "1.3.0-beta.20",
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.2.0-beta.4",
37
- "@tinycloud/share-envelope": "1.1.0",
38
- "@tinycloud/node-sdk": "3.3.0-beta.18",
36
+ "@tinycloud/share-sdk": "1.2.0-beta.5",
37
+ "@tinycloud/share-envelope": "1.2.0-beta.0",
38
+ "@tinycloud/node-sdk": "3.3.0-beta.21",
39
39
  "@tinycloud/node-sdk-wasm": "1.7.7",
40
- "@tinycloud/sdk-core": "3.3.0-beta.18",
40
+ "@tinycloud/sdk-core": "3.3.0-beta.21",
41
41
  "@tinycloud/sdk-services": "3.3.0-beta.11",
42
- "@tinycloud/operations": "0.6.1-beta.17",
42
+ "@tinycloud/operations": "0.6.1-beta.19",
43
43
  "chalk": "^5.3.0",
44
44
  "commander": "^14.0.0",
45
45
  "open": "^11.0.0",
@@ -47,7 +47,7 @@
47
47
  "siwe": "^3.0.0"
48
48
  },
49
49
  "devDependencies": {
50
- "@tinycloud/courier": "0.1.6-beta.17",
50
+ "@tinycloud/courier": "0.1.6-beta.19",
51
51
  "@tinycloud/replica": "0.3.0-beta.5",
52
52
  "@types/node": "^20",
53
53
  "tsup": "^8.0.0",
@@ -372,7 +372,7 @@ printf '%s' "$SHARE_URL" | "$TC" share receive - --output .
372
372
  "$TC" share revoke <id> # bearer or addressed share this profile created
373
373
  ```
374
374
 
375
- **Artifact versions (pinned shares).** `--artifact <id|new>` stores the file as the next write-once version, `artifacts/<id>/versions/<n>/<file>` plus a `manifest.json` written last (file sha256 and size, parent, `--note`), in the owner's space. The share is pinned to that version: its delegation covers only that file and never carries `put`. Publishing the same bytes again to a bearer link returns the same version; changed content makes the next one; earlier versions are never overwritten. An addressed share stores ciphertext under a fresh random key each time, so every addressed publish is a new version, and `manifest.json` records only the sha256 of the stored ciphertext, never of the plaintext (an unsalted plaintext hash next to the ciphertext would let a reader of the space confirm a guess). `--artifact new` mints an id. JSON output adds `artifactId`, `version` and `mode` (`pinned`). `--action edit` on an artifact share is refused (a pinned version is read-only). An artifact share takes one file. Every artifact share pins one version; shares that follow later versions are not available yet. Profiles signed in before this feature need `auth login --device --manifest builtin:share-publishing` again, because the manifest now includes `artifacts/`.
375
+ **Artifact versions (pinned shares).** `--artifact <id|new>` stores the file as the next write-once version, `artifacts/<id>/versions/<n>/<file>` plus a `manifest.json` written last (file sha256 and size, parent, `--note`), in the owner's space. The share is pinned to that version: its delegation covers only that file and never carries `put`. Publishing the same bytes again to a bearer link returns the same version; changed content makes the next one. Publishing never overwrites an earlier version, but the node has no write-once ACL for the owner, so the owner (or anyone holding the owner's session) can overwrite a version file afterwards; the CLI will not, and the writes it makes use `If-None-Match: *`. Only addressed artifact shares detect such an overwrite (see Pin below); a bearer artifact share carries no digest and would deliver the new bytes. An addressed share stores ciphertext under a fresh random key each time, so every addressed publish is a new version, and `manifest.json` records only the sha256 of the stored ciphertext, never of the plaintext (an unsalted plaintext hash next to the ciphertext would let a reader of the space confirm a guess). `--artifact new` mints an id. JSON output adds `artifactId`, `version` and `mode` (`pinned`). `--action edit` on an artifact share is refused (a pinned version is read-only). An artifact share takes one file. Every artifact share pins one version; shares that follow later versions are not available yet. Profiles signed in before this feature need `auth login --device --manifest builtin:share-publishing` again, because the manifest now includes `artifacts/`.
376
376
 
377
377
  ```bash
378
378
  "$TC" share publish ./report.md --artifact new --to email:alice@example.com --json # v1, pinned
@@ -382,6 +382,8 @@ cat report-v2.md | "$TC" share publish - --name report.md --artifact art_0123456
382
382
 
383
383
  Versions are kept by default and count against the owner's storage. The node does not reclaim overwritten or deleted values; byte reclamation depends on history GC (TC-1277).
384
384
 
385
+ **Pin (addressed artifact shares).** The signed envelope of an addressed artifact share carries `artifactPin`: artifact id, version, the sha256 of that version's `manifest.json`, and the sha256 and size of the one stored (encrypted) file the share reads. The owner's signature covers it. The recipient refuses the share unless the pin matches what the share reads, and refuses the fetched bytes unless they hash to the pinned digest. A share that reads `artifacts/` without a valid pin is refused, and a pinned share never carries `put`. The owner is the trusted signer: the node has no write-once ACL, so the owner (or anyone holding the owner's session) can still overwrite a version file afterwards. Recipients then fail closed on the digest mismatch; they cannot tell that apart from a node serving altered bytes. Bearer artifact shares carry no envelope, so they have no pin and no digest yet: they are limited to the one version file by their delegation only, and an owner overwrite of that file reaches bearer recipients undetected. A viewer built before this field exists rejects the envelope (its schema is strict) instead of showing unverified content.
386
+
385
387
  **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. `tinycloud 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. `tinycloud 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.
386
388
 
387
389
  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 never contains the link: it retains the redacted publication fields (including the share id) and adds `notification` (the `ShareNotifyResult`, including `state`, `attempts`, and optional failure `reason`) when `--notify` was requested. To get the complete link after a `--json` publish, run `tinycloud share show <id> --reveal-link`, ideally writing it straight to a private file. Inspect never prints plaintext or secret-bearing fields. Receive uses a sanitized single-segment filename and refuses overwrite unless `--force`. `revoke` asks the owner node to revoke the share (an addressed share's Policy/v3 root, or a bearer link's delegation) and reports `revoked` only when the node confirms it; receiving the link then fails; for a bearer link, `tinycloud share receive` reports `SHARE_REVOKED` (exit 4, "This share link has been revoked by its sender."). Revoking an already revoked share keeps its original `revokedAt`. A bearer revoke that cannot proceed revokes nothing: `SHARE_ISSUER_KEY_UNAVAILABLE` (exit 5) when this profile cannot sign for the link, `SHARE_LINK_UNAVAILABLE` (exit 4) when the stored link is missing or does not match the record, and `SHARE_REVOKE_REJECTED` (exit 4, with the node's reason) when the node refuses. `SHARE_REVOKE_UNCONFIRMED` (exit 1) means the node answered without confirming: the link may already be revoked, history is not marked revoked, and you should check whether the link still opens before retrying. Pre-cutover blob-backed and plaintext `?tc2` links are not accepted.