dsh-projects
Codex-style projects for DeepSeek Harness: isolated named work units with a persistent background/goal description, injected into every bound session (default on).

dsh-projects brings the Codex Projects concept to DeepSeek Harness — a native implementation for the DSH architecture, not a port. Every piece of work (a feature, a refactor, a research topic) becomes a named, isolated project with its own background/goal description, holding multiple sessions, and that description is injected into every bound session's system prompt by default (toggleable per session).
┌─────────────────────────────────────────────────────────────┐
│ You Model │
│ /project create "背景与目标: 重构订单模块..." ← 注入 │
│ alpha 重构订单 (every session, default ON) │
│ │ │
│ ▼ │
│ project.json ── sessions[s1, s2, s3] ── desc ── memos │
└─────────────────────────────────────────────────────────────┘
Features
- Isolated projects —
/project create alpha 重构订单模块 creates an independent work unit; projects never share state.
- Multiple sessions per project — new sessions auto-inherit the last-opened project (
autoBindDefault), and every bound session is recorded into the project's session list.
- Sub-tasks / threads —
/project task create|switch|list|close groups sessions into named sub-tasks inside one project.
- git worktree isolation —
/project worktree add|switch|list|remove creates isolated git worktrees (<root>-<name>) and binds sessions to them; the worktree path is injected so the model works in isolation.
- Auto-loaded instruction files —
DEEPSEEK.md / AGENT.md from the project root are injected on every prompt, Codex-AGENTS.md-style (DSH core already loads AGENTS.md/CLAUDE.md, so this plugin complements rather than duplicates).
- Persistent background/goal description — set once with
/project desc, injected forever after.
- Session history + retention — every session is recorded;
/project archive keeps one forever, non-archived records older than 7 days are auto-pruned.
- Per-session injection toggle, default ON —
/project inject off silences the background for the current session only; every other session keeps it.
- Zero runtime dependencies — pure Cordis (
commands + systemPrompt services), plain ESM JavaScript, no build step required.
- Portable state — project state lives inside the project directory (
<root>/.dsh/projects/), committable to git, discoverable from anywhere via $DSH_HOME/projects.json.
Install
Requires the dsh CLI and pnpm on your PATH.
dsh plugin --profile web add dsh-projects
dsh plugin --profile web add github:Alexis-fish/dsh-projects
dsh plugin --profile web add github:Alexis-fish/dsh-projects
dsh plugin --profile web add file:/path/to/this/repo
dsh plugin automatically appends dsh-projects to dsh.profile.bundles. Restart your profile to activate.
Quick start
/project create alpha 重构订单模块,迁移到 vitest
→ 项目已创建并绑定当前会话: alpha
(工作若干会话后,第二天新开会话 —— 自动继承 alpha 项目)
/project status
→ 项目: alpha
根目录: C:/dev/app
背景与目标: 重构订单模块,迁移到 vitest
会话数: 4(最近: 2026-08-14T09:12:00Z)
本会话注入: 开
/project desc alpha 迁移完成,下一步:接入新支付网关
→ 项目 alpha 的背景与目标已更新
/project inject off # 只关掉当前会话的注入
/project close # 当前会话脱离项目(数据保留)
Command reference
/project create <name> [background] | Create a project and bind the current session |
/project open <name> | Bind the current session to an existing project |
/project close | Unbind the current session (stays unbound even with a default project) |
/project list | List all projects (most recently active first) |
/project status | Current session's project, background, sessions and injection state |
/project desc [<name>] <background> | Set the project's background/goal description |
/project inject on|off | Toggle background injection for the current session (default on) |
/project task create <name> [说明] | Create a sub-task/thread in the project |
/project task list | List sub-tasks |
/project task switch <name> | Bind the current session to a sub-task |
/project task close | Unbind the current session's sub-task |
/project worktree add <name> [branch] | Create an isolated git worktree |
/project worktree list | List worktrees |
/project worktree switch <name> | Bind the current session to a worktree |
/project worktree remove <name> | Remove a git worktree |
/project archive [sessionId] | Archive a session (kept forever) |
/project sessions | List project sessions with retention status |
/project delete <name> | Remove project state (never touches project files) |
/project help | Usage |
How it works
Bound sessions get the project context injected as a dynamic system-prompt section (systemPrompt.context, order 115) on every prompt assembly:
[project: alpha]
# DEEPSEEK.md
<project root instruction file contents>
背景与目标: 重构订单模块,迁移到 vitest
当前子任务: auth-refactor
当前工作目录(worktree): C:/dev/app-auth-refactor
The model therefore always knows the project's background, goals, current thread and isolated work directory. /project inject off returns "" for that session only.
Storage layout
<project root>/.dsh/projects/<name>.json # per-project state (source of truth, git-committable)
$DSH_HOME/projects.json # discovery index: name -> root + default project
{
"version": 1,
"name": "alpha",
"root": "C:/dev/app",
"description": "重构订单模块,迁移到 vitest",
"createdAt": "2026-08-13T09:00:00.000Z",
"updatedAt": "2026-08-14T09:12:00.000Z",
"sessions": [{ "id": "sess-1", "startedAt": "2026-08-13T09:05:00.000Z" }]
}
Configuration
The plugin row id is projects. Defaults:
stateDir | .dsh | Directory name inside a project root holding per-project state |
injectOrder | 115 | Order of the injected context among system-prompt contexts |
autoBindDefault | true | New sessions without an explicit binding inherit the default project |
instructionFiles | ["DEEPSEEK.md", "AGENT.md"] | Instruction files auto-loaded from the project root |
maxInstructionBytes | 16384 | Total byte budget across instruction files |
retentionDays | 7 | Non-archived session records older than this are pruned |
Override from your profile's cordis.patch.yml by row id (config is replaced wholesale — restate every key):
- id: projects
config:
stateDir: '.dsh'
injectOrder: 130
autoBindDefault: false
instructionFiles: ['DEEPSEEK.md', 'AGENT.md', 'AGENTS.md']
maxInstructionBytes: 32768
retentionDays: 14
Development
npm test
The plugin is plain ESM JavaScript with zero runtime dependencies; the repo also ships DESIGN.md with the full vision (v0.2+ roadmap: agent tools, session summaries, UI panel, git awareness).
FAQ
- Why not "project-management"? The plugin organizes project context (background, sessions, injection) — it does not track tasks, milestones or progress.
projects matches the Codex terminology this is inspired by.
- How is this different from
dsh-memory / dsh-track? Memory plugins persist facts across sessions; task plugins manage tasks. dsh-projects scopes work units: one named project, many sessions, one shared background injected by default.
- Is my data safe on
/project delete? Yes — deletion removes only the project state file and index entry; project files are never touched.
- Does it change default behavior? No. Without a bound project, sessions behave exactly as before.
Links
License
MIT © 2026 Alexis-fish
中文说明
dsh-projects 让 DeepSeek Harness 拥有 Codex Projects 式的工作单元:用 /project 创建独立隔离的项目,每个项目包含多个会话、可设定项目背景/目标说明,并在每个会话中默认注入这段背景(可按会话关闭)。灵感来自 OpenAI Codex CLI 的 Projects(codex project init/open),这是面向 DSH 架构的原生实现,非移植。
安装
dsh plugin --profile web add dsh-projects
dsh plugin --profile web add github:Alexis-fish/dsh-projects
dsh plugin --profile web add github:Alexis-fish/dsh-projects
dsh plugin --profile web add file:<本仓库绝对路径>
安装后 dsh plugin 会自动把 dsh-projects 加入 dsh.profile.bundles,重启 profile 即生效。
用法
/project create <name> [背景说明] | 创建并绑定一个项目(背景可选) |
/project open <name> | 绑定当前会话到已有项目 |
/project close | 解绑当前会话(即使存在默认项目也保持解绑) |
/project list | 列出全部项目 |
/project status | 当前会话的项目与注入状态 |
/project desc [<name>] <背景说明> | 设置项目背景/目标说明 |
/project inject on|off | 本会话是否注入项目背景(默认开) |
/project task create <name> [说明] | 在项目内创建子任务/线程 |
/project task list | 列出项目子任务 |
/project task switch <name> | 绑定当前会话到子任务 |
/project task close | 解除当前会话的子任务绑定 |
/project worktree add <name> [branch] | 创建隔离的 git worktree |
/project worktree list | 列出项目 worktree |
/project worktree switch <name> | 绑定当前会话到 worktree |
/project worktree remove <name> | 移除 git worktree |
/project archive [sessionId] | 归档会话(永久保留) |
/project sessions | 列出项目会话与保留状态 |
/project delete <name> | 删除项目状态(不删除项目文件) |
/project help | 用法 |
工作方式
-
项目 = 独立的工作单元:每个项目有自己的状态文件,互不干扰。
-
多会话:新会话自动继承"最近打开的项目"(autoBindDefault);会话绑定后会被记录进项目的会话列表。
-
背景注入:绑定项目的会话在每次组装系统提示时,自动注入:
[project: alpha]
背景与目标: 重构订单模块,迁移到 vitest
模型因此始终知道"这个项目的背景与目标"。/project inject off 只关闭当前会话的注入。
存储布局
<项目根目录>/.dsh/projects/<name>.json # 项目状态(随项目走,可提交 git)
$DSH_HOME/projects.json # 发现索引:name -> root + 默认项目
{
"version": 1,
"name": "alpha",
"root": "C:/dev/app",
"description": "重构订单模块,迁移到 vitest",
"createdAt": "...",
"updatedAt": "...",
"sessions": [{ "id": "sess-1", "startedAt": "..." }]
}
配置
行 id 为 projects,默认配置:
stateDir | .dsh | 项目根内状态目录名 |
injectOrder | 115 | 注入上下文在系统提示中的顺序 |
autoBindDefault | true | 新会话是否自动继承默认项目 |
instructionFiles | ["DEEPSEEK.md", "AGENT.md"] | 从项目根目录自动加载的指令文件 |
maxInstructionBytes | 16384 | 指令文件总字节预算 |
retentionDays | 7 | 未归档会话超过该天数自动清理 |
在 profile 的 cordis.patch.yml 中按 id 覆盖(注意:config 是整体替换,覆盖时需写全所有键):
- id: projects
config:
stateDir: '.dsh'
injectOrder: 130
autoBindDefault: false
instructionFiles: ['DEEPSEEK.md', 'AGENT.md', 'AGENTS.md']
maxInstructionBytes: 32768
retentionDays: 14
开发与路线图
npm test
完整设计见 DESIGN.md。
相关链接
License
MIT © 2026 Alexis-fish