github Gentleman-Programming/engram v1.16.0

latest releases: v1.20.0, v1.19.0, pi-v0.1.10...
one month ago

Engram v1.16.0 lands a broad, high-impact wave of fixes and features: opt-in HTTP auth and constant-time token comparisons, new CLI delete sub-commands, a TUI clipboard shortcut, cross-project personal search, case-insensitive legacy project matching, a cloud allowlist wildcard, Pi setup hardening, and a wholesale docs refresh. Multiple external contributors and issue reporters drove this release.

Highlights

Security

  • Optional local auth for destructive HTTP endpoints (ENGRAM_HTTP_TOKEN): when set, DELETE /sessions/{id}, DELETE /observations/{id}, DELETE /prompts/{id}, GET /export, POST /import, and POST /projects/migrate require Authorization: Bearer <token>. Unset = open (zero-config preserved). Constant-time compare via hmac.Equal.
  • Constant-time token comparisons: bearer and admin token checks in internal/cloud/auth and cloudserver use hmac.Equal instead of ==/!=, eliminating the timing-oracle.
  • Obsidian exporter path traversal: internal/obsidian/exporter.go sanitizes project and type components before filepath.Join and adds a post-join containment check, rejecting any path that escapes the export root.

CLI

  • engram delete now supports sub-commands: delete observation <id>, delete session <id>, delete prompt <id>, and delete project <name>. All accept --hard. The legacy engram delete <obs_id> form still works.
  • store.DeleteProject atomic cascade: orphans memory_relations, removes observations (soft or hard), prompts, and sessions (hard only — the FK constraint blocks session removal while soft-deleted observations still reference them).

TUI

  • c keybinding copies the highlighted observation to the clipboard via OSC 52 on Recent Observations, Search Results, Observation Detail, and Session Detail. Works over SSH, no system deps.

Search and scopes

  • mem_search accepts all_projects: true to search every project at once instead of the resolved one.
  • scope=personal without an explicit project now searches personal observations across all projects (mem_search, mem_context).
  • global is a valid scope alongside project and personal (was silently coerced to project).
  • Legacy mixed-case project data is now searchable: store queries use LOWER(project) = ? so observations stored as Ebook2Audio are found when queried as ebook2audio — the MCP path normalizes; the CLI was the only path that happened to work before.
  • Configurable timestamp display: ENGRAM_TIMEZONE sets the display timezone for the TUI and the cloud dashboard. Falls back to system local; UTC is preserved in storage.

Cloud

  • ENGRAM_CLOUD_ALLOWED_PROJECTS accepts * to allow every project (per-project enforcement bypassed). Useful for dev and internal deploys.
  • sync --cloud sends the Authorization header when only cloud.json carries the token: resolveCloudRuntimeConfig no longer zeroes the file token before reading the env var.
  • cloud status detects a dead local daemon with a 1-second probe and prints actionable guidance; the launchd unit template is documented.

MCP

  • handleSessionSummary hardened: it now respects the process-level project override (ENGRAM_PROJECT / engram mcp --project) consistent with every other write tool, and rejects empty or whitespace-only content before AddObservation. This fixes stuck sync_mutation rows that blocked cloud upgrade.

Windows

  • CLAUDE_PLUGIN_ROOT is escape-quoted in every hooks.json command entry, so all Claude Code hooks fire on profile paths containing spaces (e.g. C:\Users\John Doe\...).

Pi

  • engram setup pi pins npmCommand to a mise-stable form (["mise","exec","node@X.Y.Z","--","npm"]) when mise is detected and no command is configured, preventing duplicate installs when Node drifts. Existing values are preserved.
  • Pi status bar maps ambiguous_project to an actionable label instead of the generic error.

Docs

  • Wholesale sync: the DOCS.md environment-variables table went from 3 to 17 rows; printUsage() env block synced with code; CLI reference tables in README.md and docs/ARCHITECTURE.md now include doctor, conflicts, delete, and projects prune; Codex troubleshooting for "MCP Transport closed" was added; the new ENGRAM_HTTP_TOKEN, ENGRAM_TIMEZONE, scope=personal cross-project behavior, global scope, * cloud wildcard, and Pi npmCommand pinning are all documented.

Contribution highlights

Thanks to the external contributors and issue reporters who shaped this release:

  • @carlosmoradev shipped #408 (all_projects flag for mem_search), #346 (configurable timezone), and #410 (install-from-source version-stamp docs).
  • @jlsevillano shipped #337 (dead-daemon detection in cloud status and launchd documentation).
  • Issue reports that drove targeted fixes: #180 (Obsidian path traversal), #200 (HTTP auth), #350 (constant-time compare), #260 (cloud wildcard), #146 (MCP search empty for legacy data), #391 (personal-scope filter), #403, #413, #393 (handleSessionSummary gaps), #122 (global scope), #343 (sync --cloud auth header), #209, #218, #219 (CLI delete), #141 (TUI copy), #420 (Windows hooks quoting), #385 (Pi npmCommand), #384 (Pi status bar), #167 (Codex docs).

Pi companion notes

No new gentle-engram npm package was published in this release. The current Pi companion remains gentle-engram@0.1.7; this release updates the main Engram binary, the Pi setup logic in engram setup pi, and the Pi documentation.

Changelog

  • #443 docs(codex): add troubleshooting for MCP Transport closed error (closes #167)
  • #442 fix(plugin): quote CLAUDE_PLUGIN_ROOT in hooks for paths with spaces (closes #420)
  • #441 feat(store,cli): cascade DeleteProject + engram delete session|prompt|project (closes #218, #219)
  • #439 fix(pi): show actionable status for ambiguous project errors (closes #384)
  • #436 docs: bring docs up to date with recently merged features (closes #435)
  • #434 feat(cli): add engram delete command to remove observations (closes #209)
  • #433 feat(tui): add clipboard copy keybinding via OSC 52 (closes #141)
  • #432 fix(pi): pin npmCommand to stable mise node spec (closes #385)
  • #431 feat(cloud): wildcard support for ENGRAM_CLOUD_ALLOWED_PROJECTS (closes #260)
  • #430 fix(cloud): fall back to cloud.json token when ENGRAM_CLOUD_TOKEN is unset (closes #343)
  • #429 security(server): add optional local auth for destructive HTTP endpoints (closes #200)
  • #428 fix(store): handle global scope in normalizeScope (closes #122)
  • #427 fix(store): use case-insensitive project filter for legacy mixed-case data (closes #146)
  • #426 fix(security): replace timing-unsafe token comparisons with hmac.Equal (closes #350)
  • #425 fix(mcp): skip project filter for scope=personal with no explicit project (closes #391)
  • #424 fix(mcp): harden handleSessionSummary process override and empty-content guard (closes #403, #413, #393)
  • #423 fix(obsidian): prevent path traversal in exporter file path construction (closes #180)
  • #410 docs: clarify version stamp PATH gotcha and Claude Code schema error (closes #67)
  • #408 feat(mcp): add all_projects flag to mem_search (closes #303)
  • #346 feat(timeutil): support configurable timezone for timestamp display (closes #169)
  • #337 feat(cloud): detect dead local daemon in cloud status and document launchd unit (closes #279)

Don't miss a new engram release

NewReleases is sending notifications on new releases.