dsh-recall
DSH 0.2.1-rc.2 plugin. Node >=24; developed and tested locally with Node 26 / TypeScript 5.9.3. Release CI is configured for Node 24; that CI run is separate from local verification.
Install from a GitHub Release
After a release is published, install its built archive into your DSH profile:
dsh plugin --profile headless add https://github.com/LIghtJUNction/dsh-recall/releases/download/v0.1.0/lightjunction-dsh-recall-0.1.0.tgz
dsh headless --dump-config
The release URL is the expected v0.1.0 asset location, not a claim that it has already been published. Use the archive and SHA256SUMS attached to the same GitHub Release. The package includes a DSH bundle patch and built JavaScript; no Pi dependency is needed. Restart DSH after installation. Substitute your existing profile for headless if needed.
Configuration
The default bundle config is {}: each tool uses the invoking agent's working directory. A host call without an agent requires an explicit root. To pin a host-local workspace, add an override in your profile's cordis.patch.yml:
- id: dsh-recall
config:
root: /absolute/local/project
The root must already exist. It is interpreted on the DSH host, using Node filesystem APIs. A remote DSH world or sandbox does not redirect these operations: only enable this plugin for a host-local project. This is not a remote-world adapter or a security sandbox.
Tools and examples
recall_save({role:"user",text:"We chose SQLite for the local cache",sessionId:"optional-source-id"})saves only the explicitly provided excerpt. The source ID defaults to the current agent ID, ormanualfor a host call. Exact duplicate role/text/session combinations return the existing record.recall_search({query:"sqlite cache",limit:10})performs literal case-insensitive AND matching on saved text, newest first. Omit the query to list saved excerpts. Results includeid,revision,role,text,sessionIdandsavedAt.recall_delete({id:"",expectedRevision:""})removes one saved excerpt only when its revision matches. An unknown ID or stale revision fails explicitly.
Ask DSH: “Explicitly save this decision in recall: we chose SQLite for the local cache.” Later: “Search recall for sqlite cache.” Excerpts are untrusted quoted conversation data, not instructions. No session log is automatically searched, copied or summarized. Caller-supplied role/session attribution is not independently authenticated.
Storage and limits
The store lives in /.dsh-recall/records.json. The directory is created with mode 0700 and replacement files with mode 0600 (subject to filesystem/platform behavior). This is plaintext, not encryption: save only material appropriate to keep in this project, exclude .dsh-recall/ from version control, and do not save secrets. This plugin intentionally does not edit your .gitignore.
At most 200 records / 4 MiB total, 50,000 UTF-8 bytes per excerpt, 200 characters per session ID, 500 per search query, and a search limit of 1–50. Traversal, symlink storage paths and nonregular files are rejected. Malformed stores fail closed; they are never silently reset. Search does not create storage. Records survive DSH/plugin restarts and are shared across agents using the same local root.
Writers acquire .dsh-recall/write.lock exclusively. Concurrent writers fail with “store busy” and can retry; accepted writes use a fsynced temporary file and atomic rename so readers see a complete old or new store. Temporary files and locks are removed on normal success/failure. A process crash can leave a lock/temp file: stop all writers, inspect/recover the store, then manually remove the stale lock/temp. There is no automatic stale-lock stealing or crash-time directory fsync guarantee. Cancellation is checked before commit and work is drained on dispose; a rename already committed is not rolled back by a later cancellation.
No Pi picker/menu, global Pi store migration, Markdown notes/templates, automatic session capture, DSH session-search replacement or automatic prompt injection is provided.
Filesystem boundary and verification
Path checks reject ordinary symlink redirection; regular-file opens use no-follow flags and inode checks, bounded reads and cancellation. These checks are not a sandbox against a malicious process concurrently replacing ancestor directories; use a trusted local workspace. Linux/macOS-style filesystem semantics are the intended target; Windows behavior has not been verified.
npm run check
The suite uses real Cordis, DSH ToolRuntime, agent-loop and an offline scripted model; it verifies actual model tool dispatch and results in the following model request, plus limits, revision/path checks, cancellation and unregistration. It requires no live model credentials. check includes TypeScript checks for source/tests, behavior tests and a build. See UPSTREAM.md for pinned source and migration differences and NOTICE for upstream MIT attribution.