9 Commits
Author SHA1 Message Date
Khaled Ahmed 4e304ccaad fix(audit): resolve bugs, perf and UX issues
Client logic:
- ChatWindow nearBottom listener now attaches after the loading gate
  (history no longer slides away mid-run); streaming bubble gets a
  per-message key via timestamp so block timers/expanded state no
  longer leak across messages
- Background loadSession failures log instead of replacing the chat
  with a full-screen error
- AudioContext hoisted to a module singleton (sound died after ~6
  session switches); theme OS-flip re-renders all consumers
- ChatInput: attachment revision bump on draft switch/unmount (no
  cross-session image leak), attachError reset, builtin-command clear
  guard, fileIndex AbortController
- SessionSidebar: restore deadlock on empty/failed list fixed,
  expansion keys case-folded via comparableProjectPath, timer cleanup,
  loadProjects seq guard, remove-project catch+toast, worktree
  dropdown close + case-folded highlight, SSE onerror fallback
- AppShell: auto-name refreshKey below guard, archive-restore bails
  when selection changes + tracked timer, same-id select early-return,
  cwd-suppress expected-string latch, fork optimistic row, palette
  null-cwd default-cwd fallback, denied-notification toast,
  visibilitychange update re-check
- MessageView: terminal indicator for interrupted toolCalls, image-only
  results render, edit-from-here gated on navigate success
  (handleNavigate/loadContext return Promise<boolean>), ToolCallBlock
  shallow input compare
- CommandPalette seq guard + focus restore; composer panels persist
  collapse state; SubagentTranscriptDialog refetch/version fixes;
  TodoList in_progress-first preview

Server/RPC:
- getMcpList dedicated in-flight mutex (no waiter stealing/hangs);
  abort resets awaitingAgentStart state (no 10s phantom running)
- agent/new destroys spawned child on post-spawn failure
- sessions PATCH bounded body + stable error contract; mcp liveError
  sanitized; runIsolatedUtilityCommand abortable (wired to req.signal)
- file-access strips Windows long-path prefixes (false 403s); worktree
  branch-name and skills-install package-name validation

Data layer:
- session-reader: timestamps normalized, 256MiB parse-cache byte
  budget, 404-poll cache churn fix
- subagent-history: stale progress can't clobber settled status,
  positional page reads (O(n^2)->O(n)), single-pass async collection
- tool-presets returns null for custom sets; shortModel strips only
  thinking-level suffix; draft-store globalThis persistence;
  subagent-types lastUpdate stamp; project-ordering folded fallback

Perf: displayModel/availableThinkingLevels memoized (composer no
longer re-renders per token frame); ChatMinimap drag re-entrancy,
epsilon-quantized ratios, transform-based viewport

Gates: tsc clean, 472/472 tests, lint clean for touched files
2026-09-01 17:36:13 +03:00
Khaled Ahmed fef3ed589d fix: visual polish — AA contrast, tokens, spacing, mobile layout
- Filled buttons (send, worktree create, confirm dialogs) switch to
  --accent-strong: the design system documents white-on-accent fails AA in the
  dark theme, so filled buttons use the AA-verified strong token.
- Tokens/sec speed badge drops the hardcoded #53b3cb/#9bc53d/#f9c22e/#e01a4f
  palette (three of four failed AA small-text) for theme-adaptive
  --status-* text over a subtle tint.
- Compaction-error tooltip: token surface instead of #1f2937 (near-invisible
  in light theme) and wraps instead of overflowing the viewport.
- Mobile: reserve 44px on the right so the always-fixed file-panel toggle no
  longer covers the session-stats button; popover control heights unified to
  32px; invalid unitless gap: 6 -> 6px.
- --accent-strong used as small text (retry line, error labels, update
  commands) moves to --accent / --status-error; upload progress fill uses the
  accent token; chat keeps its Firefox scrollbar on mobile where the minimap
  is absent.
- Shared SubagentStatusIcon component (composer roster + task summary) and
  useCopyFeedback hook (copy buttons) now back the four previously inlined
  copy-with-check blocks; context-percent formatting unified via lib/format.
2026-08-13 14:12:19 +03:00
Khaled Ahmed 832f541458 fix: polish subagent preview panel 2026-08-12 20:02:16 +03:00
Khaled Ahmed 4419a7926d fix: name IRC message cards by sender; advisor label; transcript pager retry
- irc:incoming/autoreply/relay custom messages now title with the SENDER
  parsed from the envelope ("Incoming IRC message from agent \`X\`") and
  render the stripped body instead of the raw customType label
- advisor custom messages use a localized 'Advisor' title
- transcript pager: a version bump arriving while an older page is in flight
  is no longer marked consumed — the effect retries the latest version once
  the in-flight page settles (open live transcript could otherwise stay stale
  with no Load-more)
2026-08-12 19:35:50 +03:00
Khaled Ahmed bb99d4a586 fix: subagent dialog a11y and missing loadMore locales
- add subagentTranscript.loadMore to en/ja/zh (the dialog referenced it but
  the keys were never added — non-en locales showed the raw key)
- transcript toggle: aria-expanded + aria-controls wiring to the panel
- TaskResultPanel rows: accessible name includes agent + localized status
  (status icons are aria-hidden)
2026-08-12 19:24:05 +03:00
Khaled Ahmed 57ee1f9e36 fix: harden subagent integration from three-agent audit
Wire/hook:
- progress frames keyed by progress.id never fall back to parentToolCallId/
  index when unmatched (was: could overwrite a different child); ID-less
  fallback prefers the exact (parent, index) pair
- roster hydration fenced by session + prompt-run + a generation counter
  bumped on every run-end clear, so stale get_subagents/history responses
  cannot merge or prune a later run's roster
- vanished live entries pruned from get_subagents snapshots, keeping entries
  updated after the request was made
- unknown lifecycle/snapshot statuses rejected; retry state requires all
  documented fields; lifecycle updates sorted by index
- subagentEvents/version maps cleared on run end (cancelling the pending rAF
  flush) and cardinally capped per id

History/API:
- roster route is telemetry-only (full task output no longer shipped); settled
  cost derived from usage.cost.total
- dotted nested subagent ids allowed; symlink escapes blocked via realpath
  confinement on transcript and completion reads (TOCTOU closed by reading the
  resolved path); completion read bounded to the byte cap with UTF-8-safe
  boundary trimming

UI:
- task detail allowlist bounds every string field, projects async/structured-
  output/retry-failure to UI-only fields, and caps rows at 50
- transcript dialog: version-deduped refetch (no infinite loop), remount per
  selection (no stale completion), separate completion/transcript sequence
  refs, live transcript paging on new events, Show transcript toggle with
  RPC-to-disk fallback
- localized chip/task-panel strings (retrying, nested, tok, ctx); sub-second
  durations suppressed; extractedToolData.task array counted; chip accessible
  names include state and listitem roles

Tests: 300 passing (12 new), tsc clean.
2026-08-12 19:09:58 +03:00
Khaled Ahmed 1f7cd8cd4f feat: subagent composer panels, roster, and task/completion dialog
- ComposerPanels: todo plan + subagent roster pinned above the chat input,
  each independently collapsible, with live state chips (activity, retry,
  telemetry, nested count, async marker) fed by subagent_lifecycle/progress
  SSE frames
- Subagent integration: lib/subagent-types.ts (defensive AgentProgress
  parsing), lib/subagent-history.ts (on-disk roster recovery from task
  toolResults + sibling transcript/completion artifacts), task tool-result
  summaries in MessageView (size-bounded telemetry via session-reader)
- Transcript dialog now shows only the assignment (markdown) and the final
  output (<id>.md via ?mode=completion, bounded read that bypasses the
  16MB transcript cap), screen-adaptive width; structured JSON outputs
  render as key/value rows with unescaped text
- Session list cache invalidation fixes for new-session visibility
- Tests: composer panels, dialog blocks, subagent history/types, session
  reader; 295 passing
2026-08-12 17:49:02 +03:00
Khaled Ahmed 25b4da985f Refine sidebar and composer mode status 2026-08-12 04:08:51 +03:00
Khaled Ahmed 725596de86 Add session import, subagent transcript viewer, and lazy syntax grammars 2026-08-11 22:22:10 +03:00