# Changelog

All notable changes to `@rdk-moss/agent` will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- **Background command completion notifications** (Grok TaskCompletionReminder
  parity): when `exec` / `exec_background` finishes after the start result
  returned "still running", Moss injects a system reminder (exit code + output
  tail) on the next model turn and onto the current tool-result batch. Immediate
  exits remain one-shot in the start result (no double notify).
- **Incomplete-todo completion gate** (Grok TodoGate light): multi-item
  `todo_write` checklists with open `pending` / `in_progress` items trigger one
  correction turn if the model reports done early.
- **CLI injects the software-engineering domain prompt by default**: coding is
  the primary CLI workload; the compact `buildSoftwareEngineeringPromptQuick`
  layer is now the stable `domainPrompt`. Robotics engineering guidance remains
  per-turn only when the message (or board connection) signals robotics work.
- **`search_code` `case_sensitive` parameter**: defaults to case-sensitive symbol
  search (Claude Code / Codex Grep parity); set `case_sensitive: false` for
  case-insensitive recall.
- **`search_code` context lines**: defaults to 1 line before/after each match
  (`context_lines`, max 3) so the model can place hits without an extra read.
- **Coding verification completion gate**: when the model edits under a
  fix/implement/refactor intent and never runs `run_tests` / `verify_fix` /
  `exec`, the CLI injects one correction turn before accepting "done".
- **`multi_edit` tool**: apply multiple precise `edit_file`-style replacements
  across one or more files in a single all-or-nothing call (Claude Code
  MultiEdit / Codex multi-hunk parity). Shares resilient matching with
  `edit_file` (line-number strip, trailing-ws, closest-line hints).
- **Coding skills (CC/Codex/SkillHub-aligned)**: builtin
  `verification-before-completion`, `frontend-ui-polish`, `pr-and-ship`, and
  `efficient-coding-loop` — matched into the dynamic prompt when the request
  is a coding/UI/PR/ship task.
- **Per-turn live git status**: oneshot and TUI inject a fresh
  `buildGitStatusSnapshot` into `extraContext` each turn so uncommitted work
  stays visible after the startup environment layer freezes.
- **`ask_user_question` tool** (Claude Code / Grok AskUserQuestion): structured
  multiple-choice (or freeform) questions via the TUI asker; fails closed with
  guidance in non-interactive runs.
- **Codex hierarchical project instructions**: load instruction files along the
  path from git root → `cwd`, prefer `AGENTS.override.md` over `AGENTS.md` in
  the same directory, optionally load `~/.config/moss/AGENTS.md`, and inject the
  hierarchical override policy note (deeper path wins).

### Fixed

- **Live streaming restored for normal turns**: the agent loop previously
  treated any installed `completionGate` as "buffer all assistant text", and
  MossAgent always installs a gate for optional structured-output validation —
  so every coding turn suppressed `message_delta` until end-of-turn. Buffering
  now runs only when structured validation is pending (or the host sets
  `bufferAssistantUntilComplete`).
- **`edit_file` resilience**: strips accidental `read_file` line-number
  prefixes, matches after ignoring trailing whitespace per line, and on miss
  returns closest-line hints so the model can re-target without guessing.
- **Claude FileEdit read-before-edit**: `edit_file` / `multi_edit` require a
  prior `read_file` of the target in the session before surgical edits.
- **`read_file` similar-path suggestion**: on ENOENT, suggests a similarly named
  sibling file (authService ↔ auth-service) instead of a bare not-found.
- **web_search query preprocessing**: Chinese/CJK queries now auto-set the Bing
  `mkt=zh-CN` region parameter (previously defaulted to no region, causing
  Bing to return Western results for Chinese brand names). `site:` operators
  and `OR`/`AND` boolean syntax are stripped before sending to keyless backends
  (Bing/DuckDuckGo HTML endpoints don't support them and return errors/timeouts);
  the extracted `site:` domain is surfaced as a tip suggesting `web_fetch` on
  that URL instead.
- **Project instructions no longer first-file-wins**: `WorkspaceMemory` merges
  all present candidates (`AGENTS.md`, `CLAUDE.md`, `MOSS.md`, …) and walks
  ancestor directories up to the git root so monorepo-root Claude Code rules
  apply in nested workspaces. Previously only the first matching root file
  loaded, so a short `AGENTS.md` could hide a full `CLAUDE.md`.

### Changed

- **Steering rule and tool loop guard no longer falsely claim search results
  were relevant**: `BUILTIN_WEB_SEARCH_VARIATION_RULE` and the tool loop guard
  previously told the model "the first search almost certainly returned the
  relevant results" — a false assumption when the backend returned irrelevant
  results. Both now acknowledge that results may have been irrelevant and
  proactively suggest `web_fetch` on a known URL as an alternative. Steering
  trigger threshold raised from 2 to 3 distinct queries; variation limit raised
  from 4 to 6.
- **web_search tool description** now guides the model to use concise keywords,
  avoid `site:` operators, and try `web_fetch` directly for known brand URLs.
- **Coding autonomy contracts in the compact behavior prompt** (Grok-inspired):
  keep going until the request is fully resolved; short preamble with tool
  calls; same-turn parallel tools; `todo_write` for 3+ steps; background-finish
  notifications; stay until every explicit requirement is verified; prefer
  surgical edits; do not re-read after a successful write tool.
- **CLI tool activity labels**: `todo_write` shows `done/total · active item`;
  `multi_edit` shows file count × edit count.
- **Tool routing hides plan/eval by default**: `plan`, `plan_step`, and `eval`
  are gated like browser/subagent tools — only exposed when the prompt asks
  for planning or evaluation suites — cutting schema noise on ordinary coding
  turns.
- **`exec` output hygiene**: large stdout is head+tail truncated with a re-run
  hint; timeout failures mention `timeout_ms` / `exec_background`.
- **TUI default-mode footer** shows `shift+tab mode` so users discover the
  plan / default / accept-edits cycle without guessing.

### Internal

- **Bundled Bocha search API key**: `web_search` now reads a bundled
  `bundled-search-key.json` (generated at `npm pack` time via
  `prepare-bundled-search-key.mjs`) or falls back to `BOCHA_API_KEY` env var.
  Packaged builds include the key for better Chinese search quality; the source
  repo never contains the key (gitignored, injected at pack time).

## [0.5.1] - 2026-06-30

### Added

- **"Reasoning" activity indicator on the Working line**: reasoning models (e.g.
  `glm-5.2`) can think for tens of seconds before the first visible token. The
  status line now reads `Reasoning (Ns · M thinking chars · esc to interrupt)`
  while the model streams thinking tokens — even when `/thinking` display is off
  — then falls back to `Working`. Previously a long reasoning pause was
  indistinguishable from a freeze.
- **Thinking content visible by default as a collapsible block**: the model's
  reasoning text was hidden unless `/thinking` was run (or `MOSS_SHOW_THINKING=true`),
  and when enabled it streamed as raw `[thinking]` text mixed into the reply.
  Thinking now defaults to on (`MOSS_SHOW_THINKING` defaults on; `=false` disables)
  and renders as a collapsible block above the reply: collapsed shows a one-line
  summary (`○ Reasoning… (N chars)` streaming / `💭 Thinking (N chars) — Ctrl+O
  展开` done); `Ctrl+O` expands the full text in a dim side-ruled block.
  `/thinking` still toggles whether the block is shown.

### Fixed

- **Input text invisible on light terminals**: the OSC 11 background probe
  (`detectTerminalBackgroundMode`) existed but was never called, so the palette
  fell back to the dark theme and input text was nearly invisible on white
  terminals. The TUI now runs the probe before the first frame and applies the
  matching palette. A pinned `MOSS_TUI_THEME=light|dark` still wins.
- **`web_search` no longer cries wolf at startup**: the "no API keys configured"
  notice was logged at `warn` level unconditionally on tool registration. It is
  now demoted to `debug` (keyless search actually works); key guidance appears
  only on an actual search failure.
- **Unhandled promise rejection crash on Node.js v15+**: a global
  `unhandledRejection` handler is now installed at CLI startup. Two
  fire-and-forget call sites (`runGoalContinuation`, PostToolUse hook) were also
  hardened with `.catch()`.
- `fan_out_subagents` errors now include task index, scope, and recovery guidance.
- `generate_structured` rejects schemas missing required fields with a clear
  error and example; `generateSchemaDescription()` recursively expands
  oneOf/anyOf/allOf branches and constraints.
- `create_subagent` with `background=false` now returns turns/toolCalls/elapsed
  metrics (matching background mode).
- `plan review` and `plan status` errors now show structured recovery options
  (fix / skip / cancel) with actionable CLI commands.

### Changed

- **CLI command dispatch**: replaced 22 if-else branches in `main()` with a
  declarative command routing table and explicit initialization phases
  (`CliPhase.None / ConfigOnly / WorkspaceReady / AgentReady`). Config-only
  commands (`setup`, `auth`, `config`, `mcp`, `migrate`, `sessions`) no longer
  load the workspace or agent.
- **Unified provider error parsing**: introduced `ProviderErrorResponse`
  (`{ status, code, message, provider, retryable, retryAfterMs }`) plus
  `createProviderErrorResponse()` / `throwProviderErrorResponse()` helpers.
  `anthropic.ts` and `openai.ts` now use the helpers instead of inline
  `throw new MossError()`, centralizing error detection and retryability.

### Internal

- **Tool module split**: `builtin.ts` (815→~0 lines of tool handlers) split into
  `file-tools.ts`, `patch-tool.ts`, `search-tools.ts`, `tool-helpers.ts`.
  `moss-agent.ts` extracted `moss-agent-helpers.ts`; `tui.ts` extracted
  `tui-utils.ts`. TUI component files renamed to lowercase
  (`StreamingSpinner.ts`→`streaming-spinner.ts`,
  `VirtualList.ts`→`virtual-list.ts`, `useTerminalSize.ts`→`use-terminal-size.ts`).
- **Context management optimizations**: `compaction.ts` uses
  `estimateMessagesChars`/`estimateTokensForText` (was `length/4`,
  underestimating CJK ~2.7×) and `Array.from` for surrogate-pair-safe
  truncation; `pruning.ts` eliminated 2 of 3 full-array scans and removed the
  dead `isToolResultProtected` stub; `session-manager.ts` fixed O(n²)
  filter-in-loop; `output.ts` hoisted `formatErrorResult` to module level.
- **Compaction strategy refactor**: replaced hardcoded if/else dispatch with a
  `CompactionStrategy` interface + `selectCompactionStrategy()` factory.
- **CLI dependency injection (Phase 3)**: `runInteractive` receives injectable
  `CliServices`; `ToolStateManager` extracted (eliminates module-level
  `fileReadState` Map, per AGENTS.md no-module-level-mutable-state rule).
- OSS boundary: removed host-specific product names from `tui.ts` comments.
- `prepare` hook installer now works in submodule environments (`.git` as a
  `gitdir:` pointer).
- Subagent progress output reformatted to multi-line (one metric per line).
- Plan formatting enhanced with blocked-step markers and spacing every 5 steps.
- `cli-working-indicator.spec.mjs` settled at 250ms (was 120ms) to stabilize the
  80ms-tick + 1.5s-threshold timing boundary that made the "shows Reasoning"
  assertion flaky under load.

## [0.5.0] - 2026-06-25

### Added

- **Vision understanding** — built-in image analysis tool for visual inputs.
- **Web browser automation** — Puppeteer-based browser agent for page interaction.
- **Structured output** — schema-constrained JSON output tool for reliable data extraction.
- **Built-in eval framework** — evaluation runner for measuring agent performance.
- **Plan-Execute separation** — dedicated planning tools that decouple strategy from execution.
- **Tool target display** — non-verbose CLI mode now shows what each tool operates on
  (e.g., `reading file hello.ts` instead of `reading file running`).
- New built-in steering rule `BUILTIN_WEB_SEARCH_VARIATION_RULE`
  (`web-search-variation`): detects ≥2 `web_search` calls with different queries
  in one turn and nudges the model to pivot to `web_fetch` on the best existing
  result, stopping the wasteful "rephrase and re-search" loop. Exported from
  `@rdk-moss/agent` and `@rdk-moss/agent/core`.

### Changed

- `web_search` tool description now includes query-efficiency guidance: use one
  targeted query (entity name + result-oriented terms, not a natural-language
  question), trust returned results, and follow up with `web_fetch` on the best
  URL instead of re-searching with synonym variations.
- `web_fetch` tool description now warns against fetching brand/marketing
  homepages (often client-side-rendered SPAs that return an empty shell) —
  prefer a specific article/product/docs URL discovered via `web_search`.
- CLI auto-execution notice is now concise and localized:
  `[moss] 已自动执行 write_file（非交互模式，workspace-write 权限）`
  instead of a verbose English explanation.
- Multi-turn CLI output shows turn numbers:
  `working... (turn 2)` instead of repeating bare `working...`.
- Context checkpoint messages are now user-friendly status lines
  (`⚠️ 任务暂停（可恢复）`) instead of raw LLM-facing `nextAction` text.
- Error messages in non-verbose mode extract friendly summaries
  (e.g., `文件不存在` instead of full ENOENT stack traces).
- Skill-learning candidate notices are now debug-only — no longer
  surface as user-visible `[agent] saved a skill candidate` messages.
- Each `MossAgent` now owns a private `PlatformExtensionRegistry`, removing
  the previous last-agent-wins extension knowledge binding. Deprecated extension
  free functions still target the legacy process singleton and bridge startup
  extension knowledge into future agents.
- `MossAgent.streamChat()` now always delegates to the unified `runAgentLoop` path.
  The legacy inline loop, `MOSS_AGENT_LOOP_LEGACY` rollback switch, and
  `ChatOptions.experimentalUseAgentLoop` test override were removed so there is
  a single authoritative agent loop.

### Deprecated

The following global free functions are now deprecated (since 0.4.0, removal target 1.0).
Migrate to instance methods on `MossAgent` or `KnowledgeRegistry` / `PlatformExtensionRegistry`:

| Deprecated function | Replacement |
|---|---|
| `registerKnowledgeModule(mod)` | `agent.registerKnowledge(mod)` |
| `unregisterKnowledgeModule(id)` | `agent.knowledge.unregister(id)` |
| `getKnowledgeModule(id)` | `agent.knowledge.get(id)` |
| `getAllKnowledgeModules()` | `agent.knowledge.getAll()` |
| `findModuleForPlatform(platform)` | `agent.knowledge.findForPlatform(platform)` |
| `getAllDeviceProfiles()` | `agent.knowledge.getAllDeviceProfiles()` |
| `getAllDocEntries()` | `agent.knowledge.getAllDocEntries()` |
| `getAllPromptFragments()` | `agent.knowledge.getAllPromptFragments()` |
| `getAllCommandPatterns()` | `agent.knowledge.getAllCommandPatterns()` |
| `getAllFailureHints()` | `agent.knowledge.getAllFailureHints()` |
| `getAggregatedEcosystemPrompt()` | `agent.knowledge.getAggregatedEcosystemPrompt()` |
| `setVendorPluginCallbacks(cb)` | `agent.extensions.setVendorPluginCallbacks(cb)` |
| `setKnowledgeRegistryForExtensions(reg)` | `agent.extensions.setKnowledgeRegistry(reg)` |
| `applyPlatformExtension(ext)` | `agent.extensions.apply(ext)` |
| `applyPlatformExtensionForce(ext)` | `agent.extensions.applyForce(ext)` |
| `syncPlatformExtensionsAtStartup(factories)` | `agent.extensions.syncAtStartup(factories)` |
| `getRegisteredPlatformExtensions()` | `agent.extensions.getExtensions()` |

Deprecated functions emit a one-time `log.warn` on first call. The warning includes a stack trace
to help identify call sites that need migration.

### Fixed

- Fatal error handler in `cli-main.ts` now shows a clean message with
  actionable guidance instead of dumping raw stack traces.
- Progress tool labels include `memory_delete` → `deleting memory`.

## [0.3.32] - 2026-06-10

### Changed

- CLI `/goal <condition>` now behaves as an active goal runner: Moss continues
  bounded follow-up turns until the goal is completed, blocked, cleared, or
  stopped, while still letting the user send messages during the run.
- Tool-loop count limits are now opt-in budgets instead of hidden defaults.
  Hosts or users can still set `MOSS_TOOL_LOOP_IDENTICAL_LIMIT`,
  `MOSS_TOOL_LOOP_SINGLE_TOOL_LIMIT`, `MOSS_TOOL_LOOP_TOTAL_LIMIT`,
  `MOSS_TOOL_LOOP_FAILURE_LIMIT`, or per-call `maxToolCalls`.

### Fixed

- `/goal clear`, `/goal pause`, `/goal complete`, and `/goal block` now apply
  immediately while the CLI is busy, so a long goal run can be stopped without
  waiting for the current queue.
- Internal context-repair logs for dangling tool-use/tool-result pairs are
  debug-only instead of ordinary user-visible warnings.

## [0.3.22] - 2026-06-08

### Changed

- CLI help now matches the zero-config experience: the built-in Moss model is
  described as the default path, API keys are documented as optional for custom
  providers, and the package docs link points at the D-Robotics repository.

## [0.3.21] - 2026-06-08

### Fixed

- CLI model selection now behaves like a real picker: `/model` and `/models`
  list selectable models for the active provider, try the provider's
  `/v1/models` endpoint when available, fall back to common model names, and
  support switching with `/model <number>` or `/model <model-name>`.

## [0.3.20] - 2026-06-08

### Fixed

- CLI slash-command surface: `/goal`, `/compact`, `/context`, `/sessions`,
  `/cost`, `/diff`, `/rewind`, `/version`, and related controls are now
  discoverable from the terminal slash menu, readline completion, `/help`, and
  `moss --help` instead of existing only as hidden runtime capabilities.
- `/compact` is wired to the public `compactSession()` runtime path so users can
  manually compress older conversation context from the terminal.

### Changed

- CLI onboarding and docs now describe the built-in D-Robotics model as ready
  without setup or API keys, and present slash commands as action-oriented
  controls rather than feature introductions.

## [0.3.15] - 2026-06-08

### Fixed

- CLI identity prompt wiring: standalone `moss` now actually passes the Moss
  identity layer into the runtime system prompt, so model requests consistently
  identify Moss as an AI Agent developed by 地瓜机器人 (D-Robotics) instead of
  relying on README text or model prior knowledge.

## [0.3.14] - 2026-06-08

### Fixed

- CLI startup no longer crashes under SOCKS or otherwise unsupported proxy
  environment variables before any model request is made. Moss now avoids
  importing the pi-ai runtime during CLI startup paths that do not need it, and
  the keep-alive dispatcher tolerates unsupported proxy protocols.

## [0.3.13] - 2026-06-08

### Fixed

- CLI sessions: a plain `moss` launch now starts a fresh saved session instead
  of reusing the legacy `cli` session and inheriting old conversation history.
  Use `resume --last` or `--session <key>` to continue previous history
  intentionally.

## [0.3.12] - 2026-06-08

### Changed

- CLI identity: Moss now states that it is an AI Agent developed by
  地瓜机器人 (D-Robotics), including the Chinese brand name in the stable
  identity prompt.
- README docs now state the D-Robotics / 地瓜机器人 origin while preserving the
  host-neutral embedding model.

## [0.3.11] - 2026-06-08

### Fixed

- CLI providers: accept API base URLs that already end in `/v1` without
  constructing duplicate `/v1/v1/...` endpoints. This fixes the bundled
  zero-config gateway path used by npm-installed `moss`.

## [0.3.10] - 2026-06-08

### Fixed

- update notice: raise the registry check timeout from 800ms to 3000ms. On slower
  networks (e.g. reaching `registry.npmjs.org` from China, measured ~1.9s) the
  800ms check timed out before it could fetch, so the "a new version is available"
  notice never appeared and the cached latest version went stale. The check stays
  async and the timer is unref'd, so the longer wait never blocks startup or exit.

## [0.3.9] - 2026-06-08

### Added

- Zero-config startup: `moss` works out of the box with a built-in free model.
  Your own provider/key (env vars or `moss setup`) always overrides it. The
  built-in gateway is hidden from `/status`, `/quick_start`, and the welcome panel.
- `/quick_start` now surfaces `AGENTS.md` — the project system-prompt file that is
  auto-loaded every session (scaffold it with `/init`).

### Changed

- The `/quick_start` panel is all-English and explains how to configure the model
  (`moss setup` / env vars / config file) and the workspace.

### Fixed

- skills: validate the candidate id up front in `promoteSkillCandidate`
  (path-traversal hardening; the late `removeCandidate` can no longer be the first
  thing to reject the id after a skill is already written).
- cli provider: throw on malformed OpenAI tool-call arguments instead of silently
  using `{}`.
- async tasks: cancelling a parent no longer enters a still-queued child's runner.
- sub-agent orchestration: `runFanOut` / `runPipeline` enforce `timeoutMs` even when
  a child runner ignores the abort signal.
- `compactSession` returns `{ compacted: false }` for histories that fit within the
  keep-recent window, matching its documented contract.
- providers: accept SSE `data:<payload>` frames without the optional space.
- memory: `syncFromFiles` no longer leaves both the old and new entry when a file's
  content changes.
- `web_search` no longer issues a fetch when its signal is already aborted.
- tool registry: re-registering a tool now updates the group snapshot.

## [0.3.7] - 2026-06-04

### Added

- Added a built-in `web_search` tool that completes the web tool pair with
  `web_fetch` (search → fetch). It is keyless by default (DuckDuckGo HTML
  endpoint), supports a Brave provider via `apiKey`/`BRAVE_API_KEY`, and accepts
  a host-injectable custom backend (`search`) for proprietary or multi-engine
  routing. Registered in `builtinTools` and exported as `createWebSearchTool`,
  `duckDuckGoSearch`, and `createBraveSearch`. Existing scaffolding
  (`NETWORK_TOOLS` guard, subagent scope set, output-truncation limit, and the
  "use `web_search` only when registered" prompt guidance) now activates
  natively without an external backplane.
- Added a `move_file` built-in tool for renaming/reorganizing files and
  directories inside the workspace sandbox (both source and destination are
  sandbox-checked; refuses to clobber without `overwrite`).
- Added `offset`/`limit` line-range paging to `read_file` so large files can be
  read in pages instead of stopping at the 100 KB truncation.
- Added background command tools — `exec_background`, `exec_logs`, `exec_stop` —
  backed by an in-process registry so the agent can start and supervise
  long-running processes (dev servers, watchers, `ros2 launch`) that the
  synchronous `exec` cannot. Group-kill on POSIX; an immediate crash during the
  start window is reported inline.
- Added a `code_diagnostics` tool that runs the project's type/lint checks
  (auto-detected for JS/TS via package.json scripts, local tsc, or local eslint;
  or an explicit `command` for ruff/mypy/cargo/go) and reports pass/fail with
  errors and warnings — the "see type errors and warnings after editing" pillar
  of code intelligence. Go-to-definition / find-references stay a language-server
  concern, intended to be wired through the MCP client (an LSP-MCP server).

#### Standalone session richness (parity with host-embedded runs)

- Added an `# Environment` context layer injected at session start by the
  standalone CLI (`context/environment.ts`): working directory, platform, date,
  a shallow top-level file listing, and git state (branch, uncommitted changes,
  recent commits). Snapshotted once per session, so it is prompt-cache friendly.
  This gives standalone `moss` the git/project awareness the RDK Studio host
  previously provided on its own.
- `WorkspaceMemory` now recognizes a project-level `MOSS.md` (and `Moss.md` /
  `moss.md`) as the standalone analog of `CLAUDE.md` / `AGENTS.md`, loaded into
  the workspace-context prompt layer (leading the section) alongside the existing
  `AGENTS.md` / `USER.md` / `MEMORY.md`.
- Added config-driven hooks (`cli/hooks.ts`, `hooks` in the moss config) to
  automate workflows: `PreToolUse` (a blocking shell command can veto a tool),
  `PostToolUse` (side-effect automation — format/notify/log), and `SessionStart`.
  Hooks compose with — and run before — the existing tool-approval flow. Each
  command receives a JSON payload on stdin plus `MOSS_HOOK_EVENT` /
  `MOSS_TOOL_NAME` / `MOSS_WORKSPACE` env vars, and is matched to tools by an
  optional `matcher` regex.

### Compatibility

- Backward compatible and additive. New tools are registered in `builtinTools`;
  `read_file` behaves exactly as before when `offset`/`limit` are omitted. The
  `web_search` default backend needs no API key, and its tool name + `query`
  input match the contract host UIs already expect.

## [0.3.6] - 2026-06-01

### Added

- Added an effective host tool inventory projection so hosts can distinguish
  declared tools from tools that are hidden, disabled, denied, or not ready for
  the current session.
- Registered `web_fetch` as a built-in read-only CLI evidence tool with metadata
  and root export coverage.

### Changed

- Refined the interactive TUI output path so transcript text remains visible and
  local shell approval copy stays clear about host-only execution.
- Updated built-in prompt and recovery guidance to reference only Web tools that
  are actually available instead of implying `web_search` is always registered.

### Compatibility

- Backward compatible for existing hosts and CLI consumers. New tool metadata and
  inventory fields are additive.

## [0.3.5] - 2026-05-31

### Added

- Added async task registry support for long-running subagent and host task
  workflows.

### Changed

- Updated the agent package to consume `@rdk-moss/core@^0.3.2`.

### Compatibility

- Backward compatible for existing tool and session consumers.

## [0.3.1] - 2026-05-02

### Added

- **`ToolResult.aborted` / tool end `aborted` metadata** — optional `{ by: 'user' | 'timeout' }`
  marker for host UIs to distinguish user-cancelled single-tool runs from normal tool errors.
  Source: `2026-05-01-moss-device-exec-progress`.

### Compatibility

- Backward compatible for consumers: the field is optional and existing callers may ignore it.

## [0.3.0] - 2026-05-02

### Added

- **`MemoryScope`** — fourth tier `'learning'` (personal learning corpus; stored like other scopes,
  excluded from default system-prompt memory injection on the host — see harness task).
- **`MemoryEntry.topic` / `MemoryEntry.starred`** — optional fields for learning-topic slug and starred flag;
  omit/undefined behaves as no topic / not starred on read paths.
- **`LEARNING_TOPIC_SLUGS`** — exported fixed slug list aligned with the host memory UI whitelist.
  Source: **`2026-05-01-memory-learning-scope-add`**.

### Compatibility

- **Backward compatible for consumers**: new scope value and optional fields only; JSON index remains a
  superset; older clients may ignore unknown fields; existing `workspace`/`user`/`device` semantics unchanged.

### Tests

- `packages/moss-agent/test/memory-learning.spec.mjs` — legacy-entry normalization + learning CRUD
  smoke (requires `npm run build` in this package).

## [0.2.2] - 2026-05-02

### Added

- **`ProviderErrorSurface.retryable: boolean`** — required field; only `true`
  for `aborted_by_server` / `rate_limit` / `timeout` / `network` (transient
  categories); `auth` / `quota_exceeded` / `context_corruption` / `unknown` /
  `aborted_by_user` remain `false`. Old callers that ignore the field are
  unaffected at runtime; callers that **construct** surfaces directly need to
  add the field (likely `false` if uncertain).
  Source: `2026-05-01-moss-reliability-fallback-ux` (G-2).
- **`ProviderErrorAction.id: 'useFallbackProvider'`** — new variant in the union
  type; emitted by callers when a user-configured fallback provider is available
  for `auth` / `quota_exceeded` errors. Action is informational only — switching
  always requires explicit user click.
  Source: `2026-05-01-moss-reliability-fallback-ux` (G-3).
- **`ProviderErrorCategory: 'ambiguous'`** — new category for server-side
  `ambiguous_short_circuit` short-circuit decisions, allowing the host to route
  through the same surface + actions pipeline as provider errors.
  Source: `2026-05-01-moss-reliability-fallback-ux` (G-5a).
- **`runWithProviderRetry(fn, opts)`** — new exported helper from
  `@rdk-moss/agent/provider`. Runs `fn`; if first call throws and the classified
  surface is `retryable === true`, sleeps a jittered 800–2000 ms and retries
  exactly **once**. Caller passes a `classify` function (typically
  `classifyProviderError`) and an optional `signal` to abort during the wait.
  - Hard cap: maximum 1 retry (`maxAttempts?: 1`); the type system forbids
    raising it.
  - Eligibility: `aborted_by_server`, `rate_limit`, `timeout`, `network` only.
  - `auth`, `quota_exceeded`, `context_corruption` never auto-retry.
  - Abort-during-wait surfaces the **original** error (not the abort reason),
    so the caller's downstream UX remains accurate.
  Source: `2026-05-01-moss-reliability-fallback-ux` (G-2).
- **Re-exported from `@rdk-moss/agent/provider` root**: `classifyProviderError`,
  `renderProviderErrorSurface`, `sanitizeRawErrorForDetail`, plus types
  `ProviderErrorCategory`, `ProviderErrorAction`, `ProviderErrorSurface`,
  `ProviderErrorInput`. These were previously available only via deep import
  (`./provider/error-classify.js`); the public surface now matches the API.md
  contract for host consumption.
  Source: `2026-05-01-moss-reliability-fallback-ux` (Commit 2 follow-up).

### Compatibility

- All additions are **non-breaking** (additive types, new exports, new helper).
- `renderProviderErrorSurface` behavior is unchanged for backwards compatibility
  with the CLI and Microsoft Teams / 微信 / 飞书 channels. The product host
  consumes the structured surface object directly via SSE error payload + a
  forthcoming `ProviderErrorBlock` for clickable buttons; the markdown text
  rendering remains the fallback for non-rich channels.
- No exports were removed; no signatures changed.

### Tests

- `packages/moss-agent/test/error-classify.spec.mjs` — 7/7 (added retryable
  field semantics on 6 categories).
- `packages/moss-agent/test/runtime-retry.spec.mjs` — new, 6/6 covering
  retry success, non-retryable abort, retry-then-fail throws last error,
  `shouldRetry` override, pre-aborted signal, and abort-during-wait.

## [0.1.0] - 2026-04-14

### Added

- **MossAgent** — central orchestrator with `chat()` (Promise) and `streamChat()` (AsyncGenerator) APIs
- **ToolRegistry** — pluggable tool registration and discovery with groups
- **KnowledgeModule** — pluggable domain knowledge system (device profiles, prompts, failure hints)
- **PlatformExtension** — hardware platform lifecycle management
- **ToolHookRegistry** — pre/post tool execution interceptors (Pre/Post/PostFailure)
- **CompactHookRegistry** — compaction lifecycle hooks
- **ToolPipeline** — JSON Schema input validation + pre-hook chain
- **MemoryManager** — long-term memory with BM25 keyword search
- **MiniAgentEvent** — discriminated union event type system with EventStream
- **Context management** — three-layer pruning, adaptive compaction, token estimation
- **Safety** — dangerous command detection, secret sanitization, configurable protected paths
- **Provider** — error classification (rate limit, timeout, overflow), exponential backoff retry
- **Built-in tools** — `read_file`, `write_file`, `list_directory`, `exec`, `search_files`
- **CLI** — interactive, one-shot, and piped modes
- **Configurable APIs** — `registerProtectedPaths()`, `registerToolOutputLimits()`
- **SessionManager** — JSONL persistence + `InMemorySessionStore`
- **Skills** — SKILL.md scanning and matching via `SkillRegistry`
- **Prompts** — vendor-neutral robotics engineering prompts, telemetry hashing

### Architecture

- Core interfaces and contracts are vendor-neutral (from `@rdk-moss/core`)
- Some utility defaults reference host tool names (e.g. `device_exec`) — configurable via `registerToolOutputLimits()` and `registerProtectedPaths()`
- Formal `@rdk-moss/core` dependency (not relative paths)
- All environment variables use `MOSS_*` prefix
- MIT licensed, ready for independent publication
