@softspark/ai-toolkit 4.29.1 → 4.30.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +115 -0
  2. package/README.md +44 -18
  3. package/app/.claude-plugin/plugin.json +1 -1
  4. package/app/ARCHITECTURE.md +2 -2
  5. package/app/mcp-templates/README.md +7 -2
  6. package/app/mcp-templates/rag-mcp-legal.json +11 -0
  7. package/app/mcp-templates/rag-mcp.json +11 -0
  8. package/app/surface.json +1 -0
  9. package/benchmarks/ecosystem-doctor-snapshot.json +29 -17
  10. package/bin/ai-toolkit.js +8 -0
  11. package/kb/history/completed/dsh-integration-plan-superseded.md +322 -0
  12. package/kb/history/completed/dsh-native-install-target-plan.md +331 -0
  13. package/kb/procedures/ecosystem-sync-sop.md +7 -5
  14. package/kb/procedures/maintenance-sop.md +1 -1
  15. package/kb/procedures/release-verification-sop.md +35 -5
  16. package/kb/reference/architecture-overview.md +24 -5
  17. package/kb/reference/cli-reference.md +1 -1
  18. package/kb/reference/dsh-compatibility.md +183 -0
  19. package/kb/reference/manifest-install.md +112 -5
  20. package/kb/reference/mcp-templates.md +11 -4
  21. package/kb/reference/plugin-pack-conventions.md +35 -18
  22. package/kb/reference/supported-tools-registry.md +30 -6
  23. package/llms-full.txt +1110 -50
  24. package/llms.txt +3 -0
  25. package/manifest.json +2 -2
  26. package/package.json +2 -2
  27. package/scripts/codex_skill_adapter.py +673 -34
  28. package/scripts/config_resolver.py +80 -14
  29. package/scripts/doctor.py +98 -20
  30. package/scripts/ecosystem_tools.json +51 -1
  31. package/scripts/generate_codex_skills.py +22 -20
  32. package/scripts/install.py +30 -13
  33. package/scripts/install_steps/ai_tools.py +104 -34
  34. package/scripts/install_steps/dsh.py +5063 -0
  35. package/scripts/install_steps/install_state.py +1645 -57
  36. package/scripts/mcp_editors.py +5 -2
  37. package/scripts/plugin.py +2495 -163
  38. package/scripts/plugin_mcp.py +279 -0
  39. package/scripts/plugin_rules.py +389 -0
  40. package/scripts/plugin_schema.py +139 -23
  41. package/scripts/uninstall.py +47 -4
  42. package/scripts/validate.py +421 -0
@@ -0,0 +1,322 @@
1
+ ---
2
+ title: "Plan: DeepSeek Harness (dsh) Integration"
3
+ category: planning
4
+ service: ai-toolkit
5
+ tags:
6
+ - dsh
7
+ - deepseek-harness
8
+ - cordis
9
+ - integration
10
+ - skills
11
+ - subagents
12
+ - multi-model
13
+ - acp
14
+ - emission-target
15
+ doc_type: plan
16
+ status: superseded
17
+ created: "2026-08-25"
18
+ last_updated: "2026-08-27"
19
+ closed: "2026-08-27"
20
+ completion: "Functional objective delivered through standalone 1.0.0 modules; native ai-toolkit install target moved to a replacement plan"
21
+ superseded_by: "kb/history/completed/dsh-native-install-target-plan.md"
22
+ description: "Superseded DSH integration plan retained as the historical record of the subscription-backed runtime validation and the architecture split into dsh-codex and dsh-orchestrator."
23
+ ---
24
+
25
+ # Plan: DeepSeek Harness (dsh) Integration (Superseded)
26
+
27
+ **Status:** Superseded on 2026-08-27
28
+ **Completion:** Functional objective delivered; native ai-toolkit install target moved to a replacement plan
29
+ **Created:** 2026-08-25
30
+ **Origin:** Requirement for a single window driving three already-owned subscriptions (Claude Max, ChatGPT Plus, Gemini) without buying API credits
31
+ **Upstream reviewed:** `deepseek-ai/deepseek-harness` @ `b150a55` (2026-08-21), package version `0.1.1-rc.2`, MIT, developer preview
32
+ **Replacement:** [`dsh-native-install-target-plan.md`](dsh-native-install-target-plan.md)
33
+
34
+ ## Closure Record
35
+
36
+ This plan mixed two outcomes that now have different ownership:
37
+
38
+ 1. The user-facing runtime objective is complete. `@softspark/dsh-codex@1.0.0` provides the ChatGPT-backed Codex parent, and `@softspark/dsh-orchestrator@1.0.0` delegates bounded tasks to Claude Code and GitHub Copilot Gemini. Both are public Apache-2.0 modules with CI, provenance, security gates, KB, release SOPs, and post-release verification.
39
+ 2. Direct Gemini delegation through a personal Google AI Pro/Ultra login is not supported. The delivered route uses GitHub Copilot CLI ACP, GitHub authentication, and GitHub plan credits. No Google credential proxy or Antigravity workaround is part of the system.
40
+ 3. The native ai-toolkit emission target was not implemented. `ai-toolkit install --local --editors dsh`, managed preset installation, DSH-specific uninstall, registry metadata, and focused bats coverage move to the replacement plan.
41
+
42
+ The historical phases below remain useful as the research and validation record. Their status table is updated to show what shipped, what was cut, and what moved.
43
+
44
+ ## 1. Objective
45
+
46
+ Add dsh as the twelfth emission target so a single harness can delegate to Claude Code, Codex,
47
+ and Gemini CLI while each child authenticates natively against its own vendor subscription.
48
+
49
+ **Non-goal:** rewriting ai-toolkit on top of dsh. The toolkit stays the control plane and source
50
+ of truth. dsh is a runtime it emits to, exactly like Codex CLI and opencode.
51
+
52
+ **Hard constraint that shaped this plan:** Anthropic prohibits third-party tools from routing
53
+ Free/Pro/Max OAuth credentials, and enforces it server-side without notice. Any harness that
54
+ speaks the Anthropic API itself therefore requires a separate API key. dsh avoids this by
55
+ spawning the real Claude Code binary instead of routing credentials.
56
+
57
+ ## 2. Why dsh satisfies the subscription constraint
58
+
59
+ `packages/subagent/subagent-claude-code/README.md` states the provider deliberately omits the SDK
60
+ `settingSources` option, so the official Agent SDK reads the host's normal user, project, and local
61
+ Claude settings relative to the parent session cwd, including native account state. It neither
62
+ copies nor filters those files and does not create or modify login state. Authentication and
63
+ account state remain native; the bundle supplies the CLI but does not create an account, log in,
64
+ or probe an account. Credential-shaped ambient variables are scrubbed before the explicit `env`
65
+ overlay, so `ANTHROPIC_API_KEY` reaches the child only when supplied deliberately. The runtime is
66
+ pinned to `@anthropic-ai/claude-agent-sdk@0.3.220` (Claude Code 2.1.220) and the executable comes
67
+ from the SDK platform package, not from `PATH`.
68
+
69
+ Consequence: the subscription is exercised by Claude Code authenticating itself, not by dsh
70
+ presenting the user's credentials to Anthropic.
71
+
72
+ ### Subagent providers present in the tree
73
+
74
+ | Package | Spawns | Subscription exercised |
75
+ |---|---|---|
76
+ | `subagent-claude-code` | Agent SDK to native `claude` | Claude Max |
77
+ | `subagent-codex` | Codex | ChatGPT Plus |
78
+ | `subagent-acp` | any Agent Client Protocol agent (Gemini CLI ships native ACP) | Gemini |
79
+ | `subagent-dsh-sdk` | dsh SDK loop | model provider config |
80
+ | `subagent-fork-in-process` | forked in-process session | inherited |
81
+ | `subagent-spawn-in-process` | fresh in-process session | inherited |
82
+ | `subagent-in-process-driver` | shared driver for the in-process providers | inherited |
83
+
84
+ ## 3. Verified compatibility surface
85
+
86
+ ### 3.1 Skill discovery is already satisfied
87
+
88
+ `packages/skill/skill-filesystem` resolves roots in rank order:
89
+
90
+ | Rank | Source | Path |
91
+ |---|---|---|
92
+ | 100 | `project-dsh` | `<projectRoot>/.dsh/skills` |
93
+ | 200 | `project-agents` | `<projectRoot>/.agents/skills` |
94
+ | 300 | `custom` | `Config.customSkillDirs` |
95
+ | 400 | `user-dsh` | `<dshHome>/skills` (`$DSH_HOME`, default `~/.dsh`) |
96
+ | 500 | `user-agents` | `<agentsHome>/skills` (`$DSH_AGENTS_HOME`, default `~/.agents`) |
97
+
98
+ Skill format: single-level directory bundles `<name>/SKILL.md` or flat `<name>.md`. Frontmatter is
99
+ an open YAML object; the provider interprets required `name` and `description` plus optional
100
+ `whenToUse`, `metadata`, `disable-model-invocation`, and `user-invocable`. Names must be kebab-case.
101
+
102
+ This is the ai-toolkit skill convention field for field. `scripts/generate_codex_skills.py` already
103
+ mirrors every skill in `app/skills/` into `<target>/.agents/skills/<name>/`, native skills as
104
+ symlinks to canonical `app/skills` and delegation-heavy skills as adapted wrappers through
105
+ `codex_skill_adapter.sync_codex_skill`.
106
+
107
+ **No new skill generator is required.** Rank 200 is the same directory Codex CLI consumes.
108
+
109
+ A bare checkout shows only `ai-toolkit-skill-catalogue` under `.agents/skills/` because
110
+ `enable_codex_skills` defaults to `False` for the standalone generator; the installer sets it when
111
+ Codex is selected.
112
+
113
+ ### 3.2 Presets are compositions, not personas
114
+
115
+ `packages/preset/agent-presets` treats a preset as a plugin composition: the composition file is a
116
+ top-level list of plugin rows, with an optional sibling `preset.yml` carrying display `name` and
117
+ `description` only. The `id` is the directory name and must match `[a-z0-9][a-z0-9-]*`; `trust`
118
+ derives from the discovery root. Authoring is copy-only: `copy()` rejects a non-conforming id, an
119
+ id already supplied by any root, and an unknown source, then re-tightens the copied tree to
120
+ owner-only permissions and dereferences symlinks. A copied `preset.yml` keeps the description but
121
+ drops `name` and roster `order`.
122
+
123
+ Package-name rows resolve against the host composition rather than the preset directory, because a
124
+ user-home preset cannot reach the harness through Node's upward `node_modules` walk. Relative
125
+ paths resolve from the preset's own directory, so a preset's own plugin files and skill directories
126
+ travel with it.
127
+
128
+ **Implication:** mapping 44 agents onto 44 presets is architecturally wrong. Presets are session
129
+ compositions (expect 2-3 of them). The 44 agents belong on the subagent surface.
130
+
131
+ ## 4. Gotchas that must become gates
132
+
133
+ 1. **Invocation frontmatter fails closed.** A camel-case spelling (`userInvocable`,
134
+ `disableModelInvocation`) or a non-boolean invocation value **drops the entire skill from
135
+ discovery** with a warning rather than falling back to a permissive default. Accepted boolean
136
+ spellings are YAML booleans plus case-insensitive `true`/`false`, `yes`/`no`, `on`/`off`,
137
+ `1`/`0`. Current emitters are clean; this must be enforced by `validate.py`, not left to chance.
138
+ 2. **Discovery is one level deep.** Only `<root>/<name>/SKILL.md` and `<root>/<name>.md` are
139
+ recognized. Nested skill trees and package manifests are ignored. Resources under `references`,
140
+ `scripts`, and `assets` inside a bundle are fine and do not invalidate the catalog.
141
+ 3. **Project root is the nearest `.git` ancestor.** Without that marker the provider falls back to
142
+ the supplied cwd. No alternate project-root marker, no monorepo subproject selection.
143
+ 4. **Symlinked skills.** `generate_codex_skills.py` emits symlinks into `app/skills`.
144
+ `watchFollowSymlinks` defaults to `true`, so this should hold, but it needs empirical
145
+ confirmation before being relied on.
146
+ 5. **Malformed entries disappear silently.** The model catalog receives no per-skill diagnostic and
147
+ cannot distinguish an absent skill from an invalid one.
148
+
149
+ ## 5. Open questions
150
+
151
+ | # | Question | How to close |
152
+ |---|---|---|
153
+ | Q1 | Subagent definition format: how a delegatable agent such as `security-auditor` is declared | Moved to the replacement plan; the released orchestrator deliberately exposes two bounded static tools instead of mapping 44 toolkit agents |
154
+ | Q2 | Whether `packages/hooks` ("Claude Code/Codex hook bridges + wire-protocol library") accepts the toolkit's `app/hooks/*.sh` directly | Moved to the replacement plan as an optional compatibility slice, not a prerequisite for the install target |
155
+ | Q3 | Whether `subagent-acp` can drive Gemini CLI end to end on a Google login | Closed negative: individual Gemini CLI access ended; Antigravity has no ACP and prohibits third-party login use |
156
+ | Q4 | Plugin row schema for a composition file | Closed by the released `softspark-orchestrator` preset and `cordis.patch.yml` |
157
+ | Q5 | Whether Claude Max actually authenticates through the spawned CLI in practice | Closed positive by isolated Codex-to-Claude Max verification without an Anthropic API key |
158
+
159
+ ## 6. Progress Tracking
160
+
161
+ | Phase | Deliverable | Depends on | Status |
162
+ |---|---|---|---|
163
+ | 0 | Empirical validation: dsh sees all 109 skills; subscription-backed providers run | none | completed through standalone modules; direct Google route replaced by Copilot Gemini |
164
+ | 1 | `validate.py` gates for kebab-case invocation fields and one-level `.agents/skills` depth | 0 | moved to replacement Phase 1 |
165
+ | 2 | `scripts/generate_dsh_preset.py` emitting 1-2 compositions | 0, Q4 | replaced by the released `softspark-orchestrator` preset; managed installation moved to the replacement plan |
166
+ | 3 | 44 agents mapped onto the subagent surface | Q1 | cut; the released boundary exposes only Claude Code and Copilot Gemini delegation tools |
167
+ | 4 | MCP servers and hook bridge | Q2 | cut from the runtime deliverable; optional compatibility work moved to the replacement plan |
168
+ | 5 | `ecosystem_tools.json` entry, docs across the nine mandated files, bats coverage | 1-4 | native ai-toolkit registry, docs, tests, and uninstall moved to the replacement plan |
169
+
170
+ ### Phase 0 checkpoint: Codex primary provider verified (2026-08-26)
171
+
172
+ - The checkpoint began at `@softspark/dsh-codex@0.1.0`; the public `1.0.0` release now bridges DSH to the official local `codex app-server`
173
+ over JSONL stdio. Codex retains sole ownership of ChatGPT authentication and tokens.
174
+ - The isolated DSH profile loaded provider `codex`, exposed seven models, booted the Web UI
175
+ on `127.0.0.1:3080`, and completed end-to-end session prompts on Codex models.
176
+ - The live app-server reported authentication kind `chatgpt`; no OpenAI API key was configured.
177
+ - The final local tarball passed 92 tests, typecheck, lint, build, coverage, dependency,
178
+ signature, SARIF, package, and composition gates. Its SHA-256 is
179
+ `87db7be9f959de507d708bfa74feb4b5890b9b8a7a33d3520e31d91fcbe673c0`.
180
+ - A persistent DSH session resumed the identical Codex thread after a host restart, and a live
181
+ cancellation ended with reason `aborted`.
182
+ - The public `1.0.0` release keeps stable mode unchanged and exposes a bounded, opt-in
183
+ `experimentalDynamicTools` bridge. Dynamic-tool threads remain non-replayable after restart.
184
+
185
+ Evidence and release gates live in the standalone repository:
186
+ the public [softspark/dsh-codex](https://github.com/softspark/dsh-codex) repository.
187
+
188
+ ### Phase 0 checkpoint: SoftSpark orchestrator composition (2026-08-26)
189
+
190
+ - `@softspark/dsh-codex@1.0.0` exposes an explicit bounded dynamic-tool bridge while stable mode remains unchanged.
191
+ - `@softspark/dsh-orchestrator@1.0.0` is a separate Apache-2.0 public module with exact DSH dependencies, multi-OS CI, provenance, security gates, tests, KB, and release SOPs.
192
+ - The isolated DSH profile loads `softspark-orchestrator` as its default preset and registers one-shot `subagent_claude_code` plus `subagent_gemini_copilot` tools.
193
+ - A real Codex-to-DSH `todo_write` tool roundtrip completed on the final composition with no provider API keys.
194
+ - Claude Max native login is verified. Google AI Pro/Ultra cannot be delegated through DSH: Gemini CLI ended individual access, Antigravity has no ACP, and its terms prohibit third-party use of account login. No proxy or token workaround will be implemented.
195
+ - The final isolated profile completed both a neutral Codex-to-DSH tool call and a Codex-to-Claude Max delegation with exact markers and no provider API keys.
196
+
197
+ ## 7. Detailed Implementation
198
+
199
+ ### Phase 0 - Empirical validation (no code)
200
+
201
+ ```bash
202
+ ai-toolkit install --local --editors codex # populates .agents/skills/ with all 109
203
+ npx @deepseek-ai/dsh web # UI on 127.0.0.1:3080
204
+ ```
205
+
206
+ Verify, in order:
207
+
208
+ 1. The skill catalog lists 109 entries, not the single `ai-toolkit-skill-catalogue` pointer.
209
+ 2. Symlinked skill bodies load (gotcha 4).
210
+ 3. A `subagent-claude-code` delegation runs without an `ANTHROPIC_API_KEY` present (Q5).
211
+ 4. A `subagent-codex` delegation runs on the ChatGPT login.
212
+ 5. A `subagent-acp` delegation reaches Gemini CLI on the Google login (Q3).
213
+
214
+ If step 3 fails, the entire premise collapses and the plan reverts to the ACP-in-JetBrains
215
+ alternative recorded in section 10.
216
+
217
+ ### Phase 1 - Gates
218
+
219
+ Extend `scripts/validate.py`:
220
+
221
+ - Reject any emitted `SKILL.md` whose frontmatter carries `userInvocable` or
222
+ `disableModelInvocation`, or a non-boolean value for the kebab-case forms.
223
+ - Reject any `SKILL.md` deeper than `<root>/<name>/SKILL.md` under `.agents/skills/`.
224
+ - Reject skill directory names failing `[a-z0-9]+(-[a-z0-9]+)*`.
225
+
226
+ These protect Codex CLI and opencode as well; the fail-closed behavior is what makes them
227
+ non-optional rather than cosmetic.
228
+
229
+ ### Phase 2 - Presets
230
+
231
+ `scripts/generate_dsh_preset.py` emits composition directories plus `preset.yml` display metadata.
232
+ Start with `ai-toolkit-standard`; add `ai-toolkit-strict` only if the profile split earns it. Ids
233
+ must satisfy `[a-z0-9][a-z0-9-]*`. Do not attempt to author presets by writing into a shipped
234
+ preset directory. Upstream authoring is copy-only and `remove()` refuses shipped presets.
235
+
236
+ ### Phase 3 - Agents
237
+
238
+ Blocked on Q1. Expected shape: one subagent declaration per `app/agents/*.md`, carrying
239
+ `description`, tool allowances, and delegation targets, with the model left unset so host settings
240
+ stay authoritative. The `model` alias problem is the same one documented for opencode in
241
+ `kb/reference/opencode-compatibility.md`: the toolkit stores `opus`/`sonnet`/`haiku`, which cannot
242
+ be mapped without assuming a provider.
243
+
244
+ ### Phase 4 - MCP and hooks
245
+
246
+ `packages/mcp` for server config, `packages/hooks` for the bridge. If the hook bridge speaks the
247
+ Claude Code hook wire protocol, `app/hooks/*.sh` may attach with a thin adapter rather than a
248
+ rewrite. Preserve `exit 2` blocking semantics for `guard-destructive.sh`. This matters most under
249
+ unattended delegation, where nobody is watching the permission prompt.
250
+
251
+ ### Phase 5 - Registry, docs, tests
252
+
253
+ Follow the opencode precedent exactly:
254
+
255
+ - `scripts/ecosystem_tools.json` entry with docs and release-notes URLs for drift detection.
256
+ - `kb/reference/dsh-compatibility.md` mirroring the section layout of
257
+ `kb/reference/opencode-compatibility.md` (Summary, Local/Global Install Outputs, Editor Surface
258
+ Comparison, translation models, Behavioral Limits, Verification, CLI Commands).
259
+ - Entry in `kb/reference/supported-tools-registry.md`.
260
+ - The nine files mandated by `CLAUDE.md`: README.md, CLAUDE.md, ARCHITECTURE.md, package.json,
261
+ plugin.json, skills-catalog.md, architecture-overview.md, llms.txt, AGENTS.md.
262
+ - bats generator contract tests, auto-detection tests, idempotency tests.
263
+ - `python3 scripts/validate.py --strict`, `python3 scripts/audit_skills.py --ci`, and
264
+ `shellcheck --severity=warning app/hooks/*.sh` if any hook is touched.
265
+
266
+ ## 8. Original Success Criteria and Outcome
267
+
268
+ | Criterion | Outcome |
269
+ |---|---|
270
+ | `ai-toolkit install --local --editors dsh` creates the workspace without manual editing | Not delivered; moved to the replacement plan |
271
+ | One session runs Claude Max, ChatGPT-backed Codex, and Gemini without provider API keys | Delivered with Gemini hosted through GitHub Copilot rather than a Google login |
272
+ | `validate.py --strict` and `audit_skills.py --ci` pass | Delivered for the standalone repositories; native target coverage remains in the replacement plan |
273
+ | Uninstall preserves user-authored files | Not applicable until ai-toolkit owns DSH artifacts; moved to the replacement plan |
274
+ | DSH remains opt-in | Delivered by separate packages and retained as a requirement of the replacement plan |
275
+
276
+ ## 9. Risks and Mitigation
277
+
278
+ | Risk | Impact | Mitigation |
279
+ |---|---|---|
280
+ | Upstream breaking changes (declared developer preview) | Generators break for users mid-release | Keep dsh strictly opt-in; never in `--editors all` defaults until it leaves preview |
281
+ | Anthropic changes its stance on spawned-CLI orchestration | Phase 0 premise invalidated | Fall back to ACP in JetBrains/Zed, where each agent owns its own auth by design |
282
+ | Preset schema churn | Phase 2 rework | Emit the minimum viable composition; keep display metadata in `preset.yml` where the contract is narrow and stable |
283
+ | Documentation drift across the nine mandated files | Broken user trust, per CLAUDE.md | Phase 5 is one atomic change with `validate.py --strict` as the gate |
284
+ | Silent skill loss from fail-closed frontmatter | Skills vanish with only a warning | Phase 1 gates land before phase 2 |
285
+
286
+ ## 10. Pre-Mortem
287
+
288
+ *It is six months out and this failed. What happened?*
289
+
290
+ 1. **We shipped dsh in the default editor set.** An upstream breaking change broke `install` for
291
+ every toolkit user, not just dsh users. Prevented by success criterion 5.
292
+ 2. **Phase 0 was skipped.** Phases 1-5 were built on the assumption that Max authenticates through
293
+ the spawned CLI, and it turned out to require an API key in practice. Prevented by making Q5 a
294
+ hard gate.
295
+ 3. **We mapped 44 agents onto 44 presets.** The preset surface is a session composition, not a
296
+ persona, so the emission produced 44 near-identical compositions nobody could maintain.
297
+ Prevented by section 3.2.
298
+ 4. **We became Cordis contributors.** Time went into upstream plugin work instead of the toolkit.
299
+ Prevented by treating dsh as an emission target with a fixed contract surface, never a fork.
300
+ 5. **A frontmatter regression silently dropped skills.** Nobody noticed because discovery only
301
+ warns. Prevented by phase 1.
302
+
303
+ ## 11. Archived Next Actions
304
+
305
+ No work should continue from this archived document. The scoped native install target is complete in [`dsh-native-install-target-plan.md`](dsh-native-install-target-plan.md). Reopen this record only if evidence about the 2026-08-26 validation needs correction.
306
+
307
+ ## Sources
308
+
309
+ - `deepseek-ai/deepseek-harness` @ `b150a55`, `0.1.1-rc.2`, MIT: `packages/skill/skill-filesystem`,
310
+ `packages/preset/agent-presets`, `packages/subagent/*`, `docs/`
311
+ - https://github.com/deepseek-ai/deepseek-harness
312
+ - https://deepseek.com/harness/en/
313
+ - `kb/reference/opencode-compatibility.md`: precedent for the emission-target contract
314
+ - `kb/reference/codex-cli-compatibility.md`: `.agents/skills` precedent
315
+ - `kb/reference/supported-tools-registry.md`
316
+
317
+ ## Related
318
+
319
+ - `kb/reference/opencode-compatibility.md`
320
+ - `kb/reference/codex-cli-compatibility.md`
321
+ - `kb/reference/architecture-overview.md`
322
+ - `kb/reference/supported-tools-registry.md`
@@ -0,0 +1,331 @@
1
+ ---
2
+ title: "Plan: Native DSH Install Target"
3
+ category: planning
4
+ service: ai-toolkit
5
+ tags:
6
+ - dsh
7
+ - deepseek-harness
8
+ - installer
9
+ - editor-target
10
+ - subscriptions
11
+ - lifecycle
12
+ - security
13
+ doc_type: plan
14
+ status: completed
15
+ created: "2026-08-27"
16
+ last_updated: "2026-09-01"
17
+ approved: "2026-08-28"
18
+ started: "2026-08-28"
19
+ completion: "Phase 3 of 3 complete"
20
+ completed: "2026-09-01"
21
+ predecessor: "kb/history/completed/dsh-integration-plan-superseded.md"
22
+ description: "Implementation plan for an explicit ai-toolkit DSH target that emits project skills and safely manages the published dsh-codex and dsh-orchestrator packages without handling vendor credentials."
23
+ ---
24
+
25
+ # Plan: Native DSH Install Target
26
+
27
+ ## Status
28
+
29
+ Approved on 2026-08-28 and completed on 2026-09-01.
30
+
31
+ Estimated size: **L (3 to 5 days)**. The runtime integrations already exist. The remaining work is installer ownership, lifecycle safety, validation, tests, and documentation.
32
+
33
+ Predecessor: [`dsh-integration-plan-superseded.md`](dsh-integration-plan-superseded.md).
34
+
35
+ ## Context
36
+
37
+ The subscription-backed runtime is already delivered in two standalone Apache-2.0 packages:
38
+
39
+ - `@softspark/dsh-codex@1.0.0` registers the DSH `codex` provider and delegates authentication, tools, thread state, and model execution to the locally installed Codex app server. See <https://github.com/softspark/dsh-codex>.
40
+ - `@softspark/dsh-orchestrator@1.0.1` registers bounded Claude Code and GitHub Copilot Gemini delegation through native vendor logins. It accepts no provider API keys. See <https://github.com/softspark/dsh-orchestrator>.
41
+
42
+ ai-toolkit does not expose `dsh` in its editor list, does not track DSH profile artifacts, and has no DSH-specific install, doctor, update, or uninstall contract. [PATH: bin/ai-toolkit.js:309]
43
+
44
+ The published packages currently require two explicit operations: install exact plugins into a named DSH profile, then copy `softspark-orchestrator` from the installed package into `$DSH_HOME/.agent-presets`. See the orchestrator setup guide at <https://github.com/softspark/dsh-orchestrator>.
45
+
46
+ ## Decision
47
+
48
+ The native target has two separate ownership surfaces:
49
+
50
+ 1. `ai-toolkit install --local --editors dsh` emits project-owned `.agents/skills` and validates DSH compatibility. It must not mutate `$DSH_HOME`, install npm packages, or inspect vendor credentials.
51
+ 2. `ai-toolkit dsh install --profile web` is the explicit profile mutation command. It installs exact reviewed package versions, copies the released preset, and records ownership in the existing ai-toolkit state model.
52
+
53
+ This split preserves the meaning of `--local`. It also makes global DSH changes impossible without a command that names DSH and the target profile.
54
+
55
+ `dsh` stays out of `--editors all`, auto-detection, default profiles, and global editor defaults while DSH remains a developer preview. Selecting `dsh` must be explicit.
56
+
57
+ ## Scope
58
+
59
+ ### Included
60
+
61
+ - Explicit project target under `--editors dsh`.
62
+ - Reuse of the existing `.agents/skills/<name>/SKILL.md` emission path.
63
+ - DSH-specific validation for fail-closed skill metadata and one-level discovery depth.
64
+ - Explicit `ai-toolkit dsh install`, `update`, `doctor`, and `uninstall` lifecycle commands.
65
+ - Exact installation of `@softspark/dsh-codex@1.0.0` and `@softspark/dsh-orchestrator@1.0.1` into a named DSH profile.
66
+ - Ownership-safe copy and update of `$DSH_HOME/.agent-presets/softspark-orchestrator`.
67
+ - State tracking through `~/.softspark/ai-toolkit/state.json`.
68
+ - Dry-run output, collision refusal, rollback, tests, registry metadata, and public documentation.
69
+
70
+ ### Excluded
71
+
72
+ - Direct Google AI Pro/Ultra, Gemini CLI OAuth, Antigravity, or Gemini API integration.
73
+ - Provider API keys, custom OAuth, token copying, credential-file reads, or login automation.
74
+ - Mapping all 44 ai-toolkit agents into DSH subagents.
75
+ - A new DSH skill generator. DSH already consumes `.agents/skills`.
76
+ - Automatic DSH installation from `--editors all`, auto-detection, or default install profiles.
77
+ - Rewriting the released dsh-codex or dsh-orchestrator packages inside ai-toolkit.
78
+ - MCP and hook bridging in the first native-target release.
79
+ - Support for arbitrary DSH prereleases or unpinned community package versions.
80
+
81
+ ## Global Success Criteria
82
+
83
+ - [x] `ai-toolkit install --local --editors dsh` emits the complete managed skill catalog and makes no write under `$DSH_HOME`.
84
+ - [x] `ai-toolkit dsh install --profile web` installs exact `@softspark/dsh-codex@1.0.0` and `@softspark/dsh-orchestrator@1.0.1` packages plus the released preset without manual file editing.
85
+ - [x] Install, update, doctor, and uninstall preserve user-authored presets and unrelated DSH plugins.
86
+ - [x] No command accepts, reads, copies, logs, or forwards provider credentials.
87
+ - [x] `dsh` remains excluded from `--editors all`, auto-detection, default profiles, and default global editors.
88
+ - [x] Offline, missing-runtime, collision, partial-install, and interrupted-update paths fail without leaving untracked artifacts.
89
+ - [x] The full repository test, validation, skill-audit, and documentation gates pass.
90
+
91
+ ## Phase 1: Project Target and Fail-Closed Gates
92
+
93
+ Dependency: none.
94
+
95
+ Size: **M (1 to 2 days)**.
96
+
97
+ ### Phase 1 Success Criteria
98
+
99
+ - [x] CLI help and validation accept `dsh` only when named explicitly.
100
+ - [x] `--editors all` resolves to the existing stable editor set and excludes `dsh`.
101
+ - [x] Dry-run lists `.agents/skills` changes but writes nothing.
102
+ - [x] Project installation emits every managed skill at one discovery level.
103
+ - [x] Validation rejects camel-case invocation fields, non-boolean invocation values, invalid skill directory names, and nested `SKILL.md` locations.
104
+ - [x] A read-only doctor check reports DSH, Codex, Claude Code, and Copilot executable availability without opening credential stores.
105
+
106
+ ### Phase 1 Completion Evidence
107
+
108
+ Completed on 2026-08-28 after sequential TDD, three spec review passes, and four quality-review repair cycles.
109
+
110
+ - Full repository suite: 1726/1726 tests.
111
+ - Final spec review: 10/10 requirements approved.
112
+ - Final quality review: 0 Critical, 0 Important.
113
+ - Strict validator: 0 errors, 0 warnings.
114
+ - Skill audit: 0 HIGH, 0 WARN.
115
+ - DSH remains explicit-only, project-local, credential-blind, transactionally owned, and outside Phase 2 profile lifecycle behavior.
116
+
117
+ ### Phase 1 Tasks
118
+
119
+ | ID | Outcome | Affected files | Owner | Depends on |
120
+ |---|---|---|---|---|
121
+ | P1.1 | Add an explicit-only DSH editor capability separate from the stable `ALL_EDITORS` expansion | `bin/ai-toolkit.js`, `scripts/install.py`, `scripts/install_steps/ai_tools.py` | `backend-specialist` | none |
122
+ | P1.2 | Reuse the managed Codex skill emitter for the DSH project surface without emitting unrelated Codex configuration | `scripts/generate_codex_skills.py`, `scripts/install_steps/ai_tools.py` | `backend-specialist` | P1.1 |
123
+ | P1.3 | Enforce the DSH fail-closed metadata, name, and depth contract | `scripts/validate.py`, `tests/test_metadata_contracts.bats`, `tests/test_skills_native.bats` | `backend-specialist` | none |
124
+ | P1.4 | Add read-only runtime and version diagnostics with no login automation | `scripts/doctor.py`, `tests/test_doctor_fix.bats`, `tests/test_dsh.bats` | `infrastructure-validator` | P1.1 |
125
+ | P1.5 | Cover explicit selection, `all` exclusion, dry-run, idempotency, and project-only writes | `tests/test_dsh.bats`, `tests/test_install.bats`, `tests/test_install_profiles.bats` | `test-engineer` | P1.1, P1.2, P1.3, P1.4 |
126
+
127
+ ### Phase 1 Rollback and Scope Cut
128
+
129
+ Remove the explicit `dsh` selector and its focused tests. Existing Codex skill emission and both standalone DSH packages remain unchanged. If the fail-closed metadata gates reveal unrelated invalid skills, fix those skills before shipping rather than weakening the gate.
130
+
131
+ ## Phase 2: Explicit DSH Profile Lifecycle
132
+
133
+ Dependency: Phase 1 → Phase 2.
134
+
135
+ Size: **M (1 to 2 days)**.
136
+
137
+ ### Phase 2 Success Criteria
138
+
139
+ - [x] `ai-toolkit dsh install --profile web` performs preflight before the first mutation.
140
+ - [x] The command installs exact reviewed package versions through the DSH plugin manager.
141
+ - [x] The preset is copied from the installed orchestrator package, not reconstructed by ai-toolkit.
142
+ - [x] Existing user-owned preset or plugin collisions stop the command with an actionable error.
143
+ - [x] State records the DSH home, profile, package versions, preset path, and managed content hash without recording credentials.
144
+ - [x] Update replaces only artifacts whose ownership and previous hash match state.
145
+ - [x] Uninstall removes only ai-toolkit-managed DSH artifacts and leaves unrelated profile content unchanged.
146
+ - [x] Interrupted or failed installation restores the pre-operation state or reports a deterministic recovery command.
147
+
148
+ ### Phase 2 Completion Evidence
149
+
150
+ Completed on 2026-08-31 after adversarial transaction, concurrency, rollback, path-swap, state-CAS, and credential-boundary testing.
151
+
152
+ - Full repository suite on the final isolated DSH scope: 1846/1846 tests.
153
+ - Phase 2 spec review: approved with zero must-fix gaps.
154
+ - Defensive security review: approved with zero findings.
155
+ - Code quality review: 0 Critical, 0 Important, 0 Suggestions.
156
+ - Strict validator: 0 errors, 0 warnings on the verified DSH tree.
157
+ - Skill audit: 0 HIGH, 0 WARN.
158
+ - Exact reviewed pins are DSH `0.1.1-rc.2`, dsh-codex `1.0.0`, and dsh-orchestrator `1.0.1`.
159
+ - Lifecycle state stores canonical package and preset ownership metadata without credentials or package contents.
160
+
161
+ ### Phase 2 Tasks
162
+
163
+ | ID | Outcome | Affected files | Owner | Depends on |
164
+ |---|---|---|---|---|
165
+ | P2.1 | Freeze the pinned DSH plugin add, update, and removal contract against DSH `0.1.1-rc.2` in bounded fixtures | `scripts/install_steps/dsh.py`, `tests/fixtures/dsh/`, `tests/test_dsh.bats` | `backend-specialist` | Phase 1 |
166
+ | P2.2 | Implement explicit profile install, update, doctor, and uninstall dispatch with `web` as the documented default profile | `bin/ai-toolkit.js`, `scripts/install.py`, `scripts/install_steps/dsh.py`, `scripts/uninstall.py` | `command-expert` | P2.1 |
167
+ | P2.3 | Extend state tracking with DSH profile and managed-preset ownership | `scripts/install_steps/install_state.py`, `kb/reference/manifest-install.md`, `tests/test_install_state.bats` | `backend-specialist` | P2.1 |
168
+ | P2.4 | Add atomic preset copy, collision refusal, hash verification, and recovery behavior | `scripts/install_steps/dsh.py`, `tests/test_dsh.bats`, `tests/test_uninstall_recovery.bats` | `backend-specialist` | P2.2, P2.3 |
169
+ | P2.5 | Audit command construction, environment filtering, logs, and state for credential exposure | `scripts/install_steps/dsh.py`, `scripts/uninstall.py`, `tests/test_dsh.bats` | `security-auditor` | P2.2, P2.4 |
170
+ | P2.6 | Exercise clean install, repeat install, update, collision, offline, interruption, and uninstall with fake DSH binaries and isolated roots | `tests/test_dsh.bats`, `tests/test_uninstall_ai_tools.bats`, `tests/fixtures/dsh/` | `test-engineer` | P2.2, P2.3, P2.4, P2.5 |
171
+
172
+ ### Phase 2 Rollback and Scope Cut
173
+
174
+ Disable the lifecycle subcommand while retaining the Phase 1 project target and read-only doctor output. Users can continue following the standalone package installation guides. Never recover from a lifecycle bug by deleting an unowned preset or profile.
175
+
176
+ ## Phase 3: Registry, Documentation, and Release Qualification
177
+
178
+ Dependency: Phase 2 → Phase 3.
179
+
180
+ Size: **S to M (1 day)**.
181
+
182
+ ### Phase 3 Success Criteria
183
+
184
+ - [x] DSH has one opt-in registry entry with pinned docs and release-note sources.
185
+ - [x] Compatibility documentation distinguishes project emission, explicit profile mutation, vendor authentication, and unsupported Google routes.
186
+ - [x] README, CLI help, architecture, supported-tools registry, manifest install reference, and `llms.txt` describe the same commands and boundaries.
187
+ - [x] An isolated real-profile qualification installs the two published packages, selects the released preset, and completes Codex-to-Claude plus Codex-to-Copilot-Gemini delegation.
188
+ - [x] No release is tagged while focused tests, full tests, validation, skill audit, ShellCheck, or generated-document checks are red.
189
+
190
+ ### Phase 3 Completion Evidence
191
+
192
+ Completed on 2026-09-01 after exact-package pre-tag and post-release qualification.
193
+
194
+ - Full repository suite: 1920/1920 tests.
195
+ - Strict validator: 0 errors and 0 warnings; skill audit: 0 HIGH and 0 WARN.
196
+ - ShellCheck, Apache-2.0 licensing, SARIF, public-surface, ecosystem, npm audit, and package dry-run gates passed.
197
+ - `@softspark/dsh-orchestrator@1.0.1` published with SLSA provenance after both native-login marker tools completed through a Codex parent.
198
+ - The exact npm registry package repeated both Claude Code and Copilot Gemini child/parent marker roundtrips, with no provider API key handling.
199
+ - The isolated DSH process stopped cleanly and the unrelated profile fixture remained intact.
200
+
201
+ ### Phase 3 Tasks
202
+
203
+ | ID | Outcome | Affected files | Owner | Depends on |
204
+ |---|---|---|---|---|
205
+ | P3.1 | Add the opt-in DSH registry and drift-monitoring contract | `scripts/ecosystem_tools.json`, `tests/test_ecosystem_doctor.bats` | `technical-researcher` | Phase 2 |
206
+ | P3.2 | Publish one compatibility contract and synchronize all user-facing command surfaces | `kb/reference/dsh-compatibility.md`, `kb/reference/supported-tools-registry.md`, `kb/reference/architecture-overview.md`, `kb/reference/manifest-install.md`, `README.md`, `CLAUDE.md`, `llms.txt`, `bin/ai-toolkit.js` | `documenter` | P3.1 |
207
+ | P3.3 | Run isolated end-to-end qualification with real DSH and published packages, then record evidence | `kb/reference/dsh-compatibility.md`, `kb/procedures/release-verification-sop.md` | `infrastructure-validator` | P3.2 |
208
+ | P3.4 | Run focused and full repository gates and assess regression blast radius | `tests/test_dsh.bats`, `tests/test_cli.bats`, `tests/test_install.bats`, `tests/test_uninstall_ai_tools.bats`, `scripts/validate.py`, `scripts/audit_skills.py` | `qa-automation-engineer` | P3.2, P3.3 |
209
+ | P3.5 | Review final security boundaries and veto release on credential or ownership regressions | `scripts/install_steps/dsh.py`, `scripts/install_steps/install_state.py`, `scripts/uninstall.py`, `kb/reference/dsh-compatibility.md`, `tests/test_dsh.bats` | `security-architect` | P3.3, P3.4 |
210
+
211
+ ### Phase 3 Rollback and Scope Cut
212
+
213
+ Do not tag or publish the ai-toolkit release. Keep the published standalone `@softspark/dsh-codex@1.0.0` and `@softspark/dsh-orchestrator@1.0.1` packages as the supported installation route. If upstream DSH drifts during qualification, retain the registry entry as unsupported-preview metadata and remove the user-facing install command until compatibility is restored.
214
+
215
+ ## Dependencies
216
+
217
+ ```text
218
+ Phase 1 → Phase 2 → Phase 3
219
+ ```
220
+
221
+ Within phases:
222
+
223
+ ```text
224
+ P1.1 → P1.2 → P1.5
225
+ P1.3 ─────────→ P1.5
226
+ P1.4 ─────────→ P1.5
227
+
228
+ P2.1 → P2.2 → P2.4 → P2.5 → P2.6
229
+ ↘ P2.3 ↗
230
+
231
+ P3.1 → P3.2 → P3.3 → P3.4 → P3.5
232
+ ```
233
+
234
+ No phase begins until the previous phase meets its success criteria. Phase 1 can ship as project-only compatibility without Phase 2. Phase 2 can remain unreleased if real-profile qualification fails.
235
+
236
+ ## Requirement Traceability
237
+
238
+ | Requirement | Tasks |
239
+ |---|---|
240
+ | Explicit DSH project target | P1.1, P1.2, P1.5 |
241
+ | DSH excluded from defaults and `all` | P1.1, P1.5 |
242
+ | Fail-closed skill discovery | P1.3, P1.5 |
243
+ | No credential handling | P1.4, P2.5, P3.5 |
244
+ | Exact package installation | P2.1, P2.2, P2.6 |
245
+ | Managed preset lifecycle | P2.3, P2.4, P2.6 |
246
+ | Ownership-safe uninstall | P2.3, P2.4, P2.6 |
247
+ | Registry and documentation parity | P3.1, P3.2 |
248
+ | Real subscription-backed smoke test | P3.3, P3.4 |
249
+ | Release blocked on red gates | P3.4, P3.5 |
250
+
251
+ ## Verification
252
+
253
+ ### Focused gates
254
+
255
+ ```bash
256
+ bats tests/test_dsh.bats
257
+ bats tests/test_install.bats
258
+ bats tests/test_install_profiles.bats
259
+ bats tests/test_install_state.bats
260
+ bats tests/test_uninstall_ai_tools.bats
261
+ bats tests/test_uninstall_recovery.bats
262
+ ```
263
+
264
+ ### Repository gates
265
+
266
+ ```bash
267
+ python3 scripts/validate.py --strict
268
+ python3 scripts/audit_skills.py --ci
269
+ python3 scripts/ecosystem_doctor.py
270
+ npm test
271
+ ```
272
+
273
+ Run ShellCheck when a shell fixture, hook, or command wrapper changes. Run the existing generated-document drift checks before commit.
274
+
275
+ ### Isolated runtime qualification
276
+
277
+ Use a new task-specific `DSH_HOME` and DSH profile. Do not replace `HOME` and do not reuse the maintainer's regular DSH profile.
278
+
279
+ Verify these observations:
280
+
281
+ 1. Project installation emits the full managed skill catalog and no nested skill entry.
282
+ 2. Profile installation records exact package versions and one managed preset.
283
+ 3. Codex reports ChatGPT-owned authentication through its own status command.
284
+ 4. Claude Code and Copilot own their login state; ai-toolkit state and logs contain no credential values.
285
+ 5. A Codex parent delegates one bounded marker task to Claude Code and one to Copilot Gemini.
286
+ 6. Uninstall returns the isolated profile to its pre-install inventory while preserving an injected user-owned preset fixture.
287
+
288
+ ## Pre-Mortem
289
+
290
+ | Failure mode | Probability | Impact | Mitigation |
291
+ |---|---|---|---|
292
+ | Generic `install --local` mutates a global DSH profile | Medium | High | Separate project emission from the explicit `ai-toolkit dsh install` command and test zero `$DSH_HOME` writes in Phase 1 |
293
+ | `--editors all` silently gains a developer-preview runtime | Medium | High | Keep explicit-only editors in a separate registry and assert expansion output in tests |
294
+ | Preset update overwrites user edits or a same-name user preset | Medium | High | Require ownership state plus matching previous hash; refuse every ambiguous collision |
295
+ | Partial DSH plugin installation leaves one provider without the matching preset | Medium | High | Preflight all inputs, snapshot managed state, order mutations, and implement deterministic recovery |
296
+ | Installer logs or state capture vendor credentials | Low | Critical | Never invoke login flows, never read credential files, redact command output, and audit fixtures for secret-shaped data |
297
+ | DSH prerelease changes plugin or preset discovery semantics | High | High | Pin the reviewed DSH version, run ecosystem drift checks, and block release on real-profile qualification failure |
298
+ | Reusing Codex-adapted skills produces incorrect DSH delegation instructions | Medium | Medium | Validate representative delegation-heavy skills in the Codex parent and add a DSH-specific adapter only if evidence requires it |
299
+ | Copilot changes Gemini model availability or credit policy | Medium | Medium | Treat model and credit policy as doctor-visible compatibility data, not a promise hardcoded into ai-toolkit behavior |
300
+
301
+ ## Agent Assignments
302
+
303
+ | Workstream | Primary agent | Review agent | Reason |
304
+ |---|---|---|---|
305
+ | CLI and installer plumbing | `backend-specialist` | `tech-lead` | Python and Node entry-point integration with existing installer layers |
306
+ | Command UX | `command-expert` | `product-manager` | Explicit mutation semantics, dry-run output, and actionable errors |
307
+ | Runtime preflight and qualification | `infrastructure-validator` | `technical-researcher` | DSH profile behavior, pinned compatibility, and observable smoke evidence |
308
+ | Security and ownership | `security-auditor` | `security-architect` | Credential boundary, collision refusal, state minimization, and release veto |
309
+ | Test automation | `test-engineer` | `qa-automation-engineer` | Fake-runtime fixtures, lifecycle integration tests, and full regression gates |
310
+ | Documentation | `documenter` | `fact-checker` | Cross-file parity and evidence-backed compatibility claims |
311
+
312
+ ## Approval Checkpoint
313
+
314
+ Implementation starts only after the user approves:
315
+
316
+ 1. The two-command split between project emission and explicit DSH profile mutation.
317
+ 2. Excluding DSH from `--editors all` and auto-detection while upstream remains a developer preview.
318
+ 3. Pinning the native target to DSH `0.1.1-rc.2`, dsh-codex `1.0.0`, and dsh-orchestrator `1.0.1`.
319
+ 4. Deferring 44-agent mapping, MCP bridging, and hook bridging outside this plan.
320
+
321
+ ## Sources
322
+
323
+ - `kb/history/completed/dsh-integration-plan-superseded.md`
324
+ - `bin/ai-toolkit.js`
325
+ - `scripts/install.py`
326
+ - `scripts/install_steps/ai_tools.py`
327
+ - `scripts/install_steps/install_state.py`
328
+ - `scripts/ecosystem_tools.json`
329
+ - <https://github.com/softspark/dsh-codex>
330
+ - <https://github.com/softspark/dsh-orchestrator>
331
+ - <https://github.com/deepseek-ai/deepseek-harness>