@softspark/ai-toolkit 4.29.2 → 4.30.3

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 (43) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/README.md +40 -15
  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-preparation-sop.md +81 -20
  16. package/kb/procedures/release-verification-sop.md +35 -5
  17. package/kb/reference/architecture-overview.md +24 -5
  18. package/kb/reference/cli-reference.md +1 -1
  19. package/kb/reference/dsh-compatibility.md +183 -0
  20. package/kb/reference/manifest-install.md +112 -5
  21. package/kb/reference/mcp-templates.md +11 -4
  22. package/kb/reference/plugin-pack-conventions.md +35 -18
  23. package/kb/reference/supported-tools-registry.md +30 -6
  24. package/llms-full.txt +1190 -69
  25. package/llms.txt +3 -0
  26. package/manifest.json +2 -2
  27. package/package.json +2 -2
  28. package/scripts/codex_skill_adapter.py +673 -34
  29. package/scripts/config_resolver.py +80 -14
  30. package/scripts/doctor.py +98 -20
  31. package/scripts/ecosystem_tools.json +51 -1
  32. package/scripts/generate_codex_skills.py +22 -20
  33. package/scripts/install.py +30 -13
  34. package/scripts/install_steps/ai_tools.py +97 -33
  35. package/scripts/install_steps/dsh.py +5063 -0
  36. package/scripts/install_steps/install_state.py +1645 -57
  37. package/scripts/mcp_editors.py +5 -2
  38. package/scripts/plugin.py +2495 -163
  39. package/scripts/plugin_mcp.py +279 -0
  40. package/scripts/plugin_rules.py +389 -0
  41. package/scripts/plugin_schema.py +139 -23
  42. package/scripts/uninstall.py +47 -4
  43. package/scripts/validate.py +421 -0
@@ -3,10 +3,10 @@ title: "SOP: Ecosystem Sync"
3
3
  category: procedures
4
4
  service: ai-toolkit
5
5
  tags: [sop, ecosystem, editors, generators, drift-detection, sync]
6
- version: "1.1.0"
6
+ version: "1.2.0"
7
7
  created: "2026-04-23"
8
- last_updated: "2026-07-10"
9
- description: "Quarterly (or event-triggered) sync procedure that detects documentation and capability drift in supported tools (Claude Code, Claude app, and 11 editors), analyses our generators and skills for missing features, and walks through the migration + generator-update workflow."
8
+ last_updated: "2026-08-31"
9
+ description: "Quarterly or event-triggered sync procedure for the 14 registry tools: Claude Code, Claude app, explicit-preview DSH, and 11 default editor integrations."
10
10
  ---
11
11
 
12
12
  # SOP: Ecosystem Sync
@@ -26,7 +26,7 @@ Keeps ai-toolkit aligned with the tools it integrates with. When an editor adds
26
26
  ## Quick Reference
27
27
 
28
28
  ```bash
29
- # Full check (all 13 tools, online)
29
+ # Full check (all 14 registry tools, online)
30
30
  python3 scripts/ecosystem_doctor.py --format text
31
31
 
32
32
  # Single tool
@@ -48,11 +48,13 @@ python3 scripts/ecosystem_doctor.py --offline --format text
48
48
 
49
49
  | File | Purpose |
50
50
  |------|---------|
51
- | `scripts/ecosystem_tools.json` | Authoritative registry: 13 tools with doc URLs, config paths, our generators, capability markers |
51
+ | `scripts/ecosystem_tools.json` | Authoritative registry: 14 tools with doc URLs, config paths, our generators, capability markers |
52
52
  | `benchmarks/ecosystem-doctor-snapshot.json` | Last-seen state (headings, content hash, markers, version) — updated via `--update` |
53
53
  | `scripts/ecosystem_doctor.py` | Drift detector |
54
54
  | `kb/reference/supported-tools-registry.md` | Human-readable view of the registry |
55
55
 
56
+ DSH is counted because the ecosystem doctor tracks its upstream documentation and reviewed version. It remains an explicit developer-preview target, not a default editor integration, and stays outside `--editors all` and auto-detection.
57
+
56
58
  ---
57
59
 
58
60
  ## Phase 1: Run the Doctor
@@ -313,7 +313,7 @@ python3 scripts/validate.py --strict
313
313
  ai-toolkit plugin list # show available packs
314
314
  ai-toolkit plugin install --editor claude <name> # install for Claude Code global target
315
315
  ai-toolkit plugin install --editor codex <name> # install for Codex global target
316
- ai-toolkit plugin install --editor all --all # install all 12 packs for both runtimes
316
+ ai-toolkit plugin install --editor all --all # install all available packs for all supported editors
317
317
  ai-toolkit plugin update --editor all --all # re-apply all installed packs after toolkit updates
318
318
  ai-toolkit plugin clean <name> # prune data older than 90 days
319
319
  ai-toolkit plugin clean <name> --days 30 # custom retention
@@ -3,10 +3,10 @@ title: "SOP: Release Preparation"
3
3
  category: procedures
4
4
  service: ai-toolkit
5
5
  tags: [sop, release, version, publish, changelog, semver, provenance, sarif, ecosystem, shellcheck]
6
- version: "1.14.0"
6
+ version: "1.15.0"
7
7
  created: "2026-04-10"
8
- last_updated: "2026-08-06"
9
- description: "Step-by-step checklist for preparing a new ai-toolkit release — ecosystem-sync drift check, version sync, changelog, artifact regeneration, validation, and tagging. Run BEFORE every git tag. Includes mandatory Provenance, SARIF, and checksum-pin checks added in v2.8.0, the single-run npm test discipline added in v1.8.0, the ecosystem-sync gate added in v1.9.0, the registry-vs-generators drift gate added in v1.10.0, the mandatory pre-tag ShellCheck gate added in v1.11.0 (publish.yml does not run ShellCheck, so a hook lint failure can publish while reddening main CI see the v4.5.1 postmortem in Phase 5), the pre-push tag assertions added in v1.12.0 after v4.19.0 was tagged on the wrong commit (Phase 7), and the licensing gate added in v1.13.0 with the move to Apache-2.0 (Phase 5c)."
8
+ last_updated: "2026-09-02"
9
+ description: "Step-by-step checklist for preparing a new ai-toolkit release — ecosystem-sync drift check, version sync, changelog, artifact regeneration, validation, branch CI, and tagging. Run BEFORE every git tag. Includes mandatory Provenance, SARIF, checksum-pin, ShellCheck, licensing, exact-tag assertions, and a green Ubuntu/macOS branch-CI gate before any release tag is created."
10
10
  ---
11
11
 
12
12
  # SOP: Release Preparation
@@ -68,16 +68,38 @@ python3 scripts/ecosystem_doctor.py --offline --check || { echo "STALE ecosystem
68
68
  # 5c. Licensing gate — SPDX headers, LICENSE, NOTICE, manifest consistency
69
69
  npx bats tests/test_licensing.bats || { echo "LICENSING GATE FAILED"; exit 1; }
70
70
 
71
- # 6. Commit + tag + push
71
+ # 6. Commit, push branch, and wait for the exact commit's full CI
72
72
  git add -A && git commit -m "chore: release vX.Y.Z"
73
- git tag vX.Y.Z
74
-
75
- # 6a. Assert the tag before pushing it (v4.19.0 postmortem, Phase 7)
76
- test "$(git rev-parse vX.Y.Z)" = "$(git rev-parse HEAD)" || { echo "FAIL: tag not on HEAD"; exit 1; }
73
+ RELEASE_SHA=$(git rev-parse HEAD)
74
+ git push origin main || { echo "FAIL: release commit push failed"; exit 1; }
75
+ RUN_ID=""
76
+ for ATTEMPT in 1 2 3 4 5; do
77
+ RUN_ID=$(gh run list --workflow ci.yml --event push --commit "$RELEASE_SHA" \
78
+ --limit 1 --json databaseId --jq '.[0].databaseId')
79
+ [ -n "$RUN_ID" ] && break
80
+ echo "Waiting for CI run registration ($ATTEMPT/5)" >&2
81
+ [ "$ATTEMPT" -eq 5 ] || sleep 60
82
+ done
83
+ test -n "$RUN_ID" || { echo "FAIL: CI run not found for release commit"; exit 1; }
84
+ gh run watch "$RUN_ID" --exit-status \
85
+ || { echo "FAIL: release commit CI failed"; exit 1; }
86
+ for OS in ubuntu-latest macos-latest; do
87
+ gh run view "$RUN_ID" --json jobs \
88
+ --jq ".jobs[] | select(.name == \"Bats test suite ($OS)\") | .conclusion" \
89
+ | grep -qx success || { echo "FAIL: $OS test job not green"; exit 1; }
90
+ done
91
+ test "$(git rev-parse HEAD)" = "$RELEASE_SHA" || { echo "FAIL: local HEAD changed during CI"; exit 1; }
92
+ git fetch origin main || { echo "FAIL: origin/main refresh failed"; exit 1; }
93
+ test "$(git rev-parse origin/main)" = "$RELEASE_SHA" || { echo "FAIL: origin/main changed during CI"; exit 1; }
94
+
95
+ # 6a. Only green branch CI authorizes tag creation
96
+ git tag vX.Y.Z "$RELEASE_SHA"
97
+
98
+ # 6b. Assert the tag before pushing it (v4.19.0 postmortem, Phase 7)
99
+ test "$(git rev-parse vX.Y.Z)" = "$RELEASE_SHA" || { echo "FAIL: tag not on tested release commit"; exit 1; }
77
100
  git show --no-patch --format=%s vX.Y.Z | grep -qx "chore: release vX.Y.Z" || { echo "FAIL: tag not on release commit"; exit 1; }
78
101
 
79
- # 6b. Branch first, then the single tag by full ref. Never --tags.
80
- git push origin main
102
+ # 6c. Push the single tag by full ref. Never --tags.
81
103
  git push origin refs/tags/vX.Y.Z
82
104
  ```
83
105
 
@@ -493,23 +515,60 @@ git commit -m "chore: release vX.Y.Z"
493
515
 
494
516
  ---
495
517
 
496
- ## Phase 7: Tag and Push
518
+ ## Phase 7: Push Branch, Verify CI, Tag, and Push Tag
497
519
 
498
520
  ```bash
499
- git tag vX.Y.Z
521
+ RELEASE_SHA=$(git rev-parse HEAD)
522
+ git push origin main || { echo "FAIL: release commit push failed"; exit 1; }
523
+
524
+ # Bind the gate to the exact release commit. GitHub run registration is
525
+ # asynchronous, so retry at most five times and log every attempt.
526
+ RUN_ID=""
527
+ for ATTEMPT in 1 2 3 4 5; do
528
+ RUN_ID=$(gh run list --workflow ci.yml --event push --commit "$RELEASE_SHA" \
529
+ --limit 1 --json databaseId --jq '.[0].databaseId')
530
+ [ -n "$RUN_ID" ] && break
531
+ echo "Waiting for CI run registration ($ATTEMPT/5)" >&2
532
+ [ "$ATTEMPT" -eq 5 ] || sleep 60
533
+ done
534
+ test -n "$RUN_ID" || { echo "FAIL: CI run not found for release commit"; exit 1; }
535
+ gh run watch "$RUN_ID" --exit-status \
536
+ || { echo "FAIL: release commit CI failed"; exit 1; }
537
+
538
+ # publish.yml is Ubuntu-only. Require both full CI matrix jobs before creating
539
+ # the tag so a green publish job cannot bypass a red macOS test.
540
+ for OS in ubuntu-latest macos-latest; do
541
+ gh run view "$RUN_ID" --json jobs \
542
+ --jq ".jobs[] | select(.name == \"Bats test suite ($OS)\") | .conclusion" \
543
+ | grep -qx success || { echo "FAIL: $OS test job not green"; exit 1; }
544
+ done
545
+
546
+ # Refuse to tag if either local or remote main moved while CI was running.
547
+ test "$(git rev-parse HEAD)" = "$RELEASE_SHA" \
548
+ || { echo "FAIL: local HEAD changed during CI"; exit 1; }
549
+ git fetch origin main || { echo "FAIL: origin/main refresh failed"; exit 1; }
550
+ test "$(git rev-parse origin/main)" = "$RELEASE_SHA" \
551
+ || { echo "FAIL: origin/main changed during CI"; exit 1; }
552
+
553
+ git tag vX.Y.Z "$RELEASE_SHA"
500
554
 
501
555
  # Assert the tag before pushing it. Both checks are one line each and both
502
556
  # have caught a real broken release.
503
- test "$(git rev-parse vX.Y.Z)" = "$(git rev-parse HEAD)" \
504
- || { echo "FAIL: tag is not on HEAD"; exit 1; }
557
+ test "$(git rev-parse vX.Y.Z)" = "$RELEASE_SHA" \
558
+ || { echo "FAIL: tag is not on the tested release commit"; exit 1; }
505
559
  git show --no-patch --format=%s vX.Y.Z | grep -qx "chore: release vX.Y.Z" \
506
560
  || { echo "FAIL: tag is not on the chore: release commit"; exit 1; }
507
561
 
508
- # Push the branch, then the single release tag by its full ref.
509
- git push origin main
562
+ # Push the single release tag by its full ref.
510
563
  git push origin refs/tags/vX.Y.Z
511
564
  ```
512
565
 
566
+ **Why branch CI comes before the tag (v4.30.2 postmortem).** The publish
567
+ workflow runs only on Ubuntu and can publish while the separate macOS matrix job
568
+ is red. `v4.30.2` exposed this with a macOS-only DSH timing failure. A release
569
+ commit must therefore pass the complete Ubuntu/macOS branch workflow before its
570
+ tag exists; a successful publish workflow is not a substitute for green CI.
571
+
513
572
  **Why the assertions (v4.19.0 postmortem).** v4.19.0 was tagged on a commit
514
573
  that contained only a KB document and still carried `package.json` version
515
574
  `4.18.0`; the actual release sat in the commit above it under a recycled
@@ -580,7 +639,9 @@ git push origin --delete vX.Y.Z
580
639
  | 15a | Licensing gate | `npx bats tests/test_licensing.bats` | 7/7 — SPDX headers, LICENSE, NOTICE, npm `files`, manifest consistency |
581
640
  | 16 | Tests | `git add -A kb/` if the KB changed, then `npm test` | All pass |
582
641
  | 17 | Commit | `git commit` | Clean working tree |
583
- | 18 | Tag | `git tag vX.Y.Z` | Tag exists |
584
- | 18a | Tag is on HEAD | `test "$(git rev-parse vX.Y.Z)" = "$(git rev-parse HEAD)"` | Exit 0 |
585
- | 18b | Tag is on the release commit | `git show --no-patch --format=%s vX.Y.Z` | Reads `chore: release vX.Y.Z` |
586
- | 19 | Push branch, then the single tag | `git push origin main && git push origin refs/tags/vX.Y.Z` | CI triggered with `id-token: write`. Never `--tags`. |
642
+ | 18 | Push branch | `git push origin main` | Exact release commit is on `origin/main` |
643
+ | 18a | Full branch CI | `gh run watch "$RUN_ID" --exit-status` plus matrix job assertions | Ubuntu and macOS Bats jobs both conclude `success` |
644
+ | 19 | Tag | `git tag vX.Y.Z` | Tag exists only after green branch CI |
645
+ | 19a | Tag is on tested SHA | `test "$(git rev-parse vX.Y.Z)" = "$RELEASE_SHA"` | Exit 0 |
646
+ | 19b | Tag is on the release commit | `git show --no-patch --format=%s vX.Y.Z` | Reads `chore: release vX.Y.Z` |
647
+ | 20 | Push the single tag | `git push origin refs/tags/vX.Y.Z` | Publish CI triggered with `id-token: write`. Never `--tags`. |
@@ -2,11 +2,11 @@
2
2
  title: "SOP: Release Verification"
3
3
  category: procedures
4
4
  service: ai-toolkit
5
- tags: [sop, verification, release, smoke-test, install, update, qa, provenance, sarif]
6
- version: "1.7.0"
5
+ tags: [sop, verification, release, smoke-test, install, update, qa, provenance, sarif, dsh]
6
+ version: "1.8.0"
7
7
  created: "2026-04-08"
8
- last_updated: "2026-07-14"
9
- description: "End-to-end smoke test after installing or updating @softspark/ai-toolkit. Verifies CLI, native Codex and GitHub Copilot surfaces, Claude app export, doctor, validation, tests, eject, provenance, SARIF, and per-skill permissions."
8
+ last_updated: "2026-09-01"
9
+ description: "End-to-end smoke test after installing or updating @softspark/ai-toolkit. Verifies CLI, native Codex and GitHub Copilot surfaces, explicit DSH lifecycle, Claude app export, doctor, validation, tests, eject, provenance, SARIF, and per-skill permissions."
10
10
  ---
11
11
 
12
12
  # SOP: Release Verification
@@ -31,7 +31,7 @@ Verifies all critical paths from the user's perspective.
31
31
 
32
32
  ## Quick Checklist (TL;DR)
33
33
 
34
- 14 commands if all pass, the release is ready:
34
+ The 14 core commands below must pass. Releases that change DSH must also complete Phase 10.
35
35
 
36
36
  ```bash
37
37
  # Pre-commit (Phase 0)
@@ -444,6 +444,36 @@ app-native rules skill, bundled agents/skills, and plugin-relative Cowork hooks.
444
444
 
445
445
  ---
446
446
 
447
+ ## Phase 10: Explicit DSH Qualification (v4.30.0+)
448
+
449
+ Run this phase whenever the release changes the `dsh` target, package pins, preset lifecycle, or DSH compatibility documentation. Use a new task-specific `DSH_HOME`; never replace `HOME` or reuse a regular profile.
450
+
451
+ Prerequisites: DSH `0.1.1-rc.2`, pnpm `>=11.7.0,<12.0.0`, Codex logged in through ChatGPT, Claude Code logged in natively, and GitHub Copilot CLI logged in natively. Do not supply provider API keys.
452
+
453
+ ```bash
454
+ DSH_SMOKE_ROOT="$(mktemp -d)"
455
+ export DSH_HOME="$DSH_SMOKE_ROOT/dsh-home"
456
+
457
+ ai-toolkit dsh install --profile web
458
+ ai-toolkit dsh doctor --profile web
459
+ dsh --profile web --host 127.0.0.1 --port 0 --no-open
460
+ ```
461
+
462
+ In a new `softspark-orchestrator` session, select the `codex` provider and run two standalone marker prompts:
463
+
464
+ 1. `subagent_claude_code` returns an exact child marker, then the Codex parent returns its exact completion marker.
465
+ 2. `subagent_gemini_copilot` returns an exact child marker, then the Codex parent returns its exact completion marker.
466
+
467
+ Stop DSH, then remove only the managed profile artifacts:
468
+
469
+ ```bash
470
+ ai-toolkit dsh uninstall --profile web --yes
471
+ ```
472
+
473
+ **Verify:** both tool results have `isError=false`, both turns end as `completed`, `doctor` reports no recovery requirement before uninstall, and an unrelated preset fixture remains unchanged. Preserve only redacted event sequence evidence; never attach credentials, auth files, or full private prompts.
474
+
475
+ ---
476
+
447
477
  ## Troubleshooting
448
478
 
449
479
  ### `ai-toolkit: command not found`
@@ -3,17 +3,17 @@ title: "AI Toolkit - Architecture Overview"
3
3
  category: reference
4
4
  service: ai-toolkit
5
5
  tags: [architecture, overview, design, structure]
6
- version: "1.8.0"
6
+ version: "1.10.0"
7
7
  created: "2026-03-23"
8
- last_updated: "2026-08-19"
9
- description: "Architecture of ai-toolkit: directory layout, Claude app export, global install model, editor-aware MCP install, Codex translation layer, skill tiers, and integration with projects."
8
+ last_updated: "2026-09-01"
9
+ description: "Architecture of ai-toolkit: install ownership, runtime adapters, the explicit DSH target, skill tiers, and project integration."
10
10
  ---
11
11
 
12
12
  # AI Toolkit Architecture
13
13
 
14
14
  ## Purpose
15
15
 
16
- Shared, project-agnostic AI development toolkit for Claude Code, Claude Chat/Cowork, and compatible assistants such as Cursor, Devin, Copilot, Gemini, Cline, Roo/Zoo Code, Aider, Augment, and Google Antigravity. Provides agents, skills, lifecycle hooks, persona presets, and runtime-specific plugin packaging.
16
+ Shared, project-agnostic AI development toolkit for Claude Code, Claude Chat/Cowork, compatible assistants, and the explicit developer-preview DSH target. Provides agents, skills, lifecycle hooks, persona presets, and runtime-specific plugin packaging.
17
17
 
18
18
  ## Design Principles
19
19
 
@@ -117,6 +117,7 @@ Machine (global) Project (local)
117
117
  **`ai-toolkit install --local`** — run per project. Always installs Claude Code configs (CLAUDE.md, settings.local.json, constitution.md, language rules). Editor configs are opt-in via `--editors`:
118
118
  - `--editors all` — install all 11 editors (Cursor, Windsurf, Cline, Roo, Aider, Augment, Copilot, Antigravity, Codex, Gemini, opencode)
119
119
  - `--editors cursor,aider` — install only selected editors
120
+ - `--editors dsh` requires explicit selection. Its DSH-specific output is project `.agents/skills`; the normal `--local` Claude files, detected language rules, and generic project outputs still apply. DSH is excluded from `all`, auto-detection, and defaults.
120
121
  - (no flag) — auto-detect from existing project files; `update --local` picks up whatever editors already have configs
121
122
 
122
123
  Each editor gets its documented directory-based format. Copilot receives root
@@ -139,6 +140,10 @@ packs can layer their rules, skills, and hooks onto that Codex user target.
139
140
 
140
141
  Claude Chat/Desktop/Cowork is deliberately outside `--editors`: the app does not scan filesystem configuration under `~/.claude`. `ai-toolkit claude-app export` creates a self-contained plugin ZIP with skills, agents, Cowork hooks, app-native rules, and bundled hook dependencies. It also emits the compact text that users paste into Cowork global instructions. Updating requires re-export and re-upload because the app owns its plugin store.
141
142
 
143
+ DSH profile mutation is also outside generic installation. `ai-toolkit dsh install|update|doctor|uninstall --profile web` names both the integration and profile. It manages only `@softspark/dsh-codex@1.0.0`, `@softspark/dsh-orchestrator@1.0.1`, the released preset, and their ownership record. Vendor CLIs own login and credentials. DSH `0.1.1-rc.2` is the only reviewed host version.
144
+
145
+ Both DSH preview paths are read-only. Project `--dry-run` resolves `extends` without persisting its lockfile and changes no project or `DSH_HOME` entry. Profile lifecycle `--dry-run` changes no package, preset, state, profile, or authentication surface.
146
+
142
147
  If a project already has `.mcp.json`, local install mirrors its `mcpServers`
143
148
  entries into `.claude/settings.local.json` plus any selected editors with
144
149
  project-scoped native MCP files: `.cursor/mcp.json`, `.github/mcp.json`,
@@ -150,6 +155,10 @@ project-scoped native MCP files: `.cursor/mcp.json`, `.github/mcp.json`,
150
155
  |---------|--------|-------------|
151
156
  | `install` | `~/.claude/` | First-time: per-file symlinks + JSON merge + marker injection + rules |
152
157
  | `install --local` | `./` | Claude Code configs + editors via `--editors` (auto-detect or explicit) |
158
+ | `install --local --editors dsh` | `./` | Generic local outputs plus the shared `.agents/skills` catalog; no DSH profile writes |
159
+ | `dsh install|update --profile <name>` | `$DSH_HOME/profiles/<name>` | Exact SoftSpark package and preset lifecycle |
160
+ | `dsh doctor --profile <name>` | DSH profile and ai-toolkit state | Read-only runtime, ownership, drift, and recovery diagnostics |
161
+ | `dsh uninstall --profile <name>` | Managed DSH package, preset, and state entries | Ownership-checked removal that preserves unrelated profile content |
153
162
  | `claude-app export` | output ZIP + Markdown | Uploadable Claude Chat/Cowork plugin and global instructions |
154
163
  | `update` | `~/.claude/` | Re-apply after npm update or after add-rule/remove-rule |
155
164
  | `update --local` | `./` | Re-apply + refresh project-local configs |
@@ -246,6 +255,16 @@ translation and hook-compatibility model when targeting the global Codex layer.
246
255
 
247
256
  See `kb/reference/codex-cli-compatibility.md` for the detailed mapping.
248
257
 
258
+ ### DSH Explicit Target
259
+
260
+ The DSH target reuses the Codex `.agents/skills` emitter. Canonical skill ownership stays under `app/skills`. DSH invocation metadata is validated before emission because invalid camel-case fields, non-boolean invocation values, and nested discovery entries fail closed upstream.
261
+
262
+ The profile lifecycle is a separate transaction boundary. It stores exact package-tree and preset identity under the shared ai-toolkit state path selected by `AI_TOOLKIT_HOME`, `SOFTSPARK_HOME`, or the default `~/.softspark/ai-toolkit`. A DSH lifecycle lock plus state compare-and-swap checks protect concurrent writers. Collision or rollback ambiguity preserves user data and reports doctor-visible recovery paths.
263
+
264
+ Codex remains the parent model through its local app server. The released preset adds one-shot Claude Code and GitHub Copilot Gemini delegation tools. ai-toolkit does not handle provider API keys or login state. GitHub Copilot policy and AI credits apply to the Gemini route. Direct Google, Antigravity, and Gemini API-key routes are unsupported.
265
+
266
+ See `kb/reference/dsh-compatibility.md` for the exact command, version, authentication, and recovery contract. Real-profile Phase 3 qualification is pending.
267
+
249
268
  ## MCP Rendering Layer
250
269
 
251
270
  `.mcp.json` is the canonical project-level template format. ai-toolkit can render that configuration into editor-native MCP files through `scripts/mcp_editors.py`.
@@ -369,7 +388,7 @@ Severity levels: HIGH (blocks deployment), WARN (should fix), INFO (best practic
369
388
  ## Extension Points
370
389
 
371
390
  ### MCP Templates
372
- `app/mcp-templates/` contains 26 ready-to-use MCP server config templates. Opt-in via `ai-toolkit install --modules mcp-templates` or activated automatically with `--profile strict|full`.
391
+ `app/mcp-templates/` contains 28 ready-to-use MCP server config templates. Opt-in via `ai-toolkit install --modules mcp-templates` or activated automatically with `--profile strict|full`.
373
392
 
374
393
  ### Language Rules
375
394
  `app/rules/` provides language-specific rule files covering 13 languages (TypeScript, Python, Go, Rust, Java, Kotlin, Swift, Dart, C#, PHP, C++, Ruby, common). Auto-detected from project files via `--auto-detect` or selectable with `--modules rules-<lang>`. See README.md for current count.
@@ -47,7 +47,7 @@ Usage: ai-toolkit <command> [options]
47
47
 
48
48
  | Command | Description |
49
49
  |---------|-------------|
50
- | `mcp list` | List available MCP server templates (26 templates) |
50
+ | `mcp list` | List available MCP server templates (28 templates) |
51
51
  | `mcp editors` | List editors with native MCP config adapters and scopes |
52
52
  | `mcp add <name> [names...]` | Add MCP server template(s) to `.mcp.json` |
53
53
  | `mcp install --editor <name[,..]> [names...]` | Install templates into native editor MCP config |
@@ -0,0 +1,183 @@
1
+ ---
2
+ title: "AI Toolkit - DSH Compatibility"
3
+ category: reference
4
+ service: ai-toolkit
5
+ tags: [dsh, deepseek-harness, subscriptions, lifecycle, compatibility]
6
+ version: "1.7.0"
7
+ created: "2026-08-31"
8
+ last_updated: "2026-09-01"
9
+ description: "Compatibility contract for project skills and the explicit SoftSpark package lifecycle in DeepSeek Harness."
10
+ ---
11
+
12
+ # DSH Compatibility
13
+
14
+ ## Summary
15
+
16
+ ai-toolkit supports DeepSeek Harness as an explicit developer-preview target. The integration is maintained by SoftSpark as a community compatibility layer. DeepSeek AI has not endorsed it.
17
+
18
+ The reviewed runtime is DSH `0.1.1-rc.2`. Newer upstream prereleases are not covered until they pass the same qualification. Isolated pre-tag and exact-registry post-release profiles completed the Claude Code and Copilot Gemini marker roundtrips through a Codex parent on 2026-09-01.
19
+
20
+ ## Project vs Profile Outputs
21
+
22
+ | Surface | Command | Managed output | Explicit non-output |
23
+ |---|---|---|---|
24
+ | Project install | `ai-toolkit install --local --editors dsh` | `CLAUDE.md`, `.claude/settings.local.json`, `.claude/constitution.md`, detected language rules, other generic local outputs, and the DSH-specific one-level `.agents/skills/<name>/SKILL.md` catalog with bundled resources | No `$DSH_HOME` writes, npm package changes, profile changes, preset changes, or credential reads |
25
+ | DSH profile | `ai-toolkit dsh install --profile web` | Two exact npm dependencies in the named profile, the released `softspark-orchestrator` preset, and ai-toolkit ownership state | No project files, provider login, API keys, unrelated plugins, or user presets |
26
+
27
+ DSH is excluded from `--editors all`, auto-detection, default profiles, and default editor selection. Naming `dsh` without `--local` is not a supported project install route.
28
+
29
+ Project `--dry-run` resolves and validates `extends`, then plans the generic local outputs and `.agents/skills` catalog without creating, changing, or deleting a project entry. It does not create or update `.softspark-toolkit.lock.json`, and it does not mutate `DSH_HOME`, packages, profiles, state, or authentication.
30
+
31
+ ## Local and Global Commands
32
+
33
+ ```bash
34
+ # Generic local outputs plus DSH-specific project skills
35
+ ai-toolkit install --local --editors dsh
36
+
37
+ # Read-only project preview
38
+ ai-toolkit install --local --editors dsh --dry-run
39
+
40
+ # Explicit machine profile lifecycle
41
+ ai-toolkit dsh install --profile web
42
+ ai-toolkit dsh update --profile web
43
+ ai-toolkit dsh doctor --profile web
44
+ ai-toolkit dsh uninstall --profile web --yes
45
+ ```
46
+
47
+ The DSH profile defaults to `web` when `--profile` is omitted. `DSH_HOME` selects the DSH root and defaults to `~/.dsh`. Profile mutation is never an implicit side effect of local installation, global installation, update, or generic uninstall.
48
+
49
+ ## Exact Pins
50
+
51
+ | Component | Reviewed version | Role |
52
+ |---|---:|---|
53
+ | DeepSeek Harness | `0.1.1-rc.2` | Profile host and plugin manager |
54
+ | pnpm | `>=11.7.0,<12.0.0` | Package manager used by the DSH plugin command |
55
+ | `@softspark/dsh-codex` | `1.0.0` | Codex parent provider through local `codex app-server` |
56
+ | `@softspark/dsh-orchestrator` | `1.0.1` | Claude Code and GitHub Copilot Gemini delegation bundle plus released preset |
57
+
58
+ Install and update use exact package arguments with `--save-exact`. Arbitrary DSH prereleases and unpinned SoftSpark packages are outside this contract.
59
+
60
+ The reviewed DSH tag declares `pnpm@11.7.0`. The isolated cold-install environment used Corepack pnpm `11.24.0`, so the lifecycle accepts stable pnpm releases from `11.7.0` through the end of major 11. Before it creates the lifecycle lock or changes a profile, it resolves exact DSH and pnpm command paths from the minimal child `PATH`, records their command and resolved-file identities, and runs their version probes with a five-second bound. Missing, nonzero, timed-out, malformed, or unsupported pnpm probes fail with no package, preset, state, or lifecycle artifact.
61
+
62
+ ## Subscription and Authentication Boundaries
63
+
64
+ ai-toolkit does not log in to a model provider, accept a provider API key, read a vendor credential store, copy tokens, or add credentials to state. Each vendor CLI owns authentication:
65
+
66
+ | Route | Login owner | Subscription or billing boundary |
67
+ |---|---|---|
68
+ | Codex parent | `codex login` and `codex login status` | ChatGPT subscription managed by Codex |
69
+ | Claude delegate | `claude auth login` | Claude Max or Pro managed by Claude Code |
70
+ | Gemini delegate | `copilot login` | Active GitHub Copilot plan and GitHub AI credits |
71
+
72
+ Lifecycle subprocesses receive only `HOME`, the validated `DSH_HOME`, `PATH`, and locale or temporary-directory settings when present. Provider and registry secret environment variables are not forwarded. Vendor CLI output is not copied into lifecycle error messages.
73
+
74
+ ## DSH, Codex, Claude, and Copilot Topology
75
+
76
+ ```text
77
+ DSH session using SoftSpark Orchestrator
78
+ |
79
+ +-> @softspark/dsh-codex
80
+ | -> local codex app-server
81
+ | -> Codex-owned ChatGPT authentication and parent thread
82
+ |
83
+ +-> subagent_claude_code
84
+ | -> DSH Claude Code provider
85
+ | -> Claude Code native login
86
+ |
87
+ +-> subagent_gemini_copilot
88
+ -> GitHub Copilot CLI ACP server
89
+ -> Gemini 3.6 Flash under GitHub policy and AI credits
90
+ ```
91
+
92
+ Codex is the parent provider. The preset keeps the optional Codex subagent row disabled. Claude Code and Copilot Gemini receive bounded standalone delegation tasks.
93
+
94
+ ## Invocation Metadata and Shared Skill Ownership
95
+
96
+ DSH and Codex share the project `.agents/skills` output. `app/skills/<name>/` remains canonical. `scripts/generate_codex_skills.py` emits native links or adapted wrappers, so ai-toolkit does not maintain a second DSH-specific skill catalog.
97
+
98
+ DSH discovers one-level `<name>/SKILL.md` bundles and flat `<name>.md` entries. Names must use lowercase kebab-case. The required fields are `name` and `description`. Optional invocation fields use `user-invocable` and `disable-model-invocation` with boolean values. Camel-case spellings or invalid boolean values fail closed and remove the skill from discovery. Nested `SKILL.md` entries are not supported, but resources inside a valid bundle remain available.
99
+
100
+ The preset owns the session composition and external delegation tools. It does not copy the 44 ai-toolkit agent definitions into 44 DSH presets or subagents.
101
+
102
+ ## Lifecycle State and Recovery
103
+
104
+ State resolves in this order:
105
+
106
+ 1. `$AI_TOOLKIT_HOME/state.json` when `AI_TOOLKIT_HOME` is set.
107
+ 2. `$SOFTSPARK_HOME/ai-toolkit/state.json` when `SOFTSPARK_HOME` is set.
108
+ 3. `~/.softspark/ai-toolkit/state.json` by default.
109
+
110
+ The DSH record stores the canonical DSH home, profile, exact package versions, package-tree identity, preset path, preset hash, ownership flags, and timestamps. It stores no package contents, prompts, credentials, authentication paths, or child-process environment.
111
+
112
+ The published npm packages own their installed code. The canonical preset source is `@softspark/dsh-orchestrator/agent-presets/softspark-orchestrator` inside the exact installed package. ai-toolkit copies and verifies that tree. It does not reconstruct the preset.
113
+
114
+ Mutations first take a nonblocking exclusive POSIX `flock` on the already pinned `DSH_HOME` directory descriptor, then claim the bounded canonical lifecycle lock and use the shared state lock with compare-and-swap publication. Directory locking is independent of the replaceable lock filename. It remains held across sentinel scans, package and preset mutation, normal canonical-lock release, or recovery-sentinel creation plus file and directory `fsync`. A competing lifecycle must acquire the same directory lock before it can scan recovery state or claim the canonical name. The immutable prerequisite record is revalidated after lock acquisition and before every package mutation or package rollback. A replaced or removed executable, or a new earlier `pnpm` PATH shadow, blocks the command. The verified pnpm command directory is placed first in the child PATH so DSH's literal `pnpm` lookup resolves to the probed command. Install, update, and uninstall verify the profile manifest, package trees, preset identity, and unrelated dependencies before and after each external package-manager command. Rollback restores the immutable pre-operation target. It does not reinterpret concurrent bytes as owned data.
115
+
116
+ Each DSH plugin add, update, remove, or rollback command has a 300-second process bound, separate from the short prerequisite probe. This bound accommodates cold package resolution without promising registry or network latency. Every mutation starts DSH in a dedicated POSIX session and process group. A timeout or interruption signals the complete group, escalates from `SIGTERM` to `SIGKILL` when needed, and waits for confirmed group exit before rollback. If exit cannot be confirmed, package rollback is blocked and deterministic inspection steps are reported. Child stdout and stderr remain suppressed from user-facing errors.
117
+
118
+ Process-group signals are allowed only while the unreaped DSH supervisor still binds its PID to that group. If the supervisor identity is lost before escalation, the lifecycle fails closed instead of signaling a group identifier that the operating system could reuse. Before `Popen`, the calling thread blocks `SIGINT` with `pthread_sigmask`. It restores the previous mask only inside a catchable region that covers `communicate`, final PGID inspection, and command postconditions, then restores the mask again in `finally`. Any `BaseException` after spawn runs full process-tree teardown before propagation. Repeated `SIGINT` cannot escape the bounded TERM, KILL, and wait sequence.
119
+
120
+ An unconfirmed process-tree exit first verifies that `$DSH_HOME/.ai-toolkit-lifecycle.lock` still names the held inode, then creates and syncs a transaction-unique process-tree recovery sentinel. It rewrites the canonical lock as a recovery gate only while that identity remains exact. A removed or renamed lock leaves the sentinel as the gate; a foreign replacement is neither overwritten nor deleted. Install, update, and uninstall scan these sentinels before and after claiming the canonical lock, so recovery blocks DSH invocation even when the original lock name was displaced. `doctor` reports every gate's process-group identifier, original profile path, and exact artifact path. ai-toolkit never clears these gates automatically: the operator must verify that the recorded process group has exited, inspect the profile, and only then remove every named recovery artifact.
121
+
122
+ An identity conflict preserves the conflicting path and creates a doctor-visible recovery marker instead of deleting or replacing it. User plugins, dependencies, presets, profile patches, and unrelated state keys remain outside ai-toolkit ownership. Secure mutation and process-tree termination require POSIX primitives available on Linux, WSL, and macOS. Native Windows mutation is unsupported and fails before the lifecycle lock.
123
+
124
+ Profile lifecycle `--dry-run` is read-only. It runs the bounded DSH and pnpm prerequisite probes, but it does not create state, acquire a lock, invoke the plugin manager, or create profile paths. It can therefore report a missing or unsupported prerequisite without leaving lifecycle output.
125
+
126
+ ## Unsupported Google, Antigravity, and API-Key Routes
127
+
128
+ This integration does not provide direct Google AI Pro or Ultra login, Gemini CLI OAuth, Antigravity login, Gemini API keys, DeepSeek API keys, Anthropic API keys, or OpenAI API keys. Gemini is available only through the GitHub Copilot CLI ACP route described above.
129
+
130
+ The first native target also excludes DSH hook bridging, MCP bridging, arbitrary preset import, automatic profile selection, and full ai-toolkit agent mapping. Generic `ai-toolkit uninstall` does not mutate DSH profiles.
131
+
132
+ ## Behavioral Limits
133
+
134
+ - Claude Code and Copilot delegation are one-shot child tasks. Each child receives the task and workspace directory, not the parent conversation history.
135
+ - Copilot runs with no available tools, rejects permission requests, disables built-in MCP servers, remote control, custom instructions, and auto-update, and uses a 30-credit session cap.
136
+ - Child effects completed before cancellation are not rolled back.
137
+ - Workspace content selected by a vendor CLI may leave the machine under that vendor's product terms and account policy.
138
+ - Codex owns its built-in tools, sandbox, approval policy, thread state, and model execution. ai-toolkit does not reproduce those controls inside DSH.
139
+ - Existing DSH sessions keep the preset generation with which they started. Restart DSH and open a new session after install or update.
140
+
141
+ ## Uninstall, Update, and Doctor
142
+
143
+ `ai-toolkit dsh update` changes only a recorded profile whose managed package and preset identities match state. It installs the current reviewed pins, then publishes the new state after all postconditions pass.
144
+
145
+ `ai-toolkit dsh doctor` is read-only. It reports the DSH runtime version, pnpm availability and version, package pins, package-tree and preset ownership, state consistency, lifecycle lock recovery artifacts, staging paths, and recovery markers. A recovery marker keeps `Recovery needed: yes` visible until the operator resolves the named paths.
146
+
147
+ `ai-toolkit dsh uninstall --yes` removes only the recorded SoftSpark packages, preset, and profile state. Drift or ownership ambiguity stops removal. Unrelated profile dependencies, patch files, presets, and state keys remain unchanged.
148
+
149
+ ## Verification
150
+
151
+ Run the static and isolated checks without modifying a regular DSH profile:
152
+
153
+ ```bash
154
+ bats tests/test_ecosystem_doctor.bats
155
+ bats tests/test_dsh.bats
156
+ python3 scripts/ecosystem_doctor.py --tool dsh --offline --format text
157
+ python3 scripts/validate.py --strict
158
+
159
+ ai-toolkit install --local --editors dsh --dry-run
160
+ ai-toolkit dsh install --profile web --dry-run
161
+ ai-toolkit dsh update --profile web --dry-run
162
+ ai-toolkit dsh doctor --profile web
163
+ ai-toolkit dsh uninstall --profile web --dry-run --yes
164
+ ```
165
+
166
+ Phase 3 real-profile qualification completed with a task-specific `DSH_HOME`, exact published package artifacts, and native vendor logins. The pre-tag candidate and exact npm registry package both produced successful child and parent markers through `subagent_claude_code` and `subagent_gemini_copilot`; no provider API key was supplied or handled. The isolated DSH processes stopped cleanly and the unrelated profile fixture remained intact.
167
+
168
+ ## Preview and Upstream Drift
169
+
170
+ DeepSeek Harness describes itself as a developer preview with compatibility-breaking changes. The upstream release feed published `0.1.2-alpha.2` after the reviewed `0.1.1-rc.2` line. ai-toolkit does not adopt that prerelease by inference.
171
+
172
+ Use the registry doctor to detect documentation, capability-marker, and local version changes. A new upstream version requires source review, focused fixture updates, isolated real-profile qualification, and explicit pin changes before support moves.
173
+
174
+ ## Sources
175
+
176
+ - [DeepSeek Harness documentation](https://deepseek-harness.github.io/deepseek-harness/)
177
+ - [DeepSeek Harness releases](https://github.com/deepseek-ai/deepseek-harness/releases)
178
+ - [Reviewed DSH 0.1.1-rc.2 release](https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.1.1-rc.2)
179
+ - [Reviewed DSH package-manager declaration](https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.1-rc.2/package.json)
180
+ - [Reviewed DSH CLI profile and plugin contract](https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.1-rc.2/apps/cli/reference/README.md)
181
+ - [Reviewed DSH skill discovery contract](https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.1-rc.2/docs/subsystems/skills.md)
182
+ - [PATH: kb/reference/manifest-install.md]
183
+ - [PATH: kb/history/completed/dsh-native-install-target-plan.md]