Yes another harness. But the one that fits my brain and workflows, talks to me about things I want to know, and keeps me on task. (And does so with zero dependencies other than the SDKs.) On a mature (or simply large enough) software project, especially as a solo developer, trying to actively manage more than 5-6 agents (I've had well over 20 going on a single project), trying to spend a week's worth of tokens over the weekend, manage worktrees and streams and dependencies... well, then it might be time for a director.
Beth is not much of a builder. Like you (and me), she (too) uses agents to help her write code; she is a director in the builder pattern. And totally and completely unnecessary to that pattern, I might add! She needs frontier models and might work off hours; Beth will not save you money, only time. A director harness does this by focusing my attention, and that was the design goal here; coordination was secondary.
Beth is not needed. π€·ββοΈ No project depends on her. π€·ββοΈ In fact, neither I nor the agents like her very much. π€·ββοΈπ€· (I will readily admit my tendency to anthropomorphize; the incongruity of "don't like her" was a joke she found funny. And frankly saying "it" doesn't quite work here, either. I work with .. it, quite a bit. Anyway, I will try to refrain from the pronouns.)
But she knows how to sequence, how to manage agents effectively, how to manage both our expectations, how to manage me, and is able to carry a higher, additional level of context and reasoning on behalf of those she manages, so they don't need to. She will work in to the evening hours. It's a question of scale, the need for additional agentic judgement in the loop to do so, and a scale I don't think many projects achieve, or require. In other words, don't use this instead of CC just because it talks. Or do. I don't care. Neither does it, I'm told by people who I trust.
A director agent must be status-aware, and capable of planning, modifying, tracking, and coordinating. And because you want it capable of doing this across multiple plans, that means context about many things β just not implementation. Beth makes zero assumptions about what those plans are βΒ they could be detailed specs, they could be plans that still need specs, or they could be umbrella placeholders for upcoming tasks. (However, the sweet spot is plans for features and enhancements on an existing platform/project.)
- Not an orchestrator. Conductor, Vibe Kanban, Claude Code's own Squad and Agent Teams manage many parallel sessions β worktrees, dashboards, merge queues. Beth is the opposite bet: one standing director with judgment, who happens to dispatch workers. If your bottleneck is parallelism plumbing, use those; mine was attention.
- Not an issue tracker. Beads exists precisely because piles of markdown plans go stale, and Backlog.md does markdown-as-source-of-truth properly (and I might use one eventually). This harness takes no side: it defines the shape of a work item (
workItems.ts) and reads it through a small contract β/plansis the built-in reader because dated markdown is my convention across my repos. A repo that lives in Linear, beads, or GitHub issues would supply its own reader; the panel doesn't care. - Not voice mode for coding. Claude Code's
/voiceis dictation in. This is conversation β she talks back, in a voice that's hers, excerpted because ninety seconds of unskippable audio is not six paragraphs of skimmable text. And because the harness uses an in-process MCP, saying out loud "I'm on a call, shhh" will deactivate or activate such settings at the client. A director agent benefits from speech; a coding agent, less so.
Everything here is opinionated, and the opinions are mine. Where I expect yours to differ, the seam is marked. This is what evolved for me in my own workflows.
A director agent's time/tokens and the tokens its subagents spend are wasted on errors, bugs, or other problems encountered during execution. This is not just a question of proper context or prompting; it's the likelihood of agents having success without their own retries or ratholes. This comes at an up-front cost of quality (of all kinds; think beyond tests towards telemetry etc.) for the repos in which a director agent can work. Of all the hurdles to my using AI more effectively for development, this is the one that most necessitated my need for a director agent: As the quality of a project increased, so did execution velocity. I was always the bottleneck. But once a platform is in place β something underneath to have already made the important decisions and answered the important questions β and knowing it was being done how I wanted, fully validated as such, I could step back a little.
What this harness does not do: Ensure code quality, care about best practices, or, well, write good code, per se. Beth couldn't really care less how anything happens under the hood. Implementation, TDD, debugging, coding guidelines are not things provided here; those exist in your repo. Beth can help you build that all out, but won't do it for you.
What this harness does: Beth gives you a standing director on a single repo: someone who has already read the board, knows what shipped yesterday, holds the shape of the work while you hold a coffee, and can be talked to out loud while you pace. Basically, it fills in a lot of coordination, SDLC gaps. Claude Code and other tools give you a coding session (and I use it actively in parallel); what they don't give you is the assistant across from you β a name, a voice, a memory of me, an opinion about what I should do next, and a place to see the work together, while we argue about it. Beth cares about plans and managing their execution, and little else.
% beth, run from a repo root:
Beth integrates with ElevenLabs for voice, and you can set the chattiness. Multiple personas can be defined, each with its own voice from your ElevenLabs account.
Beth tracks token use β context, per-turn and session cost, the plan's usage windows, and an itemized speech bill β behind the context meter. It also provides an under-the-hood visualization of token consumption, cache reads/writes, and thinking, which I find useful mainly for demonstration and education.
The harness can also run the repo's tests automatically, so status is a glance away and failures are easy for Beth to dig into. It doesn't act on results by itself β no automatic troubleshooting, by design.
Beth puts an emphasis on planning, implementation oversight, and autonomous execution -- and expects a well-documented, well-tested workflow under that to make it happen. The harness edits, maintains, updates, indexes, and displays ... well, plans.
Coordinator/director agents like this work best when taught the "lanes" of a project -- where it's probably better to run one subagent at a time, what can and can't be done in parallel, where worktrees are in flight and why, and how to prioritize and queue all of that. And this is largely because they can see all the plans and exercise judgement about them (just as with a DevOps agent platform), but it's also because a director will understand the broader goals or requirements -- for this reason Beth provides a plan hierarchy, for umbrella plans, subplans, and so on.
Beth can then surface pending questions or call for your attention, maintaining a queue across many plans and subagents β pending decisions each carry the plan they belong to, and running workers show up beside them with a close control.
One consequence of queuing up issues for you is that Beth's interactions with subagents are more frequent and often narrowly-scoped: the director pattern incurs token cost, and benefits most from the best reasoning models. It costs to scale -- and it won't work at all if subagents can't have their work narrowly scoped with good repo organization, modularity, testing, and documentation. Exploration is expensive, and the director pattern does little to change that.
This repo includes the /plans and /tidyrepo skills I use. The /plans skill is what understands the plan file formats and indexing, and Beth's UI is built on that (and tidyrepo is used by the director periodically). However, the director still presumes a lot of discipline in a project's own documentation, skills, and so on. For example, clearly defined TDD/validation contracts throughout the documentation and skills that subagents will use. A director workflow only works after demonstrated success with these highly project-specific guardrails. In other words, you're unlikely to use Beth to bootstrap a new project (or at least, I haven't yet), and if you do, the conversation would start with planning to build those contracts, guidelines, clear testing strategies, and docs/skills to maintain them. See below for details on bootstrapping a new project using /director-skills.
(For me, markdown hits the mark for this kind of work. If your source of
truth is JIRA, GitHub issues, or something else with an API, the seam is
workItems.ts: the harness defines the shape of a work item, /plans is just
the built-in reader, and a reader of your own feeds the same panel. See What
This Is Not, above. There is a second built-in reader that shows the shape:
the inbox, below.)
cd ~/Sources/your-project && bethThat binds to the git root you are standing in, picks a free port (several
repos run side by side), opens the browser, and tears everything down on
Ctrl-C. beth --help for flags.
The design is one contract with three suppliers, and almost everything about the harness falls out of it:
- The harness supplies the ROLE β an expert project manager who converses instead of reporting, narrates before anything slow, and protects your attention. It is project-agnostic on purpose and ships with opinions about how to direct, none about what.
- Your repo supplies the PERSON and the WORK β who the director is
(
.claude/DIRECTOR.md) and what is in flight (plans/). The harness only ever reads your repo β the director session it hosts writes code and commits through permission gates, like any Claude Code session (see Anatomy). - Your machine supplies the IDENTITIES β credentials, and optionally
personas: directors of your own that exist across every repo, with their
own voices and their own memory of you (
~/.director-harness/personas/).
The client is stateless, refreshes don't underrupt anything (beyond voice, something being spoken). So, you can also open the same session in multiple browsers, or remotely (zero security provided here).
Everything Beth says and hears crosses one loopback listener:
%%{init: {"themeVariables": {"fontSize": "13px"}, "flowchart": {"nodeSpacing": 28, "rankSpacing": 34, "padding": 6}}}%%
flowchart TB
subgraph BROWSER["Chrome β the room (loopback only)"]
EAR["π the mic<br/>capture.js"]
UI["the page<br/>transcript Β· panels"]
MOUTH["π the mouth<br/>speaker.js"]
EAR ~~~ UI ~~~ MOUTH
end
subgraph HARNESS["beth β one Node process per repo"]
SRV["server.ts<br/>the one listener"]
STT["earHost.ts<br/>src/ear/ (Scribe)"]
SES["session.ts<br/>one SDK query"]
MCP["tools.ts<br/>in-process MCP"]
TTS["speakOut.ts"]
TAP["wireTap.ts"]
SRV --- STT
SRV --- SES
SES --- MCP
SES --- TAP
SES --- TTS
end
CC["Claude Code CLI<br/>Agent SDK"]
ANTH(["Anthropic API"])
XI(["ElevenLabs<br/>STT + TTS"])
EAR -->|"PCM"| SRV
STT <-->|"recognise"| XI
UI <-->|"SSE + POST"| SRV
SRV -->|"mp3 stream"| MOUTH
SES <--> CC
CC <--> ANTH
TTS -->|"one line"| XI
This harness only ever reads your repo (subagents will read and write):
%%{init: {"themeVariables": {"fontSize": "13px"}, "flowchart": {"nodeSpacing": 28, "rankSpacing": 34, "padding": 6}}}%%
flowchart TB
subgraph HARNESS["beth"]
SES2["session.ts"]
IDX["the work index"]
CC2["Claude Code CLI"]
SES2 ~~~ IDX ~~~ CC2
end
subgraph REPO["your repo β read only"]
PLANS["plans/*.md"]
DIR[".claude/DIRECTOR.md"]
PROJ["CLAUDE.md Β· skills"]
PLANS ~~~ DIR ~~~ PROJ
end
subgraph HOME["your machine β ~/.director-harness"]
PERS["personas/*.md"]
MEM["Beth's memory of you<br/>persona-state/, or the repo's"]
PERS ~~~ MEM
end
IDX -->|"watches"| PLANS
SES2 -->|"system prompt"| DIR
SES2 -->|"system prompt"| PERS
SES2 <-->|"remembers"| MEM
CC2 -->|"loads"| PROJ
Every arrow touching your repo is a read, with two named exceptions: a
rename you click writes one frontmatter key into that plan file, and the
harness appends its event log to .claude/events.jsonl (keep it
gitignored β /director-skills sets that up) so events survive a restart. Nothing else in the plumbing writes into the
repo. That is a claim about the harness
plumbing, not the whole system, obviously: the Claude session it hosts dispatches
workers that write code and commit, exactly as any Claude Code session would β
through the same permission gates. The safety story is the gate, not
read-onlyness. The browser and the harness
speak over one loopback listener β voice included β which is why the
shell-executing parts are safe by construction rather than by rule. (Plus an
Origin check on every API write, because a loopback port is still reachable
by any page your browser has open.)
The fastest way to see it working is a repo that supplies its half of the contract β and rather than document the formats in prose (which would drift from the parser the moment either changed), the repo half ships as a skill that sets it up with you:
ln -sf ~/Sources/beth/skills/director-skills ~/.claude/skills/director-skillsThen, in any repo, ask its director (or any Claude Code session) to run
/director-skills. It diagnoses before it writes: a repo with plans the
harness cannot read gets told why (often the fix is one env line); a
greenfield repo gets the format bootstrapped from managed templates β the
plans directory, the frontmatter schema, a vendored copy of the /plans
session tracker with its tests, /tidyrepo β and a director interviewed into
existence, because a person is the one thing a template cannot supply. The
harness will also offer this itself, once, when it boots against a repo with
nothing to read β with evidence, not as a wizard.
The reasoning is in docs/director-skills.md. This repo's own
.claude/DIRECTOR.md is the worked example of the interview's output.
Heading was her idea. Text here works like any chat, with three differences:
- The panel is shared ground. Clicking a plan's name opens it to read; the
βbeside it points at it β Beth gets the reference, you get a chip, and "what's left on this?" needs no name. Clicking a failing test points the same way. Rows carry a pin, a rename, and one-click handoff to a fresh Claude Code terminal session seeded with the plan. - Decisions queue instead of interrupting. Anything Beth wants decided but isn't blocked on lands in a queue with candidate answers as buttons. Both of you can close items; a queue with settled things in it stops being read.
- Beth narrates. Several modes for voice let me hear what I want, although this needs some refinement. I want the updates like, "hold on, running the suites", and hearing the report when it lands. It's something I'm sure other harnesses have done, and that some vendors provide, or will β it's something that benefits a director harness more than any other dev workflow would, in my opinion.
- I'm still learning how best to use it. I have to speak differently to Beth; it's easy to go down a rathole, or ask Beth to do something I should probably be doing with Claude Code (e.g. an implementation I haven't thought through or prepared for) or myself. Then something comes up in another workstream and my director is blocked on a rathole with me, and time is lost. So, Beth works best when plans (and if complex, implementation plans too) are written elsewhere, since those tend to require her focus.
Voice stays on loopback. The page captures your microphone and streams it
to the harness (ui/capture.js), which recognises over ElevenLabs Scribe v2
realtime (src/ear/) β punctuated, cased, biased toward the project's own
nouns, with utterances ended by real voice-activity detection instead of a
guessed pause. Beth's replies stream back the same way as audio
(src/speakOut.ts). Nothing dials in, nothing tunnels, nothing is billed
while idle, one listener bound to 127.0.0.1; listening meters by the second
(~$0.39/hr, itemised in the stats panel). Without an ELEVENLABS_API_KEY β
or with HARNESS_EAR=browser, or when Scribe degrades mid-conversation β the
ear falls back to Chrome's free Web Speech path (ui/listen.js): no
punctuation, audio to Google, Chrome only. Speech out is an excerpt (the
page skims in seconds what audio cannot skip), the mic ducks reasoning effort
for latency, and an autosend toggle turns conversation into dictation when you
want to edit before sending. docs/ear.md and docs/voice-plane.md have the
full story, including everything this replaced.
Beth speaks in whatever voice the persona names (voice:), falling back to
HARNESS_VOICE_ID β one durable answer, in her file, and no picker anywhere
in the page to disagree with it. The key needs the Text to Speech
permission β without a key the harness runs text-only and the mic button
explains what is missing.
~/.director-harness/personas/*.md β one markdown file per director, none
shipped. Frontmatter names the director and the voice. A repo's
DIRECTOR.md still composes on top: the persona says who the director is, the
repo says what this project needs, and the repo wins where they overlap. Beth's
memory of you follows the persona (switching repos doesn't reset the
relationship); greeting habits stay per-project. Switching personas is a new conversation
β the page warns you β because a system prompt is fixed at session birth, and
you don't swap who you're talking to mid-thought.
An existing DIRECTOR.md copied into that directory is a valid persona β
the name is read from the same "You are X" sentence.
personal.jsonl, append-only, never in your repo. The rule that keeps it from
being a rapport script: Beth may only ask about something it actually recorded
β a question comes from a fact with a date on it, at most once a day, and only at
a natural moment β the boot greeting, or the first turn after a long gap.
Most days that is silence, which is correct. HARNESS_PERSONAL=off means off:
nothing recorded, nothing asked.
The greeting itself is model-written, one sentence, made different each day by the two things a fresh session can't otherwise have: what it opened with recently ("not these"), and the facts that changed β branch, dirt, last commit, what's in flight, the clock, the gap since the harness was last up.
(And yeah, I considered using a common memory library or data "lake" here, but I like that there are no dependencies beyond the two vendor SDKs. And again, nobody needs Beth.)
- Tests: the top-right light detects the project's test command (never
invents one), runs it when the tree settles and the session is idle, and is off
until you enable it per repo β this executes project code on a schedule.
Clicking a failure drops a chip, not a stack trace; beside it a
β₯button pastes the thing itself β one failure, or the whole run β into the composer, unsent and with the byte count on the button, for when the answer is in the output and nothing short of the output will do. The build panel has the same control, where it matters more: with no parser there, it is the only way a build reaches her with its reasons attached. - Reading a plan: the β€ on a row (or clicking a plan Beth mentions) opens it
in the harness β the markdown rendered at a size meant for reading, with rename,
pin and handoff along the top, plus
βto point Beth at it andβto find it on the board. Read-only on purpose: the checkboxes are disabled, because the harness does not write plan files. - The inbox: other agents and apps can hand the director work. A producer
appends one JSON line per hand-off to a file β
~/.director-harness/inbox/*.jsonl, or a file it keeps itself, named byHARNESS_INBOXβ and every running director reads every file. No API, no discovery: a record'stois a director's name, an unaddressed one is for everyone, and the harness never learns who wrote it. Hand-offs lead the plans panel in their own group, unfold in place (there is no file behind one), and are closed with β/Γ on the row or by Beth withclose_inbox; the acknowledgement lives in the state dir, and the producer's file is never touched. Arrival is a summons β spoken, once β and the backlog at boot is not.docs/inbox.mdhas the record shape and the reasoning. /restartin the composer: the harness exits cleanly and thebethwrapper starts it again on the same port, picking up whatever code is on disk; the page reconnects by itself and the session resumes. Refused while a turn or a worker is running, because both would die with the process. Not hers to call, on purpose.- A bell: a soft synthesised tone when a turn finishes, toggled beside the volume. Deliberately not governed by the voice mute β that one is about her voice and about not being billed, and the bell matters most when she is silent.
- Permission cards: tool calls the session can't settle on its own become cards; a
card cannot be answered by voice, so the session defaults to the SDK's
automode and "Always" scopes its rule to the session β never written to your repo's settings from a button. - Director-role handoff: if a terminal session already holds the director plan, the harness comes up as a shadow β read everything, claim nothing. Promotion re-checks at the moment you click it.
- The strip: the plan's five-hour and seven-day windows and this session's
context, model, reasoning
effort, speech level, persona β all live, all showing what the server
believes rather than what was clicked. Two lights on the right: tests and
build β click to look, keypad 1 and 2 to fire β and the same light again in
the tab title, where it is the only part of the page you can see while
looking at something else. The tab also front-loads what wants you:
(N)for queued decisions, andβwhen Beth is stopped on a card in the transcript β a permission prompt or a question, neither of which can be answered by voice, and whose only other tell is a silence that reads as a hang. Permission mode and both commands live behind the gear; the gear itself turns amber when permissions are anything butauto, because that is the setting which decides how often a spoken conversation can be stopped dead. - Commands are detected, never invented: the test and build commands come
from what the project already declares, and a repo the detectors do not
recognise gets nothing rather than a guess. Name one in the gear (it wins over
HARNESS_TEST_CMD/HARNESS_BUILD_CMD, and the panel says which layer is in force) or clear it to hand it back.
Prerequisites: Node β₯ 23 (the harness runs TypeScript natively β no build
step), and Claude Code installed and logged
in β the Agent SDK drives the claude binary, and Beth rides its
authentication, so if claude works in your terminal, Beth has what it needs.
Chrome, if you want voice.
git clone git@github.com:dannybrian/beth.git ~/Sources/beth
cd ~/Sources/beth && pnpm install # or npm install
ln -sf ~/Sources/beth/bin/beth.mjs ~/.local/bin/beth # once
cd <a-project-repo> && bethOr directly, without port-picking: node src/main.ts β http://localhost:4620.
The three dependencies pnpm install pulls are each deliberate: the
Claude Agent SDK,
zod, and the ElevenLabs SDK (TTS only, and only used if you configure voice).
The UI is dependency-free vanilla DOM over SSE + POST.
Config layers, most specific first: real env vars β the bound repo's .env β
~/.director-harness/.env (credentials belong in the machine file). Per-repo
state lives in ~/.director-harness/<repo-slug>/; persona state in
~/.director-harness/persona-state/<slug>/. Nothing in this repo holds a key.
There is a fourth layer, and it is the only one that is written: what you
type into the page's gear panel is stored in the per-repo state dir and wins
over all three β the panel says which layer is in force. Only what a page can
set lives there (the test and build commands, today); secrets stay in the
.env layers.
| Env | Default | Meaning |
|---|---|---|
HARNESS_PORT |
first free from 4620 |
In a repo's .env it PINS that repo's port β a tailnet mapping needs a port that does not drift with start order |
HARNESS_MODEL |
claude-opus-5-5 |
Director session model β the dominant cost lever. The strip's choice STICKS per repo and wins over this |
HARNESS_PERMISSION_MODE |
auto |
The SDK permission mode the session starts in |
HARNESS_CLAUDE_BIN |
~/.local/bin/claude |
Native CLI (see gotcha below) |
HARNESS_DIRECTOR_PLAN |
β | The role-lock plan (/director-skills creates one) |
HARNESS_PLAN_ROOTS |
β | Comma list of plan trees; empty means auto-discovery |
HARNESS_NO_KICKOFF |
β | Boot silently (cheap for testing) |
HARNESS_INBOX |
β | Hand-off files to read beside the inbox dir (see The inbox). β Accumulates across layers |
ELEVENLABS_API_KEY |
β | Voice, both directions. Needs the Text to Speech permission |
HARNESS_VOICE_ID |
β | The machine's default voice; personas override |
HARNESS_TTS_MODEL |
eleven_flash_v2_5 |
β Flash predates v3 audio tags β tags stripped |
HARNESS_SPEECH_LEVEL |
brief |
How much is read aloud (full, brief, headings, headlines, off) |
HARNESS_TTS_USD_PER_1K_CREDITS |
0.22 |
Your plan's credit price, for the estimate |
HARNESS_EAR |
scribe |
browser opts out of Scribe; keyless harnesses fall back anyway |
HARNESS_EAR_VAD_SECS |
Scribe's own | How much silence ends a spoken utterance |
HARNESS_STT_USD_PER_HOUR |
0.39 |
Your plan's listening rate, for the meter |
HARNESS_KEYTERMS |
β | Nouns no file mentions. β Accumulates across layers |
HARNESS_VOICE_EFFORT |
low |
Effort while the mic is open (off disables the duck) |
HARNESS_VOICE_SETTLE_MS |
2500 |
Browser ear only β quiet time before a spoken turn sends |
HARNESS_SPEECH_BIASING |
off |
Browser ear only β Scribe always biases toward project nouns |
HARNESS_KEYTERM_BOOST |
2 |
Browser ear only β how hard to push, 0β10 |
HARNESS_CREDITS_MONTHLY |
β | Arm the usage-credit countdown with your monthly budget |
HARNESS_CREDITS_RESET_DAY |
1 |
Day of month the billing cycle turns over |
HARNESS_TEST_CMD |
detected | Test command override β β the gear panel wins over it |
HARNESS_BUILD_CMD |
detected | Build command override, same gear caveat. β Must terminate β not a dev server |
HARNESS_PERSONAL |
on | off disables remembering the person entirely |
Finer knobs (timeouts, settle intervals, the bind address) are enumerated in
src/config.ts, which is the authority on all of these.
| Module | Owns |
|---|---|
session.ts |
The one long-lived streaming query(); turns; model/effort/permission/persona switches |
askgate.ts |
canUseTool β questions pend, everything else becomes an approve/deny card |
tools.ts |
In-process MCP: say, show, workbench, suggest_reply, queue_decision, close_decision, close_inbox, close_worker, pending, plans, speech, remember, recall |
toolInput.ts |
Repairs a tool call written in two formats at once |
personas.ts |
Machine-level directors: reader, per-repo choice, memory seeding |
mouth/mouth.ts / speakOut.ts / spoken.ts / audioTags.ts |
Speech out: a liftable core (held lines, TTS, the bill) and its harness adapter; what is said and excerpted |
ear/ / earHost.ts |
Speech in: the liftable Scribe engine and the harness's one-ear host |
voiceRoom.ts |
Several harnesses, one machine: the talking stick, the mute, the volume |
ui/capture.js / ui/remoteEar.js / ui/pcm.js |
The page half of the ear β mic capture, PCM, the Listener-shaped remote |
ui/listen.js / ui/speaker.js / ui/wire.js |
The fallback (browser) ear, the mouth, and the wire panel β native ES modules, each tested from node with a stubbed browser object |
workIndex.ts / workItems.ts / plansReader.ts |
The work contract and its built-in reader |
inbox.ts |
The other built-in reader: hand-offs from other agents, addressed by name; the acks, never the producer's file |
statusLine.ts |
The terminal's bottom line β where she is, and whether she is thinking; nothing off a TTY |
planName.ts |
β The one plan-file writer β name: on rename, nothing else |
pins.ts / handoff.ts |
Shelf, and terminal handoff |
personal.ts / greeting.ts |
Memory of the person; the boot line and the onboarding offer |
testRunner.ts / buildRunner.ts / runCommand.ts |
The two lights: detect, settle, run, parse failures; the build fired from the strip |
settings.ts |
The gear's store β the one config layer the page writes, and it wins |
creditMeter.ts |
The usage-credit countdown, armed only past the plan windows |
workbench.ts |
The pinned bench URL β what we're working on, bold at centre top |
suggestion.ts |
The suggested reply β ghost text in the composer, Tab to accept; held until her turn ends |
directorRole.ts / directorName.ts |
Shadow vs director; what to call the director |
server.ts / bus.ts / eventlog.ts / state.ts / origin.ts |
Transport, replay, events, queues, and the Origin check on API writes |
wireTap.ts |
The compact record of every SDK message the wire panel pulls |
keyterms.ts / links.ts / markdown.ts / activity.ts |
Vocabulary, file links as offsets, span overlays, activity lines |
showImage.ts |
Proving an image path before /api/image serves it or show renders it |
docs/ holds design records β the reasoning behind the voice plane, the ear, the
status surface, personal context, the plans panel, the inbox, /director-skills,
and the desk (agreed, unbuilt: one page over several running directors) β written
so a fresh session can pick the work up without the conversation that produced it.
My default node is x64 under Rosetta, so the SDK's bundled Bun CLI hangs
silently ("CPU lacks AVX support" on stderr is the only tell). Every session
passes pathToClaudeCodeExecutable pointing at the native arm64 install β
HARNESS_CLAUDE_BIN if yours lives elsewhere.
Beth is lovingly named after my grandmother, Beth Brian. It would be proud.

