diff --git a/README.md b/README.md index d4baca3..cd338f0 100644 --- a/README.md +++ b/README.md @@ -43,15 +43,15 @@ To set options, use the object form: A running TUI picks up `cli.json` changes immediately. On first use it installs the package into its own cache under `~/.cache/opencode/npm/` on Linux — one millisecond-timestamped generation per spec, for example `opencode2-tps@latest//`, with the newest generation winning. -The host reuses the newest installed generation without contacting the registry, so a restart alone may not pick up a new release. To upgrade, delete the spec's cache directory and restart: +The host reuses the newest installed generation without contacting the registry, so a restart alone may not pick up a new release. Delete the spec's cache directory and restart to upgrade: ```sh rm -rf ~/.cache/opencode/npm/opencode2-tps@latest ``` -To pin a version instead, put the range in the entry — `"opencode2-tps@0.1.0"`. Every distinct entry gets its own cache directory. +Put the range in the entry to pin a version instead — `"opencode2-tps@0.1.0"`. Every distinct entry gets its own cache directory. -The plugin ID is `opencode2.tps`. To switch it off without losing the entry and its options, add `"-opencode2.tps"` after it: +The plugin ID is `opencode2.tps`. Add `"-opencode2.tps"` after it to switch it off without losing the entry and its options: ```json { @@ -71,9 +71,9 @@ The defaults are usable as they are. For the full option list, the ranges and mo ## How it works -While output streams, the plugin estimates tokens from observable UTF-8 bytes at a default of 4.75 bytes per token and calculates a bounded rolling delivery rate. Complete text, reasoning, and tool-input events reconcile buffered or missed deltas without creating artificial live-rate spikes. +The plugin estimates tokens from observable UTF-8 bytes at a default of 4.75 bytes per token and calculates a bounded rolling delivery rate while output streams. Complete text, reasoning, and tool-input events reconcile buffered or missed deltas without creating artificial live-rate spikes. -At the end of each model step, OpenCode's reported output and reasoning usage replaces the byte estimate. Settled TPS divides those exact tokens by observed step spans ending at `session.step.streamed`, the host's authoritative end of the model stream, published before local tools join. Hosts that do not publish the event fall back to the final model-content boundary. Either way, local tool execution and time between model calls are excluded. +OpenCode's reported output and reasoning usage replaces the byte estimate at the end of each model step. Settled TPS divides those exact tokens by observed step spans ending at `session.step.streamed`, the host's authoritative end of the model stream, published before local tools join. Hosts that do not publish the event fall back to the final model-content boundary. Either way, local tool execution and time between model calls are excluded. OpenCode's built-in assistant-footer t/s divides visible output tokens by the same step spans, leaving hidden reasoning out of its numerator. This plugin counts output plus reasoning, so on reasoning models its settled figure reads higher than the built-in one — those tokens were generated too. @@ -85,7 +85,7 @@ For more detail, see [Architecture](docs/development.md#architecture). Every output event carries the ID of the session that produced it, so each session is measured on its own. -A sub-agent streams under its own child session ID. While it works, the orchestrator's number stops moving and holds the average of the output the orchestrator produced before delegating. Open the sub-agent's session to watch its live throughput. +A sub-agent streams under its own child session ID. The orchestrator's number stops moving while it works and holds the average of the output the orchestrator produced before delegating. Open the sub-agent's session to watch its live throughput.

Sub-agent session showing its own live throughput indicator diff --git a/docs/configuration.md b/docs/configuration.md index ae24d9d..0d28c6a 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -2,7 +2,7 @@ Options go in the `options` field of the plugin's `cli.json` entry. -The plugin always loads. An unknown key, or a value of the wrong type, falls back to the default; a number outside its range is clamped to the nearest limit. +The plugin always loads. An unknown key is ignored; a value of the wrong type falls back to the default; a number outside its range is clamped to the nearest limit. | Option | Default | Range | Description | | --------------- | -------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------ | diff --git a/docs/development.md b/docs/development.md index f2ba676..96222d3 100644 --- a/docs/development.md +++ b/docs/development.md @@ -10,7 +10,14 @@ npm test # bun test npm run build # write dist/tui.js and its sibling modules ``` -Tests run through `bun test`. `bunfig.toml` preloads `@opentui/solid/preload` so tests use Solid's client build and can observe reactive updates. `tests/tracker.test.ts` covers the throughput tracker, `tests/options.test.ts` the option parsing and label formatting, `tests/debug.test.ts` the debug switch, `tests/plugin.test.ts` the event wiring through a fake context and a patched `setInterval`, `tests/options-schema.test.ts` pins `options.schema.json` and the docs to the same constants the parser uses, and `tests/entrypoint.test.tsx` runs `scripts/build.mjs`, imports `dist/tui.js`, and renders the composer claim with `testRender` asserting the label appears while streaming, settles and freezes, resets for a new prompt, and stays per-session. +Tests run through `bun test`. `bunfig.toml` preloads `@opentui/solid/preload` so tests use Solid's client build and can observe reactive updates. + +- `tests/tracker.test.ts` covers the throughput tracker. +- `tests/options.test.ts` covers the option parsing and label formatting. +- `tests/debug.test.ts` covers the debug switch. +- `tests/plugin.test.ts` covers the event wiring through a fake context and a patched `setInterval`. +- `tests/options-schema.test.ts` pins `options.schema.json` and the docs to the same constants the parser uses. +- `tests/entrypoint.test.tsx` runs `scripts/build.mjs`, imports `dist/tui.js`, and renders the composer claim with `testRender`, asserting the label appears while streaming, settles and freezes, resets for a new prompt, and stays per-session. `scripts/*.mjs` run under plain node and stay outside the `tsconfig.json` typecheck — they are exercised by CI and the entrypoint test instead. @@ -39,7 +46,7 @@ The host also picks up plugins from a `plugin` or `plugins` directory in the con ## Build -The host only applies the Solid transform outside `node_modules`, and an installed package lives inside it, so `scripts/build.mjs` runs the transform ahead of time and writes `dist/tui.js` plus its sibling modules (`dist/tracker.js`, `dist/options.js`, `dist/debug.js`), which the entrypoint imports relatively. See `scripts/build.mjs` and the `exports` and `files` fields in `package.json`. The tarball ships only `dist` and `options.schema.json`, so `tui.tsx` never reaches the package — it exists only for path entries. +`scripts/build.mjs` runs the transform ahead of time and writes `dist/tui.js` plus its sibling modules (`dist/tracker.js`, `dist/options.js`, `dist/debug.js`), which the entrypoint imports relatively, because the host only applies the Solid transform outside `node_modules` and an installed package lives inside it. See `scripts/build.mjs` and the `exports` and `files` fields in `package.json`. The tarball ships only `dist` and `options.schema.json`, so `tui.tsx` never reaches the package — it exists only for path entries. `solid-js` and `@opentui/solid` are optional peer dependencies; the host supplies its own copies. @@ -66,7 +73,7 @@ That means one directory and one log per PID. Hot reloads append to the same fil - A finished run keeps its state until the next run replaces it, and the number of tracked sessions is bounded. See `MAX_TRACKED_RUNS` in `src/tracker.ts`. - A generation guard makes sure only the newest generation of the plugin counts tokens and renders. -For the event names and the formulas, read `src/`. +Read `src/` for the event names and the formulas. ## Example run diff --git a/docs/release.md b/docs/release.md index 89ae06c..6db36e5 100644 --- a/docs/release.md +++ b/docs/release.md @@ -6,7 +6,7 @@ A path entry loads the `tui.tsx` source through the host's transform; an install The pinned `@opencode/*` beta is the build and test baseline. Move it in the same pull request as the fix or feature that needs it; CI validates the pin format, the README compatibility floor, and that the installed CLI reports the pinned version. -A docs-only release skips steps 1 to 5. The bundle is unchanged, and CI already packs and imports the artifact on every push to `main`. Go straight to step 6. npmjs.com only refreshes the rendered README when a new version is published, so a README change that matters on the package page needs a patch release to reach it. +A docs-only release skips steps 1 to 5. The bundle is unchanged, and CI already packs and imports the artifact on every push to `main`. Go straight to step 6. A README change that matters on the package page needs a patch release to reach it, because npmjs.com only refreshes the rendered README when a new version is published. ## 1. Build the tarball