Commit Graph
80 Commits
Author SHA1 Message Date
hh 064379ca90 fix(cli): mask query tokens in uvicorn access log 2026-08-30 18:30:26 +02:00
hh e90963a6c3 feat(auth): bootstrap token entries carry an optional scope 2026-08-30 18:25:48 +02:00
hh 064d855382 feat(auth): query-string token for headerless webhook senders 2026-08-30 18:10:00 +02:00
hh 5d67cfcc9e fix(gateway_tools,conversations): say refused in user turns, the reply reaches the human itself 2026-08-30 02:26:35 +02:00
hh b4853b9fd0 feat(scheduler): job dedupe flag for webhooks that must not collapse 2026-08-29 22:15:15 +02:00
hh 2d12391176 fix(ui): chat keeps the bottom pinned while async markdown lands 2026-08-29 19:26:45 +02:00
hh 60dc7db925 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 be114e6eaf feat(injects,conversations): configurable inject header, urgent inject marks the turn it cut 2026-08-29 17:07:43 +02:00
hh 4a59c59bda 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 72639c4b90 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 1786406b31 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 12728b2eb4 refactor(envelope): drop the reply counter and the injects line, keep time and vault changes 2026-08-29 02:38:39 +02:00
hh bc4233977d 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 fd69eae05d 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 d3a3e7b1f1 fix(markdown): a rewritten assistant reply reseeds the session instead of resuming it 2026-08-29 01:37:52 +02:00
hh 772db11c7f fix(ui): sidebar footer in one row, no user name 2026-08-29 01:19:58 +02:00
hh 4fb020c788 fix(ui): thread header counts only queued items; label the live dot 2026-08-29 01:08:44 +02:00
hh 932a7a80af feat: one gateway port with path-mounted frontends, markdown chat, collapsible sidebars 2026-08-29 00:49:06 +02:00
hh 3ca5843868 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 8ea4cea3ef feat(ui): endpoint catalog with copyable urls on the now page 2026-08-28 22:30:11 +02:00
hh b6c5a80326 chore(ui): beaver favicon from beaver-land and impeccable design sidecar 2026-08-28 22:20:36 +02:00
hh 98796a82c6 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 61562e947d 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 609af9fe67 fix(core): a turn cut by shutdown keeps running_turn for recover 2026-08-28 19:33:26 +02:00
hh e469e7e174 fix(telegram): brief-seeded branches reply and stream in their topic 2026-08-28 19:21:03 +02:00
hh c88726db9e feat(core): seeds without text wait for the first turn 2026-08-28 19:03:08 +02:00
hh 38986cb82e fix(telegram,core): no draft for seed turns 2026-08-28 18:59:00 +02:00
hh 43407016d0 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 7240e0cdac fix(telegram,core): bare seeds stay silent in telegram 2026-08-28 18:42:35 +02:00
hh 7b0c61c18e fix(telegram): final message waits for the draft push in flight 2026-08-28 18:32:45 +02:00
hh 0110cbd1cc fix(telegram,core): first message seeds the branch, registered commands, no ellipses, html drafts 2026-08-28 18:25:46 +02:00
hh 9663fbf956 feat(telegram,core): master topic instead of general in private chats 2026-08-28 18:12:58 +02:00
hh 5177392f46 feat(telegram,core,backends,storage): telegram frontend with inbox, outbox, drafts and question buttons 2026-08-28 17:57:09 +02:00
hh 5fc58e3bc7 fix(backends,markdown): stream turn events live, no blank lines for tool blocks 2026-08-28 17:27:35 +02:00
hh 5d2ce68f6b feat(core): publish tool.result on the bus for the activity panel 2026-08-28 17:01:00 +02:00
hh 70349e5ff4 refactor(agents,core,frontends): typed kinds, prompts per kind, frontend agents as parameters 2026-08-28 16:36:44 +02:00
hh 827fa0977b feat(core,frontends,agents): agent kinds, frontend routing, anthropic on conversations, vault mirror 2026-08-28 03:50:33 +02:00
hh e3074c266a feat(core,backends,frontends,storage): conversations, inject queue, session pool, gateway mcp tools, api frontend 2026-08-28 03:08:30 +02:00
hh ab52fdc2b8 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 7424d52f88 feat(backends,storage,core,markdown,infra): claude agent sdk backend, session store, transcript seeding, runner isolation 2026-08-28 01:56:39 +02:00
hh b3a584a362 docs(env): .env.example for local development 2026-08-27 23:45:53 +02:00
hh a2a80ab150 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.
2026-08-27 23:22:23 +02:00
hh d33039f497 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.
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