00080000/dsh-project-memory ↗★ 13
@yolk_vat-y/dsh-project-memory
Persistent project memory for dsh agents: index docs (PDF/Markdown/text) and code symbols into a searchable per-workspace store, recall them with cited sources, and keep experience entries (problems -> solutions) searchable on demand. 适合持续处理大项目并需快速定位事实时使用,需先完成工作区索引后查询
Install
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:00080000/dsh-project-memoryREADME
Read the full README ↗Usage
The tools below are invoked by the agent, not typed by the user. In the chat, just ask naturally — e.g. "index this project" or "what does the auth module do?" — or simply keep working, and the agent calls the matching tool automatically. By default (lazyIndexing) files are indexed the moment the model reads them, so memory fills in while you work. watch_repo keeps explicitly-watched roots fresh in the background; index_repo forces a full backfill of a project (unchanged files are skipped).
| Tool | Purpose |
|---|---|
index_doc file_path | Index one document (PDF/MD/txt): chunk → deterministic summary + whole-chunk terms → store with path:line. Unchanged files are skipped. |
index_repo root | Index a whole project: docs get deterministic summaries + whole-chunk terms, code files get a zero-token symbol table. Incremental, cleans up deleted files, cross-links docs to symbols. |
watch_repo root | Enable automatic refresh: a background poll detects new/changed files (mtime + content hash) and re-indexes only those. Watched roots persist across plugin restarts. |
memory_stats root | Show what the store contains: totals (files / entries / experience notes), last index time, and the per-file list sorted by recency. |
query_memory query | BM25 search over docs + symbols + experience + insights (lessons / decisions / procedures), optionally query-expanded by the LLM. type selects a layer (all / doc / symbol / experience / insight / task). Returns ranked hits with relative scores, sources or insight ids, and doc→symbol references. |
list_tasks | List task records for the project (archived marked). Call first in a new session before continuing work. |
select_task | Bind the session to a task so its todo list and file reads sync into it. Exact taskId, or exact title (multiple matches return candidates; no match creates a new task). Pass title with taskId to rename. Auto-unarchives. |
archive_task | Archive a task (hide from default views, exclude from capacity, stop syncing). select_task restores it. |
show_task_panel | Show the task panel in the UI. Call when the user asks to see the task list or when you want to display the panel. |
/tasks (typed by the user, not the model) | Shows the task stack: title, step progress, involved files, and which task the current session is bound to. |
/task (typed by the user, not the model) | Task panel subcommands: switch / archive / unbind / rename / todos. Invoked by panel buttons/clicks; does not go through the model. |
/insight (typed by the user, not the model) | v0.5 memory view actions (panel buttons): `list [task |
remember problem solution | Save an experience note. Similar problems supersede instead of duplicating. |
forget id_or_query | Delete stale experience notes. |
save_lesson (agent tool) | Save a lesson/decision/procedure at task/project/global scope (single insight entity). Near-duplicates merge (≥ 0.7 overlap) or reinforce (0.65–0.7); 2+ tasks hitting the same insight auto-promote task → project, 3+ → global. Params: title, kind, scope, pattern/fix or choice/reason or steps, trigger (keywords/symbols/actions/paths/scope — any kind; a hit injects the entry before the action), task_id, files, symbols, confidence, root. |
Configuration
| Key | Default | Meaning |
|---|---|---|
memoryDir | .dsh-project-memory | store directory inside each indexed root |
chunkChars | 3000 | max chars per document chunk |
maxChunksPerFile | 40 | max chunks per document |
maxFileSizeMb | 50 | skip documents (incl. PDF) and code files larger than this (MB) |
maxOutputChars | 8000 | cap for query_memory result text (chars) |
tasklist.enabled | true | enable TaskBridge auto-sync (task entities from the session todo list and file reads) |
tasklist.syncHostOnAdopt | true | when select_task//task switch binds a task, push its steps to host todo/write so dsh's task list mirrors the task |
maxPdfPages | 1000 | PDF page cap when pages are not otherwise limited |
llmQueryExpansion | false | expand queries via ctx.llm before BM25 (off by default to save tokens) |
expansionCount | 6 | max expansion variants |
lazyIndexing | true | index files the moment the model reads them (fs/observed) |
autoIndexOnFirstUse | false | full scan of the current working directory on plugin load (opt-in) |
watch | true | enable the background refresh |
watchInterval | 15 | poll interval (seconds) |
tsPath | (auto) | optional absolute path to a specific typescript install; if omitted, resolves from project cwd → plugin node_modules |
enableTypeScript | true | set false to disable L2 TS enhancement entirely (L1 regex only) |
insight.* | dedupOverlap 0.7 · reinforceBand 0.65 · maxProject 100 · maxGlobalProcedures 200 · promoteConfidence 0.7 · globalPromoteTasks 3 · decayDays 90 · globalFile (auto) | v0.5 insight dedupe / reinforce / promotion / capacity / archive settings |
reflection.enabled | false | v0.5 LLM reflection, draft-only at task level (fires on task switch-away / archive). cooldownMs 1800000, maxLessonsPerReflect 3, maxDecisionsPerReflect 2 |
autoContext.enabled | true | v0.5 silent injection wrapper (entry block + relevance). Inert (full passthrough) until the host exposes a resolvable session cwd; maxTokens 400, editedMax 3 (how many recently-written "editing now" files the resident task card shows), signalMinRatio 0.5 (a hint must reach half of its layer's top score), skipEchoSelfTodo true (don't echo the task card back when the model itself maintains the task list with no newer human message; relevant insights still inject) |
Toggling features
The two most relevant switches are lazyIndexing (index a file the moment the model reads it; default on) and autoIndexOnFirstUse (full scan of the current working directory on plugin load; default off). Lazily indexed project roots are automatically registered with the watcher, so changed files stay fresh without an explicit watch_repo.
Settings live in the plugin's config object. To change them, add an override entry to your profile's cordis.patch.yml — for the web profile that is ~/.dsh/profiles/web/cordis.patch.yml:
- id: project-memory
config:
lazyIndexing: true # on: index files as the model reads them (default)
autoIndexOnFirstUse: false # off: no upfront full scan (default)
llmQueryExpansion: false # off: do not spend tokens on LLM query expansion (default)
watch: true # on: background refresh for watched roots (default)
watchInterval: 15 # poll interval in seconds
enableTypeScript: true # on: L2 TS enhancement when TS is installed (default)
# tsPath: /custom/path/to/typescript # optional: force specific TS install
Only list the keys you want to change; the rest fall back to the plugin defaults. Verify the result with dsh --profile web --dump-config.
For a one-off run without editing the profile, pass the override as a CLI patch overlay:
dsh web --patch ./config.yml
where config.yml contains the same override block.