Commit Graph

13 Commits

Author SHA1 Message Date
b27e1bf3ec fix(web): coerce chat composer draft to string (input.trim crash)
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled
The Send button's disabled={!input.trim()} threw "trim is not a function" when
input was initialized from a non-string initialDraft (a Svelte 5 prop-init edge
where a null/undefined draft reached $state). Coerce at init so the composer
state is always a string.

VERSION: 0.15.0 -> 0.15.1
2026-08-03 16:00:01 +02:00
39e9227fdb feat(nomos): per-session turn serialization + chat reliability/UX fixes
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled
The agent could run two turns for one session at once (a reconnect resumed
while the live turn was still going), and their interleaved tool calls
corrupted the activity panel, fabricated a confusing "parallel/nested"
sequence, and made tasks feel stuck/never-ending. Several UX gaps compounded it.

Turn serialization (F1):
- turnGate: at most one in-flight turn per session. Background resume paths
  (continuation worker, idle sweep, answer-question, /resume, reconnect)
  skip non-blocking when busy; the live chat path waits briefly then bails
  cleanly instead of stacking a second turn.
- resumeSession returns whether it ran; continueSession marks an execution
  "continued" only after a real run (review P0) so a busy-skip can't lose a
  finished-execution result. Idle nudge bumps only after delivery (P1).

Connection state (F2/F3, web):
- humanize/bucket raw errors ("model connection dropped..."); one surface
  per drop; a terminal task.status event clears stuck streaming/disconnected
  state and dismisses the connection toast. Reconnect no longer spawns turns.

Streaming where you look (F4, web):
- live command output in the global activity timeline and in the inline
  tool card (auto-opened, tail-pinned) -- not just the per-window rail.

Other (web): artifact/knowledge deep links (F5); step-first stable
"thinking" headline (F6); stable chat layout, no empty->content reflow (F7);
lazy event sync (P2.2); reconnect skips a terminal session (P2.1).

VERSION: 0.14.2 -> 0.15.0
2026-08-03 15:42:10 +02:00
ad29295c93 feat(web): make the entity window a triage surface, not a data dump
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled
The window rendered the same 13 collapsible sections for every entity, sorted
only by "does it have content". Audit trail carried the same visual weight as
Health, and the window answered "what data do we hold about X?" rather than
"what do I need to know, and what should I do?".

Measured against prod: host:hubris has 223 relations, 1,601 events, 2.7M metric
samples and 148 executions; an ingress route has three facts. Both got 13
identical headers. Expanding a host put ~540 interactive elements on screen.

- **A verdict header that never collapses.** Not just "down" but *why*:
  "ping failing · 5 of 6 checks passing". That line did not previously exist
  and could not have — checks rendered as configuration, never as results.
- **Sections composed per type.** A document has no checks, metrics or blast
  radius; a signal or execution is a record, not a thing. Infrastructure gets
  Status/Impact/Activity/Metrics/Reference, knowledge types lead with Content,
  records get a minimal view. Unknown types fall back to infrastructure so a
  new entity type is never a blank window.
- **Status replaces Monitoring**, showing each check's own verdict and when it
  last ran — the section that answers the header's "why".
- **Impact** finally calls /entities/{id}/blast-radius. The endpoint has existed
  since the first API and had no frontend caller anywhere, despite
  .agents/OIKOS.md naming blast radius as the reason the ontology exists. Its
  outgoing-edges-only limitation is stated in the UI rather than hidden.
- **Activity merges four lists** (executions, signals, events, agent activity)
  that were telling one story in four places.
- **Relations cap at 8 with a drill-in** — 540 interactive elements down to 126.
- **Ask Nomos** opens a task pre-scoped to what you are looking at, seeded with
  the verdict just computed, via an optional draft threaded through
  openNewTaskWindow -> NewTaskChat -> ChatThread.

Requires exposing check_defs.last_health/last_run_at through the API (the
columns landed with the health-aggregation work but were never surfaced).
Adding a fourth enum containing "unknown" made oapi-codegen disambiguate all
enum constants by type prefix, so metrics.go moves to gen.TrendDirection*.

Verdict derivation and type->section composition live in $lib/entityView.ts as
pure functions with 15 unit tests, including the host:strong case that
motivated this.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-29 09:24:28 +02:00
89312a9ce4 feat(web): redesign Knowledge as an editable wiki
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled
Replaces the read-only stats dashboard with a three-pane wiki: a
navigator tree (group by folder/type/tag/entity), a reader/editor with
bare-slug auto-linking and revision history + diff, and a context rail
for backlinks and related notes. Adds a Cleanup mode for the drift
tools (duplicates, tag manager, orphans, trash) and a Cmd+K quick-open.

Also:
- Adds a real landing view (hero count, KPI row, Nomos-share meter,
  recently-updated, busiest tags) in place of the old "Select a note"
  empty state, and extends the design pass across the tree/reader/rail
  (kind icons instead of repeated text badges, accent-bar selection,
  constrained prose measure).
- Guards every note-selection path behind a confirm when there's an
  unsaved edit in progress, so switching notes can no longer silently
  discard a draft.
- Extracts the markdown-rendering CSS duplicated across ChatThread,
  EntityDetailContent, and the new WikiReader into a shared
  .markdown-body class in app.css, with ChatThread keeping only its
  decorative deltas.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-27 22:50:54 +02:00
873b00ac42 style(web): fix prettier config, format entire web/ tree
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled
.prettierrc.json was missing "semi": false, so prettier wanted to add
semicolons to a codebase written without them (763 semicolon-free
statements vs. 150 with, in hand-written .ts; zero hand-written .svelte
files use them at all). That's why prettier --check failed on 249 files
— not because the code was unformatted, but because the config didn't
match the actual house style. Added "semi": false; left printWidth/etc
as configured (printWidth barely moves the failure count: 218/213/212
files at 100/120/140).

Ran `prettier --write .` with the corrected config. Verified
semantics-preserving before and after:
- eslint: 142 problems both before and after, byte-identical
- build passes, 38/38 tests pass
- token-stream diff (whitespace/semicolons/quotes normalized) on all
  218 changed files: only 52 had any remaining token change, all either
  trailing-comma removal (matching trailingComma: "none") or import/
  ternary reflow — no semantic changes
- live smoke test: Knowledge, Tasks, Fleet map, and a chat window
  (AgentTrace, markdown, Scope graph, activity rail) all render
  correctly, no console errors

Most of the diff is shadcn/ui vendor files (lib/components/ui/) moving
from the CLI's own style (double quotes, tabs, semicolons) to house
style; re-running `shadcn-svelte add` on a component will need a
follow-up format pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 12:56:07 +02:00
8f440c5ad5 feat(web): collapse chat tool calls into one agent trace, reverse the activity rail
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled
The chat rendered one card per tool call, so a 20-call turn buried the
answer under 20 stacked cards. Merge them with the "thinking" indicator
into a single collapsible strip above the answer:

- collapsed: the live activity while running, a count once finished
- expanded: the turn's work in humanized language (reuses the activity
  log's toolActivityLabel, so ten identical "run · target: host:strong"
  rows now read as what they actually did)
- per row: the raw args/result, one more click in

Also flip the Activity rail to newest-first with the current step on top:

- follow-mode/auto-scroll re-anchored to the top to match, or it would
  jump to the oldest entry on every new event
- pending plan steps park at the tail rather than sorting above the
  running step and pushing it off the top; the goal anchors the bottom

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-26 13:06:01 +02:00
dffe01fb02 fix(web): use the terracotta accent instead of green for done checkmarks
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled
text-primary instead of text-success — keeps the "done" state on-brand
with the rest of the UI (buttons, focus rings) rather than introducing
a separate green that only really worked well on the dark theme.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-21 12:12:00 +02:00
0f9e366ad5 fix(web): tool-call checkmarks nearly invisible on the terracotta (light) theme
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled
text-success/50 and /60 washed out to almost nothing against the light
theme's cream card background — full-opacity text-success still reads
as a calm, muted green (not alarming) but is actually visible on both
themes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-21 11:46:49 +02:00
e5a81241b7 feat(web): operator questions inline in chat, mascot reactions scoped to the focused task
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled
The pending operator-question card now renders inline in ChatThread (the
newest thing in the conversation) instead of in the context rail — it's
part of the chat, not a separate side panel, and the panel's hasContext
gate no longer needs to special-case it.

The desktop mascot's reactions are now entirely about whichever task
window has focus, not fleet-wide events: thinking/talking is a new
continuous `busy` behavior that tracks the focused session's own
streaming state (thinking before any text arrives, talking once it
does — using the previously-unwired peep/talk sprite), eureka fires with
the actual knowledge title that was recorded, happy fires with the
task's own completion summary, and alarmed now means "this task needs
your OK" (an operator question was raised) rather than a fleet-wide
critical/signal event.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-21 10:46:46 +02:00
6b6bfe1fd8 feat(web): new task opens straight into chat, context rail waits for content, frosted windows
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled
New Task now opens directly as an empty ChatThread (NewTaskChat) instead of
a separate compose screen, sized like a real task window. The Scope/Activity
context rail in a task window no longer renders until there's actually
something to show (touched entities, activity, or an open question),
avoiding an empty-placeholder sidebar on every new task. Also fixes the
chat input defaulting to several lines tall on window open, centers the
empty-chat greeting vertically, and gives floating windows the same
frosted-glass look as the desktop's task launcher card.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-21 09:50:47 +02:00
ce34cfeac7 feat(web+nomos): fix chat streaming reactivity, unified activity timeline, tool cards in chat
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled
- fix(web): Svelte 5 identity-based reactivity broke text_delta streaming —
  immutable message objects in all three chat handlers so text streams live
- feat(web): streaming cursor + inline status indicator merged into message flow
- feat(web): expandable inline tool call cards in chat thread
- feat(web): merge Plan + Event log into one backbone Activity timeline —
  filled status nodes, branch stubs, auto-scroll follow mode, per-session
  activityLog, compact for the rail
- fix(nomos): add X-Accel-Buffering:no to /chat SSE (proxy buffering)
- fix(nomos): plan step auto-close SQL param bug (store.go)
- polish: timestamps, role labels, code copy button, table overflow, min
  window size, delete AgentIndicator/ActivityTimeline dead code
2026-07-21 07:49:02 +02:00
58a11ca872 feat(web): resizable panels via svelte-splitpanes + Claude-style composer
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled
Replace hand-rolled pointer-resize logic (TaskContextPanel's 3-way vertical
split, SessionChatWindow's rail, ChatThread's message/input split) with
svelte-splitpanes, themed onto the app's existing border/primary tokens.

- TaskContextPanel: Scope/Plan/Event-log sections collapse to a fixed header
  height and restore their last size on reopen.
- ChatThread: input area is now a separate resizable pane, clamped to a
  measured one-line minimum and a 45% max, instead of a fixed max-h textarea.
- Send button restyled to sit inside the input's corner (Claude-style),
  swapping the up-arrow for a corner-down-left return icon.
- Adds a $app/environment shim + optimizeDeps exclude, since
  svelte-splitpanes assumes SvelteKit and this is a plain Vite app.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 10:32:54 +02:00
8657ac5669 feat(web): open tasks/sessions as floating windows with independent live chat
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled
Clicking a task now opens it as a wmkit floating window (like entity
windows already do) instead of navigating away from wherever you were.
Several task windows can be open and actively streaming at once, each
fully independent — no "which one's on screen" guard needed, since
each window owns its own store bundle:

- chat.ts: chatFor(sessionId)/loadSessionChat/sendSessionMessage give
  each window its own messages/streaming/connectionState, alongside
  the existing singleton path the main Chat page still uses unchanged.
- workspace.ts: same split for plan/questions/touched/health-diffs
  (workspaceFor/startSessionWorkspace), each with its own live-event
  watermark since several windows can watch the same event stream.
- activity.ts: activityLogFor(sessionId) mirrors the global derivation.

SessionGraph.svelte, OperatorQuestion.svelte, and ActivityTimeline.svelte
were converted from store-importing to prop-driven (matching the new
ChatThread.svelte, extracted from Chat.svelte's transcript/input so both
the main page and task windows share one implementation instead of
duplicating markup/styling) so each can render either the global
"current session" or a specific window's session.

Also: minimized-window taskbar chips now cap at a max width with
middle-ellipsis truncation instead of growing unbounded, and the
window header's title/action-button row is fixed to genuinely match
heights (not just share a center point) for more robust alignment.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-19 17:01:34 +02:00