Markdown 196 lines
<div align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="assets/eeco_logo_dark.png">
<img src="assets/eeco_logo_light.png" alt="eeco" width="280">
</picture>
<h1>Changelog</h1>
<p><i>All notable changes to eeco, release by release.</i></p>
<p>
<a href="README.md"><b>README</b></a> ·
<a href="VISION.md"><b>Vision</b></a> ·
<a href="docs/COCKPIT.md"><b>Cockpit</b></a> ·
<a href="docs/USAGE.md"><b>Usage</b></a> ·
<a href="docs/ARCHITECTURE.md"><b>Architecture</b></a> ·
<a href="docs/PUBLIC_API.md"><b>Public API</b></a> ·
<a href="EXTENDING.md"><b>Extending</b></a> ·
<a href="CONTRIBUTING.md"><b>Contributing</b></a> ·
<a href="docs/UPGRADING.md"><b>Upgrading</b></a> ·
<a href="VERSIONING.md"><b>Versioning</b></a> ·
<b>Changelog</b> ·
<a href="SECURITY.md"><b>Security</b></a>
</p>
</div>
---
All notable changes to eeco are documented in this file.
The format is based on
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/). From v0.1.0
eeco follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
over the surface in [`docs/PUBLIC_API.md`](docs/PUBLIC_API.md), under the
pre-stability caveat of the [versioning policy](VERSIONING.md) §2.1.
## [v0.2.1] - 2026-06-07
### Fixed
- **Cross-platform paths in settings import.** The `eeco config import` /
`eeco init --from` self-import guard and the internal file copy compared
workspace paths by string, which slips on Windows (drive-letter case, 8.3
short names): a self-import was not blocked there, and a `--force`
self-import could truncate `cockpit.json` or workflow files by opening the
same file with `O_TRUNC`. Both now use file identity (`os.SameFile`), and a
copy whose source and destination are the same file is a no-op. No behaviour
change on Linux or macOS.
## [v0.2.0] - 2026-06-07
### Added
- **Cross-project settings — a user-global config layer.** Configuration
now resolves in three layers, each overriding the previous: built-in
defaults → a user-global `config.local` → the per-workspace
`config.local`. The global file lives under `EECO_CONFIG_HOME`, else
`$XDG_CONFIG_HOME/eeco`, else `~/.config/eeco`. Set a key once with
`--global` and every project inherits it unless it overrides the key
locally (the git `--global` model). See
[`docs/USAGE.md`](docs/USAGE.md) §4a.
- **`eeco config` command group.** `eeco config list` shows every key
with its effective value and origin (default | global | local);
`eeco config get <key>` prints one value; `eeco config set [--global]
<key> <value>` writes the workspace (or global) layer, validating the
key and value before writing. This is the first CLI surface for editing
`config.local` (previously only the TUI `/settings` and hand-editing).
- **Global cockpit target set.** `eeco cockpit target --global
list|add|rm` manages a cross-project target set; a project with no
`cockpit.json` of its own inherits it, with the workspace selection
always winning.
- **Import settings from another project.** `eeco init --from <path>` and
`eeco config import [--force] <path>` copy a source project's
`config.local`, cockpit selection, and scaffolded `workflows/` into this
one — a one-shot alternative to the live global layer. Project-specific
knowledge, state, and bug reports never travel; existing files and keys
are preserved unless `--force` is given.
## [v0.1.1] - 2026-06-06
### Fixed
- **Cockpit machinery no longer silently no-ops when launched from
`<repo>/<username>/`.** Repo-root detection walked up and stopped at the
first `.git`, so from inside the private workspace-history repo
(`<username>/.git`, created by `eeco init`) it resolved that nested repo
instead of the project root, leaving the engine workspace unresolved. The
SessionStart briefer/drift, Stop handover-nudge, and PostToolUse
contract-watch hooks then degraded to no-ops in the documented launch
directory (the PreToolUse git-write guard, which fails closed, was
unaffected). Detection now walks past eeco's own private repo to the host
project root.
## [v0.1.0] - 2026-06-06
First public release of eeco as a **provider-agnostic AI-cockpit
generator**: a single, local-first binary that generates and maintains
the config a coding assistant's harness needs to run AI well, plus a
deterministic, no-AI-spend knowledge layer any assistant can read.
eeco does not run AI as a product capability — it authors and maintains
the cockpit the harness runs. The AI lives in the harness eeco
configures; eeco is its author and mechanic. eeco is pre-stability on the
`v0.x` line (see [`VERSIONING.md`](VERSIONING.md) §2.1).
### Added
- **The cockpit generator (`eeco cockpit`) — the headline capability.**
eeco renders a neutral, reviewable playbook library
(`internal/playbooks`) into harness-specific AI config, reversibly and
behind a machine-checked safety invariant. `eeco cockpit generate |
verify | off | status | show` emit and manage the artifacts; `eeco
cockpit target list | add | rm` choose the harness targets (recorded in
`<username>/.eeco/cockpit.json`). Four targets ship: **Claude**
`SKILL.md` (enforced via `allowed-tools`) and the advisory **Cursor**
`.cursor/rules/*.mdc`, **`AGENTS.md`**, and **`GEMINI.md`** (each
carrying a loud `ADVISORY ONLY` banner and an honest fidelity line). The
**safety invariant is uniform across every target**: an emitted artifact
can never grant a write-capable git verb a playbook declares forbidden,
and generation *refuses* rather than silently drop one. Every emit is
reversible (a pre-existing foreign file is backed up and restored on
`off`), sha-gated (a hand-edited artifact is left untouched), and
byte-idempotent. The `cockpit-sync` workflow detects drift (and, at
`automation=auto`, regenerates in place); `eeco cockpit machinery on`
installs the auto-firing deterministic machinery into
`<username>/.claude/settings.json` — a PreToolUse git-write guard
(paired with `eeco authorize commit | tag`), a SessionStart orient/drift
brief, a Stop handover nudge, and a PostToolUse contract-watch — as one
reversible, ledgered unit. See [`docs/COCKPIT.md`](docs/COCKPIT.md).
- **Workspace model.** `eeco init` scaffolds a per-user workspace at
`<repo>/<username>/.eeco/`, detects the project type through a
four-layer pipeline (marker-file scan, conventional-dir scan,
interactive prompt, then an opt-in AI fallback constrained by a bundled
canonical-layouts catalog), and scaffolds project-type-aware knowledge
directories. `init` is the single verb permitted one initial commit and
one initial push, both restricted to the `.gitignore` line that scopes
the workspace out of the tracked tree. Flags: `--type`, `--ai`,
`--username`, `--no-commit`, `--no-push`, `--no-track`.
- **Knowledge layer for AI assistants.** `eeco go` prints a deterministic,
no-AI-spend project brief (with `--json`, `--brief`, `--write`,
`--copy`, and `--metrics`); `eeco ask "<question>"` answers a free-form
question with ranked `file:line` pointers; `eeco add fact` / `eeco add
task` / `eeco add note` write durable memory, queue items, and notes
back; `eeco stats` aggregates the AI-call ledger. The layer is
provider-agnostic — any assistant that can read a file or a clipboard is
briefable.
- **Workflow ecosystem.** Ten builtin workflows — `comment-hygiene`,
`leak-guard`, `version-sync`, `gate`, `bug-sweep`, `handover-refresh`,
`evolve`, `memory-drift`, `doc-drift`, `manifest-refresh` — plus the
pre-1.0 `cockpit-sync` machinery, `eeco new` to scaffold a project
workflow, and `eeco workflows <name> on|off` to toggle one. Findings
land in one Markdown decision queue, never a silent edit.
- **Git integration.** Opt-in, ledgered, byte-for-byte removable hooks —
`pre-commit`, `post-merge`, `session-start`, and `commit-msg` — plus the
cockpit's PreToolUse machinery. The session-start hook briefs an AI
assistant from project state.
- **Manifests and prompts.** `eeco refresh-manifest [<dir>]` regenerates
per-directory `.ai.json` manifests; `eeco show prompt [<name>]` lists or
prints the versioned prompt library.
- **Migration.** `eeco migrate v1 [--yes]` moves a legacy `<repo>/.eeco`
workspace under `<repo>/<username>/.eeco` idempotently — the `v1` names
the workspace-layout generation, not the product version (see
[`docs/UPGRADING.md`](docs/UPGRADING.md)).
- **Private workspace history.** An opt-out, local-only git repository
inside the gitignored workspace versions the knowledge layer over time
(`workspace_history`: `manual` default / `auto` / `off`); `eeco history`
shows, snapshots, and compacts it. It has no remote and never touches
the tracked tree.
- **The AI safety floor.** The one provider path that remains is a
brand-free CLI provider for eeco's own optional chores; `ai_provider` is
`{cli, none}`. Every AI pass is consent-gated, budget-capped, recorded
to `state/ai-calls.json`, and scanned for AI-attribution before anything
is written.
- **Supporting surface.** `eeco gc`, `eeco doctor`, `eeco docs
new|refresh|compact`, `eeco guide`, `eeco show adaptations`, `eeco
adaptations <name> on|off`, `eeco report-bug [--submit]`, `eeco
uninstall`, `eeco update` (cosign-signature + sha256 +
build-provenance verified), and the Bubble Tea control-center TUI.
- **Frozen public surface (pre-1.0).** The CLI commands and flags, config
keys, workflow contract, memory frontmatter, queue and ledger formats,
and builtin workflow names enumerated in
[`docs/PUBLIC_API.md`](docs/PUBLIC_API.md) are eeco's tracked surface. A
`v0.x` MINOR may change it with a migration note ([`VERSIONING.md`](VERSIONING.md)
§2.1); the cockpit surface is documented but not yet frozen
([`docs/COCKPIT.md`](docs/COCKPIT.md)).
[v0.2.1]: https://github.com/ajhahnde/eeco/releases/tag/v0.2.1
[v0.2.0]: https://github.com/ajhahnde/eeco/releases/tag/v0.2.0
[v0.1.1]: https://github.com/ajhahnde/eeco/releases/tag/v0.1.1
[v0.1.0]: https://github.com/ajhahnde/eeco/releases/tag/v0.1.0
---
[← Prev: Versioning](VERSIONING.md) · [Next: Security →](SECURITY.md)