@rune-kit/rune 2.1.1 → 2.2.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.
Files changed (157) hide show
  1. package/README.md +40 -34
  2. package/compiler/__tests__/pack-split.test.js +145 -0
  3. package/compiler/adapters/antigravity.js +1 -1
  4. package/compiler/adapters/codex.js +77 -0
  5. package/compiler/adapters/cursor.js +1 -1
  6. package/compiler/adapters/generic.js +1 -1
  7. package/compiler/adapters/index.js +4 -0
  8. package/compiler/adapters/opencode.js +86 -0
  9. package/compiler/adapters/windsurf.js +1 -1
  10. package/compiler/bin/rune.js +10 -7
  11. package/compiler/doctor.js +42 -0
  12. package/compiler/emitter.js +64 -10
  13. package/compiler/parser.js +42 -3
  14. package/compiler/transformer.js +10 -6
  15. package/compiler/transforms/branding.js +1 -1
  16. package/compiler/transforms/compliance.js +40 -0
  17. package/extensions/ai-ml/PACK.md +38 -474
  18. package/extensions/ai-ml/skills/ai-agents.md +172 -0
  19. package/extensions/ai-ml/skills/code-sandbox.md +187 -0
  20. package/extensions/ai-ml/skills/deep-research.md +146 -0
  21. package/extensions/ai-ml/skills/embedding-search.md +66 -0
  22. package/extensions/ai-ml/skills/fine-tuning-guide.md +74 -0
  23. package/extensions/ai-ml/skills/llm-architect.md +125 -0
  24. package/extensions/ai-ml/skills/llm-integration.md +64 -0
  25. package/extensions/ai-ml/skills/prompt-patterns.md +72 -0
  26. package/extensions/ai-ml/skills/rag-patterns.md +66 -0
  27. package/extensions/ai-ml/skills/web-extraction.md +114 -0
  28. package/extensions/analytics/PACK.md +19 -484
  29. package/extensions/analytics/skills/ab-testing.md +72 -0
  30. package/extensions/analytics/skills/dashboard-patterns.md +83 -0
  31. package/extensions/analytics/skills/data-validation.md +68 -0
  32. package/extensions/analytics/skills/funnel-analysis.md +81 -0
  33. package/extensions/analytics/skills/sql-patterns.md +57 -0
  34. package/extensions/analytics/skills/statistical-analysis.md +79 -0
  35. package/extensions/analytics/skills/tracking-setup.md +71 -0
  36. package/extensions/backend/PACK.md +44 -618
  37. package/extensions/backend/skills/api-patterns.md +84 -0
  38. package/extensions/backend/skills/async-pipeline.md +193 -0
  39. package/extensions/backend/skills/auth-patterns.md +97 -0
  40. package/extensions/backend/skills/background-jobs.md +133 -0
  41. package/extensions/backend/skills/caching-patterns.md +108 -0
  42. package/extensions/backend/skills/cli-generation.md +133 -0
  43. package/extensions/backend/skills/database-patterns.md +87 -0
  44. package/extensions/backend/skills/middleware-patterns.md +104 -0
  45. package/extensions/chrome-ext/PACK.md +19 -921
  46. package/extensions/chrome-ext/skills/cws-preflight.md +143 -0
  47. package/extensions/chrome-ext/skills/cws-publish.md +104 -0
  48. package/extensions/chrome-ext/skills/ext-ai-integration.md +251 -0
  49. package/extensions/chrome-ext/skills/ext-messaging.md +139 -0
  50. package/extensions/chrome-ext/skills/ext-storage.md +133 -0
  51. package/extensions/chrome-ext/skills/mv3-scaffold.md +164 -0
  52. package/extensions/content/PACK.md +43 -335
  53. package/extensions/content/skills/blog-patterns.md +88 -0
  54. package/extensions/content/skills/cms-integration.md +131 -0
  55. package/extensions/content/skills/content-scoring.md +107 -0
  56. package/extensions/content/skills/i18n.md +83 -0
  57. package/extensions/content/skills/mdx-authoring.md +137 -0
  58. package/extensions/content/skills/reference.md +1014 -0
  59. package/extensions/content/skills/seo-patterns.md +67 -0
  60. package/extensions/content/skills/video-repurpose.md +153 -0
  61. package/extensions/devops/PACK.md +38 -457
  62. package/extensions/devops/skills/chaos-testing.md +67 -0
  63. package/extensions/devops/skills/ci-cd.md +75 -0
  64. package/extensions/devops/skills/docker.md +58 -0
  65. package/extensions/devops/skills/edge-serverless.md +163 -0
  66. package/extensions/devops/skills/infra-as-code.md +158 -0
  67. package/extensions/devops/skills/kubernetes.md +110 -0
  68. package/extensions/devops/skills/monitoring.md +57 -0
  69. package/extensions/devops/skills/server-setup.md +64 -0
  70. package/extensions/devops/skills/ssl-domain.md +42 -0
  71. package/extensions/ecommerce/PACK.md +62 -226
  72. package/extensions/ecommerce/skills/cart-system.md +79 -0
  73. package/extensions/ecommerce/skills/inventory-mgmt.md +102 -0
  74. package/extensions/ecommerce/skills/order-management.md +126 -0
  75. package/extensions/ecommerce/skills/payment-integration.md +472 -0
  76. package/extensions/ecommerce/skills/shopify-dev.md +69 -0
  77. package/extensions/ecommerce/skills/subscription-billing.md +93 -0
  78. package/extensions/ecommerce/skills/tax-compliance.md +117 -0
  79. package/extensions/gamedev/PACK.md +66 -317
  80. package/extensions/gamedev/skills/asset-pipeline.md +74 -0
  81. package/extensions/gamedev/skills/audio-system.md +129 -0
  82. package/extensions/gamedev/skills/camera-system.md +87 -0
  83. package/extensions/gamedev/skills/ecs.md +98 -0
  84. package/extensions/gamedev/skills/game-loops.md +72 -0
  85. package/extensions/gamedev/skills/input-system.md +199 -0
  86. package/extensions/gamedev/skills/multiplayer.md +180 -0
  87. package/extensions/gamedev/skills/particles.md +105 -0
  88. package/extensions/gamedev/skills/physics-engine.md +89 -0
  89. package/extensions/gamedev/skills/scene-management.md +146 -0
  90. package/extensions/gamedev/skills/threejs-patterns.md +90 -0
  91. package/extensions/gamedev/skills/webgl.md +71 -0
  92. package/extensions/mobile/PACK.md +56 -223
  93. package/extensions/mobile/skills/app-store-connect.md +152 -0
  94. package/extensions/mobile/skills/app-store-prep.md +66 -0
  95. package/extensions/mobile/skills/deep-linking.md +109 -0
  96. package/extensions/mobile/skills/flutter.md +60 -0
  97. package/extensions/mobile/skills/ios-build-pipeline.md +142 -0
  98. package/extensions/mobile/skills/native-bridge.md +66 -0
  99. package/extensions/mobile/skills/ota-updates.md +97 -0
  100. package/extensions/mobile/skills/push-notifications.md +111 -0
  101. package/extensions/mobile/skills/react-native.md +82 -0
  102. package/extensions/saas/PACK.md +26 -720
  103. package/extensions/saas/skills/billing-integration.md +121 -0
  104. package/extensions/saas/skills/feature-flags.md +130 -0
  105. package/extensions/saas/skills/multi-tenant.md +103 -0
  106. package/extensions/saas/skills/onboarding-flow.md +139 -0
  107. package/extensions/saas/skills/subscription-flow.md +95 -0
  108. package/extensions/saas/skills/team-management.md +144 -0
  109. package/extensions/security/PACK.md +10 -448
  110. package/extensions/security/skills/api-security.md +140 -0
  111. package/extensions/security/skills/compliance.md +68 -0
  112. package/extensions/security/skills/owasp-audit.md +64 -0
  113. package/extensions/security/skills/pentest-patterns.md +77 -0
  114. package/extensions/security/skills/secret-mgmt.md +65 -0
  115. package/extensions/security/skills/supply-chain.md +65 -0
  116. package/extensions/trading/PACK.md +18 -535
  117. package/extensions/trading/skills/chart-components.md +55 -0
  118. package/extensions/trading/skills/experiment-loop.md +125 -0
  119. package/extensions/trading/skills/fintech-patterns.md +47 -0
  120. package/extensions/trading/skills/indicator-library.md +58 -0
  121. package/extensions/trading/skills/quant-analysis.md +111 -0
  122. package/extensions/trading/skills/realtime-data.md +58 -0
  123. package/extensions/trading/skills/trade-logic.md +104 -0
  124. package/extensions/ui/PACK.md +34 -853
  125. package/extensions/ui/skills/a11y-audit.md +91 -0
  126. package/extensions/ui/skills/animation-patterns.md +106 -0
  127. package/extensions/ui/skills/component-patterns.md +75 -0
  128. package/extensions/ui/skills/design-decision.md +98 -0
  129. package/extensions/ui/skills/design-system.md +68 -0
  130. package/extensions/ui/skills/landing-patterns.md +155 -0
  131. package/extensions/ui/skills/palette-picker.md +162 -0
  132. package/extensions/ui/skills/react-health.md +90 -0
  133. package/extensions/ui/skills/type-system.md +125 -0
  134. package/extensions/ui/skills/web-vitals.md +153 -0
  135. package/extensions/zalo/PACK.md +117 -0
  136. package/extensions/zalo/skills/zalo-oa-mcp.md +317 -0
  137. package/extensions/zalo/skills/zalo-oa-messaging.md +429 -0
  138. package/extensions/zalo/skills/zalo-oa-setup.md +236 -0
  139. package/extensions/zalo/skills/zalo-oa-webhook.md +189 -0
  140. package/extensions/zalo/skills/zalo-personal-messaging.md +194 -0
  141. package/extensions/zalo/skills/zalo-personal-setup.md +153 -0
  142. package/extensions/zalo/skills/zalo-rate-guard.md +219 -0
  143. package/package.json +5 -2
  144. package/skills/brainstorm/SKILL.md +63 -1
  145. package/skills/cook/SKILL.md +89 -6
  146. package/skills/debug/SKILL.md +5 -0
  147. package/skills/fix/SKILL.md +5 -0
  148. package/skills/mcp-builder/SKILL.md +48 -1
  149. package/skills/neural-memory/SKILL.md +362 -0
  150. package/skills/plan/SKILL.md +3 -0
  151. package/skills/rescue/SKILL.md +5 -0
  152. package/skills/review/SKILL.md +44 -5
  153. package/skills/review-intake/SKILL.md +17 -1
  154. package/skills/skill-router/SKILL.md +106 -8
  155. package/skills/team/SKILL.md +24 -1
  156. package/skills/test/SKILL.md +18 -0
  157. package/skills/verification/SKILL.md +40 -1
package/README.md CHANGED
@@ -2,15 +2,15 @@
2
2
 
3
3
  **Less skills. Deeper connections.**
4
4
 
5
- A lean, interconnected skill ecosystem for AI coding assistants. 55 skills, 200+ mesh connections, full project lifecycle — from idea to production.
5
+ A lean, interconnected skill ecosystem for AI coding assistants. 58 skills, 200+ mesh connections, full project lifecycle — from idea to production.
6
6
 
7
- Works on **Claude Code** (native plugin) · **Cursor** · **Windsurf** · **Google Antigravity** · any AI IDE
7
+ Works on **Claude Code** (native plugin) · **Cursor** · **Windsurf** · **Google Antigravity** · **OpenAI Codex** · **OpenCode** · any AI IDE
8
8
 
9
9
  ## Why Rune?
10
10
 
11
11
  Most skill ecosystems are either **too many isolated skills** (540+ that don't talk to each other) or **rigid pipelines** (A → B → C, if B fails everything stops).
12
12
 
13
- Rune is a **mesh** — 55 skills with 200+ connections across a 5-layer architecture. Skills call each other bidirectionally, forming resilient workflows that adapt when things go wrong.
13
+ Rune is a **mesh** — 58 skills with 200+ connections across a 5-layer architecture. Skills call each other bidirectionally, forming resilient workflows that adapt when things go wrong.
14
14
 
15
15
  ```
16
16
  Pipeline: A → B → C → D (B fails = stuck)
@@ -20,24 +20,23 @@ Mesh: A ↔ B ↔ C (B fails = A reaches C via D→E)
20
20
  D ↔ E ↔ F
21
21
  ```
22
22
 
23
- ## What's New (v2.1.0)
23
+ ## What's New (v2.2.1)
24
24
 
25
- - **Phase-Aware Execution** — cook v0.5.0 resumes multi-session plans automatically. Master plan + phase files = one phase per session, any model executes accurately
26
- - **Amateur-Proof Plans** plan v0.4.0 generates self-contained phase files with data flow diagrams, code contracts, failure scenarios, and rejection criteria. Designed so even the weakest model succeeds
27
- - **Cognitive Bias Detection** — problem-solver v0.3.0 runs mandatory bias checks (12 biases) before every analysis. Reversibility Filter, Pre-Mortem, Weighted Matrix, MECE decomposition
28
- - **Second-Order Thinking** — sequential-thinking v0.3.0 classifies decision reversibility, traces cascading effects, and cross-checks for anchoring/status-quo/overconfidence biases
29
- - **6 New Skills** — ba (business analyst), scaffold (project bootstrap), docs (documentation lifecycle), git (semantic commits), mcp-builder (MCP server generator), doc-processor (PDF/DOCX/XLSX)
30
- - **Multi-Platform Compiler** — all 55 skills compile to Cursor, Windsurf, Antigravity, and generic formats with zero knowledge loss
25
+ - **Enforcement Upgrade** — Antigravity-level IDE compliance: 5-type Request Classifier, File Ownership Matrix, Self-Verification HARD-GATE, Routing Proof, Clarification Gate, Phase Transition Protocol. Distributed via compiler every skill file gets compliance preamble on non-Claude platforms
26
+ - **All 14 Free Packs Deep** every L4 extension pack now exceeds 500 lines of production-ready patterns and code examples
27
+ - **8 Platform Adapters** — Claude Code, Cursor, Windsurf, Google Antigravity, OpenAI Codex, OpenCode, OpenClaw, Generic
28
+ - **58 Core Skills** — +3 since v2.1.0: adversary (red team), sentinel-env (env validation), chrome-ext pack
29
+ - **Rune Pro** — 4 premium packs (product, sales, data-science, support) in private repo. $49 lifetime
31
30
 
32
31
  ## What Rune Is (and Isn't)
33
32
 
34
- Rune started as a **Claude Code plugin** and now compiles to **every major AI IDE**. Same 55 skills, same mesh connections, same workflows — zero knowledge loss across platforms.
33
+ Rune started as a **Claude Code plugin** and now compiles to **every major AI IDE**. Same 58 skills, same mesh connections, same workflows — zero knowledge loss across platforms.
35
34
 
36
35
  | | Rune Provides | Claude Code Provides |
37
36
  |---|---|---|
38
37
  | **Workflows** | 8-phase TDD cycle (cook), parallel DAG execution (team), rescue pipelines | Basic tool calling |
39
38
  | **Quality Gates** | preflight + sentinel + review + completion-gate (parallel) | None built-in |
40
- | **Domain Knowledge** | 12 extension packs (trading, SaaS, mobile, etc.) | General-purpose |
39
+ | **Domain Knowledge** | 14 extension packs (trading, SaaS, mobile, etc.) | General-purpose |
41
40
  | **Cross-Session State** | .rune/ directory (decisions, conventions, progress) | Conversation only |
42
41
  | **Mesh Resilience** | 200+ skill connections, fail-loud-route-around | Linear execution |
43
42
  | **Cost Optimization** | Auto model selection (haiku/sonnet/opus per task) | Single model |
@@ -55,7 +54,7 @@ Rune started as a **Claude Code plugin** and now compiles to **every major AI ID
55
54
  | CI quality gates | `verification` skill: lint + typecheck + tests + build (actual commands, not LLM review) |
56
55
  | Memory / state | `session-bridge` + `journal`: cross-session decisions, conventions, ADRs, module health |
57
56
  | Multi-model strategy | Every skill has assigned model: haiku (scan), sonnet (code), opus (architecture) |
58
- | Agent specialization | 55 specialized skills with dedicated roles (architect, coder, reviewer, scanner, researcher, BA, scaffolder) — each runs as a Task agent via Claude Code |
57
+ | Agent specialization | 58 specialized skills with dedicated roles (architect, coder, reviewer, scanner, researcher, BA, scaffolder) — each runs as a Task agent via Claude Code |
59
58
  | Security scanning | `sentinel`: OWASP patterns, secret scanning, dependency audit. `sast`: static analysis |
60
59
 
61
60
  ## Install
@@ -82,16 +81,16 @@ npx @rune-kit/rune init --platform windsurf
82
81
  npx @rune-kit/rune init --platform antigravity
83
82
  ```
84
83
 
85
- This compiles all 55 skills into your IDE's rules format. Same knowledge, same workflows.
84
+ This compiles all 58 skills into your IDE's rules format. Same knowledge, same workflows.
86
85
 
87
86
  ### Platform Comparison
88
87
 
89
88
  | Feature | Claude Code | Cursor / Windsurf / Others |
90
89
  |---------|-------------|---------------------------|
91
- | Skills available | 55/55 | 55/55 |
90
+ | Skills available | 58/58 | 58/58 |
92
91
  | Mesh connections | 200+ (programmatic) | 200+ (rule references) |
93
92
  | Workflows & HARD-GATEs | Full | Full |
94
- | Extension packs | 12 | 12 |
93
+ | Extension packs | 14 | 14 |
95
94
  | Subagent parallelism | Native | Sequential fallback |
96
95
  | Lifecycle hooks | 8 hooks (JS runtime) | Inline MUST/NEVER constraints |
97
96
  | Adaptive model routing | haiku/sonnet/opus | Single model |
@@ -153,7 +152,7 @@ This compiles all 55 skills into your IDE's rules format. Same knowledge, same w
153
152
  ║ Full lifecycle workflows ║
154
153
  ║ cook │ team │ launch │ rescue │ scaffold ║
155
154
  ╠══════════════════════════════════════════════════════╣
156
- ║ L2: WORKFLOW HUBS (26) ║
155
+ ║ L2: WORKFLOW HUBS (27) ║
157
156
  ║ Cross-hub mesh — the key differentiator ║
158
157
  ║ ║
159
158
  ║ Creation: plan │ scout │ brainstorm │ design │ ║
@@ -164,8 +163,9 @@ This compiles all 55 skills into your IDE's rules format. Same knowledge, same w
164
163
  ║ logic-guardian ║
165
164
  ║ Delivery: deploy │ marketing │ incident │ docs ║
166
165
  ║ Rescue: autopsy │ safeguard │ surgeon ║
166
+ ║ Security: adversary ║
167
167
  ╠══════════════════════════════════════════════════════╣
168
- ║ L3: UTILITIES (23) ║
168
+ ║ L3: UTILITIES (25) ║
169
169
  ║ Stateless, pure capabilities ║
170
170
  ║ ║
171
171
  ║ Knowledge: research │ docs-seeker │ trend-scout ║
@@ -182,14 +182,17 @@ This compiles all 55 skills into your IDE's rules format. Same knowledge, same w
182
182
  ║ Workspace: worktree ║
183
183
  ║ Git: git ║
184
184
  ║ Documents: doc-processor ║
185
+ ║ Security: sentinel-env ║
186
+ ║ Memory: neural-memory ║
185
187
  ╠══════════════════════════════════════════════════════╣
186
- ║ L4: EXTENSION PACKS (12) ║
188
+ ║ L4: EXTENSION PACKS (14) ║
187
189
  ║ Domain-specific, install what you need ║
188
190
  ║ ║
189
191
  ║ @rune/ui │ @rune/backend │ @rune/devops │ ║
190
192
  ║ @rune/mobile │ @rune/security │ @rune/trading │ ║
191
193
  ║ @rune/saas │ @rune/ecommerce │ @rune/ai-ml │ ║
192
- ║ @rune/gamedev │ @rune/content │ @rune/analytics
194
+ ║ @rune/gamedev │ @rune/content │ @rune/analytics
195
+ ║ @rune/chrome-ext │ @rune/zalo ║
193
196
  ╚══════════════════════════════════════════════════════╝
194
197
  ```
195
198
 
@@ -310,8 +313,9 @@ Business department packs for product, sales, and data teams. Same PACK.md forma
310
313
  | @rune-pro/product | feature-spec, roadmap, metrics, release-comms, user-research, competitive | Product Management |
311
314
  | @rune-pro/sales | account-research, call-prep, outreach, pipeline-review, competitive-intel | Sales Enablement |
312
315
  | @rune-pro/data-science | data-exploration, sql-advanced, visualization, statistical-testing, dashboards | Data Science |
316
+ | @rune-pro/support | ticket-triage, response-drafting, knowledge-base, escalation, faq, metrics | Customer Support |
313
317
 
314
- Coming soon. See [docs/plans/RUNE-PRO-PLAN.md](docs/plans/RUNE-PRO-PLAN.md) for the full roadmap.
318
+ **$49 lifetime** (Pro) · **$149 lifetime** (Business). See [docs/plans/RUNE-PRO-PLAN.md](docs/plans/RUNE-PRO-PLAN.md).
315
319
 
316
320
  ## Multi-Platform Compiler
317
321
 
@@ -321,13 +325,14 @@ Rune includes a 3-stage compiler that transforms SKILL.md files into platform-na
321
325
  skills/*.md → PARSE → TRANSFORM → EMIT → platform rules
322
326
  ```
323
327
 
324
- **6 transforms applied per platform:**
325
- 1. Cross-references: `rune:cook` `@rune-cook.mdc` (Cursor) / prose ref (Windsurf)
326
- 2. Tool names: `Read`, `Edit`, `Bash` generic language
327
- 3. Frontmatter: strip Claude Code-specific directives
328
+ **8 transforms applied per platform:**
329
+ 1. Frontmatter: strip Claude Code-specific directives
330
+ 2. Cross-references: `rune:cook` → `@rune-cook.mdc` (Cursor) / prose ref (Windsurf)
331
+ 3. Tool names: `Read`, `Edit`, `Bash` → generic language
328
332
  4. Subagents: parallel → sequential workflow
329
- 5. Hooks: runtime hooks inline MUST/NEVER constraints
330
- 6. Branding: Rune attribution footer
333
+ 5. Compliance: inject enforcement preamble (non-Claude platforms)
334
+ 6. Hooks: runtime hooks → inline MUST/NEVER constraints
335
+ 7. Branding: Rune attribution footer
331
336
 
332
337
  ```bash
333
338
  # Build for any platform
@@ -343,13 +348,14 @@ See [docs/MULTI-PLATFORM.md](docs/MULTI-PLATFORM.md) for the full architecture.
343
348
  ## Numbers
344
349
 
345
350
  ```
346
- Core Skills: 55 (L0: 1 │ L1: 5 │ L2: 26 │ L3: 23)
347
- Extension Packs: 12 free + 3 pro (coming soon)
348
- Mesh Connections: 206 cross-references + 151 tool references
349
- Connections/Skill: 3.7 avg
350
- Platforms: 5 (Claude Code, Cursor, Windsurf, Antigravity, Generic)
351
- Compiler: ~1200 LOC (parser + transforms + adapters + CLI)
352
- Quality: 55/55 skills with Output Format, Sharp Edges, Done When, Cost Profile
351
+ Core Skills: 58 (L0: 1 │ L1: 5 │ L2: 27 │ L3: 25)
352
+ Extension Packs: 14 free + 4 pro + 2 business
353
+ Mesh Connections: 200+ cross-references
354
+ Connections/Skill: 3.4 avg
355
+ Platforms: 8 (Claude Code, Cursor, Windsurf, Antigravity, Codex, OpenCode, OpenClaw, Generic)
356
+ Compiler: ~1400 LOC (parser + 8 transforms + 8 adapters + CLI)
357
+ Quality: 58/58 skills with Output Format, Sharp Edges, Done When, Cost Profile
358
+ Pack Depth: 20 packs total (14 free + 4 pro + 2 business, all free packs rated Deep)
353
359
  ```
354
360
 
355
361
  ## License
@@ -0,0 +1,145 @@
1
+ import { parsePack, parseSkill } from '../parser.js';
2
+ import { test } from 'node:test';
3
+ import assert from 'node:assert';
4
+ import { readFileSync, existsSync } from 'node:fs';
5
+ import path from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
+ const EXTENSIONS_DIR = path.resolve(__dirname, '../../extensions');
10
+
11
+ // --- Monolith format (regression) ---
12
+
13
+ test('parsePack: monolith format has isSplit=false', () => {
14
+ const content = `---
15
+ name: "@rune/trading"
16
+ description: "Trading patterns"
17
+ metadata:
18
+ version: "0.2.0"
19
+ layer: L4
20
+ price: free
21
+ target: Traders
22
+ ---
23
+
24
+ # @rune/trading
25
+
26
+ ## Purpose
27
+ Trading pack.
28
+
29
+ ## Skills Included
30
+
31
+ ### risk-management
32
+ Risk management workflow.
33
+ `;
34
+
35
+ const parsed = parsePack(content, 'extensions/trading/PACK.md');
36
+
37
+ assert.strictEqual(parsed.isSplit, false);
38
+ assert.deepStrictEqual(parsed.skillManifest, []);
39
+ assert.strictEqual(parsed.name, '@rune/trading');
40
+ assert.strictEqual(parsed.version, '0.2.0');
41
+ assert.strictEqual(parsed.layer, 'L4');
42
+ assert.ok(parsed.body.includes('risk-management'));
43
+ });
44
+
45
+ test('parsePack: monolith without metadata block defaults correctly', () => {
46
+ const content = `---
47
+ name: "@rune/test"
48
+ description: "Test pack"
49
+ ---
50
+
51
+ # @rune/test
52
+ Body here.
53
+ `;
54
+
55
+ const parsed = parsePack(content, 'test/PACK.md');
56
+
57
+ assert.strictEqual(parsed.isSplit, false);
58
+ assert.strictEqual(parsed.version, '1.0.0');
59
+ });
60
+
61
+ // --- Split format detection ---
62
+
63
+ test('parsePack: split format detected via metadata.format', () => {
64
+ const content = `---
65
+ name: "@rune/backend"
66
+ description: "Backend patterns"
67
+ metadata:
68
+ version: "0.3.0"
69
+ layer: L4
70
+ price: free
71
+ target: Backend developers
72
+ format: split
73
+ ---
74
+
75
+ # @rune/backend
76
+
77
+ ## Purpose
78
+ Backend pack index.
79
+
80
+ ## Skills Included
81
+ | Skill | Model | Description |
82
+ |-------|-------|-------------|
83
+ | api-design | sonnet | API patterns |
84
+ | auth | sonnet | Auth patterns |
85
+ `;
86
+
87
+ const parsed = parsePack(content, 'extensions/backend/PACK.md');
88
+
89
+ assert.strictEqual(parsed.isSplit, true);
90
+ assert.strictEqual(parsed.version, '0.3.0');
91
+ assert.strictEqual(parsed.name, '@rune/backend');
92
+ });
93
+
94
+ test('parsePack: skill manifest parsed from string array', () => {
95
+ // Note: our YAML parser is simple — it handles nested objects but not arrays.
96
+ // This test validates the parseSkillManifest function directly with object skills.
97
+ const content = `---
98
+ name: "@rune/test"
99
+ description: "Test"
100
+ metadata:
101
+ format: split
102
+ ---
103
+
104
+ Body.
105
+ `;
106
+
107
+ const parsed = parsePack(content, 'test/PACK.md');
108
+ assert.strictEqual(parsed.isSplit, true);
109
+ // With simple YAML parser, skills array won't parse — manifest will be empty
110
+ // Real usage will use the skills/ directory detection as fallback
111
+ assert.ok(Array.isArray(parsed.skillManifest));
112
+ });
113
+
114
+ // --- Real pack regression: existing monolith packs parse correctly ---
115
+
116
+ test('parsePack: real trading PACK.md parses as split', () => {
117
+ const tradingPath = path.join(EXTENSIONS_DIR, 'trading', 'PACK.md');
118
+ if (!existsSync(tradingPath)) {
119
+ console.log(' skip: trading PACK.md not found');
120
+ return;
121
+ }
122
+
123
+ const content = readFileSync(tradingPath, 'utf-8');
124
+ const parsed = parsePack(content, tradingPath);
125
+
126
+ assert.strictEqual(parsed.isSplit, true);
127
+ assert.strictEqual(parsed.layer, 'L4');
128
+ assert.strictEqual(parsed.group, 'extension');
129
+ assert.ok(parsed.body.length > 50);
130
+ });
131
+
132
+ test('parsePack: real backend PACK.md parses as split (post-split)', () => {
133
+ const backendPath = path.join(EXTENSIONS_DIR, 'backend', 'PACK.md');
134
+ if (!existsSync(backendPath)) {
135
+ console.log(' skip: backend PACK.md not found');
136
+ return;
137
+ }
138
+
139
+ const content = readFileSync(backendPath, 'utf-8');
140
+ const parsed = parsePack(content, backendPath);
141
+
142
+ assert.strictEqual(parsed.isSplit, true);
143
+ assert.strictEqual(parsed.layer, 'L4');
144
+ assert.ok(parsed.sections.size > 0);
145
+ });
@@ -41,7 +41,7 @@ export default {
41
41
  return [
42
42
  '',
43
43
  '---',
44
- '> **Rune Skill Mesh** — 49 skills, 170+ connections',
44
+ '> **Rune Skill Mesh** — 58 skills, 200+ connections',
45
45
  '> Source: https://github.com/rune-kit/rune',
46
46
  '> Full experience with subagents, hooks, adaptive routing → use Rune on Claude Code.',
47
47
  ].join('\n');
@@ -0,0 +1,77 @@
1
+ /**
2
+ * OpenAI Codex Adapter
3
+ *
4
+ * Emits SKILL.md files into .codex/skills/{name}/ directories.
5
+ * Codex uses the same SKILL.md frontmatter format (name, description)
6
+ * with markdown body — very close to Rune's native format.
7
+ *
8
+ * Codex project context: AGENTS.md (equivalent to CLAUDE.md)
9
+ * Codex skills dir: .codex/skills/
10
+ * Codex skill format: .codex/skills/{name}/SKILL.md
11
+ */
12
+
13
+ const TOOL_MAP = {
14
+ Read: 'read the file',
15
+ Write: 'write/create the file',
16
+ Edit: 'edit the file',
17
+ Glob: 'find files by pattern',
18
+ Grep: 'search file contents',
19
+ Bash: 'run a shell command',
20
+ TodoWrite: 'track task progress',
21
+ Skill: 'follow the referenced skill',
22
+ Agent: 'execute the workflow',
23
+ };
24
+
25
+ export default {
26
+ name: 'codex',
27
+ outputDir: '.codex/skills',
28
+ fileExtension: '.md',
29
+ skillPrefix: 'rune-',
30
+ skillSuffix: '',
31
+
32
+ // Codex uses directory-per-skill: .codex/skills/{name}/SKILL.md
33
+ useSkillDirectories: true,
34
+ skillFileName: 'SKILL.md',
35
+
36
+ transformReference(skillName, raw) {
37
+ const isBackticked = raw.startsWith('`') && raw.endsWith('`');
38
+ const ref = `the rune-${skillName} skill`;
39
+ return isBackticked ? `\`${ref}\`` : ref;
40
+ },
41
+
42
+ transformToolName(toolName) {
43
+ return TOOL_MAP[toolName] || toolName;
44
+ },
45
+
46
+ generateHeader(skill) {
47
+ const desc = (skill.description || '').replace(/"/g, '\\"');
48
+ return [
49
+ '---',
50
+ `name: rune-${skill.name}`,
51
+ `description: "${desc}"`,
52
+ '---',
53
+ '',
54
+ '',
55
+ ].join('\n');
56
+ },
57
+
58
+ generateFooter() {
59
+ return [
60
+ '',
61
+ '---',
62
+ '> **Rune Skill Mesh** — 58 skills, 200+ connections',
63
+ '> Source: https://github.com/rune-kit/rune',
64
+ '> Full experience with subagents, hooks, adaptive routing → use Rune on Claude Code.',
65
+ ].join('\n');
66
+ },
67
+
68
+ transformSubagentInstruction(text) {
69
+ return text;
70
+ },
71
+
72
+ postProcess(content) {
73
+ return content
74
+ .replace(/^context: fork\n/gm, '')
75
+ .replace(/^agent: general-purpose\n/gm, '');
76
+ },
77
+ };
@@ -49,7 +49,7 @@ export default {
49
49
  return [
50
50
  '',
51
51
  '---',
52
- '> **Rune Skill Mesh** — 49 skills, 170+ connections',
52
+ '> **Rune Skill Mesh** — 58 skills, 200+ connections',
53
53
  '> Source: https://github.com/rune-kit/rune',
54
54
  '> Full experience with subagents, hooks, adaptive routing → use Rune on Claude Code.',
55
55
  ].join('\n');
@@ -42,7 +42,7 @@ export default {
42
42
  return [
43
43
  '',
44
44
  '---',
45
- '> **Rune Skill Mesh** — 49 skills, 170+ connections',
45
+ '> **Rune Skill Mesh** — 58 skills, 200+ connections',
46
46
  '> Source: https://github.com/rune-kit/rune',
47
47
  '> Full experience with subagents, hooks, adaptive routing → use Rune on Claude Code.',
48
48
  ].join('\n');
@@ -10,6 +10,8 @@ import windsurf from './windsurf.js';
10
10
  import antigravity from './antigravity.js';
11
11
  import generic from './generic.js';
12
12
  import openclaw from './openclaw.js';
13
+ import codex from './codex.js';
14
+ import opencode from './opencode.js';
13
15
 
14
16
  const adapters = {
15
17
  claude,
@@ -18,6 +20,8 @@ const adapters = {
18
20
  antigravity,
19
21
  generic,
20
22
  openclaw,
23
+ codex,
24
+ opencode,
21
25
  };
22
26
 
23
27
  /**
@@ -0,0 +1,86 @@
1
+ /**
2
+ * OpenCode Adapter
3
+ *
4
+ * Emits SKILL.md files into .opencode/skills/{name}/ directories.
5
+ * OpenCode uses the same SKILL.md frontmatter format (name, description)
6
+ * with markdown body — identical to Codex pattern.
7
+ *
8
+ * OpenCode project context: AGENTS.md (+ CLAUDE.md fallback)
9
+ * OpenCode skills dir: .opencode/skills/
10
+ * OpenCode skill format: .opencode/skills/{name}/SKILL.md
11
+ * OpenCode agents dir: .opencode/agents/
12
+ *
13
+ * OpenCode also searches:
14
+ * .claude/skills/{name}/SKILL.md (Claude-compatible)
15
+ * .agents/skills/{name}/SKILL.md (agent-compatible)
16
+ *
17
+ * @see https://opencode.ai/docs/skills/
18
+ * @see https://opencode.ai/docs/agents/
19
+ */
20
+
21
+ const TOOL_MAP = {
22
+ Read: 'read the file',
23
+ Write: 'write/create the file',
24
+ Edit: 'edit the file',
25
+ Glob: 'find files by pattern',
26
+ Grep: 'search file contents',
27
+ Bash: 'run a shell command',
28
+ TodoWrite: 'track task progress',
29
+ Skill: 'invoke the named skill',
30
+ Agent: 'delegate to a subagent',
31
+ };
32
+
33
+ export default {
34
+ name: 'opencode',
35
+ outputDir: '.opencode/skills',
36
+ fileExtension: '.md',
37
+ skillPrefix: 'rune-',
38
+ skillSuffix: '',
39
+
40
+ // OpenCode uses directory-per-skill: .opencode/skills/{name}/SKILL.md
41
+ useSkillDirectories: true,
42
+ skillFileName: 'SKILL.md',
43
+
44
+ transformReference(skillName, raw) {
45
+ const isBackticked = raw.startsWith('`') && raw.endsWith('`');
46
+ const ref = `the rune-${skillName} skill`;
47
+ return isBackticked ? `\`${ref}\`` : ref;
48
+ },
49
+
50
+ transformToolName(toolName) {
51
+ return TOOL_MAP[toolName] || toolName;
52
+ },
53
+
54
+ generateHeader(skill) {
55
+ const desc = (skill.description || '').replace(/"/g, '\\"');
56
+ return [
57
+ '---',
58
+ `name: rune-${skill.name}`,
59
+ `description: "${desc}"`,
60
+ '---',
61
+ '',
62
+ '',
63
+ ].join('\n');
64
+ },
65
+
66
+ generateFooter() {
67
+ return [
68
+ '',
69
+ '---',
70
+ '> **Rune Skill Mesh** — 58 skills, 200+ connections',
71
+ '> Source: https://github.com/rune-kit/rune',
72
+ '> Full experience with subagents, hooks, adaptive routing → use Rune on Claude Code.',
73
+ ].join('\n');
74
+ },
75
+
76
+ transformSubagentInstruction(text) {
77
+ // OpenCode has native subagent support — preserve parallel agent instructions
78
+ return text;
79
+ },
80
+
81
+ postProcess(content) {
82
+ return content
83
+ .replace(/^context: fork\n/gm, '')
84
+ .replace(/^agent: general-purpose\n/gm, '');
85
+ },
86
+ };
@@ -42,7 +42,7 @@ export default {
42
42
  return [
43
43
  '',
44
44
  '---',
45
- '> **Rune Skill Mesh** — 49 skills, 170+ connections',
45
+ '> **Rune Skill Mesh** — 58 skills, 200+ connections',
46
46
  '> Source: https://github.com/rune-kit/rune',
47
47
  '> Full experience with subagents, hooks, adaptive routing → use Rune on Claude Code.',
48
48
  ].join('\n');
@@ -46,14 +46,11 @@ function detectPlatform(projectRoot) {
46
46
  if (existsSync(path.join(projectRoot, '.windsurf'))) return 'windsurf';
47
47
  if (existsSync(path.join(projectRoot, '.agent'))) return 'antigravity';
48
48
  if (existsSync(path.join(projectRoot, '.openclaw'))) return 'openclaw';
49
+ if (existsSync(path.join(projectRoot, '.codex'))) return 'codex';
50
+ if (existsSync(path.join(projectRoot, '.opencode'))) return 'opencode';
49
51
  return null;
50
52
  }
51
53
 
52
- function discoverExtensions() {
53
- const extDir = path.join(RUNE_ROOT, 'extensions');
54
- if (!existsSync(extDir)) return [];
55
- return [];
56
- }
57
54
 
58
55
  async function prompt(question) {
59
56
  const rl = createInterface({ input: process.stdin, output: process.stdout });
@@ -159,7 +156,7 @@ async function cmdBuild(projectRoot, args) {
159
156
 
160
157
  const adapter = getAdapter(platform);
161
158
  const runeRoot = config?.source || RUNE_ROOT;
162
- const outputRoot = args.output || projectRoot;
159
+ const outputRoot = typeof args.output === 'string' ? args.output : projectRoot;
163
160
  const disabledSkills = config?.skills?.disabled || [];
164
161
  const enabledPacks = config?.extensions?.enabled || null;
165
162
 
@@ -220,6 +217,9 @@ async function cmdDoctor(projectRoot, args) {
220
217
 
221
218
  // ─── Arg Parsing ───
222
219
 
220
+ // Flags that require a string value (not boolean)
221
+ const VALUE_REQUIRED_FLAGS = new Set(['platform', 'output', 'disable', 'extensions']);
222
+
223
223
  function parseArgs(argv) {
224
224
  const args = {};
225
225
  const positional = [];
@@ -232,6 +232,9 @@ function parseArgs(argv) {
232
232
  if (next && !next.startsWith('--')) {
233
233
  args[key] = next;
234
234
  i++;
235
+ } else if (VALUE_REQUIRED_FLAGS.has(key)) {
236
+ log(` ✗ Flag --${key} requires a value. Example: --${key} <value>`);
237
+ process.exit(1);
235
238
  } else {
236
239
  args[key] = true;
237
240
  }
@@ -271,7 +274,7 @@ async function main() {
271
274
  log(' doctor Validate compiled output');
272
275
  log('');
273
276
  log(' Options:');
274
- log(' --platform <name> Override platform (cursor, windsurf, antigravity, openclaw, generic)');
277
+ log(' --platform <name> Override platform (cursor, windsurf, antigravity, codex, openclaw, opencode, generic)');
275
278
  log(' --output <dir> Override output directory');
276
279
  log(' --disable <skills> Comma-separated skills to disable');
277
280
  log('');
@@ -7,6 +7,7 @@
7
7
  import { readdir, readFile, stat } from 'node:fs/promises';
8
8
  import { existsSync } from 'node:fs';
9
9
  import path from 'node:path';
10
+ import { parsePack } from './parser.js';
10
11
 
11
12
  /**
12
13
  * Run doctor checks on compiled output
@@ -89,6 +90,18 @@ export async function runDoctor({ outputRoot, adapter, config, runeRoot }) {
89
90
  results.warnings.push(`${disabled.length} skills disabled: ${disabled.join(', ')}`);
90
91
  }
91
92
 
93
+ // Check 7: Split pack integrity (validate skill manifest files exist)
94
+ const extensionsDir = path.join(runeRoot, 'extensions');
95
+ if (existsSync(extensionsDir)) {
96
+ const splitPackErrors = await checkSplitPacks(extensionsDir);
97
+ if (splitPackErrors.length === 0) {
98
+ results.checks.push({ name: 'Split packs', status: 'pass' });
99
+ } else {
100
+ results.checks.push({ name: 'Split packs', status: 'fail', detail: `${splitPackErrors.length} missing skill files` });
101
+ results.errors.push(...splitPackErrors);
102
+ }
103
+ }
104
+
92
105
  if (results.errors.length > 0) results.healthy = false;
93
106
 
94
107
  return results;
@@ -119,6 +132,35 @@ async function checkCrossRefs(outputDir, files, adapter) {
119
132
  return [...new Set(errors)]; // deduplicate
120
133
  }
121
134
 
135
+ /**
136
+ * Check that all split packs have their declared skill files present
137
+ */
138
+ async function checkSplitPacks(extensionsDir) {
139
+ const errors = [];
140
+ const entries = await readdir(extensionsDir, { withFileTypes: true });
141
+
142
+ for (const entry of entries) {
143
+ if (!entry.isDirectory()) continue;
144
+ const packFile = path.join(extensionsDir, entry.name, 'PACK.md');
145
+ if (!existsSync(packFile)) continue;
146
+
147
+ const content = await readFile(packFile, 'utf-8');
148
+ const parsed = parsePack(content, packFile);
149
+
150
+ if (!parsed.isSplit) continue;
151
+
152
+ const packDir = path.dirname(packFile);
153
+ for (const skill of parsed.skillManifest) {
154
+ const skillPath = path.join(packDir, skill.file);
155
+ if (!existsSync(skillPath)) {
156
+ errors.push(`@rune/${entry.name}: skill file "${skill.file}" declared in manifest but not found`);
157
+ }
158
+ }
159
+ }
160
+
161
+ return errors;
162
+ }
163
+
122
164
  /**
123
165
  * Format doctor results for console output
124
166
  */