@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
@@ -2,11 +2,11 @@
2
2
  title: "Manifest-Driven Install System"
3
3
  category: reference
4
4
  service: ai-toolkit
5
- tags: [install, manifest, modules, profiles, auto-detect, state-tracking]
6
- version: "1.0.0"
5
+ tags: [install, manifest, modules, profiles, auto-detect, state-tracking, dsh]
6
+ version: "1.16.0"
7
7
  created: "2026-04-07"
8
- last_updated: "2026-04-07"
9
- description: "Reference for the manifest-driven install system: 17 modules, 4 profiles, auto-detection, and state tracking in ~/.softspark/ai-toolkit/state.json."
8
+ last_updated: "2026-09-01"
9
+ description: "Reference for manifest-driven project installation, explicit DSH profile lifecycle management, and ownership state in ~/.softspark/ai-toolkit/state.json."
10
10
  ---
11
11
 
12
12
  # Manifest-Driven Install System
@@ -39,7 +39,7 @@ Modules are defined in `manifest.json` at the repository root. There are 17 modu
39
39
  | `rules-php` | PHP-specific rules (5 files) | auto-detect |
40
40
  | `rules-cpp` | C++-specific rules (5 files) | auto-detect |
41
41
  | `rules-ruby` | Ruby-specific rules (5 files) | auto-detect |
42
- | `mcp-templates` | 26 MCP server config templates | strict, full |
42
+ | `mcp-templates` | 28 MCP server config templates | strict, full |
43
43
 
44
44
  ## Profiles
45
45
 
@@ -119,6 +119,64 @@ ai-toolkit status
119
119
 
120
120
  Re-applies installed modules, skipping files whose content hash has not changed since last install. Implemented in `scripts/install_steps/install_state.py`.
121
121
 
122
+ ## Explicit DSH Profile Lifecycle
123
+
124
+ The DSH project target and the DSH profile lifecycle are separate operations:
125
+
126
+ ```bash
127
+ # Generic local outputs plus DSH-specific project skills. No DSH profile change.
128
+ ai-toolkit install --local --editors dsh
129
+
130
+ # Read-only project plan, including extends resolution.
131
+ ai-toolkit install --local --editors dsh --dry-run
132
+
133
+ # Explicit global DSH profile mutation. The default profile is web.
134
+ ai-toolkit dsh install --profile web
135
+ ai-toolkit dsh update --profile web
136
+ ai-toolkit dsh doctor --profile web
137
+ ai-toolkit dsh uninstall --profile web --yes
138
+ ```
139
+
140
+ The project command is explicit-only. DSH is excluded from `--editors all`, auto-detection, default profiles, and default editor selection. Its DSH-specific output is `.agents/skills`; the generic `--local` Claude files, detected language rules, and other project outputs still apply. It never writes below `DSH_HOME`.
141
+
142
+ Project `--dry-run` resolves and validates `extends` without persisting `.softspark-toolkit.lock.json`, then plans every generic and DSH-specific project output without changing the project tree. Existing lock bytes and metadata remain unchanged. It also makes no DSH package, profile, state, or authentication change.
143
+
144
+ `DSH_HOME` selects the DSH root. The default is `~/.dsh`. It must resolve to an absolute, non-symlink managed root. Profile identifiers accept 1 to 64 lowercase letters, digits, periods, underscores, or hyphens.
145
+
146
+ The lifecycle supports DSH `0.1.1-rc.2`, stable pnpm `>=11.7.0,<12.0.0`, `@softspark/dsh-codex@1.0.0`, and `@softspark/dsh-orchestrator@1.0.1`. The DSH tag declares `pnpm@11.7.0`, while isolated cold-install qualification used Corepack pnpm `11.24.0`. It invokes the plugin manager with bounded argv-array subprocesses:
147
+
148
+ ```text
149
+ dsh plugin --profile web add @softspark/dsh-codex@1.0.0 --save-exact
150
+ dsh plugin --profile web add @softspark/dsh-orchestrator@1.0.1 --save-exact
151
+ ```
152
+
153
+ The orchestrator preset is copied from the installed package:
154
+
155
+ ```text
156
+ $DSH_HOME/profiles/web/node_modules/@softspark/dsh-orchestrator/agent-presets/softspark-orchestrator
157
+ -> $DSH_HOME/.agent-presets/softspark-orchestrator
158
+ ```
159
+
160
+ The lifecycle refuses unowned same-name plugins and presets. An unchanged owned install is idempotent. Update and uninstall require every recorded package-tree entry and the preset tree to match current bytes, types, paths, links, and POSIX modes. Generic `ai-toolkit uninstall` does not mutate DSH profiles or remove their ownership state. Use `ai-toolkit dsh uninstall` explicitly.
161
+
162
+ The persisted `packages` map is the ownership baseline, not the desired version target. Its key set must contain exactly the two managed package names, each value must be an exact version, and its keys must match the stored package-tree inventories. After a reviewed pin bump, `update` verifies the on-disk manifest and trees against those recorded versions, installs the current reviewed pins, and replaces the state record only after all postconditions pass. `uninstall` verifies and removes the recorded owned package names even when the current reviewed pins are newer. Rollback always restores the exact versions captured before the operation.
163
+
164
+ A zero exit status from DSH is not sufficient to commit a lifecycle operation. Immediately before and after every plugin add or remove, ai-toolkit rereads the profile manifest and the complete managed package trees under the lifecycle lock. A changed, malformed, unexpected, or newly introduced managed entry stops the next external mutation and preserves the concurrent bytes. The managed packages must have the exact recorded pins or be fully absent for uninstall. Dependency entries outside the two managed package names must remain unchanged. A false-success postcondition leaves ownership state uncommitted.
165
+
166
+ Each stored package inventory uses a domain-separated SHA-256 over stable, length-prefixed records. A record contains the entry type, relative path, POSIX mode, and type-specific metadata. Regular-file metadata contains the byte length and per-file SHA-256. Symlink metadata contains the target text. Traversal is bounded to 100,000 entries and 128 levels, never follows symlinks, and rejects special files. The state stores hashes and metadata only. It stores no package contents, credentials, authentication paths, or child-process environment.
167
+
168
+ Rollback gives every package-manager recovery command an explicit target derived from the immutable pre-operation snapshot. The target contains the managed package inventory, the exact target package tree, the unchanged non-target package trees, and the pre-operation unrelated dependencies. A successful child exit is accepted only when all four match. A post-command observation is evidence, never a new target. Target drift or unreadable state blocks every later package-manager recovery call, preserves the current bytes, creates a transaction-unique doctor-visible recovery marker, and prints `ai-toolkit dsh doctor --profile <name>` plus deterministic manual inspection paths. This rule applies to install, update, and uninstall rollback.
169
+
170
+ Before the first mutation, the lifecycle resolves exact DSH and pnpm command paths from the minimal child `PATH`. It records each command path, resolved path, device, inode, type, mode, size, timestamps, and symlink target when applicable. It runs both version probes with a five-second bound and requires pnpm to parse inside the supported range. Missing, nonzero, timed-out, malformed, or unsupported pnpm probes fail before the lifecycle lock and leave no package, preset, state, or lock artifact.
171
+
172
+ Profile lifecycle `--dry-run` performs read-only runtime, package-manager, and ownership preflight. It prints the exact planned argv and paths. It does not acquire a lifecycle or state lock, create a directory, write state, or start a package-manager mutation. Mutating install, update, and uninstall operations first acquire a nonblocking exclusive POSIX `flock` on the pinned `DSH_HOME` directory descriptor, then hold `$DSH_HOME/.ai-toolkit-lifecycle.lock` from preflight through mutation, rollback, cleanup, and recovery. The directory lock is independent of that replaceable filename. It remains held while a recovery sentinel is created with `O_EXCL` and while both its file and parent directory are synced; release occurs only after normal canonical-lock release or durable sentinel publication. Every competing lifecycle must acquire the same directory lock before sentinel scans and canonical claim. Lock acquisition pins the exact lexical `DSH_HOME` parent and root directory descriptors and passes that one resolved home through the full operation. The prerequisite record is revalidated after the lock and before every package mutation or rollback. Replacement, removal, in-place identity drift, and a new earlier PATH shadow fail closed. The verified pnpm command directory leads the child PATH. Every internal mutation and each external DSH command verifies that the lexical path still names the pinned device, inode, and directory kind. Preset parents, staging trees, recovery containers, copied children, and recovery markers are opened by walking from that root descriptor with no-follow operations. Creation, copy, cleanup, and recovery use descriptor-relative system calls and retain the parent and child device and inode identities through postcondition checks. A mismatch blocks state success and later package commands, preserves both roots, and reports recovery. The child process receives only the verified canonical path. The canonical lock is claimed as a regular non-symlink with exclusive descriptor-relative creation and waits for at most one second. A write, `fsync`, close, or interruption during lock initialization removes only the captured lock inode. If that cleanup cannot complete, the command reports a doctor-visible lock recovery artifact and the next lifecycle command remains fail-closed. Release uses the pinned root descriptor, atomically relocates the lock without replacement, and deletes it only after its device and inode still match the transaction. A displaced root never redirects lock cleanup into its replacement. `doctor` is read-only and does not acquire the lifecycle lock.
173
+
174
+ If process-tree termination cannot be confirmed, the lifecycle does not enter package rollback or normal lock release. Before writing recovery metadata it verifies that the canonical lock still names the held device and inode, then creates and syncs a transaction-unique `unconfirmed-process-tree` sentinel in the pinned DSH root. It rewrites the held inode only after a second canonical identity check. A removed or renamed canonical lock therefore leaves the recognized sentinel, while a foreign replacement remains byte-identical. Lock acquisition checks process-tree sentinels before and after claiming the canonical name, and every later install, update, or uninstall fails before DSH invocation. `doctor` prints the recorded process group, original profile path, and every exact gate file. Recovery is deliberately manual: verify that the process group has exited, inspect the preserved profile, and only then remove every named gate. Group signaling is permitted only while the unreaped DSH supervisor still binds the group identifier; after that identity is lost, the command preserves the gate rather than risk signaling a reused PGID. Repeated `SIGINT` is deferred or retried through the bounded TERM, KILL, and wait sequence.
175
+
176
+ Doctor reports runtime compatibility, pnpm availability and version, installed package versions, complete package-tree ownership, preset ownership and hash drift, state consistency, legacy recovery collisions, transaction-unique recovery containers, preserved staging, and whether recovery is required.
177
+
178
+ The lifecycle never runs login commands, reads vendor credential stores, accepts provider API keys, or forwards provider and registry secret environment variables. Codex, Claude Code, and GitHub Copilot own login state. GitHub AI credits apply to Copilot Gemini delegation. Direct Google AI Pro or Ultra, Gemini CLI OAuth, Antigravity, and Gemini API-key routes are unsupported. Prerequisite probes have a five-second bound. DSH plugin mutations and package rollback commands have a separate 300-second bound suitable for cold resolution, without promising registry or network latency. Each mutation uses a dedicated POSIX session and process group on Linux, WSL, or macOS. The calling thread blocks `SIGINT` with `pthread_sigmask` before `Popen`, restores its previous mask inside one catchable region covering communication and final PGID checks, and restores the mask in `finally`. Every `BaseException` after spawn triggers complete process-tree teardown before propagation. Timeout and interruption require confirmed group exit before rollback; an unconfirmed exit blocks rollback. POSIX directory `flock`, process groups, and thread signal masks are mandatory mutation primitives. Native Windows mutation is unsupported and fails before lifecycle writes. Failed child-process stdout and stderr are never included in user-facing errors. Errors expose only the safe command outcome, such as exit status, timeout, or interruption. Recovery argv contains only the validated DSH executable, profile, fixed package names, and exact pinned versions.
179
+
122
180
  ## State Tracking
123
181
 
124
182
  Installed module state is persisted to `~/.softspark/ai-toolkit/state.json`:
@@ -131,14 +189,61 @@ Installed module state is persisted to `~/.softspark/ai-toolkit/state.json`:
131
189
  "last_updated": "2026-04-07T10:00:00Z",
132
190
  "file_hashes": {
133
191
  "app/hooks/session-start.sh": "abc123..."
192
+ },
193
+ "dsh": {
194
+ "profiles": {
195
+ "web": {
196
+ "dsh_home": "/Users/example/.dsh",
197
+ "profile": "web",
198
+ "packages": {
199
+ "@softspark/dsh-codex": "1.0.0",
200
+ "@softspark/dsh-orchestrator": "1.0.1"
201
+ },
202
+ "package_trees": {
203
+ "@softspark/dsh-codex": {
204
+ "digest": "<canonical-tree-sha256>",
205
+ "entries": [
206
+ {"type": "directory", "path": ".", "mode": 493},
207
+ {"type": "file", "path": "package.json", "mode": 420, "size": 53, "sha256": "<file-sha256>"}
208
+ ]
209
+ },
210
+ "@softspark/dsh-orchestrator": {
211
+ "digest": "<canonical-tree-sha256>",
212
+ "entries": [
213
+ {"type": "directory", "path": ".", "mode": 493}
214
+ ]
215
+ }
216
+ },
217
+ "preset_path": "/Users/example/.dsh/.agent-presets/softspark-orchestrator",
218
+ "preset_hash": "<sha256>",
219
+ "owned": true,
220
+ "installed_at": "2026-08-29T08:00:00Z",
221
+ "last_updated": "2026-08-29T08:00:00Z"
222
+ }
223
+ }
134
224
  }
135
225
  }
136
226
  ```
137
227
 
138
228
  - `installed_modules` — used by `update` to know which modules to re-apply
139
229
  - `file_hashes` — used to skip unchanged files during `update`
230
+ - `dsh.profiles` records the DSH home, profile, exact package versions, canonical package-tree inventories, preset path and hash, ownership, and timestamps
140
231
  - The file is written after every successful install or update
141
232
 
233
+ Every shared state writer uses the canonical path from `AI_TOOLKIT_HOME`, `SOFTSPARK_HOME`, or the default `~/.softspark/ai-toolkit/state.json` and cooperates through the same bounded `.state.lock`. Where the host provides descriptor-relative atomic primitives, the lock context pins the state parent device and inode. Transaction reads, snapshots, compare-and-swap merges, private temporary creation, writes, `fsync`, publication, mode changes, cleanup, and lock release then address entries relative to that same open parent descriptor. A DSH lifecycle snapshot also records this parent identity and requires the final install, update, uninstall, and rollback state transaction to reopen that exact lexical path and match the same device and inode. The lexical parent binding is checked before publication and release. Replacing the state directory therefore fails without publishing into the replacement or losing either root. Generic install, MCP, and editor state writers retain the portable state contract on every supported Python platform. They use this pinned atomic publisher when available and otherwise publish a private temporary with the platform's atomic replacement primitive while holding the shared lock.
234
+
235
+ DSH ownership mutation has a stricter platform gate. It requires Linux, WSL, or macOS support for pinned-directory, no-follow, no-replace, and atomic-exchange operations. The lifecycle checks both its DSH filesystem primitives and the state publisher before it creates the state root, state lock, lifecycle lock, temporary, or profile artifact. Secure state lock creation addresses `.state.lock` relative to a pinned no-follow parent descriptor and keeps that descriptor open through release. DSH state publication uses an atomic exchange for an existing file or a no-replace rename for first creation. The writer validates the displaced device, inode, and content digest before cleanup. A mismatched inode is restored or preserved for manual recovery instead of being overwritten or deleted. A bounded retry merges unrelated concurrent state keys. A concurrent change to the same DSH profile is preserved and reported as a recovery conflict.
236
+
237
+ Records created before package-tree inventories were introduced are intentionally not migrated by assumption. `doctor` reports the invalid ownership state. Reinstall the explicit DSH integration after inspecting or removing the old record. Update and uninstall never claim unknown package bytes as owned.
238
+
239
+ DSH mutations snapshot the profile manifest, managed package trees, base-directory existence, prior state, and preset before the first external mutation. Interruption and cleanup failure run the same rollback as package failure. Cleanup uses an entry-level inventory of device, inode, kind, digest, and symlink target. Snapshot recreation walks every ancestor without following symlinks, pins the destination parent, and uses descriptor-relative no-clobber creation for files, directories, and symlinks. File and directory modes are restored with `fchmod` only after pinning the exact inode. Post-creation and post-mode checks bind type, inode, mode, digest, and link target to the pinned parent. Unsupported primitives fail before any write, and an inode or ancestor mismatch remains untouched and doctor-visible. Manifest removal, manifest restoration, and transaction-created profile-directory pruning first relocate the candidate without replacement through pinned parent descriptors, then validate the moved inode and content before cleanup. A mismatch remains at its concurrent path or in a reported recovery container. Cleanup never unlinks, replaces, or removes a concurrently substituted file, symlink, or directory. A transaction-created `.agent-presets` parent is removed only when its identity is unchanged and it remains empty.
240
+
241
+ Update and uninstall revalidate the owned preset identity and content immediately before relocation. The transaction atomically claims a private mode-0700 recovery container with a cryptographically random suffix, then moves the preset to its previously absent `managed-preset` child. It never replaces a caller-provided recovery path. The relocated payload remains bound to the captured device, inode, kind, digest, and symlink target; that same identity is checked immediately and again before every restore or removal. A byte-identical replacement is therefore preserved and reported instead of being treated as transaction-owned. Managed dependency entries must contain exact semantic versions; malformed or non-string values fail before DSH is invoked. A clean-profile rollback removes transaction-created manifest and base directories when they remain unchanged. Existing profile manifests are restored byte-for-byte, and missing pre-existing package entries are recreated without overwriting collisions.
242
+
243
+ If byte-identical rollback cannot finish, the command returns nonzero and prints every exact safely quoted residual path plus deterministic recovery steps. One failed package recovery command does not authorize the next package command: the loop immediately rechecks the rollback-blocked flag and complete package identity after success or failure, records doctor and inspection actions, and stops package mutation on drift. Independent preset cleanup and state restoration still run, so their failures are aggregated without replacing the original error. Every surviving staging or recovery path remains listed and doctor-visible, so no operation reports success while its owned recovery data survives. Update staging cleanup removes only transaction-owned entries and reports every surviving staging path, including concurrent additions. Package-filesystem and cleanup residuals create transaction-unique `.softspark-orchestrator.ai-toolkit-package.<token>` containers. `ai-toolkit dsh doctor --profile <name>` reports `Recovery needed: yes` until manual recovery is complete.
244
+
245
+ Real-profile qualification with the published packages and native subscription logins remains pending Phase 3. Static, fixture, and dry-run success is not evidence that this qualification has completed.
246
+
142
247
  ## Implementation Files
143
248
 
144
249
  | File | Purpose |
@@ -146,6 +251,7 @@ Installed module state is persisted to `~/.softspark/ai-toolkit/state.json`:
146
251
  | `manifest.json` | Module and profile definitions |
147
252
  | `scripts/install_steps/detect_language.py` | Auto-detect project language from marker files |
148
253
  | `scripts/install_steps/install_state.py` | Read/write `~/.softspark/ai-toolkit/state.json` |
254
+ | `scripts/install_steps/dsh.py` | Explicit DSH install, update, doctor, uninstall, and recovery lifecycle |
149
255
 
150
256
  ## Backward Compatibility
151
257
 
@@ -163,3 +269,4 @@ No existing install scripts or CI configurations need changes.
163
269
  - [PATH: kb/reference/language-rules.md] — language rules structure and auto-detection detail
164
270
  - [PATH: kb/reference/mcp-templates.md] — MCP server templates (the `mcp-templates` module)
165
271
  - [PATH: kb/reference/architecture-overview.md] — overall install model
272
+ - [PATH: kb/reference/dsh-compatibility.md] - DSH commands, topology, authentication, and preview limits
@@ -3,17 +3,17 @@ title: "MCP Server Templates"
3
3
  category: reference
4
4
  service: ai-toolkit
5
5
  tags: [mcp, templates, servers, configuration, editors, inject-mcp, external-templates]
6
- version: "1.5.0"
6
+ version: "1.6.0"
7
7
  created: "2026-04-07"
8
- last_updated: "2026-08-21"
9
- description: "Reference for 26 built-in MCP server templates, external template injection via inject-mcp, and native editor MCP installation support."
8
+ last_updated: "2026-08-31"
9
+ description: "Reference for 28 built-in MCP server templates, external template injection via inject-mcp, and native editor MCP installation support."
10
10
  ---
11
11
 
12
12
  # MCP Server Templates
13
13
 
14
14
  ## Overview
15
15
 
16
- ai-toolkit ships 26 ready-to-use MCP server configuration templates in `app/mcp-templates/`. Each template is a JSON file that defines the canonical `mcpServers` block for a specific service. Templates can be merged into the project's `.mcp.json` and rendered into editor-native MCP config files via the `ai-toolkit mcp` CLI subcommand.
16
+ ai-toolkit ships 28 ready-to-use MCP server configuration templates in `app/mcp-templates/`. Each template is a JSON file that defines the canonical `mcpServers` block for a specific service. Templates can be merged into the project's `.mcp.json` and rendered into editor-native MCP config files via the `ai-toolkit mcp` CLI subcommand.
17
17
 
18
18
  **External templates:** Tools outside the toolkit (MCP servers, plugins, custom integrations) can register their own MCP templates via `ai-toolkit inject-mcp <file|url>` -- the toolkit caches the template, tags every server with a `_source` field, and propagates the config to every editor that exposes a `global_path`. URL-sourced templates are auto-refreshed on every `ai-toolkit update`. See [PATH: kb/reference/extension-api.md] for the inject-mcp / remove-mcp reference.
19
19
 
@@ -79,6 +79,7 @@ loads `.codex/config.toml` only for trusted project layers.
79
79
  | `filesystem` | Local filesystem access for reading, writing, and searching files | — |
80
80
  | `git` | Git repository inspection: diffs, logs, branches | — |
81
81
  | `github` | GitHub API: issues, PRs, repos, code search | `GITHUB_PERSONAL_ACCESS_TOKEN` |
82
+ | `jira` | Jira multi-instance routing, ADF, caching, and comment templates | — |
82
83
  | `google-drive` | Google Drive file search, reading, and management | `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`, `GOOGLE_REDIRECT_URI` |
83
84
  | `google-maps` | Google Maps geocoding, directions, place search | `GOOGLE_MAPS_API_KEY` |
84
85
  | `grafana` | Grafana dashboard queries, alerting, and data source management | `GRAFANA_URL`, `GRAFANA_API_KEY` |
@@ -87,6 +88,8 @@ loads `.codex/config.toml` only for trusted project layers.
87
88
  | `notion` | Notion workspace: pages, databases, content management | `NOTION_API_KEY` |
88
89
  | `postgres` | PostgreSQL database access, schema inspection, analysis | — |
89
90
  | `puppeteer` | Browser automation: screenshots, navigation, web scraping | — |
91
+ | `rag-mcp` | General knowledge-base RAG over HTTP MCP (localhost port 8081 by default) | — |
92
+ | `rag-mcp-legal` | Polish legal RAG over HTTP MCP (localhost port 8082 by default) | — |
90
93
  | `redis` | Redis cache inspection, data management, and monitoring | `REDIS_URL` |
91
94
  | `sentry` | Sentry error tracking: issue search, event details, alerting | `SENTRY_AUTH_TOKEN`, `SENTRY_ORG` |
92
95
  | `sequential-thinking` | Step-by-step reasoning and problem decomposition | — |
@@ -120,6 +123,10 @@ Each template is a JSON file with the following structure:
120
123
  - `mcpServers` — the block merged verbatim into `.mcp.json`
121
124
  - `env` values use `${VAR_NAME}` placeholders that must be set in the shell environment or `.env` file before Claude Code starts
122
125
 
126
+ `rag-mcp` and `rag-mcp-legal` expose unauthenticated HTTP MCP endpoints by
127
+ design. Keep the default localhost binding, use a VPN, or protect remote access
128
+ with a restricted reverse proxy.
129
+
123
130
  ## Example: Adding GitHub and PostgreSQL
124
131
 
125
132
  ```bash
@@ -3,17 +3,17 @@ title: "Plugin Pack Conventions"
3
3
  category: reference
4
4
  service: ai-toolkit
5
5
  tags: [plugins, plugin-packs, conventions, manifests, hooks, policy-packs]
6
- version: "1.2.0"
6
+ version: "1.3.0"
7
7
  created: "2026-03-28"
8
- last_updated: "2026-08-18"
9
- description: "Conventions for experimental ai-toolkit plugin packs, policy packs, hook packs, and plugin-creator scaffolding across Claude Code and Codex runtimes."
8
+ last_updated: "2026-08-31"
9
+ description: "Conventions for experimental ai-toolkit plugin packs, policy packs, hook packs, and plugin-creator scaffolding across supported editors."
10
10
  ---
11
11
 
12
12
  # Plugin Pack Conventions
13
13
 
14
14
  ## Purpose
15
15
 
16
- `ai-toolkit` includes experimental plugin packs under `app/plugins/` for Claude Code and optional global Codex layering, and discovers external packs under `~/.softspark/ai-toolkit/plugins/` (see *Where Packs Live*). These internal pack manifests are distinct from the official uploadable Claude app plugin built by `ai-toolkit claude-app export`.
16
+ `ai-toolkit` includes experimental plugin packs under `app/plugins/` for Claude Code, Codex, Cursor, and Gemini global layering, and discovers external packs under `~/.softspark/ai-toolkit/plugins/` (see *Where Packs Live*). These internal pack manifests are distinct from the official uploadable Claude app plugin built by `ai-toolkit claude-app export`.
17
17
 
18
18
  ## Where Packs Live
19
19
 
@@ -69,6 +69,7 @@ app/plugins/<pack-name>/
69
69
  ├── plugin.json
70
70
  ├── README.md
71
71
  ├── hooks/ # optional, executable if present
72
+ ├── mcp/ # optional, pack-local MCP templates
72
73
  ├── rules/ # optional
73
74
  ├── skills/ # optional
74
75
  ├── agents/ # optional
@@ -92,6 +93,14 @@ Required keys:
92
93
  - `skills`
93
94
  - `rules`
94
95
  - `hooks`
96
+ - `mcp` (optional MCP template names)
97
+
98
+ An MCP reference such as `"rag-mcp-legal"` resolves first to the pack-owned
99
+ `mcp/rag-mcp-legal.json`, then to the built-in
100
+ `app/mcp-templates/rag-mcp-legal.json`. Each template must use the same `name`
101
+ as the reference and provide a non-empty `mcpServers` object. A localhost HTTP
102
+ template must also include a `postInstall` warning that the endpoint is
103
+ `unauthenticated`.
95
104
 
96
105
  ## Naming Rules
97
106
 
@@ -111,10 +120,12 @@ Required keys:
111
120
  ## CLI Management
112
121
 
113
122
  ```bash
114
- ai-toolkit plugin list # show all 12 packs with install status
123
+ ai-toolkit plugin list # show all available packs with install status
115
124
  ai-toolkit plugin install --editor claude <name> # Claude Code global target
116
125
  ai-toolkit plugin install --editor codex <name> # Codex global target
117
- ai-toolkit plugin install --editor all --all # install all 12 packs for both runtimes
126
+ ai-toolkit plugin install --editor cursor <name> # Cursor global target
127
+ ai-toolkit plugin install --editor gemini <name> # Gemini CLI global target
128
+ ai-toolkit plugin install --editor all --all # install all available packs for all supported editors
118
129
  ai-toolkit plugin update --editor all --all # update all installed packs
119
130
  ai-toolkit plugin clean <name> # prune data older than 90 days (default)
120
131
  ai-toolkit plugin clean <name> --days 30 # prune data older than 30 days
@@ -125,21 +136,25 @@ ai-toolkit plugin status --editor all # show installed packs with r
125
136
 
126
137
  ### What `plugin install` Does
127
138
 
128
- 1. **Parses** `--editor claude|codex|all` (default: `claude`)
139
+ 1. **Parses** `--editor claude|codex|cursor|gemini|all` (default: `claude`)
129
140
  2. **Copies** plugin-specific hooks to runtime-owned storage: Claude uses `~/.softspark/ai-toolkit/hooks/plugin-<pack>-<hook>.sh`; Codex uses `$CODEX_HOME/ai-toolkit-hooks/plugin-<pack>-<hook>.sh`
130
141
  3. **Copies** shared plugin scripts to `~/.softspark/ai-toolkit/plugin-scripts/<pack>/`
131
142
  4. **Runs** init scripts if present (e.g. `init_db.py` for memory-pack — safe to re-run, preserves data)
132
143
  5. **Claude Code target**: links missing agents/skills into `~/.claude/`, injects plugin-local rules into `~/.claude/CLAUDE.md`, and merges plugin hook entries into `~/.claude/settings.json`
133
144
  6. **Codex target**: bootstraps `$CODEX_HOME/AGENTS.md`, `$HOME/.agents/skills`, `$CODEX_HOME/hooks.json`, and self-contained `$CODEX_HOME/ai-toolkit-hooks`, then layers plugin-specific rules and hooks on top; it does not write `~/AGENTS.md` or `.agents/rules/`
134
- 7. **Records** installed state per runtime in `~/.softspark/ai-toolkit/plugins.json`
145
+ 7. **Cursor target**: writes each pack-owned rule as `~/.cursor/rules/plugin-<pack>-<rule>.mdc` with `alwaysApply: true`; files are exact-hash owned and collisions are rejected
146
+ 8. **Gemini target**: marker-injects each pack-owned rule into `~/.gemini/GEMINI.md` as `plugin-<pack>-<rule>`, preserving all unrelated content
147
+ 9. **Records** installed state per runtime in `~/.softspark/ai-toolkit/plugins.json`
148
+ 10. **MCP assets**: installs `includes.mcp` into the selected editor's global MCP config, rejects unowned same-name entries, and records the exact normalized server configuration under the plugin's ownership state
135
149
 
136
150
  ### What `plugin update` Does
137
151
 
138
- 1. **Removes** existing plugin runtime entries for the selected editor(s) (same as `remove`)
139
- 2. **Reinstalls** from the current source (same as `install`)
140
- 3. **Preserves plugin data** (e.g. memory-pack SQLite database is never deleted)
141
- 4. Shared plugin scripts/hooks are kept if another runtime still has the same pack installed
142
- 5. `--all` updates only currently installed packs for the selected runtime(s)
152
+ 1. **Preflights** MCP and native-rule collisions before changing any plugin state, skill, rule, hook, or script
153
+ 2. **Removes** existing plugin runtime entries for the selected editor(s) (same as `remove`)
154
+ 3. **Reinstalls** from the current source (same as `install`)
155
+ 4. **Preserves plugin data** (e.g. memory-pack SQLite database is never deleted)
156
+ 5. Shared plugin scripts/hooks are kept if another runtime still has the same pack installed
157
+ 6. `--all` updates only currently installed packs for the selected runtime(s)
143
158
 
144
159
  ### What `plugin clean` Does
145
160
 
@@ -151,10 +166,12 @@ ai-toolkit plugin status --editor all # show installed packs with r
151
166
 
152
167
  1. **Claude Code target**: strips plugin hook entries from `~/.claude/settings.json` and removes plugin-local rule sections from `~/.claude/CLAUDE.md`
153
168
  2. **Codex target**: strips only command handlers carrying the exact `AI_TOOLKIT_HOOK_OWNER=ai-toolkit-plugin-<pack>` marker from `$CODEX_HOME/hooks.json`, removes owned `$CODEX_HOME/ai-toolkit-hooks/plugin-<pack>-*` assets, and removes the pack's marker-bounded sections from `$CODEX_HOME/AGENTS.md`
154
- 3. **Claude/shared assets** (`~/.softspark/ai-toolkit/hooks/plugin-*`, `plugin-scripts/<pack>/`) are removed only when no remaining runtime still uses that pack
155
- 4. **Updates** `plugins.json` state per runtime
156
- 5. **Leaves** core agents/skills untouched (they belong to the base install)
157
- 6. **Leaves** plugin data intact (e.g. `memory.db` use `clean` to prune)
169
+ 3. **Cursor/Gemini rules**: removes only exact content recorded in `rule_ownership`; foreign or user-modified files/sections are preserved with a warning
170
+ 4. **Claude/shared assets** (`~/.softspark/ai-toolkit/hooks/plugin-*`, `plugin-scripts/<pack>/`) are removed only when no remaining runtime still uses that pack
171
+ 5. **Updates** `plugins.json` state per runtime
172
+ 6. **Leaves** core agents/skills untouched (they belong to the base install)
173
+ 7. **Leaves** plugin data intact (e.g. `memory.db` — use `clean` to prune)
174
+ 8. **MCP cleanup**: removes only unchanged servers recorded as owned by that plugin; user-created, foreign, or manually changed entries are preserved with a warning
158
175
 
159
176
  ### Data Retention (memory-pack)
160
177
 
@@ -178,7 +195,7 @@ time.
178
195
  links every core skill and agent, so a manifest naming only core assets resolves
179
196
  to nothing: `plugin install` reports `(0 file items)` and no file appears on
180
197
  disk. This is not a subtle degradation — it is a complete no-op, identical on
181
- every profile (`minimal`, `standard`, `strict`) and on both runtimes.
198
+ every profile (`minimal`, `standard`, `strict`) and on every supported editor.
182
199
 
183
200
  Nine packs were removed in v4.20.0 for failing this: `csharp`, `java`, `kotlin`,
184
201
  `ruby`, `rust`, `swift`, `frontend`, `research`, `security`. Every one declared
@@ -3,19 +3,19 @@ title: "Supported Tools Registry"
3
3
  category: reference
4
4
  service: ai-toolkit
5
5
  tags: [editors, platforms, generators, integration, ecosystem]
6
- version: "1.13.0"
6
+ version: "1.15.0"
7
7
  created: "2026-04-23"
8
- last_updated: "2026-08-19"
9
- description: "Human-readable view of scripts/ecosystem_tools.json — the canonical list of tools ai-toolkit integrates with (Claude Code, Claude Chat/Cowork, and 11 editors), their documentation URLs, config paths, our generators, and tracked capability markers."
8
+ last_updated: "2026-09-01"
9
+ description: "Human-readable view of scripts/ecosystem_tools.json: Claude Code, Claude Chat/Cowork, 11 editors, and the explicit developer-preview DSH target."
10
10
  ---
11
11
 
12
12
  # Supported Tools Registry
13
13
 
14
- The canonical data lives in **`scripts/ecosystem_tools.json`** and is consumed by `scripts/ecosystem_doctor.py`. This document is a derived view when the JSON changes, update this table too.
14
+ The canonical data lives in **`scripts/ecosystem_tools.json`** and is consumed by `scripts/ecosystem_doctor.py`. This document is a derived view. Update it whenever the JSON changes.
15
15
 
16
- ## Tool Count: 13
16
+ ## Tool Count: 14
17
17
 
18
- 1 primary runtime (Claude Code) + 1 Claude app target + 11 editor integrations.
18
+ 1 primary runtime, 1 Claude app target, 11 editor integrations, and 1 explicit developer-preview harness target.
19
19
 
20
20
  ---
21
21
 
@@ -58,6 +58,30 @@ The canonical data lives in **`scripts/ecosystem_tools.json`** and is consumed b
58
58
 
59
59
  ---
60
60
 
61
+ ## Explicit Developer-Preview Harness
62
+
63
+ ### DeepSeek Harness
64
+
65
+ | Field | Value |
66
+ |-------|-------|
67
+ | ID | `dsh` |
68
+ | Status | `developer-preview`, `explicit-only`. This is a SoftSpark-maintained community compatibility target. DeepSeek AI has not endorsed it. |
69
+ | Reviewed version | DSH `0.1.1-rc.2`, `@softspark/dsh-codex@1.0.0`, and `@softspark/dsh-orchestrator@1.0.1`. |
70
+ | Docs | https://deepseek-harness.github.io/deepseek-harness/ |
71
+ | Release sources | https://github.com/deepseek-ai/deepseek-harness/releases and the reviewed [DSH 0.1.1-rc.2 release](https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.1.1-rc.2) |
72
+ | Reviewed contracts | Tagged [CLI profile and plugin reference](https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.1-rc.2/apps/cli/reference/README.md) and [skill discovery reference](https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.1-rc.2/docs/subsystems/skills.md) |
73
+ | Config paths | Project `.agents/skills/*/SKILL.md`; profile `$DSH_HOME/profiles/<profile>/package.json`; installed packages under `$DSH_HOME/profiles/<profile>/node_modules/@softspark/`; preset `$DSH_HOME/.agent-presets/softspark-orchestrator` |
74
+ | Project generator | `scripts/generate_codex_skills.py` emits the shared Codex and DSH `.agents/skills` catalog. `ai-toolkit install --local --editors dsh` makes no `$DSH_HOME` write. |
75
+ | Profile lifecycle | `scripts/install_steps/dsh.py` implements explicit `install`, `update`, `doctor`, and `uninstall` for one named profile. |
76
+ | Selection boundary | Excluded from `--editors all`, auto-detection, defaults, default profiles, and global editor selection. |
77
+ | Authentication | ai-toolkit accepts no provider API key and performs no login. Codex, Claude Code, and GitHub Copilot own authentication. Copilot Gemini usage consumes GitHub AI credits. |
78
+ | State and recovery | State uses `AI_TOOLKIT_HOME`, then `SOFTSPARK_HOME`, then `~/.softspark/ai-toolkit/state.json`. Locks and compare-and-swap publication protect ownership. Doctor reports preserved recovery markers and drift. |
79
+ | Upstream drift | Upstream has newer prereleases, including `0.1.2-alpha.2`. They remain unqualified until source review and isolated real-profile verification complete. Phase 3 real-profile evidence is pending. |
80
+
81
+ See [DSH Compatibility](./dsh-compatibility.md) for commands, topology, subscription boundaries, lifecycle ownership, and limitations.
82
+
83
+ ---
84
+
61
85
  ## Editor Integrations
62
86
 
63
87
  ### Cursor