This directory contains a local OpenCode plugin that saves session context from runtime events and restores a compact summary when a new session starts.
- Logs relevant session/message/tool events into JSONL files.
- Builds a context snapshot when a session becomes idle, compacted, or deleted.
- Generates/updates one HANDOFF proposal markdown per worktree on the same session-end markers.
- Injects the latest snapshot only for recall-intent messages routed on
chat.message. - Includes the latest 5 dialogue turns (user/assistant) in restored context.
- Does not auto-inject snapshot context for normal chat or session compacting.
- Automatically removes old snapshots/logs with TTL-based cleanup.
- Auto-routes Korean recall-intent user messages to
/history-recall ...onchat.message.
plugins/index.ts currently loads ContextMemoryHook, HistoryRecallRouterHook, and ToolCallGuardHook.
If you want additional hooks, add them in plugins/index.ts and merge them into hooksList.
- Trigger: detects Korean recall-intent phrasing (for example, variants of "what did we do last", "show history", "I do not remember", and "did we do this yesterday afternoon").
- Rewrite: prefixes only the first text part with
/history-recalland keeps the original message body intact. - Contract boost: appends a per-message system instruction that enforces recall response blocks (
판정,근거,[UNCERTAIN],HANDOFF Draft). - Skip: does nothing when the first text part already starts with
/,/history-recall, or/recall.
plugins/index.ts: plugin entrypoint and hook merge logic.plugins/lib/hooks/context-memory.ts: event logging, snapshot generation, latest snapshot loading helpers, TTL cleanup.plugins/lib/hooks/history-recall-router.ts:chat.messagerewrite hook for recall-intent routing and recall-only snapshot injection.plugins/lib/hooks/tool-call-guard.ts: tool-call reliability guard (chat.params,experimental.chat.system.transform,tool.execute.before).
- Scope default: enabled for
nvidiaprovider modelz-ai/glm5. - Prompt guard: injects a strict tool-call JSON contract once per session.
- Sampling guard: lowers
temperature,topP, andtopKfor guarded models to reduce malformed tool args. - Args guard: sanitizes parsed tool args and normalizes known enum/shape pitfalls before tool execution.
- Task prompt guard: prepends a per-task execution contract to
tasktool prompts to reduce malformed subagent tool-call loops. - Compatibility guard: marks Gemma/CodeGemma and selected Nemotron families as no-tool sessions to reduce tool-first failure modes.
Environment toggles:
OPENCODE_TOOLCALL_GUARD_ALL_NVIDIA=1: enable guard for all NVIDIA provider models.OPENCODE_TOOLCALL_GUARD_ALL_MODELS=1: enable guard for every model/provider.OPENCODE_DISABLE_TASK_PROMPT_GUARD=1: disable automatic prompt contract injection fortaskcalls.
Ensure opencode.jsonc includes this plugin entry:
OpenCode resolves this to a file:///.../plugins/index.ts URL at runtime.
Data is stored under:
~/.config/opencode/context-memory/
Subdirectories:
logs/: per-session JSONL event logs.snapshots/: per-session summarized snapshot JSON.latest/: one latest snapshot file per worktree hash.handoff-proposals/: one latest HANDOFF proposal markdown per worktree hash (proposal-only, manual apply).
On Windows in this setup, this typically maps to:
C:\Users\<user>\.config\opencode\context-memory\...
Default retention is 30 days.
- Env var:
OPENCODE_CONTEXT_TTL_DAYS - Valid range:
1to365 - If unset or invalid: fallback to
30
Examples:
$env:OPENCODE_CONTEXT_TTL_DAYS = "14"
opencodeRemove-Item Env:OPENCODE_CONTEXT_TTL_DAYS
opencodeCleanup runs:
- once during plugin initialization
- after each snapshot save
Cleanup behavior:
- deletes expired snapshots and their paired logs
- deletes stale logs without a valid snapshot (when expired)
- deletes invalid/stale latest pointers
- Triggered on
session.idle,session.compacted, andsession.deletedafter snapshot save. - Writes one proposal file per worktree hash under
context-memory/handoff-proposals/. - Does not auto-write or modify workspace
HANDOFF.md. - Applies churn guard: if proposal content is unchanged, it skips rewriting.
Proposal format includes metadata and source pointers:
- confidence level plus bounded multi-signal
confidenceScore(evidence count, files touched, tools used, recent user goals) - source snapshot path and source log path
- exactly four sections:
## Now,## Decisions,## Next,## Risks(3-5 bullets each) ## Decisionsfavors concise decision/rule/policy bullets and filters noisy assistant-note fragments (status chatter, recall headings, long response blocks)
- Open the latest proposal in
context-memory/handoff-proposals/<worktree-hash>.md. - Verify each bullet against
sourceSnapshotandsourceLogmetadata pointers. - Copy only confirmed bullets into workspace
HANDOFF.md(Now/Decisions/Next/Risks). - Keep uncertain items explicitly marked as assumptions.
- Save
HANDOFF.mdmanually.
Each snapshot stores:
sessionID,worktree,savedAtrecentUserGoalsrecentAssistantNotesrecentDialogue(last 5 turns with role)toolsUsedfilesTouchedevidenceCount
Text is trimmed with markdown-aware balancing to reduce broken inline/fenced code in restored hints.
- Best-effort design: logging/snapshot failures do not block normal OpenCode flow.
- Snapshot restore is recall-only and is not injected into normal sessions.
- Restored context is a hint, not source of truth.
- No secret masking layer is included in this plugin.
- Start a session and do a few actions.
- Let it reach idle (or compact/delete the session).
- Confirm files are created in
context-memory/logs,context-memory/snapshots, andcontext-memory/handoff-proposals. - Start a new session and verify recovered context is added only when you send a recall-intent message.
Optional typecheck:
npx tsc --noEmit --target ES2022 --module ESNext --moduleResolution bundler --types node "plugins/index.ts" "plugins/lib/hooks/context-memory.ts" "plugins/lib/hooks/history-recall-router.ts"
{ "plugin": ["oh-my-opencode-slim", "./plugins/index.ts"] }