4.0.0
What's Changed
- chore(release): 4.0.0
- feat(tasks): roster agents in templates + "Add to work order" context menu (#123)
- feat(tasks): edit work-order bodies inline in the Agent Board modal
- feat(tasks): agent-loops library for work orders (#119)
- docs(product): add Agent Roster feature doc
- fix(header): don't truncate the bound-agent chip when the row has space
- docs(tech-debt): record HTTP-tier grant scoping Phase 1 shipped
- fix(agents): provider-gate bound model; thread tool grant to Opencode/Cursor (P1b)
- feat(tools): grant-scope the HTTP tool server by bearer token (Phase 1a)
- fix(skills): invalidate skill cache after direct Library writes
- docs(tools): clarify per-token vs per-conversation scoping guarantee
- docs(tools): spec for HTTP tool-tier grant scoping
- fix(claude): include bound-agent prompt in persistent-query config key
- polish(ui): UX cleanups across roster, libraries, and chips
- style(library): give the shared name-button class a chrome reset
- docs(tech-debt): mark resolved roster follow-ups; record deferrals
- a11y(chat): roving tabindex for the tab strip
- refactor(agents): unify roster view onto shared library shell/card
- i18n(app): localize view titles, ribbon tooltips, command names
- docs(agents): note tool-grant scope divergence in roster UI
- fix(tools): drain in-flight HTTP tool calls before rebuild
- fix(storage): atomic temp+rename writes for JSON config stores
- a11y(agents): mark card + detail-header avatars decorative
- a11y(chat): mark the tab-badge container as role=tablist
- docs(tech-debt): record agent-subsystem improvement-pass deferrals
- a11y(chat): keyboard-operable header buttons + tab badges, ARIA states
- a11y(agents): label inputs, announce states, fix card semantics + picker ARIA
- feat(agents): defer new-agent persistence; loading states; binding hint
- fix(agents): remove projected provider files when a roster agent is deleted
- feat(agents): apply granted skills to bound chats via the bound prompt
- feat(agents): render per-agent icons + icon picker
- harden(tools): atomic+serialized tool-registry load; log roster/projection failures
- refactor(agents): extract tested tool-scoping + provider-resolution helpers
- fix(i18n): correct interpolation, drop dead keys, tidy agent copy
- docs(plan): agent subsystem improvement pass (5-lens review)
- feat(chat): stack the header into a title row + agent/git meta row
- refactor(chat): split TabBar.renderBadge to clear critical complexity
- feat(chat): slim the bound-agent header chip and let the header breathe
- feat(chat): mark agent-bound chat tabs with a badge glyph
- docs(plan): chat header declutter + agent-bound indicators
- docs(spec): chat header declutter + agent-bound indicators
- polish(agents): clearer discard label, header card, save-safe start chat
- style(agents): detail-editor cards, profile header, sticky footer
- feat(agents): extract AgentDetailEditor with card layout + pickers
- feat(agents): reusable collapsible CapabilityPicker
- feat(agents): isRosterAgentDirty for unsaved-change tracking
- i18n(agents): add detail-editor picker + save keys
- docs(plan): agent detail page overhaul implementation plan
- docs(spec): agent detail page overhaul design
- polish(libraries): richer empty states, a11y focus, and card refinements
- docs(tech-debt): record the three deferred hardening decisions
- harden(ui): surface library/roster action failures and fix modal polish
- fix(tasks): resolve work-order personas synchronously from a preloaded roster
- fix(claude): re-apply the claudian tool server when its scoped set changes
- harden(agents): sanitize roster fields before provider projection
- harden(tools): bound user-tool handlers and validate tool names
- fix(skills): require sourced outcome metric/target in framing
- docs(skills): re-run impact-map GREEN after metric hardening (COMPLY)
- docs: add usability to the skill-catalog assumption-map summary
- docs(skills): re-run assumption-map GREEN with usability (COMPLY)
- docs: add usability to the arc-summary assumption categories
- fix(skills): confirm impact-map metric with stakeholders, not just target
- fix(skills): include usability in the feasibility-only common-mistake fix
- fix(skills): add usability to assumption-mapping risk categories
- fix(tasks): drop the redundant "Agent:" prefix from the work-order agent picker
- docs: carry named-human-source gate into the methodology note
- docs(skills): re-run synthesis/JTBD/prioritization GREEN cases (all COMPLY)
- docs(skills): record impact/journey GREEN re-runs (both COMPLY)
- fix(skills): require sourced targets/assumptions in impact + journey maps
- test(skills): re-run persona/NFR GREEN cases; strengthen both skills
- docs(skills): add reproducible RED/GREEN scenarios to evaluation artifact
- docs(skills): align with trigger-only description rule; conditional persona quote
- feat(libraries): rename in editor modals, hide view title bar, cross-library nav
- test(skills): RED/GREEN-harden the discovery skills + address review
- fix(skills): correct riskiest-assumption quadrant axis direction
- docs: add product-discovery agent-skill baseline + research
- feat(libraries): edit tools and skills in a dedicated modal (dot-folder fix)
- feat(agents): project roster agents into provider-native subagent folders
- feat(agents): make bound-agent persona a forceful leading directive (Cursor fix)
- fix(tasks): keep TaskRunCoordinator.run() reservation synchronous
- feat(libraries): overhaul Tool + Skill libraries with create/edit/delete + roster links
- feat(agents): work-orders adopt agent provider/model; new-tab agent chat; library ribbons
- fix(agents): resolve an enabled provider for agent chats; polish the bound-agent chip
- feat(agents): overhaul the Agent Roster UI with provider/model, avatars, roles
- fix(agents): de-dupe bound-agent chip, provider-aware start chat, populate WO agent picker
- feat(agents): scope user tools to a bound agent's grant (Claude)
- docs: update roster follow-ups (avatars/i18n/signal/coverage shipped; enforcement fork)
- feat(tools): wire per-request abort signal into tool host; localize library views
- feat(agents): render roster-agent avatars on the board and detail modal
- feat(agents): add installable starter agent definitions to the roster
- docs: mark non-Claude bound-agent projection shipped
- chore(ci): update LOC and quality baselines for bound-agent prompt changes
- feat(opencode): append bound agent prompt to ACP prompt blocks each turn
- feat(cursor): append bound agent prompt as delimited section in CLI prompt
- feat(codex): thread bound agent system prompt into CodexChatRuntime.query
- feat(chat): fold boundAgentModel into queryOptions.model for non-Claude providers
- docs: update followups (cursor tools + work-order assignment shipped)
- feat(cursor): wire HTTP MCP tool server pre-spawn via writeCursorMcpConfig (Slice 3)
- feat(cursor): add cursorMcpConfig helper and unit tests (Slice 3)
- feat(tasks/chat): thread boundAgentId from work-order through to createConversation (Slice 2B)
- feat(tasks/agents): add roster agents to work-order agent picker (Slice 2A)
- feat(T3): add Start-chat button to each agent roster card
- feat(T2): bound-agent chip in chat header with unbind action
- fix(T1): use ensureViewOpen in openConversation to fix race after activateView
- docs: design spec for wiring the agent roster (chat usability, work-orders, cursor)
- docs: mark cross-provider tools partial (HTTP tier + Opencode shipped)
- test(tools): cover HTTP MCP server bearer-auth reject + constant-time compare
- feat(tools): expose user tools to Opencode via in-process HTTP MCP server
- docs: design spec for in-process HTTP MCP tool tier (replaces stdio)
- docs: mark roster->run chat binding shipped in tech-debt followups
- fix(claude): keep bound-agent model across persistent turns
- chore: bump complexFunctions baseline 235 -> 236
- refactor(agents): keep core free of features import for bound-agent resolution
- chore: update LOC baseline for ClaudeChatRuntime, InputController, main
- feat(roster-view): add Start chat button and use shared agentRosterStore
- feat(input): resolve bound-agent query options at send time
- feat(claude-runtime): thread boundAgentPrompt/Model into query contexts
- i18n: add agentRoster.startChat key to all 10 locales
- feat(agents): thread boundAgentPrompt/boundAgentModel into ClaudeQueryOptionsBuilder
- feat(agents): add boundAgentPrompt/boundAgentModel to ChatRuntimeQueryOptions
- feat(agents): persist and hydrate boundAgentId through conversation storage
- feat(agents): add boundAgentId to Conversation and SessionMetadata types
- docs: design spec for roster->run chat binding (MVP: prompt + model)
- chore: bump ClaudeChatRuntime LOC ceiling 1602 -> 1605
- feat(claude): keep user tools available across the persistent query
- docs: record increment-1 follow-ups (tech-debt)
- fix(agents): prevent duplicate-slug overwrite when creating agents
- test: fix CI guards for new views (LOC ceiling, coverage)
- fix(views): reveal existing leaf when opening roster/tool/skill views
- feat: wire roster store, tool registry, three views, and Claude tool server
- feat(skills): Skill Library view over the vault skill aggregator
- feat(tools): Tool Library view (list, scaffold, reload, errors)
- feat(agents): Agent Roster view with tool/skill pickers
- feat(skills): skill library row mapper
- refactor(tools): address Part B review (typed cast, comments, handler test)
- chore(tools): fix lint (import order, no-global-this) and reduce validateModule complexity
- feat(claude): merge in-process Claudian tool MCP server into query options
- feat(tools): in-process Claude SDK MCP server from registry
- feat(tools): ClaudianToolRegistry discover/transpile/validate
- feat(tools): runtime TS->CJS transpile via sucrase
- feat(tools): ClaudianTool manifest+handler types
- refactor(agents): address Part A review (drop redundant ensureFolder, guard delete emit)
- feat(agents): AgentRosterStore JSON CRUD over .claudian/agents
- feat(agents): RosterAgent type and capability helpers
- feat(agents): add roster/toolLibrary event keys
- build: add zod and sucrase for user tool authoring
- docs: implementation plan for agent roster + tools + skills (increment 1)
- docs: fold loop controls into the Agent Board and Work-Orders
- docs: research on loop engineering / loopcraft fit with agent designs
- docs: research + design for user-authored Tool Library & Skill Library
- docs: rework agent roster spec for provider-agnostic dedicated UI
- docs: research + design spec for AI agent roster feature
- refactor(i18n): split TranslationKey union into per-namespace files
- fix(tasks): dedupe card action button render/styles; bump i18n LOC ceiling
- feat(tasks): surface "Go to conversation" button on running work-order cards
- fix: quote leading YAML-indicator scalars in yamlString
- fix(cursor): restrict @mentions to delegatable agents (vault/global only)
- feat(cursor): codex-compat root via TOML parsing; drop built-ins from @mentions
- docs(cursor): drop stale .codex mention from the subagents empty-state text
- fix(cursor): don't require a description when editing an existing agent
- fix(cursor): keep description-less vault/global agents; stay strict for compat
- fix(cursor): drop the non-functional .codex/agents compat root
- feat(cursor): subagent foundation + shared frontmatter/settings improvements
- test(runtime): lift opencode + cursor runtime coverage, raise both floors
- refactor(codex): dedup codexSessionTailMapping call-id claim (clone 32→31)
- refactor(codex): split codexAppServerTypes by domain (barrel re-export)
- test(opencode): lift opencode/runtime branch coverage + raise the floor
- refactor(tasks): graduate WorkOrderDetailModal off the LOC allowlist + tighten thresholds
- refactor(chat,tasks): split MessageRenderer and AgentBoardRenderer card actions
- docs: add portable quality-tooling integration guide
- fix(project-setup): don't shadow an existing fallow config with .fallowrc.json
- fix(project-setup): normalize a leading ./ in entry paths (Codex 2x P2, same cause)
- fix(project-setup): detect entry from lib/app/source dirs + main/module fields (Codex P2)
- fix(project-setup): report runs the generated file, not a shadowed report script (Codex P2)
- fix(project-setup): sanitize entry-derived paths; honor coverage opt-out (Codex 2x P2)
- fix(project-setup): LOC scan root from entry; commit the coverage-baselined marker (Codex 2x P2)
- fix(project-setup): derive coverage globs from the detected entry (non-src layouts) (Codex P2)
- refactor(chat): extract TabProviderCommandCoordinator from TabManager
- fix(project-setup): robust CI branch triggers; track coverage baseline by marker (Codex 2x P2)
- fix(project-setup): valid coverage floor on empty Istanbul; tests don't trip the dead-code ratchet (Codex 2x P2)
- fix(project-setup): baseline via the generated file, not a shadowed script; verify clears stale coverage (Codex 2x P2)
- fix(project-setup): complete test-config detection (package.json#jest + .cts/.cjs) (Codex 2x P2)
- fix(project-setup): recover an interrupted baseline; install the runner on standdown (Codex 2x P2)
- fix(project-setup): close the coherence seams (coherence review)
- chore(project-setup): portability polish + doc reconciliation (review pass)
- refactor(project-setup): de-duplicate engine internals (code-quality review, behavior-preserving)
- fix(project-setup): make the notice layer coherent (output review)
- fix(project-setup): harden input/template/exec sinks against injection (security audit)
- refactor(chat): extract ClaudianViewWorkOrderBridge from ClaudianView
- fix(project-setup): retry an incomplete dependency install on re-apply (Codex P2)
- fix(project-setup): own test-lint plugin dep in planEslint; notice same-name eslint config (Codex 2x P2)
- Address Codex review: record async sub-agent edits after hydration
- fix(project-setup): TS coverage includes JS sources; scope config standdown to runner (Codex 2x P2)
- refactor(chat): split StreamController's subagent handling into two coordinators
- fix(project-setup): Vite standdown by resolved runner; test:coverage collision (Codex 2x P2)
- Address Codex review: record hydrated sub-agent edits (Cursor Task)
- Address Codex review: faithful transcript replay for edited-files derive
- fix(project-setup): finish .mts/.cts/.cjs propagation + flat-config collision (Codex 3x P2)
- Address Codex review: remove chips for Cursor file deletes
- fix(project-setup): route baselines + verify through the PM; cover .mts/.cts/.cjs (Codex 3x P2)
- Address Codex review: vault-refresh sub-agent file edits
- Address Codex review: include sub-agent edits in the edited-files list
- fix(project-setup): config-matrix audit — batch-close day-one gaps across TS/JS, jest/vitest, PM
- chore(quality): ratchet-down locks — graduate OpencodeHistoryStore, re-lock coverage floors, refresh roadmap
- chore(settings): offset i18n LOC growth from the new setting keys
- Address Codex review: consolidate apply_patch ops, strict reload resolution
- fix(project-setup): emit coverage json-summary; disable no-undef for JS (Codex 2x P2)
- fix(project-setup): baseline only newly-added guardrails; flag report collision (Codex 2x P2)
- Address Codex review: close apply_patch rename/delete edge cases
- docs(tech-debt): ratchet-down roadmap for grandfathered thresholds
- fix(project-setup): vitest-globals lint, report via PM, CI default-branch (Codex 3x P2)
- Address Codex review: refresh moved files and apply opt-out immediately
- fix(project-setup): close two gaps the polishing pass left (Codex 2x P2)
- refactor(chat): snapshot collapse mode once per text block
- refactor: hold LOC ratchet ceilings instead of bumping them (Codex review)
- refactor(chat): extract InlinePromptController from InputController
- fix(project-setup): address Codex review on the polishing pass (3x P2)
- fix(chat): ignore renders scheduled before collapse was enabled
- Address Codex review: close out-of-vault path class and apply_patch renames
- docs(project-setup): record the review-driven polishing pass + add plan frontmatter
- fix(chat): re-render when collapse is enabled mid-stream after a live render
- fix(project-setup): package-manager-aware docs, discoverability, readable preview
- fix(project-setup): brownfield day-one-green + report collisions, don't silently no-op
- Address Codex review: out-of-vault paths and apply_patch deletes/renames
- docs(inline-edit): record YishenTu#761 skip decision + known x86_64 limitation
- chore(loc): ratchet hotspot baseline for YishenTu#767 + YishenTu#776 additions
- fix(chat): address PR review — mid-stream toggle, indicator extraction, plan frontmatter
- fix(project-setup): keep apply idempotent across an install-induced detect flip
- fix(opencode): harden history hydration for renderer + large sessions (upstream YishenTu#776)
- fix(project-setup): make the quality report accurate and actionable
- Address Codex review: record new files live, honor opt-out on reload
- feat(chat): add setting to expand Write/Edit diffs by default (upstream YishenTu#767)
- Add "files changed by the agent" list above the chat composer
- docs(project-setup): reconcile spec + plans with shipped engine
- refactor(chat): extract ConversationHistoryView from ConversationController
- refactor(chat): extract renderFinalizedTextBlock to clear complexity gate
- fix(project-setup): resolve typescript from detection; skip CI for bun
- feat(settings): expose collapseStreamingResponse toggle + i18n
- feat(chat): collapse streaming response behind a placeholder until complete
- fix(project-setup): verify always runs a test gate; planReport pins fallow
- docs(chat): implementation plan for collapse-streaming-response
- fix(project-setup): ignore generated files in lint, resolved-pm install/ci, js coverage globs, pnpm ci version
- docs(plan): triage upstream 2.0.22->2.0.24 sync delta
- fix(mention): allow spaces in @-mentioned filenames (upstream YishenTu#748)
- test(project-setup): greenfield + brownfield end-to-end smoke
- feat(project-setup): SKILL.md orchestration + reference docs
- feat(project-setup): opt-in GitHub MCP + compose docs/report into plan()
- feat(project-setup): docs scaffold templates + planDocs
- feat(project-setup): report delegates to quality-report; verify runs enabled gates
- docs(chat): spec collapse-streaming-response design
- feat(project-setup): actionable quality-report script + planReport
- feat(project-setup): set coverage floor from measured summary (rise-only)
- fix(project-setup): stable run report + greenfield-safe test scripts
- fix(project-setup): entry detection, locCap render, pm-aware run cmd, coverage-absent baseline, install dry-run preview
- feat(project-setup): compose harness into plan() and run baselines after apply
- feat(project-setup): baseline init drives ratchet --update, coverage last
- feat(project-setup): CI workflow template (opt-in) + planInstall
- feat(project-setup): LOC guard + Jest/Vitest templates and planners
- feat(project-setup): fallow config + ratchet script template + planFallow
- feat(project-setup): ESLint template + planEslint sub-planner
- feat(project-setup): installDeps action with injectable exec
- refactor(context): build+render a shared ContextEnvelope across the four turn encoders
- feat(project-setup): template load + render primitive
- fix(project-setup): detect packageManager field + worktree git remote; harden plan docs
- fix(project-setup): bun.lock detection, non-clobbering backups, Node-22 test command
- docs: address Codex round 2 on the harness plan (framework + CI gating)
- docs: address Codex review on project-setup plans
- feat(project-setup): wire CLI to detect/plan/apply with options loader
- feat(project-setup): idempotent apply with dry-run and backups
- feat(project-setup): plan options+state into an ordered Action[]
- feat(project-setup): additive non-destructive merge helpers + backups
- feat(project-setup): detect project state (package manager, tooling, github)
- feat(project-setup): engine CLI skeleton with arg parsing and dispatch
- docs: add user-facing-skill implementation plan (project-setup, plan 3 of 3)
- docs: render contract is per-provider, not per-style (PR #98 review)
- docs: add harness-templates implementation plan (project-setup, plan 2 of 3)
- docs: phrase builder test as trust-assignment-only (PR #98 review)
- docs: fix Context Envelope wrapping-ownership inconsistency (PR #98 review)
- docs: add engine-core implementation plan (project-setup, plan 1 of 3)
- docs: capture Context Envelope architecture design + glossary terms (run 17)
- docs: baseline coverage floors on brownfield adoption (project-setup spec)
- docs: add project-setup skill design spec
- docs: correct unused-dependency gating claim in quality guide
- fix(codex): replace (not accumulate) JSON-RPC notification handlers on re-wire (PR #96 review)
- docs: add quality integration guide for fallow + ESLint
- docs(tech-debt): shared-transport-extraction done (JSON-RPC client, run 16)
- refactor(core): extract shared JsonRpcStdioClient (ADR-0001 Move 2 step 2, run 16)
- docs(tech-debt): record shared-transport process-helper extraction (run 15)
- chore(quality): lock run-15 baseline (cloneGroups 33->32, duplicatedLines 819->803)
- refactor(core): extract shared AgentSubprocess process helper (ADR-0001 Move 2, run 15)
- docs(quality): record run-14 test-file split; oversized-modules debt -> done
- chore(quality): lock run-14 baseline (complexFunctions 237->236)
- test: split oversized Tab and ClaudianService test files by behavior surface (run 14)
- chore(quality): promote remaining jest warn rules; correct all-error claim (PR #93 review)
- chore(quality): promote jest/expect-expect to error; refresh quality tech-debt docs (run 13)
- chore(quality): lock run-12b baseline (cloneGroups 35->33, duplicatedLines 869->819)
- refactor: extract Windows batch-shim spawn logic to utils/windowsSpawn (run 12b)
- chore(quality): tidy loc-baseline — re-lock grandfathered hotspots to current size (run 12a)
- docs(quality): record run-11 cross-zone clone consolidation
- chore(quality): lock run-11 baseline (cloneGroups 42->35, duplicatedLines 1063->869)
- refactor: consolidate cross-zone settings/modal clones into shared/ (run 11)
- docs(quality): record run-10 complexity decomposition
- chore(quality): lock run-10 baseline (complexFunctions 254->239)
- refactor: decompose 16 high-complexity functions across chat, providers, core, utils, shared (run 10)
- docs(quality): record run-9 complexity decomposition
- chore(quality): lock run-9 baseline (complexFunctions 263->254)
- refactor: decompose high-complexity functions across utils, core, providers, app, shared (run 9)
- docs(quality): record run-8 clone-group reduction
- chore(quality): lock run-8 baseline (cloneGroups 68->42, duplicatedLines 1790->1063)
- refactor: reduce duplication across chat, providers, shared, and settings (run 8)
- build: promote complexity/max-lines-per-function to error; lock baselines
- refactor: decompose 10 function-health offenders below complexity/max-lines thresholds
- docs(quality): record criticalComplexity reaching 0 in run 6
- Require tool-capable validation for Auto Router on Agent Board
- chore(quality): lock run-6 wave-2 baseline (criticalComplexity 33 -> 0)
- refactor(test): decompose two critical-complexity test helpers
- refactor(quality): decompose claude/codex/cursor runtime+history criticals
- refactor(quality): decompose opencode runtime/history/settings criticals
- refactor(quality): decompose settings renderTabs and work-order footerActions
- refactor(quality): decompose features/chat criticals (drop, rewind, save, tabs, web-search)
- Clarify provider registration and remove read-only Agent Board escape hatch
- Handle Auto Router session expiry by persisting model selection
- Require tool-capable model filtering for Agent Board
- Add Agent Board tool execution and Auto mode persistence requirements
- Add session_id pinning requirement for Auto Router consistency
- Fix MVP scope inconsistency: include Agent Board model selection
- Add OpenRouter integration product specification
- chore(quality): lock run-6 wave-1 baseline gains
- refactor(quality): decompose codex history and opencode runtime/settings criticals
- refactor(quality): decompose claude history and slash-command settings criticals
- refactor(quality): decompose StreamController and InlineAskUserQuestion criticals
- refactor(quality): decompose projectProviderState and showMentionDropdown
- fix(settings): rebuild the registry when the locale changes
- docs: reconcile reference docs with runs 4-5 reality
- fix(settings): reconcile model selections after custom-model commits
- fix(tests): make codexPort parity assertions platform-deterministic
- feat(settings): render all tabs through the registry
- feat(settings): port cursor tab to the registry
- feat(settings): port opencode tab to the registry
- feat(settings): port codex tab to the registry
- feat(settings): port claude tab to the registry via the provider-widgets seam
- refactor(claude): decompose the query turn family behind claudeQueryTurnHelpers
- feat(settings): port general tab to the registry
- refactor(codex): decompose the query generator's thread lifecycle and chunk pump
- refactor(cursor): table-drive tool input mapping and success formatting
- refactor(codex): decompose conversation-history loadMessages dispatcher
- docs(plans): settings registry port completion plan
- chore(quality): ratchet fallow baseline down after run-4 refactors
- refactor(runtime): replace ChatRuntime callback setters with construction-time RuntimeHost
- refactor(quality): decompose the next critical-complexity tier in parser and stream-mapping code
- feat(security): demarcate untrusted web content in all provider prompts
- feat(quality): tighten duplication detector to minOccurrences 2 and re-baseline
- feat(lint): zero out max-params/max-depth and promote four clean rule families to error
- refactor(quality): consolidate the worst clone families ahead of detector tightening
- feat(ci): graduate perf scaling guards into a blocking CI job
- chore(quality): ratchet fallow baseline down after run-2 refactors
- refactor(chat): decompose InputController.sendMessage send path
- refactor(claude): decompose transformSDKMessage stream dispatch
- feat(quality): drop the provider->features boundary allowance
- refactor(settings): move shared settings-UI helpers out of features
- chore(quality): ratchet fallow baseline down to lock in refactor gains
- refactor(quality): decompose chat rendering and subagent-result hotspots
- refactor(quality): decompose provider history and agent parsing hotspots
- refactor(quality): decompose env path and secret-migration hotspots
- feat(quality): gate cycles and architecture boundaries in the fallow ratchet
- docs: add Obsidian plugin design guidelines for design agents
- chore(quality): true up fallow baseline to merged main
- chore(quality): keep fallow ratchet green after merging main
- fix(storage): preserve persisted tab kind through tab-state validation
- fix(mcp): deny remaining non-global IPv6 ranges in SSRF guard
- fix(mcp): vet remote MCP URLs on the runtime activation path
- fix(tasks): count deferred chat leaf slots on startup
- fix(mcp): deny IANA non-global IPv4/IPv6 ranges in SSRF guard
- fix(mcp): deny RFC6598 shared address space (100.64.0.0/10) in SSRF guard
- fix(mcp): deny IPv4-compatible and NAT64 embedded-IPv4 forms in SSRF guard
- Burn down fallow findings: break 4 import cycles, extract 6 clone groups
- chore(ci): align release Node to 22 and reconcile build/perf docs
- test(lifecycle): guard synchronous child-kill on unload and deferred view load
- test(perf): guard Agent Board, run-coordinator, and multi-tab streaming scaling
- feat(mcp): block SSRF for remote MCP connections before any socket opens
- fix(tasks): collision-proof handoff field delimiters with legacy fallback
- refactor(chat): split InputToolbar widgets into ui/toolbar/ modules
- refactor(settings): drive first-run banner from ProviderRegistry metadata
- refactor(cursor): apply code-review fixes to the AskUserQuestion follow-up seam
- Add fallow quality ratchet as a blocking CI gate
- fix(cursor): preserve Git-for-Windows shell env for cursor-agent
- fix(cursor): suppress the answer follow-up when a plan is cancelled/dismissed
- fix(cursor): carry the AskUserQuestion answer into the plan implement turn
- fix(cursor): honor plan Revise over the AskUserQuestion answer follow-up
- fix(cursor): preserve duplicate AskUserQuestion answers in the resume follow-up
- docs(adr): ADR 0002 — Cursor AskUserQuestion transport (resume now, ACP gated on spike)
- fix(cursor): resolve AskUserQuestion ids to prompt text in answer follow-up
- fix(cursor): deliver AskUserQuestion answers via auto-resumed follow-up turn
- fix(cursor): harden Windows runtime, streaming, and model resolution
- chore(ci): ratchet LOC baseline for the Agent Board redesign
- fix(tasks): guard optional work-order callbacks + sanitize renamed title
- style(tasks): zero the native modal padding so the header/footer fill edge-to-edge
- style(tasks): drop unneeded min-height:0 from the native modal-header reset
- style(tasks): drop the "Click title to rename" hint from the work-order modal
- fix(tasks): bulletproof acceptance ring + modal header/footer polish
- fix(tasks): stop hiding the native modal title that now holds the header
- fix(tasks): fix acceptance-ring crash + render the header into the native modal title
- fix(tasks): modal native-content scroll + sticky chrome; card shadow/hover; menu-open cluster
- style(tasks): modal native-style sweep — tame rendered markdown + conformance
- style(tasks): board native-style sweep + conformance polish
- style(tasks): scope + reset native button styling so our design wins
- fix(tasks): keep the modal mobile grid override at matching specificity
- style(tasks): board visual polish to match the design prototype
- fix(tasks): set work-order modal size vars via setCssProps
- fix(tasks): scroll the work-order modal via Obsidian's modal-size variables
- style(tasks): robust modal body scroll + visible card surfaces + subtler add-row
- style(tasks): board scroll bound, native close, datetime format, smoother chrome
- style(tasks): fix work-order modal scroll + semantic action buttons
- docs: polish stale frontmatter, paths, and cross-refs
- docs(tasks): close out the agent-board redesign tracker — all 14 slices done
- a11y(tasks): audit + lock reduced-motion and ARIA across the agent board (redesign slice 14)
- i18n(tasks): key remaining agent-board UI literals across 10 locales (redesign slice 13)
- docs(build-ci): note fallow audit in pre-PR flow
- feat(icons): expand lucide icon picker catalog
- feat(agents): persona seam — Standard built-in + avatar + assignee
- feat(chat): collapse work-order execution prompt in chat
- fix(tasks): avoid double-toggling the Auto-run switch via keyboard
- fix(chat): drain hydration before commit prompt and collapse empty WO slot
- chore(build-ci): add fallow for codebase quality signals
- fix(tasks): fall back for the --color-accent-3 prototype token
- fix(tasks): fall back for the Auto-run OFF track token
- feat(tasks): agent board toolbar + auto-run switch
- fix(tasks): scope live-strip dot pulse to live card statuses
- feat(tasks): restyle agent board card live strip
- docs(product): add audience, TOC, and related links to OD-DoR
- fix(tasks): re-evaluate ⋯ menu items on each open
- fix(tasks): gate Open conversation in the card menu
- fix(tasks): align card menu with run/archive guards + popout viewport
- fix(tasks): exclude live work-order tabs from closable list
- fix(tasks): surface a close affordance for finished work-order tabs
- chore(tasks): clean up portal popover lint warnings
- feat(tasks): card hover action cluster + portal overflow menu
- fix(chat): never strand the user when closing the last chat tab
- ci: trigger checks after re-targeting #60 to main
- test: count backtick provider-id literals in the guard (Codex review)
- fix(chat): keep tab bar visible when an active work-order tab is the only escape
- test: detect object-shaped provider lists in the guard (Codex review)
- docs: list check:loc/check:artifacts commands in CLAUDE.md
- docs: reflect that provider-boundary guards now exist
- test: make built-in provider assertion a subset check (Codex review)
- test: add provider-boundary regression + no-hardcoded-list guards
- fix(tasks): keep the card footer across reply transitions
- docs: defer import-cycle gate to a tech-debt note
- ci: add function-health lint rules as a non-blocking backlog
- fix(tasks): tolerate legacy priority values in card priority bars
- ci: remove interactive Claude Code workflow (dead on this fork)
- ci: remove Claude Code Review workflow
- test: dedupe obsidian mocks behind a single canonical seam
- feat(tasks): rebuild agent board card body
- ci: add agentic quality gates (LOC guard, build, artifact smoke, no-warn lint)
- fix(tasks): reveal owning split and watch vault in activity dropdown
- fix(tasks): keep lane vertical scroll on the container
- fix(tasks): host the add-row on the single inbox-routed lane
- fix(tasks): restore lane vertical scroll + route add-row by inbox status
- fix(tasks): guard activity dropdown against stale refreshes and silent saves
- feat(tasks): borderless agent board lanes + add-work-order row
- feat(tasks): work-order modal sticky footer actions
- fix(tasks): collapse pasted multi-line title to a single line
- docs: mark work-order activity dropdown implemented
- test: align activity provider verification mocks
- feat(ui): localize and style work-order activity dropdown
- feat(tabs): hide work-order tabs from visible badge row
- feat(chat): mount work-order activity dropdown
- feat(chat): add work-order activity dropdown component
- feat(tasks): expose work-order activity provider
- refactor(tasks): allow read-only work-order detail modals
- feat(tasks): summarize active work-order activity
- fix(tasks): make work-order activity summaries readonly
- feat(tasks): add work-order activity contracts
- fix(tasks): sync the body title H1 on work-order rename
- fix(tasks): respect IME composition in the editable title
- fix(tasks): restore modal dialog name + revert rejected empty title
- docs: add product refinement resources
- feat(tasks): work-order modal header with editable title
- docs(issues): track handoff storage heading-collision hardening
- docs: clarify chat and board workflows
- fix(tasks): parse handoff sections by the generated sequence
- feat(tasks): work-order modal activity block
- docs: capture repeatable tech debt review
- fix(tasks): expose checklist checked state to assistive tech
- fix(tasks): fall back to markdown for nested acceptance task-lists
- fix(tasks): render checklist item labels as markdown
- fix(tasks): preserve mixed checkbox + prose acceptance criteria
- fix(tasks): render non-checkbox acceptance criteria as markdown
- feat(tasks): work-order modal objective + acceptance ring
- docs: update idea and plan metadata
- fix(tasks): update value-chip label on selection
- docs: plan semantic ask vault rag layer
- docs: triage shipped issue records
- feat(tasks): work-order modal properties sidebar with value chips
- docs: design semantic ask vault rag layer
- docs: rename Specorator product vision
- docs: add work-order activity dropdown plan
- feat(tasks): migrate work-order modal to sticky-shell frame
- docs(workspaces): add isolation implementation plan
- test(quickActions): restore Modal titleEl + normalizePath in obsidian mocks
- docs: add work-order activity dropdown design
- docs(workspaces): design workspace isolation
- refactor(quickActions): own favorite-block separators in helper
- docs(agent-board): publish redesign issue breakdown + design brief
- rename chat user-manual to sidepanel-chat
- docs(ideas): capture worktree integration + work-order tab dropdown
- fix(quickActions): use Modal titleEl for launch modal heading
- feat(tasks): delete inbox work-order via context menu
- docs(settings): flip overhaul plan + spec to shipped/implemented
- docs: rename Chat to Co-Worker - Chat, rewrite product copy
- docs(settings): refresh registry-port followup audit for 3.5.0 reality
- refactor(settings): rename LEGACY_STRIPPED_SETTING_FIELDS
- refactor(settings): drop vestigial USE_REGISTRY_RENDERER const
- fix(chat,quickactions): suppress auto-turn retry + reject blank quick-action folder
- fix(chat): finalize open thinking block before persisting runtime error
- fix: redact full long bearer tokens + normalize quick-action folder consistently
- fix(chat): persist runtime error cards across reloads
- docs(research): scope plugin command scanner to probe-failure, not cold start
- docs(research): correct dynamic plugin reload — SDK exposes reloadPlugins()
- docs(research): make Tier 2.1 role brief provider-neutral
- docs: sync improvement-proposal + CLAUDE.md to release-hardening package
- docs(research): correct ruflo MCP-from-plugin claim and DAG pre-launch re-check
- docs(research): reconcile Tier 1.1 DAG brief with the section 10.1 design
- docs(issues): mark actionable-runtime-error-states done
- feat(chat): actionable runtime error cards (open settings / retry)
- docs(research): add Worth Deepening section with implementation-ready designs
- docs(research): scope shared memory off MCP for cross-provider reach
- docs: record normalizePath audit table and mark OBS-C done
- fix(paths): normalizePath() on user/agent-constructed vault paths
- docs(research): correct plugin-panel and cost-tracking claims
- docs(research): add ruflo vs Claudian feature-adoption review
- docs: mark audit-innerhtml-rendering done
- security(render): eliminate unsafe innerHTML + add lint guard
- fix(logging): value-level redaction for diagnostics export
- docs: mark codex-spawn-env-allowlist done
- fix(codex): route spawn through subprocess env allowlist
- docs: add release-hardening improvement package handoff
- chore(release): align repo identity to Luis85/claudian
- docs: normalize frontmatter + add feature overview screenshots
- fix(tasks): agent-board polish-pass resolutions
- feat(tabs): split work-order tab budget from chat budget
- docs: update plan frontmatter, add quick-action issue and agent-board lane manual
- i18n(quickActions): launchModal.providerDisabled + untitledFallback
- feat(quickActions): fallback notice uses display labels, re-validate on confirm
- feat(quickActions): launch modal a11y, focus, keyboard handling
- feat(quickActions): CSS for launch modal (rows, actions, notice)
- test(quickActions): favorites menu preserves getFavorites() order
- test(quickActions): non-blank matching-provider override creates new tab
- refactor(quickActions): lowercase stem for case-insensitive preference lookup
- fix(quickActions): override path forces new tab when model differs from active
- test(quickActions): launchQuickAction without store; integration Cancel path
- test(quickActions): store persist-retry, delete, debounce timer, hydrate idempotence
- docs(tasks): mark write-race-fix plan implemented, document sidecar architecture
- feat(tasks): startup sweep of stale sidecar dirs
- fix(quickActions): break circular import by extracting quickActionStem helper
- docs(spec): mark quick-action provider+model prompt implemented
- test(quickActions): extend runQuickActionForFile mock with quickActionStemFromPath
- test(quickActions): integration coverage for launch modal end-to-end
- test(tasks): coverage for missing markers, no-runId recovery, error-swallowing contracts
- feat(quickActions): favorites menu routes through launchQuickAction
- feat(quickActions): picker onRun routes through launchQuickAction
- feat(tasks): live heartbeat in board UI, sidecar GC after snapshot, periodic orphan re-check
- refactor(tasks): dedup heartbeat shape, rename ledger-snapshot helper, share stale threshold
- fix(tasks): RunSidecarStore robust to fresh vault, corrupt JSONL, CRLF, multiline messages
- feat(quickActions): runQuickActionForFile accepts provider+model override
- feat(quickActions): launchQuickAction seam with last-used preset
- feat(quickActions): QuickActionLaunchModal UI
- test(tasks): integration test pinning the no-race-on-note invariant
- fix(tasks): orphan recovery prefers sidecar heartbeat over stale frontmatter
- feat(main): wire QuickActionLastUsedStore lifecycle
- feat(tasks): route AgentBoardView through RunSidecarStore; drop note-bound flushLedger
- refactor(quickActions): align last-used store with VaultFileAdapter + project Logger
- feat(quickActions): QuickActionLastUsedStore with debounced write
- feat(quickActions): serialize/parse helpers for last-used store
- chore(chat): retire WorkOrderHandoffDisplay shim, document splitter semantics
- test(chat): MessageRenderer dispatches and finalizes progress/needs_input/needs_approval cards
- docs(plan): quick-action provider+model prompt implementation plan
- test(chat): WorkOrderProgressCard edge cases (0/0, overrun, full)
- fix(chat): protocol splitter ignores blocks inside fenced code, plus coverage tests
- docs(spec): quick-action provider+model prompt design
- feat(tasks): wire shared RunSidecarStore on plugin load
- fix(chat): protocol-only assistant messages anchor actions to the last card
- feat(tasks): TaskRunCoordinator wires sidecar hooks into RunSession
- refactor(chat): WorkOrderHandoffDisplay re-exports from WorkOrderProtocolDisplay
- refactor(chat): exhaustiveness check on protocol segment dispatcher
- feat(tasks): RunSession routes heartbeat + ledger to sidecar; snapshots to note at terminal
- feat(chat): MessageRenderer dispatches protocol cards alongside handoff
- feat(chat): CSS for work-order protocol cards
- test(chat): WorkOrderNeedsApprovalCard tests title + risk with irreversible
- feat(tasks): TaskNoteStore.writeLedgerSnapshot replaces ledger region atomically
- feat(chat): WorkOrderNeedsApprovalCard renders action + risk + reversible chip
- feat(tasks): RunSidecarStore renders markdown ledger snapshot
- fix(chat): WorkOrderNeedsInputCard preserves empty-string why/default and tests label spans
- feat(chat): WorkOrderNeedsInputCard renders question + optional why/default
- feat(tasks): RunSidecarStore appends + reads JSONL ledger
- feat(chat): WorkOrderProgressCard renders compact step + counter + bar
- feat(tasks): scaffold RunSidecarStore with heartbeat round-trip
- feat(chat): WorkOrderProtocolDisplay splitter for progress/needs_input/needs_approval/handoff
- fix(tasks): emit board-config-changed on lane collapse toggle
- wip: collapsible-lanes feature work + doc updates
- docs: mark archive-context-menu spec implemented, plan done
- docs(plan): mark archive-context-menu plan shipped
- feat(tasks): wire Archive context-menu action through AgentBoardView
- feat(tasks): add Archive item to work-order context menu
- feat(i18n): add tasks.board.contextMenu.archive translations
- fix(chat): keep response footer below handoff card on live finalize
- fix(chat): derive handoff-card content element from text block parent
- docs: mark work-order-handoff-card spec implemented, plan shipped
- chore: sort imports in WorkOrderHandoffCard
- docs(quick-actions): add trailing semicolon to docs-update reminder
- docs(plan): implementation plan for work-order tab budget
- style: add work order handoff chat card
- feat: render work order handoffs as chat cards
- docs(spec): order tab bar chat-first then work-order
- docs(spec): separate tab budget for work-order runs
- feat: add work order handoff card renderer
- feat: split work order handoffs for chat display
- docs: update plan statuses and link parents
- docs: add execute-plan quick action
- fix(tasks): never hijack active tab when opening work-order conversation
- docs: address Codex re-review (card-anchored action visibility)
- docs: add archive action context-menu implementation plan
- docs: add archive action context-menu design spec
- docs: address Codex re-review (durable reopen + stale tab path)
- docs: sync status frontmatter and refresh handoff attachment
- docs: add collapsible Agent Board lanes implementation plan
- docs: address Codex re-review on work-order handoff card plan/spec
- fix(tasks): implicit needs_input pause + wrap card actions
- docs: add collapsible Agent Board lanes design spec
- docs(plan/history-service-contract): sync architecture summary with renamed methods
- docs: align CLAUDE.md doc-location guidance with actual layout
- refactor(core/providers): close history-service contract followups
- docs: refine work-order handoff card plan for minor review nits
- docs: address review on work-order handoff card plan/spec
- docs: remove superseded handoff note
- docs: plan work order handoff chat card
- docs: design work order handoff chat card
Full Changelog: 3.5.0...4.0.0