@softspark/ai-toolkit 2.12.0 → 3.0.0

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 (41) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +18 -8
  3. package/app/.claude-plugin/plugin.json +1 -1
  4. package/app/skills/hook-creator/SKILL.md +84 -8
  5. package/app/skills/skill-creator/SKILL.md +8 -4
  6. package/benchmarks/ecosystem-doctor-snapshot.json +395 -0
  7. package/kb/history/completed/deep-coverage-v3-20260423.md +160 -0
  8. package/kb/history/completed/ecosystem-deep-sweep-20260423.md +273 -0
  9. package/kb/procedures/ecosystem-sync-sop.md +255 -0
  10. package/kb/procedures/maintenance-sop.md +13 -2
  11. package/kb/procedures/release-preparation-sop.md +83 -10
  12. package/kb/reference/global-install-model.md +15 -2
  13. package/kb/reference/supported-tools-registry.md +229 -0
  14. package/llms-full.txt +1052 -14
  15. package/llms.txt +4 -0
  16. package/manifest.json +1 -1
  17. package/package.json +4 -1
  18. package/scripts/ecosystem_doctor.py +348 -0
  19. package/scripts/ecosystem_tools.json +500 -0
  20. package/scripts/generate_aider_conf.py +26 -1
  21. package/scripts/generate_antigravity.py +77 -8
  22. package/scripts/generate_augment_agents.py +161 -0
  23. package/scripts/generate_augment_commands.py +160 -0
  24. package/scripts/generate_augment_hooks.py +162 -0
  25. package/scripts/generate_augment_skills.py +98 -0
  26. package/scripts/generate_cline_rules.py +96 -9
  27. package/scripts/generate_codex_hooks.py +13 -2
  28. package/scripts/generate_codex_skills.py +195 -0
  29. package/scripts/generate_copilot.py +296 -18
  30. package/scripts/generate_cursor_agents.py +144 -0
  31. package/scripts/generate_cursor_hooks.py +155 -0
  32. package/scripts/generate_cursor_mdc.py +20 -8
  33. package/scripts/generate_gemini_commands.py +158 -0
  34. package/scripts/generate_gemini_hooks.py +159 -0
  35. package/scripts/generate_gemini_skills.py +98 -0
  36. package/scripts/generate_roo_modes.py +42 -1
  37. package/scripts/generate_windsurf_hooks.py +143 -0
  38. package/scripts/generate_windsurf_rules.py +162 -10
  39. package/scripts/install.py +11 -2
  40. package/scripts/install_steps/ai_tools.py +120 -5
  41. package/scripts/validate.py +20 -3
@@ -0,0 +1,500 @@
1
+ {
2
+ "schema_version": 1,
3
+ "description": "Authoritative registry of tools ai-toolkit integrates with. Consumed by scripts/ecosystem_doctor.py to detect upstream doc/version drift.",
4
+ "last_updated": "2026-04-23",
5
+ "tools": [
6
+ {
7
+ "id": "claude-code",
8
+ "display_name": "Claude Code",
9
+ "kind": "primary",
10
+ "urls": {
11
+ "docs": "https://platform.claude.com/docs/en/claude-code",
12
+ "release_notes": "https://github.com/anthropics/claude-code/releases",
13
+ "changelog": null
14
+ },
15
+ "config_paths": [
16
+ "~/.claude/settings.json",
17
+ ".claude/settings.local.json",
18
+ "CLAUDE.md",
19
+ ".claude/agents/*.md",
20
+ ".claude/skills/*/SKILL.md",
21
+ "~/.claude/themes/*.json"
22
+ ],
23
+ "our_generators": [],
24
+ "capability_markers": [
25
+ "PreToolUse",
26
+ "PostToolUse",
27
+ "SessionStart",
28
+ "SessionEnd",
29
+ "SubagentStart",
30
+ "SubagentStop",
31
+ "UserPromptSubmit",
32
+ "Notification",
33
+ "Stop",
34
+ "StopFailure",
35
+ "PreCompact",
36
+ "PostCompact",
37
+ "PermissionRequest",
38
+ "PermissionDenied",
39
+ "Elicitation",
40
+ "ElicitationResult",
41
+ "TaskCreated",
42
+ "TaskCompleted",
43
+ "TeammateIdle",
44
+ "WorktreeCreate",
45
+ "WorktreeRemove",
46
+ "CwdChanged",
47
+ "FileChanged",
48
+ "ConfigChange",
49
+ "Setup",
50
+ "InstructionsLoaded",
51
+ "slash command",
52
+ "MCP server",
53
+ "sub-agent",
54
+ "output style",
55
+ "SKILL.md",
56
+ "hook handler: command",
57
+ "hook handler: prompt",
58
+ "hook handler: agent",
59
+ "hook handler: mcp_tool"
60
+ ],
61
+ "version_probe": {
62
+ "kind": "command",
63
+ "command": "claude --version"
64
+ }
65
+ },
66
+ {
67
+ "id": "cursor",
68
+ "display_name": "Cursor",
69
+ "kind": "editor",
70
+ "urls": {
71
+ "docs": "https://cursor.com/docs",
72
+ "release_notes": "https://cursor.com/changelog",
73
+ "changelog": "https://cursor.com/changelog"
74
+ },
75
+ "config_paths": [
76
+ ".cursorrules",
77
+ ".cursor/rules/*.mdc",
78
+ ".cursor/rules/*.md",
79
+ "AGENTS.md",
80
+ ".cursor/mcp.json",
81
+ "~/.cursor/mcp.json",
82
+ ".cursor/skills/*/SKILL.md",
83
+ ".cursor/agents/*.md",
84
+ ".cursor/hooks.json",
85
+ "~/.cursor/hooks.json"
86
+ ],
87
+ "our_generators": [
88
+ "scripts/generate_cursor_rules.py",
89
+ "scripts/generate_cursor_mdc.py"
90
+ ],
91
+ "capability_markers": [
92
+ "cursorrules",
93
+ ".cursor/rules",
94
+ "AGENTS.md",
95
+ "mcp.json",
96
+ "Composer",
97
+ "Agent Mode",
98
+ "hooks.json",
99
+ "subagents",
100
+ "skills",
101
+ "plugins"
102
+ ],
103
+ "version_probe": null
104
+ },
105
+ {
106
+ "id": "windsurf",
107
+ "display_name": "Windsurf",
108
+ "kind": "editor",
109
+ "urls": {
110
+ "docs": "https://docs.windsurf.com",
111
+ "release_notes": "https://windsurf.com/changelog",
112
+ "changelog": "https://windsurf.com/changelog"
113
+ },
114
+ "config_paths": [
115
+ ".windsurfrules",
116
+ ".windsurf/rules/*.md",
117
+ ".windsurf/workflows/*.md",
118
+ "AGENTS.md",
119
+ "~/.codeium/windsurf/memories/global_rules.md",
120
+ "~/.codeium/windsurf/mcp_config.json",
121
+ "~/.codeium/windsurf/global_workflows/*.md"
122
+ ],
123
+ "our_generators": [
124
+ "scripts/generate_windsurf.py",
125
+ "scripts/generate_windsurf_rules.py"
126
+ ],
127
+ "capability_markers": [
128
+ "Cascade",
129
+ "windsurfrules",
130
+ "AGENTS.md",
131
+ "always_on",
132
+ "glob",
133
+ "model_decision",
134
+ "workflows",
135
+ "MCP",
136
+ "memories",
137
+ "hooks"
138
+ ],
139
+ "version_probe": null
140
+ },
141
+ {
142
+ "id": "github-copilot",
143
+ "display_name": "GitHub Copilot",
144
+ "kind": "editor",
145
+ "urls": {
146
+ "docs": "https://docs.github.com/en/copilot",
147
+ "release_notes": "https://github.blog/changelog/label/copilot/",
148
+ "changelog": null
149
+ },
150
+ "config_paths": [
151
+ ".github/copilot-instructions.md",
152
+ ".github/instructions/*.instructions.md",
153
+ ".github/prompts/*.prompt.md",
154
+ "AGENTS.md"
155
+ ],
156
+ "our_generators": [
157
+ "scripts/generate_copilot.py"
158
+ ],
159
+ "capability_markers": [
160
+ "copilot-instructions.md",
161
+ "Copilot Chat",
162
+ "Copilot Workspace",
163
+ "Copilot cloud agent",
164
+ "applyTo",
165
+ "custom agents",
166
+ "prompt files",
167
+ "instructions.md",
168
+ "MCP"
169
+ ],
170
+ "version_probe": null
171
+ },
172
+ {
173
+ "id": "gemini-cli",
174
+ "display_name": "Gemini CLI",
175
+ "kind": "editor",
176
+ "urls": {
177
+ "docs": "https://github.com/google-gemini/gemini-cli/tree/main/docs",
178
+ "release_notes": "https://github.com/google-gemini/gemini-cli/releases",
179
+ "changelog": null
180
+ },
181
+ "config_paths": [
182
+ "GEMINI.md",
183
+ ".gemini/settings.json",
184
+ "~/.gemini/settings.json",
185
+ ".gemini/commands/*.toml",
186
+ ".gemini/skills/*/SKILL.md",
187
+ ".agents/skills/*/SKILL.md",
188
+ "~/.gemini/skills/*/SKILL.md",
189
+ ".gemini/extensions/gemini-extension.json"
190
+ ],
191
+ "our_generators": [
192
+ "scripts/generate_gemini.py"
193
+ ],
194
+ "capability_markers": [
195
+ "GEMINI.md",
196
+ "mcpServers",
197
+ "tools",
198
+ "settings.json",
199
+ "BeforeTool",
200
+ "AfterTool",
201
+ "BeforeAgent",
202
+ "AfterAgent",
203
+ "BeforeModel",
204
+ "SessionStart",
205
+ "SessionEnd",
206
+ "Stop",
207
+ "SKILL.md",
208
+ "activate_skill",
209
+ "custom commands",
210
+ "gemini-extension.json"
211
+ ],
212
+ "version_probe": {
213
+ "kind": "command",
214
+ "command": "gemini --version"
215
+ }
216
+ },
217
+ {
218
+ "id": "cline",
219
+ "display_name": "Cline",
220
+ "kind": "editor",
221
+ "urls": {
222
+ "docs": "https://docs.cline.bot",
223
+ "release_notes": "https://github.com/cline/cline/releases",
224
+ "changelog": null
225
+ },
226
+ "config_paths": [
227
+ ".clinerules/*.md",
228
+ ".clinerules/workflows/*.md",
229
+ ".clinerules/hooks/",
230
+ ".cline/skills/",
231
+ "~/.cline/data/settings/cline_mcp_settings.json",
232
+ "~/Documents/Cline/Rules/"
233
+ ],
234
+ "our_generators": [
235
+ "scripts/generate_cline.py",
236
+ "scripts/generate_cline_rules.py"
237
+ ],
238
+ "capability_markers": [
239
+ "clinerules",
240
+ "Plan Mode",
241
+ "Act Mode",
242
+ "MCP",
243
+ "custom modes",
244
+ "workflows",
245
+ "hooks",
246
+ "skills",
247
+ "subagents",
248
+ "conditional rules"
249
+ ],
250
+ "version_probe": null
251
+ },
252
+ {
253
+ "id": "roo-code",
254
+ "display_name": "Roo Code",
255
+ "kind": "editor",
256
+ "urls": {
257
+ "docs": "https://docs.roocode.com",
258
+ "release_notes": "https://github.com/RooCodeInc/Roo-Code/releases",
259
+ "changelog": null
260
+ },
261
+ "config_paths": [
262
+ ".roomodes",
263
+ ".roo/rules/*.md",
264
+ ".roo/rules-{slug}/*.md",
265
+ ".roo/mcp.json",
266
+ "~/.roo/rules/",
267
+ "~/.roo/settings/custom_modes.yaml",
268
+ "~/.roo/settings/mcp_settings.json"
269
+ ],
270
+ "our_generators": [
271
+ "scripts/generate_roo_modes.py",
272
+ "scripts/generate_roo_rules.py"
273
+ ],
274
+ "capability_markers": [
275
+ "roomodes",
276
+ "custom modes",
277
+ "Code Actions",
278
+ "MCP",
279
+ "Orchestrator mode",
280
+ "whenToUse",
281
+ "description",
282
+ "roleDefinition",
283
+ "groups"
284
+ ],
285
+ "version_probe": null
286
+ },
287
+ {
288
+ "id": "aider",
289
+ "display_name": "Aider",
290
+ "kind": "editor",
291
+ "urls": {
292
+ "docs": "https://aider.chat/docs",
293
+ "release_notes": "https://aider.chat/HISTORY.html",
294
+ "changelog": "https://aider.chat/HISTORY.html"
295
+ },
296
+ "config_paths": [
297
+ ".aider.conf.yml",
298
+ "CONVENTIONS.md",
299
+ "~/.aider.conf.yml"
300
+ ],
301
+ "our_generators": [
302
+ "scripts/generate_aider_conf.py",
303
+ "scripts/generate_conventions.py"
304
+ ],
305
+ "capability_markers": [
306
+ ".aider.conf.yml",
307
+ "CONVENTIONS.md",
308
+ "architect",
309
+ "auto-accept-architect",
310
+ "read",
311
+ "lint-cmd",
312
+ "test-cmd",
313
+ "commit-prompt",
314
+ "attribute-co-authored-by",
315
+ "chat-language",
316
+ "commit-language",
317
+ "watch-files",
318
+ "auto-commits"
319
+ ],
320
+ "version_probe": {
321
+ "kind": "command",
322
+ "command": "aider --version"
323
+ }
324
+ },
325
+ {
326
+ "id": "augment",
327
+ "display_name": "Augment",
328
+ "kind": "editor",
329
+ "urls": {
330
+ "docs": "https://docs.augmentcode.com",
331
+ "release_notes": "https://www.augmentcode.com/changelog",
332
+ "changelog": null
333
+ },
334
+ "config_paths": [
335
+ ".augment/rules/*.md",
336
+ ".augment/guidelines.md",
337
+ ".augment/agents/*.md",
338
+ ".augment/commands/*.md",
339
+ ".augment/skills/*/SKILL.md",
340
+ "~/.augment/rules/*.md",
341
+ "~/.augment/agents/*.md",
342
+ "~/.augment/commands/*.md",
343
+ "~/.augment/settings.json",
344
+ "/etc/augment/settings.json"
345
+ ],
346
+ "our_generators": [
347
+ "scripts/generate_augment.py",
348
+ "scripts/generate_augment_rules.py"
349
+ ],
350
+ "capability_markers": [
351
+ ".augment",
352
+ "Agent mode",
353
+ "Next Edit",
354
+ "MCP",
355
+ "context engine",
356
+ "Auggie CLI",
357
+ "always_apply",
358
+ "agent_requested",
359
+ "subagents",
360
+ "custom commands",
361
+ "SKILL.md",
362
+ "PreToolUse",
363
+ "PostToolUse",
364
+ "SessionStart",
365
+ "SessionEnd",
366
+ "Stop",
367
+ "ACP Mode"
368
+ ],
369
+ "version_probe": null
370
+ },
371
+ {
372
+ "id": "google-antigravity",
373
+ "display_name": "Google Antigravity",
374
+ "kind": "editor",
375
+ "urls": {
376
+ "docs": "https://antigravity.google/docs",
377
+ "release_notes": "https://antigravity.google/changelog",
378
+ "changelog": null
379
+ },
380
+ "config_paths": [
381
+ ".agent/rules/*.md",
382
+ ".agent/workflows/*.md",
383
+ ".agent/skills/*/SKILL.md",
384
+ "AGENTS.md",
385
+ "GEMINI.md"
386
+ ],
387
+ "our_generators": [
388
+ "scripts/generate_antigravity.py"
389
+ ],
390
+ "capability_markers": [
391
+ "Antigravity",
392
+ "agent manager",
393
+ "artifacts",
394
+ "MCP",
395
+ "workflows",
396
+ "rules",
397
+ "skills",
398
+ "AGENTS.md",
399
+ "GEMINI.md",
400
+ "agent permissions"
401
+ ],
402
+ "version_probe": null
403
+ },
404
+ {
405
+ "id": "codex-cli",
406
+ "display_name": "Codex CLI",
407
+ "kind": "editor",
408
+ "urls": {
409
+ "docs": "https://github.com/openai/codex",
410
+ "release_notes": "https://github.com/openai/codex/releases",
411
+ "changelog": null
412
+ },
413
+ "config_paths": [
414
+ "AGENTS.md",
415
+ ".agents/rules/*.md",
416
+ ".codex/hooks.json",
417
+ ".codex/skills/*/SKILL.md",
418
+ "~/.codex/config.toml"
419
+ ],
420
+ "our_generators": [
421
+ "scripts/generate_codex.py",
422
+ "scripts/generate_codex_rules.py",
423
+ "scripts/generate_codex_hooks.py"
424
+ ],
425
+ "capability_markers": [
426
+ "AGENTS.md",
427
+ "config.toml",
428
+ "mcp_servers",
429
+ "hooks",
430
+ "sandbox",
431
+ "hook event: PreToolUse",
432
+ "hook event: PostToolUse",
433
+ "hook event: SessionStart",
434
+ "hook event: UserPromptSubmit",
435
+ "hook event: Stop",
436
+ "hook event: PermissionRequest",
437
+ "hook handler: command",
438
+ "hook handler: prompt",
439
+ "hook handler: agent",
440
+ ".codex/skills"
441
+ ],
442
+ "version_probe": {
443
+ "kind": "command",
444
+ "command": "codex --version"
445
+ }
446
+ },
447
+ {
448
+ "id": "opencode",
449
+ "display_name": "opencode",
450
+ "kind": "editor",
451
+ "urls": {
452
+ "docs": "https://opencode.ai/docs",
453
+ "release_notes": "https://github.com/sst/opencode/releases",
454
+ "changelog": null
455
+ },
456
+ "config_paths": [
457
+ "opencode.json",
458
+ ".opencode/agents/*.md",
459
+ ".opencode/commands/*.md",
460
+ ".opencode/plugins/*",
461
+ ".opencode/skills/*/SKILL.md",
462
+ "AGENTS.md",
463
+ ".claude/skills/*/SKILL.md"
464
+ ],
465
+ "our_generators": [
466
+ "scripts/generate_opencode.py",
467
+ "scripts/generate_opencode_agents.py",
468
+ "scripts/generate_opencode_commands.py",
469
+ "scripts/generate_opencode_json.py",
470
+ "scripts/generate_opencode_plugin.py"
471
+ ],
472
+ "capability_markers": [
473
+ "opencode.json",
474
+ "agents",
475
+ "commands",
476
+ "plugins",
477
+ "MCP",
478
+ "rules",
479
+ "AGENTS.md",
480
+ "skills (native .opencode/skills)",
481
+ "skills (via .claude/skills fallback)",
482
+ "permission.skill",
483
+ "subagent mode",
484
+ "primary mode",
485
+ "plugin event: session.created",
486
+ "plugin event: session.compacted",
487
+ "plugin event: session.deleted",
488
+ "plugin event: tool.execute.before",
489
+ "plugin event: tool.execute.after",
490
+ "plugin event: permission.asked",
491
+ "plugin event: command.executed",
492
+ "plugin event: message.updated"
493
+ ],
494
+ "version_probe": {
495
+ "kind": "command",
496
+ "command": "opencode --version"
497
+ }
498
+ }
499
+ ]
500
+ }
@@ -17,9 +17,13 @@ def main() -> None:
17
17
  default_model = DEFAULT_CLAUDE_MODELS["sonnet"]
18
18
  print("# Aider configuration generated by ai-toolkit")
19
19
  print("# Regenerate using: ai-toolkit install --local")
20
+ print("# Aider docs: https://aider.chat/docs/config/aider_conf.html")
20
21
  print()
21
22
  print("# Use the architect mode for complex tasks, aligned with our 2-phase workflow")
22
23
  print("architect: true")
24
+ print("# Auto-accept architect proposals (default: true in aider >=0.82). Set to false")
25
+ print("# if you want to approve every architect-mode edit manually.")
26
+ print("auto-accept-architect: true")
23
27
  print()
24
28
  print("# Read project rules (loaded as read-only context)")
25
29
  print("read:")
@@ -36,16 +40,37 @@ def main() -> None:
36
40
  print(' - "php: ./vendor/bin/phpstan analyse"')
37
41
  print(' - "go: go vet"')
38
42
  print()
43
+ print("# Test commands (uncomment and customize per project). aider >=0.80 supports a")
44
+ print("# single `test-cmd`; run with `--test` or enable `auto-test: true` to run after edits.")
45
+ print("# test-cmd: pytest -q")
46
+ print("# auto-test: false")
47
+ print()
39
48
  print("# Model configuration")
40
49
  print(f"model: {default_model}")
41
50
  print(f"editor-model: {default_model}")
42
51
  print()
43
52
  print("# Auto-commit message formatting (matches our conventional commits)")
44
53
  print(
45
- 'commit_prompt: "Write a short, concise commit message following'
54
+ 'commit-prompt: "Write a short, concise commit message following'
46
55
  ' Conventional Commits (feat/fix/chore/docs/test/refactor)."'
47
56
  )
48
57
  print()
58
+ print("# Git attribution (ai-toolkit policy: no AI co-authorship in commits).")
59
+ print("# Do not flip this to true -- conflicts with the toolkit git-workflow rule")
60
+ print("# (see app/rules/common/git-workflow.md).")
61
+ print("attribute-co-authored-by: false")
62
+ print("attribute-commit-message-author: false")
63
+ print("attribute-commit-message-committer: false")
64
+ print()
65
+ print("# Language settings (aider >=0.83 `commit-language`, >=0.85 confirmed stable).")
66
+ print("# Leave unset to inherit the user's system locale. Uncomment to pin.")
67
+ print("# chat-language: en")
68
+ print("# commit-language: en")
69
+ print()
70
+ print("# Watch-files mode scans for `# AI!` / `# ai?` comments (aider >=0.75). Opt-in")
71
+ print("# because it changes how aider reads your editor buffers.")
72
+ print("# watch-files: false")
73
+ print()
49
74
  print("# Disable auto-commits if you prefer using the /commit slash skill explicitly")
50
75
  print("# auto-commits: false")
51
76
  print()
@@ -1,16 +1,25 @@
1
1
  #!/usr/bin/env python3
2
- """Generate Antigravity IDE .agent/rules/ and .agent/workflows/ files.
2
+ """Generate Antigravity IDE ``.agent/rules/``, ``.agent/workflows/``, and
3
+ skill pointer files.
3
4
 
4
5
  Antigravity reads rules from:
5
- - GEMINI.md (highest priority) — already generated by generate_gemini.py
6
- - AGENTS.md (cross-tool) — already generated by generate_agents_md.py
7
- - .agent/rules/*.md — per-category rule files (this generator)
8
- - .agent/workflows/*.md — workflow templates (this generator)
6
+ * ``GEMINI.md`` (highest priority) — generated by ``generate_gemini.py``
7
+ * ``AGENTS.md`` (cross-tool) — generated by ``generate_agents_md.py``
8
+ * ``.agent/rules/*.md`` — per-category rule files (this generator)
9
+ * ``.agent/workflows/*.md`` — workflow templates (this generator)
10
+
11
+ Antigravity also supports the Agent Skills standard via ``.agent/skills/
12
+ <skill-name>/SKILL.md`` (the changelog entry "Agent Skills now available in
13
+ Antigravity" confirms this surface). We do not duplicate our full skill
14
+ catalogue into ``.agent/skills/``; instead we emit a single pointer skill
15
+ that teaches Antigravity to look up the real catalogue in
16
+ ``~/.softspark/ai-toolkit/app/skills/`` (global install) or
17
+ ``.claude/skills/`` (local install).
9
18
 
10
19
  Usage:
11
20
  python3 scripts/generate_antigravity.py [target-dir]
12
21
 
13
- Writes files directly to target-dir/.agent/rules/ and .agent/workflows/.
22
+ Writes files directly to target-dir/.agent/{rules,workflows,skills}/.
14
23
  """
15
24
  from __future__ import annotations
16
25
 
@@ -25,17 +34,77 @@ from dir_rules_shared import (
25
34
  build_registered_rules,
26
35
  write_rules,
27
36
  )
37
+ from emission import emit_skills_bullets
38
+
39
+
40
+ # ---------------------------------------------------------------------------
41
+ # Skill pointer — a single SKILL.md that directs Antigravity to our catalogue
42
+ # ---------------------------------------------------------------------------
43
+
44
+ POINTER_SKILL_NAME = "ai-toolkit-skill-catalogue"
45
+
28
46
 
47
+ def _pointer_skill_md() -> str:
48
+ """Build the SKILL.md body for the pointer skill."""
49
+ body = (
50
+ "# AI Toolkit Skill Catalogue\n\n"
51
+ "This workspace uses the ai-toolkit. Real skills are installed "
52
+ "alongside Claude Code at `.claude/skills/` (project install) or "
53
+ "`~/.claude/skills/` (global install). If the ai-toolkit installer "
54
+ "has run, every skill below already exists as an agent-invocable "
55
+ "SKILL.md on disk.\n\n"
56
+ "## When to use this skill\n\n"
57
+ "- You are asked to run a task that maps to one of the catalogued "
58
+ "skills below.\n"
59
+ "- You want to discover which skills the user has installed before "
60
+ "reinventing the wheel.\n\n"
61
+ "## How to invoke a catalogue entry\n\n"
62
+ "1. Match the user's task to a skill name in the catalogue.\n"
63
+ "2. Read the skill's SKILL.md from `.claude/skills/<name>/SKILL.md` "
64
+ "or `~/.claude/skills/<name>/SKILL.md` (whichever exists).\n"
65
+ "3. Follow its Rules, Gotchas, and When NOT to Use sections.\n\n"
66
+ "## Catalogue (installed skills)\n\n"
67
+ f"{emit_skills_bullets()}\n"
68
+ )
69
+ return (
70
+ "---\n"
71
+ f"name: {POINTER_SKILL_NAME}\n"
72
+ "description: Index of ai-toolkit skills installed at .claude/skills/"
73
+ " or ~/.claude/skills/. Read this first when the user's request "
74
+ "matches a named skill.\n"
75
+ "---\n"
76
+ f"{body}"
77
+ )
78
+
79
+
80
+ def _write_skill_pointer(target_dir: Path) -> None:
81
+ """Write the pointer SKILL.md under .agent/skills/<name>/."""
82
+ skill_dir = target_dir / ".agent" / "skills" / POINTER_SKILL_NAME
83
+ skill_dir.mkdir(parents=True, exist_ok=True)
84
+ (skill_dir / "SKILL.md").write_text(_pointer_skill_md(), encoding="utf-8")
85
+ print(f" Generated: .agent/skills/{POINTER_SKILL_NAME}/SKILL.md")
86
+
87
+
88
+ # ---------------------------------------------------------------------------
89
+ # Main
90
+ # ---------------------------------------------------------------------------
29
91
 
30
92
  def generate(target_dir: Path, *,
31
93
  language_modules: list[str] | None = None,
32
- rules_dir: Path | None = None) -> None:
33
- """Write .agent/rules/ and .agent/workflows/ files to target_dir."""
94
+ rules_dir: Path | None = None,
95
+ emit_skill_pointer: bool = True) -> None:
96
+ """Write ``.agent/rules/``, ``.agent/workflows/``, and ``.agent/skills/``.
97
+
98
+ ``emit_skill_pointer`` controls whether the pointer SKILL.md is written.
99
+ Set to ``False`` if you manage ``.agent/skills/`` yourself.
100
+ """
34
101
  rules = dict(STANDARD_RULES)
35
102
  rules.update(build_language_rules(language_modules))
36
103
  rules.update(build_registered_rules(rules_dir))
37
104
  write_rules(target_dir, rules, ".agent/rules")
38
105
  write_rules(target_dir, STANDARD_WORKFLOWS, ".agent/workflows")
106
+ if emit_skill_pointer:
107
+ _write_skill_pointer(target_dir)
39
108
 
40
109
 
41
110
  def main() -> None: