@softspark/ai-toolkit 2.5.0 → 2.6.1

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.
@@ -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)
@@ -4638,7 +4639,7 @@ Three tiers determine how to approach a task:
4638
4639
 
4639
4640
  | Type | Field | Invocation | Count |
4640
4641
  |------|-------|-----------|-------|
4641
- | Task | `disable-model-invocation: true` | User via `/skill` only | 30 |
4642
+ | Task | `disable-model-invocation: true` | User via `/skill` only | 31 |
4642
4643
  | Hybrid | (neither) | User via `/skill` + agent knowledge | 31 |
4643
4644
  | Knowledge | `user-invocable: false` | Claude auto-loads | 32 |
4644
4645
 
@@ -8241,6 +8242,172 @@ Project-local setup uses the same preservation approach for files that should re
8241
8242
 
8242
8243
  ---
8243
8244
 
8245
+ ## kb/reference/opencode-compatibility.md
8246
+
8247
+ ---
8248
+ title: "AI Toolkit - opencode Compatibility"
8249
+ category: reference
8250
+ service: ai-toolkit
8251
+ tags: [opencode, compatibility, install, skills, hooks, mcp, plugins]
8252
+ version: "1.0.0"
8253
+ created: "2026-04-16"
8254
+ last_updated: "2026-04-16"
8255
+ description: "Reference for how ai-toolkit integrates with opencode — AGENTS.md, subagents, slash commands, JS plugin hook bridge, and MCP merge into opencode.json."
8256
+ ---
8257
+
8258
+ # AI Toolkit - opencode Compatibility
8259
+
8260
+ ## Summary
8261
+
8262
+ 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`.
8263
+
8264
+ 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.
8265
+
8266
+ ## Local Install Outputs
8267
+
8268
+ `ai-toolkit install --local --editors opencode` generates:
8269
+
8270
+ - `AGENTS.md` (shared with Codex CLI via distinct marker sections)
8271
+ - `.opencode/agents/ai-toolkit-*.md` (one per ai-toolkit agent, `mode: subagent`)
8272
+ - `.opencode/commands/ai-toolkit-*.md` (one per user-invocable skill, required `template: |` frontmatter field)
8273
+ - `.opencode/plugins/ai-toolkit-hooks.js` (JS plugin bridging Bash hooks)
8274
+ - `opencode.json` (MCP key merged from `.mcp.json`, user keys preserved)
8275
+
8276
+ ## Global Install Outputs
8277
+
8278
+ `ai-toolkit install --editors opencode` (no `--local`) lays down:
8279
+
8280
+ - `~/.config/opencode/AGENTS.md`
8281
+ - `~/.config/opencode/agents/ai-toolkit-*.md`
8282
+ - `~/.config/opencode/commands/ai-toolkit-*.md`
8283
+ - `~/.config/opencode/plugins/ai-toolkit-hooks.js`
8284
+ - `~/.config/opencode/opencode.json` (MCP merge, user keys preserved)
8285
+
8286
+ 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.
8287
+
8288
+ ## Editor Surface Comparison
8289
+
8290
+ | Feature | Claude Code | Codex CLI | opencode |
8291
+ |--------------------|-------------|-----------------|-------------------------------------------|
8292
+ | Rules file | `CLAUDE.md` | `AGENTS.md` | `AGENTS.md` + `CLAUDE.md` fallback |
8293
+ | Subagents | Yes | No | Yes (`mode: subagent`) |
8294
+ | Slash commands | Skills | Adapted skills | Native commands with frontmatter |
8295
+ | MCP | Yes | Yes | Yes (`opencode.json`) |
8296
+ | Lifecycle hooks | JSON config | `.codex/hooks` | JS/TS plugins (~30+ events) |
8297
+ | Global config dir | `~/.claude` | `~/.codex` | `~/.config/opencode` |
8298
+ | Project config dir | `.claude` | `.agents` | `.opencode` |
8299
+
8300
+ ## Shared AGENTS.md
8301
+
8302
+ 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`).
8303
+
8304
+ ## Subagent Translation Model
8305
+
8306
+ Each file in `app/agents/*.md` emits a corresponding `.opencode/agents/ai-toolkit-<name>.md` with:
8307
+
8308
+ - `description` — copied from the source agent frontmatter
8309
+ - `mode: subagent` (required)
8310
+ - `color` — copied when present
8311
+
8312
+ 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.
8313
+
8314
+ Opencode treats these files as auto-completable with `@` and can delegate to them from the primary agent.
8315
+
8316
+ ## Slash Command Translation Model
8317
+
8318
+ 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.
8319
+
8320
+ Each command file carries opencode's required `template: |` frontmatter field, built from the SKILL.md body.
8321
+
8322
+ ## Hook Bridge (JS Plugin)
8323
+
8324
+ `.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/`:
8325
+
8326
+ | opencode event | Bash hook(s) |
8327
+ |----------------------------|--------------------------------------------------------------------|
8328
+ | `session.created` | `session-start.sh` + `session-context.sh` + `mcp-health.sh` |
8329
+ | `session.compacted` | `pre-compact.sh` + `pre-compact-save.sh` (PreCompact equivalent) |
8330
+ | `session.deleted` | `session-end.sh` + `save-session.sh` |
8331
+ | `message.updated` | `user-prompt-submit.sh` + `track-usage.sh` |
8332
+ | `message.part.updated` | `user-prompt-submit.sh` + `track-usage.sh` |
8333
+ | `tool.execute.before` (bash) | `guard-destructive.sh` + `commit-quality.sh` |
8334
+ | `tool.execute.after` | `post-tool-use.sh` |
8335
+ | `permission.asked` | `guard-destructive.sh` (approval-gate bridge) |
8336
+ | `command.executed` | `post-tool-use.sh` |
8337
+
8338
+ 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.
8339
+
8340
+ **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.
8341
+
8342
+ ## MCP Merge (opencode.json)
8343
+
8344
+ `generate_opencode_json.py` reads `.mcp.json` and merges its servers under the `mcp` key in `opencode.json`:
8345
+
8346
+ - `local` shape entries are translated to opencode's local command shape.
8347
+ - `remote` shape entries are translated to opencode's remote URL shape.
8348
+ - User-authored keys in `opencode.json` (outside `mcp`) are preserved.
8349
+ - Re-running the generator is idempotent.
8350
+
8351
+ ## Auto-Detection
8352
+
8353
+ The installer detects opencode as configured when any of these markers exist:
8354
+
8355
+ - `opencode.json`
8356
+ - `.opencode/` directory
8357
+ - `.opencode/agents/`
8358
+ - `.opencode/commands/`
8359
+ - `~/.config/opencode/`
8360
+
8361
+ `ai-toolkit update` picks up opencode automatically when detection fires.
8362
+
8363
+ ## Uninstall & Reset
8364
+
8365
+ `scripts/install_steps/ai_tools.py` cleanup only removes ai-toolkit-marked artifacts:
8366
+
8367
+ - Generated `.opencode/agents/ai-toolkit-*.md`
8368
+ - Generated `.opencode/commands/ai-toolkit-*.md`
8369
+ - Generated `.opencode/plugins/ai-toolkit-hooks.js`
8370
+ - Managed markers from `AGENTS.md`
8371
+ - `mcp` key entries injected by the toolkit (user keys preserved)
8372
+
8373
+ User-authored opencode files and user-authored `opencode.json` keys are never deleted.
8374
+
8375
+ ## Behavioral Limits
8376
+
8377
+ - 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.
8378
+ - 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.
8379
+
8380
+ ## Verification
8381
+
8382
+ The opencode integration is verified by:
8383
+
8384
+ 1. Generator contract tests for the five `generate_opencode*.py` scripts (bats)
8385
+ 2. MCP merge idempotency and user-key preservation tests
8386
+ 3. Plugin export shape and event coverage tests
8387
+ 4. Auto-detection tests for install / update flow
8388
+ 5. `validate.py --strict` + `audit_skills.py --ci` in CI
8389
+
8390
+ ## CLI Commands
8391
+
8392
+ | Command | Description |
8393
+ |---------|-------------|
8394
+ | `ai-toolkit opencode-md` | Generate `AGENTS.md` body for opencode |
8395
+ | `ai-toolkit opencode-agents` | Generate `.opencode/agents/ai-toolkit-*.md` |
8396
+ | `ai-toolkit opencode-commands` | Generate `.opencode/commands/ai-toolkit-*.md` |
8397
+ | `ai-toolkit opencode-plugin` | Generate `.opencode/plugins/ai-toolkit-hooks.js` |
8398
+ | `ai-toolkit opencode-json` | Merge MCP servers into `opencode.json` |
8399
+
8400
+ ## Related
8401
+
8402
+ - `kb/reference/skills-catalog.md`
8403
+ - `kb/reference/agents-catalog.md`
8404
+ - `kb/reference/codex-cli-compatibility.md`
8405
+ - `kb/reference/architecture-overview.md`
8406
+ - `kb/reference/global-install-model.md`
8407
+ - `kb/reference/mcp-editor-compatibility.md`
8408
+
8409
+ ---
8410
+
8244
8411
  ## kb/reference/plugin-pack-conventions.md
8245
8412
 
8246
8413
  ---
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
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.5.0",
2
+ "version": "2.6.1",
3
3
  "components": {
4
4
  "agents": {
5
5
  "description": "44 specialized agents (orchestrator, backend, frontend, security, devops, etc.)",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@softspark/ai-toolkit",
3
- "version": "2.5.0",
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.1",
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:all": "npm run generate:agents && npm run generate:codex-rules && 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
+ "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/",
@@ -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()
@@ -0,0 +1,126 @@
1
+ #!/usr/bin/env python3
2
+ """Generate .opencode/agents/*.md files for opencode (https://opencode.ai).
3
+
4
+ Each ai-toolkit agent becomes an opencode subagent with frontmatter:
5
+
6
+ ---
7
+ description: "..."
8
+ mode: subagent
9
+ ---
10
+
11
+ <body from agent file>
12
+
13
+ Generated files are prefixed ``ai-toolkit-`` so they never collide with
14
+ user-authored opencode agents and can be cleanly removed on uninstall.
15
+
16
+ Usage:
17
+ python3 scripts/generate_opencode_agents.py [target-dir]
18
+
19
+ Writes files to target-dir/.opencode/agents/.
20
+ """
21
+ from __future__ import annotations
22
+
23
+ import sys
24
+ from pathlib import Path
25
+
26
+ sys.path.insert(0, str(Path(__file__).resolve().parent))
27
+ from emission import agents_dir
28
+ from frontmatter import frontmatter_field
29
+
30
+ AGENT_PREFIX = "ai-toolkit-"
31
+
32
+
33
+ def _agent_body(agent_file: Path) -> str:
34
+ """Return the markdown body of an agent file (content after frontmatter)."""
35
+ text = agent_file.read_text(encoding="utf-8")
36
+ if not text.startswith("---"):
37
+ return text.strip() + "\n"
38
+ # Skip first frontmatter block
39
+ parts = text.split("---", 2)
40
+ if len(parts) < 3:
41
+ return text.strip() + "\n"
42
+ return parts[2].lstrip("\n")
43
+
44
+
45
+ def _render_opencode_agent(agent_file: Path) -> str:
46
+ """Render a single opencode subagent .md file from an ai-toolkit agent."""
47
+ name = frontmatter_field(agent_file, "name")
48
+ description = frontmatter_field(agent_file, "description")
49
+ model = frontmatter_field(agent_file, "model")
50
+ color = frontmatter_field(agent_file, "color")
51
+
52
+ # Escape description for YAML quoted string
53
+ safe_desc = description.replace('"', "'")
54
+
55
+ lines: list[str] = ["---"]
56
+ lines.append(f'description: "{safe_desc}"')
57
+ lines.append("mode: subagent")
58
+ # opencode requires `provider/model-id` for the `model` field. ai-toolkit
59
+ # only stores a short alias (opus/sonnet/haiku) which is not mappable
60
+ # without assuming a provider, so we deliberately omit it — opencode falls
61
+ # back to the user's `default_agent` / top-level `model` config.
62
+ _ = model # intentionally unused
63
+ if color:
64
+ lines.append(f"color: {color}")
65
+ lines.append("---")
66
+ lines.append("")
67
+ body = _agent_body(agent_file).rstrip()
68
+ if body:
69
+ lines.append(body)
70
+ lines.append("")
71
+ return "\n".join(lines)
72
+
73
+
74
+ def _cleanup_stale(agents_out: Path) -> int:
75
+ """Remove stale ai-toolkit-* agent files whose source no longer exists."""
76
+ if not agents_out.is_dir():
77
+ return 0
78
+ removed = 0
79
+ for f in sorted(agents_out.glob(f"{AGENT_PREFIX}*.md")):
80
+ source_name = f.stem[len(AGENT_PREFIX):]
81
+ source = agents_dir / f"{source_name}.md"
82
+ if not source.is_file():
83
+ f.unlink()
84
+ removed += 1
85
+ return removed
86
+
87
+
88
+ def generate(
89
+ target_dir: Path, config_root: Path | None = None
90
+ ) -> tuple[int, int]:
91
+ """Write opencode agent files and return (written, removed_stale).
92
+
93
+ By default writes to ``target_dir/.opencode/agents/`` (project-local).
94
+ Pass ``config_root=~/.config/opencode`` for the global layout, which
95
+ lives directly under ``agents/`` (no ``.opencode/`` prefix).
96
+ """
97
+ base = config_root if config_root is not None else target_dir / ".opencode"
98
+ agents_out = base / "agents"
99
+ agents_out.mkdir(parents=True, exist_ok=True)
100
+
101
+ written = 0
102
+ for agent_file in sorted(agents_dir.glob("*.md")):
103
+ name = frontmatter_field(agent_file, "name")
104
+ description = frontmatter_field(agent_file, "description")
105
+ if not name or not description:
106
+ continue
107
+ out_path = agents_out / f"{AGENT_PREFIX}{name}.md"
108
+ out_path.write_text(_render_opencode_agent(agent_file), encoding="utf-8")
109
+ written += 1
110
+
111
+ removed = _cleanup_stale(agents_out)
112
+ return written, removed
113
+
114
+
115
+ def main() -> None:
116
+ target = Path(sys.argv[1]) if len(sys.argv) > 1 else Path.cwd()
117
+ written, removed = generate(target)
118
+ msg = f"Generated: .opencode/agents/ ({written} agents"
119
+ if removed:
120
+ msg += f", {removed} stale removed"
121
+ msg += ")"
122
+ print(msg)
123
+
124
+
125
+ if __name__ == "__main__":
126
+ main()