@uiid/bertrand 0.10.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 uiid
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,200 @@
1
+ # bertrand
2
+
3
+ Multi-session workflow manager for Claude Code. Tracks concurrent Claude Code sessions, captures their timelines into a local database, and surfaces them in a dashboard for review.
4
+
5
+ > **Status:** TypeScript rebuild. The previous Go release (v0.9.1) is still on Homebrew but no longer developed against this branch.
6
+
7
+ ## How it works
8
+
9
+ Bertrand wraps Claude Code with two pieces:
10
+
11
+ 1. **A system-prompt contract** that tells the agent to call `AskUserQuestion` every turn with concrete, actionable options.
12
+ 2. **Claude Code hooks** that observe tool calls and lifecycle events (`PreToolUse`, `PostToolUse`, `UserPromptSubmit`, `Stop`, `PermissionRequest`) and write structured events into a local SQLite database.
13
+
14
+ The agent never knows bertrand exists. Hooks fire, scripts call `bertrand update`, rows land in the DB, the dashboard reads them.
15
+
16
+ When a session calls `AskUserQuestion`, bertrand marks it `waiting`, sets a Wave Terminal badge, and sends a notification. When you answer, the badge clears and the session moves to `active`.
17
+
18
+ ## Prerequisites
19
+
20
+ - **[Claude Code](https://code.claude.com/docs/en/overview)** — `--append-system-prompt` and hooks support required.
21
+ - **[Bun](https://bun.sh/)** ≥ 1.3 — runtime for bertrand and the dashboard.
22
+ - **[Wave Terminal](https://www.waveterm.dev/)** — optional, but the only supported terminal for badges/notifications. Without it, bertrand still tracks state; you just don't get focus management.
23
+
24
+ ## Install
25
+
26
+ ```sh
27
+ bun i -g @uiid/bertrand # or: npm i -g @uiid/bertrand
28
+ ```
29
+
30
+ The first run of `bertrand` auto-runs `init`; you can also invoke `bertrand init` explicitly.
31
+
32
+ ### From source
33
+
34
+ ```sh
35
+ git clone https://github.com/uiid-systems/bertrand.git
36
+ cd bertrand
37
+ bun install
38
+ bun run src/index.ts init
39
+ ```
40
+
41
+ Invoke via `bun run src/index.ts <command>` while developing.
42
+
43
+ ## Setup
44
+
45
+ ```sh
46
+ bertrand init
47
+ ```
48
+
49
+ This:
50
+
51
+ 1. Creates `~/.bertrand/` with `config.json` and `bertrand.db`.
52
+ 2. Installs hook scripts to `~/.bertrand/hooks/`.
53
+ 3. Registers them in `~/.claude/settings.json`.
54
+ 4. Writes shell completions to `~/.bertrand/completions/`.
55
+
56
+ Re-run `init` whenever bertrand updates — hook scripts are versioned and may need refreshing.
57
+
58
+ ## Usage
59
+
60
+ ### Launch a new session
61
+
62
+ ```sh
63
+ bertrand
64
+ ```
65
+
66
+ Opens an Ink TUI to type a session name (e.g. `bertrand/fix-recap-render`, `frontend/ENG-142-auth`). Slashes nest the session under group folders. Claude Code launches with the bertrand contract applied.
67
+
68
+ ### Resume
69
+
70
+ ```sh
71
+ bertrand <group/session>
72
+ ```
73
+
74
+ Shows a picker: start a fresh Claude conversation, or resume one of the prior conversations on this session. Either way, bertrand re-injects the session timeline and any sibling-session context.
75
+
76
+ ### List
77
+
78
+ ```sh
79
+ bertrand list
80
+ ```
81
+
82
+ Interactive picker showing all sessions with status badges.
83
+
84
+ ### Other commands
85
+
86
+ | Command | Purpose |
87
+ |---|---|
88
+ | `bertrand log <session>` | Print the timeline event log for a session. |
89
+ | `bertrand stats <session>` | Print materialized stats (duration, work/wait split, lines changed). |
90
+ | `bertrand archive <name>` | Archive or unarchive a session. |
91
+ | `bertrand serve` | Start the dashboard HTTP API on `:5200`. |
92
+ | `bertrand backfill-stats` | Re-compute stats for older sessions after schema changes. |
93
+ | `bertrand update` | Hook-facing event writer. Internal — don't call directly. |
94
+
95
+ ## Dashboard
96
+
97
+ A Vite + React + TanStack Router app at `dashboard/`. Renders timelines (assistant text, thinking, code diffs, permissions, Q&A pairs, context snapshots), engagement stats, and a session sidebar.
98
+
99
+ Run both the API and the dev server:
100
+
101
+ ```sh
102
+ cd dashboard
103
+ bun run dev
104
+ ```
105
+
106
+ This spawns `bertrand serve` (API on `:5200`) and `vite` (dashboard on `:5199`). Visit [http://localhost:5199](http://localhost:5199). The dashboard proxies `/api` to `:5200`.
107
+
108
+ > The dashboard is currently dev-mode only. There's no production build/serve path yet.
109
+
110
+ ## Session states
111
+
112
+ | Status | Meaning |
113
+ |---|---|
114
+ | `active` | Agent is generating a response. |
115
+ | `waiting` | Agent called `AskUserQuestion`, blocked on user input. |
116
+ | `paused` | Session ended (Claude Code exited). |
117
+ | `archived` | Manually archived; hidden from default views. |
118
+
119
+ ## Focus management (Wave)
120
+
121
+ When a session enters `waiting`, hooks call `wsh badge` to mark the block tab and `wsh notify` to send a notification. When it returns to `active`, the badge clears.
122
+
123
+ Other terminals fall back to no-ops; the session state is still tracked.
124
+
125
+ ## Architecture
126
+
127
+ ```
128
+ Claude Code hook → ~/.bertrand/hooks/*.sh → `bertrand update --event …` → SQLite (events table)
129
+
130
+ /api/events/:sessionId
131
+
132
+ dashboard timeline
133
+ ```
134
+
135
+ Key tables ([`src/db/schema.ts`](src/db/schema.ts)):
136
+
137
+ - **`groups`** — nestable session containers.
138
+ - **`sessions`** — named workspaces, status-tracked.
139
+ - **`conversations`** — Claude conversations within a session (claude_id UUIDs).
140
+ - **`events`** — every hook firing and lifecycle moment (`session.waiting`, `session.answered`, `tool.applied`, `context.snapshot`, `session.recap`, etc.). Free-form `meta` JSON column.
141
+ - **`session_stats`** — materialized stats, refreshed at session end.
142
+ - **`worktree_associations`** — tracked worktree branches per session.
143
+
144
+ Stats are computed live for `active`/`waiting` sessions and read from the materialized row otherwise — see [`src/server/index.ts`](src/server/index.ts).
145
+
146
+ ## File layout
147
+
148
+ ### Repo
149
+
150
+ ```
151
+ src/
152
+ cli/ # Command router and command handlers
153
+ contract/ # System-prompt contract (AskUserQuestion loop, sibling context)
154
+ db/ # Drizzle schema, migrations, query functions
155
+ engine/ # Session lifecycle (launch, resume, finalize)
156
+ hooks/ # Hook script generation (bash templates)
157
+ lib/ # Timing FSM, diff stats, engagement, formatting, tests
158
+ server/ # Bun HTTP server (/api/*)
159
+ terminal/ # Terminal adapters (Wave, Noop)
160
+ tui/ # Ink-based TUI screens
161
+ dashboard/
162
+ src/
163
+ api/ # Typed TanStack Query hooks
164
+ components/ # Timeline content renderers, sidebar, markdown
165
+ lib/ # Event categories, transforms, formatting
166
+ routes/ # TanStack Router pages
167
+ schema/ # Drizzle migration SQL
168
+ ```
169
+
170
+ ### Runtime
171
+
172
+ ```
173
+ ~/.bertrand/
174
+ config.json # Terminal + bertrand settings
175
+ bertrand.db # SQLite (sessions, events, stats)
176
+ hooks/
177
+ on-waiting.sh # PreToolUse AskUserQuestion → session.waiting
178
+ on-answered.sh # PostToolUse AskUserQuestion → session.answered
179
+ on-active.sh # PreToolUse catch-all → session.active
180
+ on-permission-wait.sh # PermissionRequest → permission.request
181
+ on-permission-done.sh # PostToolUse catch-all → permission.resolve
182
+ on-user-prompt.sh # UserPromptSubmit → user.prompt
183
+ on-done.sh # Stop → session.paused
184
+ completions/ # Shell completion scripts
185
+ ```
186
+
187
+ ## Development
188
+
189
+ ```sh
190
+ bun run typecheck # Type-check src/
191
+ bun test # Run backend tests
192
+ bun run db:generate # Generate Drizzle migration after schema change
193
+ bun run db:migrate # Apply migrations to ~/.bertrand/bertrand.db
194
+ ```
195
+
196
+ The dashboard has its own `tsc -b` typecheck — run from `dashboard/`.
197
+
198
+ ## License
199
+
200
+ MIT