dsh-user-preferences
Replacement for dsh-user-prompt. Injects your standing preferences into every model request.
The host half avoids coupling to the settings service and handles optional-service and file errors without failing prompt assembly. A malformed package or missing hard dependency can still prevent activation.
Files (edit in any editor; changes apply on the next request, no restart)
| File | Scope |
|---|
<dshHome>/preferences/global.md | all sessions (dshHome = $DSH_HOME or ~/.dsh) |
<project>/.dsh/preferences.md | nearest to the session cwd; walks up, stops at the repo root (.git) or ~ |
<dshHome>/preferences/settings.json | { "enabled": true, "mode": "section" | "context" }, overrides plugin config live |
Project text takes priority over global text when the budget (maxChars, default 20000) is exceeded.
<!-- html comments --> are stripped, so you can leave notes to yourself.
Modes
section (default): merged into the system prompt (highest authority); {{...}} stays literal.
context: separate user-role snapshot; every {{ is defused so the renderer cannot throw.
Startup resilience
- Only
systemPrompt is a hard dependency; commands / connection are attached lazily via ctx.inject.
- It does not use the
settings service; invalid settings-file values fall back at runtime.
- Prompt registrations and optional attachments are guarded, so an individual registration failure is logged instead of escaping
apply().
- Providers never throw: bad JSON, unreadable or oversized files, a directory in place of a file,
a hostile agent shape all degrade to "inject nothing" plus one deduplicated log line.
- Transient read errors fall back to the last good content.
Commands
/preferences shows the status. /preferences path prints the global file path.
Install (desktop profile, local development)
- Back up the profile's
package.json, pnpm-lock.yaml, pnpm-workspace.yaml and cordis.patch.yml and copy the old prompt to <dshHome>/preferences/global.md.
- From the desktop profile directory, use the profile's pnpm runtime to add
link:D:/Programs/dsh-user-preferences; include dsh-user-preferences in dsh.profile.bundles and remove dsh-user-prompt from both dependencies and bundles. Remove its user-prompt row from cordis.patch.yml without changing unrelated rows.
- Reload the profile (or restart DSH if its HMR watcher is unavailable). Verify that the effective bundle composition contains
user-preferences and not user-prompt, then confirm the Plugins → User preferences card loads and saves, and prompt assembly contains the migrated text. The generated cordis.yml can remain unchanged after a live HMR reconciliation; its timestamp alone does not prove whether the running Host reloaded.
The link: spec uses the local source directory. Keep that directory intact while installed. Revert the backed-up profile files and reinstall its dependencies to roll back; do not overwrite the migrated global preferences file.
Development
node --test test/core.test.mjs test/client.test.mjs test/rpc.test.mjs
node test/host-integration.mjs # requires extracted host packages in .tmp/host