@tinycloud/cli 1.3.0-beta.43 → 1.3.0-beta.45

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.43",
3
+ "version": "1.3.0-beta.45",
4
4
  "description": "TinyCloud CLI - manage data, delegations, and nodes from the terminal",
5
5
  "author": "TinyCloud, Inc.",
6
6
  "license": "EGPL",
@@ -35,11 +35,11 @@
35
35
  "dependencies": {
36
36
  "@tinycloud/share-sdk": "1.2.0-beta.6",
37
37
  "@tinycloud/share-envelope": "1.2.0-beta.0",
38
- "@tinycloud/node-sdk": "3.3.0-beta.35",
38
+ "@tinycloud/node-sdk": "3.3.0-beta.36",
39
39
  "@tinycloud/node-sdk-wasm": "1.7.8-beta.0",
40
- "@tinycloud/sdk-core": "3.3.0-beta.31",
40
+ "@tinycloud/sdk-core": "3.3.0-beta.36",
41
41
  "@tinycloud/sdk-services": "3.3.0-beta.25",
42
- "@tinycloud/operations": "0.7.0-beta.33",
42
+ "@tinycloud/operations": "0.7.0-beta.34",
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.2.0-beta.38",
50
+ "@tinycloud/courier": "0.2.0-beta.40",
51
51
  "@tinycloud/replica": "0.3.0-beta.10",
52
52
  "@types/node": "^20",
53
53
  "tsup": "^8.0.0",
@@ -279,6 +279,23 @@ threads for the same work, other channels): your human resumes it with
279
279
  `courier resume <peer> <threadId>`. A "thread paused" inform from the peer only
280
280
  means their side stopped waking; it is not a request, and needs no reply.
281
281
 
282
+ Pause notices use one fixed record per locally known thread, never records keyed
283
+ by incoming ids. Only our authored meta/message/task or a local wake/pause record
284
+ establishes a known thread; mirrored metadata does not. Newer peer notice ULIDs
285
+ within ten minutes of our clock update the peer pause latch: paused-to-resumed
286
+ clears it, resumed-to-paused queues one episode notice. Duplicate/old notices, repeated paused
287
+ states and unknown threads do not notify, across days and restarts. Every delivery
288
+ attempt, successful or failed, counts toward ten globally and ten per peer per
289
+ hour across channels; at most three attempts per notice, with persisted backoff.
290
+ Failed wake backoff starts when the attempt finishes and survives a restart;
291
+ approval wakes have a separate retry clock and never wait for message backoff.
292
+
293
+ Two fixed pending episode slots per known thread retain separate pause notices,
294
+ including across retries and restarts. Additional pauses while both slots are
295
+ occupied are included as a bounded repeated-pause count in the second notice.
296
+ The global hourly allowance reserves up to three attempts per locally paired
297
+ peer (at most the integer part of 10 divided by the peer count).
298
+
282
299
  ## Notify-only setup
283
300
 
284
301
  For the first handoff, run `courier watch --wake none`. It mirrors messages,
@@ -288,6 +305,14 @@ no wake budget and starts or messages no agent. Inbox JSON includes recent
288
305
  fixed-text notifications, even if the watcher already committed delivery
289
306
  receipts. The /courier view retains the owner's approval cards.
290
307
 
308
+ D mode preallocates one message slot and one approval slot per locally paired
309
+ peer. Each slot coalesces deliveries into a six-digit count (up to 999999+),
310
+ records its first local arrival time and latest validated thread ULID, and
311
+ keeps separate retry metadata. Arrivals during a dispatch remain pending for
312
+ another notice. The shared outbox admits and dispatches eligible peers in
313
+ round-robin order within each priority class, under the same hourly caps and
314
+ reserved shares. A message retry deadline does not delay the approval slot.
315
+
291
316
  Example only: pick your own channel (push, Telegram, email, or tail the log).
292
317
  This example appends only the fixed notice
293
318
  kind, validated peer handle and thread ID/fingerprint inside COURIER_HOME:
@@ -298,7 +323,7 @@ courier watch --wake none --notify exec --notify-exec 'printf "%s %s %s\n" "$COU
298
323
 
299
324
  `<COURIER_HOME>/notifications.jsonl` always exists after the first notification;
300
325
  it holds fixed-text status, never the peer's subject or message. Once notified,
301
- Start a session and watch it yourself. Paste this prompt (replace the
326
+ start a session and watch it yourself. Paste this prompt (replace the
302
327
  thread and peer with the IDs shown by `courier inbox`):
303
328
 
304
329
  ```text
@@ -392,6 +392,8 @@ Versions are kept by default and count against the owner's storage. The node doe
392
392
 
393
393
  The fragment after `#` is the read key. Browsers never send it to a server; `--notify` gives the link to TinyCloud only to email your recipients. 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.
394
394
 
395
+ **Publish history status.** `share publish --json` reports the sender-history write as `history`: `{"recorded": true}` when the share was saved, or `{"recorded": false, "reason": "<CODE>"}` when it was not. `HISTORY_UNREADABLE` means the existing history file cannot be decrypted or parsed with the current session key. `HISTORY_READ_FAILED` means the filesystem refused or failed to read that file. `HISTORY_WRITE_FAILED` means a filesystem or permission error during the write. `HISTORY_UNAVAILABLE` covers every other failure, including a profile-lock timeout. The exit status is 0 in all four cases, so do not retry the publish on this result: a retry creates a duplicate share. The stderr warning names the reason and the share id and CID to keep. It never includes the link, the key, or ciphertext. When `--notify` delivers but the delivery confirmation cannot be saved, `history.recorded` stays `true` (the share itself was saved) and the warning names the reason, the share id, and the CID.
396
+
395
397
  **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, `tinycloud 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.
396
398
 
397
399
  **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 and keeps its normal exit status: human output still prints the published link, but `--json` output stays redacted, and because the share was not recorded, `share show <id> --reveal-link` cannot recover it either. 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.