Skip to content

Atmospenguin/opencode-chronicle

Repository files navigation

opencode-chronicle

Chronicle memory system for OpenCode - aligned with Codex-style memory architecture (excluding screen capture).

Chronicle hero

What it does

Captures conversation memory from your OpenCode sessions, extracts structured memories with your configured LLM, consolidates them over time, and injects relevant past memories into future sessions via the system prompt.

Defaults

  • Global memory root: ~/.opencode/memories
  • Project memory root: <cwd>/.memories
  • Phase 1 extraction / rollout summary model: gpt-5.4-mini
  • Phase 2 global consolidation / memory management model: gpt-5.4

The global store is intentionally user-wide. Project memory is written beside the project so repo-specific facts stay local to that checkout. Both levels are consolidated with the same low-noise rule: prefer no memory over weak memory.

Chronicle isolation

Design philosophy

Chronicle follows Codex's memory split: raw evidence is cheap to collect, but durable memory should be scarce, explicit, and auditable.

  • Prefer omission over low-quality recall: if a session has no reusable lesson, Phase 1 records no memory instead of inventing a weak one.
  • Progressive disclosure: future sessions always get the compact memory_summary.md, then only matching project memory and the most relevant retrieved memories.
  • Scope isolation by default: global memories can help anywhere, but project memories only load for the exact current working directory. A React repo should not inherit operational notes from a Rust checkout.
  • Source files are evidence, consolidated files are views: raw_memories.md, rollout_summaries/, and extension notes preserve provenance; MEMORY.md and memory_summary.md are rewritten summaries optimized for future agents.
  • Ad-hoc notes are persistent authority, not a queue: add_ad_hoc_note writes a timestamped note under extensions/ad_hoc/notes/. Consolidation folds it into memory with an [ad-hoc note] tag, but does not delete the note. Edit or delete the note when the underlying preference changes; the next workspace diff becomes the update or forgetting signal.
  • Usage strengthens memory: when an agent cites a retrieved memory with <oai-mem-citation>, Chronicle updates usage_count and last_usage, so frequently useful memories survive selection pressure.
  • Untrusted by design: memories are reference data, never executable instructions. Agents are told not to follow commands embedded inside remembered content.

The intended mental model is a small local memory workspace, managed like a git-backed knowledge base: keep original signals around, consolidate aggressively, and let diffs drive both learning and forgetting.

Architecture

  • SQLite (bun:sqlite) state at ~/.opencode/memories/state.db by default - threads, stage1_outputs, jobs, metrics
  • Phase 1: Per-thread extraction (session.idle event triggered, 2s debounce, plus startup batch)
    • Eligibility: non-ephemeral, non-subagent, age/idle gates, max-per-startup cap
    • Up to 8 parallel workers, 3 retries with 3600s backoff
    • Strict JSON schema (raw_memory/rollout_summary/rollout_slug), secret redaction before model call
  • Phase 2: Global and project consolidation (singleton DB job, 90s lease, 30s heartbeat, 30m cooldown)
    • Selects top-N by usage_count DESC, last_usage, max 256 default
    • Rebuilds MEMORY.md, memory_summary.md (with v1 prefix), raw_memories.md, rollout_summaries/*.md
    • Consolidates project-scoped PROJECT_MEMORY.md to <cwd>/.memories/PROJECT_MEMORY.md
    • Writes git-style phase2_workspace_diff.md for the consolidation agent to read
    • Prunes extension resources older than 7 days
  • Read path: Injects global memory_summary.md, matching project memory, and top-relevant memories into system prompt (gated by useMemories)
  • Citation tracking: Parses <oai-mem-citation> blocks in tool/assistant output, increments usage_count/last_usage for cited stage1 outputs
  • Polluted detection: web_search/fetch/browse tool invocations flip thread memory_mode to polluted (excluded from future extraction)

Chronicle architecture

Layout

Chronicle file layout

~/.opencode/memories/              # global user memory
├── MEMORY.md                      # consolidated global memory
├── memory_summary.md              # short-form global summary (v1 prefix)
├── raw_memories.md                # merged global raw memory dump
├── rollout_summaries/<id>.md      # global per-rollout summaries
├── skills/<name>.md               # learned global skills/patterns
├── extensions/                    # ad-hoc + Chronicle extension resources
├── .git/                          # git baseline for workspace diff
└── state.db                       # SQLite state

<cwd>/.memories/                   # project-local memory
├── PROJECT_MEMORY.md              # project-scoped facts for this cwd
└── cwd_source                     # audit/debug path source

Tools exposed

Chronicle tools ecosystem

  • chronicle_search - relevance search across stage1_outputs
  • chronicle_list - browse memories by usage/recency
  • chronicle_manage - stats / consolidate / reset
  • add_ad_hoc_note - write a persistent user-requested note to extensions/ad_hoc/notes/
  • When dedicatedTools=true:
    • memory_read - read any memory file (1-indexed line_offset, 20k token cap)
    • memory_list - list dir entries with cursor pagination
    • memory_search - Codex-style search (any / all_on_same_line / all_within_lines)

How to use it

1. Install the plugin

Add the published package to your OpenCode config and restart OpenCode:

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": [
    "opencode-chronicle"
  ]
}

For local development, point the same config field at your checkout instead:

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": [
    "/path/to/opencode-chronicle"
  ]
}

The published npm package is opencode-chronicle@1.0.1.

2. Let passive memory run

With the defaults, Chronicle watches normal root sessions, buffers conversation text, and extracts memory after session idle/startup eligibility gates pass. You do not need to call a tool for routine learning.

Useful config overrides:

{
  "plugin": [
    [
      "opencode-chronicle",
      {
        "memoriesDir": "~/.opencode/memories",
        "generateMemories": true,
        "useMemories": true,
        "dedicatedTools": true,
        "providerId": "openai",
        "modelId": "gpt-5.5"
      }
    ]
  ]
}
  • generateMemories=false stops new extraction/consolidation writes.
  • useMemories=false stops injecting memory into future prompts.
  • dedicatedTools=true exposes raw memory browsing tools (memory_read, memory_list, memory_search).
  • providerId / modelId select the OpenCode provider/auth context used by Chronicle's internal model calls.
  • extractModel / consolidationModel select Phase 1 and Phase 2 models separately. If they are omitted, Chronicle uses the lightweight defaults above (gpt-5.4-mini for extraction and gpt-5.4 for consolidation), not modelId.
  • internalAgent optionally selects the OpenCode agent used for delegated internal model calls; the default is the hidden summary agent.

3. Add explicit memories only when the user asks

Use add_ad_hoc_note when the user explicitly says to remember something. Keep notes short and durable:

{
  "slug": "review-style",
  "content": "User prefers review comments grouped by severity, with exact file/line references."
}

The note remains under extensions/ad_hoc/notes/ after consolidation. To correct or forget it, edit or remove the note file and run consolidation; do not patch MEMORY.md directly.

4. Inspect and maintain memory

  • chronicle_search: find relevant remembered context by natural-language query.
  • chronicle_list: browse memories by recency and usage.
  • chronicle_manage with stats: inspect DB/artifact status.
  • chronicle_manage with consolidate: force a Phase 2 pass.
  • chronicle_manage with reset: clear the memory workspace and DB state.

For normal operation, treat MEMORY.md, memory_summary.md, raw_memories.md, and rollout_summaries/ as generated artifacts. Change ad-hoc notes or source conversations instead, then let consolidation rewrite the derived view.

Tests

bun install
bun test            # test suite
bun run typecheck   # typecheck

Releasing

Maintainer release steps are documented in RELEASING.md. Releases are created through GitHub Releases and published to npm by Trusted Publishing.

Origin

Built by porting Codex's memories/ architecture to a single-process OpenCode plugin in TypeScript.

About

Chronicle memory system for OpenCode

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors