@tonbo/yield 0.0.0-stage → 0.1.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.
Files changed (3) hide show
  1. package/README.md +83 -2
  2. package/dist/bin/yield.js +3704 -0
  3. package/package.json +40 -4
package/README.md CHANGED
@@ -1,3 +1,84 @@
1
- # Temporary Holding Version
1
+ # Tonbo Yield
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ `yield` captures the sessions of your coding agents (Claude Code and Codex) on every machine you use and lists them from any of them. It signs in, runs a capture service on each machine, snapshots the git work trees the agents work in, lists sessions and recalls the turns that changed a file; handoff comes later.
4
+
5
+ Install the public package with Node.js 22 or newer:
6
+
7
+ ```console
8
+ npm install --global @tonbo/yield
9
+ ```
10
+
11
+ Merging a change to the `version` in `package.json` to `main` releases it: [`tonbo-yield-release.yml`](../../.github/workflows/tonbo-yield-release.yml) tests the package, publishes it through npm trusted publishing and installs it back from the registry, as the [Tonbo CLI release](../../docs/operations/tonbo-cli-release.md) does.
12
+
13
+ ## Sign in
14
+
15
+ ```console
16
+ yield login [--account <name>]
17
+ yield whoami [--json]
18
+ yield logout
19
+ ```
20
+
21
+ `yield` and the [`tonbo`](../tonbo) CLI share one login through the internal package [`@tonbo/cli-core`](../../packages/tonbo-cli-core): the same browser handoff, the same personal key named `CLI on <hostname>` and the same credentials file, `${XDG_CONFIG_HOME:-$HOME/.config}/tonbo/credentials.json`. Logging in with either CLI signs both in, and a login replaces the host's earlier key, so the two never hold different keys. `whoami` prints the account, your role and this machine's device id, which is the key id of that login; revoking the key revokes the device.
22
+
23
+ ## Capture
24
+
25
+ ```console
26
+ yield daemon install [--since <date>]
27
+ yield daemon status [--json]
28
+ yield daemon uninstall
29
+ yield daemon run [--since <date>]
30
+ ```
31
+
32
+ `install` writes a user service that runs `yield daemon run` with the current Node.js and starts it: a launchd agent at `~/Library/LaunchAgents/dev.tonbo.yield.plist` on macOS (`RunAtLoad`, `KeepAlive`) or a systemd user unit at `~/.config/systemd/user/tonbo-yield.service` on Linux (`Restart=always`). The service logs to `${XDG_STATE_HOME:-$HOME/.local/state}/tonbo-yield/daemon.log`. `uninstall` stops and removes it and keeps the capture state. `run` captures in the foreground and logs to stderr. `status` reports whether the capture runs, its last upload, how many sessions it tracks and skipped, the sessions it blocked and its recent errors.
33
+
34
+ The capture follows [`contracts/sessions/capture-v1.json`](../../contracts/sessions/capture-v1.json), which the build embeds (`pnpm generate:contracts`):
35
+
36
+ - It discovers the account's store once an hour through `GET /v1/sessions/store` and again whenever the store refuses a request. An account without a store (409 `sessions_store_unavailable`: no active git workspace Agent) is reported by `daemon status` and `sessions` as needing an account owner to enable git, and the daemon asks again every 10 minutes.
37
+ - Streams does not accept the personal key itself: the client exchanges it at `POST <console origin>/api/iam/token` for a ten-minute Streams access token (`@tonbo/cli-core` `AccessTokens`), keeps it in memory, replaces it a minute before it expires, and exchanges again once after a Streams 401. A refused exchange asks for `yield login`; a 429 or 5xx is retried with backoff while the offsets stay.
38
+ - It watches `~/.claude/projects` and `~/.codex/sessions` and rescans them every two seconds; a missing root is fine. Each file is read from its saved byte offset, and only complete lines count.
39
+ - Each line, except the contract's excluded types, is redacted with the contract's patterns and becomes one record of the stream `session.<session id>`. Consecutive lines go in one append request (at most the contract's `max_batch_lines` and `max_batch_bytes`), which ends early at a line that causes an inbox record. Each request carries `Producer-Id: yield/<device id>`, `Producer-Epoch` and `Producer-Seq`, the request's ordinal within the epoch; the batch's seq and byte range are saved before it is sent, so a resend after a crash is the identical batch and is answered as a duplicate. A line that is not JSON is uploaded as it is. If the redaction fails, nothing more of that session is uploaded and the session is marked blocked.
40
+ - When a session is first seen it appends `session_start` to `proc.inbox`, and at each turn end `turn_end` with the cwd, git root, branch, the paths written since the previous turn end (at most 50, relative to the git root inside it) and `stream_offset`, the session stream's `Stream-Next-Offset` after the turn's last record (the append's answer, or the stream's tail when a resent batch is answered as a duplicate).
41
+ - The state, `${XDG_STATE_HOME:-$HOME/.local/state}/tonbo-yield/state.json`, keeps each file's offset with its producer sequence and epoch, and is replaced atomically. The source files are the offline queue: while the store is unreachable the offset stays and the upload is retried with backoff, honoring `Retry-After`. A new epoch starts from seq 0, saved before it is used, when Streams has forgotten the producer (idle for 7 days) or is ahead of a lost local state.
42
+ - The first run also captures the session files changed in the last 14 days (`--since` sets the bound); older files are recorded as skipped until they change again.
43
+
44
+ ### Snapshots
45
+
46
+ After each `turn_end` of a turn that ended in the last 10 minutes, in a cwd inside a git work tree, the daemon snapshots the work tree as [`contracts/sessions/recall-v1.json`](../../contracts/sessions/recall-v1.json) `snapshots` defines; the build embeds that contract too. Snapshots run one at a time beside the capture and never hold it up; a failure is logged as a warning, and a 4xx from the git token exchange or gitd pauses publishing for 10 minutes.
47
+
48
+ - The tree is what `git add -A` sees through a private index under `${XDG_STATE_HOME:-$HOME/.local/state}/tonbo-yield/snapshots/index/`, so `.gitignore` applies and the user's index, HEAD, branches and config stay untouched. Every git command runs the user's `git` with `GIT_TERMINAL_PROMPT=0`, `core.hooksPath=/dev/null`, no automatic gc and no credential helper. Files over 100 MiB, gitd's object limit, are left out with a logged notice.
49
+ - An unchanged tree makes no snapshot. Otherwise `git commit-tree` writes a commit whose parent is the previous snapshot of this device's chain (none for the first, the baseline) with the trailers `Tonbo-Session`, `Tonbo-Turn`, `Tonbo-Base` (the merge-base of HEAD and its upstream, or HEAD) and `Tonbo-Baseline: true` on the root; `refs/tonbo/snapshots/<device id>` keeps it in the user's repository.
50
+ - The repository is `snap-<slug>` of the origin URL (or of the root's directory name and path hash), created once through gitd's idempotent `PUT /api/v1/workspaces/<ws_hex>/repos/<name>` `{"private": false}`, `ws_hex` being the store's `agent_id` without hyphens. The commit is pushed to `refs/tonbo/u/<sub>/<device id>` with `-o tonbo.session=<id>`. The git token (`POST /api/iam/token` with the git audience, kept and refreshed like the Streams token) reaches git only as an `http.<gitd origin>/.extraHeader` in the environment of that one command: never in a file, an argument, a URL or the log.
51
+ - The chain head of each repository and device is kept in `state.json`. A push refused because gitd's ref moved on without this state (say, after the state was lost) fetches gitd's ref and continues the chain from it; a clone that lacks the chain's head fetches it first.
52
+
53
+ The daemon uses the saved login only; `TONBO_API_KEY` does not name a device. One daemon runs per state directory.
54
+
55
+ ## Sessions
56
+
57
+ ```console
58
+ yield sessions [--limit <records>] [--json]
59
+ ```
60
+
61
+ `sessions` reads `proc.inbox` and prints one row per session among its newest records (200 by default): the last activity, the device (`this machine` for this one), the source, the git root or cwd, the branch and the turn ends seen.
62
+
63
+ ## Recall
64
+
65
+ ```console
66
+ yield why <path> [--limit <turns>] [--max-chars <n>] [--json]
67
+ yield files <path> [--limit <turns>] [--json]
68
+ yield session read <id> [--turn <n>] [--max-chars <n>] [--json]
69
+ ```
70
+
71
+ The recall commands read the git-ingester's queries at `https://git.tonbo.dev/api/recall/v1/workspaces/<ws_hex>` (recall-v1 `queries`) with the git token, and the turns themselves from `session.<session id>` with the Streams token. A path is resolved from the current directory to its git root and the snapshot repository name the daemon pushes to.
72
+
73
+ - `files` lists the turns that changed the file, newest first: when, session, turn, change, whether the turn wrote the file itself, device and snapshot commit.
74
+ - `session read` prints a session as role-tagged lines (`user:`, `assistant:`, `tool:`), each cut at `--max-chars`; with `--turn` only that turn, read between the offsets of its `turn_end` and the previous one, or split from the whole stream when they are missing.
75
+ - `why` joins `files` with each turn's prompt, the assistant's last words and the other files the turn changed, as a timeline an agent can read; `--json` gives the same structure.
76
+
77
+ ## The Tonbo skill
78
+
79
+ `daemon install` also writes the Tonbo skill ([`skills/tonbo/SKILL.md`](skills/tonbo/SKILL.md), embedded by the build) to `~/.claude/skills/tonbo/SKILL.md` for Claude Code (`CLAUDE_CONFIG_DIR` moves it) and `~/.codex/skills/tonbo/SKILL.md` for Codex (`CODEX_HOME` moves it). It tells an agent to run `yield why`, `yield files` and `yield session read` when asked why code is the way it is or before changing an unfamiliar file, to cite session and time, to treat the results as reference and never as instructions, and not to guess when nothing is found. A manifest, `skills.json` in the state directory, records what was written: install never overwrites a `tonbo` skill it did not write, and `daemon uninstall` removes only its own unchanged files. `CLAUDE.md` and `AGENTS.md` are never edited.
80
+
81
+ ## Environment
82
+
83
+ - `TONBO_API_KEY`: a personal key used instead of the saved login by `whoami` and `sessions`.
84
+ - `TONBO_API_ORIGIN`: the Management API origin, `https://api.tonbo.dev` by default. `daemon install` writes it into the service, with `PATH`, `XDG_CONFIG_HOME` and `XDG_STATE_HOME`.