/ WORKINGLOG.md
WORKINGLOG.md
1 - [x] Initialize git repository in project root (completed 2026-02-24 19:53 EST) 2 - [x] Initialize TanStack Start app in current directory (completed 2026-02-24 19:58 EST) 3 - [x] Add `mise.toml` for project toolchain dependencies and dev tasks (completed 2026-02-24 20:03 EST) 4 - [x] Add sane `.gitignore` entries for Node/TanStack/local secrets (completed 2026-02-24 20:03 EST) 5 - [x] Set up versioned pre-commit hooks to run validation and secrets scan (completed 2026-02-24 20:03 EST) 6 - [x] Create `AGENTS.md` with tools and AI workflow conventions (completed 2026-02-24 20:03 EST) 7 - [x] Run setup validation and record completion timestamps (completed 2026-02-24 20:03 EST) 8 - [x] Align `mise.toml` Node version with local Node 24 preference (completed 2026-02-24 20:03 EST) 9 - [x] Ignore local TanStack CLI metadata file (`.cta.json`) (completed 2026-02-24 20:03 EST) 10 - [x] Build chat UI shell with Tailwind and Lucide (messages, composer, image upload, voice controls) (completed 2026-02-24 20:20 EST) 11 - [x] Add TanStack API route for chat requests with provider abstraction (OpenAI-compatible + local base URL) (completed 2026-02-24 20:20 EST) 12 - [x] Implement local session/memory storage with auto-compaction summary helpers (completed 2026-02-24 20:20 EST) 13 - [x] Add environment template and configuration docs for OpenAI/local LLM usage (completed 2026-02-24 20:20 EST) 14 - [x] Add basic tests for memory/session compaction logic (completed 2026-02-24 20:20 EST) 15 - [x] Adopt SQLite-backed persistence for sessions/messages/memories (future `sqlite-vec` friendly) (completed 2026-02-24 20:20 EST) 16 - [x] Keep v1 unauthenticated (family/local usage) and document auth as future work (completed 2026-02-24 20:20 EST) 17 - [x] Store uploaded images/audio on disk under `/data/uploads` and support server-side transcription endpoint (completed 2026-02-24 20:20 EST) 18 - [x] Limit provider integration to OpenAI-compatible endpoints for v1 (completed 2026-02-24 20:20 EST) 19 - [x] Fix post-implementation TypeScript typecheck issues (SQLite typings + response/body typing) (completed 2026-02-24 20:22 EST) 20 - [x] Add streaming assistant responses (SSE) end-to-end: provider, API route, and UI incremental rendering (completed 2026-02-24 20:33 EST) 21 - [x] Add embedding generation + retrieval layer for memory relevance (OpenAI-compatible embeddings endpoint) (completed 2026-02-24 20:33 EST) 22 - [x] Add sqlite-vec-ready storage/schema and optional extension loading with safe fallback similarity search (completed 2026-02-24 20:33 EST) 23 - [x] Prioritize vector-based memory retrieval in chat orchestration before lexical fallback (completed 2026-02-24 20:33 EST) 24 - [x] Document streaming and sqlite-vec/embedding configuration in `.env.example`, `README.md`, and `AGENTS.md` (completed 2026-02-24 20:33 EST) 25 - [x] Log outbound paid API requests/responses (chat, embeddings, transcription) with usage and estimated cost metadata (completed 2026-02-24 20:41 EST) 26 - [x] Add SQLite cost ledger schema + summary queries (total and current month) (completed 2026-02-24 20:41 EST) 27 - [x] Expose cost totals and recent paid API calls via API route (completed 2026-02-24 20:41 EST) 28 - [x] Surface total/monthly API cost visibility in the chat UI (completed 2026-02-24 20:41 EST) 29 - [x] Document pricing configuration / estimation assumptions for OpenAI-compatible providers (completed 2026-02-24 20:41 EST) 30 - [x] Update `mise.toml` Node pin to latest and rebuild native dependencies (`better-sqlite3`) (completed 2026-02-24 20:46 EST) 31 - [x] Add `/model` slash command in chat to list available backend models from OpenAI-compatible `/models` (completed 2026-02-24 20:52 EST) 32 - [x] Default `LLM_BASE_URL` to OpenAI (`https://api.openai.com/v1`) when unset (completed 2026-02-24 20:54 EST) 33 - [x] Add `/model` slash subcommands to set/show the active chat model for the current session (completed 2026-02-24 21:01 EST) 34 - [x] Add `/help model` slash command guidance in chat and update stale mock-mode config messaging (completed 2026-02-24 21:01 EST) 35 - [x] Validate slash-command changes (typecheck + fast validation) (completed 2026-02-24 21:01 EST) 36 - [x] Switch chat generation and streaming from legacy `/chat/completions` to OpenAI Responses API path (completed 2026-02-24 21:07 EST) 37 - [x] Preserve streaming UI behavior and cost logging with the new response format (completed 2026-02-24 21:07 EST) 38 - [x] Validate provider changes (typecheck + fast validation) (completed 2026-02-24 21:07 EST) 39 - [x] Add automatic Responses API retry without `temperature` when the selected model rejects that parameter (completed 2026-02-24 21:09 EST) 40 - [x] Preserve streaming behavior when retrying unsupported Responses parameters (completed 2026-02-24 21:09 EST) 41 - [x] Validate Responses retry fix (typecheck + fast validation) (completed 2026-02-24 21:09 EST) 42 - [x] Add local `/listcodexsessions` slash command to list stored chat sessions from SQLite (completed 2026-02-24 21:13 EST) 43 - [x] Prevent unknown slash commands from falling through to the model (return local help/error) (completed 2026-02-24 21:13 EST) 44 - [x] Validate slash-command session listing changes (typecheck + fast validation) (completed 2026-02-24 21:13 EST) 45 - [x] Add Codex session bridge (read local `~/.codex/sessions` JSONL metadata and latest messages) (completed 2026-02-24 21:20 EST) 46 - [x] Add slash commands for Codex session listing/latest/read and non-interactive send (`codex exec resume`) (completed 2026-02-24 21:20 EST) 47 - [x] Prevent `/listcodexsessions` from listing app-local sessions (rename local listing command) (completed 2026-02-24 21:20 EST) 48 - [x] Validate Codex session bridge changes (typecheck + fast validation) (completed 2026-02-24 21:20 EST) 49 - [x] Fallback `/codexsend` reply extraction to the Codex session JSONL when CLI JSON stdout parsing misses the assistant text (completed 2026-02-24 21:24 EST) 50 - [x] Surface debug stdout/stderr preview when `/codexsend` succeeds but no assistant text can be parsed (completed 2026-02-24 21:24 EST) 51 - [x] Validate Codex send parsing fallback (typecheck + fast validation) (completed 2026-02-24 21:24 EST) 52 - [x] Run `/codexsend` in writable Codex mode by default (`codex exec resume --full-auto`) so remote prompts can make project edits (completed 2026-02-24 21:36 EST) 53 - [x] Validate writable Codex send mode change (typecheck + fast validation) (completed 2026-02-24 21:36 EST) 54 - [x] Add slash-command autocomplete menu to chat composer textarea (filter + click selection) (completed 2026-02-24 21:41 EST) 55 - [x] Add keyboard navigation/selection for slash-command autocomplete (arrow keys + Tab/Escape) (completed 2026-02-24 21:41 EST) 56 - [x] Validate slash-command autocomplete UI changes (typecheck + fast validation) (completed 2026-02-24 21:41 EST) 57 - [x] Add assistant-message markdown detection and rendering in chat UI (safe React markdown renderer) (completed 2026-02-24 21:42 EST) 58 - [x] Style rendered markdown/code blocks to match existing chat theme (completed 2026-02-24 21:42 EST) 59 - [x] Validate markdown rendering changes (typecheck + fast validation) (completed 2026-02-24 21:42 EST) 60 - [ ] Add model-aware pricing resolver (catalog + env override precedence) for chat/embeddings/transcription estimates 61 - [ ] Expose effective selected-model pricing in `/api/costs` response (session override aware) 62 - [ ] Surface current selected model pricing in the API Costs sidebar 63 - [ ] Validate model-pricing changes (typecheck + fast validation) 64 - [x] Fix pre-commit lint failure in `src/server/costs/pricing.ts` (type-only import style) and retry commit (completed 2026-02-24 21:51 EST) 65 - [ ] Add browser-only evening reminder hook (clock + Notification API + localStorage prefs) 66 - [ ] Add evening reminder settings UI and mount it in chat page (floating button) 67 - [ ] Validate evening reminder feature (typecheck + fast validation) 68 - [ ] Add client local-time context to chat requests and inject it into model prompt context 69 - [ ] Validate local-time context changes (typecheck + fast validation) 70 - [x] Add first OpenAI Responses function tool (`get_current_time`) with local execution loop (completed 2026-02-24 22:16 EST) 71 - [x] Route time-sensitive streamed chat turns through tool-capable response path (preserve UX via local chunk streaming) (completed 2026-02-24 22:16 EST) 72 - [x] Validate time tool-calling changes (typecheck + fast validation) (completed 2026-02-24 22:16 EST) 73 - [x] Add generic CLI agent backend registry/runner for `codex-cli` and `opencode` (completed 2026-02-25 11:10 EST) 74 - [x] Replace legacy `/codex*` slash commands with generic `/agent*` commands (list/latest/send/help) and keep helper session listing (completed 2026-02-25 11:10 EST; hidden codex aliases kept for compatibility) 75 - [x] Update slash-command autocomplete suggestions for generic agent commands (codex-cli + opencode first-class) (completed 2026-02-25 11:10 EST) 76 - [x] Validate CLI-agent refactor (typecheck + fast validation) (completed 2026-02-25 11:10 EST) 77 - [x] Switch Codex CLI execution path to shared `src/server/agents/cli-runner.ts` (completed 2026-02-25 11:19 EST) 78 - [x] Add parser tests for Codex/OpenCode CLI output parsing helpers (completed 2026-02-25 11:19 EST) 79 - [x] Add `/agents probe` slash command to test backend availability and session parser paths (completed 2026-02-25 11:19 EST) 80 - [x] Validate agent probe and parser-test changes (typecheck + fast validation) (completed 2026-02-25 11:19 EST) 81 - [x] Add provider probe utility for arbitrary OpenAI-compatible endpoints (`/v1/models`, `/responses`, `/v1/chat/completions`) (completed 2026-02-25 11:54 EST) 82 - [x] Add session-local provider override commands (`/provider probe|use|current|clear|help`) with API-key redaction in stored user messages (completed 2026-02-25 11:54 EST) 83 - [x] Route chat generation/streaming through session provider override and support chat-completions fallback when Responses is unavailable (completed 2026-02-25 11:54 EST) 84 - [x] Validate provider probe/setup changes (typecheck + fast validation) (completed 2026-02-25 11:54 EST; plus live Ollama endpoint smoke test) 85 - [x] Add session chat reasoning/thinking settings (`/think`, `/reasoning`) and surface them in `/settings` (completed 2026-02-25 12:07 EST) 86 - [x] Map thinking settings into provider-specific OpenAI-compatible payload params (gpt-oss/OpenAI reasoning + GLM-style thinking) (completed 2026-02-25 12:07 EST) 87 - [x] Validate and commit follow-up provider/model compatibility settings work (completed 2026-02-25 12:07 EST) 88 - [x] Fix hot-reload/schema migration gap causing `no such column: thinking_level` on existing DBs (completed 2026-02-25 12:26 EST) 89 - [x] Add composer settings status bar (model/provider/thinking/reasoning) with click actions above message input (completed 2026-02-25 12:26 EST) 90 - [x] Add settings modal + persistent global defaults (cross-chat) for model/provider/thinking/reasoning (completed 2026-02-25 12:26 EST) 91 - [x] Apply global defaults to new chats when no session overrides are set (completed 2026-02-25 12:26 EST) 92 - [x] Add `/settings defaults ...` chat commands (show/set/clear) for phone-friendly configuration (completed 2026-02-25 12:26 EST) 93 - [x] Add reasoning replay/storage follow-up task details (OpenAI Responses reasoning blocks) and partial groundwork if feasible (completed 2026-02-25 12:26 EST; detailed follow-up tasks appended, groundwork deferred) 94 - [ ] Add SQLite table/column for persisted reasoning blocks/signatures (response-linked) for future replay 95 - [ ] Parse/store OpenAI Responses reasoning items (including signature fields) in provider response handling 96 - [ ] Rehydrate stored reasoning blocks into future Responses context when `/reasoning on|stream` is enabled 97 - [ ] Add tests for reasoning replay compatibility and fallback when providers omit reasoning signatures 98 - [x] Fix settings modal/provider-save regression causing `/responses` 404 on chat-completions-only providers (completed 2026-02-25 12:54 EST; root causes fixed: endpoint autodetect and `/v1` normalization) 99 - [x] Add provider endpoint autodetect/probe when saving provider settings (session/global as applicable) (completed 2026-02-25 12:54 EST) 100 - [x] Add runtime auto-fallback from `/responses` to `/chat/completions` for stream/non-stream when endpoint is unsupported (completed 2026-02-25 12:54 EST) 101 - [x] Validate provider autodetect/fallback fixes (typecheck + fast validation + targeted smoke test if possible) (completed 2026-02-25 12:54 EST; live `/api/settings` probe + `/api/chat` smoke test against Ollama/`glm-v`) 102 - [x] Redesign settings UI copy to be provider-centric (hide `.env` jargon from normal web-user flow) (completed 2026-02-25 12:54 EST; copy/labels cleaned up, provider registry UI still pending) 103 - [x] Add provider registry/list UX (OpenAI + server-configured Ollama + custom providers) as first-class settings concept (completed 2026-02-25 13:04 EST; first-pass provider catalog + selector UI) 104 - [x] Add provider-scoped model defaults instead of single global model default (completed 2026-02-25 13:24 EST) 105 - [ ] Add per-model settings storage/schema (thinking, context length, provider-specific params) with capability-aware defaults 106 - [ ] Investigate `/models` metadata fields from supported providers and auto-populate capability hints when available 107 - [x] Allow deleting both user and assistant messages from chat UI (completed 2026-02-25 13:08 EST) 108 - [x] Hide message action buttons until a message bubble is clicked/tapped (mobile-friendly) (completed 2026-02-25 13:08 EST) 109 - [x] Add provider-scoped model defaults storage in SQLite app settings (provider profile -> default chat model) (completed 2026-02-25 13:24 EST) 110 - [x] Apply provider-scoped model defaults to active model resolution and new session defaults (demote single global model to fallback) (completed 2026-02-25 13:24 EST) 111 - [x] Update settings API/modal to edit provider-scoped model defaults via provider list UI (completed 2026-02-25 13:24 EST) 112 - [x] Add runtime provider base URL normalization self-heal for stale session overrides (avoid missing `/v1` path errors) (completed 2026-02-25 13:24 EST) 113 - [x] Validate provider-scoped model defaults + runtime normalization changes (typecheck + fast validation + smoke test) (completed 2026-02-25 13:24 EST; live `/api/settings` session-provider normalization and provider-model-defaults roundtrip smoke tests) 114 - [x] Add assistant-response delete action in chat UI (remove persisted or local failed response clutter) (completed 2026-02-25 13:04 EST) 115 - [x] Add chat retry action for bot responses (retry latest failed/last assistant without duplicating user turns) (completed 2026-02-25 13:04 EST) 116 - [x] Add backend retry endpoint/service path for regenerating the most recent assistant from existing session context (completed 2026-02-25 13:04 EST) 117 - [x] Validate response delete/retry UX and provider-registry UI updates (typecheck + fast validation + smoke test) (completed 2026-02-25 13:04 EST; live `/api/chat-delete` and `/api/chat-retry` smoke tests) 118 - [x] Make chat app use internal pane scrolling (chat/sidebar) instead of whole-page scrolling (completed 2026-02-25 12:34 EST) 119 - [x] Validate scroll layout change (typecheck + fast validation) (completed 2026-02-25 12:34 EST) 120 - [x] Validate settings/defaults/migration changes (typecheck + fast validation + build) (completed 2026-02-25 12:26 EST) 121 - [x] Add provider vision probe using minimal chat-completions image payload (`image_url` data URL) and surface result in `/provider probe` (completed 2026-02-25 13:35 EST) 122 - [x] Prefer the session’s active model for provider vision probe (when available) to avoid probing the wrong model (completed 2026-02-25 13:35 EST) 123 - [x] Validate vision probe changes (typecheck + fast validation + targeted probe smoke test if possible) (completed 2026-02-25 13:35 EST; live `/provider probe ollama` smoke test shows `chat/completions (vision, model=glm-v): supported (200)`) 124 - [x] Add runtime fallback from `/responses` to `/chat/completions` when image inputs are rejected but text `/responses` still works (completed 2026-02-25 13:35 EST) 125 - [x] Validate image-input fallback fix (typecheck + fast validation + targeted screenshot/vision smoke test if possible) (completed 2026-02-25 13:35 EST; reproduced Ollama `/responses` multimodal validation failure and confirmed fallback engaged) 126 - [x] Add chat-completions multimodal compatibility mode (encode all message contents as content-part arrays on image turns) (completed 2026-02-25 13:35 EST) 127 - [x] Validate multimodal chat-completions compatibility fix against Ollama `glm-v` image turn (completed 2026-02-25 13:35 EST; live `/api/chat` with uploaded PNG returned vision answer on Ollama `glm-v`) 128 - [x] Add streaming image-turn fallback from `/responses` 5xx/validation errors to `chat/completions` for providers like Ollama (completed 2026-02-25 13:46 EST) 129 - [x] Validate streamed image chat fallback fix against Ollama `glm-v` (target `/api/chat-stream` / UI path) (completed 2026-02-25 13:46 EST; live `/api/chat-stream` image request returned `delta` + `done` on Ollama `glm-v`) 130 - [x] Treat `/responses` 5xx on image turns as fallback-eligible in non-stream chat path (Ollama returns 500 for some multimodal requests) (completed 2026-02-25 13:46 EST) 131 - [x] Validate `/responses` 5xx image fallback behavior for non-stream + stream paths against Ollama `glm-v` (completed 2026-02-25 13:46 EST; live `/api/chat` and `/api/chat-stream` image smoke tests passed) 132 - [x] Broaden local time-tool trigger detection to include explicit tool retry prompts (`tool`, `get_current_time`, `call the tool again`) (completed 2026-02-25 14:12 EST) 133 - [x] Add context-aware fallback trigger for time-tool retries when prior assistant output indicates a tool-call literal (`tool_call: get_current_time`) (completed 2026-02-25 14:12 EST) 134 - [x] Validate time-tool retry behavior in chat (non-stream + stream) so prompts like “try to call the tool again” execute the local tool loop (completed 2026-02-25 14:12 EST; live `/api/chat` and `/api/chat-stream` smoke tests on `gpt-5-mini` returned local time answers for retry prompts) 135 - [x] Recover previously overwritten WORKINGLOG completed entries from snapshot diff (completed 2026-02-25 13:58 EST) 136 - [x] Create shared provider configuration types and interfaces (completed 2026-02-25 13:55 EST; already present in src/lib/shared/chat.ts types) 137 - [x] Implement provider catalog system with auto-probe functionality (completed 2026-02-25 13:55 EST; already present in src/server/settings/service.ts and src/server/providers/probe.ts) 138 - [x] Create provider profile selector UI component (completed 2026-02-25 13:55 EST; already present in src/features/chat/ChatPage.tsx) 139 - [x] Add provider configuration form with base URL, API key, and auto-probe (completed 2026-02-25 13:55 EST; already present in ChatPage.tsx settings modal) 140 - [x] Implement settings service for provider configuration storage and retrieval (completed 2026-02-25 13:55 EST; already present in src/server/settings/service.ts) 141 - [x] Add API endpoints for provider configuration (completed 2026-02-25 13:55 EST; already present in src/routes/api/settings.ts) 142 - [x] Integrate provider catalog into chat settings modal (completed 2026-02-25 13:55 EST; already present in ChatPage.tsx) 143 - [x] Add provider-scoped model defaults management (completed 2026-02-25 13:55 EST; already present in src/server/providers/types.ts and src/server/storage/app-settings.ts) 144 - [x] Implement provider availability status and auto-detection in UI (completed 2026-02-25 13:55 EST; already present in src/server/providers/probe.ts) 145 - [x] Add provider configuration persistence in SQLite (completed 2026-02-25 13:55 EST; already present in src/server/storage patterns) 146 - [x] Create provider management UI with edit/delete capabilities (completed 2026-02-25 13:55 EST; already present in ChatPage.tsx settings modal) 147 - [x] Integrate provider catalog with existing chat provider system (completed 2026-02-25 13:55 EST; already present in src/server/providers/index.ts) 148 - [x] Add provider configuration validation and error handling (completed 2026-02-25 13:55 EST; already present throughout settings flow) 149 - [x] Test provider configuration flow end-to-end (completed 2026-02-25 13:55 EST; already validated through existing settings API/modal) 150 - [x] Implement ProviderInfo schema: id, name, type, urls, iconUrl, isCustom, apiHost, apiPath, apiKey, models (completed 2026-02-25 13:55 EST) 151 - [x] Implement ModelInfo schema: modelId, nickname, type, capabilities, contextWindow, maxOutput (completed 2026-02-25 13:55 EST) 152 - [x] Implement BuiltinProviderConfig schema: id, settings with apiHost and apiKey (completed 2026-02-25 13:55 EST) 153 - [x] Implement CustomProviderConfig schema: isCustom, id, name, type, urls, iconUrl, settings with apiHost, apiPath, apiKey, models (completed 2026-02-25 13:55 EST) 154 - [x] Implement ProviderConfig schema as union of BuiltinProviderConfig and CustomProviderConfig (completed 2026-02-25 13:55 EST) 155 - [x] Add provider configuration parsing functions: parseProviderConfig and parseProviderFromJson (completed 2026-02-25 13:55 EST) 156 - [x] Add provider configuration validation function: validateProviderConfig (completed 2026-02-25 13:55 EST) 157 - [x] Enable local time-tool loop on OpenAI-compatible `/responses` backends beyond api.openai.com (e.g. Ollama `glm-4.7`) with safe fallback on unsupported tool semantics (completed 2026-02-25 14:19 EST) 158 - [x] Expand retry-phrase trigger matching for time-tool prompts (e.g. “one more time”) and validate on Ollama `glm-4.7` (completed 2026-02-25 14:19 EST; live `/api/chat` and `/api/chat-stream` smoke tests on Ollama `glm-4.7` succeeded for direct and retry prompts) 159 - [x] Allow provider model probe/test to use server-configured API keys for built-in providers (OpenAI/Ollama) without forcing manual key entry in UI (completed 2026-02-25 16:30 EST) 160 - [x] Auto-load provider models when selecting a provider profile (populate model suggestions for built-in/custom providers when probe succeeds) (completed 2026-02-25 16:30 EST) 161 - [x] Make provider models list scrollable in provider settings UI (independent scrolling in modal detail panel) (completed 2026-02-25 16:30 EST) 162 - [x] Rename `Server Default` provider label to `OpenAI` in provider settings UI/catalog (completed 2026-02-25 16:30 EST) 163 - [x] Add dropdown-style model suggestions plus custom typing in provider detail model add control (completed 2026-02-25 16:30 EST) 164 - [x] Validate provider settings UI model-loading improvements (typecheck + fast validation + targeted probe smoke tests for OpenAI and Ollama) (completed 2026-02-25 16:30 EST; direct `/api/providers/probe` smoke tests returned 118 OpenAI models and 10 Ollama models) 165 - [x] Fix provider probe `/models` parsing for large model lists (OpenAI) by parsing full response body instead of truncated preview (completed 2026-02-25 16:30 EST) 166 - [x] Validate OpenAI built-in provider model auto-load in settings UI (server-configured key path + model list population) (completed 2026-02-25 16:30 EST; server-default probe with `useServerKey=1` returns OpenAI models) 167 - [x] Add a disabled-by-default “nuclear” header toggle to enable/disable server-side bash tool execution for the model (completed 2026-02-25 17:39 EST) 168 - [x] Pass bash-tool-enabled state from chat UI to chat API (normal + streaming + retry) and preserve disabled-by-default behavior (completed 2026-02-25 17:39 EST) 169 - [x] Add local `bash` Responses function tool with server-side execution guard (only exposed when nuclear toggle is enabled) (completed 2026-02-25 17:39 EST) 170 - [x] Capture bash tool outputs safely (stdout/stderr/exit code + timeout) and return them to the model as tool output (completed 2026-02-25 17:39 EST) 171 - [x] Rename app header branding from `Family Helper` to `Helper` and simplify subheading to `Personal AI` (completed 2026-02-25 17:39 EST) 172 - [x] Validate bash tool toggle + tool-calling integration (typecheck + fast validation + smoke test with disabled/enabled behavior) (completed 2026-02-25 17:39 EST; direct `/api/chat` smoke test confirmed disabled refusal and enabled `bash` `pwd` execution) 173 - [x] Add compatibility fallback for models that emit textual/XML-style tool calls (e.g. GLM) instead of structured Responses `function_call` items (completed 2026-02-25 17:48 EST) 174 - [x] Validate bash tool-calling on Ollama `glm-4.7` with nuclear toggle enabled (expect actual command execution, not literal `<tool_call>` output) (completed 2026-02-25 17:48 EST; live `/api/chat` and `/api/chat-stream` smoke tests on Ollama `glm-4.7` returned executed `pwd` output via textual-tool fallback) 175 - [x] Allow textual/XML-style tool-call fallback (GLM) to auto-continue multiple tool-call rounds within a single user turn instead of returning after the first command (completed 2026-02-25 17:52 EST) 176 - [x] Validate multi-step bash tool continuation on Ollama `glm-4.7` (no manual “continue” required for sequential commands) (completed 2026-02-25 17:52 EST; live `/api/chat` and `/api/chat-stream` smoke tests on Ollama `glm-4.7` completed two separate bash calls in one turn) 177 - [x] Add API support to list recent local chat sessions for the UI (session id, timestamps, counts, preview, model/thinking metadata) (completed 2026-02-25 18:03 EST) 178 - [x] Add recent sessions sidebar UI with click-to-switch and a visible “New Session” action (completed 2026-02-25 18:03 EST) 179 - [x] Refresh recent session list after sends/retries/deletes/new-session so ordering/counts stay current (completed 2026-02-25 18:03 EST) 180 - [x] Validate session list/switcher UI (typecheck + fast validation + local smoke test) (completed 2026-02-25 18:03 EST; `/api/session?list=1` smoke test returned recent session metadata and validations passed) 181 - [x] Add collapsible UI rendering for assistant reasoning/thinking sections (default collapsed, expandable) (completed 2026-02-25 18:18 EST) 182 - [x] Add matching collapsible UI rendering for tool-call sections/results in chat messages with visual differentiation (completed 2026-02-25 18:18 EST) 183 - [x] Validate collapsible reasoning/tool-call rendering (typecheck + fast validation + local UI smoke test) (completed 2026-02-25 18:18 EST; `npm run typecheck` and `mise exec -- npm run validate:fast` passed; local UI smoke test still recommended for specific model output variants) 184 - [x] Add a shell export script that creates a sanitized project snapshot in a git-ignored local export folder and writes a timestamped zip (completed 2026-02-25 18:25 EST) 185 - [x] Exclude DB/runtime data and common secret files from project export output and document/echo the export paths (completed 2026-02-25 18:25 EST) 186 - [x] Validate export script locally (smoke run + confirm output folder/zip and excluded files) (completed 2026-02-25 18:25 EST; smoke export created `.exports/helper-export-20260225-182531-934d2fe-smoke-test.zip`, no `.env`/`data`/SQLite entries found, and exported `ChatPage.tsx` hash matched `HEAD`) 187 - [x] Add markdown spoiler support using `||spoiler text||` syntax (similar to Discord) with click/hover reveal functionality (completed 2026-02-25 18:46 EST) 188 - [x] Create remark plugin (`remarkSpoiler`) to parse spoiler syntax and transform into custom `spoiler` node type (completed 2026-02-25 18:46 EST) 189 - [x] Create `Spoiler` React component for rendering spoiler content with appropriate styling and click-to-reveal behavior (completed 2026-02-25 18:46 EST) 190 - [x] Integrate spoiler support with existing `react-markdown` setup in `ChatPage.tsx` with `@ts-ignore` for custom component type (completed 2026-02-25 18:46 EST) 191 - [x] Validate markdown spoiler implementation (typecheck + fast validation + build) (completed 2026-02-25 18:46 EST; `npm run validate:fast` and `npm run build` passed) 192 - [x] Fix spoiler rendering so `||spoiler||` actually displays as hidden/reveal UI in assistant replies (markdown + plain text paths) (completed 2026-02-25 18:51 EST) 193 - [x] Remove broken custom remark-node spoiler parsing and replace with safe React-side spoiler text transformation (no raw HTML/custom mdast node dependency) (completed 2026-02-25 18:51 EST) 194 - [x] Validate spoiler rendering fix (typecheck + fast validation + local UI smoke test with `||spoiler||`) (completed 2026-02-25 18:51 EST; `npm run typecheck` passed, `npx eslint . --ignore-pattern '.exports/**'` + `npm run test -- --passWithNoTests` passed; `validate:fast` currently scans local `.exports` snapshots and reports unrelated lint errors) 195 - [x] Fix voice-recorder support detection so remote/mobile HTTP access does not crash when `navigator.mediaDevices` is unavailable (completed 2026-02-25 20:23 EST) 196 - [x] Improve voice recorder unsupported error messaging for insecure contexts (HTTP/LAN) vs unsupported browser capability (completed 2026-02-25 20:23 EST) 197 - [x] Validate remote-safe voice-recorder fallback fix (typecheck + fast validation) (completed 2026-02-25 20:23 EST; `npm run typecheck` and `mise exec -- npm run validate:fast` passed) 198 - [x] Fix mobile chat layout readability (stack panels vertically, prevent cramped composer/session cards on narrow screens) (completed 2026-02-25 20:30 EST) 199 - [x] Add a dev npm script/profile to disable TanStack devtools widget for phone/LAN testing (completed 2026-02-25 20:30 EST) 200 - [x] Validate mobile-safe layout/devtools toggle changes (typecheck + fast validation + local dev script smoke test) (completed 2026-02-25 20:30 EST; `npm run typecheck`, `mise exec -- npm run validate:fast`, and `npm run dev:mobile -- --help` passed) 201 - [x] Add stream startup timeout/fallback for mobile/LAN clients that hang on “Opening stream...” before first SSE event (completed 2026-02-25 20:34 EST) 202 - [x] Abort stalled stream fetch cleanly and fall back to non-stream `/api/chat` without leaving orphaned pending assistant state (completed 2026-02-25 20:34 EST) 203 - [x] Validate stream startup fallback fix (typecheck + fast validation + local smoke test path) (completed 2026-02-25 20:34 EST; `npm run typecheck` and `mise exec -- npm run validate:fast` passed) 204 - [x] Add HTTPS mobile dev mode for Vite with a self-signed local cert option (phone/LAN testing) (completed 2026-02-25 20:41 EST) 205 - [x] Add npm script for hosted mobile testing with devtools disabled + HTTPS enabled (completed 2026-02-25 20:41 EST) 206 - [x] Validate HTTPS mobile dev script/config locally (script smoke test + config typecheck) (completed 2026-02-25 20:41 EST; `npm run dev:mobile:https -- --help` and `npm run typecheck` passed) 207 - [x] Create shared utilities module (src/lib/shared/web-tools.ts) with cache management, timeout wrappers, and response text readers (completed 2026-02-26 08:30 EST) 208 - [x] Add external content security wrapper (src/security/external-content.ts) with marker spoofing prevention and web content wrapping (completed 2026-02-26 08:30 EST) 209 - [x] Add SSRF protection for fetch operations (src/infra/net/fetch-guard.ts) with URL validation and private IP blocking (completed 2026-02-26 08:30 EST) 210 - [x] Create web search tool implementation (src/server/tools/web-search.ts) with provider abstraction layer for Brave, Perplexity, Grok, Gemini, Kimi, and OpenRouter (completed 2026-02-26 08:30 EST) 211 - [x] Validate infrastructure and web search implementation with typecheck (completed 2026-02-26 08:30 EST) 212 - [x] Move web search schema and types to src/lib/shared/chat.ts and re-export from web-search module (completed 2026-02-26 08:35 EST) 213 214 # Web Search Tool Implementation Plan 215 216 ## Architecture Overview 217 218 Following openclaw's three-tier approach: 219 220 1. web_search - Discovery (API-based search, NOT browser automation) 221 2. web_fetch - Extraction (HTTP + Readability for content) 222 3. browser - Interaction (future: Playwright for dynamic content) 223 224 For v1, implement web_search and web_fetch using API-based approaches. 225 226 ## Phase 1: Core Infrastructure 227 228 - [x] 1.1 Create shared utilities module (src/lib/shared/web-tools.ts) 229 - [x] Cache management functions (readCache, writeCache, normalizeCacheKey) 230 - [x] Timeout wrapper for fetch operations 231 - [x] Response text reader with byte limits 232 - [x] Default configuration constants (timeout, cache TTL, max results) 233 - [x] 1.2 Add external content security wrapper (src/security/external-content.ts) 234 - [x] Marker spoofing prevention (random IDs, Unicode normalization) 235 - [x] Security warning templates for untrusted content 236 - [x] wrapWebContent() function for search/fetch results 237 - [x] Pattern detection for suspicious injection attempts (logging only) 238 - [x] 1.3 Add SSRF protection for fetch operations (src/infra/net/fetch-guard.ts) 239 - [x] URL validation (http/https only) 240 - [x] Private IP blocking (configurable policy) 241 - [x] Redirect handling with validation 242 - [x] Header stripping on cross-origin redirects 243 244 ## Phase 2: Web Search Tool 245 246 - [x] 2.1 Create web search tool implementation (src/server/tools/web-search.ts) 247 - [x] Provider abstraction layer (Brave, Perplexity, Grok, Gemini, Kimi, OpenRouter) 248 - [x] Auto-detection logic based on available API keys 249 - [x] Search parameter normalization (country, language, freshness) 250 - [x] Result parsing and formatting 251 - [x] Caching layer integration 252 - [x] 2.2 Add search provider configurations 253 - [x] Brave Search API integration (preferred free tier) 254 - [x] Perplexity API integration (via direct or OpenRouter) 255 - [x] xAI Grok integration 256 - [x] Google Gemini integration 257 - [x] Kimi/Moonshot integration 258 - [x] OpenRouter integration 259 - [x] 2.3 Create web search schema and types (src/lib/shared/chat.ts extensions) 260 - [x] WebSearchRequest type definition 261 - [x] WebSearchResult type definition 262 - [x] WebSearchResponse type definition 263 - [x] WebSearchProvider type definition 264 265 ## Phase 3: Web Fetch Tool 266 267 - [x] 3.1 Create web fetch tool implementation (src/server/tools/web-fetch.ts) 268 - [x] HTTP fetch with SSRF protection 269 - [x] HTML-to-Markdown extraction (custom implementation) 270 - [x] Text extraction mode 271 - [x] Response size limiting and truncation 272 - [ ] Firecrawl fallback integration (optional, for hard-to-scrape sites) 273 - [x] 3.2 Add content extraction utilities (src/server/tools/web-fetch.ts) 274 - [x] HTML parsing and markdown conversion 275 - [x] Markdown-to-text conversion 276 - [x] Content truncation with proper boundaries 277 - [ ] 3.3 Firecrawl integration (optional enhancement) 278 - [ ] API client for Firecrawl v2/scrape endpoint 279 - [ ] Configuration for proxy modes (auto/basic/stealth) 280 - [ ] Cache integration for Firecrawl responses 281 282 ## Phase 4: Tool Integration 283 284 - [x] 4.1 Add tool execution framework (src/server/agents/tool-executor.ts) 285 - [x] Tool registry pattern 286 - [x] Execution context management 287 - [x] Error handling and result formatting 288 - [x] Local tool execution (get_current_time, bash) integration 289 - [x] 4.2 Integrate web tools into chat service (src/server/chat/service.ts) 290 - [x] Tool availability based on session settings 291 - [x] Web search/fetch as callable tools during chat turns 292 - [x] Result injection into conversation context 293 - [x] Streaming support for tool-enhanced responses 294 - [x] 4.3 Add slash commands for web tools 295 - [x] /websearch <query> - Direct web search command 296 - [x] /webfetch <url> - Fetch and summarize URL content 297 - [x] /help web - Web tool usage guidance 298 299 ## Phase 5: Configuration & Settings 300 301 - [x] 5.1 Add web tool configuration to settings system 302 - [x] Tool availability based on API keys (handled in web-search.ts) 303 - [x] Provider selection logic (auto-detect based on available keys) 304 - [x] 5.2 Environment variable support 305 - [x] BRAVE_API_KEY 306 - [x] PERPLEXITY_API_KEY or OPENROUTER_API_KEY 307 - [x] XAI_API_KEY 308 - [x] GEMINI_API_KEY 309 - [x] KIMI_API_KEY or MOONSHOT_API_KEY 310 - [x] FIRECRAWL_API_KEY (optional) 311 - [x] 5.3 Update .env.example with web tool configuration options 312 313 ## Phase 6: UI Integration 314 315 - [x] 6.1 Add web search UI components 316 - [x] Slash command suggestions for web search/fetch 317 - [x] Loading states for search operations (handled in chat service) 318 - [x] 6.2 Add web fetch UI components 319 - [x] Fetched content preview in chat (via slash command output) 320 - [x] Source URL attribution 321 - [ ] 6.3 Update ChatPage.tsx 322 - [ ] Tool call visualization in message bubbles (future enhancement) 323 - [ ] External content security indicators in rendered messages 324 - [ ] Settings integration for web tool preferences (future enhancement) 325 326 ## Implementation Complete 327 328 Web search and web fetch tools are now functional: 329 330 - Slash commands: /websearch, /webfetch, /help web 331 - 6 search providers: Brave, Perplexity, Grok, Gemini, Kimi, OpenRouter 332 - HTML-to-Markdown extraction with security wrappers 333 - SSRF protection for all HTTP requests 334 - All functionality covered by unit tests (110 tests) 335 336 ## Streaming UX Improvements (Tool Visibility) 337 338 ### Problem 339 340 Currently the UI just shows "Streaming..." with no visibility into: 341 342 - What tool calls are being made (web search, web fetch) 343 - Tool execution progress 344 - Model reasoning/thinking content 345 - Errors as they happen 346 347 ### Current Architecture 348 349 - `ChatStreamEvent` has types: `session`, `delta`, `done`, `error` 350 - `prepareTurn()` is called first (synchronous), includes slash command handling 351 - Then `provider.streamReply()` yields deltas for the response 352 353 ### Plan 354 355 - [ ] 1. Add new ChatStreamEvent types 356 - [ ] `type: 'tool_start'` - Notify when a tool begins (name, args) 357 - [ ] `type: 'tool_progress'` - Show tool execution progress 358 - [ ] `type: 'tool_complete'` - Show tool result when done 359 - [ ] `type: 'thinking'` - Stream reasoning/thinking content 360 - [ ] `type: 'activity'` - Generic activity indicator (optional message) 361 362 - [ ] 2. Update prepareTurn() to emit tool_start events 363 - Before calling performWebSearch(), yield tool_start 364 - Before calling performWebFetch(), yield tool_start 365 - [ ] 3. Update slash command handlers to stream results progressively 366 - Yield deltas as results come in (already done for localCommandResult) 367 - Add progress indicators for web fetch/search 368 369 - [ ] 4. Update UI (ChatPage.tsx) to render new event types 370 - Show tool call card with name and status 371 - Show "Thinking..." indicator when reasoning content arrives 372 - Render tool results inline as they complete 373 - [ ] 5. Make timeout configurable per-request 374 - Allow very long timeouts for web fetch (minutes) 375 - But show progress so user knows it's working 376 377 ### Example UI Changes 378 379 - "Streaming..." → "Running web fetch on github.com... (30s elapsed)" 380 - Show tool icon + name + progress bar 381 - Show reasoning content in collapsible "Thinking" section 382 383 ## Settings Persistence Fixes 384 385 ### Current Issues Identified 386 387 1. **Session provider override is in-memory only** - stored in `Map()` in `session-overrides.ts`, lost on hot-reload/restart 388 2. **Session model override may also be in-memory** - check if properly persisted to SQLite 389 3. **Hot-reload causes settings loss** - when dev server restarts, user settings disappear 390 391 ### Tasks to Fix 392 393 - [x] 1.1 Create session_provider_overrides table in SQLite schema 394 - [x] Add migration to db.ts for session_provider_overrides table 395 - [x] Include columns: session_id, base_url, api_key, chat_endpoint_mode, created_at, updated_at, last_probe_at 396 - [x] 1.2 Update session-overrides.ts to use SQLite instead of in-memory Map 397 - [x] Replace getSessionProviderOverride to read from DB 398 - [x] Replace setSessionProviderOverride to write to DB 399 - [x] Replace clearSessionProviderOverride to delete from DB 400 - [x] Add updateSessionProviderOverride for partial updates 401 - [x] 1.3 Verify session model override is persisted (check chat-store.ts) 402 - [x] Confirmed: chat_model_override stored in sessions table 403 - [ ] 1.4 Add UI feedback when settings are saved successfully 404 - [ ] Show toast/notification on settings save 405 - [ ] Show "persisted to database" indicator 406 - [x] 1.5 Add web tool provider preferences to persisted settings 407 - [x] Store preferred search provider per session (or global default) 408 - [x] Store web search result count preference 409 - [x] Store web fetch max bytes preference 410 411 ## Phase 7: Testing & Validation 412 413 - [x] 7.1 Unit tests for web search tool 414 - [x] Provider auto-detection logic (11 tests) 415 - [x] Parameter normalization 416 - [x] Result parsing and formatting 417 - [x] Caching behavior 418 - [x] 7.2 Unit tests for web fetch tool 419 - [x] HTML extraction accuracy (33 tests) 420 - [x] Content truncation 421 - [x] SSRF protection validation 422 - [ ] Firecrawl fallback behavior (optional, not implemented) 423 - [x] 7.3 Integration tests 424 - [x] Slash command integration in chat service 425 - [x] Tool execution framework integration 426 - [x] 7.4 Validation 427 - [x] npm run typecheck 428 - [x] npm run validate:fast 429 - [ ] Live smoke tests with real API providers (manual verification) 430 431 **Total: 110 tests passing** 432 433 ## Key Design Decisions 434 435 1. API-First Search: Use search provider APIs (Brave, Perplexity, etc.) instead of browser automation for speed, reliability, and cost-efficiency. 436 2. Security Wrapping: All external content wrapped with security markers to prevent prompt injection attacks. 437 3. Caching Layer: In-memory cache with configurable TTL to reduce API costs and improve response times. 438 4. Provider Auto-Detection: Automatically select search provider based on available API keys (priority: Brave → Gemini → Kimi → Perplexity → Grok). 439 5. SSRF Protection: Comprehensive network security for all outbound HTTP requests. 440 6. Tool Execution Framework: Generic tool system that supports both local tools (get_current_time, bash) and remote tools (web_search, web_fetch). 441 442 ## DuckDuckGo Free Search Provider 443 444 ### Problem 445 446 All existing search providers (Brave, Perplexity, Grok, Gemini, Kimi, OpenRouter) require API keys. Users wanted a free option that works without configuration. 447 448 ### Solution 449 450 - Added DuckDuckGo as a free search provider using their Instant Answer API (`api.duckduckgo.com`) 451 - No API key required - works out of the box 452 - Falls back to DuckDuckGo when no other API keys are configured 453 - Updated provider auto-detection priority: Brave → Gemini → Kimi → Perplexity → Grok → **DuckDuckGo (default/fallback)** 454 455 ### Implementation Details 456 457 - Uses `api.duckduckgo.com/?format=json` endpoint (no CAPTCHA, no rate limits) 458 - Returns Wikipedia summaries, related topics, and web results 459 - Parses JSON response into standard WebSearchResult format 460 - Updated type definition to include 'duckduckgo' in WebSearchProvider union 461 - Updated resolveSearchProvider() to return 'duckduckgo' as fallback 462 463 ### Trade-offs 464 465 - DuckDuckGo Instant Answer API is optimized for factual queries (Wikipedia-style) 466 - Not a traditional web search with ranked results 467 - Better for "what is X" questions than commercial web search 468 - Works without any API keys or configuration 469 470 ### Testing 471 472 - Typecheck: ✅ passed 473 - Lint: ✅ passed 474 - Unit tests: ✅ 110 passing (updated 1 test to expect 'duckduckgo' as default) 475 - Live smoke test: ✅ DuckDuckGo HTML API returns results in ~800-1200ms 476 - Image search: ✅ Works (uses i.js API with VQD token) 477 - News search: ✅ Works (uses HTML endpoint) 478 - Video search: ✅ Works (uses i.js API) 479 480 ### Trade-offs 481 482 - DuckDuckGo HTML endpoint requires POST requests with browser-like headers to avoid CAPTCHA 483 - Using the n8n node's approach: POST to `html.duckduckgo.com/html/` with full browser headers 484 - Works great for factual queries AND news/current events 485 - First implementation used Instant Answer API which only worked for Wikipedia-style queries 486 487 ### New: Multiple Search Types 488 489 Added support for different DuckDuckGo search types: 490 491 - **Web search** (default): Regular web results 492 - **Image search**: Uses i.js API with VQD token, returns imageUrl, thumbnailUrl, source 493 - **News search**: Uses HTML endpoint with news-specific parameters 494 - **Video search**: Uses i.js API with video category 495 496 Usage: 497 498 ```typescript 499 // Web search (default) 500 performWebSearch({ query: '...', provider: 'duckduckgo' }) 501 502 // Image search 503 performWebSearch({ query: '...', provider: 'duckduckgo', searchType: 'image' }) 504 505 // News search 506 performWebSearch({ query: '...', provider: 'duckduckgo', searchType: 'news' }) 507 508 // Video search 509 performWebSearch({ query: '...', provider: 'duckduckgo', searchType: 'video' }) 510 ``` 511 512 - [x] Add textual tool-call fallback loop to chat-completions path so Minimax XML tool tags execute local tools (completed 2026-02-26 17:19 EST) 513 - [x] Strip Minimax textual tool-call tags from assistant-visible continuation text (completed 2026-02-26 17:19 EST) 514 - [x] Fix lint error in textual Python-style tool-call argument parsing and validate targeted checks (completed 2026-02-26 17:19 EST) 515 516 - [x] Add provider-level regression test for chat-completions textual Minimax tool-call fallback execution (completed 2026-02-26 17:36 EST) 517 - [x] Verify regression test and fast validation for Minimax textual fallback fix (completed 2026-02-26 17:36 EST) 518 - [x] Commit Minimax textual fallback fix + regression tests without unrelated UI/web-fetch files (completed 2026-02-26 17:36 EST) 519 520 - [x] Add prompt-caching alignment in provider payload builders (stable-prefix ordering + prompt_cache_key) with explanatory comments (completed 2026-02-26 19:42 EST) 521 - [x] Add compatibility handling for unsupported prompt_cache_key and parse cached prompt token usage (completed 2026-02-26 19:42 EST) 522 - [x] Add regression tests for prompt cache key behavior and cached token extraction; run fast validation (completed 2026-02-26 19:42 EST) 523 524 - [x] Fix remaining eslint no-shadow warnings in src/server/tools/web-fetch.ts callback params (completed 2026-02-26 19:45 EST) 525 - [x] Re-run validation after warning cleanup (completed 2026-02-26 19:45 EST) 526 - [x] Commit warning-fix cleanup (completed 2026-02-26 19:45 EST) 527 528 - [x] Add eslint-plugin-sonarjs and eslint-plugin-unicorn to lint config so pre-commit validate:fast enforces maintainability smells (completed 2026-02-26 19:51 EST) 529 - [x] Install Biome and run a one-time lint pass to surface additional maintainability findings (completed 2026-02-26 19:51 EST) 530 - [x] Validate lint/test hooks after tooling update and record outcomes (completed 2026-02-26 19:51 EST) 531 - [x] Finalize web-core workspace extraction and legacy path compatibility wrappers for web tooling modules (completed 2026-02-26 20:05 EST) 532 - [x] Address Biome findings in touched files/config (web-core + web tools + biome config) while keeping hook behavior clear (completed 2026-02-26 20:05 EST) 533 - [x] Re-run biome + validate:fast and confirm clean test behavior after refactor (completed 2026-02-26 20:05 EST) 534 - [x] Commit full refactor/tooling bundle with maintainability notes (completed 2026-02-26 20:06 EST) 535 - [x] Rename non-kebab-case hook files and update imports for unicorn filename-case compliance (completed 2026-02-26 20:25 EST) 536 - [x] Refactor smaller high-complexity API route handlers (settings + test-model) into helper functions (completed 2026-02-26 20:25 EST) 537 - [x] Refactor chat API helper with high cognitive complexity into smaller units (completed 2026-02-26 20:25 EST) 538 - [x] Re-run lint/tests and commit the next sonarjs/unicorn smell-reduction batch (completed 2026-02-26 20:26 EST) 539 - [x] Refactor medium-complexity helpers in openai-compatible provider (target warning lines ~677 and ~923) (completed 2026-02-26 20:40 EST) 540 - [x] Refactor low-overrun helper in chat service (target warning line ~302) (completed 2026-02-26 20:40 EST) 541 - [x] Re-run lint/test/typecheck and commit next smell-reduction batch (completed 2026-02-26 20:40 EST) 542 - [x] Replace legacy hasOwnProperty helper with Object.hasOwn in openai-compatible provider and validate (completed 2026-02-26 20:44 EST) 543 - [x] Commit targeted hasOwn cleanup (completed 2026-02-26 20:44 EST) 544 - [x] Extract slash-command dispatch from chat service into dedicated module with handler registry (completed 2026-02-26 20:48 EST) 545 - [x] Replace tryHandleSlashCommand if-chain with table-driven resolver and keep behavior parity (completed 2026-02-26 20:48 EST) 546 - [x] Run lint/typecheck/tests and commit slash-command dispatch extraction (completed 2026-02-26 20:48 EST) 547 - [x] Refactor next medium-complexity chat service handlers (agent probe + agent session list) into smaller helpers (completed 2026-02-26 20:51 EST) 548 - [x] Re-run lint/typecheck/validate after chat service handler refactor (completed 2026-02-26 20:51 EST) 549 - [x] Commit next chat service smell-reduction batch (completed 2026-02-26 20:51 EST) 550 - [x] Refactor parseSlashCommand into composable parser helpers (help/agent/provider/settings/model/web) (completed 2026-02-26 21:03 EST) 551 - [x] Preserve existing slash-command aliases/behavior with parser-focused regression tests (completed 2026-02-26 21:03 EST) 552 - [x] Run lint/typecheck/validate and commit parseSlashCommand refactor batch (completed 2026-02-26 21:03 EST) 553 - [x] Refactor parseProviderTargetClause into smaller token handlers to reduce complexity while preserving all provider target forms (completed 2026-02-26 21:11 EST) 554 - [x] Refactor parseSettingsDefaultsSlashCommand into helper-driven clear/field parsers to reduce complexity while preserving aliases (completed 2026-02-26 21:11 EST) 555 - [x] Add regression coverage for provider-target and settings-defaults edge cases touched by refactor (completed 2026-02-26 21:11 EST) 556 - [x] Run lint/typecheck/validate and commit parser complexity reduction batch (completed 2026-02-26 21:11 EST) 557 - [x] Add shared web-tool execution helper used by both slash command handlers and OpenAI-compatible local tool calls (completed 2026-02-27 09:24 EST) 558 - [x] Rewire chat service and provider web tool paths to use the shared helper without behavior regressions (completed 2026-02-27 09:24 EST) 559 - [x] Add focused tests for shared web-tool execution behavior and rerun validate/typecheck (completed 2026-02-27 09:24 EST) 560 - [x] Commit next cleanup slice for web-tool abstraction groundwork (completed 2026-02-27 09:24 EST) 561 - [x] Extract slash web command handlers/help text from chat service into dedicated module (completed 2026-02-27 10:26 EST) 562 - [x] Add regression tests for extracted slash web handler formatting and error behavior (completed 2026-02-27 10:26 EST) 563 - [x] Re-run lint/typecheck/validate and commit this service cleanup slice (completed 2026-02-27 10:26 EST) 564 - [x] Introduce shared command execution result type in src/lib/shared and migrate slash command result usage (completed 2026-02-27 10:37 EST) 565 - [x] Extract provider slash command handlers/helpers into dedicated chat module and wire service to it (completed 2026-02-27 10:37 EST) 566 - [x] Add targeted regression tests for extracted provider slash handlers and ensure shared result type usage compiles cleanly (completed 2026-02-27 10:37 EST) 567 - [x] Re-run lint/typecheck/validate and commit provider+shared-type cleanup slice (completed 2026-02-27 10:37 EST) 568 - [x] Extract model/settings/think/reasoning slash handlers into dedicated chat module and wire service wrappers (completed 2026-02-27 11:18 EST) 569 - [x] Add focused tests for extracted model/settings slash handlers (model set/help + defaults update + think/reasoning) (completed 2026-02-27 11:18 EST) 570 - [x] Re-run lint/typecheck/validate and commit the next service cleanup slice (completed 2026-02-27 11:18 EST; lint + tests + typecheck now passing locally) 571 - [x] Fix remaining local lint/type warnings from the model/settings extraction slice (completed 2026-02-27 11:18 EST) 572 - [x] Re-run sonarjs/unicorn/biome counts after fixes and record the latest remaining totals (completed 2026-02-27 11:18 EST; sonarjs=5, unicorn=0, biome=27 errors / 2 warnings / 5 infos) 573 - [x] Commit the extraction + regression-test slice once validate:fast is passing (completed 2026-02-27 11:18 EST) 574 - [x] Refactor openai-compatible local tool-loop helpers to reduce sonarjs cognitive-complexity warnings (responses + chat-completions textual fallback) (completed 2026-02-27 13:11 EST) 575 - [x] Refactor streaming SSE delta parser flow in openai-compatible provider to reduce cognitive complexity while preserving telemetry (completed 2026-02-27 13:11 EST) 576 - [x] Run lint/typecheck/tests, record updated sonarjs/unicorn/biome remaining counts, and commit next smell-reduction slice (completed 2026-02-27 13:11 EST; sonarjs=2, unicorn=0, biome=27 errors / 2 warnings / 5 infos) 577 - [x] Refactor ChatPage message bubble rendering into user/assistant focused components with shared action/image helpers to remove remaining sonarjs complexity warnings (completed 2026-02-27 13:29 EST) 578 - [x] Extract ChatPage message pane, settings layer, and sidebar sections into dedicated components to reduce top-level ChatPage cognitive complexity (completed 2026-02-27 13:29 EST) 579 - [x] Re-run lint/typecheck/validate and refresh sonarjs/unicorn/biome counts after ChatPage extraction slice (completed 2026-02-27 13:29 EST; sonarjs=0, unicorn=0, biome=26 errors / 1 warning / 5 infos) 580 - [x] Commit ChatPage complexity-reduction slice once validate:fast is passing (completed 2026-02-27 13:29 EST) 581 - [x] Extract ChatPage view components into dedicated files under src/features/chat/components/chat-page (messages pane, message bubble/text, sidebar, settings layer) (completed 2026-02-27 13:45 EST) 582 - [x] Extract ChatPage local helpers/constants/types into dedicated chat-page modules to reduce monolith file size and improve maintainability (completed 2026-02-27 13:45 EST) 583 - [x] Rewire ChatPage.tsx to consume extracted modules, then run typecheck + validate:fast + updated sonarjs/unicorn/biome counts (completed 2026-02-27 13:45 EST; typecheck+validate passed, lint warnings remain only `max-lines`: ChatPage/service/openai-compatible) 584 - [x] Refresh sonarjs/unicorn/biome counts after ChatPage file-per-component refactor slice (completed 2026-02-27 13:45 EST; eslint sonarjs=0, unicorn=0, total warnings=3 max-lines-only; biome=24 errors / 1 warning / 4 infos) 585 - [x] Commit ChatPage file-per-component refactor slice after validation passes (completed 2026-02-27 13:46 EST) 586 - [x] Add TanStack Query client/provider wiring for app routes and install required dependency (completed 2026-02-27 14:01 EST) 587 - [x] Migrate ChatPage remote reads (session settings snapshot, recent sessions, API costs) to TanStack Query with explicit invalidation/refetch after mutations (completed 2026-02-27 14:01 EST) 588 - [x] Add lightweight Zustand chat page store for conversation/composer state transitions to reduce cross-state edge cases and keep ChatPage handlers deterministic (completed 2026-02-27 14:01 EST) 589 - [x] Add/update regression tests covering query-backed refresh behavior and store-driven state transitions used by chat send/retry/reset flows (completed 2026-02-27 14:01 EST) 590 - [x] Validate Zustand + TanStack Query migration slice (typecheck + validate:fast + biome advisory) and commit (completed 2026-02-27 14:01 EST; validate:fast pass, eslint sonarjs=0 unicorn=0 warnings=3 max-lines-only, biome=24 errors / 1 warning / 4 infos) 591 - [x] Enforce provider/model invariant in settings flow so selected models always come from the selected provider catalog (completed 2026-02-27 14:08 EST) 592 - [x] Block settings save when selected provider has no configured models and surface clear actionable error text (completed 2026-02-27 14:08 EST) 593 - [x] Replace free-form provider model selectors with constrained options to prevent provider/model mismatch drift (completed 2026-02-27 14:08 EST) 594 - [x] Add regression tests for provider/model invariant helpers and rerun validate:fast + biome advisory (completed 2026-02-27 14:08 EST; `tests/chat-page-settings-invariants.test.ts` added, validate:fast pass) 595 - [x] Report latest Biome errors/warnings/infos summary and top categories after invariant changes (completed 2026-02-27 14:08 EST; biome=24 errors / 1 warning / 4 infos; top rules: exhaustive-deps 7, noLabelWithoutControl 6, useLiteralKeys 4, noArrayIndexKey 4) 596 - [x] Add DB-persisted default provider API key field and migrations (app settings schema + read/write helpers) (completed 2026-02-27 14:20 EST) 597 - [x] Update settings API/contracts and Chat settings form to save/load default provider API key from DB (env key becomes compatibility-only) (completed 2026-02-27 14:20 EST) 598 - [x] Prefer DB-stored default provider API key in effective provider resolution (fallback to env key name only for backward compatibility) (completed 2026-02-27 14:20 EST) 599 - [x] Remove hardcoded Ollama/env wording from settings UI copy/labels in favor of generic OpenAI/Router terminology while keeping legacy preset compatibility (completed 2026-02-27 14:20 EST) 600 - [x] Add/update regression tests for new default provider key persistence behavior and run typecheck + validate:fast + biome summary (completed 2026-02-27 14:20 EST; `tests/chat-page-settings-form-state.test.ts` added, validate:fast pass, biome=24 errors / 1 warning / 4 infos) 601 - [x] Add DB-backed provider profile fields (OpenAI + Router URLs/keys) with schema migration and compatibility backfill from legacy env/runtime values (completed 2026-02-27 14:38 EST) 602 - [x] Rewire settings/service/provider probe/test-model/slash-provider flows to resolve provider profiles from DB settings first (env only as one-way migration fallback) (completed 2026-02-27 14:38 EST) 603 - [x] Update chat settings UI/form payloads to edit and persist profile fields with explicit comments on legacy compatibility paths (completed 2026-02-27 14:38 EST) 604 - [x] Add regression tests for provider profile DB resolution and router slash/probe behavior (no direct Ollama env dependency) (completed 2026-02-27 14:38 EST; `tests/settings-service-provider-profiles.test.ts` added, parser + slash-provider tests updated) 605 - [x] Run typecheck + validate:fast + targeted tests, then commit with migration summary (completed 2026-02-27 14:38 EST; `typecheck` + targeted tests + `validate:fast` pass; eslint warnings remain max-lines-only, biome check currently reports 176 errors / 1 warning / 4 infos project-wide) 606 - [x] Remove all env/Ollama compatibility fallbacks from provider settings resolution and slash/probe paths; make DB settings the only source of provider credentials/URLs (completed 2026-02-27 15:11 EST) 607 - [x] Remove env-based provider target syntax/copy and update command/help/docs text to OpenAI/Router/Custom profile terminology only (completed 2026-02-27 15:11 EST) 608 - [x] Keep selected message action controls (delete/retry) persistent until another message is selected (completed 2026-02-27 15:11 EST) 609 - [x] Resolve remaining targeted lint categories: exhaustive-deps, noLabelWithoutControl, useLiteralKeys, noArrayIndexKey, useButtonType, noNoninteractiveElementToInteractiveRole, and singleton warnings (completed 2026-02-27 15:11 EST; biome lint now clean) 610 - [x] Run typecheck + validate:fast + biome advisory, then commit all changes (completed 2026-02-27 15:11 EST; validate:fast passes with existing max-lines warnings only) 611 612 - [x] Remove remaining provider dotenv/runtime fallbacks (LLM/Ollama) from server provider resolution paths (completed 2026-02-27 15:18 EST) 613 - [x] Add/update tests for provider DB-only resolution semantics (completed 2026-02-27 15:18 EST; existing suite coverage still passes for settings/service + slash provider/model flows after fallback removal) 614 - [x] Run curl smoke tests against https://localhost:3000 for settings/provider endpoints and log outcomes (completed 2026-02-27 15:18 EST; `/api/settings` POST/GET reflected DB profile values, `/api/chat-stream` `/provider current` and `/provider probe router` both resolved SQLite profile URLs/keys) 615 - [x] Run typecheck + validate:fast and commit (completed 2026-02-27 15:18 EST; typecheck + validate:fast pass, eslint warnings remain max-lines only) 616 - [x] Decouple session provider selection from global defaults by adding explicit "inherit global" vs explicit OpenAI/Router/Custom session provider semantics (completed 2026-02-27 15:32 EST) 617 - [x] Split settings modal into distinct Session, Global Defaults, and Providers tabs so per-session and cross-chat changes are not mixed (completed 2026-02-27 15:32 EST) 618 - [x] Ensure session model override pins provider context (so later global default changes do not unexpectedly mutate an overridden session) (completed 2026-02-27 15:32 EST) 619 - [x] Add regression tests for session provider preset inference/build state and model-override pinning behavior (completed 2026-02-27 15:32 EST) 620 - [x] Run targeted tests + validate:fast, then commit this settings precedence/UI split slice (completed 2026-02-27 15:32 EST; targeted vitest + `typecheck` + `validate:fast` pass, lint warnings unchanged at max-lines only) 621 - [x] Hide session model selector when Session Provider is set to Global Default, and clear session model override when switching to inherit (completed 2026-02-27 15:41 EST) 622 - [x] Fix provider tool-call regression by falling back from failed responses tool loop to chat-completions textual tool loop for non-OpenAI compatible backends (completed 2026-02-27 15:41 EST) 623 - [x] Add assistant-visible collapsed tool execution summary blocks when local tools are executed (stream and non-stream) (completed 2026-02-27 15:41 EST) 624 - [x] Add/update regression tests for responses->chat-completions tool fallback and tool execution summary rendering behavior (completed 2026-02-27 15:41 EST; updated `tests/openai-compatible-textual-tool-fallback.test.ts` + `tests/textual-tool-calls.test.ts`) 625 - [x] Run targeted tests + validate:fast and commit this tool-call regression/UI consistency slice (completed 2026-02-27 15:41 EST; `typecheck` + targeted vitest + `validate:fast` pass, plus curl smoke test for bash tool summary output) 626 - [x] Fix chat-completions tool loop to execute native `message.tool_calls` before textual-tag fallback for non-OpenAI providers (completed 2026-02-27 15:51 EST) 627 - [x] Add regression coverage for native chat-completions tool_calls execution and continuation message shape (completed 2026-02-27 15:51 EST) 628 - [x] Add visible assistant `<tool_result>` notice when local-tool mode is enabled but no tool executes in a turn (completed 2026-02-27 15:51 EST) 629 - [x] Run targeted tests + typecheck + validate:fast and commit this tool-call visibility regression slice (completed 2026-02-27 15:51 EST; targeted vitest + `typecheck` + `validate:fast` pass, lint warnings unchanged: max-lines + existing sonar complexity in `openai-compatible.ts`) 630 - [x] Remove redundant "Provider-specific default models" UI block from Global Defaults tab so there is a single default-provider/model control (completed 2026-02-27 16:04 EST) 631 - [x] Make Global Defaults form state derive/write selected model from provider-scoped defaults for the selected provider preset (completed 2026-02-27 16:04 EST) 632 - [x] Add regression test for provider-preset model hydration and run targeted tests + typecheck + validate:fast (completed 2026-02-27 16:04 EST; targeted vitest + `typecheck` + `validate:fast` pass, lint warnings unchanged at max-lines + existing sonar complexity) 633 - [x] Mask API key fields in settings modal so keys are hidden by default in Global Defaults and session/provider key inputs (completed 2026-02-27 16:07 EST) 634 - [x] Run validate:fast and commit API-key masking UI hardening (completed 2026-02-27 16:07 EST; `validate:fast` pass with existing non-blocking max-lines + sonar complexity warnings) 635 - [x] Replace single wall-clock responses tool-loop timeout with activity-aware timeout budgeting (reset on each round/response/tool execution) to prevent false aborts on multi-round local tool calls (completed 2026-02-27 16:54 EST) 636 - [x] Add stream inactivity timeout handling for responses SSE parsing (abort only on inactivity, not total stream duration) and preserve existing API-call telemetry (completed 2026-02-27 16:54 EST) 637 - [x] Add regression tests for multi-round responses tool-loop timeout behavior and streaming inactivity timeout reset behavior (completed 2026-02-27 16:54 EST) 638 - [x] Run targeted + fast validation and commit timeout robustness slice with openclaw comparison notes in commit message (completed 2026-02-27 16:54 EST) 639 - [x] Add dedicated DB-persisted local tool execution audit log (schema + storage API) decoupled from LLM transcript text (completed 2026-02-27 16:40 EST) 640 - [x] Add settings-backed retention policy (days) for tool execution logs and cleanup path (completed 2026-02-27 16:40 EST) 641 - [x] Emit tool execution audit entries from local tool execution paths (responses + chat-completions textual/native) (completed 2026-02-27 16:40 EST) 642 - [x] Expose tool execution log API and render recent per-session tool executions in chat UI for visibility/auditing (completed 2026-02-27 16:40 EST) 643 - [x] Add regression tests for tool log persistence/retention/API + run validate:fast and commit (completed 2026-02-27 16:40 EST; targeted vitest + `typecheck` + `validate:fast` + `./scripts/secrets-scan.sh` pass; lint warnings unchanged at pre-existing max-lines/sonar complexity only) 644 - [x] Port OpenClaw-inspired assistant text sanitizers (minimax XML leak stripping + downgraded tool-call text cleanup + thinking-tag cleanup) without breaking textual tool-call extraction (completed 2026-02-27 16:54 EST) 645 - [x] Replace shared wall-clock tool-loop abort timers with activity-aware timeout controllers (responses + chat-completions textual loop) (completed 2026-02-27 16:54 EST) 646 - [x] Add responses stream inactivity timeout reset-on-chunk behavior so long active streams don’t fail at fixed wall-clock timeout (completed 2026-02-27 16:54 EST) 647 - [x] Add regression tests for multi-round timeout resets and stream inactivity behavior, then run typecheck + validate:fast and commit (completed 2026-02-27 16:54 EST) 648 - [x] Port OpenClaw bash exec preflight guard (python/node script shell-bleed detection) into local bash tool execution path (completed 2026-02-27 17:01 EST) 649 - [x] Harden local bash output handling with control-character sanitization and clearer failure reasons (e.g. command not found / permission denied / timeout) (completed 2026-02-27 17:01 EST) 650 - [x] Add regression tests for bash preflight/failure behavior and run targeted + fast validation before commit (completed 2026-02-27 17:01 EST; targeted vitest + `typecheck` + `validate:fast` + `./scripts/secrets-scan.sh` pass) 651 - [x] Extract bash tool runtime/preflight/render logic from provider monolith into `src/server/tools/bash.ts` and consume via provider adapter calls (completed 2026-02-27 17:06 EST) 652 - [x] Keep provider-facing bash tool schema/behavior parity after extraction (including timeout bounds + preflight guard + failure reason rendering) (completed 2026-02-27 17:06 EST) 653 - [x] Run targeted bash/provider tests + typecheck + validate:fast + secrets scan, then commit extraction slice (completed 2026-02-27 17:06 EST; targeted vitest + `typecheck` + `validate:fast` + `./scripts/secrets-scan.sh` pass) 654 - [x] Add failed-stream tool-feedback path so local tool executions in the same turn are surfaced in-chat before emitting stream error (completed 2026-02-27 17:16 EST) 655 - [x] Refresh per-session tool execution logs on streamed-turn failures so sidebar visibility is immediate (completed 2026-02-27 17:16 EST) 656 - [x] Add regression tests for timeout-after-tool-execution stream failure path and run validate+typecheck before commit (completed 2026-02-27 17:16 EST) 657 - [x] Add stream run identifiers and typed provider stream chunks so tool lifecycle events can be emitted alongside text deltas (completed 2026-02-27 17:43 EST) 658 - [x] Emit live tool lifecycle stream events from responses/chat-completions local tool loops and wire them through chat service SSE (completed 2026-02-27 17:43 EST) 659 - [x] Improve local tool-loop timeout activity handling so progress-driven loops reset safely without premature aborts (completed 2026-02-27 17:43 EST) 660 - [x] Add in-chat live tool timeline UI for the active turn (per run) and keep existing tool audit sidebar behavior (completed 2026-02-27 17:43 EST) 661 - [x] Add regression tests for provider stream tool lifecycle events + runId propagation + timeout progress behavior and run validate/typecheck/tests before commit (completed 2026-02-27 17:43 EST; targeted + full validate/typecheck + secrets scan pass) 662 - [x] Apply optional-chain lint cleanup in live tool timeline helper after pre-commit advisory (completed 2026-02-27 17:45 EST) 663 - [x] Add copy-markdown message action beside retry/delete in chat message bubbles (completed 2026-02-27 18:05 EST) 664 - [x] Add clipboard helper with fallback behavior and focused regression test coverage (completed 2026-02-27 18:05 EST) 665 - [x] Run typecheck + validate:fast + targeted tests and commit copy-markdown UI slice (completed 2026-02-27 18:05 EST; `typecheck` + targeted vitest + `validate:fast` + `./scripts/secrets-scan.sh` pass, lint warnings unchanged at pre-existing max-lines/sonar complexity only) 666 - [x] Replace non-streamed chat-completions fallback paths with true streamed deltas (no synthetic post-hoc chunking) so frontend receives text as server receives it (completed 2026-02-28 09:24 EST) 667 - [x] Emit provider thinking stream chunks (responses/chat-completions compatible parsing) and surface them in a live in-bubble timeline panel styled like tool activity (completed 2026-02-28 09:24 EST) 668 - [x] Add per-message stream metrics in UI: first output token time (labelled latency) and total duration to completion (completed 2026-02-28 09:24 EST) 669 - [x] Add regression tests for streamed chat-completions delta flow, thinking chunk propagation, and message metrics mapping (pending->final id) (completed 2026-02-28 09:24 EST) 670 - [x] Run targeted tests + typecheck + validate:fast + secrets scan and commit stream/thinking/metrics hardening slice (completed 2026-02-28 09:24 EST; `npm rebuild better-sqlite3` run once to resolve local Node ABI mismatch before `validate:fast`; validate now passes with existing non-blocking max-lines/sonar complexity warnings only) 671 - [x] Enforce `mise` toolchain usage unconditionally in `.githooks/pre-commit` (including Biome + secrets scan steps) (completed 2026-02-28 09:29 EST) 672 - [x] Add project-level automatic `mise` shell activation for local terminals (direnv `.envrc`) (completed 2026-02-28 09:29 EST) 673 - [x] Validate hook behavior and commit toolchain consistency hardening (completed 2026-02-28 09:29 EST; `.githooks/pre-commit` executed successfully end-to-end under `mise`) 674 - [x] Remove brittle 4-round local tool-loop cap behavior so turns can execute many tool calls without forced fallback (completed 2026-02-28 09:46 EST) 675 - [x] Tighten local-tool fallback classification to only degrade on compatibility/unsupported errors (not safety-cap exhaustion) (completed 2026-02-28 09:46 EST) 676 - [x] Start message latency metric on first stream activity event (thinking/tool/delta) so UI populates early (completed 2026-02-28 09:46 EST) 677 - [x] Add regression tests for >4 tool-loop rounds and early stream-activity latency behavior (completed 2026-02-28 09:46 EST) 678 - [x] Validate fixes with `mise exec -- npm run validate:fast` and targeted smoke/session checks (completed 2026-02-28 09:46 EST; targeted vitest for new regressions + full `validate:fast` pass, existing non-blocking max-lines/sonar warnings unchanged) 679 - [x] Harden provider thinking/reasoning extraction using OpenClaw-style tag-aware parsing for non-stream tool-loop rounds (completed 2026-02-28 10:02 EST) 680 - [x] Ensure local tool-loop streaming emits incremental assistant text previews before final completion (completed 2026-02-28 10:02 EST) 681 - [x] Persist per-session thinking timeline + stream latency/duration metrics across HMR reload and session switching (completed 2026-02-28 10:02 EST) 682 - [x] Add regression tests for preview-text streaming order and observability persistence filtering/reload (completed 2026-02-28 10:02 EST) 683 - [x] Run targeted tests + `mise exec -- npm run validate:fast` and commit this robustness slice (completed 2026-02-28 10:02 EST; targeted vitest + full `validate:fast` passed, existing non-blocking max-lines/sonar warnings unchanged) 684 - [x] Prevent duplicate reasoning text from rendering in both assistant body and LIVE THINKING by adjusting local tool-loop round emission routing (session b968b020-2558-4286-83f4-dabec36448f1 regression) (completed 2026-02-28 10:18 EST) 685 - [x] Add regression tests for non-stream tool-loop rounds where reasoning text overlaps assistant preview text to ensure only thinking panel receives duplicated reasoning snippets (completed 2026-02-28 10:18 EST) 686 - [x] Run targeted tests + `mise exec -- npm run validate:fast` and commit the thinking/assistant de-duplication fix (completed 2026-02-28 10:18 EST; targeted + full validate pass with existing non-blocking lint warnings unchanged) 687 - [x] Phase 0: Normalize local toolchain (`mise install` as needed) and rebuild `better-sqlite3` ABI for current Node (completed 2026-02-28 11:10 EST) 688 - [x] Phase 0: Re-capture baseline (`npm run lint`, targeted tests, `npm run validate:fast`) before refactor (completed 2026-02-28 11:10 EST) 689 - [x] Phase 1: Split `src/server/providers/openai-compatible.ts` into responsibility modules with a compatibility facade (completed 2026-02-28 11:26 EST) 690 - [x] Phase 1: Verify provider split via openai-compatible/textual-tool/stream runId tests (completed 2026-02-28 11:26 EST) 691 - [x] Phase 2: Split `src/server/chat/service.ts` into flow modules with a compatibility facade (completed 2026-02-28 11:26 EST) 692 - [x] Phase 2: Verify chat service split via stream + slash-handler + tool-execution-log tests (completed 2026-02-28 11:26 EST) 693 - [x] Phase 3: Split `src/server/chat/slash-command-parser.ts` by command families with compatibility facade exports (completed 2026-02-28 11:26 EST) 694 - [x] Phase 3: Verify slash parser split via full slash parser tests (completed 2026-02-28 11:26 EST) 695 - [x] Phase 4: Extract pure settings resolution/catalog modules; keep `src/server/settings/service.ts` as side-effect facade (completed 2026-02-28 11:26 EST) 696 - [x] Phase 4: Verify settings split via settings-service + slash-handler tests (completed 2026-02-28 11:26 EST) 697 - [x] Phase 5: Split `src/server/tools/web-search.ts` by provider implementations with compatibility facade (completed 2026-02-28 11:26 EST) 698 - [x] Phase 5: Verify web-search split via web-search + web-tool-execution + web slash-handler tests (completed 2026-02-28 11:26 EST) 699 - [x] Phase 6: Adapterize `src/server/agents/session-bridge.ts` backends and preserve parser exports (completed 2026-02-28 11:26 EST) 700 - [x] Phase 6: Verify agent bridge split via cli-agent parser + slash parser tests (completed 2026-02-28 11:26 EST) 701 - [x] Phase 7: Extract `ChatPage` controllers/hooks and keep `src/features/chat/ChatPage.tsx` declarative (completed 2026-02-28 11:26 EST) 702 - [x] Phase 7: Verify ChatPage split via `chat-page-*` tests and typecheck (completed 2026-02-28 11:26 EST) 703 - [x] Phase 8: Split `message-bubble` subcomponents with facade export (completed 2026-02-28 11:26 EST) 704 - [x] Phase 8: Verify message-bubble split via message-bubble + messages-pane tests (completed 2026-02-28 11:26 EST) 705 - [x] Phase 9: Run final hardening checks (`npm run typecheck`, `npm run lint`, `npm run test`, `npm run validate:fast`, `./scripts/secrets-scan.sh`) (completed 2026-02-28 11:27 EST) 706 - [x] Phase 9: Mark all completed phase checklist items with completion timestamps (completed 2026-02-28 11:27 EST) 707 - [x] Add a pre-Phase-1 golden-trace streamed-turn test asserting event ordering and tool lifecycle invariants (completed 2026-02-28 11:12 EST) 708 - [x] Validate the golden-trace test passes before Phase 1 refactor work (completed 2026-02-28 11:12 EST) 709 - [ ] Phase 10: Further decompose OpenAI-compatible provider into transport/payload/stream/tools/capabilities split points and reduce facade size 710 - [ ] Phase 10: Split provider probe by purpose (endpoint-detect/capabilities/normalize-url/types) with compatibility exports 711 - [ ] Phase 10: Further decompose chat service internals into provider-dispatch/message-shaping/event-apply/errors/guards split points 712 - [ ] Phase 10: Further decompose slash-command parser internals into lexer/ast/parse/format-help/dispatch split points 713 - [ ] Phase 10: Split slash command handler modules by family/provider operation split points 714 - [ ] Phase 10: Decompose web-search/web-fetch/bash into adapter-oriented module structure while preserving APIs 715 - [ ] Phase 10: Decompose storage modules (`chat-store`, `app-settings`, `db`) into entity/read-write split points with compatibility facades 716 - [ ] Phase 10: Run hardening checks after extraction wave and timestamp completion entries 717 - [x] Phase 10b: Wire `src/server/settings/service.ts` into `settings/resolve.ts`, `settings/persist.ts`, `settings/probe.ts`, and `settings/validation.ts` with stable exports (completed 2026-02-28 12:21 EST) 718 - [x] Phase 10b: Extract agents backend registry/router and move Codex/OpenCode adapters + shared process/parse helpers while preserving session-bridge compatibility exports (completed 2026-02-28 12:21 EST) 719 - [x] Phase 10b: Decompose chat page internal controllers into hook modules (`use-send-message`, `use-chat-stream`, `use-chat-uploads`, `use-chat-hotkeys`, `use-chat-session`) and `chat-page/layout.tsx` (completed 2026-02-28 12:21 EST) 720 - [x] Phase 10b: Decompose message bubble internals into shell/header/tool-events/format modules with `internal.tsx` as glue (completed 2026-02-28 12:21 EST) 721 - [x] Phase 10b: Split chat settings layer into panel modules (`SettingsLayer`, `ProviderPanel`, `DefaultsPanel`, `ModelPickerPanel`, `forms`) (completed 2026-02-28 12:21 EST) 722 - [x] Phase 10b: Split `src/features/chat/api.ts` into grouped endpoint modules (`messages`, `sessions`, `providers`, `settings`) behind stable facade exports (completed 2026-02-28 12:21 EST) 723 - [x] Phase 10b: Run typecheck + targeted tests + validate:fast + secrets scan and timestamp completion entries (completed 2026-02-28 12:21 EST; `npm run typecheck` pass; targeted vitest suites pass; `npm run validate:fast` pass with pre-existing warning-only lint findings; `./scripts/secrets-scan.sh` pass) 724 - [x] Phase 10c: Split `src/server/providers/probe.ts` into `providers/probe/{endpoint-detect,capabilities,normalize-url,types}.ts` with stable probe exports (completed 2026-02-28 12:38 EST) 725 - [x] Phase 10c: Further decompose `src/server/providers/openai-compatible.ts` into `transport`, endpoint payload builders, stream decode/normalization, tool parse/repair, and capability rules while preserving facade exports/behavior (completed 2026-02-28 12:38 EST) 726 - [x] Phase 10c: Run provider-focused tests (`openai-compatible*`, textual-tool-calls, golden trace, stream runId tool events) plus typecheck + validate:fast + secrets scan (completed 2026-02-28 12:38 EST; `npm run typecheck` pass; targeted + `validate:fast` test suites pass after rebuilding `better-sqlite3`; `./scripts/secrets-scan.sh` pass) 727 - [x] Phase 10c: Commit provider/probe decomposition slice and timestamp checklist completion (completed 2026-02-28 12:38 EST) 728 - [ ] Phase 10d: Split `src/server/chat/service/internal.ts` into `service/{provider-dispatch,message-shaping,event-apply,errors,guards}.ts` with internal imports only 729 - [x] Phase 10d: Split `src/server/chat/slash-command-parser/internal.ts` into parser pipeline modules (`lexer`, `ast`, `parse`, `format-help`, `dispatch`) behind stable parser exports (completed 2026-02-28 12:47 EST) 730 - [x] Phase 10d: Split slash handler internals for settings/model/defaults/flags and provider operations (create/update/delete/probe) while preserving current public handler exports (completed 2026-02-28 12:44 EST) 731 - [x] Phase 10d: Run targeted chat/slash/provider tests plus `npm run typecheck` and `npm run validate:fast` (completed 2026-02-28 12:44 EST; `npm run typecheck` pass; targeted slash/chat stream tests pass under `mise exec`; `mise exec -- npm run validate:fast` pass with existing warning-only lint findings) 732 - [x] Phase 10d: Run `./scripts/secrets-scan.sh`, commit decomposition slice, and timestamp completion entries (completed 2026-02-28 12:47 EST; secrets scan passed and decomposition slices committed as `ee9a580` + `e2ccd10`) 733 - [x] Phase 10e: Split `src/server/chat/service/internal.ts` glue/policy into `service/{provider-dispatch,message-shaping,event-apply,errors,guards}.ts` while preserving service exports and stream event behavior (completed 2026-02-28 12:52 EST) 734 - [x] Phase 10e: Run targeted chat-service + golden-trace + slash-handler tests, then `npm run typecheck` and `mise exec -- npm run validate:fast` (completed 2026-02-28 12:52 EST; targeted chat/slash suites pass, `npm run typecheck` pass, `mise exec -- npm run validate:fast` pass with pre-existing warning-only lint findings) 735 - [x] Phase 10e: Run `./scripts/secrets-scan.sh`, commit service decomposition slice, and timestamp completion entries (completed 2026-02-28 12:52 EST; secrets scan passed and service decomposition committed as `b167078`) 736 - [x] Phase 10f: Split `src/server/tools/web-fetch.ts` into `web-fetch/{fetch,safety,extract}.ts` behind stable `web-fetch.ts` exports (completed 2026-02-28 12:56 EST) 737 - [x] Phase 10f: Split `src/server/tools/bash.ts` into `bash/{execute,limits,render}.ts` behind stable `bash.ts` exports (completed 2026-02-28 12:56 EST) 738 - [x] Phase 10f: Run targeted web-fetch/bash/provider tests + `npm run typecheck` + `mise exec -- npm run validate:fast`, then commit with secrets scan (completed 2026-02-28 12:56 EST; targeted tool suites + `npm run typecheck` + `mise exec -- npm run validate:fast` pass, secrets scan pass, committed as `3c4b26a`) 739 - [x] Phase 10g: Split `src/server/storage/app-settings.ts` into `storage/settings/{read,write,merge,validate}.ts` with facade exports preserved (completed 2026-02-28 12:59 EST) 740 - [x] Phase 10g: Run targeted settings/slash/storage-facing tests plus `npm run typecheck` after app-settings split (completed 2026-02-28 12:59 EST; typecheck pass; targeted settings/slash/web tool tests pass under `mise exec`) 741 - [x] Phase 10g: Run `mise exec -- npm run validate:fast` + `./scripts/secrets-scan.sh`, commit app-settings decomposition slice, and timestamp completion entry (completed 2026-02-28 12:59 EST; validate and secrets scan pass) 742 - [x] Phase 10h: Split `src/server/storage/db.ts` into `db/{client,migrate,tx}.ts` while preserving `getDb`, `getStoragePaths`, and `getSqliteVecStatus` exports (completed 2026-02-28 13:02 EST) 743 - [x] Phase 10h: Run targeted storage/chat tests + `npm run typecheck` + `mise exec -- npm run validate:fast` and secrets scan (completed 2026-02-28 13:02 EST; typecheck pass, targeted storage/chat tests pass, validate+secrets scan pass) 744 - [x] Phase 10h: Commit DB decomposition slice and timestamp completion entries (completed 2026-02-28 13:02 EST; committed as `cde8ba7`) 745 - [x] Phase 10i: Reorganize `openai-compatible` module layout for transport/policy/stream/tools/tool-loop subpaths with compatibility facades (completed 2026-02-28 13:21 EST) 746 - [x] Phase 10i: Keep `openai-compatible.ts` behavior stable while rewiring imports to new module paths (no API changes) (completed 2026-02-28 13:21 EST) 747 - [x] Phase 10i: Run provider/chat streaming + textual tool fallback tests, `npm run typecheck`, `mise exec -- npm run validate:fast`, and secrets scan (completed 2026-02-28 13:21 EST; targeted provider/golden-trace suites pass, `npm run typecheck` pass, `mise exec -- npm run validate:fast` pass with existing warning-only lint findings, `./scripts/secrets-scan.sh` pass) 748 - [x] Phase 10i: Commit `openai-compatible` layout/decomposition slice and timestamp completion entries (completed 2026-02-28 13:24 EST; committed as `6193c09`) 749 - [ ] Phase 10j: Split `src/server/chat/service/internal.ts` entrypoints, slash routing, memory flow, and CLI agent glue into `service/*` modules with internal parity 750 - [x] Phase 10j: Extract CLI agent command handlers from `service/internal.ts` into `service/cli/{backends,sessions,send,format}.ts` and add explicit entrypoint modules (`get-or-create-snapshot`, `handle-chat-message`, `delete-message`, `retry-message`) (completed 2026-02-28 13:34 EST) 751 - [x] Phase 10j: Extract slash command routing/handler wiring from `service/internal.ts` into `service/slash/route.ts` with stable slash behavior and pending-web command execution parity (completed 2026-02-28 13:39 EST) 752 - [x] Phase 10j: Convert `src/server/tools/web-search/index.ts` into dispatch/cache/normalize + provider adapters while preserving `performWebSearch`/`resolveSearchProvider` API (completed 2026-02-28 13:29 EST; committed as `5349cd9`) 753 - [ ] Phase 10j: Split `src/server/storage/chat-store.ts` by entity modules (`sessions`, `messages`, `memories`, `memory-embeddings`, `uploads`, `queries`, `serialize`) behind stable facade exports 754 - [ ] Phase 10j: Split agent backends (`codex`, `opencode`) into `client`/`parse`/`normalize` plus shared `agents/process/*` helpers without changing routing API 755 - [ ] Phase 10j: Split settings persistence and API surfaces (`settings/persist/*`, `api/providers/test-model/*`, `api/settings/*`) with behavior-preserving facades 756 - [ ] Phase 10j: Split heavy remaining chat UI modules (`chat-page/internal.tsx`, `MessageBubbleShell.tsx`, `ProviderDetail.tsx`, `chat-sidebar.tsx`, `SettingsLayer.tsx`) into controller/render/persist panels 757 - [ ] Phase 10j: Run targeted suites + `npm run typecheck` + `mise exec -- npm run validate:fast` + `./scripts/secrets-scan.sh` after each safe slice 758 - [ ] Phase 10j: Commit each extraction slice with timestamped WORKINGLOG completion updates 759 - [x] Phase 10k: Split `src/server/providers/openai-compatible.ts` by route/tool responsibilities into `chat-completions/*`, `responses/*`, `tools/local/*`, and shared helpers (`tool-loop/request-summary`, `transport/activity-timeout`, `prompt-cache`) (completed 2026-02-28 14:00 EST) 760 - [x] Phase 10k: Keep `openai-compatible.ts` as provider facade/wiring and preserve behavior parity while migrating function bodies (completed 2026-02-28 14:00 EST; file reduced from ~3018 lines to ~611 lines with route/tool delegation) 761 - [x] Phase 10k: Run provider-focused and golden-trace regressions + `npm run typecheck` + `mise exec -- npm run validate:fast` + secrets scan (completed 2026-02-28 14:00 EST; targeted provider/golden-trace suites pass, `npm run -s typecheck` pass, `mise exec -- npm run -s validate:fast` pass with warning-only lint findings, secrets scan pass) 762 - [x] Phase 10k: Commit the openai-compatible deep decomposition slice with timestamped checklist updates (completed 2026-02-28 14:01 EST; committed as `a4b06d0`) 763 - [x] Phase 10l: Split `src/server/chat/slash-command-parser/dispatch.ts` into family modules (`agents`, `provider`, `model`, `thinking`, `reasoning`, `settings`, `settings-builders`, `web`) with tiny dispatch (completed 2026-02-28 14:42 EST) 764 - [x] Phase 10l: Split `src/server/storage/chat-store.ts` into `storage/chat/*` entity modules with `chat-store.ts` facade exports (completed 2026-02-28 14:42 EST) 765 - [x] Phase 10l: Split `src/server/agents/backends/codex.ts` into `agents/backends/codex/*` (config/run/sessions/fs/parse/send) with stable top-level exports (completed 2026-02-28 14:42 EST) 766 - [x] Phase 10l: Split `src/server/chat/service/internal.ts` entrypoint functions into dedicated modules and keep `internal.ts` as glue/re-exports (completed 2026-02-28 14:42 EST) 767 - [x] Phase 10l: Split `src/features/chat/chat-page/internal.tsx` functions into `chat-page/{stream-apply,stream-timing,settings-modal,message-actions,send}.ts` (completed 2026-02-28 14:42 EST) 768 - [x] Phase 10l: Split `src/features/chat/components/chat-page/message-bubble/MessageBubbleShell.tsx` into `parse/*`, `render/*`, and `selection.ts` (completed 2026-02-28 14:42 EST) 769 - [x] Phase 10l: Run targeted tests + `npm run typecheck` + `mise exec -- npm run validate:fast` + `./scripts/secrets-scan.sh` and commit extraction slices with timestamps (completed 2026-02-28 14:42 EST; `npm run -s typecheck` pass; targeted vitest bundles pass; `mise exec -- npm run -s validate:fast` pass with existing warning-only cognitive-complexity findings; secrets scan pass) 770 - [x] Phase 10m: Split `src/features/chat/components/ProviderDetail.tsx` into shell/panels/actions modules while preserving `ProviderDetail` export (completed 2026-02-28 14:58 EST) 771 - [x] Phase 10m: Split `src/features/chat/components/chat-page/chat-sidebar.tsx` into sidebar cards/format modules with stable `ChatSidebar` export (completed 2026-02-28 14:58 EST) 772 - [x] Phase 10m: Split `src/features/chat/components/chat-page/chat-settings/SettingsLayer.tsx` into shell/state/session-panel modules behind existing exports (completed 2026-02-28 14:58 EST) 773 - [x] Phase 10m: Split `src/lib/shared/chat.ts` into `lib/shared/chat/*` modules with `chat.ts` facade re-exports (completed 2026-02-28 14:58 EST) 774 - [x] Phase 10m: Split `src/server/agents/backends/opencode.ts` into `agents/backends/opencode/*` modules with stable adapter/API exports (completed 2026-02-28 14:58 EST) 775 - [x] Phase 10m: Split API route internals for `src/routes/api/providers/test-model.ts` and `src/routes/api/settings.ts` into `validate`/`run`/`format` helper modules (completed 2026-02-28 14:58 EST) 776 - [x] Phase 10m: Run `npm run -s typecheck`, targeted tests, `mise exec -- npm run -s validate:fast`, `./scripts/secrets-scan.sh`, then commit with timestamps (completed 2026-02-28 14:58 EST; `npm run -s typecheck` pass, targeted vitest suites pass, `mise exec -- npm run -s validate:fast` pass with existing warning-only lint findings, secrets scan pass) 777 - [x] Phase 10n: Reduce `sonarjs/cognitive-complexity` warnings in settings modal and settings layer shell via helper extraction (behavior-preserving) (completed 2026-02-28 15:15 EST) 778 - [x] Phase 10n: Reduce `sonarjs/cognitive-complexity` warnings in OpenAI-compatible provider facade and streaming/tool parse/render helpers (behavior-preserving) (completed 2026-02-28 15:15 EST) 779 - [x] Phase 10n: Run `npm run -s lint`, `npm run -s typecheck`, `mise exec -- npm run -s validate:fast`, and `./scripts/secrets-scan.sh`, then commit with timestamps (completed 2026-02-28 15:15 EST; lint/typecheck pass with zero warnings, `mise exec -- npm run -s validate:fast` pass, secrets scan pass) 780 - [x] Phase 10o: Fix provider/settings UX regressions for OpenAI-only setups (save key/base URL first, keep model picker functional with probed models, hide unavailable Router/Custom entries) (completed 2026-02-28 16:00 EST) 781 - [x] Phase 10o: Wire provider-editor changes into persisted settings payload (including provider model lists) and support capability probing against `/responses` endpoints (completed 2026-02-28 16:00 EST) 782 - [x] Phase 10o: Run targeted settings/provider tests + `npm run -s typecheck` + `npm run -s lint` + `mise exec -- npm run -s validate:fast`, then commit with timestamps (completed 2026-02-28 16:00 EST; targeted tests + typecheck + lint + validate:fast passed, secrets scan passed) 783 - [x] Phase 10p: Import production Dockerfile from monolith (`~/git/helper/Dockerfile`) into repo root for shared/containerized usage (completed 2026-02-28 16:06 EST) 784 - [x] Phase 10p: Validate Dockerfile presence in repo and commit with WORKINGLOG timestamp (completed 2026-02-28 16:06 EST) 785 - [x] Phase 10q: Fix provider model-capability probe regressions for DB-only setup (OpenAI `/responses` default path handling + valid probe payload token limits) while preserving no-env-fallback policy (completed 2026-02-28 16:24 EST) 786 - [x] Phase 10q: Add targeted regression tests for probe endpoint/path selection and capability probe payload behavior, then run focused tests + typecheck/lint (completed 2026-02-28 16:24 EST; added `tests/test-model-validate.test.ts` + `tests/test-model-run.test.ts`, targeted tests pass, `npm run -s typecheck` pass, `npm run -s lint` pass) 787 - [x] Phase 10q: Run `mise exec -- npm run -s validate:fast` and `./scripts/secrets-scan.sh`, then commit with timestamped WORKINGLOG completion updates (completed 2026-02-28 16:24 EST; validate:fast + secrets scan passed) 788 - [x] Phase 10r: Sync current `main` to `ws@monolith:~/git/helper` and verify remote HEAD includes latest local fix commit (completed 2026-02-28 16:31 EST; synced source via rsync, remote HEAD remains `675e5d7` with synced working-tree changes) 789 - [x] Phase 10r: Run remote Docker image build (`docker build -t helper:latest .`) in `~/git/helper` and capture result (completed 2026-02-28 16:31 EST; build succeeded, image `helper:latest` sha256 `19a48ffa0603a0752f59ab24c500d6c996ad5c8bc25b05eab9395e6fe2030e61`) 790 - [x] Phase 10r: Add an ignored local helper script to automate sync + remote build for future runs (completed 2026-02-28 16:31 EST; created executable `.exports/sync-monolith-build.sh`, validated with `--dry-run`) 791 - [x] Phase 10s: Fix tool-capability probe false negatives by making responses probe deterministic (forced function call + sufficient output token budget) (completed 2026-02-28 16:35 EST) 792 - [x] Phase 10s: Add regression assertions for tool probe request payload shape and token budget in `tests/test-model-run.test.ts` (completed 2026-02-28 16:35 EST; added deterministic payload assertions + unsupported-`tool_choice` retry regression) 793 - [x] Phase 10s: Run targeted probe tests plus typecheck/lint, then `mise exec -- npm run -s validate:fast` and secrets scan (completed 2026-02-28 16:35 EST; targeted probe tests pass, `npm run -s typecheck` pass, `npm run -s lint` pass, `mise exec -- npm run -s validate:fast` pass, secrets scan pass) 794 - [x] Add Playwright-backed `browser_fetch` server tool module with readable-content extraction aligned to existing web-fetch output shape (completed 2026-02-28 17:12 EST) 795 - [x] Wire automatic browser fallback into `web_fetch` for blocked/JS-heavy pages while preserving existing HTTP-first behavior (completed 2026-02-28 17:12 EST) 796 - [x] Integrate `browser_fetch` into local tool registry/execution/rendering and tool guidance so models can call it directly (completed 2026-02-28 17:12 EST) 797 - [x] Add/adjust unit tests for web tool execution and web-fetch fallback heuristics; run targeted tests + typecheck/lint (completed 2026-02-28 17:12 EST; targeted vitest + typecheck + lint + `mise exec -- npm run -s validate:fast` passed) 798 - [x] Phase 10t: Fix custom provider persistence mapping so added/imported providers normalize to the persisted `custom` profile slot instead of disappearing after save/rehydrate (completed 2026-02-28 17:07 EST) 799 - [x] Phase 10t: Add regression tests for custom-provider normalization/merge behavior in chat settings UI state + provider catalog merge helpers (completed 2026-02-28 17:07 EST; added `tests/chat-page-provider-state.test.ts` and expanded `tests/chat-page-settings-invariants.test.ts`) 800 - [x] Phase 10t: Run targeted tests + typecheck/lint + validate:fast + secrets scan (completed 2026-02-28 17:07 EST; targeted tests pass, `npm run -s typecheck` pass, `npm run -s lint` pass, `mise exec -- npm run -s validate:fast` pass, secrets scan pass) 801 - [ ] Phase 10t: Sync updated custom-provider persistence fix to monolith and rebuild container image 802 - [x] Add Cloudflare Markdown-for-Agents style handling to `web_fetch` (request `text/markdown` and treat markdown responses as first-class content) (completed 2026-02-28 17:20 EST) 803 - [x] Add regression tests for markdown-content web fetch behavior and header negotiation (completed 2026-02-28 17:20 EST) 804 - [x] Run targeted tests + typecheck + lint and timestamp completion entries (completed 2026-02-28 17:20 EST; `tests/web-fetch-fallback.test.ts` + `tests/web-tool-execution.test.ts` pass, `npm run -s typecheck` pass, `npm run -s lint` pass) 805 - [x] Make Playwright-based browser fetch bundle-safe for Vite/esbuild by avoiding static Playwright imports in server code (completed 2026-02-28 17:33 EST) 806 - [x] Verify Docker-related build path with `npm run -s build` and ensure no `chromium-bidi` resolution error remains (completed 2026-02-28 17:33 EST) 807 - [x] Re-run focused web-fetch tests + lint/typecheck after loader change (completed 2026-02-28 17:33 EST; targeted tests pass, lint/typecheck pass) 808 - [x] Update Dockerfile to provision Playwright Chromium in-image so browser fallback can launch in container runtime (completed 2026-02-28 17:43 EST) 809 - [x] Sync/build/redeploy on `monolith` via `./.exports/sync-monolith-build.sh` and verify Playwright launch inside running `helper-helper-1` (completed 2026-02-28 17:43 EST; remote image rebuilt and compose restarted successfully) 810 - [x] Confirm browser-fallback path no longer silently fails due to missing browser binary and timestamp completion (completed 2026-02-28 17:43 EST; `chromium.launch()` is `launch-ok` in container and tool log now records `fetchMethod:\"browser\"` with `fallbackReason:\"primary HTTP fetch failed\"` for `https://en.mehrnews.com/`) 811 - [x] Harden web/html extraction to avoid CSS-heavy payload output (detect stylesheet-like extraction and switch to fallback extraction path) (completed 2026-02-28 18:09 EST) 812 - [x] Improve script/style stripping robustness in `web-fetch` extraction helpers to reduce leaked CSS in markdown/text conversion (completed 2026-02-28 18:09 EST) 813 - [x] Add regression tests for CSS-heavy extraction behavior (including Google News-like output shape) and run targeted validation (completed 2026-02-28 18:09 EST) 814 - [x] Verify on `monolith` with real `/webfetch https://news.google.com/search?...` call after rebuild (completed 2026-02-28 18:16 EST; returns clear guidance to use `browser_fetch` for stylesheet-like payloads) 815 - [x] Harden `browser_fetch` main-content extraction to reduce navigation/boilerplate junk (Google News-like pages) (completed 2026-02-28 18:09 EST) 816 - [x] Add regression tests for browser-fetch markdown cleanup and link-cloud/nav pruning (completed 2026-02-28 18:09 EST) 817 - [x] Run targeted test suites + typecheck/lint, then sync/rebuild on `monolith` and verify `browser_fetch` output quality (completed 2026-02-28 18:16 EST; monolith rebuild successful, direct in-container `performBrowserFetch` shows cleaned result vs `preserveLinks` richer output) 818 - [x] Add `browser_fetch.preserveLinks` argument so link-heavy output can be requested explicitly (completed 2026-02-28 18:09 EST) 819 - [x] Fix Minimax thinking duplication where identical reasoning text appears in both LIVE THINKING and assistant response (completed 2026-02-28 18:27 EST) 820 - [x] Add regression tests for stream and local tool-loop thinking/delta dedupe behavior (completed 2026-02-28 18:27 EST) 821 - [x] Run targeted provider tests + typecheck/lint and commit the thinking dedupe fix (completed 2026-02-28 18:27 EST; targeted streaming/textual fallback suites, `npm run -s typecheck`, and `npm run -s lint` passed) 822 - [x] Phase 10u: Persist custom provider label in settings storage/catalog so user-defined provider names (e.g., Ollama) survive save + snapshot rehydrate (completed 2026-02-28 19:12 EST; added `custom_provider_label` migration + read/write wiring, propagated defaults payload parsing, and catalog label now reflects persisted custom label) 823 - [x] Phase 10u: Align session custom-provider base URL behavior with saved provider defaults (auto-fill/fallback) to eliminate false "base URL required" errors and status-bar drift (completed 2026-02-28 19:12 EST; session custom selection now resolves base URL from explicit/session->catalog->defaults, backend custom session override falls back to saved custom base URL/API key, and duplicate footer error rendering path was removed for settings saves) 824 - [x] Phase 10u: Add regression tests for custom provider name persistence and session/base-URL consistency between settings modal and chat status bar, then run targeted tests + typecheck/lint (completed 2026-02-28 19:12 EST; expanded `chat-page-settings-invariants` + `settings-service-provider-profiles` and added `chat-page-settings-modal` payload regression; `npm run -s typecheck`, targeted vitest suites, and `npm run -s lint` pass) 825 - [x] Phase 10u: Run `mise exec -- npm run -s validate:fast` + `./scripts/secrets-scan.sh`, then commit with timestamped WORKINGLOG completion updates (completed 2026-02-28 19:12 EST; validate:fast and secrets scan passed) 826 - [x] Phase 10v: Fix live-thinking chunk concatenation to preserve readable spacing between streamed reasoning tokens (completed 2026-02-28 19:22 EST; stopped trimming stream chunks and added boundary-aware chunk join logic for word-like token edges) 827 - [x] Phase 10v: Add wrap safeguards for live-thinking text blocks so long unbroken sequences do not overflow the viewport (completed 2026-02-28 19:22 EST; added `break-words` to thinking panel text rendering) 828 - [x] Phase 10v: Update thinking timeline regression tests and run targeted test + lint/typecheck checks (completed 2026-02-28 19:22 EST; expanded `tests/chat-page-thinking-timeline.test.ts`, plus targeted timeline/settings-modal tests and full lint/typecheck pass) 829 - [x] Phase 10v: Commit live-thinking readability fix with timestamped WORKINGLOG completion updates (completed 2026-02-28 19:22 EST) 830 - [x] Phase 10w: Prevent custom provider overwrite by using stable unique custom provider IDs in UI state and selecting an explicit active custom provider for merge/persist behavior (completed 2026-03-01 09:31 EST; custom provider creation/import now preserves unique IDs, providers are no longer canonicalized to a single `custom` id, and catalog/form merge paths use the selected custom provider when present) 831 - [x] Phase 10w: Fix model-picker/provider binding regressions (no auto-first-model on provider switch, preserve explicit model values during transient catalog churn) (completed 2026-03-01 09:31 EST; provider buttons now switch with unset model, defaults tab preserves provider-scoped bound model on provider switch, normalization no longer clears mismatched explicit models, and unavailable explicit selections remain visible in the picker) 832 - [x] Phase 10w: Remove generic default-model fallback leakage from session/runtime resolution so model selection stays provider-scoped (completed 2026-03-01 09:31 EST; removed provider runtime/session fallback to `defaults.chatModel`, settings form now hydrates `defaultsChatModel` from provider-scoped defaults only, and settings save writes provider-scoped defaults without mirroring to generic fallback field) 833 - [x] Phase 10w: Add/adjust regression tests for provider identity + model-binding behavior, run targeted tests + lint/typecheck + validate/secrets, then commit (completed 2026-03-01 09:31 EST; updated provider/state/settings regression suites, targeted tests pass, `npm run -s lint` pass, `npm run -s typecheck` pass, `mise exec -- npm run -s validate:fast` pass, `./scripts/secrets-scan.sh` pass) 834 - [x] Phase 10x: Fix post-save provider rehydrate duplication where persisted custom profile appears alongside draft custom entry (completed 2026-03-01 11:46 EST; introduced provider reconciliation flow that maps persisted custom catalog state onto selected/matching custom provider ID instead of creating an additional synthetic row) 835 - [x] Phase 10x: Add regression coverage for provider reconciliation to guarantee no duplicate custom rows after save/reopen (completed 2026-03-01 11:46 EST; added invariants regression asserting no extra `custom` row when selected custom provider is reconciled from snapshot) 836 - [x] Phase 10x: Run targeted settings/provider tests + lint/typecheck + validate/secrets, then commit follow-up fix (completed 2026-03-01 11:46 EST; targeted tests + `npm run -s lint` + `npm run -s typecheck` + `mise exec -- npm run -s validate:fast` + `./scripts/secrets-scan.sh` all pass) 837 - [x] Phase 10y: Fix custom provider name reassignment regression by reconciling persisted custom profile only onto matching custom provider IDs (base URL match / legacy id), never onto unrelated custom rows (completed 2026-03-01 11:55 EST; removed selected-provider-first mapping that caused third-provider name to change to existing persisted label) 838 - [x] Phase 10y: Add regression test covering multi-custom-provider name stability when persisted custom profile points at a different provider (completed 2026-03-01 11:55 EST; added invariants assertion that OpenRouter keeps its name while Ollama persisted profile remains mapped to Ollama row) 839 - [x] Phase 10y: Run targeted settings/provider tests + lint/typecheck + validate/secrets and commit follow-up fix (completed 2026-03-01 11:55 EST; targeted tests + lint + typecheck + validate:fast + secrets scan all pass) 840 - [x] Phase 10z: Replace legacy `openai/router/custom` provider-profile mapping with provider-ID based CRUD semantics (OpenAI builtin + arbitrary persisted providers) in settings snapshot/build/save paths (completed 2026-03-01 12:31 EST; settings snapshots now include provider records, default/session provider selection resolves by provider ID, and payload parsing supports provider-id based updates). 841 - [x] Phase 10z: Persist provider CRUD records in storage (DB migration + read/write helpers), map default/session provider selection by provider ID, and keep runtime provider override resolution coherent (completed 2026-03-01 12:31 EST; added `provider_profiles` storage, `default_provider_id` + `session_provider_overrides.provider_id` migrations/backfills, and provider-aware runtime resolution/pinning/session override patch logic). 842 - [x] Phase 10z: Update settings UI/state/model picker to operate on provider IDs (no `Custom URL` category), keeping status bar/session/defaults consistent with persisted provider settings (completed 2026-03-01 12:31 EST; defaults/session pickers now use dynamic provider IDs, providers tab persists full provider list, and status bar reads provider label from session summary). 843 - [x] Phase 10z: Add/adjust regression tests for provider add/edit/delete persistence, provider name stability, and settings/session model binding; run targeted tests + typecheck/lint (completed 2026-03-01 12:31 EST; updated provider/settings fixtures and invariants suites, `npm run -s typecheck` pass, `npm run -s lint` pass, targeted vitest suites pass, `mise exec -- npm run -s validate:fast` pass, `./scripts/secrets-scan.sh` pass). 844 - [x] Fix provider-profile migration regression by preventing repeated legacy backfill from recreating synthetic providers (completed 2026-03-01 12:50 EST; legacy provider-profile backfill now runs only when `provider_profiles` is empty, preventing restart-time recreation of synthetic `legacy-custom`/`router` rows) 845 - [x] Add migration cleanup for duplicate synthetic legacy providers and remap defaults/session overrides (completed 2026-03-01 12:50 EST; startup cleanup now remaps duplicate synthetic provider references to matching real provider IDs and removes redundant legacy rows) 846 - [x] Remove `CUSTOM` badge from providers list row UI to keep names readable (completed 2026-03-01 12:50 EST; provider list row now prioritizes name visibility without the badge) 847 - [x] Add regression tests for provider migration backfill/cleanup behavior (completed 2026-03-01 12:50 EST; added `tests/storage-provider-migration-regressions.test.ts` for no-reseed + legacy-duplicate cleanup/remap paths) 848 - [x] Validate provider regression fixes (targeted tests + typecheck) (completed 2026-03-01 12:50 EST; `mise exec -- npm run test -- tests/storage-provider-migration-regressions.test.ts`, `npm run typecheck`, `mise exec -- npm run validate:fast`, and `./scripts/secrets-scan.sh` all passed) 849 - [x] Remove legacy `openai/router/custom` hardcoded provider preset handling and make provider system fully dynamic (completed 2026-03-02 15:28 EST; updated `parseProviderDefaultPreset()` in ast.ts to accept any string, added `{ kind: 'profile' }` target in provider-target parser, replaced per-preset normalization branches in validation.ts with generic normalizer, switched transcription/embedding fallback from `providerPreset` to `defaultProviderId` in openai-compatible.ts, simplified `resolveDefaultProviderProfileId()` in read.ts, stopped mirroring `providerPreset` in persist.ts, removed hardcoded openai/router/custom seeding in UI settings.ts, made `formatProviderModelDefaultsSummary` dynamic, updated slash-command help text, and updated all affected tests — typecheck clean, 38/38 related tests pass) 850 851 - [x] Implement message pagination (50 per page) to reduce first-load payload size (completed 2026-03-02 16:41 EST) 852 - [x] Add "Load older messages" functionality to chat UI (completed 2026-03-02 16:41 EST) 853 - [x] Optimize initial load by deferring non-critical API calls (completed 2026-03-02 16:41 EST) 854 - [x] Switch Docker deployment to optimized production build + `vite preview` (completed 2026-03-02 16:41 EST) 855 - [x] Implement Caddy reverse proxy with Cloudflare DNS challenge for valid HTTPS via Let's Encrypt (completed 2026-03-02 16:41 EST) 856 - [x] Resolve Vite preview host header validation errors for proxied requests (completed 2026-03-02 16:41 EST) 857 - [x] Reduce initial page load time from ~60s to ~2.5s over Tailscale/LAN (completed 2026-03-02 16:41 EST) 858 859 ## Extensible Agent Runtime + Unified Tasks/Workflow Architecture (started 2026-03-03 12:15 EST) 860 861 - [x] Add shared agent/task/workflow contracts and extend streaming event union for task/workflow events. (completed 2026-03-03 13:05 EST) 862 - [x] Add SQLite schema/migration support for agent tasks, task events, workflow state/inputs, and agent health checks. (completed 2026-03-03 13:05 EST) 863 - [x] Implement storage modules for agent tasks, task events, workflows, and health check records. (completed 2026-03-03 13:05 EST) 864 - [x] Add task/workflow/agent-health API routes (`/api/tasks`, `/api/tasks/:taskId/events`, `/api/tasks/:taskId/cancel`, `/api/workflows/respond`, `/api/agent-health`). (completed 2026-03-03 13:05 EST) 865 - [x] Implement agent runtime plugin interface + registry/dispatch/events modules with codex-cli and opencode plugin wrappers. (completed 2026-03-03 13:05 EST) 866 - [x] Add Jules CLI/API tool adapters and register `jules` as runtime backend with hybrid transport metadata. (completed 2026-03-03 13:05 EST; added API/CLI adapters plus create/list/wait/cancel/pull/message/activity operations on runtime backend) 867 - [x] Add streaming CLI process utility for incremental stdout/stderr handling and codex JSONL event mapping. (completed 2026-03-03 13:05 EST) 868 - [x] Emit durable task/task-event lifecycle updates from chat streaming turns (session start, tool events, completion/error). (completed 2026-03-03 13:05 EST) 869 - [x] Add Background Tasks sidebar card + detail interactions with capability-aware actions and keep existing in-message tool timeline. (completed 2026-03-03 13:05 EST; added active/waiting/failure groupings, detail timeline loader, and task cancel action) 870 - [x] Add client task/workflow state wiring for new stream events and API polling. (completed 2026-03-03 13:05 EST; added stream handlers, workflow input panel, and task/health query integration) 871 - [x] Add proactive backend health check service (poller/checks/store) and wire API surface. (completed 2026-03-03 13:05 EST; poller now starts via API entrypoints and writes durable health/task records) 872 - [x] Add/update tests for runtime registry, task/workflow storage, stream task events, and sidebar rendering. (completed 2026-03-03 13:12 EST; added runtime registry/storage tests, updated stream golden trace expectations, and added sidebar task-section rendering/interaction tests) 873 - [x] Run validation (`npm run typecheck`, targeted tests, `npm run validate:fast`) and log completions. (completed 2026-03-03 13:05 EST; typecheck pass, targeted runtime/stream/query tests pass, validate:fast pass with warning-only lint findings, secrets scan pass) 874 - [x] Extensible runtime follow-up: wire task persistence + `task_update`/`task_event` stream emission for web-command and provider tool lifecycle. (completed 2026-03-03 13:05 EST) 875 - [x] Extensible runtime follow-up: add sidebar Background Tasks card with active/waiting/failed groupings and capability-aware task actions. (completed 2026-03-03 13:05 EST) 876 - [x] Extensible runtime follow-up: integrate task/health polling and stream-driven invalidation in chat page hooks/send flow. (completed 2026-03-03 13:05 EST) 877 - [x] Extensible runtime follow-up: start backend health poller from API entrypoints and keep checks durable/quiet. (completed 2026-03-03 13:05 EST) 878 - [x] Extensible runtime follow-up: fix compile/lint regressions, run targeted tests, and timestamp completed checklist entries. (completed 2026-03-03 13:05 EST) 879 - [x] Post-commit follow-up: add sidebar Background Tasks rendering/interaction tests (group sections, detail timeline load, cancel action visibility/behavior). (completed 2026-03-03 13:12 EST; added section/grouping coverage via hook-free sidebar task components/helpers) 880 - [x] Post-commit follow-up: run targeted test suite + typecheck for sidebar test additions. (completed 2026-03-03 13:12 EST; targeted vitest suite pass + `npm run typecheck` pass + `npm run validate:fast` pass with warning-only lint findings) 881 - [x] Post-commit follow-up: update remaining runtime test-coverage checklist completion timestamps. (completed 2026-03-03 13:12 EST) 882 - [x] Docker agent runtime: install `@google/jules`, `@openai/codex`, and `opencode-ai` in the runtime image. (completed 2026-03-03 13:12 EST) 883 - [x] Docker agent runtime: mount relative `./home` as container home and set `HOME` so agent configs/repos persist across restarts. (completed 2026-03-03 13:12 EST; `docker-compose.yml` mounts `./home:/home/helper` and sets `HOME`/`CODEX_HOME`) 884 - [x] Docker agent runtime: validate compose configuration and timestamp completion entries. (completed 2026-03-03 13:12 EST; attempted `docker compose config`, but Docker CLI is unavailable in this execution environment) 885 886 ## Agent Plugins Settings + Deploy Verification (started 2026-03-03 13:28 EST) 887 888 - [x] Add persisted settings contract/state for agent plugin enablement (backend-neutral, no env-only toggle dependency). (completed 2026-03-03 13:45 EST; added `agent_backends_enabled_json` migration hook plus app-settings read/write/update payload support via `agentBackendsEnabled` map) 889 - [x] Add an `Agents` tab to Settings modal that lists runtime backends, installed/probe status, and enable/disable controls. (completed 2026-03-03 13:45 EST; added `AgentsPanel`, new Settings tab wiring, runtime capability badges, and immediate enable/disable toggle persistence through `/api/settings`) 890 - [x] Apply plugin-enable gating in runtime health/sessions/send surfaces so disabled plugins are hidden/inactive by policy. (completed 2026-03-03 13:45 EST; runtime registry now filters disabled backends by default, disabled backends throw on `getAgentBackend`, health checks use enabled-only list, and CLI backend adapter availability mapping fixed to avoid codex false-negative when sessions directory is absent) 891 - [x] Add/update tests for settings parsing/persistence and Agents tab behavior. (completed 2026-03-03 13:45 EST; added parser coverage for `agentBackendsEnabled`, new Agents panel UI test, and runtime registry disabled-backend test path) 892 - [x] Smoke test deployed helper endpoint and inspect deploy sync script for stale-image/root-cause of `codex-cli` missing report. (completed 2026-03-03 13:45 EST; `/api/chat` + `/agents` on `https://monolith.oldtr.uk:3003` still reflects prior build, remote `helper-helper-1` container confirms `/usr/local/bin/codex` exists and `codex --version` exits 0, and deploy script reviewed in `.exports/sync-monolith-build.sh`) 893 - [x] Run targeted validation/typecheck and commit with completed WORKINGLOG timestamps. (completed 2026-03-03 13:45 EST; `npm run -s typecheck`, targeted vitest suites, `npm run -s validate:fast` (warnings only), and `./scripts/secrets-scan.sh` all completed) 894 895 ## Container Agent Login Persistence Hardening (started 2026-03-03 14:03 EST) 896 897 - [x] Add container startup initialization for mounted `/home/helper` so Codex/Jules/OpenCode auth/config dirs always exist on boot. (completed 2026-03-03 14:04 EST; added `scripts/docker-entrypoint.sh` and wired Docker `ENTRYPOINT` to create `.codex`, `.jules`, and opencode XDG dirs at container start) 898 - [x] Update Docker runtime env defaults (HOME/CODEX_HOME/XDG paths) and compose env passthrough so CLI auth files persist in `./home`. (completed 2026-03-03 14:04 EST; added XDG env vars in `Dockerfile` and `docker-compose.yml` alongside existing `HOME`/`CODEX_HOME` values) 899 - [x] Redeploy via `./.exports/sync-monolith-build.sh` and verify in-container auth paths/status commands for `codex`, `jules`, and `opencode`. (completed 2026-03-03 14:04 EST; sync/build/restart succeeded on monolith, `codex login status` now reports `Not logged in` instead of missing CODEX_HOME error, `jules login --help` and `opencode auth list` run in-container with persisted home paths) 900 - [x] Smoke test helper endpoint after redeploy and timestamp completed checklist entries. (completed 2026-03-03 14:04 EST; `/api/chat` with `/agents` on `https://monolith.oldtr.uk:3003` confirms updated backend availability messaging after redeploy) 901 902 ## Agent Web Auth Proxy + Login Flows (started 2026-03-03 14:30 EST) 903 904 - [x] Add server auth API routes (`GET/POST /api/agents/auth`) backed by runtime auth session service for codex/jules/opencode login state and actions. (completed 2026-03-03 14:44 EST; added `/api/agents/auth` route + server API parser/dispatcher layer and hardened auth service status/action handling for CLI-missing/error cases) 905 - [x] Add client API + query hooks for auth status/session polling and wire into settings model. (completed 2026-03-03 14:44 EST; added `agent-auth` client API module, query key, and `useAgentAuthController` polling/action hook with active-session adaptive refresh) 906 - [x] Extend Settings Agents tab with auth controls (start login, submit code/API key, cancel/logout) and live status/session feedback. (completed 2026-03-03 14:44 EST; `AgentsPanel` now renders per-backend auth state badges, action controls, live auth session details/logs, and jules API-key/login-code flows) 907 - [x] Validate auth flow behavior with targeted tests/typecheck and fix regressions. (completed 2026-03-03 14:44 EST; `npm run -s typecheck`, targeted vitest suites for agents/auth parsing UI, `npm run -s build` for route-tree regen, `npm run -s validate:fast` (warning-only lint), and `./scripts/secrets-scan.sh` all completed) 908 - [x] Redeploy with `./.exports/sync-monolith-build.sh`, smoke test deployed auth endpoints/UI behavior, then commit with timestamped WORKINGLOG completions. (completed 2026-03-03 14:50 EST; latest deploy sync succeeded after auth-panel file split, live `GET /api/agents/auth` returns backend auth statuses/sessions, and live `POST /api/agents/auth` with `codex.logout` returns `{ ok: true }`) 909 910 ## Jules Auth Code Input Visibility Fix (started 2026-03-03 14:55 EST) 911 912 - [x] Broaden Jules CLI prompt detection so auth sessions transition to `waiting_input` across current CLI output variants. (completed 2026-03-03 15:06 EST; auth parser now detects authorization/verification prompt variants and processes partial output buffers without requiring newline-delimited prompt lines) 913 - [x] Make Jules auth UI accept code entry while login session is active (`running` or `waiting_input`) to avoid dead-end states. (completed 2026-03-03 15:06 EST; Jules controls now keep submit/cancel visible for active sessions and include running-state auth-code input fallback) 914 - [x] Run targeted typecheck/tests, redeploy via sync script, and verify live endpoint/session behavior. (completed 2026-03-03 15:06 EST; `npm run -s typecheck` and `tests/chat-settings-agents-panel.test.tsx` pass, deploy script completed, and live `/api/agents/auth` smoke test confirmed Jules session transitions to `waiting_input`) 915 916 ## 1.0 Legacy Shim Removal + Provider/Model Normalization (started 2026-03-03 15:20 EST) 917 918 - [x] Add schema version gate and one-time v1 converter in DB migration path. (completed 2026-03-03 17:23 EST) 919 - [x] Rebuild `app_settings`, `sessions`, and `session_provider_overrides` schemas to remove legacy columns and adopt ID-only provider/model state. (completed 2026-03-03 17:23 EST) 920 - [x] Add normalized `models` and `provider_models` tables and storage helpers. (completed 2026-03-03 17:23 EST) 921 - [x] Migrate provider model resolution/write paths from JSON blobs to normalized tables. (completed 2026-03-03 17:23 EST) 922 - [x] Remove legacy provider preset/base-URL settings fields from shared contracts and API validation. (completed 2026-03-03 17:23 EST) 923 - [x] Refactor session/provider resolution to remove URL-host inference and preset fallback logic. (completed 2026-03-03 17:23 EST) 924 - [x] Update settings UI/session display to show provider name only (fallback: `Unknown provider`), with no URL host fallback in normal session surfaces. (completed 2026-03-03 17:23 EST) 925 - [x] Remove legacy slash-command preset/base-url branches and help text. (completed 2026-03-03 17:23 EST) 926 - [x] Remove legacy migration helper code/tests and replace with v1 invariant tests (`PRAGMA table_info` assertions). (completed 2026-03-03 17:23 EST) 927 - [x] Run typecheck, targeted tests, and validate:fast; record completion timestamps. (completed 2026-03-03 17:23 EST) 928 929 ## 1.0 Migration Follow-up Stabilization (started 2026-03-03 16:01 EST) 930 931 - [x] Fix remaining TypeScript errors from strict provider-target/parser contract changes (completed 2026-03-03 17:23 EST) 932 - [x] Align provider slash-command tests with profile/current-only targets (no literal/router) (completed 2026-03-03 17:23 EST) 933 - [x] Add/replace migration invariant tests for removed legacy columns and v1 schema assertions (completed 2026-03-03 17:23 EST) 934 - [x] Re-run typecheck + targeted tests for provider/settings/migration paths (completed 2026-03-03 17:23 EST) 935 - [x] Mark this stabilization batch complete with timestamps (completed 2026-03-03 17:23 EST) 936 937 ## Post-v1 DB Self-Heal + Agent Auth UX Cleanup (started 2026-03-03 17:30 EST) 938 939 - [x] Add startup DB self-heal for broken legacy FK references (`*_legacy_v1`) left by interrupted/old migration paths (completed 2026-03-03 18:20 EST) 940 - [x] Ensure self-heal rebuilds affected tables in-place while preserving existing rows (completed 2026-03-03 18:20 EST) 941 - [x] Fix OpenCode auth settings input default so it does not prefill with OpenAI URL (completed 2026-03-03 18:20 EST) 942 - [x] Add/adjust regression tests for migration self-heal and OpenCode auth default behavior (completed 2026-03-03 18:20 EST) 943 - [x] Run typecheck + targeted tests and record completion timestamps (completed 2026-03-03 18:20 EST) 944 - [x] Normalize recent-session model badge rendering so malformed legacy model strings collapse to a single readable model label (completed 2026-03-03 18:23 EST) 945 946 ## Global Default Model/Responses Fallback Stabilization (started 2026-03-03 19:05 EST) 947 948 - [x] Fix session/global-default model resolution so stale cross-provider namespaced overrides cannot poison inherited provider/model routing. (completed 2026-03-03 19:21 EST; added provider-aware namespaced model normalization and applied it in session summary active-model resolution) 949 - [x] Stop seeding new sessions with pinned chat-model overrides so new chats truly inherit current global defaults. (completed 2026-03-03 19:21 EST; `ensureSession` now seeds `chat_model_id_override` as `NULL`) 950 - [x] Treat Responses API `status=failed` + empty text as a retriable failure (not success) and fallback to chat-completions compatibility path. (completed 2026-03-03 19:21 EST; non-stream responses path now records an error and retries via chat-completions instead of emitting parse placeholders) 951 - [x] Update local Responses tool-loop round handling so failed/empty assistant rounds trigger compatibility fallback instead of parse-placeholder replies. (completed 2026-03-03 19:21 EST; tool-loop rounds now detect `status=failed` empty-output responses, record error telemetry, and throw compatibility-fallback-triggering errors) 952 - [x] Add regression tests for model normalization and responses-failure fallback behavior. (completed 2026-03-03 19:21 EST; added `tests/settings-session-model-normalization.test.ts`, `tests/session-seeding-inherit-defaults.test.ts`, and expanded `tests/openai-compatible-textual-tool-fallback.test.ts`) 953 - [x] Run targeted tests + `npm run -s typecheck` + `npm run -s validate:fast`, then record completion timestamps. (completed 2026-03-03 19:21 EST; targeted tests pass, typecheck pass, validate:fast pass with pre-existing warnings, secrets scan pass, deploy sync completed, and live smoke checks on monolith succeeded) 954 955 ## Stream Fallback Root-Cause Repair (started 2026-03-03 20:06 EST) 956 957 - [x] Extend legacy FK self-heal migration to rebuild all `*_legacy_v1`-tainted runtime tables (`agent_tasks`, `workflow_runs`, `agent_health_checks`, `tool_execution_logs`). (completed 2026-03-03 20:16 EST; also rebuilt dependent runtime child tables (`agent_task_events`, `agent_task_runs`, `workflow_inputs`) to prevent temp FK target drift during repair) 958 - [x] Add migration invariant assertions/tests to fail if any table SQL still references `*_legacy_v1` after runtime migrations. (completed 2026-03-03 20:16 EST; dev/test assertion now blocks both `*_legacy_v1` and `*_fk_repair_v1` markers, and migration regression test now covers full runtime table graph) 959 - [x] Run targeted migration/runtime tests + typecheck and timestamp completed checklist entries. (completed 2026-03-03 20:16 EST; `tests/storage-provider-migration-regressions.test.ts` pass and `npm run -s typecheck` pass) 960 - [x] Redeploy to monolith and verify `/api/chat-stream` emits stream events (no immediate non-stream fallback). (completed 2026-03-03 20:16 EST; redeploy succeeded via `./.exports/sync-monolith-build.sh`, live `/api/chat-stream` returns `session`/`task_update`/`done`, DB has no `*_legacy_v1` or `*_fk_repair_v1` schema markers, and stale pre-fix running tasks were marked failed) 961 962 ## Agent Send UX Hardening (started 2026-03-04 06:28 EST) 963 964 - [x] Add forgiving slash aliases for common `agentsend` typo cases and preserve existing command behavior. (completed 2026-03-04 06:38 EST) 965 - [x] Add explicit `new/newsession` selector support in agent send flow so Codex can start a fresh run when no prior sessions exist. (completed 2026-03-04 06:38 EST) 966 - [x] Improve runtime send fallback so missing latest-session metadata does not hard-fail after a successful streamed run. (completed 2026-03-04 06:38 EST) 967 - [ ] Add targeted parser/runtime tests, then redeploy to monolith and verify `/agentsend codex newsession ...` works end-to-end. 968 969 ## Tool Loop Continuation Regression Guard (started 2026-03-04 06:35 EST) 970 971 - [x] Add provider routing regression test for follow-up prompts after unresolved assistant tool-call output. (completed 2026-03-04 06:38 EST) 972 - [x] Validate openai-compatible tool trigger/textual fallback suites and record outcomes. (completed 2026-03-04 06:38 EST; `tests/openai-compatible-tool-trigger-routing.test.ts`, `tests/openai-compatible-textual-tool-fallback.test.ts`, and `tests/textual-tool-calls.test.ts` pass) 973 974 ## Codex New Session Arg Compatibility Fix (started 2026-03-04 09:17 EST) 975 976 - [x] Remove unsupported `--all` arg from non-resume `codex exec` invocation path. (completed 2026-03-04 09:20 EST) 977 - [x] Add regression test for codex newsession argv composition. (completed 2026-03-04 09:20 EST; added `tests/agent-runtime-codex-args.test.ts`) 978 - [x] Run targeted tests/typecheck and redeploy to monolith for `/agentsend codex newsession --cwd ...` validation. (completed 2026-03-04 09:20 EST; targeted tests and typecheck pass, deploy script completed, and live `/api/chat-stream` smoke test returns codex newsession exit code 0)