# Changelog

All notable changes to this project will be documented in this file.

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

## [Unreleased]

- No changes yet.

## [0.9.2] - 2026-10-12

### Fixed

- Plugin export retains shared files and directories beside immediate skills. Grouped exports reject shared group resources or conflicting flattened names before writing, instead of silently breaking relative imports.

- Reset uses saved ownership even when previews are missing or corrupt, and reconstructs matching public definitions to clean commit-generated clones safely.

- Antigravity updates its workspace even if legacy global cleanup fails, retaining separate pending legacy ownership for a later retry.

- Disabled Codex, Grok and VS Code hiding leave unrelated malformed configs untouched instead of failing a sync with no managed settings to clean.

- Project MCP ownership uses portable relative paths; moved legacy projects recover ownership only where the saved preview still matches the local config.

- Legacy sync and reset ownership comparisons ignore JSON property order while preserving servers whose values or argument order differ.

- Plugin snapshots exclude local files ignored by Git, including inherited rules, local excludes and links to ignored credentials. Export inventories keep bundles in ignored output directories importable, retain empty runtime directories, exclude later local files and reject changed exported assets.

- Re-exported plugins include their imported runtime snapshots and preserve executable command paths and nested runtime roots, while writable plugin data stays private and is recreated on import, sync or budget.

- MCP add and import preserve reference-only authorization headers such as `Bearer ${TOKEN}` while keeping literal credentials and fallbacks local.

- Automatic update checks start after the command finishes, so optional metadata writes cannot lock out MCP edits or sync.

- HTTP MCP probes consume matching SSE replies incrementally, handling split UTF-8 and multiline events without waiting for the server to close its stream.

- HTTP MCP budget uses one per-server deadline across protocol negotiation, initialization and every tools/list page instead of resetting the timeout for each request.

- HTTP MCP budget honors bearerTokenEnvVar, preserves explicit authorization headers and reports missing or invalid credentials without printing token values.

- Doctor reports missing configs for integrations with selected MCP servers and repairs them with --fix, while allowing absent configs for empty profiles and respecting Claude scope.

- Doctor rechecks managed config syntax after applying fixes, so repaired errors no longer force a failure while unrelated source errors remain visible.

- Runtime MCP tests check only integrations and servers selected by the effective configuration and active profile, leaving unrelated installed CLIs unprobed.

- Runtime MCP tests skip disabled servers, including local overrides, without probing CLIs when no active servers remain.

- MCP test resolves environment, fallback and project-root placeholders before validation while keeping substituted values out of error output.

- MCP import preserves and validates schema 4 auth, timeout and tool restriction fields, including empty allowlists; OAuth client secrets are kept in local overrides.

- Plugin export flattens self-contained grouped skills with resources stored inside each skill and rejects duplicate output names; validation and import count only standard immediate-child skills.

- Plugin export materializes internal skill links portably, retains executable permissions and refuses escaping resources, so its own bundles can be imported after removing their sources.

- Imported stdio plugin servers receive PLUGIN_ROOT and PLUGIN_DATA, with portable, gitignored data storage retained across package updates and recreated by sync or budget after cloning.

- Imported plugin command and cwd paths resolve independently against the installed snapshot, remain portable and reject paths escaping its root.

- Claude local-scope CLI read and write failures fail sync, retain failed-removal ownership and do not advance successful-sync state.

- Claude local-scope sync refreshes changed definitions and credentials even when server names stay the same, storing only definition hashes in ownership state.

- Reset retains comments and disabled settings in Zed and Kilo JSONC files, including after removing the final managed server.

- Failed integration syncs retain legacy previews until ownership adoption succeeds, allowing retries to remove previously generated servers.

- Project MCP sync records every successfully applied target and retains failed cleanup ownership before reporting partial errors, so retries remove stale servers.

- Plugin export rejects literal credentials in separate and inline token arguments unless explicitly allowed, including unsafe placeholder fallbacks.

- Forced template initialization replaces destination symlinks atomically instead of overwriting their external targets.

- Antigravity rejects skill roots and grouping directories that resolve outside the project before dereferencing their contents.

- Update checks lock local.json metadata writes and defer them while configuration changes are in progress, preventing lost MCP secrets.

- MCP add automatically moves secret-looking env and header values into local.json, matching import and the documented security behavior.

- Reset preserves manual servers in project MCP files absent from an existing applied ownership record, including after disconnect.

- Reset uses applied ownership records instead of preview names, preserving same-named manual servers and cleaning previously applied servers after a failed sync.

- Updated transitive `source-map-js` to 1.2.2 to remove its reported high-severity vulnerability.

- Updated transitive `brace-expansion` dependencies to 5.0.12 and 1.1.21 to remove the reported denial-of-service vulnerabilities.

- Plugin import installs scripts and resources under `.agents/plugins` and points portable `${PLUGIN_ROOT}` references to that snapshot. Escaping links are rejected and executable permissions are preserved.

- Watch retries unchanged source files after a failed sync instead of remembering the failed attempt as already applied.

- Sync and `sync --check` fail when an integration config cannot be read or written, after attempting the remaining integrations. Failed runs no longer update the successful-sync timestamp.

- Profile changes, connect/disconnect and plugin import lock the full config update and reload current state after prompts, preventing concurrent edits from being lost.

- Plugin export rejects output paths overlapping `.agents`, including paths through symlinked parents, before writing or deleting source files.

- Disconnect removes managed MCP servers from Gemini, OpenCode, Cursor, VS Code and Junie while preserving manual entries.

- Sync preserves manual MCP entries and settings in Gemini, OpenCode, Cursor, VS Code and Junie, tracking ownership to remove only stale generated servers.

- Safe reset preserves manual MCP servers and settings in Cursor, Antigravity, VS Code and Junie configs, removing only agents-managed entries.

- New OpenCode configs and configs with a missing or empty `$schema` receive `"$schema": "https://opencode.ai/config.json"`. Existing nonempty custom schemas and unrelated settings are preserved. A from-scratch sync previously wrote `{ "mcp": {} }` only.

## [0.9.1] - 2026-09-13

### Added

- Skills reach the seven integrations added in 0.9.0. Grok Build, Factory Droid, Devin CLI, Zed and Goose read `.agents/skills` themselves, so the sync writes nothing for them; Kilo gets a bridge at `.kilo/skills`.
- Grok folder trust. Grok ignores a project's MCP servers and its skills until the folder is trusted, and reports nothing about it. `agents doctor` now says so, `agents doctor --fix` records the trust in `~/.grok/trusted_folders.toml`, and `agents status` shows it next to Codex project trust.
- `agents sync` warns when Zed is enabled and a skill sits inside a grouping directory: Zed only discovers skills that are direct children of the skills root, so a grouped skill is silently missing.
- `agents start` offers to set Grok folder trust during setup, next to the Codex trust step, and `agents doctor --fix-dry-run` lists it among the changes it would make.
- `SECURITY.md`: what this CLI writes outside the project, what it refuses to do, which commands start an MCP server from the project's committed config, and how to report a vulnerability.

### Changed

- `agents mcp budget` speaks MCP `2026-07-28`. That revision removed the `initialize` handshake and the protocol-level session; every request now carries its version, identity and capabilities in `_meta`, and over HTTP in the `MCP-Protocol-Version` and `Mcp-Method` headers. The probe was pinned to `2025-06-18` and opened with a handshake the revision no longer defines.
- The probe detects which revision a server implements the way the specification prescribes for a client that supports both: `server/discover` first on stdio, a modern `tools/list` first over HTTP, and a fall back to the handshake on anything that is not a recognized MCP error. A server answering `UnsupportedProtocolVersionError` is taken at its word and the probe continues with a revision it advertises. A server that answers discovery late, because `npx` was still fetching it, moves the probe back to the modern path instead of failing on the handshake it had already sent.
- `agents mcp budget` follows every page of `tools/list`. A server that paginates its tools was counted by its first page only, which is the wrong number for a command whose whole purpose is the count.
- Skill bridges are declared in one table that the sync, `status`, `start`, `reset` and the gitignore rules all read, instead of five hand-written lists.
- Each integration declares the configuration file it reads in the registry: the path, the format and the label. `agents status`, `agents doctor`, `agents reset` and the setup wizard read that declaration instead of keeping a list each. Four lists of integrations are gone, and the generated previews `doctor` checks now come from the sync hooks. The four integrations whose file depends on an option or the platform (Claude Code, Claude Desktop, Copilot CLI, Windsurf) are still handled where that choice is made, and a test fails if a new integration arrives without either a declaration or a place on that list.
- Amp, Factory Droid, Devin CLI, Goose and Grok Build are marked verified in the README: each tool's own CLI was run against the files this project generates.

### Fixed

- The Windsurf global MCP path honours `AGENTS_HOME_DIR` like every other global path. A run with that variable set used to write into the real home directory.
- In global mode the Kilo skill bridge is a symlink again. Kilo keeps `kilo.jsonc` under the XDG config directory and its skills under the home directory, so the sync created the wrong parent, the symlink failed and it silently fell back to copying the whole skills tree.
- `agents doctor` reports a `.kilo/skills` bridge that is tracked by git, and `--fix` untracks it. The tracked-path list now comes from the same table as the `.gitignore` entries.
- Setting Grok folder trust refuses to touch a `trusted_folders.toml` where `folders` is an inline table, an array of tables or a scalar. Appending a section there produced a duplicate key, which left Grok unable to read its own file.
- `agents reset` removes this project's servers from the global Windsurf config. It never did, and it deleted `.agents/generated` in the same run, so the record of which entries belonged to the project was gone and no later sync could remove them.
- `agents doctor` checks the configuration of every enabled integration. Grok, Amp, Droid, Kilo, Devin, Zed and Goose were never validated, so a file the sync had to skip produced a warning during `sync` and silence plus exit code 0 from `doctor`. `.mcp.json` is now checked in a project that uses Claude Code without Copilot CLI.
- `agents doctor --fix` reports the warnings from the sync it runs instead of discarding them.
- Entries in a config shared by every project carry the project they came from. The global Windsurf config and the Goose config were written with the plain server name, so two projects that both define `fetch` overwrote each other, and `agents reset` in one deleted the entry belonging to the other. Names now take the `agents__<hash>__` form already used for Claude Desktop. The first sync after the upgrade replaces the bare entries this project wrote, recognising them by content rather than by the state file, which a fresh clone does not have; an entry under the same name whose content is different belongs to someone else, stays, and is reported.
- One integration failing no longer ends the sync. A `.cursor/mcp.json` that is a directory used to abort the run with a bare `EISDIR`, leaving every integration after Cursor unwritten; the failure is now reported against the integration that caused it and the rest are written.
- Server validation covers only enabled integrations. A server aimed at a tool the project does not use could stop the whole sync with an invalid env key.
- Values written into a generated config are checked for control characters. A newline in `command` or `cwd` produced a TOML file the tool could not parse, and the integration dropped out of the sync with an error about a file the user never edited.
- The sync warns when it replaces an entry in a shared config that it did not write before. Goose extension names such as `developer`, `memory` or `fetch` collide with MCP server names, and the user's own entry disappeared without a word.
- `agents reset` keeps a comment in `~/.config/goose/config.yaml` when removing the last extension. Deleting the final key rendered the document as empty and the file was removed, comment and all.
- An existing `.claude/skills` (or any bridge) that is a symlink to somewhere else is left alone with a warning, instead of being replaced. The flat Antigravity bridge already behaved this way.
- `agents status` no longer lists Antigravity among the tools that read `.agents/skills` directly. It does not: it gets a flat copy at `.gemini/skills`, which is why that copy exists.
- `agents mcp test` strips terminal escape sequences from values it prints out of `agents.json`.
- `agents plugin import` reports a server whose command is a shell interpreter, which passes the specification's shape check and runs whatever the package put in its arguments.

### Security

- Secrets no longer reach configs that end up in version control, whether they come from `.agents/local.json` or from the environment. A committed config keeps `${VAR}` as it is; `${PROJECT_ROOT}` and an explicit `${VAR:-default}` still resolve, because both are already in the committed file.
- Secrets from `.agents/local.json` no longer reach configs that end up in version control. Amp, Zed and Kilo share a file with the tool's own settings, and Copilot CLI on `.github/mcp.json` writes a file teams review, so this CLI never adds them to `.gitignore`, and it was writing resolved secrets into them, one `git add` away from a published token. Those files now carry the committed definition, placeholders and all, and the sync says which values were held back and which variables to export. In `commit-generated` mode the same rule applies to every generated config.
- Atomic writes keep the permissions of the file they replace. Rewriting a config the user had restricted to `0600`, such as `~/.config/goose/config.yaml` with a key in it, left it world-readable, because the rename replaced the inode with a fresh `0644` file.
- The Antigravity flat copy no longer follows a symlink that leaves the project. A skill linked from elsewhere in the repository still works; a link to a file outside it would have placed a copy of that file inside the project, and the skill is left out with a warning instead.
- The state files in `.agents/generated` name only what this CLI writes. The directory is gitignored but can still arrive in a clone, and its contents decide which files the sync rewrites and which entries `reset` deletes: a path there is now accepted only if it is one of the two project MCP files, and a name only if it carries this project.
- The flat skill copy follows a symlinked directory inside the project when looking for a link that leaves it. A link one level down, behind a directory link, was missed while the copy itself dereferenced both.
- Recording project trust for Codex or folder trust for Grok takes a lock. Both files are shared by every project on the machine and are rewritten whole, so two syncs at once could drop one of the two decisions.
- `agents status` and `agents doctor` report a trust file they cannot read instead of failing on it.
- `AGENTS_HOME_DIR` now covers the update check, Claude Desktop and Antigravity paths, which read the real home directory through `os.homedir()`. A test run wrote its mock version into `~/.agents-dev/update-check.json`, after which the CLI announced an update that does not exist.

## [0.9.0] - 2026-09-12

### Added

- Seven integrations: Grok Build (`.grok/config.toml`), Amp (`.amp/settings.json`), Factory Droid (`.factory/mcp.json`), Kilo (`.kilo/kilo.jsonc`), Devin CLI (`.devin/mcp_config.json`), Zed (`.zed/settings.json`) and Goose (`~/.config/goose/config.yaml`). The CLI now covers 18 tools.
- Integration name aliases: `devin_desktop`, `factory`, `grok_build` and `kilocode` resolve to their canonical ids.
- Agent Plugins 1.0.0 support: `agents plugin export`, `agents plugin validate` and `agents plugin import`. Export builds `plugin.json`, `mcp.json` and `skills/` from `.agents`, reading only the committed config so secrets from `local.json` cannot ship in a package.
- Profiles: `agents profile set|use|list|remove` and `agents sync --profile <name>` apply a named subset of MCP servers.
- `agents mcp budget` connects to each server over MCP, lists its tools and reports how much context they occupy, largest first.
- Schema version 4 for `.agents/agents.json` with `timeout`, `connectTimeout`, `tools`, `disabledTools`, `oauth`, `headersHelper`, `bearerTokenEnvVar` and `envFile` on MCP servers, plus `profiles` and `activeProfile`. Version 3 files migrate automatically and a `.bak` copy of the previous file is kept.
- `${VAR:-default}` expansion in server definitions.
- The sync reports fields a target integration does not support, instead of dropping them silently.
- Copilot CLI can be pointed at `.github/mcp.json` through `integrations.options.copilotCliPath`; Copilot CLI has auto-loaded that file since 1.0.61.
- CI workflow running lint, build and tests on push and pull request across Node 20, 22 and 24.

### Changed

- **Breaking:** Claude Code now writes MCP servers to `.mcp.json` in the repository root, the project scope Anthropic documents for teams, instead of registering them in the machine-local `~/.claude.json` through the `claude` CLI. Whether that file is committed follows `syncMode`: `source-only` gitignores it and each clone regenerates it, `commit-generated` keeps it in review. Projects migrating from schema 3 keep the previous behaviour; new projects can opt back in with `integrations.options.claudeScope = "local"`.
- `.mcp.json` is written once for both Claude Code and Copilot CLI, since both read it. Two consequences are now reported instead of being silent: per-tool targets cannot isolate servers inside that file, and Claude Code on local scope alongside Copilot CLI registers every server twice.
- Codex trust is set by editing the project section of `~/.codex/config.toml` in place. The previous implementation reparsed and reserialized the whole file, discarding comments and ordering.
- Codex output no longer contains `autoApprove`, which is not a documented Codex key, and now emits `startup_timeout_sec`, `tool_timeout_sec` and `bearer_token_env_var`.
- Windsurf is labelled Devin Desktop after the June 2026 rename. Its id and config path are unchanged.
- Skill descriptions may be up to 1024 characters, as the Agent Skills specification allows, instead of 300. Names with consecutive hyphens are rejected, and `license`, `compatibility`, `metadata` and `allowed-tools` are recognised.
- `agents sync` only reports warnings from integrations that are enabled.
- `agents status` shows which integrations read `.agents/skills` directly instead of through a bridge.
- Dependencies updated, including @clack/prompts 1.8, tsx and the typescript-eslint packages. `commander` stays on 14: version 15 requires Node 22.12, and this package supports Node 20.12. `engines` moves to the 20.12 floor `@clack/prompts` already requires.
- Vitest updated to 4.1.11, closing GHSA-82fw-gwwq-j7x9 (path traversal via `@vitest/mocker`) reported by Dependabot.

### Fixed

- Disabling an integration now removes its servers. `agents disconnect --llm codex` left the managed block in `.codex/config.toml`, so the tool kept starting the servers; the same held for every config written through a managed block or key. Files that held nothing but managed entries are deleted, files with user settings keep them.
- `agents reset` removes managed entries from `.mcp.json`, `.github/mcp.json`, `.factory/mcp.json` and `.devin/mcp_config.json` instead of deleting the files, which could contain servers added by hand.
- Sync bookkeeping (`lastSync`, `lastSyncSourceHash`) moved from the committed `.agents/agents.json` to `.agents/generated/sync.state.json`. Every teammate's sync used to produce a diff in a file under version control (issue #6). Existing values are moved on the first sync.
- Configs shared with a tool's own settings (Amp, Zed, Kilo, Droid, Devin) keep entries added by hand: the sync owns only the servers it wrote, tracked per file.
- Zed `settings.json` is parsed as JSONC, so a settings file with comments no longer skips the integration.
- Project MCP files keep their other top-level keys, such as Copilot's `inputs`.
- `agents reset` cleans Kilo files that contain comments and removes Goose extensions it created.
- `agents sync --profile` with an unknown name fails instead of silently syncing every server.
- `agents mcp budget` rejects a non-numeric or non-positive `--timeout`.
- `agents mcp add --url` and `--command` no longer prompt for a transport that the flag already implies.
- Servers whose schema 3 target list named all eleven integrations of that release now reach the integrations added since.
- `agents doctor --fix` no longer runs `git rm --cached` on `.zed/settings.json`, `.amp/settings.json`, `.kilo/kilo.jsonc` or `.github/mcp.json`: those files belong to the tool or the team, and this CLI never adds them to `.gitignore`.
- `agents reset` removes its servers from `.mcp.json` in projects synced by 0.8.x, which have no state file, and deletes a project MCP file that holds nothing.
- `agents status` reads Zed and Kilo settings as JSONC, and reports Grok, Kilo and Goose, which were listed in the probe order but never filled in.
- A profile whose `servers` is not a list is kept in the config instead of being dropped by the next save.
- `agents plugin import` writes `${PROJECT_ROOT}` rather than an absolute path, so an imported server works for everyone who clones the repository.
- `agents profile remove` re-syncs when the profile it removed was the active one.
- `envFile` reaches Cursor's config; it was accepted by the schema and then dropped by every renderer.
- `agents status` counts Claude Code servers under both project-scope and local-scope names, and reports servers waiting for approval.
- `agents status` and `agents doctor` follow `copilotCliPath` instead of always looking at `.mcp.json`.
- A project upgrading from 0.8.x loses servers it disabled after the upgrade, instead of keeping them in `.mcp.json` forever.
- `agents reset` reads and writes Zed and Kilo files as JSONC, so cleanup works and comments survive.
- Settings files that belong to a tool (`.zed/settings.json`, `.amp/settings.json`, `.kilo/kilo.jsonc`, `.github/mcp.json`) are no longer added to `.gitignore`.
- The MCP probe sends `notifications/initialized` before `tools/list` over HTTP, as the specification requires.
- `agents doctor` reports when `~/.codex/config.toml` cannot be parsed, with the parse error, instead of failing silently. Codex ignores every project while that file is broken.
- Setting Codex trust no longer throws on a config with a syntax error elsewhere; the file is left untouched and the reason is reported.
- The `sse` transport is marked deprecated in `agents mcp add` and flagged by `agents doctor`, following the MCP 2026-07-28 specification.
- `agents reset` removes managed entries from Grok, Amp, Zed and Kilo configs while preserving user settings in those files.
- Security advisories in development dependencies (js-yaml, @vitest/mocker) resolved.

## [0.8.11] - 2026-09-04

### Added

- Support for global installation: all CLI commands accept `--global` / `-g` (or running from `$HOME`), syncing MCP servers and skills machine-wide.
- OpenCode global configuration support: when run in global mode, OpenCode config is materialized at `~/.config/opencode/opencode.json` (or `$XDG_CONFIG_HOME/opencode/opencode.json`), preserving non-MCP settings and automatically migrating legacy `~/opencode.json`.
- New CLI command: `agents skills list` (alias `agents skills ls`) to inspect and list discovered skills, paths, and descriptions.
- Automatic tilde expansion (`~` and `~/...`) for CLI `--path` arguments.

### Changed

- `agents doctor` now detects misplaced legacy `~/opencode.json` files and validates global OpenCode configuration paths when run in home directory mode.
- `agents status` labels the OpenCode configuration as `~/.config/opencode/opencode.json` when running in global mode.

### Fixed

- Updated `@humanfs/node` to `0.16.8` to fix path traversal security vulnerability during recursive copies (Dependabot alert #13 / GHSA-p498-v437-472g).

## [0.8.10] - 2026-08-09

### Fixed

- `agents connect --llm antigravity` now re-synchronizes already-enabled integrations and materializes the workspace MCP file at `.agents/mcp_config.json`.
- `agents reset` now removes managed files and skill bridges without deleting unrelated files inside tool configuration directories.
- Sync preserves malformed existing Gemini and OpenCode configuration files instead of replacing them with a fresh generated file.
- Secret overrides in `.agents/local.json` are now written with owner-only permissions on supported filesystems.
- Codex sync now preserves unmanaged project settings and replaces only the agents-managed MCP block, including migration from the legacy fully-generated Codex file.
- Antigravity skill sync now recursively discovers nested `SKILL.md` files and materializes a managed physical flat copy at `.gemini/skills`, with duplicate-name protection and doctor/status diagnostics.
- Legacy Codex migration now preserves user-defined TOML sections after old generated MCP tables.
- Antigravity flat bridge updates are staged, dereference source symlinks, and remove stale managed bridges when skill names collide.
- Safe reset now removes only agents-managed Gemini and OpenCode fields while preserving user settings and manual MCP entries.
- Legacy Codex migration recognizes commented TOML table headers without deleting following user sections.
- Invalid existing Codex TOML now skips only Codex materialization so other enabled integrations still synchronize.
- Antigravity flat bridge comparison now handles shared symlink targets without permanent sync drift.
- `agents doctor --fix` no longer reports stale Antigravity bridge warnings after synchronization.
- Updated Vitest and audited development dependencies to remove known vulnerabilities.

## [0.8.9] - 2026-05-31

### Changed

- Antigravity sync now targets the current Antigravity CLI workspace MCP file (`.agents/mcp_config.json`) using `serverUrl` for remote MCP servers.
- Antigravity integration preflight now checks the `agy` CLI binary instead of the older `antigravity` command name.
- Antigravity-enabled projects now rely on native `.agents/skills` discovery instead of creating a `.gemini/skills` bridge when Gemini itself is not enabled.

### Fixed

- Antigravity sync preserves unmanaged entries in `.agents/mcp_config.json` and removes only this project's previously managed entries when MCP sync is disabled.

## [0.8.8] - 2026-05-17

### Added

- New integration: **Claude Desktop** (`claude_desktop`) — MCP servers synced to Claude Desktop's global `claude_desktop_config.json`.
- New integration: **Copilot CLI** (`copilot_cli`) — MCP servers synced to project `.mcp.json`; `AGENTS.md` and `.agents/skills` are used natively by Copilot CLI.
- New generated artifact: `.agents/generated/claude-desktop.mcp.json`.
- New generated artifact: `.agents/generated/copilot.cli.mcp.json`.
- New `AGENTS_CLAUDE_DESKTOP_CONFIG_PATH` override for custom/testing Claude Desktop config paths.

### Changed

- MCP default targets now include every supported integration, including `claude_desktop`, `copilot_cli`, and `junie`.
- Legacy full-target expansion is now exact-match only so explicit partial target lists are not silently broadened.
- `agents status`, `agents doctor`, and `agents mcp test --runtime` now recognize Claude Desktop, Copilot CLI, and Junie where applicable.
- Gemini HTTP MCP rendering now uses `httpUrl` for Streamable HTTP and keeps `url` for SSE.
- `agents mcp add` and `agents mcp import` no longer pin currently enabled integrations when no `--target` is provided; targetless servers remain universal for future integrations.
- MCP import now accepts common current fields: `httpUrl`, `serverUrl`, and `type: "streamable-http"`.

### Fixed

- Claude Desktop sync now preserves user-owned top-level config and non-agents MCP servers while reconciling only `agents__*` entries.
- Claude Desktop sync is now stdio-only for local JSON and skips HTTP/SSE with a connector guidance warning.
- Disabled Claude Desktop sync no longer touches the real global Desktop config unless this project previously managed Desktop entries.
- Antigravity and Windsurf global sync now preserve unmanaged and other-project MCP entries, use global config locks, and clean up only this project's previously managed entries when disabled.
- `agents reset` now removes this project's managed Claude Desktop MCP entries from the global `claude_desktop_config.json` while preserving manual and other-project entries.
- MCP add/import/remove source writes are now locked to avoid concurrent updates losing `.agents/agents.json` or `.agents/local.json` changes.
- `agents mcp add` now rejects transport-specific fields that would otherwise be dropped, such as headers on stdio servers or env vars on remote servers.
- Docs now distinguish Copilot VS Code from Copilot CLI and use safe token-rotation examples.

## [0.8.7] - 2026-03-22

### Added

- New integration: **Junie** (JetBrains) — MCP servers synced to `.junie/mcp/mcp.json`, skills bridged to `.junie/skills/`.

### Fixed

- Fixed `agents sync` dropping `cwd` from generated MCP configs for all tools (Codex, Gemini, VS Code, Cursor, Copilot, Antigravity, Windsurf, OpenCode, Junie). Closes #11.

## [0.8.6] - 2026-03-07

### Added

- New `agents start --reinit` flag for explicit project config reinitialization from the start flow.
- New `agents start --inject-docs` flag for non-interactive/CI flows to upsert an agents usage guide block into project docs.
- New starter skills in template scaffold:
  - `docs-research`
  - `mcp-troubleshooting`
- New integration coverage for stability fixes:
  - repeated `agents start` preserves existing config by default
  - `agents start --reinit` resets to selected/default setup
  - `syncMode` switch updates managed `.gitignore` entries correctly
  - copy-mode skills bridge drift is detected in `sync --check`
  - watch snapshot traversal tolerates transient filesystem races

### Changed

- `agents connect` is now additive: selected integrations are added to the existing enabled set instead of replacing it.
- `agents sync --check` is now strictly read-only (no lock acquisition, no directory creation, no file writes).
- Startup update notifications are now non-blocking best-effort checks so command execution is not delayed by network calls.
- Sync orchestration now uses integration hooks from `src/integrations/syncHooks.ts` for generated + materialized outputs.
- `agents start` interactive flow now asks whether to add an agents usage section to `README.md`/`CONTRIBUTING.md` and performs idempotent managed-block updates when enabled.
- Template scaffold docs now include a quick workflow section and expanded MCP/skills workflow guidance.
- `agents start` is now non-destructive by default when `.agents/agents.json` already exists (preserves integrations/MCP/workspace config unless `--reinit` is used).
- Managed `.gitignore` handling is now bidirectional across sync modes:
  - `source-only` adds managed source-only ignore entries
  - `commit-generated` removes only managed source-only entries while keeping base-managed and user custom lines
- Documentation/examples now use the correct repeatable `--arg` flag for stdio MCP commands and clarify onboarding behavior around local secrets.

### Fixed

- Fixed Commander wiring for `agents mcp add|import|remove --no-sync` (maps correctly to skip auto-sync).
- `agents watch --once` now sets a non-zero exit code on sync failure and quiet mode no longer suppresses errors.
- `agents watch --quiet` now correctly respects quiet mode for non-error output while still printing sync failures.
- `integrations.options.antigravityGlobalSync=false` now prevents writing Antigravity global MCP output while keeping generated snapshots.
- Disabling `integrations.options.antigravityGlobalSync` now also removes stale previously managed global Antigravity MCP output.
- `updateCheck` now falls back to global cache when project `.agents/local.json` is malformed, instead of overwriting the broken file.
- `updateCheck` now avoids writing stale project-local snapshots when `.agents/local.json` changes or becomes invalid during in-flight checks.
- Startup update checks now use a short best-effort timeout with no retry, avoiding long command shutdown delays on bad networks.
- `validateServerName` now rejects reserved names (`__proto__`, `prototype`, `constructor`).
- `agents mcp test --runtime-timeout-ms` now normalizes invalid values (`NaN`, `<=0`) to a safe default timeout.
- Sync lock now uses owner tokens and PID liveness checks to avoid unsafe stale-lock takeovers and foreign lock removal.
- `.gitignore` managed-entry matching now treats `/entry` and `entry` as equivalent to avoid duplicate managed lines.
- `loadAgentsConfig` now validates `syncMode` and falls back to `source-only` on invalid values.
- `upsertMcpServers` now removes stale local overrides when an update does not provide an override.
- VS Code managed exclude sync now forces managed keys to `true` when they exist as `false`.
- `start` now runs optional cleanup after final confirmation and handles Codex trust TOML parse failures as warnings.
- `start` now automatically reinitializes when an existing `.agents/agents.json` is malformed, instead of failing before setup.
- `CLI_VERSION` now resolves from `package.json` (single source of truth) with a safe fallback.
- Removed `removeIfExists` TOCTOU check and fixed `cleanupManagedBridge` async return clarity.
- Replaced raw verbose sync stdout writes with shared `ui.*` output helpers.
- `sync --check` now reports drift for managed copy-mode skills bridges (`.agents_bridge`) when bridge contents diverge from `.agents/skills`.
- `agents watch` no longer crashes on transient `ENOENT`/`EPERM`/`EACCES` races during snapshot traversal.
- Gemini config materialization warning path now uses sync warning aggregation instead of raw `console.warn`.
- `agents mcp import` output now goes through the shared UI pipeline instead of direct stdout writes.
- `agents update` no longer reports "Up to date" when the npm registry check fails and only stale cached metadata is available.
- Update checks now use a longer default timeout and retry once before falling back to cache, reducing false stale-cache results on slow networks.

### Removed

- Removed unused `LegacyProjectConfig` type.
- Removed unused `loadProjectConfig` / `saveProjectConfig` compatibility aliases.

## [0.8.5] - 2026-03-06

### Fixed

- `agents sync` no longer rewrites `lastSync` after `agents reset` or other output-only regeneration when project source inputs did not change.

## [0.8.4] - 2026-03-06

### Changed

- Project licensing has been switched from MIT to Apache 2.0, and a `NOTICE` file is now included.

### Fixed

- Claude integration now manages a root `CLAUDE.md` wrapper that references canonical `AGENTS.md` without duplicating instructions.
- `agents sync`, `agents status`, `agents doctor`, and `agents reset` now distinguish between agents-managed `CLAUDE.md` wrappers and custom user-owned `CLAUDE.md` files.
- `agents sync` no longer updates `lastSync` on idempotent runs when no managed drift is detected.

## [0.8.3] - 2026-02-18

### Added

- New integrations:
  - **Windsurf** MCP sync to global `~/.codeium/windsurf/mcp_config.json`
  - **OpenCode** MCP sync to project `opencode.json`
- Windsurf skills bridge support via `.windsurf/skills` (linked from `.agents/skills`).
- New renderer support for:
  - Windsurf `mcpServers` payload format
  - OpenCode top-level `mcp` payload with `local`/`remote` server modes
- New tests:
  - `tests/windsurf-opencode.integration.test.ts`
  - expanded renderer, MCP routing, target parsing, status, and reset coverage for new integrations

### Changed

- `agents connect/disconnect --llm` now accepts `windsurf` and `opencode`.
- Default MCP target expansion now includes Windsurf and OpenCode for legacy full target sets.
- Source-only gitignore and VS Code hidden-path defaults now include Windsurf/OpenCode outputs.
- `agents status`, `agents doctor`, `agents reset`, and `agents mcp test --runtime` now recognize Windsurf/OpenCode states.
- Project version bumped to `0.8.3`.

## [0.8.2] - 2026-02-17

### Added

- New `agents update` command:
  - human-readable version check
  - `--json` machine-readable output
  - `--check` exit-code mode (`0` up-to-date, `10` outdated, `1` check failure)
- New release workflow: `.github/workflows/release.yml` (manual publish + GitHub release notes from changelog).
- New test suites:
  - `tests/update-check.test.ts`
  - `tests/update.command.test.ts`

### Changed

- CLI now performs update availability checks before commands and prints a hint when a newer version is available.
- Added global `--no-update-check` flag and `AGENTS_NO_UPDATE_CHECK=1` escape hatch.
- Project version bumped to `0.8.2`.
- Shell command execution now has a default timeout to reduce hangs from external CLIs.

### Fixed

- `sync` no longer probes Claude CLI state when Claude integration is disabled.
- Antigravity MCP sync/status/doctor now use the global Antigravity profile `mcp.json` instead of requiring project-local `.antigravity/mcp.json`.
- `agents status` now reports integration-specific files only for integrations that are enabled.
- Antigravity-enabled projects now keep skills bridged through `.gemini/skills` even when Gemini integration is disabled.
- `tests/real-project-mcp.test.ts` now uses a timeout for Claude CLI probe to avoid hanging test runs.
- Fixed stale docs example that referenced a non-existent `.status` field in `agents status --json` output.

### Removed

- Removed GitHub Actions CI workflow (`.github/workflows/ci.yml`) and CI badge from README.

## [0.8.1] - 2026-02-14

### Fixed

- `agents start` no longer overwrites an existing root `AGENTS.md` during force scaffold refresh.
- `agents init --force` no longer overwrites an existing root `AGENTS.md`.
- Added safety handling for non-regular `AGENTS.md` paths (symlink/directory): scaffold skips overwrite and emits a warning.

### Added

- New integration tests for `AGENTS.md` overwrite protection:
  - `tests/init.integration.test.ts`
  - extended `tests/start-sync.integration.test.ts`

## [0.8.0] - 2026-02-09

### Added

- **New centralized UI module** (`src/core/ui.ts`) providing consistent formatting across all commands:
  - Unicode symbols with ASCII fallback for maximum terminal compatibility (✓ ✗ ⚠ ○ → •)
  - Minimalist color scheme (colors only for status indicators: success/error/warning/info)
  - Context-aware output respecting `--json`, `--quiet`, and `NO_COLOR` environment variable
  - Spinner wrapper for async operations using `@clack/prompts`
  - Layout helpers: `keyValue()`, `list()`, `statusList()`, `arrowList()`, `section()`, `hint()`, `nextSteps()`

- Spinners added to all commands with async operations:
  - `agents doctor` — diagnostics and fix application
  - `agents sync` — configuration syncing
  - `agents init` — project initialization
  - `agents reset` — cleanup operations
  - `agents mcp add` — server addition
  - `agents mcp remove` — server removal
  - `agents mcp test --runtime` — runtime health checks
  - `agents connect` / `agents disconnect` — integration updates

### Changed

- **Unified output formatting** across all 12 commands:
  - Colored status indicators (green ✓ for success, red ✗ for errors, yellow ⚠ for warnings)
  - Consistent key-value alignment in status output
  - Arrow-prefixed lists for changed/updated items
  - Improved visual hierarchy with proper spacing

- **Migrated `connect` and `disconnect` commands** from `prompts` library to `@clack/prompts` for consistent interactive experience.

- **Removed `prompts` dependency** — now using only `@clack/prompts` for all interactive prompts, reducing bundle size and ensuring consistent UX.

- **Improved error output** in CLI entry point with colored error symbol.

- CLI version bumped to `0.8.0`.

### Fixed

- `agents mcp test --json` now correctly sets `process.exitCode = 1` when validation fails.

## [0.7.7] - 2026-02-07

### Added

- `agents status --fast` to skip external CLI probes for quicker status checks.
- `agents doctor --fix-dry-run` to preview automatic fixes without mutating project files.
- Sync lock handling for `.agents/generated/sync.lock` to guard against concurrent sync runs.
- New shell-style argument tokenizer for interactive `agents mcp add` argument input.
- New test suites:
  - `tests/status.command.test.ts`
  - `tests/sync-lock.integration.test.ts`
  - `tests/shell-words.test.ts`

### Changed

- npm package publishing is now stricter and reproducible via:
  - `prepack` build hook
  - explicit `files` whitelist in `package.json`
- CI matrix now validates Node.js `20` and `22` across Linux, macOS, and Windows.
- Interactive `agents mcp add` now parses quoted/escaped args reliably instead of naive whitespace splitting.
- README command reference updated for `status --fast` and `doctor --fix-dry-run`.
- CLI version bumped to `0.7.7`.

### Fixed

- Reduced sync race conditions by introducing project-local sync lock acquisition before writes.
- URL-based MCP import now uses timeout + retry behavior, improving resilience to transient network failures.

## [0.7.6] - 2026-02-05

### Added

- `agents mcp test --runtime` and `--runtime-timeout-ms` for best-effort live MCP health checks via Claude, Gemini, and Cursor CLIs.
- Doctor now validates syntax for generated/materialized configs:
  - TOML: `.agents/generated/codex.config.toml`, `.codex/config.toml`
  - JSON: generated/materialized Gemini/Copilot/Cursor/Antigravity/Claude payloads
- New test suites:
  - `tests/mcp-test-runtime.integration.test.ts`
  - `tests/cursor-sync.integration.test.ts`
  - `tests/doctor.integration.test.ts`
  - `tests/sync-validation.integration.test.ts`

### Changed

- Codex renderer now includes URL-based MCP servers (`http` and legacy `sse`) instead of skipping non-stdio servers.
- Codex TOML output now quotes env/header keys safely and writes HTTP headers under `http_headers`.
- `agents mcp test` output now includes runtime details when `--runtime` is used.
- Cursor status parsing recognizes connection failures as an explicit `error` state.
- Cursor auto-approval sync no longer retries enable loops for `unknown/error` runtime statuses, improving idempotency.
- CLI version bumped to `0.7.6`.

### Fixed

- Prevented invalid env/header keys from producing broken Codex TOML:
  - fail-fast validation in `mcp add` and `mcp import`
  - fail-fast validation during `agents sync` for existing bad configs
- `agents doctor` now reports invalid MCP env/header keys as errors.
- Eliminated repeated `cursor-local-approval` drift in `agents sync --check` when Cursor reports persistent connection errors.

## [0.7.5] - 2026-02-05

### Fixed

- Resolved stale Claude MCP leftovers (`agents__*`) surviving across reset/start cycles.
- Sync now reconciles with actual `claude mcp list` managed entries before applying changes, so orphaned servers are removed automatically.

### Added

- New Claude CLI parser utility:
  - `src/core/claudeCli.ts`
- New tests:
  - `tests/claude-cli.test.ts`

### Changed

- Increased timeout for MCP commands integration test to stabilize environments where local CLI probes are slower.
- CLI version bumped to `0.7.5`.

## [0.7.4] - 2026-02-05

### Fixed

- `agents mcp add https://mcpservers.org/servers/appcontext-dev` now imports successfully.
- Import parser now handles MCP snippets provided as plain `<pre><code>...</code></pre>` blocks without a `language-json` class.

### Added

- Import payload support for direct name->server maps:
  - `{ "appcontext": { "url": "http://localhost:7777/sse", "type": "sse" } }`

### Changed

- `parseImportedServers` error/help text now documents the plain map payload shape.
- CLI version bumped to `0.7.4`.

## [0.7.3] - 2026-02-05

### Fixed

- Resolved a regression where `agents mcp add/import` could fail during sync with:
  - `Invalid environment variable value ... contains potentially dangerous characters`
- Placeholder values like `${GITHUB_TOKEN}` and real API keys containing punctuation now sync correctly to CLI integrations.
- Validation now blocks only control characters (the command runner uses `spawnSync` without a shell).

### Added

- New tests for MCP env/header validation behavior:
  - `tests/mcp-validation.test.ts`

### Changed

- CLI version bumped to `0.7.3`.

## [0.7.2] - 2026-02-05

### Added

- Interactive secret prompt during MCP import for template token/key values (for example `${GITHUB_TOKEN}`, `ghp_xxxx`):
  - asks immediately during `agents mcp import` / URL-driven `agents mcp add`
  - accepts Enter to skip and configure later
  - keeps placeholders in `.agents/agents.json`
  - stores only provided values in `.agents/local.json`

### Changed

- `splitServerSecrets` now supports placeholder-only secret keys/indexes without forcing local secret values.
- README clarifies Antigravity CLI naming (`antigravity`) and the new import-time secret prompt flow.
- CLI version bumped to `0.7.2`.

## [0.7.1] - 2026-02-05

### Added

- URL import fallback for `mcpservers.org` pages without JSON snippets:
  - detects linked GitHub repo
  - fetches README
  - extracts MCP JSON/JSONC code blocks automatically

### Changed

- `agents mcp import --file` now gives a clear validation error when a URL is passed (`--file` is local path only, use `--url` for websites).
- URL import error message now points users to the correct flows (`--url` for JSON pages, or explicit `--json` / `--file` snippets).

### Fixed

- `agents mcp add <mcpservers-url>` now works for pages like `cameroncooke/xcodebuildmcp` that previously failed extraction with “Could not extract MCP JSON payload from URL”.

## [0.7.0] - 2026-02-05

### Added

- `agents status --verbose` for full files/probes breakdown while default output is compact.
- `agents mcp doctor` alias for `agents mcp test`.
- New Cursor CLI parser helper (`src/core/cursorCli.ts`) for robust MCP status parsing.

### Changed

- CLI version bumped to `0.7.0`.
- `agents start` preflight now shows only actionable warnings (missing tools), reducing setup noise.
- Warning output across commands is now compacted and deduplicated.
- Cursor sync now self-heals approval drift: it checks `cursor-agent mcp list` and re-enables non-ready servers.
- Antigravity payload now includes both `servers` and `mcpServers` for compatibility.
- Status probe output is more reliable for Cursor (handles terminal control sequences correctly).

### Fixed

- Claude MCP sync no longer emits repeated "already exists in local config" warnings for already-managed servers.

## [0.6.0] - 2026-02-05

### Added

- New `agents mcp` toolkit for project-local MCP lifecycle:
  - `agents mcp list`
  - `agents mcp add`
  - `agents mcp import` (strict JSON/JSONC from file/inline/stdin/URL)
  - `agents mcp remove`
  - `agents mcp test`
- New MCP core helpers:
  - `src/core/mcpValidation.ts`
  - `src/core/mcpCrud.ts`
  - `src/core/mcpImport.ts`
  - `src/core/mcpSecrets.ts`
- New MCP-focused test suites:
  - `tests/mcp-import.test.ts`
  - `tests/mcp-crud.test.ts`
  - `tests/mcp-secrets.test.ts`
  - `tests/mcp-commands.integration.test.ts`
  - `tests/mcp-test.integration.test.ts`

### Changed

- CLI version bumped to `0.6.0`
- `agents mcp add <https://...>` now auto-detects URL input and delegates to import flow
- `agents status` now includes MCP totals and local override counts
- `agents doctor` now warns about unresolved MCP placeholders and likely secret literals in `.agents/agents.json`
- Sync security checks now reuse shared MCP validation helpers

## [0.5.0] - 2026-02-05

### Added

- New compact `.agents` format:
  - `.agents/agents.json`
  - `.agents/local.json`
  - `.agents/skills/*/SKILL.md`
  - `.agents/generated/*`
- Managed VS Code hiding for tool directories via `.vscode/settings.json` (JSONC merge)
- VS Code settings state tracking in `.agents/generated/vscode.settings.state.json`
- New test suite: `tests/vscode-settings.test.ts`

### Changed

- Root `AGENTS.md` is now canonical
- MCP registry is now project-local (no global catalog dependency)
- `agents start` simplified to project-local setup defaults
- Skills bridges now include Gemini (`.gemini/skills`) in addition to Claude and Cursor

### Removed

- `.agents/project.json`
- `.agents/mcp/selection.json`
- `.agents/mcp/local.json`
- `.agents/AGENTS.md`
- Global catalog/preset flow

## [0.4.1] - 2026-02-05

### Fixed

- **CRITICAL**: Fixed `namesToRemove` bug in Claude MCP sync ([src/core/sync.ts:277](src/core/sync.ts#L277))
  - Previously used `union` of current and desired servers instead of `difference`
  - This caused ALL servers (both current and desired) to be removed and re-added
  - Now correctly removes only servers that exist in current but not in desired

- **CRITICAL**: Added error handling for `JSON.parse` operations
  - [src/core/fs.ts:25](src/core/fs.ts#L25): Now provides helpful error messages when JSON parsing fails
  - [src/core/sync.ts:194](src/core/sync.ts#L194): Added handling for empty/invalid generated configs
  - [src/core/sync.ts:198-202](src/core/sync.ts#L198): Now warns about corrupted files instead of silently ignoring them

### Security

- Added server name validation to prevent command injection attacks
  - Server names must only contain alphanumeric characters, hyphens, underscores, colons, and dots
  - Prevents path traversal attempts with `..`
  - Applied to both Claude and Cursor sync operations

- Added environment variable and header value validation
  - Validates values in `addClaudeServer` before using them in CLI commands
  - Rejects values containing shell metacharacters: `` ` $ \ ; | & < > ( ) { } [ ] ! ``
  - Rejects values containing control characters

### Added

- New test suite: `tests/validation.test.ts`
  - Tests JSON parsing error handling with invalid and empty JSON files

- New test suite: `tests/real-project-mcp.test.ts`
  - Validates real MCP configuration (dogfooding)
  - Checks for `.claude` directory and settings
  - Queries `claude mcp list` to verify agents-managed servers
  - Provides informational output about project MCP status
  - Helps catch configuration drift and ensures tests run against real-world setups

- Added 10 new tests (total: 24 tests, up from 14)

### Changed

- Improved error messages for JSON parsing failures
  - Now includes file path and specific parse error
  - Distinguishes between file-not-found and corrupted file errors

## [0.4.0] - 2026-02-04

### Added

- Cursor and Antigravity support
- Complete onboarding with sync hub
- Trust flow for Codex

### Changed

- Bootstrap v1 with multi-tool MCP sync
- Improved integration handling

## [Earlier versions]

See git history for changes before 0.4.0.
