npm.io
0.3.13 • Published yesterday

opencode-hindsight-plus

Licence
MIT
Version
0.3.13
Deps
2
Size
169 kB
Vulns
0
Weekly
0

opencode-hindsight-plus

Hindsight memory plugin for OpenCode — persistent long-term memory with Claude Code-aligned per-turn auto-recall.

Fork of @vectorize-io/opencode-hindsight with per-user-turn memory injection (see SOURCE.txt).

Features

  • Custom tools: hindsight_retain, hindsight_recall, hindsight_reflect — the agent calls these explicitly
  • Per-turn auto-recall: On every user message, queries Hindsight with the current prompt (Claude Code UserPromptSubmit alignment). Default recallContextTurns: 1 uses only the latest user text — no full-session re-fetch (Claude recall.py path). Multi-turn prior context (recallContextTurns > 1) is composed from the transform payload already in hand. Default inject mode is synthetic-user (a synthetic: true text part on the latest user message, closer to Claude additionalContext). Set recallInjectMode: "system" to fold into system[0] instead (that path still loads session messages). Tool-loop reuses the turn cache. Successful inject logs at INFO (chars). Optional TUI toast via "injectToast": true (fresh inject only; tool-loop silent).
  • Multi-bank recall: recallAdditionalBanks merges results from extra banks (Claude recallAdditionalBanks).
  • Auto-retain: Captures conversation on session.idle (Claude Code Stop alignment). Throttle is Claude-style userTurns % retainEveryNTurns === 0. Transcripts are sanitized (strip U+0000 / C0 controls) before retain.
  • SessionEnd flush: Force-retains any pending turns on session.deleted and plugin dispose (Claude Code SessionEnd alignment), even when under retainEveryNTurns
  • Tool trajectory retain (opt-in): Set retainToolCalls: true to include tool call inputs/outputs in retained transcripts (skips hindsight_* tools). Default is false (Claude Code-aligned) to avoid fact/consolidation blowups from agent tool noise
  • Retain tag templates: retainTags / retainMetadata support {session_id}, {bank_id}, {timestamp}, {user_id} (empty user: tags dropped when unset)
  • Bank routing: directoryBankMap (path → bank) + resolveWorktrees (linked worktrees share main-repo bank) — Claude bank.py order
  • Coding-oriented bank missions: default bankMission / retainMission guide fact extraction
  • Tools: hindsight_retain / recall / reflect, hindsight_bank_current, hindsight_ingest, hindsight_ingest_file, plus hindsight_page_* knowledge pages (Claude agent_knowledge_* equivalents)
  • Compaction hook: Retains + injects query-relevant memories during context compaction so they survive window trimming

Quick Start

The plugin defaults to Hindsight Cloud (https://api.hindsight.vectorize.io). Just enable it and provide your API key.

1. Enable the plugin

Add to your opencode.json (project) or ~/.config/opencode/opencode.json (global):

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

OpenCode auto-installs plugins listed here on startup — no npm install required.

2. Provide your Hindsight Cloud API key

Get an API key at ui.hindsight.vectorize.io/connect, then:

export HINDSIGHT_API_TOKEN="your-api-key"

# Optional: override the memory bank ID (defaults to "opencode")
export HINDSIGHT_BANK_ID="my-project"

That's it — the plugin now reads/writes against your Cloud bank.

Using a self-hosted Hindsight instance

Point HINDSIGHT_API_URL at your server (the API key is then optional):

export HINDSIGHT_API_URL="http://localhost:8888"

Or configure inline in opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": [
    [
      "opencode-hindsight-plus",
      {
        "hindsightApiUrl": "http://localhost:8888"
      }
    ]
  ]
}

Configuration

Plugin Options

Pass options directly in opencode.json:

{
  "plugin": [
    [
      "opencode-hindsight-plus",
      {
        "hindsightApiUrl": "http://localhost:8888",
        "bankId": "my-project",
        "autoRecall": true,
        "autoRetain": true,
        "recallBudget": "mid"
      }
    ]
  ]
}
Config File

Create ~/.hindsight/opencode.json for persistent configuration:

{
  "hindsightApiUrl": "http://localhost:8888",
  "hindsightApiToken": "your-api-key",
  "recallBudget": "mid",
  "retainEveryNTurns": 3,
  "debug": false
}
Environment Variables
Variable Description Default
HINDSIGHT_API_URL Hindsight API base URL https://api.hindsight.vectorize.io
HINDSIGHT_API_TOKEN API key for authentication (none — required for Hindsight Cloud)
HINDSIGHT_BANK_ID Static memory bank ID opencode
HINDSIGHT_AGENT_NAME Agent name for dynamic bank IDs opencode
HINDSIGHT_AUTO_RECALL Auto-recall on every user turn true
HINDSIGHT_AUTO_RETAIN Auto-retain on session idle true
HINDSIGHT_RETAIN_MODE full-session or last-turn full-session
HINDSIGHT_RECALL_BUDGET Recall budget: low, mid, high mid
HINDSIGHT_RECALL_MAX_TOKENS Max tokens for recall results 1024
HINDSIGHT_MIN_RECALL_PROMPT_CHARS Skip auto-recall when user prompt is shorter 5
HINDSIGHT_RETAIN_TOOL_CALLS Include tool call/result parts in retained transcripts false
HINDSIGHT_RETAIN_TAGS Comma-separated retain tags (templates supported) {session_id}
HINDSIGHT_USER_ID Used by {user_id} template in retain tags/metadata (empty)
HINDSIGHT_ENABLE_KNOWLEDGE_PAGES Register hindsight_page_* tools true
HINDSIGHT_RECALL_INJECT_MODE synthetic-user (default) or system synthetic-user
HINDSIGHT_INJECT_TOAST Show TUI toast on fresh memory inject false
HINDSIGHT_RECALL_ADDITIONAL_BANKS Comma-separated extra banks to merge on recall (none)
HINDSIGHT_RECALL_TAGS Comma-separated, filter recalls (none)
HINDSIGHT_RECALL_TAGS_MATCH Tag match mode: any, all, any_strict, all_strict any
HINDSIGHT_RETAIN_TAGS Comma-separated, added to every retain (none)
HINDSIGHT_DYNAMIC_BANK_ID Enable dynamic bank ID derivation true
HINDSIGHT_RESOLVE_WORKTREES Share bank across git linked worktrees true
HINDSIGHT_BANK_MISSION Bank mission/context (none)

Debug logging is a config-only option ("debug": true in opencode.json plugin options or ~/.hindsight/opencode.json) — there is intentionally no HINDSIGHT_DEBUG env var, because environment variables are unreliable to set for OpenCode's plugin runtime (notably on Windows). Errors and the resolved API URL/bank are logged regardless of this setting; debug only adds verbose tracing. All plugin logs go to OpenCode's log stream (service=hindsight), visible with --print-logs or in the OpenCode log files.

Configuration Priority

Settings are loaded in this order (later wins):

  1. Built-in defaults
  2. ~/.hindsight/opencode.json
  3. Plugin options from opencode.json
  4. Environment variables

Tools

hindsight_retain

Store information in long-term memory. The agent uses this to save important facts, user preferences, project context, and decisions.

hindsight_recall

Search long-term memory. The agent uses this proactively before answering questions where prior context would help.

hindsight_reflect

Generate a synthesized answer from long-term memory. Unlike recall (raw memories), reflect produces a coherent summary.

Knowledge pages (enableKnowledgePages, default true)
Tool Purpose
hindsight_page_list List page ids/names
hindsight_page_get Read full page content
hindsight_page_create Create page (name + source_query, optional page_id)
hindsight_page_update Update name / source_query
hindsight_page_delete Delete page
hindsight_page_refresh Re-run source_query against current memories

Disable:

{ "enableKnowledgePages": false }

Dynamic Bank IDs (per-project isolation)

Default: dynamicBankId: true with dynamicBankGranularity: ["gitProject"].

Each git repository gets its own memory bank (main worktree basename). Linked worktrees of the same repo share one bank. Non-git directories fall back to the working-directory basename.

Field Meaning
gitProject Main worktree basename (default) — worktrees share memory
project Working directory basename — worktrees may split
agent agentName (default opencode)
channel / user From HINDSIGHT_CHANNEL_ID / HINDSIGHT_USER_ID

Disable isolation (single global bank):

{
  "dynamicBankId": false,
  "bankId": "opencode"
}

Or set:

export HINDSIGHT_DYNAMIC_BANK_ID=false
export HINDSIGHT_BANK_ID=opencode

Compose multiple dimensions:

{
  "dynamicBankId": true,
  "dynamicBankGranularity": ["agent", "gitProject"]
}

Note: The bank ID is derived once when the plugin loads for a directory. For per-user isolation, set env vars before launching OpenCode:

export HINDSIGHT_CHANNEL_ID="slack-general"
export HINDSIGHT_USER_ID="user123"

Development

npm install
npm test        # Run tests
npm run build   # Build to dist/

License

MIT

Keywords