Skip to content

Releases: fstamatelopoulos/cerefox

v0.11.1

13 Jun 01:24

Choose a tag to compare

Fixed

  • Content updates no longer wipe a document's metadata. Every transport defaulted
    an absent metadata argument to {} and the ingest RPC applied it verbatim — so any
    content update that didn't re-pass the tags (CLI document ingest without
    --metadata, MCP cerefox_ingest, the REST EF, the frozen Python fallback) silently
    cleared the document's metadata. And since metadata is not versioned, the loss was
    unrecoverable. The contract is now NULL = "not provided" → keep existing (create
    uses {}), enforced once in the cerefox_ingest_document RPC; pass {} explicitly
    to deliberately clear. Schema version 0.5.0 → 0.6.0 (RPC-only; run
    cerefox server deploy — v0.11.1 clients sending NULL against a 0.5.0 server would
    fail the NOT NULL constraint on update).
  • CLI parity: cerefox metadata search no longer requires --metadata-filter.
    Like the MCP tool / EF (relaxed in v0.10.x — the CLI was missed), at least one of
    filter / --project-name / --updated-since / --created-since is required;
    --project-name alone lists that project's documents.

v0.11.0

13 Jun 00:00

Choose a tag to compare

Changed — BREAKING

  • Optimistic concurrency control on content updates (design:
    docs/specs/concurrency-control-design.md).
    Updating a document's content (via document_id or update_if_exists) now requires
    expected_content_hash — the content_hash of the version the edit was based on,
    returned by every read surface (cerefox_get_document, cerefox_search,
    cerefox_metadata_search, the REST EFs, cerefox document get / cerefox search,
    and the web edit page). The check is atomic inside the cerefox_ingest_document RPC
    (SELECT … FOR UPDATE), closing the read→embed→write race where two concurrent
    writers silently last-write-wins'd each other. A stale hash fails with a conflict
    (re-read → merge → retry; HTTP 409 on the REST path); a missing hash fails with
    token-required (HTTP 400). last_write_wins: true (CLI --last-write-wins)
    explicitly skips the check and is recorded in the audit log — document ingest-dir
    and guides ingest pass it internally (the filesystem / npm package is their source
    of truth), and the frozen Python fallback declares it to preserve its historical
    behavior. Breaking: pre-v0.11 clients' content updates fail against an upgraded
    server until updated (cerefox self-update); existing GPT Actions need the v2.0.0
    OpenAPI block re-pasted. Creates are unaffected. Schema version 0.4.0 → 0.5.0
    (RPC-only change; ships via cerefox server deploy --schema-only).

Added

  • content_hash returned by all document-shaped reads (MCP tool headers, CLI output,
    REST EF responses, web document API) — the token for the concurrency contract above.
  • CLI flags --expected-content-hash / --last-write-wins on cerefox document ingest.
  • Web edit page detects mid-edit concurrent changes and shows a merge-needed conflict
    error instead of silently overwriting.

Fixed

  • Web edit page could corrupt metadata keys via the key autocomplete. The key
    suggestions embedded the usage count in the option label (status (108)), and
    Mantine's Autocomplete inserts the label into the field on select — so picking a
    suggestion (and saving) stored the literal string status (108) as the metadata key,
    polluting the KB taxonomy (it then showed up in the key list as status (108) (1)).
    The dropdown now shows the count via renderOption ("status · 108 docs" style),
    while only the bare key ever enters the field. The search filter's key Select (which
    was never affected — Select keeps value/label separate) now labels the count as
    "(N docs)" for clarity.

v0.10.4

09 Jun 23:32

Choose a tag to compare

Added

  • cerefox_metadata_search can now list a project's documents — closing a CLI↔MCP
    parity gap (the CLI's cerefox document list --project <name> had no MCP equivalent).
    metadata_filter is now optional: supply project_name (and/or updated_since /
    created_since) alone to list documents by scope, ordered newest-updated first. At
    least one of metadata_filter / project_name / updated_since / created_since is
    still required, so the tool never becomes an unbounded whole-KB dump. Backward
    compatible — existing non-empty-filter callers are unaffected. The twin
    cerefox-metadata-search Edge Function and the GPT Actions OpenAPI block
    (info.version → 1.9.0) were relaxed in lockstep. A new CLI ↔ MCP parity matrix in
    docs/guides/cli.md documents the full surface and the remaining
    (intentional vs. actionable) gaps.
  • cerefox document set-projects <document-id> [names…] — new CLI command
    closing the reverse parity gap (the cerefox_set_document_projects MCP tool
    had no CLI form). Full-set replace of a document's project memberships
    (--clear removes all); created-if-missing, case-insensitively de-duplicated,
    logged as an update-metadata audit entry. Shares the membership-replace core
    with the MCP tool (_shared/mcp-tools/_projects.ts → replaceDocumentProjects)
    so both behave identically.

v0.10.3

06 Jun 08:05

Choose a tag to compare

Fixed

  • cerefox server deploy Edge Functions now deploy via the Supabase Management API
    (--use-api)
    instead of the local Docker bundler. The Docker bundler bind-mounts the
    function source dir, which fails (entrypoint path does not exist) when the npm package
    is installed under a path Docker Desktop won't file-share — notably /usr/local (the
    classic Homebrew/npm config set prefix /usr/local location) — and Docker Desktop is
    running. The API path is Docker-independent, so the deploy works regardless of where npm
    placed the package or whether Docker is up. (Thanks @tdebasis#84.)

v0.10.2

06 Jun 04:08

Choose a tag to compare

Fixed

  • Web search now actually applies CEREFOX_MIN_SEARCH_SCORE. The v0.10.1 fix was
    incomplete: the web UI defaults to docs mode, but only the hybrid branch in
    discovery.ts was updated — the docs branch still passed p_min_score: 0.0 (a
    replace_all missed it due to a different indent). The default web search therefore
    applied no threshold. Both branches now use getMinSearchScore(). (Note: in hybrid/docs,
    the threshold filters vector-only matches; FTS keyword matches still pass by design.)
  • CLI honors CEREFOX_MAX_RESPONSE_BYTES. The CLI enforces a response byte budget
    (--max-bytes) but ignored the env var; its default now reads
    CEREFOX_MAX_RESPONSE_BYTES (200000 fallback). Corrected CLAUDE.md: the budget applies
    to MCP/EF and the CLI; only the web UI is unlimited.

Security

  • Local container binds to 127.0.0.1 by default (was 0.0.0.0), so a single-user
    self-hosted backend isn't exposed on the LAN. Opt in with CEREFOX_LOCAL_BIND=0.0.0.0.

Docs

  • World-B (local/self-hosted) coverage across the guides: upgrading.md
    (cerefox-local upgrade), operational-cost.md (fully-local scenario — no Supabase/EF
    cost), access-paths.md (in-container PostgREST + docker-exec MCP; token never leaves
    the container), connect-agents.md (cerefox-local configure-agent / cerefox-local mcp).

Added — local backend (World B), continued

  • cerefox-local configure-agent --tool <client> now wires non-Claude clients too
    (Claude Desktop, Cursor, Codex, Gemini), not just Claude Code. It reuses the bundled
    config writers via a one-shot docker run (the bin gains a --local flag that points
    the MCP entry at the cerefox-local mcp shim); Claude Code still goes through
    claude mcp add on the host.
  • Shell completion is program-name aware + auto-installed. cerefox completion <shell>
    emits a script bound to the actual program name, so cerefox-local completion <shell>
    produces a working cerefox-local completion that doesn't clash with the cloud cerefox
    one (functions + bindings namespaced; cloud output unchanged). install-local.sh now
    wires it up host-side (best-effort, idempotent) — generating the script from the
    container and sourcing it from your shell rc, mirroring the cloud installer + printing an
    "exec $shell" hint. (The completion install subcommand itself can't be used for World B
    — proxied into the container, it would write inside it — hence the host-side wiring.)

v0.10.1

05 Jun 23:31

Choose a tag to compare

Fixed — .env overrides dropped in the Python→TS migration

Several documented CEREFOX_* options were silently no-ops in the TS runtime. Each now
has a single default honored consistently by the CLI, MCP, and web — and forwarded into
the local/World-B container:

  • CEREFOX_MIN_SEARCH_SCORE (default 0.5). The web API previously passed 0.0, so
    the web UI surfaced irrelevant low-similarity results; it now matches CLI/MCP.
  • CEREFOX_MAX_RESPONSE_BYTES (MCP/Edge-Function ceiling; web + CLI stay unlimited).
  • CEREFOX_MAX_CHUNK_CHARS / CEREFOX_MIN_CHUNK_CHARS / CEREFOX_VERSION_RETENTION_HOURS
    / CEREFOX_VERSION_CLEANUP_ENABLED
    (ingestion).
  • CEREFOX_BACKUP_DIR (cerefox backup default).
  • OpenAI embedding overrides CEREFOX_OPENAI_BASE_URL / _EMBEDDING_MODEL /
    _EMBEDDING_DIMENSIONS. ⚠ changing model/dimensions is breaking — requires
    cerefox server reindex (DB column is vector(768)); documented loudly.
  • A bun test guard now fails if any .env.example var isn't referenced in the TS source
    (cheap regression guard against future migration drift). .env.example cleaned up:
    removed the no-op CEREFOX_LOG_LEVEL; marked Fireworks as not-yet-implemented in TS.

Changed — local backend (World B) polish

  • install-local.sh auto-selects a free host port (steps +10 past a busy port, and
    past 8000 when a cloud install shares that default) instead of silently colliding.
  • Detect-and-guide when Docker is missing or its daemon is stopped (no auto-install).
  • World-B users can put the CEREFOX_* tuning overrides above in ~/.cerefox/local/.env;
    they're forwarded into the container (apply with cerefox-local init).

Docs

  • README presents cloud vs local as two backend options; trimmed "Project status".
  • Fixed stale items: .docx ingest is supported (mammoth; only PDF dropped); CLI old
    flat verbs are husks (not "removed"); --mode hybrid (not semantic); quickstart
    timing + setup-local.md mis-links; "Python CLI/web" framing.

v0.10.0

05 Jun 22:07

Choose a tag to compare

Local / self-hosted Cerefox backend (new deployment mode — "World B"). Run Cerefox
entirely on your own machine — Postgres + pgvector + PostgREST + cerefox-server in one
Docker container — with no cloud dependency and no Node/Bun on the host. It reuses
the existing schema, RPCs, MCP handlers, web app, and supabase-js data client unchanged
(config-only); cloud (Supabase) deployments are completely unaffected. Cloud and local
are independent worlds — separate installers, separate command names (cerefox vs
cerefox-local).

Added

  • All-in-one Docker image (docker/local/Dockerfile): pgvector + pinned PostgREST +
    the bundled app + the cerefox-local host script, supervised by s6-overlay
    (db-init → postgres/postgrest/cerefox-server). The container self-generates its JWT
    secret on boot and mints the access token internally — the token never leaves the
    container.
    Published multi-arch (amd64+arm64) to ghcr.io/.../cerefox-local by
    .github/workflows/local-image.yml — opt-in via cut_release.ts --docker-publish
    (decoupled from cutting a Release, same policy as the npm publish).
  • One-line local installer (docker/local/install-local.sh, shipped as a Release
    asset): curl -fsSL …/install-local.sh | sh. Docker-only — pulls the image, runs it
    with --restart unless-stopped, waits for readiness, and installs a cerefox-local
    command on PATH. The only host-side secret is OPENAI_API_KEY (in
    ~/.cerefox/local/.env); the cloud ~/.cerefox/.env is never touched.
  • cerefox-local command: host-side lifecycle (init, start/stop/restart,
    upgrade, uninstall [--purge], status, logs, configure-agent) plus a proxy that
    runs every KB verb (search, document, project, mcp, …) inside the container via
    docker exec — so MCP stdio works and the same bundled binary serves the local backend.
    cerefox-local init sets/rotates the OpenAI key after install.
  • CEREFOX_PROG_NAME: the bundled bin presents as cerefox-local in help/usage when
    the shim sets it (one binary, no fork).
  • /rest/v1 reverse-proxy in cerefox-server (registerPostgrestProxy), mounted only
    when CEREFOX_POSTGREST_UPSTREAM is set — so it is inert in cloud. Makes the server
    the single local gateway (UI + /api/v1 + /rest/v1).
  • cut_release.ts now uploads install-local.sh as a Release asset (next to
    install.sh).
  • Version-coupling CI (.github/workflows/version-coupling.yml): runs the read/write
    smoke against the pinned PostgREST so a supabase-js bump that breaks the local stack
    fails CI.

Fixed

  • Local image Help page: bundle the docs + agent guides into the image so /app/help
    renders offline (was "No bundled docs available").

Design: docs/research/local-cerefox-design.md; plan: docs/plan.md (Iteration 30).
Polish deferred to v0.10.1: cerefox-local --help merge, in-bin configure-agent --local for non-Claude clients, and cerefox-local shell completion.

v0.9.11

03 Jun 23:40

Choose a tag to compare

Fixed

  • Web UI analytics now records usage. The /api/v1 web routes never called the
    usage-logging RPC, so the Analytics page stayed empty even with usage tracking
    enabled (only the CLI and MCP tools logged). The web layer now logs search,
    get-document, and ingest operations (access_path = "webapp", fire-and-forget,
    best-effort — never blocks the response). The cerefox_log_usage RPC, config gate,
    and report query were all already correct; this closes the missing call sites.

v0.9.10

02 Jun 02:02

Choose a tag to compare

Installer/upgrade reliability. Client-only — no server deploy.

Fixed

  • Stale-manifest-cache upgradesinstall.sh and cerefox self-update
    now bypass the package manager's cached registry manifest (--no-cache for
    bun, --prefer-online for npm) when installing/upgrading. Previously, if a
    new version was published soon after a prior install, bun could reuse a
    still-"fresh" cached manifest that didn't list the new version — so a
    re-install resolved @latest to the old version (and even an explicit
    @<new> failed with "No version matching"). Forcing a fresh manifest fetch
    makes upgrades deterministic regardless of release cadence.

v0.9.9

02 Jun 01:46

Choose a tag to compare

Document version UX + docs/completion polish. Client-only — no server deploy.

Added

  • View an archived version in place — clicking a version number (or "Open
    this version" in its ⋯ menu) opens that snapshot read-only at
    /document/:id?version=<id>, with a "Previous version: vN" banner and a
    "View current version" link back. In version view the header offers only
    Download and a Protect / Unprotect toggle (the version's
    archive/cleanup-protection flag); Edit, Delete, the review pill, and the
    Chunks tab are hidden.
  • Per-version size in the Versions card — each row now shows
    N chunks · M chars, and the actively-viewed version is highlighted.

Changed

  • cerefox completion install (zsh) now self-bootstraps compinit if no
    completion system has been initialized yet, so cerefox completion registers
    even on a bare shell. It's a no-op when compinit already ran (no double
    init).
  • Quickstart title no longer claims "5 Minutes"; adds a dedicated Step 0:
    Create a Supabase project
    (linking setup-supabase.md) so the prerequisite
    is explicit rather than buried.