codeburn/docs/providers/lingtai-tui.md
Rick Culpepper (claude) 4ca2d4824b
Scope the root test script to tests/ so npm test runs from a clean install
vitest's default glob reached the Electron app's specs under app/, which carry their
own vitest config and their own jsdom in app/node_modules. From a root install that
fails with ERR_MODULE_NOT_FOUND: jsdom, so the command CONTRIBUTING documents and the
one RELEASING.md names as the pre-release gate both error out.

Move the scoping CI already applies into package.json: test runs tests/ minus the
parallelism-sensitive cache-refresh-lock suites, test:locks runs those three serially,
test:watch keeps watch mode at the same scope. The first two are byte-identical to the
invocations .github/workflows/tests.yml spells out, so the workflow can be pointed at
the scripts to stop the two drifting apart again; that edit is left out of this PR so it
needs no workflow permissions. test plus test:locks together still cover all 192 files
under tests/.

Scoping the script changes what a trailing path argument means: vitest ORs positional
filters, so 'npm test -- tests/providers/hermes.test.ts' would no longer narrow to that
file, it would run the whole suite. Rewrite those to 'npx vitest run <path>' everywhere
they appear - four provider guides and the MCP design plan, thirteen lines in all.

Also refresh the stale test docs: 42 files/568 tests (now 192 under tests/), the
per-directory counts, the line claiming vitest does not run in CI which stopped being
true when tests.yml landed, and the provider test-gap list, which still named
antigravity and gemini after both gained test files.

Record the cache-refresh-lock naming convention in CONTRIBUTING, since the split makes
it load-bearing: a lock test that misses the prefix runs under the full worker pool and
flakes, and one that matches it but is absent from test:locks never runs at all.
2026-08-09 10:19:58 -05:00

3.8 KiB

LingTai TUI

LingTai TUI per-agent token ledger integration.

  • Source: src/providers/lingtai-tui.ts
  • Loading: eager (src/providers/index.ts)
  • Test: tests/providers/lingtai-tui.test.ts

Where it reads from

Source Path
Explicit LingTai homes $LINGTAI_HOME or $LINGTAI_TUI_HOME if set; path-list values are supported
Default LingTai home ~/.lingtai
Project LingTai homes <project>/.lingtai for projects registered in ~/.lingtai-tui/registry.jsonl and ~/.lingtai-tui/brief/projects/*/meta.json
Current worktree home .lingtai in the current directory or any parent directory
Agent ledgers <lingtai-home>/<agent>/logs/token_ledger.jsonl

Daemon ledgers nested under <agent>/daemons/... are deliberately not discovered during normal scanning. LingTai mirrors daemon usage into the parent agent ledger with source, em_id, and run_id tags, so reading nested ledgers too would double count spend.

Storage format

Append-only JSONL. Each valid ledger line may include:

  • source
  • em_id
  • run_id
  • ts
  • input
  • output
  • thinking
  • cached
  • model
  • endpoint

Malformed lines and zero-token entries are skipped. Missing model falls back to the agent .agent.json llm.model, then unknown.

Parser

CodeBurn emits one parsed call per ledger entry. LingTai records provider-normalized total input plus a separate cached counter, so the provider maps:

  • input - cached -> fresh input tokens
  • cached -> cache-read tokens
  • output -> output tokens
  • thinking -> reasoning tokens

Costs are calculated from CodeBurn's normal model pricing table.

Activity mapping

LingTai's token ledger is an accounting source, not full chat history, so it does not include the original user prompt or per-tool transcript. CodeBurn maps the ledger source field conservatively:

LingTai source CodeBurn activity
main and unknown sources Conversation
tc_wake and other task-coordinator wake sources Delegation
daemon Delegation
summarize_apriori Planning

This keeps the menubar and dashboard By Activity view from collapsing all LingTai usage into Conversation while avoiding invented feature/debug/refactor semantics that the ledger cannot prove.

Project grouping

Discovery reads <agent>/.agent.json and groups by nickname, agent_name, address, then the directory name. Project-local homes are prefixed with the project directory name, for example sample-project-Project Agent, so same-named agents from different LingTai projects do not collapse together. The parsed call also carries the agent directory as projectPath.

Caching

The shared session cache fingerprints each token_ledger.jsonl. LINGTAI_HOME, LINGTAI_TUI_HOME, and LINGTAI_TUI_GLOBAL_DIR are part of the provider environment fingerprint so changing homes invalidates stale cached results.

Deduplication

Dedup keys include provider name, ledger path, line number, timestamp, model, endpoint, LingTai source tags, and token counts:

lingtai-tui:<ledger-path>:<line>:<timestamp>:<model>:...

The ledger is append-only, so line number is stable for normal operation.

Quirks

  • Tool calls are not reconstructed from chat history. The token ledger is the stable accounting source and does not include tool metadata.
  • Older ledger entries may not include source; those are labeled main.
  • cached is treated as cache read. LingTai does not expose a separate cache creation counter in the ledger.

When fixing a bug here

  1. Prefer a minimal redacted token_ledger.jsonl fixture over full chat_history.jsonl.
  2. Check whether a daemon entry is already mirrored into the parent ledger before adding new discovery paths.
  3. Run npx vitest run tests/providers/lingtai-tui.test.ts.