-
Notifications
You must be signed in to change notification settings - Fork 4.6k
feat(tools): add DeepSeek Harness support #1672
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
f1d4b55
5330998
02607d7
779f231
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@fission-ai/openspec": minor | ||
| --- | ||
|
|
||
| - **DeepSeek Harness** β `openspec init --tools dsh` (command-line id `dsh`) installs the OpenSpec workflow skills into `.dsh/skills/` for DeepSeek Harness. It is skills-only (no command adapter or command files): dsh discovers the generated `SKILL.md` files as its highest-priority project root and surfaces them through its skill catalog, `skill` tool, and `/openspec-*` user invocations. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -78,7 +78,7 @@ The intent is identical everywhere. The spelling follows the file your tool load | |
| | `.../commands/opsx/<id>.*` | `/opsx:propose` | Claude Code, Gemini CLI, Crush | | ||
| | `.../opsx-<id>.*` | `/opsx-propose` | Cursor, GitHub Copilot (IDE), Devin Desktop, Trae, Oh My Pi | | ||
| | `.amazonq/prompts/opsx-<id>.md` | `@opsx-propose` | Amazon Q Developer | | ||
| | none β skills only | `/openspec-propose` | CodeArts, ForgeCode, Hermes, Mistral Vibe, Zed Agent, shared `.agents` | | ||
| | none β skills only | `/openspec-propose` | CodeArts, DeepSeek Harness, ForgeCode, Hermes, Mistral Vibe, Zed Agent, shared `.agents` | | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π― Functional Correctness | π‘ Minor | β‘ Quick win Keep skills-only invocation guidance synchronized with The skills-only lists omit MiniMax Code.
π Affects 2 files
π€ Prompt for AI Agents |
||
| | none β Kimi Code | `/skill:openspec-propose` | Kimi Code | | ||
| | none β Codex CLI | `$openspec-propose` | Codex | | ||
|
|
||
|
|
@@ -114,7 +114,7 @@ See [Supported Tools](supported-tools.md) for the exact paths per tool, and [Mig | |
|
|
||
| Quick checks, fastest first: | ||
|
|
||
| 1. **Type a slash in your AI chat.** Start typing `/opsx` and watch for autocomplete suggestions. If they appear, you're set. On a skills-only tool (Codex, Kimi Code, CodeArts, ForgeCode, Hermes, Mistral Vibe, Zed Agent, or the shared `.agents` target) `/opsx` never completes even on a healthy install β try the skill name from the table above instead. | ||
| 1. **Type a slash in your AI chat.** Start typing `/opsx` and watch for autocomplete suggestions. If they appear, you're set. On a skills-only tool (Codex, Kimi Code, CodeArts, DeepSeek Harness, ForgeCode, Hermes, Mistral Vibe, Zed Agent, or the shared `.agents` target) `/opsx` never completes even on a healthy install β try the skill name from the table above instead. | ||
| 2. **Look for the files.** For Claude Code, check that `.claude/skills/` contains `openspec-*` folders. Other tools use their own directories ([Supported Tools](supported-tools.md) lists them). | ||
| 3. **Re-run setup.** From your project root, run `openspec update`. This regenerates the skill and command files for whatever tools you configured. | ||
| 4. **Restart your assistant.** Many tools scan for skills and commands at startup, so a fresh window can be the missing step. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| schema: spec-driven | ||
| created: 2026-08-15 |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,87 @@ | ||||||||||||||
| ## Context | ||||||||||||||
|
|
||||||||||||||
| See proposal.md - Why. | ||||||||||||||
|
|
||||||||||||||
| OpenSpec already routes every skill-capable tool through one pipeline: `AI_TOOLS` metadata in `src/core/config.ts` drives tool detection (`available-tools.ts`), selection and validation (`init.ts`), skill path resolution (`shared/skill-paths.ts`), generation, version drift, and update. Tools that expose no custom command files simply have no `ToolCommandAdapter`, which `command-surface.ts` classifies as capability `none`. | ||||||||||||||
|
|
||||||||||||||
| DeepSeek Harness parses skills from fixed local roots (see `.ref/dsh-skills-θ§£ζι»θΎ.md`): `<project>/.dsh/skills` (rank 100), `<project>/.agents/skills` (rank 200), and user-level `~/.dsh/skills` (rank 400). It discovers only one level (`<root>/<name>/SKILL.md` or `<root>/<name>.md`), requires `name` (kebab-case) and non-empty `description` frontmatter, tolerates extra fields, and exposes skills to the model through `<available_skills>` plus a `skill` tool; users can also trigger them with the `/name` gesture. OpenSpec's generated `SKILL.md` files already satisfy every dsh constraint, so no template or frontmatter changes are needed. | ||||||||||||||
|
|
||||||||||||||
| ## Goals / Non-Goals | ||||||||||||||
|
|
||||||||||||||
| **Goals:** | ||||||||||||||
|
|
||||||||||||||
| - Add one `dsh` entry to `AI_TOOLS` that opts into the existing project-local skills pipeline. | ||||||||||||||
| - Make first-time setup, auto-detection, refresh, and profile/delivery drift work through existing generic code. | ||||||||||||||
| - Lock the dsh path and invocation behavior with focused tests. | ||||||||||||||
|
|
||||||||||||||
| **Non-Goals:** | ||||||||||||||
|
|
||||||||||||||
| - A dsh command adapter or any `.dsh/commands/` output β dsh has no file-based command surface. | ||||||||||||||
| - A global `~/.dsh/skills` install target β dsh has a higher-priority project root and OpenSpec manages per-project artifacts. | ||||||||||||||
| - Reclassifying dsh as `skills-invocable` in `command-surface.ts`; that belongs to the in-flight `add-tool-command-surface-capabilities` work. Until then dsh shares the current adapterless behavior of Rovo Dev CLI and Kimi Code. | ||||||||||||||
| - Changing generated skill templates or frontmatter. | ||||||||||||||
|
|
||||||||||||||
| ## Decisions | ||||||||||||||
|
|
||||||||||||||
| ### 1. Represent dsh as an adapterless, project-local tool entry | ||||||||||||||
|
|
||||||||||||||
| Add to `src/core/config.ts`: | ||||||||||||||
|
|
||||||||||||||
| ```ts | ||||||||||||||
| { | ||||||||||||||
| name: 'DeepSeek Harness', | ||||||||||||||
| value: 'dsh', | ||||||||||||||
| available: true, | ||||||||||||||
| successLabel: 'DeepSeek Harness', | ||||||||||||||
| skillsDir: '.dsh', | ||||||||||||||
| detectionPaths: ['.dsh/skills', '.dsh'], | ||||||||||||||
| }, | ||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| `resolveToolSkillsDir()` then resolves to `<projectRoot>/.dsh/skills`, which is dsh's rank-100 project root. Nothing else in init/update/selection needs a code change because those paths derive from `AI_TOOLS`. | ||||||||||||||
|
|
||||||||||||||
| Alternative considered: write to `~/.dsh/skills` via `globalSkillsDir`. Rejected because the project root outranks the user root, keeps artifacts repo-local and reviewable, and matches OpenSpec's project-scoped update/removal semantics (MiniMax Code's global-only design exists to work around a tool that only reads the user root, which is not dsh's case). | ||||||||||||||
|
|
||||||||||||||
| ### 2. Detect dsh from `.dsh/skills` and `.dsh` | ||||||||||||||
|
|
||||||||||||||
| `detectionPaths: ['.dsh/skills', '.dsh']` mirrors Rovo Dev CLI's `['.rovodev/skills', '.rovodev']`. `.dsh/skills` is the actual dsh skill root; `.dsh` recognizes an existing dsh project config root even before any skill exists. | ||||||||||||||
|
|
||||||||||||||
| Alternative considered: `.dsh/skills` only. Rejected as needlessly strict β `.dsh` is tool-specific (unlike the generic `.agents`), so a bare root is a meaningful signal. | ||||||||||||||
|
|
||||||||||||||
| ### 3. No command adapter; inherit capability `none` | ||||||||||||||
|
|
||||||||||||||
| `resolveCommandSurfaceCapability('dsh')` returns `none` because no adapter is registered. Consequences, all existing generic behavior: | ||||||||||||||
|
|
||||||||||||||
| - `delivery=both` / `skills`: skills generated; init reports `Commands skipped for: dsh (no adapter)`. | ||||||||||||||
| - `delivery=commands`: no dsh artifacts and the existing zero-artifact correction is printed. | ||||||||||||||
|
|
||||||||||||||
| Alternative considered: special-case dsh as `skills-invocable` like Codex so commands-only delivery keeps skills. Semantically dsh's skill tool + `/name` gesture are invocable, but the current shipped model only special-cases Codex; widening it here would duplicate the open `add-tool-command-surface-capabilities` change and expand this change's test matrix. Deferred deliberately. | ||||||||||||||
|
|
||||||||||||||
| ### 4. Use the default `/openspec-*` skill reference spelling | ||||||||||||||
|
|
||||||||||||||
| dsh's user-facing `/name` gesture makes `/openspec-propose` a real, typeable invocation, so the default transformer (`getSkillReferenceTransformer` fallback) is correct. The model side can call the `skill` tool by name regardless. | ||||||||||||||
|
|
||||||||||||||
| Alternative considered: add `dsh` to `NATURAL_LANGUAGE_SKILL_TOOLS` (like Rovo). Rejected because Rovo has no slash-like gesture at all, while dsh documents `/name`. | ||||||||||||||
|
|
||||||||||||||
| ### 5. No shared-root ownership work | ||||||||||||||
|
|
||||||||||||||
| `.dsh/skills` is used by no other `AI_TOOLS` entry, so `shared-skill-target.ts` marker/reconciliation logic does not apply. If the same repo also generates the `.agents` target, dsh will prefer its rank-100 `.dsh/skills` tree and there is no single-writer conflict to resolve. | ||||||||||||||
|
|
||||||||||||||
| ### 6. No frontmatter or template changes | ||||||||||||||
|
|
||||||||||||||
| OpenSpec writes `---` first line, kebab-case `name`, non-empty `description`, one-level `<name>/SKILL.md`, and only kebab-case extra fields. This satisfies dsh's fail-closed validation rules from `.ref` Β§3. Tests assert the generated file shape so a future template change cannot silently break dsh discovery. | ||||||||||||||
|
|
||||||||||||||
| ## Risks / Trade-offs | ||||||||||||||
|
|
||||||||||||||
| - [Commands-only delivery leaves dsh with zero artifacts] β Mitigation: init/update already print the existing `delivery` correction for capability-`none` tools; docs list dsh as skills-only, and the deferred capability work is the real fix. | ||||||||||||||
| - [`.dsh` detection can fire on a stale empty directory after commands-only removal] β Mitigation: interactive init shows detected-but-unconfigured tools as unselected in extend mode; behavior matches Rovo and is a cosmetic pre-selection, never a forced write. | ||||||||||||||
| - [dsh fail-closed parsing could silently drop skills] β Mitigation: generated files already comply; the init regression test checks frontmatter shape, and manual smoke testing against a real dsh session is in tasks. | ||||||||||||||
| - [Same-name skills under `.dsh/skills` and `.agents/skills`] β Mitigation: dsh's rank ordering (100 < 200) deterministically prefers `.dsh/skills`; this is upstream behavior, documented in supported-tools. | ||||||||||||||
|
|
||||||||||||||
| ## Migration Plan | ||||||||||||||
|
|
||||||||||||||
| Additive metadata change: no data migration and no rollback beyond reverting the entry. Projects using the shared `.agents` target today keep working; selecting `dsh` on a later `openspec init` writes the dedicated higher-priority root without touching `.agents`. | ||||||||||||||
|
Comment on lines
+81
to
+83
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π Maintainability & Code Quality | π‘ Minor | β‘ Quick win Document rollback of generated dsh files.
Based on learnings, archived changes apply independently without transactional rollback. The supplied initialization flow writes generated skills before completion. Proposed clarification-Additive metadata change: no data migration and no rollback beyond reverting the entry.
+Additive metadata change: no data migration is required. Reverting the entry stops future dsh detection and generation, but does not remove existing `.dsh/skills` files; remove those files separately if rollback is required.π Committable suggestion
Suggested change
π€ Prompt for AI AgentsSource: Learnings |
||||||||||||||
|
|
||||||||||||||
| ## Open Questions | ||||||||||||||
|
|
||||||||||||||
| _None._ | ||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| ## Why | ||
|
|
||
| DeepSeek Harness discovers skills from fixed local roots, with `<project>/.dsh/skills` as its highest-priority project root. OpenSpec supports many assistants but has no dedicated target for it today, so dsh users can only use the vendor-neutral shared `.agents` target or hand-place skills β losing the dedicated `.dsh` integration. | ||
|
|
||
| ## What Changes | ||
|
|
||
| - Add DeepSeek Harness as a supported tool with id `dsh`, `skillsDir: '.dsh'`, and detection paths `.dsh/skills` and `.dsh`. | ||
| - Generate the OpenSpec workflow skills into `.dsh/skills/openspec-*/SKILL.md` for dsh via `openspec init --tools dsh` and `openspec update`. | ||
| - Keep dsh skills-only: no command adapter and no `.dsh/commands/` files, because dsh has no file-based custom command surface. | ||
| - Spell dsh skill references as `/openspec-*` (dsh supports the user `/name` gesture), matching the existing skills-only tool pattern. | ||
| - Document dsh in the supported tools and command syntax docs. | ||
| - Add regression tests for detection, path resolution, init, update, and invocation spelling. | ||
|
|
||
| ## Capabilities | ||
|
|
||
| ### New Capabilities | ||
|
|
||
| _None._ | ||
|
|
||
| ### Modified Capabilities | ||
|
|
||
| - `ai-tool-paths`: define the `.dsh` skills root and detection paths for DeepSeek Harness. | ||
|
|
||
| ## Impact | ||
|
|
||
| - `src/core/config.ts` β add the `dsh` entry to `AI_TOOLS` | ||
| - `docs/supported-tools.md` β tool row, invocation table, and `--tools` id list | ||
| - `docs/cli.md` β supported `--tools` id list | ||
| - `docs/commands.md`, `docs/how-commands-work.md`, `docs/troubleshooting.md` β skills-only invocation tables and notes | ||
| - `test/core/available-tools.test.ts`, `test/core/shared/skill-paths.test.ts`, `test/core/shared/tool-detection.test.ts`, `test/core/init.test.ts`, `test/core/update.test.ts`, `test/utils/command-references.test.ts`, `test/core/command-generation/registry.test.ts` β targeted dsh coverage | ||
| - `.changeset/add-dsh-support.md` β release note |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
π― Functional Correctness | π‘ Minor | β‘ Quick win
Keep accepted tool IDs synchronized with
src/core/config.ts.Both user-facing
--toolslists omit the registeredrovodevID.docs/cli.md#L117-L117: addrovodevto the--toolsID list.docs/supported-tools.md#L227-L227: addrovodevto the available ID list.π Affects 2 files
docs/cli.md#L117-L117(this comment)docs/supported-tools.md#L227-L227π€ Prompt for AI Agents