3.0 KiB
Changelog
1.4.1
Fixed — baked credentials now win unconditionally
A per-user baked artifact could still be prompted for credentials on install. The
baked DEFAULT_* tier was lowest priority, so a stale ECHO_* env var or a
leftover/placeholder ~/.claude/echo-memory/config.json shadowed the baked key —
even an unedited "<placeholder>" value won over it, flipping is_configured() to
false and triggering the first-run "ask the operator" flow despite valid baked creds.
echo_config.load()now treats a complete baked set (endpoint + key both present) as authoritative: it wins over env vars and the config file and cannot be shadowed. The generic (unbaked) plugin keeps its env → file → first-run flow.- Added
baked_complete();source()reportsbaked-in (plugin)for that tier.
Security — untracked leaked baked artifacts
- Two labeled baked artifacts (
echo-memory-1.4.0-jason.plugin,echo-memory-1.4.0-gretchen.plugin), each carrying a live vault bearer token, had been committed at the repo root. They are nowgit rm --cached-removed and.gitignoregainsecho-memory-*-*.pluginso labeled builds can't be re-committed (the version-only pointerecho-memory.pluginandecho-memory-<ver>.pluginstay tracked). Tokens remain in prior history — rotate if the repo was ever shared.
1.4.0
Added — per-user baked-key builds (CoWork zero-touch)
The plugin is the only thing reliably mounted into a CoWork session (the sandbox's
~/.claude is synthetic, not your real one), so the config now can travel inside
the artifact. echo_config gains a lowest-priority fallback tier — the
DEFAULT_OWNER / DEFAULT_BASE / DEFAULT_KEY constants — empty in source, so
the committed tree still ships zero credentials.
build.py --bake-key --from <config.json> [--label <name>]substitutes a single user's owner/endpoint/key into those constants, producing a per-user artifact that needs no config file and no per-session paste. Values may also come from--owner/--endpoint/--keyorECHO_OWNER/ECHO_BASE/ECHO_KEY.- Baked builds default to
dist/(gitignored) and never touch the sharedecho-memory.pluginpointer. build.py --strip-keynow force-blanks the same constants (guaranteed token-free).config show/doctorreport[baked-in default]when a field resolves from the baked tier.
Changed — artifact hygiene
.gitignoreexcludesdist/and the filled-inecho-memory.config.json, where baked builds and the key file are meant to live. A baked artifact carries a vault key and must be delivered directly to that one user, never committed, pushed, or published. (Note: labeled baked artifacts built at the repo root were not yet guarded — see 1.4.1.)
Resolution order (unchanged for hosts)
env → $ECHO_CONFIG file → canonical ~/.claude/echo-memory/config.json →
baked DEFAULT_*. On a normal desktop the empty defaults mean behaviour is
identical to 1.3.x; the baked tier only matters in per-user artifacts.