@softspark/ai-toolkit 2.5.0 → 2.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +44 -0
- package/README.md +8 -9
- package/app/.claude-plugin/plugin.json +3 -2
- package/app/ARCHITECTURE.md +11 -0
- package/app/skills/hipaa-validate/SKILL.md +39 -23
- package/app/skills/hipaa-validate/scripts/hipaa_scan.py +64 -7
- package/bin/ai-toolkit.js +20 -5
- package/kb/procedures/release-preparation-sop.md +6 -3
- package/kb/reference/opencode-compatibility.md +161 -0
- package/llms-full.txt +174 -4
- package/llms.txt +1 -0
- package/manifest.json +1 -1
- package/package.json +6 -3
- package/scripts/eject.py +5 -1
- package/scripts/generate_opencode.py +117 -0
- package/scripts/generate_opencode_agents.py +126 -0
- package/scripts/generate_opencode_commands.py +158 -0
- package/scripts/generate_opencode_json.py +133 -0
- package/scripts/generate_opencode_plugin.py +169 -0
- package/scripts/install_steps/ai_tools.py +117 -1
- package/scripts/install_steps/install_state.py +1 -1
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "AI Toolkit - opencode Compatibility"
|
|
3
|
+
category: reference
|
|
4
|
+
service: ai-toolkit
|
|
5
|
+
tags: [opencode, compatibility, install, skills, hooks, mcp, plugins]
|
|
6
|
+
version: "1.0.0"
|
|
7
|
+
created: "2026-04-16"
|
|
8
|
+
last_updated: "2026-04-16"
|
|
9
|
+
description: "Reference for how ai-toolkit integrates with opencode — AGENTS.md, subagents, slash commands, JS plugin hook bridge, and MCP merge into opencode.json."
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# AI Toolkit - opencode Compatibility
|
|
13
|
+
|
|
14
|
+
## Summary
|
|
15
|
+
|
|
16
|
+
opencode (https://opencode.ai) is the 11th supported editor. `ai-toolkit install --editors opencode` (or `--editors all`) lays down a full native integration: shared `AGENTS.md`, per-agent `.opencode/agents/` files, per-command `.opencode/commands/` files, a JS plugin bridging toolkit Bash hooks to opencode lifecycle events, and MCP server merge into `opencode.json`.
|
|
17
|
+
|
|
18
|
+
opencode also reads `CLAUDE.md` as a fallback, so a user without the native integration still gets baseline rules. The native path adds subagents, slash commands, hooks, and MCP.
|
|
19
|
+
|
|
20
|
+
## Local Install Outputs
|
|
21
|
+
|
|
22
|
+
`ai-toolkit install --local --editors opencode` generates:
|
|
23
|
+
|
|
24
|
+
- `AGENTS.md` (shared with Codex CLI via distinct marker sections)
|
|
25
|
+
- `.opencode/agents/ai-toolkit-*.md` (one per ai-toolkit agent, `mode: subagent`)
|
|
26
|
+
- `.opencode/commands/ai-toolkit-*.md` (one per user-invocable skill, required `template: |` frontmatter field)
|
|
27
|
+
- `.opencode/plugins/ai-toolkit-hooks.js` (JS plugin bridging Bash hooks)
|
|
28
|
+
- `opencode.json` (MCP key merged from `.mcp.json`, user keys preserved)
|
|
29
|
+
|
|
30
|
+
## Global Install Outputs
|
|
31
|
+
|
|
32
|
+
`ai-toolkit install --editors opencode` (no `--local`) lays down:
|
|
33
|
+
|
|
34
|
+
- `~/.config/opencode/AGENTS.md`
|
|
35
|
+
- `~/.config/opencode/agents/ai-toolkit-*.md`
|
|
36
|
+
- `~/.config/opencode/commands/ai-toolkit-*.md`
|
|
37
|
+
- `~/.config/opencode/plugins/ai-toolkit-hooks.js`
|
|
38
|
+
- `~/.config/opencode/opencode.json` (MCP merge, user keys preserved)
|
|
39
|
+
|
|
40
|
+
Files land directly under `~/.config/opencode/` (no `.opencode/` nesting) because that is the global layout opencode expects per https://opencode.ai/docs/config/. Shared hook scripts stay in `~/.softspark/ai-toolkit/hooks/` and are referenced by the global JS plugin.
|
|
41
|
+
|
|
42
|
+
## Editor Surface Comparison
|
|
43
|
+
|
|
44
|
+
| Feature | Claude Code | Codex CLI | opencode |
|
|
45
|
+
|--------------------|-------------|-----------------|-------------------------------------------|
|
|
46
|
+
| Rules file | `CLAUDE.md` | `AGENTS.md` | `AGENTS.md` + `CLAUDE.md` fallback |
|
|
47
|
+
| Subagents | Yes | No | Yes (`mode: subagent`) |
|
|
48
|
+
| Slash commands | Skills | Adapted skills | Native commands with frontmatter |
|
|
49
|
+
| MCP | Yes | Yes | Yes (`opencode.json`) |
|
|
50
|
+
| Lifecycle hooks | JSON config | `.codex/hooks` | JS/TS plugins (~30+ events) |
|
|
51
|
+
| Global config dir | `~/.claude` | `~/.codex` | `~/.config/opencode` |
|
|
52
|
+
| Project config dir | `.claude` | `.agents` | `.opencode` |
|
|
53
|
+
|
|
54
|
+
## Shared AGENTS.md
|
|
55
|
+
|
|
56
|
+
opencode and Codex CLI both read `AGENTS.md`. The toolkit emits two distinct marker-bounded sections in a single file, so installing both editors does not clobber either. The Codex section is produced by `generate_codex.py`; the opencode section is produced by `generate_opencode.py`. Both sections reuse `codex_skill_adapter.py` because both editors lack Claude-only orchestration primitives (`Agent`, `TeamCreate`, `TaskCreate`).
|
|
57
|
+
|
|
58
|
+
## Subagent Translation Model
|
|
59
|
+
|
|
60
|
+
Each file in `app/agents/*.md` emits a corresponding `.opencode/agents/ai-toolkit-<name>.md` with:
|
|
61
|
+
|
|
62
|
+
- `description` — copied from the source agent frontmatter
|
|
63
|
+
- `mode: subagent` (required)
|
|
64
|
+
- `color` — copied when present
|
|
65
|
+
|
|
66
|
+
The `model` field is deliberately omitted. opencode requires the `provider/model-id` form; ai-toolkit only stores a short alias (`opus`/`sonnet`/`haiku`) which cannot be mapped without assuming a provider. opencode falls back to the user's `default_agent` / top-level `model` config.
|
|
67
|
+
|
|
68
|
+
Opencode treats these files as auto-completable with `@` and can delegate to them from the primary agent.
|
|
69
|
+
|
|
70
|
+
## Slash Command Translation Model
|
|
71
|
+
|
|
72
|
+
Only user-invocable skills (`user-invocable: true` or no `disable-model-invocation`) emit to `.opencode/commands/`. Knowledge skills (`user-invocable: false`) are intentionally skipped — they are not intended as commands.
|
|
73
|
+
|
|
74
|
+
Each command file carries opencode's required `template: |` frontmatter field, built from the SKILL.md body.
|
|
75
|
+
|
|
76
|
+
## Hook Bridge (JS Plugin)
|
|
77
|
+
|
|
78
|
+
`.opencode/plugins/ai-toolkit-hooks.js` is a single-file plugin that maps opencode events to the shared Bash hooks in `~/.softspark/ai-toolkit/hooks/`:
|
|
79
|
+
|
|
80
|
+
| opencode event | Bash hook(s) |
|
|
81
|
+
|----------------------------|--------------------------------------------------------------------|
|
|
82
|
+
| `session.created` | `session-start.sh` + `session-context.sh` + `mcp-health.sh` |
|
|
83
|
+
| `session.compacted` | `pre-compact.sh` + `pre-compact-save.sh` (PreCompact equivalent) |
|
|
84
|
+
| `session.deleted` | `session-end.sh` + `save-session.sh` |
|
|
85
|
+
| `message.updated` | `user-prompt-submit.sh` + `track-usage.sh` |
|
|
86
|
+
| `message.part.updated` | `user-prompt-submit.sh` + `track-usage.sh` |
|
|
87
|
+
| `tool.execute.before` (bash) | `guard-destructive.sh` + `commit-quality.sh` |
|
|
88
|
+
| `tool.execute.after` | `post-tool-use.sh` |
|
|
89
|
+
| `permission.asked` | `guard-destructive.sh` (approval-gate bridge) |
|
|
90
|
+
| `command.executed` | `post-tool-use.sh` |
|
|
91
|
+
|
|
92
|
+
Plugin exports a single named export `AiToolkitHooks` — per opencode docs, named exports only (no default export). Hook scripts are invoked via Bun's `$` with the script path bound as a JS constant; opencode event payloads are passed as JSON on stdin, never interpolated into the shell command, so payload data cannot inject shell metacharacters. The toolkit's `exit 2` semantics for PreToolUse guards are preserved and bubble up as the plugin's return code.
|
|
93
|
+
|
|
94
|
+
**Intentionally unmapped events**: `tui.*`, `lsp.*`, `installation.*`, `session.idle/status/updated/error/diff`, `file.edited`, `file.watcher.updated`, `todo.updated`, `shell.env`, `server.connected`, `message.*.removed`, `experimental.*` — no matching Bash hook in the toolkit, or the event is opencode-UI-only.
|
|
95
|
+
|
|
96
|
+
## MCP Merge (opencode.json)
|
|
97
|
+
|
|
98
|
+
`generate_opencode_json.py` reads `.mcp.json` and merges its servers under the `mcp` key in `opencode.json`:
|
|
99
|
+
|
|
100
|
+
- `local` shape entries are translated to opencode's local command shape.
|
|
101
|
+
- `remote` shape entries are translated to opencode's remote URL shape.
|
|
102
|
+
- User-authored keys in `opencode.json` (outside `mcp`) are preserved.
|
|
103
|
+
- Re-running the generator is idempotent.
|
|
104
|
+
|
|
105
|
+
## Auto-Detection
|
|
106
|
+
|
|
107
|
+
The installer detects opencode as configured when any of these markers exist:
|
|
108
|
+
|
|
109
|
+
- `opencode.json`
|
|
110
|
+
- `.opencode/` directory
|
|
111
|
+
- `.opencode/agents/`
|
|
112
|
+
- `.opencode/commands/`
|
|
113
|
+
- `~/.config/opencode/`
|
|
114
|
+
|
|
115
|
+
`ai-toolkit update` picks up opencode automatically when detection fires.
|
|
116
|
+
|
|
117
|
+
## Uninstall & Reset
|
|
118
|
+
|
|
119
|
+
`scripts/install_steps/ai_tools.py` cleanup only removes ai-toolkit-marked artifacts:
|
|
120
|
+
|
|
121
|
+
- Generated `.opencode/agents/ai-toolkit-*.md`
|
|
122
|
+
- Generated `.opencode/commands/ai-toolkit-*.md`
|
|
123
|
+
- Generated `.opencode/plugins/ai-toolkit-hooks.js`
|
|
124
|
+
- Managed markers from `AGENTS.md`
|
|
125
|
+
- `mcp` key entries injected by the toolkit (user keys preserved)
|
|
126
|
+
|
|
127
|
+
User-authored opencode files and user-authored `opencode.json` keys are never deleted.
|
|
128
|
+
|
|
129
|
+
## Behavioral Limits
|
|
130
|
+
|
|
131
|
+
- opencode does not expose the full Claude hook event surface; only the events in the mapping table above are bridged. Claude-only events (`TaskCompleted`, `TeammateIdle`, `SubagentStart`, `SubagentStop`, `PreCompact`) are silently skipped.
|
|
132
|
+
- Multi-agent orchestration skills (`/orchestrate`, `/workflow`, `/swarm`, `/teams`, `/subagent-development`) run through the Codex adaptation layer — they use opencode subagents and explicit file ownership instead of Claude's `Agent`/`TaskCreate` primitives.
|
|
133
|
+
|
|
134
|
+
## Verification
|
|
135
|
+
|
|
136
|
+
The opencode integration is verified by:
|
|
137
|
+
|
|
138
|
+
1. Generator contract tests for the five `generate_opencode*.py` scripts (bats)
|
|
139
|
+
2. MCP merge idempotency and user-key preservation tests
|
|
140
|
+
3. Plugin export shape and event coverage tests
|
|
141
|
+
4. Auto-detection tests for install / update flow
|
|
142
|
+
5. `validate.py --strict` + `audit_skills.py --ci` in CI
|
|
143
|
+
|
|
144
|
+
## CLI Commands
|
|
145
|
+
|
|
146
|
+
| Command | Description |
|
|
147
|
+
|---------|-------------|
|
|
148
|
+
| `ai-toolkit opencode-md` | Generate `AGENTS.md` body for opencode |
|
|
149
|
+
| `ai-toolkit opencode-agents` | Generate `.opencode/agents/ai-toolkit-*.md` |
|
|
150
|
+
| `ai-toolkit opencode-commands` | Generate `.opencode/commands/ai-toolkit-*.md` |
|
|
151
|
+
| `ai-toolkit opencode-plugin` | Generate `.opencode/plugins/ai-toolkit-hooks.js` |
|
|
152
|
+
| `ai-toolkit opencode-json` | Merge MCP servers into `opencode.json` |
|
|
153
|
+
|
|
154
|
+
## Related
|
|
155
|
+
|
|
156
|
+
- `kb/reference/skills-catalog.md`
|
|
157
|
+
- `kb/reference/agents-catalog.md`
|
|
158
|
+
- `kb/reference/codex-cli-compatibility.md`
|
|
159
|
+
- `kb/reference/architecture-overview.md`
|
|
160
|
+
- `kb/reference/global-install-model.md`
|
|
161
|
+
- `kb/reference/mcp-editor-compatibility.md`
|
package/llms-full.txt
CHANGED
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
- [MCP Editor Compatibility](kb/reference/mcp-editor-compatibility.md)
|
|
45
45
|
- [MCP Server Templates](kb/reference/mcp-templates.md)
|
|
46
46
|
- [Merge-Friendly Install Model](kb/reference/merge-friendly-install-model.md)
|
|
47
|
+
- [AI Toolkit - opencode Compatibility](kb/reference/opencode-compatibility.md)
|
|
47
48
|
- [Plugin Pack Conventions](kb/reference/plugin-pack-conventions.md)
|
|
48
49
|
- [Quick Wins Implementation Summary](kb/reference/quick-wins-implementation-summary.md)
|
|
49
50
|
- [Skill Templates](kb/reference/skill-templates.md)
|
|
@@ -3517,9 +3518,9 @@ title: "SOP: Release Preparation"
|
|
|
3517
3518
|
category: procedures
|
|
3518
3519
|
service: ai-toolkit
|
|
3519
3520
|
tags: [sop, release, version, publish, changelog, semver]
|
|
3520
|
-
version: "1.
|
|
3521
|
+
version: "1.6.0"
|
|
3521
3522
|
created: "2026-04-10"
|
|
3522
|
-
last_updated: "2026-04-
|
|
3523
|
+
last_updated: "2026-04-17"
|
|
3523
3524
|
description: "Step-by-step checklist for preparing a new ai-toolkit release — version sync, changelog, artifact regeneration, validation, and tagging. Run BEFORE every git tag."
|
|
3524
3525
|
---
|
|
3525
3526
|
|
|
@@ -3677,12 +3678,15 @@ Add entry at the top of `CHANGELOG.md` (after the header, before previous releas
|
|
|
3677
3678
|
|
|
3678
3679
|
1. Change the heading version: `## What's New in vX.Y.Z`
|
|
3679
3680
|
2. Replace bullet points with 3-5 highlights from this release
|
|
3680
|
-
3. Keep the `
|
|
3681
|
+
3. **Keep only the latest version block.** Delete the previous `## What's New in vA.B.C` section(s). README is the shop window, not the archive — users see the current release, full history lives in `CHANGELOG.md`.
|
|
3682
|
+
4. Keep the `See [CHANGELOG.md](CHANGELOG.md) for full history.` link directly below the bullet list.
|
|
3681
3683
|
|
|
3682
3684
|
> **Warning:** This section is the first thing users see after the badges.
|
|
3683
3685
|
> A stale version here (e.g., "What's New in v2.1.3" when shipping v2.3.0)
|
|
3684
3686
|
> signals an unmaintained project. Do NOT skip this step.
|
|
3685
3687
|
|
|
3688
|
+
> **Single-version rule:** README.md must contain **exactly one** `## What's New in vX.Y.Z` heading at any time. If you find multiple stacked (e.g. v2.6.1 + v2.6.0 + v2.5.0), that is a SOP drift — collapse to the latest on the next release commit.
|
|
3689
|
+
|
|
3686
3690
|
---
|
|
3687
3691
|
|
|
3688
3692
|
## Phase 4: Regenerate Artifacts
|
|
@@ -4638,7 +4642,7 @@ Three tiers determine how to approach a task:
|
|
|
4638
4642
|
|
|
4639
4643
|
| Type | Field | Invocation | Count |
|
|
4640
4644
|
|------|-------|-----------|-------|
|
|
4641
|
-
| Task | `disable-model-invocation: true` | User via `/skill` only |
|
|
4645
|
+
| Task | `disable-model-invocation: true` | User via `/skill` only | 31 |
|
|
4642
4646
|
| Hybrid | (neither) | User via `/skill` + agent knowledge | 31 |
|
|
4643
4647
|
| Knowledge | `user-invocable: false` | Claude auto-loads | 32 |
|
|
4644
4648
|
|
|
@@ -8241,6 +8245,172 @@ Project-local setup uses the same preservation approach for files that should re
|
|
|
8241
8245
|
|
|
8242
8246
|
---
|
|
8243
8247
|
|
|
8248
|
+
## kb/reference/opencode-compatibility.md
|
|
8249
|
+
|
|
8250
|
+
---
|
|
8251
|
+
title: "AI Toolkit - opencode Compatibility"
|
|
8252
|
+
category: reference
|
|
8253
|
+
service: ai-toolkit
|
|
8254
|
+
tags: [opencode, compatibility, install, skills, hooks, mcp, plugins]
|
|
8255
|
+
version: "1.0.0"
|
|
8256
|
+
created: "2026-04-16"
|
|
8257
|
+
last_updated: "2026-04-16"
|
|
8258
|
+
description: "Reference for how ai-toolkit integrates with opencode — AGENTS.md, subagents, slash commands, JS plugin hook bridge, and MCP merge into opencode.json."
|
|
8259
|
+
---
|
|
8260
|
+
|
|
8261
|
+
# AI Toolkit - opencode Compatibility
|
|
8262
|
+
|
|
8263
|
+
## Summary
|
|
8264
|
+
|
|
8265
|
+
opencode (https://opencode.ai) is the 11th supported editor. `ai-toolkit install --editors opencode` (or `--editors all`) lays down a full native integration: shared `AGENTS.md`, per-agent `.opencode/agents/` files, per-command `.opencode/commands/` files, a JS plugin bridging toolkit Bash hooks to opencode lifecycle events, and MCP server merge into `opencode.json`.
|
|
8266
|
+
|
|
8267
|
+
opencode also reads `CLAUDE.md` as a fallback, so a user without the native integration still gets baseline rules. The native path adds subagents, slash commands, hooks, and MCP.
|
|
8268
|
+
|
|
8269
|
+
## Local Install Outputs
|
|
8270
|
+
|
|
8271
|
+
`ai-toolkit install --local --editors opencode` generates:
|
|
8272
|
+
|
|
8273
|
+
- `AGENTS.md` (shared with Codex CLI via distinct marker sections)
|
|
8274
|
+
- `.opencode/agents/ai-toolkit-*.md` (one per ai-toolkit agent, `mode: subagent`)
|
|
8275
|
+
- `.opencode/commands/ai-toolkit-*.md` (one per user-invocable skill, required `template: |` frontmatter field)
|
|
8276
|
+
- `.opencode/plugins/ai-toolkit-hooks.js` (JS plugin bridging Bash hooks)
|
|
8277
|
+
- `opencode.json` (MCP key merged from `.mcp.json`, user keys preserved)
|
|
8278
|
+
|
|
8279
|
+
## Global Install Outputs
|
|
8280
|
+
|
|
8281
|
+
`ai-toolkit install --editors opencode` (no `--local`) lays down:
|
|
8282
|
+
|
|
8283
|
+
- `~/.config/opencode/AGENTS.md`
|
|
8284
|
+
- `~/.config/opencode/agents/ai-toolkit-*.md`
|
|
8285
|
+
- `~/.config/opencode/commands/ai-toolkit-*.md`
|
|
8286
|
+
- `~/.config/opencode/plugins/ai-toolkit-hooks.js`
|
|
8287
|
+
- `~/.config/opencode/opencode.json` (MCP merge, user keys preserved)
|
|
8288
|
+
|
|
8289
|
+
Files land directly under `~/.config/opencode/` (no `.opencode/` nesting) because that is the global layout opencode expects per https://opencode.ai/docs/config/. Shared hook scripts stay in `~/.softspark/ai-toolkit/hooks/` and are referenced by the global JS plugin.
|
|
8290
|
+
|
|
8291
|
+
## Editor Surface Comparison
|
|
8292
|
+
|
|
8293
|
+
| Feature | Claude Code | Codex CLI | opencode |
|
|
8294
|
+
|--------------------|-------------|-----------------|-------------------------------------------|
|
|
8295
|
+
| Rules file | `CLAUDE.md` | `AGENTS.md` | `AGENTS.md` + `CLAUDE.md` fallback |
|
|
8296
|
+
| Subagents | Yes | No | Yes (`mode: subagent`) |
|
|
8297
|
+
| Slash commands | Skills | Adapted skills | Native commands with frontmatter |
|
|
8298
|
+
| MCP | Yes | Yes | Yes (`opencode.json`) |
|
|
8299
|
+
| Lifecycle hooks | JSON config | `.codex/hooks` | JS/TS plugins (~30+ events) |
|
|
8300
|
+
| Global config dir | `~/.claude` | `~/.codex` | `~/.config/opencode` |
|
|
8301
|
+
| Project config dir | `.claude` | `.agents` | `.opencode` |
|
|
8302
|
+
|
|
8303
|
+
## Shared AGENTS.md
|
|
8304
|
+
|
|
8305
|
+
opencode and Codex CLI both read `AGENTS.md`. The toolkit emits two distinct marker-bounded sections in a single file, so installing both editors does not clobber either. The Codex section is produced by `generate_codex.py`; the opencode section is produced by `generate_opencode.py`. Both sections reuse `codex_skill_adapter.py` because both editors lack Claude-only orchestration primitives (`Agent`, `TeamCreate`, `TaskCreate`).
|
|
8306
|
+
|
|
8307
|
+
## Subagent Translation Model
|
|
8308
|
+
|
|
8309
|
+
Each file in `app/agents/*.md` emits a corresponding `.opencode/agents/ai-toolkit-<name>.md` with:
|
|
8310
|
+
|
|
8311
|
+
- `description` — copied from the source agent frontmatter
|
|
8312
|
+
- `mode: subagent` (required)
|
|
8313
|
+
- `color` — copied when present
|
|
8314
|
+
|
|
8315
|
+
The `model` field is deliberately omitted. opencode requires the `provider/model-id` form; ai-toolkit only stores a short alias (`opus`/`sonnet`/`haiku`) which cannot be mapped without assuming a provider. opencode falls back to the user's `default_agent` / top-level `model` config.
|
|
8316
|
+
|
|
8317
|
+
Opencode treats these files as auto-completable with `@` and can delegate to them from the primary agent.
|
|
8318
|
+
|
|
8319
|
+
## Slash Command Translation Model
|
|
8320
|
+
|
|
8321
|
+
Only user-invocable skills (`user-invocable: true` or no `disable-model-invocation`) emit to `.opencode/commands/`. Knowledge skills (`user-invocable: false`) are intentionally skipped — they are not intended as commands.
|
|
8322
|
+
|
|
8323
|
+
Each command file carries opencode's required `template: |` frontmatter field, built from the SKILL.md body.
|
|
8324
|
+
|
|
8325
|
+
## Hook Bridge (JS Plugin)
|
|
8326
|
+
|
|
8327
|
+
`.opencode/plugins/ai-toolkit-hooks.js` is a single-file plugin that maps opencode events to the shared Bash hooks in `~/.softspark/ai-toolkit/hooks/`:
|
|
8328
|
+
|
|
8329
|
+
| opencode event | Bash hook(s) |
|
|
8330
|
+
|----------------------------|--------------------------------------------------------------------|
|
|
8331
|
+
| `session.created` | `session-start.sh` + `session-context.sh` + `mcp-health.sh` |
|
|
8332
|
+
| `session.compacted` | `pre-compact.sh` + `pre-compact-save.sh` (PreCompact equivalent) |
|
|
8333
|
+
| `session.deleted` | `session-end.sh` + `save-session.sh` |
|
|
8334
|
+
| `message.updated` | `user-prompt-submit.sh` + `track-usage.sh` |
|
|
8335
|
+
| `message.part.updated` | `user-prompt-submit.sh` + `track-usage.sh` |
|
|
8336
|
+
| `tool.execute.before` (bash) | `guard-destructive.sh` + `commit-quality.sh` |
|
|
8337
|
+
| `tool.execute.after` | `post-tool-use.sh` |
|
|
8338
|
+
| `permission.asked` | `guard-destructive.sh` (approval-gate bridge) |
|
|
8339
|
+
| `command.executed` | `post-tool-use.sh` |
|
|
8340
|
+
|
|
8341
|
+
Plugin exports a single named export `AiToolkitHooks` — per opencode docs, named exports only (no default export). Hook scripts are invoked via Bun's `$` with the script path bound as a JS constant; opencode event payloads are passed as JSON on stdin, never interpolated into the shell command, so payload data cannot inject shell metacharacters. The toolkit's `exit 2` semantics for PreToolUse guards are preserved and bubble up as the plugin's return code.
|
|
8342
|
+
|
|
8343
|
+
**Intentionally unmapped events**: `tui.*`, `lsp.*`, `installation.*`, `session.idle/status/updated/error/diff`, `file.edited`, `file.watcher.updated`, `todo.updated`, `shell.env`, `server.connected`, `message.*.removed`, `experimental.*` — no matching Bash hook in the toolkit, or the event is opencode-UI-only.
|
|
8344
|
+
|
|
8345
|
+
## MCP Merge (opencode.json)
|
|
8346
|
+
|
|
8347
|
+
`generate_opencode_json.py` reads `.mcp.json` and merges its servers under the `mcp` key in `opencode.json`:
|
|
8348
|
+
|
|
8349
|
+
- `local` shape entries are translated to opencode's local command shape.
|
|
8350
|
+
- `remote` shape entries are translated to opencode's remote URL shape.
|
|
8351
|
+
- User-authored keys in `opencode.json` (outside `mcp`) are preserved.
|
|
8352
|
+
- Re-running the generator is idempotent.
|
|
8353
|
+
|
|
8354
|
+
## Auto-Detection
|
|
8355
|
+
|
|
8356
|
+
The installer detects opencode as configured when any of these markers exist:
|
|
8357
|
+
|
|
8358
|
+
- `opencode.json`
|
|
8359
|
+
- `.opencode/` directory
|
|
8360
|
+
- `.opencode/agents/`
|
|
8361
|
+
- `.opencode/commands/`
|
|
8362
|
+
- `~/.config/opencode/`
|
|
8363
|
+
|
|
8364
|
+
`ai-toolkit update` picks up opencode automatically when detection fires.
|
|
8365
|
+
|
|
8366
|
+
## Uninstall & Reset
|
|
8367
|
+
|
|
8368
|
+
`scripts/install_steps/ai_tools.py` cleanup only removes ai-toolkit-marked artifacts:
|
|
8369
|
+
|
|
8370
|
+
- Generated `.opencode/agents/ai-toolkit-*.md`
|
|
8371
|
+
- Generated `.opencode/commands/ai-toolkit-*.md`
|
|
8372
|
+
- Generated `.opencode/plugins/ai-toolkit-hooks.js`
|
|
8373
|
+
- Managed markers from `AGENTS.md`
|
|
8374
|
+
- `mcp` key entries injected by the toolkit (user keys preserved)
|
|
8375
|
+
|
|
8376
|
+
User-authored opencode files and user-authored `opencode.json` keys are never deleted.
|
|
8377
|
+
|
|
8378
|
+
## Behavioral Limits
|
|
8379
|
+
|
|
8380
|
+
- opencode does not expose the full Claude hook event surface; only the events in the mapping table above are bridged. Claude-only events (`TaskCompleted`, `TeammateIdle`, `SubagentStart`, `SubagentStop`, `PreCompact`) are silently skipped.
|
|
8381
|
+
- Multi-agent orchestration skills (`/orchestrate`, `/workflow`, `/swarm`, `/teams`, `/subagent-development`) run through the Codex adaptation layer — they use opencode subagents and explicit file ownership instead of Claude's `Agent`/`TaskCreate` primitives.
|
|
8382
|
+
|
|
8383
|
+
## Verification
|
|
8384
|
+
|
|
8385
|
+
The opencode integration is verified by:
|
|
8386
|
+
|
|
8387
|
+
1. Generator contract tests for the five `generate_opencode*.py` scripts (bats)
|
|
8388
|
+
2. MCP merge idempotency and user-key preservation tests
|
|
8389
|
+
3. Plugin export shape and event coverage tests
|
|
8390
|
+
4. Auto-detection tests for install / update flow
|
|
8391
|
+
5. `validate.py --strict` + `audit_skills.py --ci` in CI
|
|
8392
|
+
|
|
8393
|
+
## CLI Commands
|
|
8394
|
+
|
|
8395
|
+
| Command | Description |
|
|
8396
|
+
|---------|-------------|
|
|
8397
|
+
| `ai-toolkit opencode-md` | Generate `AGENTS.md` body for opencode |
|
|
8398
|
+
| `ai-toolkit opencode-agents` | Generate `.opencode/agents/ai-toolkit-*.md` |
|
|
8399
|
+
| `ai-toolkit opencode-commands` | Generate `.opencode/commands/ai-toolkit-*.md` |
|
|
8400
|
+
| `ai-toolkit opencode-plugin` | Generate `.opencode/plugins/ai-toolkit-hooks.js` |
|
|
8401
|
+
| `ai-toolkit opencode-json` | Merge MCP servers into `opencode.json` |
|
|
8402
|
+
|
|
8403
|
+
## Related
|
|
8404
|
+
|
|
8405
|
+
- `kb/reference/skills-catalog.md`
|
|
8406
|
+
- `kb/reference/agents-catalog.md`
|
|
8407
|
+
- `kb/reference/codex-cli-compatibility.md`
|
|
8408
|
+
- `kb/reference/architecture-overview.md`
|
|
8409
|
+
- `kb/reference/global-install-model.md`
|
|
8410
|
+
- `kb/reference/mcp-editor-compatibility.md`
|
|
8411
|
+
|
|
8412
|
+
---
|
|
8413
|
+
|
|
8244
8414
|
## kb/reference/plugin-pack-conventions.md
|
|
8245
8415
|
|
|
8246
8416
|
---
|
package/llms.txt
CHANGED
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
- [MCP Editor Compatibility](kb/reference/mcp-editor-compatibility.md)
|
|
45
45
|
- [MCP Server Templates](kb/reference/mcp-templates.md)
|
|
46
46
|
- [Merge-Friendly Install Model](kb/reference/merge-friendly-install-model.md)
|
|
47
|
+
- [AI Toolkit - opencode Compatibility](kb/reference/opencode-compatibility.md)
|
|
47
48
|
- [Plugin Pack Conventions](kb/reference/plugin-pack-conventions.md)
|
|
48
49
|
- [Quick Wins Implementation Summary](kb/reference/quick-wins-implementation-summary.md)
|
|
49
50
|
- [Skill Templates](kb/reference/skill-templates.md)
|
package/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@softspark/ai-toolkit",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Professional-grade AI coding toolkit: 94 skills, 44 agents, multi-platform support (Claude, Cursor, Windsurf, Copilot, Gemini, Cline, Roo Code, Aider, Augment, Google Antigravity, Codex CLI), machine-enforced safety constitution, persona presets, skill security auditor, expanded lifecycle hooks, 11 plugin packs, and benchmark tooling.",
|
|
3
|
+
"version": "2.6.2",
|
|
4
|
+
"description": "Professional-grade AI coding toolkit: 94 skills, 44 agents, multi-platform support (Claude, Cursor, Windsurf, Copilot, Gemini, Cline, Roo Code, Aider, Augment, Google Antigravity, Codex CLI, opencode), machine-enforced safety constitution, persona presets, skill security auditor, expanded lifecycle hooks, 11 plugin packs, and benchmark tooling.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
7
7
|
"claude-code",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"augment",
|
|
24
24
|
"antigravity",
|
|
25
25
|
"google-antigravity",
|
|
26
|
+
"opencode",
|
|
26
27
|
"multi-platform"
|
|
27
28
|
],
|
|
28
29
|
"homepage": "https://github.com/softspark/ai-toolkit",
|
|
@@ -56,7 +57,9 @@
|
|
|
56
57
|
"generate:roo": "python3 scripts/generate_roo_modes.py > .roomodes",
|
|
57
58
|
"generate:aider": "python3 scripts/generate_aider_conf.py > .aider.conf.yml",
|
|
58
59
|
"generate:codex-rules": "python3 scripts/generate_codex_rules.py .",
|
|
59
|
-
"generate:
|
|
60
|
+
"generate:opencode-agents": "python3 scripts/generate_opencode_agents.py .",
|
|
61
|
+
"generate:opencode-commands": "python3 scripts/generate_opencode_commands.py .",
|
|
62
|
+
"generate:all": "npm run generate:agents && npm run generate:codex-rules && npm run generate:opencode-agents && npm run generate:opencode-commands && npm run generate:cursor && npm run generate:windsurf && npm run generate:copilot && npm run generate:gemini && npm run generate:cline && npm run generate:roo && npm run generate:aider && npm run generate:llms"
|
|
60
63
|
},
|
|
61
64
|
"files": [
|
|
62
65
|
"bin/",
|
package/scripts/eject.py
CHANGED
|
@@ -69,7 +69,11 @@ def main() -> None:
|
|
|
69
69
|
if dest.exists():
|
|
70
70
|
shutil.rmtree(dest)
|
|
71
71
|
shutil.copytree(skill, dest)
|
|
72
|
-
|
|
72
|
+
# Count only real skills. Underscore-prefixed dirs (e.g. `_lib/`)
|
|
73
|
+
# are shared helpers that must be copied so dependent skills keep
|
|
74
|
+
# working, but are not skills themselves — matches validate.py.
|
|
75
|
+
if not skill.name.startswith("_") and (skill / "SKILL.md").is_file():
|
|
76
|
+
skill_count += 1
|
|
73
77
|
print(f" Copied: {skill_count} skills")
|
|
74
78
|
|
|
75
79
|
# -- CLAUDE.md: inline all rules -----------------------------------------
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Generate AGENTS.md content for opencode (https://opencode.ai).
|
|
3
|
+
|
|
4
|
+
opencode reads AGENTS.md using the same convention as OpenAI Codex CLI.
|
|
5
|
+
The generated file is safe for both editors to consume from the same
|
|
6
|
+
project root — each injects into its own marker-wrapped block.
|
|
7
|
+
|
|
8
|
+
Usage: ./scripts/generate_opencode.py > AGENTS.md
|
|
9
|
+
"""
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import sys
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
16
|
+
from codex_skill_adapter import codex_skill_description
|
|
17
|
+
from emission import (
|
|
18
|
+
agents_dir,
|
|
19
|
+
skills_dir,
|
|
20
|
+
generate_quality_standards,
|
|
21
|
+
generate_workflow_guidelines,
|
|
22
|
+
print_toolkit_end,
|
|
23
|
+
print_toolkit_start,
|
|
24
|
+
)
|
|
25
|
+
from frontmatter import frontmatter_field
|
|
26
|
+
from paths import RULES_DIR
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _emit_agents() -> str:
|
|
30
|
+
"""Emit agents as opencode subagent bullets."""
|
|
31
|
+
lines: list[str] = []
|
|
32
|
+
for agent_file in sorted(agents_dir.glob("*.md")):
|
|
33
|
+
name = frontmatter_field(agent_file, "name")
|
|
34
|
+
description = frontmatter_field(agent_file, "description")
|
|
35
|
+
if not name or not description:
|
|
36
|
+
continue
|
|
37
|
+
lines.append(f"- **{name}**: {description}")
|
|
38
|
+
return "\n".join(lines)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _emit_skills() -> str:
|
|
42
|
+
"""Emit user-invocable skills as opencode command bullets.
|
|
43
|
+
|
|
44
|
+
Adapts Claude orchestration-only descriptions via the Codex adapter —
|
|
45
|
+
opencode, like Codex, lacks Claude's Agent/Team/Task primitives so the
|
|
46
|
+
same translation layer applies.
|
|
47
|
+
"""
|
|
48
|
+
lines: list[str] = []
|
|
49
|
+
for skill_dir in sorted(skills_dir.iterdir()):
|
|
50
|
+
if skill_dir.name.startswith("_"):
|
|
51
|
+
continue
|
|
52
|
+
skill_file = skill_dir / "SKILL.md"
|
|
53
|
+
if not skill_file.is_file():
|
|
54
|
+
continue
|
|
55
|
+
name = frontmatter_field(skill_file, "name")
|
|
56
|
+
description = codex_skill_description(skill_file)
|
|
57
|
+
if not name or not description:
|
|
58
|
+
continue
|
|
59
|
+
lines.append(f"- **{name}**: {description}")
|
|
60
|
+
return "\n".join(lines)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def main() -> None:
|
|
64
|
+
print_toolkit_start()
|
|
65
|
+
|
|
66
|
+
print("# AI Toolkit — opencode Configuration")
|
|
67
|
+
print()
|
|
68
|
+
print(
|
|
69
|
+
"Shared AI development toolkit with specialized subagents,"
|
|
70
|
+
" opencode-compatible commands, quality hooks, and a safety constitution."
|
|
71
|
+
)
|
|
72
|
+
print()
|
|
73
|
+
print(
|
|
74
|
+
"opencode reads this file at session start. Subagents are also"
|
|
75
|
+
" installed under `.opencode/agents/` and slash commands under"
|
|
76
|
+
" `.opencode/commands/` for native `@` and `/` autocomplete."
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# Agents
|
|
80
|
+
print()
|
|
81
|
+
print("## Available Subagents")
|
|
82
|
+
print()
|
|
83
|
+
print("Invoke with `@<name>` in opencode, or delegate via `spawn_agent`:")
|
|
84
|
+
print()
|
|
85
|
+
print(_emit_agents())
|
|
86
|
+
|
|
87
|
+
# Skills / slash commands
|
|
88
|
+
print()
|
|
89
|
+
print("## Available Commands")
|
|
90
|
+
print()
|
|
91
|
+
print("Invoke with `/<name>` in opencode. Knowledge-only skills load automatically:")
|
|
92
|
+
print()
|
|
93
|
+
print(_emit_skills())
|
|
94
|
+
|
|
95
|
+
# Guidelines
|
|
96
|
+
print()
|
|
97
|
+
print(generate_quality_standards())
|
|
98
|
+
print()
|
|
99
|
+
print(generate_workflow_guidelines())
|
|
100
|
+
|
|
101
|
+
print_toolkit_end()
|
|
102
|
+
|
|
103
|
+
# Registered custom rules from ~/.softspark/ai-toolkit/rules/
|
|
104
|
+
if RULES_DIR.is_dir():
|
|
105
|
+
for rule_file in sorted(RULES_DIR.glob("*.md")):
|
|
106
|
+
rule_name = rule_file.stem
|
|
107
|
+
print()
|
|
108
|
+
print(f"<!-- TOOLKIT:{rule_name} START -->")
|
|
109
|
+
print("<!-- Auto-injected by ai-toolkit. Re-run to update. -->")
|
|
110
|
+
print()
|
|
111
|
+
print(rule_file.read_text(encoding="utf-8").rstrip())
|
|
112
|
+
print()
|
|
113
|
+
print(f"<!-- TOOLKIT:{rule_name} END -->")
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
if __name__ == "__main__":
|
|
117
|
+
main()
|