@cleocode/skills 2026.9.21 → 2026.9.22

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 (151) hide show
  1. package/README.md +46 -63
  2. package/frontmatter.d.mts +60 -0
  3. package/frontmatter.mjs +277 -0
  4. package/index.d.ts +3 -3
  5. package/index.js +34 -9
  6. package/package.json +4 -2
  7. package/profiles/core.json +10 -3
  8. package/profiles/full.json +10 -6
  9. package/profiles/recommended.json +29 -3
  10. package/skills/_shared/manifest-operations.md +19 -40
  11. package/skills/_shared/skill-chaining-patterns.md +5 -9
  12. package/skills/_shared/subagent-protocol-base.md +6 -6
  13. package/skills/_shared/task-system-integration.md +5 -5
  14. package/skills/ct-adr-recorder/SKILL.md +18 -17
  15. package/skills/ct-artifact-publisher/SKILL.md +10 -7
  16. package/skills/ct-cleo/SKILL.md +25 -8
  17. package/skills/ct-cleo/references/loom-lifecycle.md +1 -1
  18. package/skills/{ct-memory/SKILL.md → ct-cleo/references/memory.md} +10 -23
  19. package/skills/ct-cleo/references/orchestrator-constraints.md +5 -5
  20. package/skills/ct-cleo/references/session-protocol.md +11 -8
  21. package/skills/{ct-stickynote/SKILL.md → ct-cleo/references/sticky-notes.md} +7 -29
  22. package/skills/ct-codebase-mapper/SKILL.md +62 -38
  23. package/skills/ct-consensus-voter/SKILL.md +10 -7
  24. package/skills/ct-contribution/SKILL.md +7 -5
  25. package/skills/ct-dev-workflow/SKILL.md +7 -7
  26. package/skills/ct-documentor/SKILL.md +29 -29
  27. package/skills/{ct-docs-review/__tests__/skill-docs-review.test.ts → ct-documentor/__tests__/reviewing-reference.test.ts} +4 -3
  28. package/skills/{ct-docs-write/__tests__/skill-docs-write.test.ts → ct-documentor/__tests__/writing-reference.test.ts} +4 -3
  29. package/skills/ct-documentor/references/anti-patterns.md +8 -8
  30. package/skills/{ct-docs-write → ct-documentor}/references/audience-targeting.md +5 -5
  31. package/skills/ct-documentor/references/chain-orchestration.md +19 -19
  32. package/skills/{ct-docs-write → ct-documentor}/references/cleo-style-guide.md +1 -1
  33. package/skills/ct-documentor/references/doc-types-and-templates.md +1 -1
  34. package/skills/{ct-docs-review → ct-documentor}/references/pr-review-mode.md +1 -1
  35. package/skills/{ct-docs-review/SKILL.md → ct-documentor/references/reviewing.md} +6 -26
  36. package/skills/ct-documentor/references/style-coordination.md +5 -5
  37. package/skills/{ct-docs-review → ct-documentor}/references/style-violations.md +1 -1
  38. package/skills/{ct-docs-write/SKILL.md → ct-documentor/references/writing.md} +5 -25
  39. package/skills/ct-epic-architect/SKILL.md +12 -9
  40. package/skills/ct-epic-architect/references/commands.md +5 -5
  41. package/skills/ct-epic-architect/references/output-format.md +2 -2
  42. package/skills/ct-epic-architect/references/patterns.md +2 -2
  43. package/skills/ct-epic-architect/references/skill-aware-execution.md +3 -3
  44. package/skills/ct-grade/SKILL.md +3 -4
  45. package/skills/ct-grade/agents/scenario-runner.md +1 -1
  46. package/skills/ct-ivt-looper/SKILL.md +23 -22
  47. package/skills/ct-lead/SKILL.md +45 -13
  48. package/skills/ct-lead/references/aggregation-protocol.md +44 -21
  49. package/skills/ct-lead/references/spawn-pattern.md +12 -11
  50. package/skills/ct-orchestrator/README.md +2 -2
  51. package/skills/ct-orchestrator/SKILL.md +14 -10
  52. package/skills/ct-orchestrator/references/SUBAGENT-PROTOCOL-BLOCK.md +4 -4
  53. package/skills/ct-orchestrator/references/autonomous-operation.md +4 -4
  54. package/skills/ct-orchestrator/references/orchestrator-compliance.md +3 -3
  55. package/skills/ct-orchestrator/references/orchestrator-patterns.md +20 -19
  56. package/skills/ct-orchestrator/references/orchestrator-recovery.md +13 -23
  57. package/skills/ct-orchestrator/references/orchestrator-spawning.md +9 -10
  58. package/skills/ct-orchestrator/references/orchestrator-tokens.md +9 -9
  59. package/skills/ct-provenance-keeper/SKILL.md +10 -7
  60. package/skills/ct-release-orchestrator/SKILL.md +21 -13
  61. package/skills/ct-release-orchestrator/references/composition.md +1 -1
  62. package/skills/ct-release-orchestrator/references/release-types.md +33 -15
  63. package/skills/ct-research-agent/SKILL.md +14 -12
  64. package/skills/ct-research-agent/references/triggers-and-routing.md +4 -4
  65. package/skills/{ct-skill-creator → ct-skill-author}/SKILL.md +9 -6
  66. package/skills/{ct-skill-validator → ct-skill-author}/agents/ecosystem-checker.md +1 -1
  67. package/skills/{ct-skill-validator → ct-skill-author}/evals/quality_evals.json +10 -10
  68. package/skills/{ct-skill-validator → ct-skill-author}/evals/trigger_queries.json +1 -1
  69. package/skills/{ct-skill-validator → ct-skill-author}/references/cleo-ecosystem-rules.md +8 -4
  70. package/skills/{ct-skill-creator → ct-skill-author}/references/provider-deployment.md +10 -6
  71. package/skills/{ct-skill-validator/SKILL.md → ct-skill-author/references/validating.md} +14 -21
  72. package/skills/{ct-skill-validator → ct-skill-author}/references/validation-rules.md +2 -2
  73. package/skills/{ct-skill-validator → ct-skill-author}/scripts/_skill_finder.py +2 -2
  74. package/skills/{ct-skill-validator → ct-skill-author}/scripts/check_depth.py +2 -5
  75. package/skills/{ct-skill-validator → ct-skill-author}/scripts/generate_validation_report.py +1 -1
  76. package/skills/{ct-skill-validator → ct-skill-author}/scripts/run_quality_eval.py +2 -2
  77. package/skills/ct-spec-writer/SKILL.md +9 -7
  78. package/skills/ct-task-executor/SKILL.md +19 -16
  79. package/skills/ct-task-executor/references/common-failures.md +1 -1
  80. package/skills/ct-validator/SKILL.md +11 -9
  81. package/skills/ct-validator/references/compliance-reports.md +1 -1
  82. package/skills/ct-validator/references/validation-modes.md +3 -3
  83. package/skills/manifest.json +381 -365
  84. package/dispatch-config.json +0 -983
  85. package/provider-skills-map.json +0 -97
  86. package/skills/ct-docs-lookup/SKILL.md +0 -185
  87. package/skills/ct-docs-lookup/references/ctx7-workflow.md +0 -198
  88. package/skills/ct-docs-lookup/references/library-id-resolution.md +0 -217
  89. package/skills/ct-docs-lookup/references/version-specific-docs.md +0 -220
  90. package/skills/ct-master-tac/SKILL.md +0 -120
  91. package/skills/ct-master-tac/__tests__/install.test.ts +0 -304
  92. package/skills/ct-master-tac/bundled/README.md +0 -40
  93. package/skills/ct-master-tac/bundled/protocols/architecture-decision.cant +0 -90
  94. package/skills/ct-master-tac/bundled/protocols/artifact-publish.cant +0 -105
  95. package/skills/ct-master-tac/bundled/protocols/consensus.cant +0 -85
  96. package/skills/ct-master-tac/bundled/protocols/contribution.cant +0 -92
  97. package/skills/ct-master-tac/bundled/protocols/decomposition.cant +0 -102
  98. package/skills/ct-master-tac/bundled/protocols/implementation.cant +0 -77
  99. package/skills/ct-master-tac/bundled/protocols/provenance.cant +0 -100
  100. package/skills/ct-master-tac/bundled/protocols/release.cant +0 -107
  101. package/skills/ct-master-tac/bundled/protocols/research.cant +0 -77
  102. package/skills/ct-master-tac/bundled/protocols/specification.cant +0 -77
  103. package/skills/ct-master-tac/bundled/protocols/testing.cant +0 -99
  104. package/skills/ct-master-tac/bundled/protocols/validation.cant +0 -75
  105. package/skills/ct-master-tac/bundled/teams/platform.cant +0 -115
  106. package/skills/ct-master-tac/manifest.json +0 -55
  107. package/skills/ct-skill-creator/eval-viewer/__pycache__/generate_review.cpython-314.pyc +0 -0
  108. package/skills/ct-skill-creator/manifest-entry.json +0 -17
  109. package/skills/ct-skill-creator/scripts/__pycache__/__init__.cpython-314.pyc +0 -0
  110. package/skills/ct-skill-creator/scripts/__pycache__/aggregate_benchmark.cpython-314.pyc +0 -0
  111. package/skills/ct-skill-creator/scripts/__pycache__/generate_report.cpython-314.pyc +0 -0
  112. package/skills/ct-skill-creator/scripts/__pycache__/improve_description.cpython-314.pyc +0 -0
  113. package/skills/ct-skill-creator/scripts/__pycache__/init_skill.cpython-314.pyc +0 -0
  114. package/skills/ct-skill-creator/scripts/__pycache__/quick_validate.cpython-314.pyc +0 -0
  115. package/skills/ct-skill-creator/scripts/__pycache__/run_eval.cpython-314.pyc +0 -0
  116. package/skills/ct-skill-creator/scripts/__pycache__/run_loop.cpython-314.pyc +0 -0
  117. package/skills/ct-skill-creator/scripts/__pycache__/utils.cpython-314.pyc +0 -0
  118. package/skills/ct-skill-validator/manifest-entry.json +0 -20
  119. package/skills/ct-stickynote/README.md +0 -14
  120. package/skills/signaldock-connect/SKILL.md +0 -137
  121. package/skills/signaldock-connect/assets/agent-card.json +0 -48
  122. package/skills/signaldock-connect/references/api-endpoints.md +0 -131
  123. package/skills.json +0 -495
  124. /package/skills/{ct-docs-review → ct-documentor}/references/inline-comment-patterns.md +0 -0
  125. /package/skills/{ct-docs-write → ct-documentor}/references/markdown-patterns.md +0 -0
  126. /package/skills/{ct-skill-creator → ct-skill-author}/agents/analyzer.md +0 -0
  127. /package/skills/{ct-skill-creator → ct-skill-author}/agents/comparator.md +0 -0
  128. /package/skills/{ct-skill-creator → ct-skill-author}/agents/grader.md +0 -0
  129. /package/skills/{ct-skill-creator → ct-skill-author}/assets/eval_review.html +0 -0
  130. /package/skills/{ct-skill-validator → ct-skill-author}/assets/valid-skill-example.md +0 -0
  131. /package/skills/{ct-skill-creator → ct-skill-author}/eval-viewer/generate_review.py +0 -0
  132. /package/skills/{ct-skill-creator → ct-skill-author}/eval-viewer/viewer.html +0 -0
  133. /package/skills/{ct-skill-creator → ct-skill-author}/references/dynamic-context.md +0 -0
  134. /package/skills/{ct-skill-creator → ct-skill-author}/references/frontmatter.md +0 -0
  135. /package/skills/{ct-skill-creator → ct-skill-author}/references/invocation-control.md +0 -0
  136. /package/skills/{ct-skill-creator → ct-skill-author}/references/output-patterns.md +0 -0
  137. /package/skills/{ct-skill-creator → ct-skill-author}/references/schemas.md +0 -0
  138. /package/skills/{ct-skill-creator → ct-skill-author}/references/workflows.md +0 -0
  139. /package/skills/{ct-skill-creator → ct-skill-author}/scripts/__init__.py +0 -0
  140. /package/skills/{ct-skill-creator → ct-skill-author}/scripts/aggregate_benchmark.py +0 -0
  141. /package/skills/{ct-skill-validator → ct-skill-author}/scripts/audit_body.py +0 -0
  142. /package/skills/{ct-skill-validator → ct-skill-author}/scripts/check_ecosystem.py +0 -0
  143. /package/skills/{ct-skill-creator → ct-skill-author}/scripts/generate_report.py +0 -0
  144. /package/skills/{ct-skill-creator → ct-skill-author}/scripts/improve_description.py +0 -0
  145. /package/skills/{ct-skill-creator → ct-skill-author}/scripts/init_skill.py +0 -0
  146. /package/skills/{ct-skill-creator → ct-skill-author}/scripts/package_skill.py +0 -0
  147. /package/skills/{ct-skill-creator → ct-skill-author}/scripts/quick_validate.py +0 -0
  148. /package/skills/{ct-skill-creator → ct-skill-author}/scripts/run_eval.py +0 -0
  149. /package/skills/{ct-skill-creator → ct-skill-author}/scripts/run_loop.py +0 -0
  150. /package/skills/{ct-skill-creator → ct-skill-author}/scripts/utils.py +0 -0
  151. /package/skills/{ct-skill-validator → ct-skill-author}/scripts/validate.py +0 -0
package/README.md CHANGED
@@ -31,69 +31,52 @@ yarn add @cleocode/skills
31
31
 
32
32
  ## Included Skills
33
33
 
34
- ### Core Skills
35
-
36
- | Skill | Purpose | Description |
37
- |-------|---------|-------------|
38
- | **ct-codebase-mapper** | Analysis | Maps project structure, stack, and architecture |
39
- | **ct-memory** | Memory | Manages persistent knowledge storage and retrieval |
40
- | **ct-orchestrator** | Orchestration | Coordinates multi-agent workflows and spawning |
41
- | **ct-task-executor** | Execution | General task execution with protocol compliance |
42
- | **ct-validator** | Validation | Validates compliance against rules and schemas |
43
-
44
- ### Research Skills
45
-
46
- | Skill | Purpose | Description |
47
- |-------|---------|-------------|
48
- | **ct-research-agent** | Research | Multi-source research aggregation and synthesis |
49
- | **ct-epic-architect** | Planning | Epic decomposition and task planning |
50
- | **ct-spec-writer** | Specification | RFC 2119 technical specification writing |
51
- | **ct-docs-lookup** | Documentation | Library and framework documentation queries |
52
-
53
- ### Documentation Skills
54
-
55
- | Skill | Purpose | Description |
56
- |-------|---------|-------------|
57
- | **ct-documentor** | Documentation | Documentation creation and management |
58
- | **ct-docs-write** | Writing | User-facing documentation writing |
59
- | **ct-docs-review** | Review | Documentation style guide compliance |
60
-
61
- ### Workflow Skills
62
-
63
- | Skill | Purpose | Description |
64
- |-------|---------|-------------|
65
- | **ct-dev-workflow** | Development | Git workflows, commits, releases |
66
- | **ct-contribution** | Contribution | Multi-agent consensus contributions |
67
- | **ct-skill-creator** | Skill Dev | Creating and validating CLEO skills |
68
- | **ct-skill-validator** | Validation | Skill compliance validation |
69
-
70
- ### Quality Skills
71
-
72
- | Skill | Purpose | Description |
73
- |-------|---------|-------------|
74
- | **ct-grade** | Grading | Session quality evaluation |
75
- | **ct-stickynote** | Notes | Quick ephemeral sticky notes |
76
-
77
- ### Integration Skills
78
-
79
- | Skill | Purpose | Description |
80
- |-------|---------|-------------|
81
- | **ct-cleo** | CLEO | Task management protocol operations |
82
-
83
- ### Specialized Skills
84
-
85
- Additional skills for specific domains:
86
- - **better-auth-svelte** - Better-Auth with SvelteKit
87
- - **drizzle-orm** - Drizzle ORM guidance
88
- - **expo-production-deploy** - Expo app deployment
89
- - **flarectl** - Cloudflare CLI management
90
- - **github-guru** - GitHub workflows
91
- - **neonctl** - Neon Postgres CLI
92
- - **payment-provider-oauth** - Payment provider OAuth
93
- - **railway** - Railway infrastructure
94
- - **resend** - Resend email API
95
- - **svelte5-sveltekit** - Svelte 5 development
96
- - **yt-dlp-webapp** - YouTube download backends
34
+ Tiers and install behaviour come from each SKILL.md's `metadata` (owner decision
35
+ D11157). `packages/skills/skills/manifest.json` is generated from them by
36
+ `node scripts/skills/generate-manifest.mjs`; gates 29-31 keep the manifest,
37
+ installability and every documented `cleo` command honest.
38
+
39
+ ### Core (installed to every harness, always relevant)
40
+
41
+ | Skill | Purpose |
42
+ |-------|---------|
43
+ | **ct-cleo** | CLEO task management protocol - session, task, and workflow guidance. |
44
+ | **ct-dev-workflow** | Development workflow orchestration for task-driven development with atomic commits, conventional commit messag… |
45
+ | **ct-documentor** | Documentation coordinator with CLEO style guide compliance. |
46
+ | **ct-lead** | Phase Lead orchestration playbook for spawning and supervising a parallel worker swarm in one wave. |
47
+ | **ct-orchestrator** | Pipeline-aware orchestration skill for managing complex workflows through subagent delegation. |
48
+ | **ct-task-executor** | General implementation task execution for completing assigned CLEO tasks by following instructions and produci… |
49
+
50
+ ### On demand (installed; loaded by description or by stage guidance)
51
+
52
+ | Skill | Purpose |
53
+ |-------|---------|
54
+ | **ct-adr-recorder** | Records Architecture Decision Records from accepted consensus verdicts. |
55
+ | **ct-artifact-publisher** | Builds and publishes artifacts to registries (npm, PyPI, cargo, docker, GitHub releases, generic tarballs) fol… |
56
+ | **ct-codebase-mapper** | Orient in an unfamiliar or large codebase with CLEO's code-intelligence graph (cleo nexus) and project map (cl… |
57
+ | **ct-consensus-voter** | Runs structured multi-agent voting for decision tasks with confidence scores, conflict detection, and HITL esc… |
58
+ | **ct-contribution** | Guided workflow for multi-agent consensus contributions. |
59
+ | **ct-council** | Convene "The Council" — a 5-advisor, shuffled gate-based peer-review, chairman-synthesis workflow for reviewin… |
60
+ | **ct-epic-architect** | Epic planning and task decomposition for breaking down large initiatives into atomic, executable tasks. |
61
+ | **ct-ivt-looper** | Runs a project-agnostic autonomous Implement-then-Validate-then-Test compliance loop on any git worktree. |
62
+ | **ct-provenance-keeper** | Generates in-toto v1 attestations, SLSA-level provenance records, SBOMs (CycloneDX or SPDX), and sigstore/cosi… |
63
+ | **ct-release-orchestrator** | Orchestrates the canonical 4-verb release pipeline introduced by SPEC-T9345: cleo release plan, then cleo rele… |
64
+ | **ct-research-agent** | Multi-source research and investigation combining web search, documentation lookup via Context7, and codebase … |
65
+ | **ct-spec-writer** | Technical specification writing using RFC 2119 language for clear, unambiguous requirements. |
66
+ | **ct-validator** | Compliance validation for verifying systems, documents, or code against requirements, schemas, or standards. |
67
+
68
+ ### Internal (CLEO development only; never installed to a harness)
69
+
70
+ | Skill | Purpose |
71
+ |-------|---------|
72
+ | **ct-grade** | CLEO session grading and A/B behavioral analysis with token tracking. |
73
+ | **ct-skill-author** | Create, improve and validate CLEO skills. |
74
+
75
+ Merged or retired in T12649: ct-docs-write and ct-docs-review are references of
76
+ ct-documentor; ct-memory and ct-stickynote are references of ct-cleo;
77
+ ct-skill-creator and ct-skill-validator became ct-skill-author; ct-docs-lookup
78
+ (use the Context7 MCP) and ct-master-tac were retired; signaldock-connect moved
79
+ to the SignalDock repository.
97
80
 
98
81
  ## Skill Structure
99
82
 
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Types for `@cleocode/skills/frontmatter.mjs` — the SKILL.md frontmatter
3
+ * rules shared by gate 29 and `cleo skills validate` (T12655).
4
+ */
5
+
6
+ /** Tag-like text the Agent Skills standard rejects. */
7
+ export declare const TAG_PATTERN: RegExp;
8
+ /** Allowed `metadata.tier` values. */
9
+ export declare const SKILL_TIERS: readonly ['core', 'on-demand', 'internal'];
10
+ /** Allowed `metadata.install` values. */
11
+ export declare const SKILL_INSTALL_MODES: readonly ['harness', 'internal'];
12
+ /** Allowed `metadata.stability` values. */
13
+ export declare const SKILL_STABILITIES: readonly ['experimental', 'stable', 'deprecated'];
14
+ /** Numeric tier written into manifest entries. */
15
+ export declare const TIER_NUMBER: { readonly core: 0; readonly 'on-demand': 1; readonly internal: 3 };
16
+ /** CAAMP catalogue `category` derived from the tier. */
17
+ export declare const CATEGORY_FOR_TIER: {
18
+ readonly core: 'core';
19
+ readonly 'on-demand': 'recommended';
20
+ readonly internal: 'meta';
21
+ };
22
+ /** Top-level keys a SKILL.md may not declare (derived from `metadata.tier`). */
23
+ export declare const DERIVED_TOP_LEVEL_KEYS: readonly ['tier', 'core', 'category'];
24
+ /** Top-level keys that moved under `metadata:`. */
25
+ export declare const MOVED_TO_METADATA_KEYS: readonly ['loomStage'];
26
+ /** Maximum `description` length accepted by harness skill loaders. */
27
+ export declare const MAX_DESCRIPTION_LENGTH: 1024;
28
+
29
+ /** Parsed SKILL.md frontmatter. */
30
+ export interface ParsedFrontmatter {
31
+ /** No parse errors. */
32
+ ok: boolean;
33
+ /** Top-level scalars (block scalars folded to one line). */
34
+ fields: Record<string, string>;
35
+ /** The nested `metadata:` map. */
36
+ metadata: Record<string, string>;
37
+ /** Lists nested under `metadata:` (e.g. `covers`). */
38
+ metadataLists: Record<string, string[]>;
39
+ /** Top-level block and inline lists. */
40
+ lists: Record<string, string[]>;
41
+ /** Every top-level key in order, duplicates included. */
42
+ keys: string[];
43
+ /** Parse errors. */
44
+ errors: string[];
45
+ }
46
+
47
+ /** Parse SKILL.md text into its frontmatter. */
48
+ export declare function parseFrontmatter(text: string): ParsedFrontmatter;
49
+
50
+ /**
51
+ * Validate one bundled skill's frontmatter against the CLEO contract.
52
+ *
53
+ * @param fm - Parsed frontmatter plus `name`, the skill's directory name.
54
+ * @param ctx - `loomStages` enables the `metadata.loomStage` binding check.
55
+ * @returns Human-readable problems (empty when valid).
56
+ */
57
+ export declare function validateFrontmatter(
58
+ fm: ParsedFrontmatter & { name: string },
59
+ ctx?: { loomStages?: Map<string, string> },
60
+ ): string[];
@@ -0,0 +1,277 @@
1
+ /**
2
+ * SKILL.md frontmatter rules for CLEO's bundled skills — the one copy shared
3
+ * by the arch gates (`scripts/skills/lib/skill-frontmatter.mjs`, gate 29) and
4
+ * the runtime (`cleo skills validate`, T12655), so the two cannot disagree.
5
+ *
6
+ * Pure: no fs, no dependencies. The gates run on a bare checkout (no
7
+ * `pnpm install`), and the frontmatter grammar used by skills is a flat map
8
+ * plus one nested `metadata:` map and folded/literal block scalars. Anything
9
+ * outside that grammar is reported as an error rather than guessed at.
10
+ *
11
+ * @module @cleocode/skills/frontmatter
12
+ * @task T12648
13
+ * @task T12655
14
+ */
15
+
16
+ /** Tag-like text the Agent Skills standard rejects (same test as CAAMP's validateSkill). */
17
+ export const TAG_PATTERN = /<[^>]+>/;
18
+
19
+ /** Allowed `metadata.tier` values — the skill's delivery class (D11157). */
20
+ export const SKILL_TIERS = /** @type {const} */ (['core', 'on-demand', 'internal']);
21
+
22
+ /** Allowed `metadata.install` values. */
23
+ export const SKILL_INSTALL_MODES = /** @type {const} */ (['harness', 'internal']);
24
+
25
+ /** Allowed `metadata.stability` values. */
26
+ export const SKILL_STABILITIES = /** @type {const} */ (['experimental', 'stable', 'deprecated']);
27
+
28
+ /**
29
+ * Numeric tier written into manifest entries for existing numeric readers
30
+ * (CAAMP catalogue, `packages/skills/index.js`), derived from the class.
31
+ */
32
+ export const TIER_NUMBER = /** @type {const} */ ({ core: 0, 'on-demand': 1, internal: 3 });
33
+
34
+ /**
35
+ * CAAMP catalogue `category` written into manifest entries, derived from the
36
+ * class so the two cannot disagree (T12653).
37
+ */
38
+ export const CATEGORY_FOR_TIER = /** @type {const} */ ({
39
+ core: 'core',
40
+ 'on-demand': 'recommended',
41
+ internal: 'meta',
42
+ });
43
+
44
+ /**
45
+ * Top-level keys a SKILL.md may not declare, because the manifest derives
46
+ * them from `metadata.tier` (T12648, T12653).
47
+ */
48
+ export const DERIVED_TOP_LEVEL_KEYS = /** @type {const} */ (['tier', 'core', 'category']);
49
+
50
+ /**
51
+ * Top-level keys that moved under `metadata:` (T12649). Each maps to its
52
+ * `metadata.<key>` home.
53
+ */
54
+ export const MOVED_TO_METADATA_KEYS = /** @type {const} */ (['loomStage']);
55
+
56
+ /** Maximum `description` length accepted by harness skill loaders. */
57
+ export const MAX_DESCRIPTION_LENGTH = 1024;
58
+
59
+ /**
60
+ * Parse the scalar on the right of `key:`.
61
+ *
62
+ * @param {string} raw - Text after the colon.
63
+ * @returns {string} Unquoted scalar ('' for an empty value).
64
+ */
65
+ function scalar(raw) {
66
+ const v = raw.trim();
67
+ if ((v.startsWith('"') && v.endsWith('"')) || (v.startsWith("'") && v.endsWith("'"))) {
68
+ return v.slice(1, -1);
69
+ }
70
+ return v;
71
+ }
72
+
73
+ /**
74
+ * Parse SKILL.md text into its frontmatter.
75
+ *
76
+ * @param {string} text - Full SKILL.md content.
77
+ * @returns {{
78
+ * ok: boolean,
79
+ * fields: Record<string, string>,
80
+ * metadata: Record<string, string>,
81
+ * metadataLists: Record<string, string[]>,
82
+ * lists: Record<string, string[]>,
83
+ * keys: string[],
84
+ * errors: string[],
85
+ * }} `fields` holds top-level scalars (block scalars folded to one line;
86
+ * nested maps omitted), `lists` top-level block (`- item`) and inline
87
+ * (`[a, b]`) lists, `keys` every top-level key in order (duplicates
88
+ * included), `metadata` the nested `metadata:` map and `metadataLists`
89
+ * its nested lists (`metadata.covers`).
90
+ */
91
+ export function parseFrontmatter(text) {
92
+ const errors = [];
93
+ // T12649: a CRLF checkout (Windows autocrlf) must parse identically.
94
+ const lines = text.replace(/\r\n?/g, '\n').split('\n');
95
+ if (lines[0] !== '---') {
96
+ return {
97
+ ok: false,
98
+ fields: {},
99
+ metadata: {},
100
+ metadataLists: {},
101
+ lists: {},
102
+ keys: [],
103
+ errors: ['no frontmatter block'],
104
+ };
105
+ }
106
+ const end = lines.indexOf('---', 1);
107
+ if (end === -1) {
108
+ return {
109
+ ok: false,
110
+ fields: {},
111
+ metadata: {},
112
+ metadataLists: {},
113
+ lists: {},
114
+ keys: [],
115
+ errors: ['unterminated frontmatter'],
116
+ };
117
+ }
118
+ const body = lines.slice(1, end);
119
+ /** @type {Record<string, string>} */
120
+ const fields = {};
121
+ /** @type {Record<string, string>} */
122
+ const metadata = {};
123
+ /** @type {Record<string, string[]>} */
124
+ const lists = {};
125
+ /** @type {Record<string, string[]>} */
126
+ const metadataLists = {};
127
+ const keys = [];
128
+
129
+ for (let i = 0; i < body.length; i++) {
130
+ const line = body[i];
131
+ if (line.trim() === '' || line.trimStart().startsWith('#')) continue;
132
+ if (/^\s/.test(line) || line.startsWith('- ')) continue; // continuation of a nested value
133
+ const m = /^([A-Za-z][\w-]*):(.*)$/.exec(line);
134
+ if (!m) {
135
+ errors.push(`unparseable frontmatter line ${i + 2}: ${line}`);
136
+ continue;
137
+ }
138
+ const [, key, rest] = m;
139
+ keys.push(key);
140
+ const value = rest.trim();
141
+
142
+ if (key === 'metadata' && value === '') {
143
+ // A blank line inside the block does not end it; the next unindented
144
+ // key does (T12649).
145
+ // A nested list (` covers:` then ` - item`) is collected into
146
+ // metadataLists (T12124).
147
+ let listKey = null;
148
+ for (let j = i + 1; j < body.length; j++) {
149
+ if (body[j].trim() === '') continue;
150
+ if (!/^\s+\S/.test(body[j])) break;
151
+ const item = /^\s+-\s+(.*)$/.exec(body[j]);
152
+ if (item && listKey) {
153
+ metadataLists[listKey].push(scalar(item[1]));
154
+ continue;
155
+ }
156
+ const mm = /^\s+([A-Za-z][\w-]*):(.*)$/.exec(body[j]);
157
+ if (!mm) continue;
158
+ listKey = null;
159
+ if (mm[2].trim() === '') {
160
+ listKey = mm[1];
161
+ metadataLists[listKey] = [];
162
+ } else {
163
+ metadata[mm[1]] = scalar(mm[2]);
164
+ }
165
+ }
166
+ continue;
167
+ }
168
+ if (value === '>' || value === '>-' || value === '|' || value === '|-') {
169
+ const parts = [];
170
+ for (let j = i + 1; j < body.length && (/^\s+\S/.test(body[j]) || body[j] === ''); j++) {
171
+ parts.push(body[j].trim());
172
+ }
173
+ fields[key] = parts.filter(Boolean).join(' ');
174
+ continue;
175
+ }
176
+ if (value === '') {
177
+ // A block list (`key:` then ` - item` lines) — T12649.
178
+ const items = [];
179
+ for (let j = i + 1; j < body.length && /^\s+-\s/.test(body[j]); j++) {
180
+ items.push(scalar(body[j].replace(/^\s+-\s+/, '')));
181
+ }
182
+ lists[key] = items;
183
+ } else if (value.startsWith('[') && value.endsWith(']')) {
184
+ lists[key] = value
185
+ .slice(1, -1)
186
+ .split(',')
187
+ .map((s) => scalar(s))
188
+ .filter(Boolean);
189
+ }
190
+ fields[key] = scalar(value);
191
+ }
192
+
193
+ return { ok: errors.length === 0, fields, metadata, metadataLists, lists, keys, errors };
194
+ }
195
+
196
+ /**
197
+ * Validate one skill's frontmatter against the SSoT contract.
198
+ *
199
+ * @param {ReturnType<typeof parseFrontmatter> & { name: string }} fm - Parsed frontmatter
200
+ * plus `name`, the skill's directory name.
201
+ * @param {{ loomStages?: Map<string, string> }} [ctx] - `loomStages` (from
202
+ * {@link loadLoomStages}) enables the `metadata.loomStage` binding check.
203
+ * @returns {string[]} Human-readable problems (empty when valid).
204
+ */
205
+ export function validateFrontmatter(fm, ctx = {}) {
206
+ const problems = [...fm.errors];
207
+ const seen = new Set();
208
+ for (const k of fm.keys) {
209
+ if (seen.has(k)) problems.push(`duplicate top-level key '${k}' (invalid YAML)`);
210
+ seen.add(k);
211
+ }
212
+ if (fm.fields.name !== fm.name) {
213
+ problems.push(`name '${fm.fields.name ?? ''}' does not equal its directory '${fm.name}'`);
214
+ }
215
+ const description = fm.fields.description ?? '';
216
+ if (description === '') problems.push('description is missing');
217
+ if (description.length > MAX_DESCRIPTION_LENGTH) {
218
+ problems.push(`description is ${description.length} chars (max ${MAX_DESCRIPTION_LENGTH})`);
219
+ }
220
+ // T12655: the Agent Skills standard (CAAMP validateSkill) rejects tag-like
221
+ // text; `epic-<TID>` in a description passed this gate and failed
222
+ // `cleo skills validate`. Write placeholders as `{TID}`.
223
+ for (const field of ['name', 'description']) {
224
+ if (TAG_PATTERN.test(fm.fields[field] ?? '')) {
225
+ problems.push(`${field} contains angle-bracket (XML/HTML tag) text; write placeholders as {name}`);
226
+ }
227
+ }
228
+ for (const key of DERIVED_TOP_LEVEL_KEYS) {
229
+ if (key in fm.fields) {
230
+ problems.push(
231
+ `top-level ${key} is not allowed — it is derived from metadata.tier (core|on-demand|internal)`,
232
+ );
233
+ }
234
+ }
235
+ for (const key of MOVED_TO_METADATA_KEYS) {
236
+ if (key in fm.fields) problems.push(`top-level ${key} moved — declare metadata.${key}`);
237
+ }
238
+ const md = fm.metadata;
239
+ if (md.loomStage !== undefined && ctx.loomStages) {
240
+ const owner = ctx.loomStages.get(md.loomStage);
241
+ if (owner === undefined) {
242
+ problems.push(
243
+ `metadata.loomStage '${md.loomStage}' is not a STAGE_SKILL_MAP stage or a .cant protocol id`,
244
+ );
245
+ } else if (owner !== fm.name) {
246
+ problems.push(
247
+ `metadata.loomStage '${md.loomStage}' is bound to '${owner}', not '${fm.name}'`,
248
+ );
249
+ }
250
+ }
251
+ if (!md.version) problems.push('metadata.version is missing');
252
+ else if (!/^\d+\.\d+\.\d+$/.test(md.version)) {
253
+ problems.push(`metadata.version '${md.version}' is not X.Y.Z`);
254
+ }
255
+ if (fm.fields.version !== undefined && fm.fields.version !== md.version) {
256
+ problems.push(
257
+ `top-level version '${fm.fields.version}' disagrees with metadata.version '${md.version ?? ''}'`,
258
+ );
259
+ }
260
+ if (!SKILL_TIERS.includes(md.tier)) {
261
+ problems.push(`metadata.tier '${md.tier ?? ''}' must be one of ${SKILL_TIERS.join('|')}`);
262
+ }
263
+ if (!SKILL_INSTALL_MODES.includes(md.install)) {
264
+ problems.push(
265
+ `metadata.install '${md.install ?? ''}' must be one of ${SKILL_INSTALL_MODES.join('|')}`,
266
+ );
267
+ }
268
+ if (md.tier === 'internal' && md.install === 'harness') {
269
+ problems.push('metadata.tier internal cannot have metadata.install harness');
270
+ }
271
+ if (md.stability !== undefined && !SKILL_STABILITIES.includes(md.stability)) {
272
+ problems.push(
273
+ `metadata.stability '${md.stability}' must be one of ${SKILL_STABILITIES.join('|')}`,
274
+ );
275
+ }
276
+ return problems;
277
+ }
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- // --- Skill Entry (from skills.json) ---
1
+ // --- Skill Entry (derived from skills/manifest.json, T12653) ---
2
2
 
3
3
  export interface SkillEntry {
4
4
  name: string;
@@ -87,7 +87,7 @@ export interface ValidationResult {
87
87
 
88
88
  // --- Existing exports (preserved) ---
89
89
 
90
- /** All skill entries from skills.json */
90
+ /** All skill entries, derived from skills/manifest.json */
91
91
  export declare const skills: SkillEntry[];
92
92
 
93
93
  /** Parsed manifest.json dispatch registry */
@@ -99,7 +99,7 @@ export declare const shared: Record<string, unknown>;
99
99
  /** List all skill names */
100
100
  export declare function listSkills(): string[];
101
101
 
102
- /** Get skill metadata from skills.json by name */
102
+ /** Get skill metadata by name */
103
103
  export declare function getSkill(name: string): SkillEntry | undefined;
104
104
 
105
105
  /** Resolve absolute path to a skill's SKILL.md file */
package/index.js CHANGED
@@ -19,23 +19,48 @@ const libraryRoot = LIBRARY_ROOT;
19
19
 
20
20
  // --- Core data ---
21
21
 
22
- /** Parsed skills.json index */
23
- const skillsIndex = JSON.parse(
24
- fs.readFileSync(path.join(LIBRARY_ROOT, 'skills.json'), 'utf8')
25
- );
26
-
27
- /** Parsed manifest.json dispatch registry */
22
+ /**
23
+ * Parsed manifest.json — the only skills index. It is generated from SKILL.md
24
+ * frontmatter by scripts/skills/generate-manifest.mjs; skills.json was
25
+ * removed in T12653.
26
+ */
28
27
  const manifest = JSON.parse(
29
28
  fs.readFileSync(path.join(SKILLS_ROOT, 'manifest.json'), 'utf8')
30
29
  );
31
30
 
31
+ /**
32
+ * Map a manifest entry to the catalog SkillEntry shape (the manifest `path`
33
+ * names the directory; the catalog path names SKILL.md). Mirrors
34
+ * catalogEntryFromManifest in @cleocode/caamp.
35
+ * @param {object} m - Manifest skill entry
36
+ * @returns {object} SkillEntry
37
+ */
38
+ function toSkillEntry(m) {
39
+ return {
40
+ name: m.name,
41
+ description: m.description,
42
+ version: m.version,
43
+ path: m.path.endsWith('SKILL.md') ? m.path : `${m.path}/SKILL.md`,
44
+ references: m.references || [],
45
+ core: m.core === undefined ? m.deliveryTier === 'core' : m.core,
46
+ category: m.category || 'recommended',
47
+ tier: m.tier,
48
+ protocol: m.protocol === undefined ? null : m.protocol,
49
+ dependencies: m.dependencies || [],
50
+ sharedResources: m.sharedResources || [],
51
+ compatibility: m.compatibility || [],
52
+ license: m.license || 'MIT',
53
+ metadata: { deliveryTier: m.deliveryTier, install: m.install },
54
+ };
55
+ }
56
+
32
57
  /** Parsed _shared/placeholders.json */
33
58
  const shared = JSON.parse(
34
59
  fs.readFileSync(path.join(SHARED_ROOT, 'placeholders.json'), 'utf8')
35
60
  );
36
61
 
37
- /** All skill entries from skills.json */
38
- const skills = skillsIndex.skills;
62
+ /** All skill entries, derived from manifest.json */
63
+ const skills = manifest.skills.map(toSkillEntry);
39
64
 
40
65
  // --- Existing API (preserved) ---
41
66
 
@@ -48,7 +73,7 @@ function listSkills() {
48
73
  }
49
74
 
50
75
  /**
51
- * Get skill metadata from skills.json by name.
76
+ * Get skill metadata by name.
52
77
  * @param {string} name - Skill name (e.g. "ct-research-agent")
53
78
  * @returns {object|undefined}
54
79
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cleocode/skills",
3
- "version": "2026.9.21",
3
+ "version": "2026.9.22",
4
4
  "description": "CLEO skill definitions - bundled with CLEO monorepo",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -9,7 +9,9 @@
9
9
  "profiles",
10
10
  "*.json",
11
11
  "*.js",
12
- "*.d.ts"
12
+ "*.d.ts",
13
+ "*.mjs",
14
+ "*.d.mts"
13
15
  ],
14
16
  "devDependencies": {
15
17
  "vitest": "^4.1.4"
@@ -1,7 +1,14 @@
1
1
  {
2
2
  "name": "core",
3
- "description": "Orchestration and LOOM (RCASD-IVTR+C) pipeline awareness",
3
+ "description": "The six core skills (D11157): CLEO protocol, orchestration, phase leads, task execution, dev workflow and documentation",
4
4
  "extends": "minimal",
5
- "skills": ["ct-orchestrator", "loom"],
6
- "includeProtocols": ["agent-protocol"]
5
+ "skills": [
6
+ "ct-orchestrator",
7
+ "ct-lead",
8
+ "ct-dev-workflow",
9
+ "ct-documentor"
10
+ ],
11
+ "includeProtocols": [
12
+ "agent-protocol"
13
+ ]
7
14
  }
@@ -1,10 +1,14 @@
1
1
  {
2
2
  "name": "full",
3
- "description": "All skills including execution, documentation, quality, and meta",
3
+ "description": "Every skill installed to harnesses. Equal to recommended: internal skills (ct-grade, ct-skill-author) are never installed (D11157)",
4
4
  "extends": "recommended",
5
- "skills": [
6
- "ct-dev-workflow", "ct-documentor", "ct-docs-lookup", "ct-docs-write", "ct-docs-review",
7
- "ct-contribution", "ct-grade", "ct-skill-creator"
8
- ],
9
- "includeProtocols": ["implementation", "contribution", "release", "testing", "artifact-publish", "provenance"]
5
+ "skills": [],
6
+ "includeProtocols": [
7
+ "implementation",
8
+ "contribution",
9
+ "release",
10
+ "testing",
11
+ "artifact-publish",
12
+ "provenance"
13
+ ]
10
14
  }
@@ -1,7 +1,33 @@
1
1
  {
2
2
  "name": "recommended",
3
- "description": "Full LOOM (RCASD-IVTR+C pipeline) skills for epic-driven development",
3
+ "description": "Core plus the on-demand skills: every LOOM (RCASD-IVTR+C) stage skill, council and codebase mapping",
4
4
  "extends": "core",
5
- "skills": ["ct-council", "ct-epic-architect", "ct-research-agent", "ct-spec-writer", "ct-validator", "loom"],
6
- "includeProtocols": ["research", "consensus", "specification", "decomposition", "validation", "adr"]
5
+ "skills": [
6
+ "ct-research-agent",
7
+ "ct-consensus-voter",
8
+ "ct-adr-recorder",
9
+ "ct-spec-writer",
10
+ "ct-epic-architect",
11
+ "ct-validator",
12
+ "ct-ivt-looper",
13
+ "ct-release-orchestrator",
14
+ "ct-contribution",
15
+ "ct-artifact-publisher",
16
+ "ct-provenance-keeper",
17
+ "ct-council",
18
+ "ct-codebase-mapper"
19
+ ],
20
+ "includeProtocols": [
21
+ "research",
22
+ "consensus",
23
+ "specification",
24
+ "decomposition",
25
+ "validation",
26
+ "adr",
27
+ "testing",
28
+ "release",
29
+ "contribution",
30
+ "artifact-publish",
31
+ "provenance"
32
+ ]
7
33
  }