@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.
- package/CHANGELOG.md +105 -0
- package/README.md +40 -15
- package/app/.claude-plugin/plugin.json +1 -1
- package/app/ARCHITECTURE.md +2 -2
- package/app/mcp-templates/README.md +7 -2
- package/app/mcp-templates/rag-mcp-legal.json +11 -0
- package/app/mcp-templates/rag-mcp.json +11 -0
- package/app/surface.json +1 -0
- package/benchmarks/ecosystem-doctor-snapshot.json +29 -17
- package/bin/ai-toolkit.js +8 -0
- package/kb/history/completed/dsh-integration-plan-superseded.md +322 -0
- package/kb/history/completed/dsh-native-install-target-plan.md +331 -0
- package/kb/procedures/ecosystem-sync-sop.md +7 -5
- package/kb/procedures/maintenance-sop.md +1 -1
- package/kb/procedures/release-preparation-sop.md +81 -20
- package/kb/procedures/release-verification-sop.md +35 -5
- package/kb/reference/architecture-overview.md +24 -5
- package/kb/reference/cli-reference.md +1 -1
- package/kb/reference/dsh-compatibility.md +183 -0
- package/kb/reference/manifest-install.md +112 -5
- package/kb/reference/mcp-templates.md +11 -4
- package/kb/reference/plugin-pack-conventions.md +35 -18
- package/kb/reference/supported-tools-registry.md +30 -6
- package/llms-full.txt +1190 -69
- package/llms.txt +3 -0
- package/manifest.json +2 -2
- package/package.json +2 -2
- package/scripts/codex_skill_adapter.py +673 -34
- package/scripts/config_resolver.py +80 -14
- package/scripts/doctor.py +98 -20
- package/scripts/ecosystem_tools.json +51 -1
- package/scripts/generate_codex_skills.py +22 -20
- package/scripts/install.py +30 -13
- package/scripts/install_steps/ai_tools.py +97 -33
- package/scripts/install_steps/dsh.py +5063 -0
- package/scripts/install_steps/install_state.py +1645 -57
- package/scripts/mcp_editors.py +5 -2
- package/scripts/plugin.py +2495 -163
- package/scripts/plugin_mcp.py +279 -0
- package/scripts/plugin_rules.py +389 -0
- package/scripts/plugin_schema.py +139 -23
- package/scripts/uninstall.py +47 -4
- 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.
|
|
6
|
+
version: "1.2.0"
|
|
7
7
|
created: "2026-04-23"
|
|
8
|
-
last_updated: "2026-
|
|
9
|
-
description: "Quarterly
|
|
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
|
|
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:
|
|
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
|
|
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.
|
|
6
|
+
version: "1.15.0"
|
|
7
7
|
created: "2026-04-10"
|
|
8
|
-
last_updated: "2026-
|
|
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,
|
|
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
|
|
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
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
-
#
|
|
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
|
|
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)" = "$
|
|
504
|
-
|| { echo "FAIL: tag is not on
|
|
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
|
|
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 |
|
|
584
|
-
| 18a |
|
|
585
|
-
|
|
|
586
|
-
|
|
|
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.
|
|
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-
|
|
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
|
|
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.
|
|
6
|
+
version: "1.10.0"
|
|
7
7
|
created: "2026-03-23"
|
|
8
|
-
last_updated: "2026-
|
|
9
|
-
description: "Architecture of ai-toolkit:
|
|
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,
|
|
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
|
|
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 (
|
|
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]
|