/ 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)