Skip to content

conch 0.3.0

Choose a tag to compare

@stupart stupart released this 21 Sep 05:57
· 226 commits to main since this release

What's Changed

  • Ledger cleanup: statuses right, voices to Settings, one accent colour by @stupart in #47
  • Render markdown in the static reply too by @stupart in #48
  • Parse the reply once, then dim the tail — splitting corrupted block markdown by @stupart in #49
  • Give markdown blocks their air back, and make the indent actually apply by @stupart in #50
  • Recognize "send" when it rides the tail of the same breath by @stupart in #51
  • Recognize a trailing "no response needed" too by @stupart in #52
  • Make keystroke-fallback a real setting instead of an env-only flag by @stupart in #53
  • Review pane: fit images, kill the white flash; plugin offers to install conch by @stupart in #54
  • Drop the border around image deliverables by @stupart in #55
  • Reviews belong to their own session; ship the app real markdown by @stupart in #56
  • Structured telemetry, and tell the app's user the plugin exists by @stupart in #57
  • The conversation pane was blank for any session that had used a tool by @stupart in #58
  • UX audit round one: colour semantics, contrast, glyphs, tables by @stupart in #59
  • UX audit round two: measure, flex priority, blockquote collision by @stupart in #60
  • UX audit round three: fix my own regression, and three real blockers by @stupart in #61
  • UX audit round four: Settings, empty state, Dynamic Type by @stupart in #62
  • Give the status colours real separation, not just different shapes by @stupart in #63
  • Fix a wrong number on screen, a mis-teaching legend, and a lopsided column by @stupart in #64
  • Clear the remaining polish: say it once, mark the trust boundary, disarm dead controls by @stupart in #65
  • Undo my own greedy frame, and stop mute from hiding a waiting turn by @stupart in #66
  • Make the window remember where it was by @stupart in #67
  • The greedy frame moved sides; remove it from both by @stupart in #68
  • Clear the four defects found alongside the world-class verdict by @stupart in #69
  • Every deliverable type renders fully, and proves it with a harness by @stupart in #70
  • The phone transport: LAN bridge, pairing, and an inject path by @stupart in #71
  • conch for iPhone: ledger, talk, deliverables — the Mac's sibling by @stupart in #72
  • iPhone audit round one: four blockers, seven polish items by @stupart in #73
  • The tall-image fix had inverted the bug; the cure was a deletion by @stupart in #74
  • Six digits, not thirty-two: the strong token is never typed by @stupart in #75
  • The phone said 'No reply yet' for almost every session by @stupart in #76
  • Voice lost everything before the last pause; /goal loops ate your dictation by @stupart in #77
  • Untrack 103MB of Xcode device-build output by @stupart in #78
  • Give each toolbar button one job: the Mac on the left, the mode on the right by @stupart in #79
  • Dot in the glass for the mode, laptop for the Mac, shell in the title by @stupart in #80
  • The phone gets a voice, and the mode dot stops waiting for the Mac by @stupart in #81
  • Audio follows the phone, and restarts stop wiping the dashboard by @stupart in #82
  • The app now says when it is stale; the phone's voice is one switch by @stupart in #83
  • Two open mics, lost dictation, and a button that meant two things by @stupart in #84
  • Gate speech at the chokepoint, and make the audio claim a real lease by @stupart in #85
  • Codex's review fixes, plus the coverage hole my verification found by @stupart in #86
  • conch: phases 1-2, resume by search, capability inspector, and a lot of honesty fixes by @stupart in #88
  • Stop the two audio owners from destroying each other's work by @stupart in #87
  • Address the window, not the session — plus per-kind capability metadata by @stupart in #89
  • Extract the session ledger, and make typecheck a test by @stupart in #90
  • Roadmap: raise a session from its title, and a cloud/local speech toggle by @stupart in #91
  • Close an open mic on request, and stop making it wait for the transcript by @stupart in #92
  • Warm a session's prompt count before anything waits on it by @stupart in #93
  • Let the app hold the microphone it spawns a recorder for by @stupart in #94
  • Make the mic say how long it took to open by @stupart in #95
  • Roadmap: a mic button that reacts to your voice by @stupart in #96
  • Stop the microphone waiting for its own courtesy sound by @stupart in #97
  • Fix the lease test's literal, and the -1 trap inside it by @stupart in #98
  • Stop one slow control from swallowing every press behind it by @stupart in #99
  • Measure the mic at the arm, not at the decision by @stupart in #100
  • Make no sound before a composer dictation's mic opens by @stupart in #101
  • Make a failed whisper request say what failed by @stupart in #102
  • Roadmap: one conch across two Macs, and why it belongs in the refactor by @stupart in #103
  • Make releasing one command, and give the repo a CI gate by @stupart in #104
  • Tell people when the conch they are running has been superseded by @stupart in #105
  • Publish from CI, and make the release gap visible by @stupart in #106
  • Roadmap: markdown fidelity for tool prose, and pasted image paths by @stupart in #107
  • Docs: record what today actually taught us by @stupart in #108
  • README: a source checkout needs an app, and an app needs an identity by @stupart in #109
  • Make CI green: inject which, and pay first-launch cost outside the timer by @stupart in #110
  • Keep bun's compile intermediates out of the repo by @stupart in #111
  • Publish a deliverable's path absolute, so the app can find it by @stupart in #112
  • Preview a deliverable in the conversation, not a card about it by @stupart in #113
  • Stop a derived registry name from masking a session's real title by @stupart in #114
  • Roadmap: Cmd+V image paste, a doc-link error, and where the memory layer lands by @stupart in #115
  • Render a nested agent's reply as prose, not as a log by @stupart in #116
  • Act on the split recon: two silent tests, a frame cap that missed, a wrong comment by @stupart in #117
  • Extract the event scheduler (cut two of the daemon split) by @stupart in #118
  • Let a dropped or pasted image reach the composer, not the editor by @stupart in #119
  • Pairing tab: show the daemon's refusal, and name the fix by @stupart in #120
  • Cut three of the daemon split: extract the control server by @stupart in #121
  • Control server: a destroyed connection dispatches nothing (A16) by @stupart in #122
  • Mic button reacts to your voice, not just to being on (C12) by @stupart in #123
  • Click a session's title to bring its terminal to the front (C10) by @stupart in #124
  • Ledger: prune resumedSessionIds with everything else (A11) by @stupart in #125
  • Mac app: start our own daemon when an adopted one dies (A2) by @stupart in #126
  • Error records keep a digest of daemon state, not the conversations by @stupart in #127
  • Theater: date and own the copied line; A7 findings, A9 stale by @stupart in #128
  • docs: the install journey map, and the A6 recheck by @stupart in #129
  • Roadmap: where the line stands after three cuts by @stupart in #130
  • Teleport by ID beside Resume, Claude only (C8) by @stupart in #131
  • Hand undelivered inject text back to the composer (A8) by @stupart in #132
  • C9b slice A0: a persistent device identity on every published document by @stupart in #133
  • C9b slice A1: see another Mac's sessions over LAN and type into them by @stupart in #134
  • Roadmap: C13 and C14 done, B7 narrowed by @stupart in #135
  • Prune reportedMissingCodexPid with the session ledger (A12) by @stupart in #136
  • Watch an adopted whisper-server, and reap a dead daemon's orphan (D3) by @stupart in #137
  • fix: setup leaves the daemon to an installed app; doctor names every conch on PATH by @stupart in #138
  • fix(setup): say what it does — download size and progress, /hooks line, start mode by @stupart in #139
  • Uninstall recognises hooks from a capitalised source checkout by @stupart in #140
  • Let the terminal open the deliverable it is sent (A10) by @stupart in #141
  • Phone remembers a working folder for fresh sessions (B7) by @stupart in #142
  • The test suite no longer writes into the live daemon log (A7 solved) by @stupart in #144
  • feat(whisper): idle-unload the owned whisper-server, reload it when a mic is about to open (D2) by @stupart in #143
  • One voice across two Macs: the audio holder and Take it (C9b Cut B) by @stupart in #145
  • The phone asks before replacing a different Mac's pairing (Path 3, step 3) by @stupart in #146
  • Install map: Path 1 steps fixed by #139 by @stupart in #147
  • feat(b2): change the model mid-session via a typed /model by @stupart in #148
  • C4: nest live subagents under their session, reachable from the conversation by @stupart in #149
  • feat(tts): Kokoro by mode — manual unloads the owned worker, auto warms it (D1) by @stupart in #150
  • E1: fold the Mac header into the hidden title-bar strip by @stupart in #151
  • A2/A3: the app learns who owns an adopted daemon, and can take it from launchd by @stupart in #152
  • C7: a help session that ships with conch by @stupart in #153
  • test(listen): make the idle-deadline growth test independent of wall-clock by @stupart in #154
  • Service plist: launchd argv carries no shell quoting by @stupart in #155
  • The app gives its daemon the service's PATH by @stupart in #156
  • The command palette (B4): ⌘K, one list for the selected session by @stupart in #157
  • refactor(E8): one AgentAdapter row per agent, looked up instead of branched on by @stupart in #158
  • Roadmap: status after the night's PRs by @stupart in #159
  • mlx-audio resolver looks under ~/.local/bin when PATH lacks it by @stupart in #160
  • Plugin contract (C5): allowlist config, bound speak, scope mode, say where audio went by @stupart in #161
  • feat(C15): a session started by another session nests under its starter by @stupart in #162
  • Approvals by voice: the four-way decision (B5) by @stupart in #163
  • Audit: what the daemon does to the rest of the Mac by @stupart in #164
  • C1: per-agent start options, validated against each CLI's own --help by @stupart in #165
  • B3: the write pass — switch a plugin or MCP server for the next session by @stupart in #166
  • Explain the 100-minute relay drop and re-dial it at once (A5) by @stupart in #167
  • A13: a link that will not open says why, where it was clicked by @stupart in #168
  • Link resolver decodes a percent-encoded bare path by @stupart in #171
  • A17: stop the daemon reaching into the rest of the Mac by @stupart in #169
  • Two windows, one transcript: each window reads its own branch (A8) by @stupart in #170
  • The app explains its Apple Events to the Automation prompt by @stupart in #172
  • C1 follow-ups: TUI start options, an honest phone toggle, no stale test count by @stupart in #173
  • A13 follow-up: every viewer that fails says why, and files it by @stupart in #174
  • Six leftovers: an honest Mac toggle, aligned overlay, shared said everywhere, viewers that file, conch_speak says held by @stupart in #175
  • Codex harness notes: what Codex exposes, and what conch should use (C16) by @stupart in #176
  • Cut four: the voice loop leaves runDaemon (src/voice-loop.ts) by @stupart in #177
  • Give Codex its own plugin MCP declaration by @stupart in #178
  • A14 after the voice cut: immediate events keep out of the running exchange by @stupart in #179
  • Codex rows read Codex's own indexes: helpers, names, and who holds the lock (C16 item 4) by @stupart in #180
  • Closing a closed Codex row reports its reason, not a missing pid by @stupart in #181
  • Give the recorder-abort test's ready wait room under a loaded suite by @stupart in #182
  • Apps: honor noTerminal on Codex rows (say why, no send/stop/close) by @stupart in #183
  • Resume picker names Codex threads from Codex's session index by @stupart in #184
  • Photograph both apps without the screen: iOS fixture mode + ui-snapshot.sh by @stupart in #185
  • Ignore .worktrees/, the shared place for agent worktrees by @stupart in #186
  • Continued sessions: the live background session is the row by @stupart in #187
  • Background sessions: route to the attached window, open one when none is by @stupart in #188
  • Stale window ids reach the job's row; Mac composer checks spelling by @stupart in #189
  • Mac app takes the front back after a send lands in Terminal by @stupart in #190
  • Deliverables keep one identity and stay visible while the session works by @stupart in #191
  • Working means working: shell is idle, resumed subagents run, parked windows thaw by @stupart in #192
  • Claude's stable registry corrects a stale latch after a 5 s grace by @stupart in #193
  • Question cards respect noTerminal, /model and /rename refocus, deliverables survive restart by @stupart in #194
  • Design system package and the menu bar status item (M1, M2) by @stupart in #195
  • Phone keeps its link, shows what became of a send, and says when it must re-pair by @stupart in #196
  • Mac: floating control bar and conversation fog (M3) by @stupart in #197
  • The fog never ends in a line, and thickens behind the words by @stupart in #198
  • Control bar fits Quiet, the reply scrolls, and a bigger fog gives the words room by @stupart in #199
  • Back to the corner fog, facing its nearest corner and kept on screen by @stupart in #200
  • Dock the fog in a corner: thrown by its middle, resized from wide free edges by @stupart in #201
  • Let the fog take every click inside it, transparent parts included by @stupart in #202
  • Wider resize strips, a liquid throw, and room above the reply by @stupart in #203
  • Resize strips twice as wide, buttons drawn above the top one by @stupart in #204
  • Resize the fog from anywhere near a free edge, both ways at once by @stupart in #205
  • Revert #205: back to the resize strips by @stupart in #206
  • Turn the overlay's look back on by @stupart in #207
  • Live-tunable overlay look, with a much lighter tint by @stupart in #208
  • Put the overlay's buttons in its docked corner by @stupart in #209
  • Save drafts once typing pauses, not on every keystroke by @stupart in #210
  • Paste long or multi-line messages into a session instead of typing them by @stupart in #211
  • Read a transcript further back when its tail holds nothing said by @stupart in #212
  • Larger menu bar mark, overlay buttons in the corner proper by @stupart in #213
  • Off its corner, the overlay fades on every side by @stupart in #214
  • Springs and the overlay's dark palette in the design system by @stupart in #215
  • The overlay moves the way the lab does: one-spring throws, resizing from any edge in its corner by @stupart in #216
  • The overlay looks the way the lab does: a magnet of blur, the voice's colour, and light and dark by @stupart in #217
  • The overlay's words behave the way the lab's do by @stupart in #218
  • The design gallery draws every spring's curve by @stupart in #219
  • CI runs the design system's Swift tests by @stupart in #220
  • A reply the overlay couldn't send comes back to the reply line by @stupart in #221
  • The overlay's text cost test bounds a hang, not a frame by @stupart in #223
  • Clicking the Ready pill brings the scene to you by @stupart in #222
  • A local record store keeps full session history, off by default by @stupart in #225
  • Publishing a result no longer ends the turn by @stupart in #224
  • Long slash commands paste their own text, not the clipboard by @stupart in #226
  • A dictation error keeps your words as a draft instead of sending half by @stupart in #227
  • Only one conch daemon can start; a losing start can't delete the winner's socket by @stupart in #228
  • iPhone: review work properly, and open on the last known state by @stupart in #229
  • A slow session scan can no longer wipe out state from a newer hook by @stupart in #230
  • Config backups stay private; a toggle can't overwrite a change made moments earlier by @stupart in #231
  • Typing into sessions happens one at a time; a failed send is never reported as sent by @stupart in #232
  • Close and orphan cleanup only act on the process conch actually saw by @stupart in #233
  • Phone sends keep your draft unless the Mac confirms; long or non-English messages arrive intact by @stupart in #234
  • A spoken approval only answers the permission request it was asked about by @stupart in #235
  • Talking over read-aloud keeps your words; dictation timing no longer depends on diagnostics by @stupart in #236
  • Retire relay retry entries by session; rotate the daemon log and stop logging dictated text by @stupart in #238
  • Verify the MCP caller and refuse ambiguous session targets by @stupart in #237
  • The record store reads transcripts as they grow, off until turned on by @stupart in #240
  • Full session history can be read in pages, over the socket, the phone and MCP by @stupart in #241
  • Announce the first busy Codex turn and show Codex turns on the phone by @stupart in #242
  • Shared windows only count their own replies by @stupart in #243
  • Turning on the encrypted relay now closes the plaintext Wi-Fi port by @stupart in #244
  • Looking for your sessions no longer freezes everything else by @stupart in #245
  • MCP PR 3: review_to_front scene v1, pill honours it, one source for agent instructions by @stupart in #239
  • The Mac app can read a session's whole history, not just the last of it by @stupart in #246
  • A failed send says why, on the phone and in the Mac app by @stupart in #247
  • A clipboard with three or more things on it no longer stops every send by @stupart in #248
  • The iPhone app can read a session's whole history, not just the last of it by @stupart in #249
  • A session with recorded history but an empty live window draws it by @stupart in #250
  • Keep the test suite off the real configuration by @stupart in #251
  • One owner for which session the workspace is on by @stupart in #252
  • A hook resumes its prompt count instead of rescanning the transcript by @stupart in #253
  • A voice answer settles in the window that was asked by @stupart in #255
  • A paste proves it still owns the clipboard, and Close checks the window by @stupart in #254
  • A recorded message is the provider's message, not its blocks by @stupart in #256
  • A sent message says what actually became of it by @stupart in #257
  • test: wait for the replacement records worker to answer, not just exist by @stupart in #259
  • workspace: group the session list by the folder each session runs in by @stupart in #260
  • design: measured row-state and attention tokens by @stupart in #261
  • A window's history is its own branch by @stupart in #262
  • workspace: the Mac palette comes from the design system, and follows the theme by @stupart in #263
  • mac: delete four unreferenced views and helpers from DashboardView by @stupart in #264
  • ios: the phone's palette comes from the design system, and follows the theme by @stupart in #265
  • mac: lift the palette, the fallback renderer and the log drawer out of DashboardView by @stupart in #266
  • ios: the session list groups by folder and nests what runs inside something by @stupart in #267
  • daemon: a deliverable gets one identity, minted when it is filed by @stupart in #268
  • mac: the window's notices become one view, above the work by @stupart in #269
  • apps: the three surfaces stop recomputing a deliverable's identity by @stupart in #270
  • daemon: a session keeps every deliverable it files, not just the last one by @stupart in #271
  • daemon: what you have already looked at belongs to the deliverable, not the window by @stupart in #272
  • apps: both apps read what the daemon now publishes about deliverables by @stupart in #273
  • apps: what you have looked at is shared, and survives a relaunch by @stupart in #274
  • mac: a session's deliverables get a strip, and you can see which you have read by @stupart in #275
  • phone: a message whose answer never arrived is not a message that failed by @stupart in #276
  • mac: the sidebar is a fixed width, and ⌘B puts it away by @stupart in #277
  • phone: an answer says which question it is answering by @stupart in #278
  • phone: a picture with no words goes through the outbox, like any other message by @stupart in #279
  • mac: both transcript renderers agree on one reading measure, at the spec's 700 by @stupart in #280
  • mac: the transcript reads at the spec's body size by @stupart in #281
  • design: the stage has three pages, not a Bool by @stupart in #282
  • mac: the stage draws its three pages by @stupart in #283
  • mac: the deliverable fills the stage, and there is one of it by @stupart in #284
  • mac: the transcript's reading rhythm, and a bubble on fill by @stupart in #285
  • mac: the view switch moves into the header by @stupart in #286
  • mac: the composer floats at the measure by @stupart in #287
  • mac: the header is the height §3 says it is by @stupart in #288
  • design: consecutive tool steps are a run by @stupart in #289
  • mac: the transcript folds a run of tool steps by @stupart in #290
  • design: a run reports time only when it plausibly worked by @stupart in #291
  • mac: the sidebar is the anatomy §3 describes by @stupart in #292
  • design: what a question's answer actually chose by @stupart in #293
  • mac: an answered question collapses to what it decided by @stupart in #294
  • mac: the header's hairline waits for the transcript to scroll by @stupart in #295
  • mac: conch shot photographs the app in its real appearance by @stupart in #296
  • mac: the composer, px for px against the lab by @stupart in #297
  • mac: the workspace moves on §4's springs by @stupart in #298
  • mac: the stage is a panel on the window ground by @stupart in #299
  • mac: the header, px for px against the lab by @stupart in #300
  • design: the four shadows, from the lab's own variables by @stupart in #301
  • mac, ios: the deliverable card is the work, not a card about it by @stupart in #302
  • mac: the caret sits on the same line as the words by @stupart in #303
  • mac: attachments, the drop ring, and dismissed sessions that stay dismissed by @stupart in #304
  • ci: the gate runs on the Mac now — Actions is out of credits by @stupart in #305
  • mac: the session list is the lab's row height by @stupart in #306
  • mac: a question is the lab's card, and reads at reading size by @stupart in #307
  • mac: the header's icon buttons are the lab's .ib by @stupart in #308
  • the app is called conch, and does not wear a shell by @stupart in #309
  • one fleet, one mark: the terminal checks a review too by @stupart in #310
  • mac: the caret, third attempt — leading, not a line box by @stupart in #311
  • mac: the status mark leads the row by @stupart in #312
  • ios: typing shows the send button by @stupart in #313
  • the shell leaves both headers — a third spelling of the same emoji by @stupart in #314
  • The overlay is a glass panel — plus the caret, the dictation loop, codex session start, and the shared renderer by @stupart in #315
  • A message sent from the Mac shows up the moment you send it by @stupart in #316
  • A file change says where the file is, not just what it is called by @stupart in #317
  • The session's files, in the work half of the stage by @stupart in #318
  • The folder tab is pinned, and the deliverables scroll by @stupart in #319
  • A deliverable tab is capped, so the strip stays scannable by @stupart in #320
  • Command output, with its colour, as something you can read by @stupart in #321
  • A terminal, running where the session runs by @stupart in #322
  • The transcript scrolls without the four stalls that were measured under it by @stupart in #323
  • The backlog records what the scroll work measured, and what it left by @stupart in #324
  • The deliverable pane browses, and always says where it is by @stupart in #325
  • Two things the address bar showed once it was on screen by @stupart in #326
  • The window stops re-rendering four times a second for a snapshot that has not changed by @stupart in #327
  • The backlog corrects a suspect it named, and records the real one by @stupart in #328
  • The split drags, the page follows you, and looking at a deliverable marks it by @stupart in #329
  • Filings of one link are one tab, aged, with the older versions under it by @stupart in #330
  • The backlog records what the version grouping deliberately left by @stupart in #331
  • Every surface renders a document the same way, tables as columns included by @stupart in #332
  • A dragged image attaches, wherever it was dragged from by @stupart in #333
  • The transcript runs underneath the composer by @stupart in #334
  • The composer card is narrower than the column it floats over by @stupart in #335
  • Close session presses Ctrl-D twice for Claude Code, once for Codex by @stupart in #336
  • Record the composer measure, the close fix, and what close still cannot do by @stupart in #337
  • Opening a deliverable stages it beside the conversation by @stupart in #338
  • Record the eight pieces of feedback, with the ledger finding measured by @stupart in #340
  • Drag a folder header onto another to reorder the sidebar by @stupart in #339
  • Side by side floats the composer over the split, and the conversation runs under it by @stupart in #342
  • The composer keeps spell checking on — SwiftUI was turning it off on every keystroke by @stupart in #343
  • The deliverable ledger lives in ~/.config/conch, not /tmp by @stupart in #341
  • The workspace remembers its page, pane and tab across a relaunch by @stupart in #344
  • A session can say which folder it actually works in by @stupart in #345
  • One way out of a deliverable, and it opens the page you are on by @stupart in #346
  • Record the stale plugin, the unsignalled question, and a 1.1GB database by @stupart in #347
  • The release bumps every file that carries the version by @stupart in #348

Full Changelog: v0.2.1...v0.3.0