ajhahn.de
← eeco
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)