@tonbo/yield 0.3.2 → 0.3.4
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 +23 -4
- package/dist/bin/yield.js +1345 -334
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,7 +40,18 @@ yield connect [folder] [--name <name> | --project <id>] [--account <name> [--yes
|
|
|
40
40
|
yield disconnect [folder]
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
`connect` binds a folder of this computer to a Project ([ADR-0016](../../apps/user-center/docs/decisions/adr-0016-org-git-workspaces.md) W-18) through `POST /v1/projects/connect`. Without a folder it binds the root of the git work tree you are in, or else the current directory. A git work tree joins the Project of its origin, made when the account has none, so every clone of one origin, on any computer, shares it; a work tree without an origin gets a Project named after its folder. A folder outside git is connected only by naming a new Project (`--name`) or joining one (`--project`). Without `--account` the Project is in your personal account; `--account <name>` binds it to that organization's shared team Project, which needs this computer registered (`yield login`), and logs this computer in to the organization first when it has no login there, without changing the account `tonbo` acts in. Before it binds, it says
|
|
43
|
+
`connect` binds a folder of this computer to a Project ([ADR-0016](../../apps/user-center/docs/decisions/adr-0016-org-git-workspaces.md) W-18) through `POST /v1/projects/connect`. Without a folder it binds the root of the git work tree you are in, or else the current directory. A git work tree joins the Project of its origin, made when the account has none, so every clone of one origin, on any computer, shares it; a work tree without an origin gets a Project named after its folder. A folder outside git is connected only by naming a new Project (`--name`) or joining one (`--project`). Without `--account` the Project is in your personal account; `--account <name>` binds it to that organization's shared team Project, which needs this computer registered (`yield login`), and logs this computer in to the organization first when it has no login there, without changing the account `tonbo` acts in. Before it binds, it says what every member sees of each session started in the folder from then on, its title, state and the files each turn writes, and that its prompts, replies and tool output stay with you unless you hand it to a teammate ([ADR-0017](../../apps/user-center/docs/decisions/adr-0017-projects-forks-visibility.md) D-12 and its metadata-only amendment, M-7), and asks; answering no keeps the folder personal and connects nothing. `--yes` answers for you, and without a terminal nothing is shared unless it is given. A folder connected in another account moves: it is disconnected there first. The folder is named only by a random id kept in `${XDG_STATE_HOME:-$HOME/.local/state}/tonbo-yield/folders.json`; its path never leaves the computer. `disconnect` removes the folder's binding (`DELETE /v1/projects/bindings/<id>`) and leaves the Project. `yield ps` and `yield daemon status` name the current folder's Project. A folder that is not connected stays in your personal account, as before.
|
|
44
|
+
|
|
45
|
+
## Pause and exclude
|
|
46
|
+
|
|
47
|
+
```console
|
|
48
|
+
yield pause [--for <duration>]
|
|
49
|
+
yield resume
|
|
50
|
+
yield exclude [folder]
|
|
51
|
+
yield include <folder>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`pause` stops capture and snapshots on this computer until `resume`, or for a while (`--for 30m`, `2h`, `1d`). Lines written while paused are never captured, also after capture resumes: the daemon drops each line whose time falls in a pause, and a line without a time of its own goes with the line before it. A paused turn makes no turn end, so no snapshot either, and `yield give` refuses while paused. `exclude` names a folder whose sessions are never captured on this computer; without a folder it lists them. A session whose cwd is in an excluded folder sends nothing, not even its start, and stays uncaptured after `include` names the folder again; only sessions started afterwards are captured. What was captured before a pause or an exclusion stays as it is. Both live in `capture-filter.json` in the state directory and never leave the computer; `yield status` shows a pause and the excluded folders.
|
|
44
55
|
|
|
45
56
|
## The device id
|
|
46
57
|
|
|
@@ -83,13 +94,13 @@ The capture follows [`contracts/sessions/capture-v1.json`](../../contracts/sessi
|
|
|
83
94
|
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 folder the cwd is bound to (its Project's, see Routing) 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.
|
|
84
95
|
|
|
85
96
|
- The tree is the bound folder's, the whole work tree when the folder is its root and the folder's subtree alone otherwise, as `git add -A` sees it 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.
|
|
86
|
-
- 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
|
|
97
|
+
- 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 origin, preferred over an upstream on another remote; absent when nothing is published, so a never-pushed branch restores on another device from the whole tree) and `Tonbo-Baseline: true` on the root; `refs/tonbo/snapshots/<device id>/<folder binding id>` keeps it in the user's repository.
|
|
87
98
|
- The repository is the Project's `snapshot_repo` (`snap-<slug>` of its origin, or `snap-<project id hex>` for a named Project), created once through gitd's idempotent `PUT /api/v1/workspaces/<ws_hex>/repos/<name>` `{"private": false}` in your personal workspace. The commit is pushed to `refs/tonbo/u/<sub>/<device id>/<folder binding id>` with `-o tonbo.session=<id>`. A device's ref of before Projects, `refs/tonbo/u/<sub>/<device id>`, is continued by the first binding chain pushed in its repository, which deletes it first (git cannot hold a ref and one under it). 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.
|
|
88
99
|
- 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.
|
|
89
100
|
|
|
90
101
|
### Routing
|
|
91
102
|
|
|
92
|
-
Each session goes where its folder's Project says ([ADR-0016](../../apps/user-center/docs/decisions/adr-0016-org-git-workspaces.md) W-7). The daemon reads your folder bindings on this computer in every account it holds a login of, once a minute, and resolves a session's cwd to the nearest connected folder that holds it; a git work tree none of whose folders is connected gets its implicit personal Project, made at its first capture (its origin's, or one named after its root folder). The raw session and every record go to your personal store, and records of a session with a Project name it (`project_id`, `binding_id`); its snapshots go to the Project's repository, as above. A cwd outside every git work tree and every connected folder has no Project, as before. A session that starts in a folder connected to an organization's team Project, after it was connected, is the team's ([`capture-v1.json`](../../contracts/sessions/capture-v1.json) `team_session_stream.routing`)
|
|
103
|
+
Each session goes where its folder's Project says ([ADR-0016](../../apps/user-center/docs/decisions/adr-0016-org-git-workspaces.md) W-7). The daemon reads your folder bindings on this computer in every account it holds a login of, once a minute, and resolves a session's cwd to the nearest connected folder that holds it; a git work tree none of whose folders is connected gets its implicit personal Project, made at its first capture (its origin's, or one named after its root folder). The raw session and every record go to your personal store, and records of a session with a Project name it (`project_id`, `binding_id`); its snapshots go to the Project's repository, as above. A cwd outside every git work tree and every connected folder has no Project, as before. A session that starts in a folder connected to an organization's team Project, after it was connected, is the team's ([`capture-v1.json`](../../contracts/sessions/capture-v1.json) `team_session_stream.routing`), and the team sees its metadata only ([ADR-0017](../../apps/user-center/docs/decisions/adr-0017-projects-forks-visibility.md)'s metadata-only amendment): its raw lines stay in your personal store, its records go to the organization's `proc.inbox` in the published form (the device named only by its handle there, paths relative to the folder), and its snapshots to the team Project's repository. A teammate reads its title, state and each turn's written paths, never its turns; those reach a teammate only with a handoff, whose excerpt of the last turns your computer attaches after the secret filter ([`secret-patterns-v1.json`](../../contracts/sessions/secret-patterns-v1.json)): keys, tokens, private keys and passwords become `[redacted:<rule>]`. Lines a team session sent to `session.t.<session id>` in the organization's store before the amendment stay there; its next lines go to your personal store. A session that started before the folder was connected stays in your personal store, raw, with no Project and no snapshot. Only a yes given on this computer shares: `connect --account` records it in `folders.json` for the binding it was given for, and the team's sessions are those started after both the binding and the yes. A folder connected to an organization before the warning existed shares nothing (its sessions stay personal, with no Project and no snapshot, and the daemon logs why) until you run `yield connect --account <name>` there and answer yes. `yield ps --account <name>` lists the team's sessions, every member's, by metadata; `yield session read <id> --account <name>` reads only your own and refuses a teammate's, and `files` and `why` show a teammate's turns without their text.
|
|
93
104
|
|
|
94
105
|
The daemon uses the saved logins only, the personal account's for everything; `TONBO_API_KEY` does not name a device. One daemon runs per state directory.
|
|
95
106
|
|
|
@@ -128,6 +139,10 @@ yield need-human "<why>"
|
|
|
128
139
|
yield pull <session-or-link> [--patch]
|
|
129
140
|
yield show <link>
|
|
130
141
|
yield renew <link> [--result]
|
|
142
|
+
yield handoffs [--account <organization>]
|
|
143
|
+
yield events [--after <seq>] [--wait <seconds>] [--account <organization>]
|
|
144
|
+
yield cancel <link>
|
|
145
|
+
yield inbox [--all] | ack [<id>...] | ignore <id>... | rate <id> useful|noise | mute | unmute
|
|
131
146
|
```
|
|
132
147
|
|
|
133
148
|
A handoff is in the Project of the folder it is made in. In a personal Project you hand a session to yourself on another computer or harness. In a shared team Project (`yield connect --account <organization>`) you hand it to any member, or with `--to <name>` to one member; `--to claude-code` or `--to codex` is you on that harness. A member's login of the organization is what makes and takes team handoffs, so the teammate needs one on their computer (`yield login --account <organization>`). Handing off to a device is not available in this release.
|
|
@@ -137,6 +152,10 @@ A handoff is in the Project of the folder it is made in. In a personal Project y
|
|
|
137
152
|
- Inside that worktree, `done` pushes and pins the result and records the handoff done; `need-human` records that it is waiting on you. Both use the login of the account the handoff is in.
|
|
138
153
|
- `pull` fetches the latest unpulled result of a session (or a handoff link) onto a branch, or with `--patch` into a patch file, without changing your worktree. The author pulls a teammate's result the same way.
|
|
139
154
|
- `show` prints a handoff's state, author, who it is for and who took it, and its captured context, without taking it. Any member can show a team handoff.
|
|
155
|
+
- `handoffs` lists your open handoffs (created, taken, running or waiting on a human) that you gave, hold, or are named in, across your personal account and every organization; `--account` narrows to one. It shows metadata only.
|
|
156
|
+
- `events` prints handoff transitions after a cursor, such as a teammate taking yours, with a `Next:` cursor for the following read; `--wait` holds up to 25 seconds for the first one. A handoff you can no longer see drops out.
|
|
157
|
+
- `cancel` withdraws a handoff you gave before anyone takes it and releases its snapshot pin. A take that loses to someone else names who holds it.
|
|
158
|
+
- `inbox` lists the messages the daemon keeps for you on this computer: a handoff that names you or is open to your team, and one you gave being taken, finished, failed, returned or waiting on you. Only the ones where you must act or a result is ready raise a system notification (Notification Center on macOS, `notify-send` on a Linux desktop; elsewhere they only reach the inbox); `mute` stops them. `ack` marks messages read, `ignore` sets them aside and `rate` records whether one was useful. Messages carry the handoff's link, task and who acted, never its turns. The daemon starts after the events already there when it first runs; `handoffs` lists what is open.
|
|
140
159
|
|
|
141
160
|
## Alpha metrics
|
|
142
161
|
|
|
@@ -148,7 +167,7 @@ During the Alpha, `yield` records a few content-free measures on your personal a
|
|
|
148
167
|
|
|
149
168
|
## The Tonbo skill
|
|
150
169
|
|
|
151
|
-
`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.
|
|
170
|
+
`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. Every daemon start refreshes yield's own unchanged copies to the skill of the running version, and the daemon restarts itself within a minute when an in-place upgrade (`npm install --global @tonbo/yield`) puts a new version on disk, so either upgrade path reaches both agents; a copy you edited or removed is left as it is. `yield status` reports the skill's version on each copy. `CLAUDE.md` and `AGENTS.md` are never edited.
|
|
152
171
|
|
|
153
172
|
## Environment
|
|
154
173
|
|