Skip to content

Latest commit

 

History

History
1013 lines (805 loc) · 53.6 KB

File metadata and controls

1013 lines (805 loc) · 53.6 KB

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

0.9.7 - 2026-09-28

Fixed

  • Add conventional server and TUI entrypoints so OpenCode 2 loads the plugin when configured as a local package directory, including an installed tarball.

Tests

  • Exercise packed V1 hooks, assets, and TUI loading plus V2 tool schemas and execution; verify real V2 host activation without optional SDK peers.
  • Require runtime dependencies except explicitly host-provided modules, preserve the smoke subprocess's isolated memory root, and check probe exit status.
  • Run the isolated smoke install even when the outer package command is a dry run.

0.9.6 - 2026-09-28

Fixed

  • Install zod with the plugin so V1 tool definitions and V2 tool adapters load in a standalone OpenCode plugin cache. 0.9.5 declared zod as an optional peer that the plugin cache never installs, so loading it failed.

0.9.5 - 2026-09-28

Fixed

  • OpenCode 2 consolidation no longer fails with Permission denied: edit when the global memory home sits inside the session or project directory, such as running OpenCode in the user home. Helper sessions now also allow the session-relative form of their one memory root; external_directory stays absolute and traversal above the root stays denied. Memory remains global. Reported in #7.

0.9.4 - 2026-09-27

Changed

  • Codex memory exchange runs for each active writer. A Memory V2 writer receives the same copies under its extensions folder and folds them into the summary. It does not create a handbook. Export from Memory V2 offers a valid summary only.

0.9.3 - 2026-09-27

Fixed

  • Codex memory exchange follows $CODEX_HOME/config.toml memories.version. Memory V2 imports memory_summary.md only and does not treat a leftover memories/ handbook as the live store. Export lands in that same store.

Added

  • Consolidation regression coverage for failed and interrupted host turns, incomplete replies, tool continuations, and legitimate completed no-ops in both memory versions. Investigation prompted by Tony-ooo's report in PR #6. Completion remains based on host lifecycle state, matching Codex, rather than requiring artifact changes or a special no-op acknowledgement.

0.9.2 - 2026-09-26

Fixed

  • OpenCode 2 memory tool metadata is normalized to JSON before returning it to the host. Optional search fields no longer prevent success events from being persisted, leaving tool calls running with no output for the next turn.
  • Removed context-hook re-execution of unanswered memory calls. Request preparation no longer reads disabled memory, replaces historical results, or advises retrying a write whose outcome is unknown.

0.9.1 - 2026-09-26

Fixed

  • OpenCode 2 memory tools stay on the normal tool list. They were only inside Code Mode execute, so the agent often reported that memory tools were not in the runtime and skipped them.

0.9.0 - 2026-09-23

Fixed

  • OpenCode 2 no longer shuts memory down in every project when one idle project is unloaded. Memory panel toggles survive other projects starting and apply to all open projects.
  • OpenCode 2 stops consolidation helpers in the process that runs them before deleting them through the registered service, so a helper cannot keep editing after its lease is released.
  • Secret redaction matches codex for values on the line after password: / token = style keys.
  • Notes added while consolidation runs are consolidated on the next run instead of being folded into the baseline unseen.
  • A consolidation lease is released as orphaned only when its owner is on this host, its process is gone, and its heartbeat is stale, so sandboxed peers sharing the memory database keep their lease. The sweep also runs before each consolidation attempt, not only at startup.
  • OpenCode 2 keeps the HTTP status of failed extraction requests, so provider 429s trigger the quota backoff instead of burning retries.
  • A request too large for the model's per-minute or context limit is no longer treated as a quota outage. It uses the normal retry budget instead of retrying forever and pausing all other extraction each time. Errors that merely mention "quota" are no longer classified as capacity failures.
  • Extraction stops 10 minutes before its job lease expires, so another process cannot reclaim the job mid-run and discard the finished result.
  • Claude Code import streams session transcripts to find a project's directory instead of loading each whole file into memory.
  • Closer codex parity: marking a consumed session as polluted re-queues consolidation right away instead of waiting out a retry backoff; compaction summaries no longer duplicate conversation in extraction input; raw memories sort by session id in byte order and pruning breaks ties like codex; the V1 extraction schema allows a null rollout_slug; the Memory V2 read-path prompt keeps codex's explicit remember/forget/correction trigger for notes.
  • The memory summary cache also notices rewrites that keep the same modification time. Freed database pages are returned after pruning. Helper sessions are no longer tracked forever on hosts that cannot confirm deletion.
  • Builds start from a clean dist/, so stale compiled files no longer ship in the npm package (0.8.4 included an unused local-session-times.js).
  • OpenCode 2 without a registered service reads transcripts from the compacted session context; extraction now keeps the compaction summary there instead of silently losing everything before it.
  • OpenCode 2: a text part that contained only a citation block is dropped instead of being sent to the model empty; title requests also have citation markup stripped. IPv6 loopback services ([::1]) are recognized as local. The event stream is re-subscribed if the host ends it, and shutdown no longer waits out a pending retry delay. Aborted extraction requests no longer leave listeners behind, and bursts of status updates are coalesced.

Changed

  • memory_reset asks you to approve the wipe; the model's confirm argument alone no longer erases memory. Re-enabling a session that was excluded for external context also needs approval.
  • On OpenCode 2, which cannot ask for approval from plugin tools, the agent no longer gets memory_reset. The memory panel has a Reset memory control with a second-press confirmation instead.

0.8.4 - 2026-09-22

Fixed

  • The OpenCode 2 memory panel separates extraction retries from queued consolidation and its normal cooldown, labels recap counts as total stored, and shows extraction failure reasons. Retry status includes both active learning pipelines during dual-write.

0.8.3 - 2026-09-22

Fixed

  • OpenCode 2 service discovery uses the current /api/info endpoint, with legacy readiness routes retained for older hosts. Removed /api/status routes no longer silently restrict extraction to locally observed sessions.
  • memory_inspect and the OpenCode 2 memory panel report degraded global discovery and its failure reason, clearing the warning after recovery.
  • OpenCode 2 extraction retains the requested JSON schema and restates the extraction task after historical conversation data, preventing replies that continue old user requests instead of extracting memories.
  • Lifecycle tests retain their temporary memory root until background work finishes, preventing teardown from pruning the user's generated memory files.

0.8.2 - 2026-09-22

Changed

  • The OpenCode 2 memory panel opens with /memory-inspect or Inspect memory in the command palette, replacing /memory and /memory-status.
  • The sidebar distinguishes memory recall from background learning. Panel controls explain their scope, persistence, and availability.

Fixed

  • Memory panel keyboard navigation works inside the modal, including tab switching, control selection, activation, scrolling, and refresh.
  • The panel adapts to smaller terminals with scrollable content and pinned navigation. Selection colors follow current and older OpenCode themes.
  • Loading, pending changes, and rejected actions show explicit feedback. Connection failures retain the last known status and pause controls until recovery; late responses cannot overwrite newer status or reopen a closed panel.
  • CI type checking no longer requires a prior build of the OpenCode 2 contract-check dependencies.

0.8.1 - 2026-09-21

Fixed

  • OpenCode 2 consolidation verifies the submitted turn's terminal outcome before accepting artifacts or clearing the workspace diff. Failed turns preserve pending notes and provider errors for retry handling.
  • Claude import aborts pruning on discovery I/O errors and preserves scoped resources when the original project directory is unavailable.
  • OpenCode 2 consolidation agents can read the memory root and use glob/grep. Search paths remain confined to each helper's assigned memory workspace.
  • Reasoning variants resolve through the current OpenCode 2 model API, with compatibility for older catalogs and selectable model aliases.
  • Failed OpenCode 2 service connections are rediscovered on subsequent calls, including after service restarts and credential rotation.
  • Citation cleanup handles model-bound OpenCode 2 message shapes without double-counting durable citation usage.
  • Toggling memory reading in OpenCode 2 refreshes the tool registry immediately and restores the previous setting if the refresh fails.
  • Creating a test sandbox no longer triggers an implicit plugin build, preventing clean-checkout unit-test timeouts.

Changed

  • Documentation starts with installation and working defaults, with separate configuration, usage, troubleshooting, and memory-version guides. The version guide explains the corresponding Codex origins of both memory implementations.
  • Type checking now covers tests and scripts as well as shipped source files.

0.8.0 - 2026-09-20

Added

  • Codex memory V2: provenance-ranked extraction, bounded session recaps, summary-only consolidation and recap-oriented retrieval in isolated memories_v2/ and memory_v2.db. V1 remains the default.
  • dual_write migration mode runs both learning pipelines independently. Inspect and the OpenCode 2 memory UI report each pipeline and V2 readiness (valid summary plus a successful consolidation of 20 distinct sessions).
  • Explicit read-version cutover for new sessions; existing sessions retain their namespace for injection, tools, notes and citations across reloads.

Changed

  • Both OpenCode hosts share pipeline scheduling with async-local namespace routing, independent DB handles and worker guards, and per-job memory-root permissions. Session exclusion metadata remains shared.
  • Reset and session deletion cover both namespaces; reset also clears readiness progress and citation dedupe while preserving session modes and routing.
  • Live e2e tests cover dual-write warmup and explicit V2 cutover on both hosts.

Fixed

  • Live e2e accepts a clean cooldown-pending Phase 2 as consolidated. A late extraction may re-enqueue consolidation after a successful run, leaving the job pending with no error; Codex treats the workspace diff as the dirty check, so the harness no longer requires a literal status=done.

0.7.7 - 2026-09-19

Fixed

  • OpenCode 2 extraction preserves reasoning variants when a complete model reference is available and avoids invalid variant-only model references.
  • Sessionless OpenCode 2 extraction releases its synthetic helper locally, avoiding spurious host-session cleanup failures.

Changed

  • Live e2e/readpath auth comes from .env (OPENCODE_LIVE_API_KEY, OPENCODE_LIVE_BASE_URL, OPENCODE_LIVE_MODEL) and an OpenAI-compatible live provider in the XDG sandbox. Host OpenCode sqlite / auth.json / OAuth are not read. opencode serve health probes /openapi.json.
  • memory_inspect separates live extraction failures from leftover exhausted jobs older than max_rollout_age_days, labels pending jobs whose retry window has elapsed as due, and states Phase 2 idle/cooldown instead of a bare pending. Discovery is this process's session list (not total chats) and no longer logs the same count on every cache hit.
  • Live tests load one explicitly configured plugin package on both host generations, verify that OpenCode 2 receives model options, and wait for completed replies to the current prompt. Permission grants remain scoped to the interactive agent so memory helpers retain their file-tool sandbox.
  • Live e2e coverage verifies automatic learning from implemented tasks, fresh-session recall, citations, explicit "remember this" requests, and reset. Hard failures retain their sandbox for diagnosis; OpenCode 2 contract checks use an isolated host.

0.7.6 - 2026-09-19

Fixed

  • V2 citation instructions now require a blank line before the memory-citation fence so markdown clients (OpenCode web) parse it as a code block instead of gluing it onto the last sentence.

0.7.5 - 2026-09-19

Added

  • home plugin option (and OPENCODE_CODEX_MEMORY_HOME) relocates only memory.db + memories/ so a sandbox can mount memory without the rest of OpenCode's local database. Precedence: home (pinned; ignores OpenCode's data dir and XDG_DATA_HOME) → OPENCODE_CODEX_MEMORY_HOME → OpenCode data dir (default; memory moves with that directory). Absolute path required (~ ok). memory_inspect shows the resolved home.

0.7.4 - 2026-09-19

Fixed

  • OpenCode 2 inside an IDE/serve --port 0 host is not the registered serve --service process. A healthy loopback service is still used for the global session list (shared database). Non-loopback PID mismatch is refused. If no service is registered, this process learns from sessions it has seen. Helper cleanup uses the local context, and consolidation no longer holds a one-hour lease after a helper interrupt.

0.7.3 - 2026-09-18

Fixed

  • Phase 2 no longer walks every file under memories/.git looking for symlinks. A nested junction or symlink cycle (common on Windows) could hang consolidation as "in-flight" with no error. Only the .git entry itself is checked. Git baseline/diff/reset also time out after 2 minutes. memory_inspect now shows how long a running consolidation has been going and when its lease expires.

0.7.2 - 2026-09-17

Fixed

  • OpenCode 1.18.29+ loads exports["./tui"] and requires default.tui(). 0.7.x pointed that export at the OpenCode 2 sidebar, which imports @opencode/plugin/tui — missing on 1.x, so the TUI reported the plugin unable to load. ./tui is now a dual-host wrapper: 1.x gets a no-op tui(), OpenCode 2 still lazy-loads the sidebar via setup().

0.7.1 - 2026-09-17

Fixed

  • OpenCode 2 background learning ships @opencode/client as a runtime dependency so the plugin cache can import it. Discovery still reads service.json and probes /api/status (not Service.discover(), which hits the 2.0.5-removed /api/health). Failures now surface the real error.

0.7.0 - 2026-09-16

Added

  • The plugin now runs on OpenCode 2 as well as 1.x. Pin 0.7.0 and, on OpenCode 2, use the plugins package form. Same memory pipeline; V1 server() is unchanged. OpenCode 2 also gets a Memory sidebar and /memory-status. Host limits (registered service, citations, models) are documented in ARCHITECTURE.md.

0.6.5 - 2026-08-31

Added

  • Architecture writeup covering learning, remembering, and forgetting (docs/how-ai-memory-works.md), linked from the README.

Fixed

  • Memory is no longer injected into OpenCode's hidden session-title generator (same session ID as the real chat; the hook has no agent field, so the title prompt is detected instead).

0.6.4 - 2026-08-28

Fixed

  • Extraction still prefers low reasoning and consolidation medium (Codex), but if the configured model does not list that effort, the plugin picks the nearest listed level (equal distance → higher). Models with no effort variants keep the host default.

0.6.3 - 2026-08-21

Fixed

  • Finder metadata files such as .DS_Store in the memories folder no longer abort consolidation.

0.6.2 - 2026-08-20

Fixed

  • Shortcuts in the memories folder that point at files elsewhere on disk are now removed, so memory cannot be redirected outside that folder. The real files those shortcuts pointed to are left alone.

0.6.1 - 2026-08-17

Fixed

  • Extraction jobs that fail because the model is out of quota stay retryable instead of being permanently dropped after three attempts. Already-failed quota jobs are reopened automatically; memory_inspect labels backoff vs quota vs other exhausted failures.
  • Reloading OpenCode finds leftover memory helper sessions across all pages of the host-wide session listing.
  • Stuck OpenCode API calls abort instead of leaving background learning hanging.
  • Time-only memory_search listings paginate with cursor instead of repeating the first page.
  • Consolidation skips sessions that no longer exist in OpenCode (same as a deleted-session forget) and backfills their slots with lower-ranked live sessions.
  • Extraction uses low reasoning and consolidation uses medium, matching Codex.

0.6.0 - 2026-08-12

Added

  • memory_list supports integer-cursor pagination and listing a single file (Codex-aligned).
  • memory_inspect reports effective memorize / memorize-extract agent sandbox health (shipped vs user override, permission issues).
  • README section on backing up and restoring the memory database and memories/ tree (including WAL/SHM and git history).

Fixed

  • Background extraction/consolidation promises are tracked so test teardown can wait for them to finish.
  • Agent health treats non-denied extra tool and external_directory permissions as unhealthy and keeps source=shipped across config-hook re-injection.
  • memory_list reports an exhausted page when a cursor equals the current result count instead of claiming the directory itself is empty.

0.5.0 - 2026-08-08

Added

  • Import memory from Claude Code (off by default). If you also use Claude Code on the same machine, enable claude_import: { "enabled": true } so OpenCode can pick up Claude's project memories on the next consolidation pass. Optional projects allowlist and claude_home override. One-way only (nothing is written back to Claude). Turning it off stops further import without erasing what already merged; see the README for staging cleanup.

Changed

  • README configuration for Codex CLI and Claude Code sharing is clearer: options tables, turn-off behavior, and how to remove local staging copies.

0.4.11 - 2026-08-08

Fixed

  • Session discovery no longer filters to the current project only. The host SDK injects a directory query on every GET; that made extraction miss idle sessions from other projects (memory is global).

0.4.10 - 2026-08-08

Fixed

  • Plugin reload while consolidation is running no longer races past an already aborted cancel signal (could leave the job hanging until timeout).
  • Extraction also listens for plugin dispose (same cancel path as consolidation), so a reload mid-extract does not wait up to an hour for the host prompt.

0.4.9 - 2026-08-08

Changed

  • Bearer-token redaction matches current codex: word boundary, space/tab only (no newline match), trailing base64 padding, and runs before API-key patterns so Bearer sk-… is one redaction.

0.4.8 - 2026-08-08

Fixed

  • Reloading or restarting OpenCode no longer leaves memory learning stuck for up to an hour, or allows two background helpers to edit memory files at once.
  • Background learning is less likely to skip sessions that just became eligible or to spam OpenCode with session lookups when nothing is ready to extract.
  • Memory tools refuse to follow symlinks that could redirect reads or writes outside the memory folder.
  • memory_reset no longer gets immediately undone by a background consolidation pass that re-created the memory folder right after the wipe.

Added

  • memory_inspect shows more of why memory is (or is not) building: extraction job status and recent errors, last session discovery, when sessions become eligible, recent pipeline events, and (if enabled) last Codex import/export file times.

Changed

  • The consolidation helper is instructed to only edit files under the memory workspace, not your project source tree.

0.4.7 - 2026-08-06

Changed

  • Memory extraction finds past sessions with one host-wide lookup instead of scanning each project separately — faster and less brittle when many projects are open.

Added

  • Automated live checks against the official OpenCode binary (bun run contract, bun run live:read, bun run live:e2e) for release verification.

0.4.6 - 2026-08-05

Fixed

  • Memory extraction/consolidation sub-sessions no longer inherit a deleted project directory from the plugin host. OpenCode fails those turns with UnknownError / ENOENT when the path is gone; sub-sessions are now anchored on the memory workspace directory (always ours, already granted to memorize).

0.4.5 - 2026-08-05

Fixed

  • memory_inspect now reports Phase 2 job status, last error, retry time, and last attempt finish time. After a failed consolidation the success watermark alone no longer looked healthy while the failure stayed invisible.

0.4.4 - 2026-08-05

Fixed

  • Memory consolidation now stops and closes its background helper immediately if it loses the job lock or can no longer refresh it. A reclaimed job can no longer overlap with an older helper that is still editing memory files.
  • An unexpectedly empty session response no longer deletes memory previously extracted from that session. The extraction retries instead; genuinely empty new sessions and explicit no-memory results still behave as before.
  • Memory tools, workspace updates, and consolidation diffs now refuse files that become symlinks while being opened, preventing redirected reads and overwrites outside the memory directory.
  • memory_inspect now distinguishes the last successful consolidation watermark from the latest failed attempt, reports malformed option types, and shows clean defaults after configuration reloads.

0.4.3 - 2026-07-30

Fixed

  • Memory consolidation now waits for its background helper chat to be closed before it finishes. If the helper cannot be closed, the run keeps its lock until it expires instead of handing it over, so a second consolidation can never edit your memory files while the first one may still be writing.

0.4.2 - 2026-07-29

Fixed

  • A session that invokes an external-context tool is now excluded from memory immediately. Failed or cancelled web/MCP calls can no longer slip through when disable_on_external_context is enabled, and a stalled MCP status check can no longer block the tool itself.
  • Failed tool calls now reach memory extraction along with their error message; content OpenCode hides from the assistant is no longer mined.
  • Secret redaction now preserves JSON and YAML structure around quoted, primitive, nested, multiline, and punctuation-bearing values instead of corrupting the surrounding tool payload or leaking part of the value.
  • If the memory root or memory_summary.md is a symlink, the plugin no longer injects redirected content into new chats. The summary stays protected even if the file is swapped while it is being opened.
  • Timed-out background extraction/consolidation now aborts the model run with a bounded request instead of leaving it running indefinitely.
  • After a plugin reload, live memory sub-sessions are recognized before hooks start. Cleanup uses a private ownership marker plus the generated title, so ordinary chats, renamed chats, and user forks cannot be deleted by mistake.
  • Citation usage for several sessions is recorded in one database transaction, so a mid-batch interruption cannot update only some of them.
  • memory_inspect config warnings reset when options are re-applied, so fixed typos no longer linger.
  • Under heavy load, citation, idle, and turn trackers no longer forget long-lived sessions before short-lived ones.
  • A burst of duplicate idle events can no longer keep extending the de-duplication window and delaying extraction on busy sessions.

0.4.1 - 2026-07-26

Fixed

  • Consolidation no longer reports success when OpenCode returns an assistant error inside an otherwise successful HTTP response. The job now retries and keeps its pending workspace diff instead of silently accepting stale memory.
  • Failed extraction and consolidation jobs now release their leases even when the host rejects with a non-standard value, avoiding one-hour stalls.
  • Memory writes now reject symlinked paths throughout the workspace, preventing notes and generated artifacts from being redirected outside the memory root.
  • MCP-backed tool calls are classified from the live server list using OpenCode's tool-name sanitization, so dynamically added or dotted server names correctly exclude a session when disable_on_external_context is enabled.
  • A failed database open now closes its SQLite handle instead of leaking one on every later memory operation.
  • Memory is no longer injected into OpenCode's sessionless agent-generation prompt; it remains limited to real conversation sessions.

0.4.0 - 2026-07-25

Added

  • Share memory with the Codex CLI (off by default). If you use both OpenCode and Codex on the same machine, the plugin can now exchange consolidated memories with Codex — in either or both directions, via codex_interop: { "import": true, "export": true }. What one assistant learns, the other picks up with its next consolidation. Codex needs no configuration for this: its own files are never modified, and nothing is written until Codex's memory feature is actually in use. Imported content is tagged with its origin so memories don't ping-pong between the two systems. (#1)
  • Easier configuration checking: memory_inspect now shows the options that are actually in effect, flags unknown or malformed configuration keys, and reports the state of the Codex exchange — just ask the agent to run it.

0.3.1 - 2026-07-16

Fixed

  • Memory is now stored under opencode's own data directory on every platform. If you set XDG_DATA_HOME, memory now lives at $XDG_DATA_HOME/opencode instead of always under ~/.local/share/opencode.

0.3.0 - 2026-07-15

Changed

  • More reliable memory extraction — the background learning agent now returns its results in a structured format instead of having its reply parsed as text, so an occasional malformed response no longer causes a session's memory to be skipped.

0.2.1 - 2026-07-15

Changed

  • Now requires opencode 1.18 or newer.

0.2.0 - 2026-07-12

Fixed

  • Consolidation works again on opencode 1.17+: opencode gates file tools outside the session's project behind the external_directory permission, and the global memory workspace is always outside the project — the consolidator's wildcard deny blocked every memory read/write. The injected memorize agent now carries an external_directory allow scoped to the memory root. Verified end-to-end against opencode 1.17.18.
  • Transcript/DB errors no longer masquerade as an empty transcript (which finalized as a successful no-output extraction and deleted the previous extraction); they fail the job, which retries under its lease.
  • memory_reset propagates deletion failures instead of reporting a successful reset while files survive, and refuses to run while a consolidation is in flight in the same process.
  • A symlinked memory root is rejected by every memory tool (previously only descendants were checked, and search/note-writing bypassed the guard).
  • Phase-2 completion updates the job row and the selected-input retention flags in one transaction (codex parity); a crash between them could let pruning delete inputs backing the consolidated artifacts.
  • Secret redaction catches quoted keys in JSON/YAML tool payloads ("password": "..."); the aws pattern no longer emits a literal $1.
  • memory_read can page past 256 KiB via line_offset (the byte cap now applies to the windowed output); the workspace diff cap counts UTF-8 bytes instead of UTF-16 code units; memory_inspect reports the promised phase-2 success watermark; internal workspace walks no longer follow symlinked directories (a self-link looped forever).
  • Developer-role messages are excluded from extraction transcripts (codex sanitize_response_item_for_memories).

Changed

  • opencode data is read exclusively through the official API — transcripts via session.messages, cross-project session discovery via project.list + per-project session.list(scope=project, roots=true). opencode.db is never opened; the only SQLite left is the plugin's own memory.db.
  • The extraction agent has no tools (codex parity: stage-1 is a raw prompt with an inline transcript). Previously it could read/glob/grep the host project — a poisoned transcript could induce unrelated file reads.
  • memory_search ports codex's full search schema: queries[], match_mode (any / all_on_same_line / all_within_lines with minimal-window pruning), path scoping, integer-cursor pagination (next_cursor / truncated), context_lines, and normalized comparison. Arg renames: query → queries, limit → max_results. The since/until time filter and no-query listing mode are unchanged.
  • Citations are recorded and stripped in the new experimental.text.complete hook, before the final text is persisted — neither the UI nor stored history shows citation markup anymore (matching codex). Older hooks remain as fallbacks for pre-existing history.
  • Memory mode is stamped and phase 1 pumped at the first chat.message of a session (codex stamps at thread creation); session.status {type: idle} is handled alongside the deprecated session.idle event.
  • The manual write-pipeline test runs fully sandboxed (XDG overrides) and drives triggers through a persistent opencode serve — opencode run exits before the async extraction pass claims anything.

0.1.9 - 2026-07-11

Fixed

  • disable_on_external_context now works: pollution marking moved to the real tool.execute.after plugin hook (it previously listened for a nonexistent event-bus type and never fired).
  • max_unused_days is now honored by the phase-1 prune (it was hardcoded to 30 days there while phase-2 selection used the configured value, so raising it silently still pruned at 30).
  • Reasoning/chain-of-thought parts are excluded from extraction transcripts, matching codex's rollout policy.
  • A failed workspace diff no longer looks like "no changes" and falsely marks consolidation succeeded; the job now fails and retries (codex failed_workspace_status).
  • A corrupt git baseline is recovered by re-initializing instead of failing every consolidation run (codex reset_git_repository_sync).
  • Stuck unowned phase-2 jobs are recovered by the failure path (codex failed_if_unowned); the heartbeat no longer dies silently on store errors.
  • The stage-1 claim cap follows max_rollouts_per_startup (1-128) instead of being silently limited to the execution concurrency of 8; the extraction timeout mirrors the 1h job lease so large transcripts cannot exhaust retries.
  • Session deletion no longer triggers a consolidation attempt while generate_memories is off (the memorize agent is not registered then).
  • The consolidation prompt no longer instructs shell commands or file deletion the sandboxed memorize agent cannot perform; stage-1 input restores codex's "empty string when unknown" contract; memory_search flags capped result sets; transcript head/tail truncation uses codex's 50/50 split.

Changed

  • README: clarified that no codex subscription or OpenAI account is needed, documented the model-selection precedence chain and dedicated_tools: false behavior, and corrected several claims (idle timing, read-only opencode.db access, redaction scope, sandbox wording, data layout).
  • With dedicated_tools: false the injected memory guidance now uses codex's file-based wording instead of referencing unregistered memory_* tools.

0.1.8 - 2026-07-11

Fixed

  • Stage-1 output changes now enqueue global consolidation, so new extractions and deleted sessions trigger a phase-2 pass without waiting for the next session.idle. If phase 2 is already running, its lease is preserved and only the input watermark advances.
  • Deleting a session whose stage-1 output was already consumed by phase 2 now enqueues a forgetting pass, so the diff drives removal of the stale memory.
  • Shipped memory subagents (memorize, memorize-extract) now default-deny unknown tools so IDE and MCP integrations cannot bypass the shell/network restrictions.

0.1.7 - 2026-07-10

Fixed

  • Phase 2 now validates consolidation artifacts like codex (#32193): early no-diff succeed only when MEMORY.md exists and memory_summary.md starts with v1; after the consolidator, invalid artifacts fail the job without resetting the git baseline so INIT/repair can run again.
  • Stage-1 extraction treats either empty raw_memory or empty rollout_summary as no-output (codex parity); previously only both-empty was discarded.

Changed

  • Re-synced stage_one_system.md, consolidation.md, and read_path.md from codex HEAD (were ~half the upstream size), re-applying the port's platform adaptations on top: the <memory-citation>/<session_ids> citation contract that citation.ts parses, memory_search/memory_read/memory_add_note tool guidance (the memory dir lives outside the workspace), per-session markdown rollout summaries with session_id metadata (codex references raw .jsonl rollouts via rollout_path/thread_id), and codex's memory-extension prompt blocks now rendered by buildConsolidationPrompt (prompts.rs parity). stage_one_input.md stays platform-shaped. New tests/prompts.test.ts guards the placeholder inventory and citation/tool contracts. Bumped codex_ref in codex-map.yaml.

0.1.6 - 2026-07-10

Fixed

  • Published package was missing every runtime asset outside compiled JS: tsc does not copy src/templates/*.md into dist/, and the bundled opencode.json was shipped at the package root while injectAgentDefinitions resolves it relative to dist/src/ (dist/opencode.json). Memory extraction, consolidation, read-path injection, and agent auto-registration were all broken in the npm artifact (dev checkouts were unaffected). The build now copies templates to dist/src/templates/ and opencode.json to dist/.
  • Added a prepack smoke test (scripts/smoke.ts) that loads the built entry the same way opencode does (V1 module -> server() -> hooks) and exercises template reads and agent injection, so this class of packaging bug fails npm pack/npm publish instead of shipping. Pattern borrowed from opencode-gemini-auth's prepack import smoke test.

0.1.5 - 2026-07-08

(No functional changes — release artifact only.)

0.1.4 - 2026-07-08

Fixed

  • Plugin was published as TypeScript source ("main": "src/index.ts") with no compiled JavaScript output, so the opencode binary could not load or execute it even though it appeared in the plugin list. The package now compiles to dist/ with tsc, ships only compiled JS, and points main/exports at dist/src/index.js.
  • tools/control.ts and tools/memory.ts used Bun path aliases (@/...) that tsc does not rewrite; they now import from ../src/*.js so the compiled output resolves under Node/Bun module resolution.

0.1.3 - 2026-07-05

Fixed

  • memory_reset no longer breaks memory until restart: it closed the SQLite handle while the plugin kept using a cached store, so every subsequent hook-driven DB operation failed silently. The DB now stays open across resets (matching codex, which only wipes directories) and the store is no longer cached.
  • Startup sub-session cleanup no longer can kill an in-flight consolidation: the cutoff was 30 minutes while consolidation is allowed 60; it is now 90 minutes.

Changed

  • Internal cleanup: dead code removed, node:crypto short hash for summary filenames (was hand-rolled base36), template fill via replaceAll.

0.1.2 - 2026-07-04

Added

  • The memorize / memorize-extract sub-agents register themselves via the plugin config hook — no manual agent block needed anymore. Definitions come from the bundled opencode.json; a user-defined agent with the same name always wins. Skipped when generate_memories is off.

0.1.1 - 2026-07-04

Fixed

  • Parity pass after a full subsystem audit vs codex (codex-map.yaml now records every remaining deliberate divergence, and the drift script watches the config/lifecycle/pollution files where past blind spots lived):
    • ensureBaseline no longer commits over an existing baseline: the phase-2 diff now spans last-success → now, so manual edits to MEMORY.md and ad-hoc notes actually reach consolidation instead of being silently baselined away.
    • Baseline reset re-initializes .git (fresh single-commit history) and memory_reset deletes .git too — deleted/redacted memory content is no longer recoverable from git history, matching codex.
    • Ad-hoc notes are never pruned (they are explicit user requests; codex keeps them permanently). The seeded instructions template regained codex's never-delete rule, [ad-hoc note] provenance tag, and prompt-injection warning.
    • Phase-2 retry semantics match codex: backoff (now 1 h) is enforced regardless of job status, the retry counter is no longer reset on claim, and retries never exhaust; stage-1 retry delay is 1 h; phase-2 lease 1 h; a failing consolidation no longer re-invokes the LLM on every idle event.
    • Multi-process safety: claims run in immediate transactions with per-claim ownership tokens; all finalizers require ownership + running status (a zombie worker can no longer clobber a re-claimed job's output); phase 2 confirms ownership one final time before resetting the baseline; the DB opens with a 5 s busy timeout.
    • disable_on_external_context now covers MCP tools (matched via client.mcp.status()), as the README already claimed.
    • Extraction sees full tool payloads (previously sliced to 200/500 chars per call) with a 600k-char (~150k-token) transcript budget, matching codex's evidence budget; rollout_slug is redacted; Bearer redaction is case-insensitive; injected AGENTS.md/<skill> blocks are excluded from extraction.
    • Path guard rejects symlinks per path component and hides dotfiles; the search walker skips symlinks and hidden files.
    • Sessions seen while generate_memories: false are permanently stamped disabled (codex stamps at thread creation) instead of being retroactively extractable after re-enabling; deleting a session now deletes its extracted memory and job (session.deleted).
    • memory_reset preserves per-session memory modes (disabled/polluted sessions stay excluded), matching codex clear_memory_data.
    • Summary truncation keeps head + tail with a marker instead of silently dropping the end of memory_summary.md.
  • Phase 2 consolidation never actually ran: the git baseline was committed after the workspace rebuild, so the captured diff was always empty. The baseline is now established before the rebuild.
  • Staging deleted files no longer throws (isogit.add → isogit.remove); previously any pruned rollout summary permanently broke baseline commits and diff capture.
  • Stage 1 jobs stuck in running after a crash are reclaimed once their lease expires.
  • Sessions with new activity after a successful extraction are re-extracted; source_updated_at and the success watermark now use the session's real time_updated instead of extraction wall-clock time.
  • Phase 2 input selection kept dropping old-but-actively-cited memories (recent activity or recent usage now qualifies), and pruneStage1Outputs is now actually called each Phase 2 run.
  • Citation usage was counted once per streaming delta instead of once per message part, inflating usage_count.
  • Template substitution no longer expands $&/$'/$n patterns contained in transcripts or the memory summary.
  • The plugin's own sub-sessions are isolated: no memory prompt injection, no phase-1 triggering on their idle events, and excluded from session capture at the SQL level.

Added

  • Full codex config parity for plugin options, using codex's exact names and defaults so the two stay easy to compare and sync: generate_memories, use_memories, dedicated_tools, disable_on_external_context, max_raw_memories_for_consolidation, max_rollouts_per_startup are now configurable (alongside the existing extract_model, consolidation_model, max_unused_days, max_rollout_age_days, min_rollout_idle_hours). Defaults now match codex (max_rollout_age_days 10, min_rollout_idle_hours 6, max_rollouts_per_startup 2, max_raw_memories_for_consolidation 256). One intentional divergence: dedicated_tools defaults to true (codex: false) so the plugin ships its memory tools out of the box.
  • memory_search supports since/until for time-scoped recall over time-anchored files (rollout summaries, ad-hoc notes); with a window and no query it returns a chronological listing of that period's sessions/notes. Extends beyond codex.
  • memory_list tool (port of codex memories/list): sorted directory listings with entry types; hidden files and symlinks are skipped.
  • memory_read supports line_offset/max_lines with start-line reporting, so file:line citations work on large files.
  • Numeric plugin options are clamped to codex's valid ranges; unknown option keys log a warning; use_memories: false now also hides the memory tools (codex extension gating).
  • Default model selection mirrors codex's split via opencode's own config: unset extract_model uses opencode's small_model (codex: gpt-5.4-mini), unset consolidation_model uses opencode's main model (codex: gpt-5.4); both fall back to the session default when not configured.

Changed

  • Renamed to opencode-codex-memory for npm publishing (opencode-memex is taken by an unrelated plugin). Plugin id, log prefixes, baseline commit author/message, the test-root env var (OPENCODE_CODEX_MEMORY_TEST_ROOT), and the sub-session title prefix (codex-memory-) all follow. Sub-sessions titled with the old prefix are no longer auto-cleaned or excluded from capture — delete any stragglers from before the rename.
  • Behavior change (parity): memory_search is now case-sensitive by default (pass case_sensitive: false for the old behavior), searches all non-hidden files instead of only .md/.txt/.json, and returns results in (path, line) order with a default limit of 200. Ad-hoc note filenames use codex's hyphen layout (<timestamp>-<slug>.md) and never overwrite on collision.
  • Behavior change from new defaults: memory now waits longer before extracting a session (idle ≥6h, was ≥1h), only looks back 10 days (was 14), and processes at most 2 sessions per pass. Web/MCP sessions are no longer excluded from memory by default — set disable_on_external_context: true to restore that.
  • Renamed the generate_memory option to generate_memories to match codex; update your opencode.json if you set it.
  • Codex memory parity pass (breaking: reset local memory state — DB schema, summary filenames, and memory_summary schema all changed):
    • All three prompt templates replaced with full adaptations of codex's memory prompts: stage-1 extraction (minimum-signal gate, task outcome triage, preference-signal extraction, task-grouped raw_memory format), Phase 2 consolidation (MEMORY.md Task Group schema, v1 memory_summary schema with User Profile / User preferences / General Tips / What's in Memory, skills format, diff-driven forgetting workflow), and the read path (decision boundary, budgeted quick memory pass, staleness guidance).
    • System/input prompt split for extraction (system via prompt body's system field); all-empty output is a supported no-op that deletes any stale stage-1 row.
    • Rich citations: citation_entries with file:line-range|note=[...] plus a session_ids block (legacy format still parses).
    • Forgetting: disabled/polluted sessions are excluded from Phase 2 selection so their workspace files disappear and the diff drives memory pruning; selected_for_phase2 snapshots are tracked and protected from retention pruning.
    • Job claiming mirrors codex: retry backoff respected, newer session activity overrides backoff and resets exhausted retries, leases cleared on completion/failure.
    • Session cwd captured and rendered through raw_memories.md and rollout summaries; summary files named <timestamp>-<shorthash>-<slug>.md; transcripts strip citation blocks and truncate head+tail.
    • extensions/ad_hoc/instructions.md seeded; resource pruning is filename-timestamp based and never touches notes or instructions; extract_model and consolidation_model plugin options wired to sub-agent prompts.
  • phase2_workspace_diff.md now matches codex's format: a ## Status listing plus a ## Diff section with the real unified content diff since the last consolidation (per-file diffs rendered in full, total bounded at 4 MiB with a truncation marker). Previously the consolidation agent only got the file-status list. The artifact is removed before diffing and before baseline commits so it never enters baseline history.
  • Full implementation of the codex memory architecture as a standalone opencode plugin (opencode-codex-memory).
  • Stage 0 (Read path MVP): memory_summary.md (≤2500 tokens) is read from ~/.local/share/opencode/memories/ and injected into every system prompt via experimental.chat.system.transform. Byte-identical append → provider cache stable.
  • Stage 1 (Tools + Citations):
    • Tools: memory_read, memory_search, memory_add_note.
    • Citation parser for <memory-citation><citation_entries>...</citation_entries></memory-citation>.
    • Citations are stripped from assistant output via experimental.chat.messages.transform.
    • Usage recording stub (wired in Stage 2).
  • Stage 2 (SQLite + Phase 1 extraction):
    • Plugin-owned SQLite DB (memory.db) with memory_stage1_outputs, memory_jobs, memory_session_meta, and schema versioning.
    • MemoryStore with claim/lease/heartbeat, stage-1 CRUD, usage counters, session mode/pollution tracking.
    • Session capture via read-only access to opencode.db + session.idle trigger.
    • Secret redaction before LLM calls and storage.
    • Phase 1 extraction via memorize-extract sub-agent over the HTTP API.
  • Stage 3 (Phase 2 consolidation):
    • Workspace management (raw_memories.md, rollout_summaries/, skills/, extensions/).
    • Git baseline diffing inside the memories directory (bundled isomorphic-git, no external binary).
    • Phase 2 orchestration with 6h cooldown, 90s heartbeat, and singleton job claim.
    • Consolidation via the sandboxed memorize sub-agent.
    • Ships opencode.json with memorize and memorize-extract agent definitions (network/tools denied).
  • Stage 4 (Control tools):
    • memory_reset (with symlink guard and confirm flag).
    • memory_inspect (counts, token estimate, file listing).
    • memory_mode (per-session enabled/disabled/polluted).
  • Stage 5 (Polish):
    • Rate-limit stub (checkRateLimit).
    • Comprehensive unit tests (42 tests).
  • Basic read-path integration harness (tests/integration.ts) and a detailed manual/agentic write-pipeline test procedure (tests/WRITE_PIPELINE_TEST.md) added. No automated Jest/Bun end-to-end harness yet.
    • Documentation: README.md, RUNNING.md (official opencode + plugin install), implementation plan preserved.
    • Plugin renamed from its opencode-memory working title.

Changed

  • All hooks are wrapped in try/catch with graceful degradation (plugin crash does not affect the host session).
  • The workspace diff is truncated at 4 MiB with an explicit marker.
  • Event handlers defensively catch per-operation errors (recordUsage, markPolluted).

Security

  • Sub-agents (memorize, memorize-extract) have bash/webfetch/websearch/task/todowrite denied.
  • memory_reset refuses to run if the memories root is a symlink.
  • Aggressive secret redaction (OpenAI/Anthropic/AWS/GitHub/Slack keys, bearer tokens, private keys, password assignments) before any LLM call or storage.
  • With disable_on_external_context: true, sessions that used web or MCP tools are marked polluted and excluded from extraction (off by default, matching codex).

0.1.0 - 2026-07-02

Initial public development release. All stages (0–5) implemented and tested. Ready for manual end-to-end testing against the official opencode release.