Commit Graph
100 Commits
Author SHA1 Message Date
hh 9e60d06829 feat(conversations): the recall hook and the user sink learn whose turn it is 2026-09-06 23:26:26 +02:00
hh d5aaa80822 feat(frontends,security,api,ui): a frontend can hold a token scope of its own 2026-09-06 23:26:26 +02:00
hh 5401cbe187 feat(ui,docs): the open tab lives in the conversation url, admin screenshots in the readme 2026-09-05 04:55:54 +02:00
hh 82029bb10d fix(ui): a stream that went quiet reconnects, the rail says so, the panel opens on the master
A phone that slept brings back an SSE socket that never errored and never
delivers: the panel read as live for hours while showing nothing new. Every
chunk now marks the connection alive and a watchdog drops the socket after
40s of silence - twice the server's keepalive - so the loop reconnects.
Each attempt gets its own controller, which is what lets the watchdog (and
a manual refresh) end one connection without ending the loop.

The connection is admitted in one dot beside the rail's search box, tapped
to reconnect at once rather than waiting out the backoff - the pill that
used to say this was dropped in the redesign and the panel had no way to
own up to being stale.

With nothing picked, the shell lands on the freshest open master instead of
a prompt to pick something: what a phone wants when the panel opens. An
explicit pick, and following the active note, still win.
2026-09-05 00:20:03 +02:00
hh 96e18156eb fix(backends,conversations,telegram,ui): a background subagent reports back as its own turn 2026-09-04 20:23:33 +02:00
hh 1f051f261e chore(ui): drop an unused suppression 2026-09-02 05:17:51 +02:00
hh 9080eb7dee perf(panel): cached info and history paint first, lazy markdown up the thread, background prefetch 2026-09-02 05:16:13 +02:00
hh 20568915db fix(panel): thread scroller opts out of scroll anchoring 2026-09-02 05:08:51 +02:00
hh 72d60b799f fix(panel): composer no longer doubles the status-bar inset 2026-09-02 05:00:35 +02:00
hh 607ed6bc93 fix(panel): column-reverse thread keeps the bottom, no island in the plugin 2026-09-02 04:58:48 +02:00
hh b6d111a610 feat(ui): times on injects and every spoken message 2026-09-02 04:52:26 +02:00
hh 74843451a4 feat(api): limits read unifiedWindows, unknown seven-day windows labelled by model 2026-09-02 04:46:43 +02:00
hh 836cd60bd8 style(ui): flat menu sheets, digests folded with job runs, shorter spend caption 2026-09-02 04:43:04 +02:00
hh 99bcec2ba0 feat(ui): graph on d3-force with steady labels, quieter quota text, flat rail 2026-09-02 04:35:01 +02:00
hh d41f18504c feat(ui): interactive graph, strip context menus, days by activity, message times, limit status words 2026-09-02 04:24:15 +02:00
hh 256b2a68d6 feat(ui,api): strip board redesign - island, rail by day, context view, server search, vault graph 2026-09-02 03:48:26 +02:00
hh 6b7de6f03d feat(telegram): stop generation from the client, questions survive a restart, images reach the model inline, albums become one turn 2026-09-02 02:11:44 +02:00
hh c3b0864e3d feat(markdown): thinking blocks between hidden tool calls collapse to the first one 2026-09-02 01:44:02 +02:00
hh 38ae967233 docs(examples): compose for the minimal setup - postgres, real env, no phase notes 2026-09-02 01:28:51 +02:00
hh c9c2e94954 refactor: no comments left - one-line module docstrings, contracts on public fields only; jobs/job.py; example config and README 2026-09-02 00:33:04 +02:00
hh 90d0fb0f00 refactor(telegram): every user-facing string lives in TelegramTexts with English defaults 2026-09-02 00:16:38 +02:00
hh cae2ed4161 refactor: split flat core into capability packages, layer the conversations service, English defaults for every model-facing text 2026-09-02 00:13:20 +02:00
hh b96714338f fix(telegram,conversations): attachments by day with sweep in both modes, merge renames the topic, gone topics unbind, failures visible 2026-09-01 23:13:22 +02:00
hh 7853d61b94 feat(telegram): block-level markdown to html, wikilinks, tables, quotes, fence-safe chunking 2026-09-01 23:13:21 +02:00
hh f6a7ea8f29 feat(agents,claude_sdk): skill sets per conversation kind 2026-09-01 23:13:21 +02:00
hh 1954a6e9f2 feat(scheduler,conversations,api): cron and schedule in the gateway tz, job runs persisted 2026-09-01 23:13:17 +02:00
hh 9b1127acff chore(deps): claude-agent-sdk 0.2.150 bundles cli 2.1.257 2026-09-01 22:00:41 +02:00
hh 1e08dfb9da fix(mcp,redact,gateway_tools): mask credentials in tool results, names kept and values gone 2026-09-01 14:12:49 +00:00
hh 8e7db6baa4 fix(redact,cli): mask credentials in every log line, silence httpx request urls 2026-09-01 14:12:49 +00:00
hh acc79c2e42 feat(envelope,conversations): recall hook under the user text, user_sink for the setup's reply log 2026-09-01 16:08:53 +02:00
hh 63014a487d fix(storage,api): usage cost as per-turn delta of the sdk running total, backfill 2026-09-01 15:37:53 +02:00
hh 3406e2e178 feat(injects,conversations,scheduler,gateway_tools,api): wake priority, master and parent aliases, scheduled injects start a turn 2026-08-30 20:34:12 +02:00
hh 878f7d6473 fix(cli): mask query tokens in uvicorn access log 2026-08-30 18:30:26 +02:00
hh c438d4cb92 feat(auth): bootstrap token entries carry an optional scope 2026-08-30 18:25:48 +02:00
hh ba9d63667e feat(auth): query-string token for headerless webhook senders 2026-08-30 18:10:00 +02:00
hh d57f660a30 fix(gateway_tools,conversations): say refused in user turns, the reply reaches the human itself 2026-08-30 02:26:35 +02:00
hh cc32307921 feat(scheduler): job dedupe flag for webhooks that must not collapse 2026-08-29 22:15:15 +02:00
hh 811035ba4f fix(ui): chat keeps the bottom pinned while async markdown lands 2026-08-29 19:26:45 +02:00
hh 9efff6e814 feat(ui,api,telegram): shared conversation panel for obsidian and /admin/panel, bind materializes a window, inbox survives link previews 2026-08-29 18:30:33 +02:00
hh a989d2909d feat(injects,conversations): configurable inject header, urgent inject marks the turn it cut 2026-08-29 17:07:43 +02:00
hh 8d252f9867 fix(claude_sdk,conversations,rotation): context size from the last api call, new-day text by rotation reason 2026-08-29 16:54:29 +02:00
hh 2895e677c0 feat(policy,claude_sdk,cli,config_loader): pretooluse policy rules per agent, tool call audit, sibling imports for config 2026-08-29 15:27:26 +02:00
hh 23cfb16228 feat(distill,conversations,scheduler,api,ui): close deep chats with a distiller fork, digest and index, idle and weekly state jobs 2026-08-29 03:15:39 +02:00
hh ab9ce50b82 refactor(envelope): drop the reply counter and the injects line, keep time and vault changes 2026-08-29 02:38:39 +02:00
hh 662bdcdfda feat(scheduler,rotation,envelope,api,ui): pgqueuer jobs and deferred injects, master rotation with handout, vault envelope, jobs page 2026-08-29 02:29:05 +02:00
hh 0479d7cdda feat(conversations): pre-SDK rows read from canonical messages, implied titles, markdown adopts them by first prompt 2026-08-29 01:44:05 +02:00
hh 0cc2c5291f fix(markdown): a rewritten assistant reply reseeds the session instead of resuming it 2026-08-29 01:37:52 +02:00
hh 5cd18fa2d7 fix(ui): sidebar footer in one row, no user name 2026-08-29 01:19:58 +02:00
hh e45e9960ed fix(ui): thread header counts only queued items; label the live dot 2026-08-29 01:08:44 +02:00
hh 16b6bbddda feat: one gateway port with path-mounted frontends, markdown chat, collapsible sidebars 2026-08-29 00:49:06 +02:00
hh 540327efa1 feat(ui,api): chat view with live tail and autoscroll, conversation rail with last message previews 2026-08-29 00:18:08 +02:00
hh 645df6f2b4 feat(ui): endpoint catalog with copyable urls on the now page 2026-08-28 22:30:11 +02:00
hh b577034c83 chore(ui): beaver favicon from beaver-land and impeccable design sidecar 2026-08-28 22:20:36 +02:00
hh 00618ab7ad feat(ui,api,admin): sveltekit admin spa, usage by day/agent/conversation/model, rate limits, memory tree, turn snapshot 2026-08-28 22:14:15 +02:00
hh aaaf459e6d fix(backends): remember the session id from the first frame so a cut turn stays resumable 2026-08-28 19:38:47 +02:00
hh 4ad014726b fix(core): a turn cut by shutdown keeps running_turn for recover 2026-08-28 19:33:26 +02:00
hh 8c9c6eee69 fix(telegram): brief-seeded branches reply and stream in their topic 2026-08-28 19:21:03 +02:00
hh 21766fe2d7 feat(core): seeds without text wait for the first turn 2026-08-28 19:03:08 +02:00
hh 1f8dae57ac fix(telegram,core): no draft for seed turns 2026-08-28 18:59:00 +02:00
hh 66325c2879 fix(telegram): last draft push is the final text so the client folds it into the message 2026-08-28 18:51:16 +02:00
hh 5a44a16ba3 fix(telegram,core): bare seeds stay silent in telegram 2026-08-28 18:42:35 +02:00
hh c711dcab13 fix(telegram): final message waits for the draft push in flight 2026-08-28 18:32:45 +02:00
hh 3995741cd5 fix(telegram,core): first message seeds the branch, registered commands, no ellipses, html drafts 2026-08-28 18:25:46 +02:00
hh b0f280b3ca feat(telegram,core): master topic instead of general in private chats 2026-08-28 18:12:58 +02:00
hh 45a5eb4a94 feat(telegram,core,backends,storage): telegram frontend with inbox, outbox, drafts and question buttons 2026-08-28 17:57:09 +02:00
hh 7ae87aeeb8 fix(backends,markdown): stream turn events live, no blank lines for tool blocks 2026-08-28 17:27:35 +02:00
hh fd8cbacd7b feat(core): publish tool.result on the bus for the activity panel 2026-08-28 17:01:00 +02:00
hh bd2d2368e1 refactor(agents,core,frontends): typed kinds, prompts per kind, frontend agents as parameters 2026-08-28 16:36:44 +02:00
hh 1d8d65b69a feat(core,frontends,agents): agent kinds, frontend routing, anthropic on conversations, vault mirror 2026-08-28 03:50:33 +02:00
hh 33ccc78fec feat(core,backends,frontends,storage): conversations, inject queue, session pool, gateway mcp tools, api frontend 2026-08-28 03:08:30 +02:00
hh 50b7057fa4 fix(backends,storage,core): setuid in exec wrapper, missing-column migration, runner config dir for mirror, tagged prompt sources 2026-08-28 02:10:19 +02:00
hh e1f242a87a feat(backends,storage,core,markdown,infra): claude agent sdk backend, session store, transcript seeding, runner isolation 2026-08-28 01:56:39 +02:00
hhandClaude Fable 5 ee2dc918ee docs(env): .env.example for local development
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 23:45:53 +02:00
hhandClaude Fable 5 33cc769ca2 chore: make ruff format and ty clean
Format two mcp modules with the current ruff, and narrow the text-block
check in conversation_store through a typed helper so ty stops flagging
dict.get on an unnarrowed block.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 23:22:23 +02:00
hhandClaude Fable 5 e4282b38cd feat(ui,infra): SvelteKit ui scaffold, Makefile, pre-commit, claude hooks
ui/: SvelteKit 2 + Svelte 5 + Tailwind 4 + shadcn-svelte (luma, lucide)
on bun with ultracite; adapter-static with SPA fallback; theme tokens
taken from msos. Dockerfile gains a bun stage that builds ui/build.
Makefile and pre-commit cover ruff, ty, ultracite and svelte-check;
.claude settings run the matching fixer after edits. docs/PRODUCT.md
captures product truth for the UI work.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 23:22:18 +02:00
hh 0e7dc263ad feat(markdown): prefer tool description in callout title 2026-08-07 18:24:06 +02:00
hh 7d1e0b365d chore(lock): scope the unconnected-MCP warning to configured servers 2026-07-28 03:27:28 +02:00
hh 6c1780583c feat(claude): warm up sessions for agents that expose MCPs
`ClaudeCodeOptions.warmup_turn` defaults to `None`, which decides per
agent: on when the agent exposes any MCP, off otherwise. An agent whose
tools are the point shouldn't answer its first message without them, and
an agent with no MCPs shouldn't pay for a warm-up it gains nothing from.

The underlying reason lives in claude-code-api: the CLI connects MCP
servers when a turn starts and doesn't await them, so turn one runs with
built-in tools only.
2026-07-28 03:22:39 +02:00
hh 7f633a11a2 chore(lock): pick up claude-code-api stream-transport shutdown fixes 2026-07-28 03:12:11 +02:00
hh 823337409a feat(claude): expose the headless stream-json transport, with real streaming
`ClaudeCodeOptions.transport="stream_json"` runs the agent on `claude -p`
with stream-json on both pipes instead of driving the TUI through a
pseudo-tty. Opt-in: the default stays `pty`, so nothing moves until a
config asks for it.

The reason to ask for it is that the PTY path pays a multi-second
readiness wait before every spawn and can silently lose a prompt to a
swallowed paste; the headless path writes to a pipe and gets a native
`result` record back. `--remote-control` and friends are dropped by the
transport when set, since they'd take claude out of print mode.

`include_partial_messages` then gives clients genuine token-level SSE.
Blocks are emitted from the `StreamEvent`s rather than forwarded raw:
the payload is already Anthropic-shaped but arrives as a dict, so it
would need validating against the SDK union anyway, and rebuilding it
through our own builders drops an unrecognized block or delta type the
same way `_emit_block` already does instead of raising mid-stream on a
claude release that adds one. When streaming, the whole-block records
are kept for TurnCapture but not re-emitted — that would duplicate every
block on the wire.

Verified end-to-end against a live claude: both paths accumulate to the
identical Message (same blocks, same stop_reason, same usage), the
envelope stays 1:1, and block indices stay collision-free across a turn
that spans several API requests.
2026-07-28 03:00:10 +02:00
hh 99b5c69c1e fix(conversation_store): splice assistant text in place, keeping thinking blocks 2026-07-26 17:57:03 +02:00
hh 1ad8f2a475 fix(agents): raise claude tui startup wait to 60s 2026-07-26 00:49:47 +02:00
hh 90fe92d014 fix(conversation_store,admin,cli): keep session when file lags db, sort pty by recency 2026-07-26 00:25:07 +02:00
hh d2981116d4 feat: live pty monitoring for claude code 2026-06-04 22:36:26 +02:00
hh c7b3eddbf4 feat: add pty monitoring for claude code 2026-05-23 00:37:49 +02:00
hh 9de5647cfa feat: bump claude-code-api 2026-05-23 00:31:42 +02:00
hh b83018b97e feat: bump claude-code-api 2026-05-23 00:12:33 +02:00
hh e53195a948 fix: asynchronous generator is already running 2026-05-23 00:04:25 +02:00
hh 5fb5b6a3fb feat: add heartbeats to prevent long-thinking from closing 2026-05-22 23:59:00 +02:00
hh 33eece331a feat: add more logging 2026-05-22 22:48:12 +02:00
hh b8ac545a51 feat: bump claude-code-api 2026-05-22 01:04:29 +02:00
hh 0c3a09456d feat: bump startup delay (new method) 2026-05-22 00:46:39 +02:00
hh e28b74ee3f feat: bump startup delay (new method) 2026-05-22 00:36:44 +02:00
hh a8c86a4292 feat: bump startup delay (new method) 2026-05-22 00:36:27 +02:00
hh 48d292904b feat: add pastable link for markdown endpoint 2026-05-21 23:38:25 +02:00
hh 64ad92b4c1 feat: allow custom base url 2026-05-21 23:27:57 +02:00
hh e8a4e3aa82 feat: markdown streaming via extension 2026-05-21 21:15:46 +02:00
hh 11f061070f feat: add streaming to markdown, fix raycast mcps exposing 2026-05-21 13:52:48 +02:00
hh 7fc0c9c0b1 fix: claude shouldn't reset creds after rebuild now 2026-05-21 12:39:53 +02:00
hh a83bec709d feat: add stateful conversation storage 2026-05-21 12:27:11 +02:00