Agent Skillsvectorize-io/hindsight › hindsight-coding-agent

hindsight-coding-agent

GitHub

管理编码会话的长期记忆插件,支持自动知识入库、检索、反思及修正。适用于存储记忆、配置内存库或排查记忆相关问题。

hindsight-integrations/coding-agents/skill/SKILL.md vectorize-io/hindsight

Trigger Scenarios

用户要求存储或记住信息 询问记忆页面功能 配置每仓库内存(禁用、重命名、Git深度) 记忆相关功能异常

Install

npx skills add vectorize-io/hindsight --skill hindsight-coding-agent -g -y
More Options

Non-standard path

npx skills add https://github.com/vectorize-io/hindsight/tree/main/hindsight-integrations/coding-agents/skill -g -y

Use without installing

npx skills use vectorize-io/hindsight@hindsight-coding-agent

指定 Agent (Claude Code)

npx skills add vectorize-io/hindsight --skill hindsight-coding-agent -a claude-code -g -y

安装 repo 全部 skill

npx skills add vectorize-io/hindsight --all -g -y

预览 repo 内 skill

npx skills add vectorize-io/hindsight --list

SKILL.md

Frontmatter
{
    "name": "hindsight-coding-agent",
    "description": "How this machine's Hindsight coding-agent memory works — the plugin behind the 🧠 banner. Use when the user says \"store\/remember this in hindsight\", asks what the memory\/knowledge pages are, wants to configure per-repo memory (disable, rename banks, git depth), or something memory-related looks broken."
}

Hindsight Coding-Agent Memory

This machine runs the hindsight-coding-agents plugin: long-term project memory for coding sessions, backed by a Hindsight server. You (the agent) are already wired into it — this skill explains what happens automatically, which tools you have, and how to configure or debug it.

What happens automatically (no action needed)

  • Per-repo memory bank: each repository resolves to a bank (shown in the session banner: ↳ memory bank “coding-agent::<repo>”). Worktrees share the main repo's bank.
  • Ingestion builds itself: on first open, the bank is seeded from recent commit messages and a read-only codebase survey; every session start, a background engine tops it up (new commits, new conversations) and keeps 5 knowledge pages current. There is NO ingest command to run.
  • Session synthesis: by default, the first prompt of a session triggers one deep memory synthesis (reflect) injected into context. With autoReflect=false, the agent searches the knowledge pages first and reflects only when they are too shallow.
  • Write-back: the session transcript is retained into the bank automatically at session end (per-turn on opencode). The user never needs to "save" a conversation.

Storing things deliberately

When the user says "store this in hindsight" / "remember this":

  • The current conversation is captured automatically at session end — say so; no tool needed.
  • An external document, notes, or durable findingshindsight_ingest_document(title, content).
  • A new feature/initiative being startedhindsight_capture_initiative(title, summary), right after the plan is agreed and before code is written.
  • A plan that materially changed (goal, scope, or rationale — including mid-implementation) → call hindsight_capture_initiative again with relates_to_page_id set to that initiative's page id, summarising the current intent. Same page, updated plan — never a second page. Trivial course-corrections don't count.

Retrieving

  • hindsight_search_knowledge_pages(query) — FIRST STOP for project questions (components, conventions, past decisions, initiatives). Server-side hybrid search, fast.
  • hindsight_read_knowledge_page(page_id) / hindsight_list_knowledge_pages — read pages fully.
  • hindsight_reflect(query) — deep reasoning over the whole memory for WHY questions and exact decided values; slower (seconds), use deliberately.
  • Credit visibly whenever memory informs an answer: start that part with 🧠 From Hindsight memory (<page>): … — and never credit memory that didn't contribute.

Correcting wrong or stale memory

If you verify that something Hindsight served is wrong or outdated (the code, git, or an external source contradicts it), FIX THE RECORD — don't just ignore it. Call hindsight_ingest_document with:

  • title: Correction: <topic> (e.g. Correction: retry policy 4xx set)
  • content: (1) what memory claimed, (2) what is verifiably true now, (3) the evidence you checked (file/commit/output). Quote exact values verbatim.

Newer facts supersede older ones in retrieval, so one clear correction permanently outranks the stale memory. Do this whenever you catch a wrong injected memory, a stale knowledge-page claim, or an outdated decision — silent disregard leaves the trap armed for the next session.

Install / update

npx @vectorize-io/hindsight-coding-agents install all          # every detected agent, wired natively
npx @vectorize-io/hindsight-coding-agents install claude-code  # or just one
npx @vectorize-io/hindsight-coding-agents uninstall all        # removes exactly what install added
npx @vectorize-io/hindsight-coding-agents update               # refresh the runtime only, no rewiring

install takes an explicit target — all, or one or more harness names. A bare npx @vectorize-io/hindsight-coding-agents install changes nothing and prints the choice, so wiring every agent on the machine is never something that happens by accident. Updating is the same install command again — it re-copies the runtime in place.

Day to day you should not have to: once a day, a session start checks npm and re-stages a newer runtime in the background (autoUpdate, on by default — set it to false to pin the version you have). That is the update command above, which refreshes the copy every wired agent already points at and deliberately touches no host config; re-run install yourself after a release that adds a new hook, or to wire another agent.

Local daemon settings (daemon mode)

Daemon settings keep the names the old per-agent Claude Code plugin used, so an existing environment carries over unchanged:

field env default meaning
serverMode HINDSIGHT_SERVER_MODE cloud cloud | self-hosted | daemon
apiPort HINDSIGHT_API_PORT 9077 port the local daemon listens on
daemonIdleTimeout HINDSIGHT_DAEMON_IDLE_TIMEOUT deprecated, ignored: the daemon no longer exits on its own
daemonProfile HINDSIGHT_DAEMON_PROFILE coding-agent which local database it uses
embedVersion HINDSIGHT_EMBED_VERSION latest which hindsight-embed release to run
embedPackagePath HINDSIGHT_EMBED_PACKAGE_PATH run a local checkout instead (development)

Any HINDSIGHT_API_* variable you export is forwarded to the daemon, so server-side settings need no equivalent here.

Configuration

Configuration is one JSON file: ~/.hindsight/coding-agent.json. Layering, later wins per field:

  1. built-in defaults
  2. environment variables — HINDSIGHT_API_URL, HINDSIGHT_API_TOKEN, and one per scalar setting (HINDSIGHT_<FIELD_IN_CAPS>), for containers and CI that inject config rather than write a file
  3. the file's top level
  4. its harnesses.<name> section — per-agent override
  5. its banks.<resolvedBankId> section — per-repo override, applied after the bank is resolved (see Per-repo opt-in/out)

Environment variables are a fallback: the file wins wherever it sets a value, so adding env to an existing setup changes nothing. The two list-valued settings, retainTags and optInPaths, take a comma-separated value (HINDSIGHT_RETAIN_TAGS="project:{gitProject},env:work"); entries are trimmed and blanks dropped. The map-valued settings (mapPathToBank, harnesses, banks, retainMetadata) are file-only — per-key branching doesn't survive flattening into one variable. maxParallelRetains is available as HINDSIGHT_MAX_PARALLEL_RETAINS for containers and CI.

HINDSIGHT_CONFIG moves the file itself — point it at another path for a container or a test harness where $HOME is not the right anchor. It is still exactly one file; only its location changes. (The other variables that are not settings are HINDSIGHT_LOG_FILE, HINDSIGHT_DIAG_FILE and HINDSIGHT_LOG_LEVEL — see Diagnostics & logging.)

When a change takes effect

Config is read when a process starts — the file is not watched — so when an edit applies depends on what reads it:

host reads the file an edit applies
hook harnesses (Claude Code, Codex CLI, Cursor CLI, GitHub Copilot CLI, Grok Build, Antigravity CLI, Devin) once per hook invocation — each hook is its own short-lived process on your next prompt
persistent plugins (opencode, opencode 2, Kilo CLI, Cline CLI, pi, Prime Agent, DeepSeek Harness) once per workspace, when the host loads the plugin after restarting the agent
the MCP server behind the hindsight_* tools once at startup in your next session

apiToken is the exception. Every host re-reads it when the server rejects a request, so enabling authentication or rotating the key is picked up on the next call with nothing to restart — otherwise a rotation would leave a long-running agent failing every memory call until it was restarted. Everything else follows the table: apiUrl, disabled, bank routing, gitIngest, and the survey and knowledge-page settings.

hindsight_diagnose reports both sides of that gap — what the file says now, and what the running client is actually using.

Opt-in only

By default every project gets memory — that is what makes the plugin zero-setup. If you would rather nothing be remembered until you say so, turn memory off everywhere and name the projects that may use it:

{
  "optInOnly": true,
  "optInPaths": ["~/work/client-x", "~/oss"],
}

Anything outside those paths is inert: no bank is created, nothing is retained, no seed runs, and the agent behaves exactly as it would without the plugin. Approving costs nothing else — optInPaths says which projects, not which bank, so an approved repo keeps its usual coding-agent::{gitProject} name. Paths are prefixes, so approving ~/work approves every repo under it while each still gets its own bank.

A mapPathToBank entry counts as opted in too, since routing a path to a named bank already declares that project. A bare bankId does not: it names a bank rather than a project, so it cannot say which work may be remembered, and a privacy switch has to fail closed.

There is no per-repo opt-in file, for the same reason there is no repo-carried config at all: a cloned repository must not be able to turn memory on.

There is deliberately no repo-carried config file — per-repo bank routing is mapPathToBank, per-agent differences are harnesses.<name>.

Each entry point knows which harness it is (the opencode plugin is loaded by opencode, the codex hook by Codex...), so one shared config serves several agents side by side:

{
  "apiUrl": "https://api.hindsight.vectorize.io",
  "harnesses": {
    "opencode": { "reflectTimeoutMs": 60000 },
    "claude-code": { "disabled": true }, // e.g. memory off for Claude only
  },
}

Reference

field default meaning
apiUrl https://api.hindsight.vectorize.io Hindsight API base URL (set to http://localhost:8888 for a local server)
apiToken bearer token (Hindsight Cloud). Picked up without restarting the agent: a long-lived host re-reads it after a rejected request, so enabling auth or rotating the key mid-session recovers on the next call
bankId explicit static bank; unset ⇒ per-repo dynamic resolution (below)
dynamicBankId dynamic iff no bankId force dynamic (true) or static (false) resolution
bankIdTemplate "coding-agent::{gitProject}" dynamic bank id format; the default makes every agent share one bank per repo
mapPathToBank absolute path → bank; longest prefix wins; linked worktrees inherit their main checkout's mapping; overrides everything
optInOnly false run memory ONLY in opted-in projects — everything else is inert, with no bank created; see Opt-in only
optInPaths directories opted in, matched as prefixes with ~ expanded; each repo beneath and its linked worktrees are approved while keeping their own dynamic bank
resolveWorktrees true linked worktrees inherit the main checkout's bank identity, path approval, and mapping
retainTags extra tags on every document written by the integration, e.g. ["project:{gitProject}"] — see Recording where a memory came from below
retainMetadata extra metadata on every document written by the integration, e.g. {"repo": "{gitProject}"}
manageBankConfig true let the plugin shape the bank's own configuration — the retain strategies it writes under, the knowledge entity-label group, and, on a bank that has none, the missions. Writing is strictly additive: it adds what the bank does not define and never overwrites what is there, so your control-plane edits survive. Set false to keep it out of the bank config entirely — see A bank you shape yourself below
observationScopes "shared" how consolidation groups observations: "shared" (default) = ONE global scope per bank, so every agent on a repo builds one set of beliefs; also "combined" (the server default), "per_tag", "all_combinations", [["t"]]; "per_source" adds a scope per source: kind alongside the global one, so commit knowledge and conversation knowledge consolidate apart
disabled false hard off-switch (inert plugin/hook — a no-memory baseline)
reflectTimeoutMs 120000 automatic session-reflect timeout (hook harnesses additionally cap it at 25s to fit the host's hook window); on timeout the session runs without reflect (recorded)
reflectToolTimeoutMs 330000 timeout for the agent-invoked hindsight_reflect tool — a call the agent waits on, whose high-budget synthesis on a populated bank runs for minutes. Defaults above the server's own reflect wall timeout (HINDSIGHT_API_REFLECT_WALL_TIMEOUT, 300s) so the server decides when to give up. Unset, it inherits an explicitly raised reflectTimeoutMs, but a short one never lowers it
reflectBudget "high" reflect budget for the hindsight_reflect tool: "low", "mid" or "high". Drop it on a large bank where high-budget synthesis exceeds the server's wall timeout. The automatic session-start reflect always uses "low" to fit its hook window and is unaffected
autoReflect true inject a one-time reflect synthesis on the session's first prompt. false = tool-only reflect: nothing is injected; the agent searches knowledge pages first and reflects only when they are too shallow
pageRefreshEveryTurns 10 refetch the knowledge pages and re-inject the page roster + tool guide every N user turns
pageTriggerType "auto-refresh" when NEW knowledge pages refresh, i.e. what keeping them current costs — "auto-refresh" after every consolidation that produced new material, "cron" on pageTriggerCron only, "manual" never on their own. Auto-refresh is the most current and the most expensive: one synthesis per page per consolidation. Maps to the page's trigger.refresh_after_consolidation in the Hindsight API (true for auto-refresh, false for manual)
pageTriggerCron schedule for pageTriggerType: "cron" — UTC, standard 5-field cron, e.g. "0 3 * * *". Sets the page's trigger.refresh_cron, which the API treats as mutually exclusive with refresh_after_consolidation; a scheduled refresh is skipped when nothing changed. Write a field as H to give each page its own value there — see Spreading refreshes with H below
autoSeed true SessionStart: auto-seed a cold repo's bank from git history
seedLimit 300 auto-seed: most-recent-N-commits cap
codebaseSurvey true SessionStart: headless survey of a cold repo's structure, run under the current harness's own CLI (claude/codex/antigravity/opencode), falling back to any available agent
surveyModel haiku model for the survey — Claude recipe only (claude -p --model); other agents use their configured default
surveyBudgetUsd 2 survey spend cap — Claude recipe only (claude -p --max-budget-usd); other agents rely on their read-only sandbox
surveyRefreshCommits 20 re-run the survey at SessionStart once this many commits have accrued since the last one, so the structural pages track an architecture that keeps moving (0 = survey a cold repo only, never again)
retainSessions true session write-back, honored by every harness: hook harnesses write the transcript on Stop, Factory Droid also writes on its cancellation notification, and plugin harnesses (opencode, opencode 2, Kilo) upsert it every turn plus an idle flush that captures the reply the per-turn pass can't see. Set false - globally, per harness, or per bank - to stop writing transcripts (the background history import stops with it) while recall, git ingest and the memory tools keep working
maxParallelRetains 10 cap on concurrent retain-related requests: drain()'s per-op polls plus deepen's chat/git retain pools. The API rate-limits bursts, not single requests — if you see 429s, lower this rather than raising it
logLevel "info" plugin-log verbosity ("debug" | "info" | "warn" | "error"); HINDSIGHT_LOG_LEVEL env overrides
autoUpdate true keep the installed runtime current by itself: once a day a session start asks npm for the published version and, when it is newer, re-stages ~/.hindsight/coding-agents in the background. It rewires no host config, so a release adding a new hook entry point still needs a manual install. Set false to pin the installed version; disabled stops it too, since an inert plugin should stay inert. Only ever replaces a runtime installed the documented way, via npx — a copy installed with npm i -g, vendored as a project dependency, or built from a checkout is left to whoever manages it (update those the way you installed them), and it needs npx on PATH
gitIngest "message" git depth for seeding AND staying current (same engine): "message" = commit messages only (one doc, re-upserted when HEAD moves); "full" = messages + per-commit full diffs (progressive, newest first); "none" = git off
harnesses.<name> per-harness override of any field above
harness opencode deepen engine only: which session format --conversations is read as

pageTriggerType/pageTriggerCron decide only when a page refreshes. How it refreshes belongs to the server: Hindsight creates a knowledge page with a delta refresh (each pass edits the page instead of rebuilding it) that doesn't reflect over sibling pages, and these settings merge over those defaults rather than replacing them.

Spreading refreshes with H

One pageTriggerCron is shared by every page in every repo you point this plugin at. So a literal "0 3 * * *" does not schedule a refresh at 03:00 — it schedules all of them at 03:00, five pages per bank, on the same worker pool that serves retain. A session ingesting at 03:0x queues behind the pile, and moving the hour just moves the pile.

Write a field as H and it is replaced, per page, by a value hashed from the bank id and the page name. Each page gets its own slot, the same slot on every run:

pageTriggerCron what each page gets
"H H * * *" once a day, at its own minute and hour
"H * * * *" once an hour, at its own minute
"H 3 * * *" daily at 03:MM — spread inside the hour you chose
"H H(0-5) * * *" daily, spread across 00:00–05:59 only
"0 3 * * *" no H, no hashing — exactly what it says, all at once

H is Jenkins' syntax for the same problem. It never reaches the API: the plugin resolves it to an ordinary cron expression ("41 17 * * *") when it creates the page, so the schedule you see in the control plane is a plain one you can edit. Hashing spreads pages out, it does not partition them — two pages can still land on the same minute, just not all of them.

These settings apply to pages created from here on. Changing them does not migrate the pages a repo already has: a page keeps the trigger it was created with, so a bank seeded before you set "manual" keeps refreshing on every consolidation. To move an existing page, change its trigger through the API (PATCH /knowledge-base/nodes/{id}), an SDK, or the control plane — or delete it and let the next session seed it again.

A bank you shape yourself — manageBankConfig

Pointed at a bank, this plugin gives it the shape its ingestion needs: retain strategies for the kinds of document it writes (git, gitlog, conversation, document, survey), a knowledge entity-label group that routes facts to the knowledge pages, and — on a bank that has no missions of its own — the coding missions.

It only ever adds what is missing. A strategy you defined, an edit you made to one of the plugin's, a reworded label group, a mission you rewrote in the control plane: each is left exactly as it is, on every session, forever. What the bank already says wins. The cost of that promise is that a plugin release which rewords an existing strategy or label does not reach a bank that already has it. To take the current default back, clear that override on the bank (delete the strategy, or the whole retain_strategies entry, in the control plane): the next session finds the bank silent there and seeds it again.

Set manageBankConfig: false to keep the plugin out of the bank's configuration altogether — the right setting for a bank you share with non-coding work, or one you configure yourself. That bank should then define the five strategies above itself. Note that the miss is silent: the server does not reject a retain naming a strategy the bank lacks, it logs a warning and extracts with the bank's own configuration — so a commit diff, a session transcript and a survey marker would all get the same generic treatment instead of the extraction each needs. Knowledge pages are seeded either way; pageTriggerType governs what they cost.

Like every field here it can be set per bank, which is usually where it belongs:

{
  "bankId": "my-global-bank",
  "banks": { "my-global-bank": { "manageBankConfig": false } }
}

Per-repo opt-in/out — banks.<bankId>

Per-repo control lives in the SAME file, keyed by the resolved bank id (shown in the session banner) and applied AFTER bank resolution — so it works regardless of where the repo lives, and survives directory moves:

{
  "banks": {
    "coding-agent::secret-client": { "disabled": true }, // blacklist: no memory at all
    "coding-agent::old-name": { "bank": "team::shared" }, // rename / converge banks
    "coding-agent::big-mono": { "gitIngest": "full", "retainSessions": false },
  },
}

Any behavioral field can be overridden per bank, and bank renames the destination (single hop: the section is selected by the resolved id, the target is literal — several ids may converge on one shared bank, and the target's own section is not consulted). Other bank-resolution fields are ignored inside a bank section.

Recipe: two repos, one shared bank

Two ways, by what the natural key is:

By resolved id — you know the repo names; works wherever the repos live (and keeps working if they move). Both ids converge on one literal target:

{
  "banks": {
    "coding-agent::backend": { "bank": "team::product" },
    "coding-agent::frontend": { "bank": "team::product" },
  },
}

By path prefix — the repos live under one directory; a single mapPathToBank entry covers every repo (present and future) beneath it:

{
  "mapPathToBank": { "/Users/me/work/client-x": "client-x-memory" },
}

Rule of thumb: converge by id for a hand-picked set of repos; map by path when a folder is the boundary ("everything I clone under work/client-x shares memory").

Bank resolution

Coding memory is per repository. Resolution order for the working directory:

  1. mapPathToBank — longest matching absolute-path prefix (mapping a repo root covers every subdirectory; deeper mappings win; overrides even an explicit bankId).
  2. Static — bankId set (or dynamicBankId: false).
  3. Dynamic — bankIdTemplate with placeholders:
    • {gitProject} — worktree-aware repo name: git rev-parse --git-common-dir resolves every linked worktree to the main worktree's basename, so all worktrees of a repo share one bank (bare repos use the bare dir name). Outside a repo there is nothing for git to resolve, so it falls back to the basename of the directory the session started in — an agent that cds into a subdirectory keeps writing to one bank, and a subdirectory gets its own bank only when you deliberately start a session there
    • {project} — plain working-directory basename
    • {harness} — the entry point asking (opencode, claude-code, codex, antigravity-cli, cursor-cli, copilot-cli)
    • {channel} / {user}$HINDSIGHT_CHANNEL_ID / $HINDSIGHT_USER_ID

The default "coding-agent::{gitProject}" is harness-neutral, so opencode, Claude Code, and Codex all share one memory per repo — use "{harness}-{gitProject}" to split per agent instead.

Recording where a memory came from

With a bank per repo, the bank is the answer to "where did this come from". On a deliberately shared bank — one bank holding cross-project knowledge so facts recall everywhere — it isn't: every memory looks alike. retainTags and retainMetadata stamp that provenance onto conversations, git history and diffs, survey lifecycle documents, initiative markers, and documents saved through hindsight_ingest_document:

{
  "bankId": "shared", // one bank for everything
  "retainTags": ["project:{gitProject}", "env:work"],
  "retainMetadata": { "repo": "{gitProject}" },
}

Recalls can then filter by project:<repo>, and every document shows which repository it came out of. Both accept the same placeholders as bankIdTemplate{gitProject}, {project}, {harness}, {channel}, {user} — plus {bankId}, {sessionId} and {timestamp}. {gitProject} is worktree-aware here too, so every linked worktree of a repo stamps one name. {sessionId} resolves to unknown for documents that do not originate from an agent session.

The plugin's own source: and harness: tags are reserved: entries in those namespaces are ignored with a warning, so a document's agent attribution always reflects the agent that actually wrote it.

One set of beliefs per repo

Every document this integration writes carries provenance tags — source:chat, harness:<id>, knowledge:<kind>, plus anything from retainTags. Those tags say who wrote a memory; they are what filters recall and draws each document's agent logo, and they stay on the facts.

They are not, however, a good boundary for observations. Consolidation's own default (combined) builds one observation set per distinct tag set, so the same repository worked on by two agents would grow two parallel sets of beliefs — one per harness — that never merge, each blind to the other, at double the consolidation cost. Which agent happened to be typing does not change whether a convention or a decision is true.

So the integration retains with observationScopes: "shared": one global, untagged observation scope per bank, which is what a bank already is — one project's memory. Set the field to change it:

{
  "observationScopes": "combined", // one observation set per distinct tag set (server default)
  "banks": {
    "coding-agent::mono": { "observationScopes": "per_tag" }, // per-repo, like any behavioral field
  },
}

Splitting code from conversation — per_source

shared puts every document a repo produces into one belief set. "per_source" keeps that set and adds one per origin, so "what the commits say" and "what was decided in conversation" can be asked apart:

{ "observationScopes": "per_source" }

Each document consolidates into the global scope plus one named for each source: tag it carries — [[], ["source:chat"]] for a session transcript, [[], ["source:git"]] for a commit diff. Read an axis back with tags: ["source:git"], tags_match: "exact", and the merged view with tags: [], tags_match: "exact".

A document carrying two source: tags gets a scope for each, and that is deliberate rather than duplication. The commit-message seed is tagged source:git and source:git-log, so source:git-log is fed only by the seed — what the commit messages say — while source:git also collects every per-commit diff under gitIngest: "full". Two questions, two answers, each deduplicated within itself by consolidation. A fact belonging to more than one axis is the point.

This cannot be expressed as a scope list. The server treats an explicit list[list[str]] as unconditional — it is not filtered against the memory's own tags — so a configured [[], ["source:git"], ["source:chat"]] writes every document into all three, and the source:git scope fills with beliefs built from chat transcripts. Only a per-document decision separates them.

It costs one extra consolidation pass per document, and it reads only source:, so a volatile provenance tag never becomes a scope. The global scope is still written first and unchanged, so the untagged observations knowledge pages read are unaffected.

"per_tag" and "all_combinations" split further still, and an explicit [["project:demo"], …] declares the scopes literally. HINDSIGHT_OBSERVATION_SCOPES sets the scalar modes; a scope list is file-only. Changing this does not rewrite observations already consolidated under the old scoping — they stay where they were built, and new work accrues under the new setting.

Diagnostics & logging

Two files, two audiences:

Leveled plugin log (humans debugging): $TMPDIR/hindsight-coding-agent/plugin.log (override HINDSIGHT_LOG_FILE) — timestamped LEVEL [scope] message lines from every component, including the ingestion engine. Level defaults to info; set "logLevel": "debug" in config or HINDSIGHT_LOG_LEVEL=debug for ad-hoc debugging (at debug, every diag event below is mirrored here too, so one file tells the whole story).

Structured diag events (machines/harnesses): every reflect and page-fetch outcome is appended as a JSON line to /tmp/hindsight-plugin.log (override with HINDSIGHT_DIAG_FILE):

{
  "ts": "2026-07-27T07:05:52Z",
  "harness": "claude-code",
  "event": "reflect_ok",
  "ms": 14210,
  "chars": 792,
  "query": "..."
}

reflect_failed / pages_failed record the error; if you're comparing memory-on vs memory-off, check this file — a run whose reflects failed is a no-memory run. Seed starts are logged as seed_started.

Is the memory ready yet?

hindsight_sync_status — the agent-facing tool, dist/status.js for scripts — answers exactly that: "synced": true means the seeded memory is queryable. It also reports gitlog freshness, how far per-commit deepening has got, the codebase survey's state (surveyBaseline is the HEAD the last survey started from, surveyDocs counts the findings documents that have landed, 0–4 — a baseline with no findings retries automatically), and the extraction operations still in flight.

Resetting a repo's memory

Delete its bank on the server. The bank is the only state this integration keeps, so the next session in that repo is a true first open — seed and survey run again from scratch. There are no client-side files to clean up.

Marker documents you may notice

Two document ids exist for the machinery's own bookkeeping. Both are safe to ignore and safe to delete:

  • survey-baseline:<sha> — reads "🛰️ researching…" while a codebase survey runs and flips to "✅ completed" once its findings land. It is retained under the survey strategy, whose marker rule extracts nothing from a status marker, and it drives the re-survey cadence (surveyRefreshCommits) and surveyBaseline in sync status.
  • gitlog:<repo> — the aggregated commit-message seed document, re-upserted rather than duplicated when the seed runs again.

When memory seems to be missing

Failures never break the agent: a reflect, page fetch or retain that fails degrades to an ordinary memoryless turn and is recorded in the logs. "No memory" is therefore a log question — check the diag file for whether session_start and deepen_started ever fired for that bank. A session that was already running when the plugin was installed has no SessionStart behind it; its first prompt after the install self-heals.

Version History

  • 134207d Current 2026-09-09 04:57

    引入哈希Cron字段(H)以分散页面刷新时间,避免并发冲突;新增Factory Droid工具链支持。

  • 614bfc9 2026-09-03 06:19

    新增对Pi和Prime Agent的首类支持,统一扩展适配器与安装器;实现基于数据源的观察作用域隔离,区分代码提交与对话记录的记忆归属。

  • cd8d4d3 2026-08-27 19:20

    优化检索策略,改为优先搜索知识页再决定是否需要深度反思;统一文档与技能定义,新增部分配置项说明。

  • ba97f85 2026-08-19 21:38

Same Skill Collection

.claude/skills/code-review/SKILL.md
.claude/skills/hs-release/SKILL.md
hindsight-integrations/agent-plugin/skills/hindsight-memory/SKILL.md
hindsight-integrations/claude-code/skills/create-agent/SKILL.md
hindsight-integrations/cursor/skills/hindsight-recall/SKILL.md
skills/hindsight-architect/SKILL.md
skills/hindsight-cloud/SKILL.md
skills/hindsight-docs/SKILL.md
skills/hindsight-local/SKILL.md
skills/hindsight-self-hosted/SKILL.md

Metadata

Files
0
Version
134207d
Hash
fae97117
Indexed
2026-08-19 21:38

Главная - Вики-сайт
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-09-10 07:41
浙ICP备14020137号-1 $Гость$