@skilly-hand/skilly-hand 0.23.2 → 0.24.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.
package/CHANGELOG.md CHANGED
@@ -16,6 +16,38 @@ All notable changes to this project are documented in this file.
16
16
  ### Removed
17
17
  - _None._
18
18
 
19
+ ## [0.24.0] - 2026-04-26
20
+ [View on npm](https://www.npmjs.com/package/@skilly-hand/skilly-hand/v/0.24.0)
21
+
22
+ ### Added
23
+ - Added install-time creation of the user-owned `.ai/DECISIONS.md` decisions registry, including entry criteria, an entry template, and a required registry changelog section.
24
+ - Added CLI install output that reports the `.ai/DECISIONS.md` decisions registry status during dry runs and applied installs.
25
+ - Added regression coverage for decisions registry planning, creation, existing-registry preservation, uninstall preservation, and invalid `.ai` parent handling.
26
+
27
+ ### Changed
28
+ - Updated `review-rangers` to own decisions registry read/write guidance and bumped the skill metadata version to `1.1.0`.
29
+
30
+ ### Fixed
31
+ - Preserved existing user-owned decisions registry content across reinstalls and uninstalls.
32
+
33
+ ### Removed
34
+ - _None._
35
+
36
+ ## [0.23.3] - 2026-04-20
37
+ [View on npm](https://www.npmjs.com/package/@skilly-hand/skilly-hand/v/0.23.3)
38
+
39
+ ### Added
40
+ - Mirrored each skill `manifest.id` into top-level `name` frontmatter across catalog `SKILL.md` files.
41
+
42
+ ### Changed
43
+ - Updated catalog frontmatter rendering to include `name` and require a non-empty `manifest.id` during frontmatter validation.
44
+
45
+ ### Fixed
46
+ - Expanded frontmatter sync tests to catch stale or missing `name` metadata regressions and enforce manifest id requirements.
47
+
48
+ ### Removed
49
+ - _None._
50
+
19
51
  ## [0.23.2] - 2026-04-13
20
52
  [View on npm](https://www.npmjs.com/package/@skilly-hand/skilly-hand/v/0.23.2)
21
53
 
@@ -1,4 +1,5 @@
1
1
  ---
2
+ name: "accessibility-audit"
2
3
  description: "Audit web accessibility against W3C WCAG 2.2 Level AA using framework-agnostic checks, remediation patterns, and portable command-line scanning."
3
4
  skillMetadata:
4
5
  author: "skilly-hand"
@@ -1,4 +1,5 @@
1
1
  ---
2
+ name: "agents-root-orchestrator"
2
3
  description: "Author root AGENTS.md as a Where/What/When orchestrator that routes tasks and skill invocation clearly."
3
4
  skillMetadata:
4
5
  author: "skilly-hand"
@@ -1,4 +1,5 @@
1
1
  ---
2
+ name: "angular-guidelines"
2
3
  description: "Guide Angular code generation and review using latest stable Angular verification and modern framework best practices."
3
4
  skillMetadata:
4
5
  author: "skilly-hand"
@@ -1,4 +1,5 @@
1
1
  ---
2
+ name: "figma-mcp-0to1"
2
3
  description: "Guide users from Figma MCP installation and authentication through first canvas creation, with function-level tool coverage and operational recovery patterns."
3
4
  skillMetadata:
4
5
  author: "skilly-hand"
@@ -1,4 +1,5 @@
1
1
  ---
2
+ name: "frontend-design"
2
3
  description: "Project-aware frontend design skill that detects the existing tech stack, UI libraries, CSS variables, and design tokens before proposing any UI work. Supports greenfield projects via DESIGN.md context setup, and includes post-generation motion and visual refinement phases."
3
4
  skillMetadata:
4
5
  author: "skilly-hand"
@@ -1,4 +1,5 @@
1
1
  ---
2
+ name: "output-optimizer"
2
3
  description: "Optimize output token consumption through compact interpreter modes with controlled expansion when complexity, ambiguity, or risk requires more detail. Trigger: minimizing response verbosity while preserving clarity and correctness."
3
4
  skillMetadata:
4
5
  author: "skilly-hand"
@@ -1,4 +1,5 @@
1
1
  ---
2
+ name: "project-security"
2
3
  description: "Scan project configuration and release surfaces for leak and security risks, and enforce security gates on commit, push, and publish workflows across GitHub, GitLab, npm, pnpm, yarn, and generic CI. Trigger: validating repository security posture, preventing secret leaks, or hardening delivery pipelines."
3
4
  skillMetadata:
4
5
  author: "skilly-hand"
@@ -1,4 +1,5 @@
1
1
  ---
2
+ name: "project-teacher"
2
3
  description: "Scan the active project and teach any concept, code path, or decision using verified information, interactive questions, and simple explanations. Trigger: user asks to explain, understand, clarify, or learn about anything in the project or codebase."
3
4
  skillMetadata:
4
5
  author: "skilly-hand"
@@ -1,4 +1,5 @@
1
1
  ---
2
+ name: "react-guidelines"
2
3
  description: "Guide React code generation and review using latest stable React verification and modern framework best practices."
3
4
  skillMetadata:
4
5
  author: "skilly-hand"
@@ -1,14 +1,17 @@
1
1
  ---
2
+ name: "review-rangers"
2
3
  description: "Review code, decisions, and artifacts through a multi-perspective committee and a domain expert safety guard, then synthesize a structured verdict."
3
4
  skillMetadata:
4
5
  author: "skilly-hand"
5
- last-edit: "2026-04-04"
6
+ last-edit: "2026-04-26"
6
7
  license: "Apache-2.0"
7
- version: "1.0.0"
8
- changelog: "Added multi-perspective review skill with committee + safety guard synthesis; enables adversarial evaluation without permanent agent files; affects catalog skill coverage for review and quality workflows"
8
+ version: "1.1.0"
9
+ changelog: "Added DECISIONS.md registry ownership guidance; preserves durable review insights and anti-slop decisions across sessions; affects review-rangers workflow, install scaffolding, and project memory usage"
9
10
  auto-invoke: "Reviewing code, decisions, or artifacts where adversarial multi-perspective evaluation adds value"
10
11
  allowed-tools:
11
12
  - "Read"
13
+ - "Edit"
14
+ - "Write"
12
15
  - "Grep"
13
16
  - "Glob"
14
17
  - "Bash"
@@ -37,14 +40,16 @@ Do not use this skill for:
37
40
  ## Core Workflow
38
41
 
39
42
  1. Identify the target (code, decision, artifact) and its domain.
40
- 2. Determine committee size: 3 members for routine reviews, 5 for high-risk or cross-domain targets.
41
- 3. Spawn N committee members using `assets/committee-member-template.md`. Assign each a distinct evaluation lens. Run them independently — no member sees another's output.
42
- 4. Determine the expert domain for the safety guard.
43
- 5. Spawn 1 safety guard using `assets/safety-guard-template.md`. It evaluates the target from an authoritative expert position.
44
- 6. Run the committee and safety guard in parallel.
45
- 7. Collect all outputs.
46
- 8. Synthesize a structured verdict following the Synthesis Rules.
47
- 9. Emit the final verdict with confidence tier, top findings, and recommended action.
43
+ 2. Read `.ai/DECISIONS.md` if it exists. Treat it as project memory for avoiding repeated mistakes and reusing documented decisions.
44
+ 3. Determine committee size: 3 members for routine reviews, 5 for high-risk or cross-domain targets.
45
+ 4. Spawn N committee members using `assets/committee-member-template.md`. Assign each a distinct evaluation lens. Run them independently — no member sees another's output.
46
+ 5. Determine the expert domain for the safety guard.
47
+ 6. Spawn 1 safety guard using `assets/safety-guard-template.md`. It evaluates the target from an authoritative expert position.
48
+ 7. Run the committee and safety guard in parallel.
49
+ 8. Collect all outputs.
50
+ 9. Synthesize a structured verdict following the Synthesis Rules.
51
+ 10. Emit the final verdict with confidence tier, top findings, and recommended action.
52
+ 11. Decide whether any insight qualifies for `.ai/DECISIONS.md`; if yes, update the registry and its changelog in the same edit.
48
53
 
49
54
  ---
50
55
 
@@ -141,6 +146,56 @@ RECOMMENDED ACTION:
141
146
 
142
147
  ---
143
148
 
149
+ ## Decisions Registry Protocol
150
+
151
+ `review-rangers` owns `.ai/DECISIONS.md` maintenance when the registry exists. Use it as both:
152
+
153
+ - A documentary source before solving or reviewing relevant problems.
154
+ - A durable memory target after review when a finding has future value.
155
+
156
+ ### Read Rules
157
+
158
+ - Read `.ai/DECISIONS.md` near the start of relevant review or problem-solving work.
159
+ - Apply documented decisions and "avoid repeating" notes as project constraints.
160
+ - If the file does not exist, continue the review without creating it unless the current task is installation or explicit registry setup.
161
+
162
+ ### Write Criteria
163
+
164
+ Write to `.ai/DECISIONS.md` only for:
165
+
166
+ - Breaking changes.
167
+ - Mid-interest or high-interest solutions.
168
+ - Architectural decisions.
169
+ - Repeated issue patterns.
170
+ - Project-specific conventions likely to matter in future sessions.
171
+
172
+ Do not write entries for minimal cleanup, obvious one-off bugs, insignificant changes, local-only implementation details, or full review transcripts.
173
+
174
+ ### Write Format
175
+
176
+ Insert new entries above the final `## Changelog` section so the changelog remains the last section.
177
+
178
+ ```md
179
+ ## YYYY-MM-DD - Short Decision Title
180
+
181
+ - Interest level: Mid | High | Breaking
182
+ - Context:
183
+ - Decision / Insight:
184
+ - Rationale:
185
+ - Avoid repeating:
186
+ - Source:
187
+ ```
188
+
189
+ Every change to `.ai/DECISIONS.md` must update `## Changelog` in the same edit.
190
+
191
+ ```md
192
+ - YYYY-MM-DD: Created/updated entry "<title>" because <why>.
193
+ ```
194
+
195
+ If the changelog section is missing, add it as the final section before making any other registry change.
196
+
197
+ ---
198
+
144
199
  ## Decision Tree
145
200
 
146
201
  ```text
@@ -10,13 +10,15 @@
10
10
  "agentSupport": ["codex", "claude", "cursor", "gemini", "copilot", "antigravity", "windsurf", "trae"],
11
11
  "skillMetadata": {
12
12
  "author": "skilly-hand",
13
- "last-edit": "2026-04-04",
13
+ "last-edit": "2026-04-26",
14
14
  "license": "Apache-2.0",
15
- "version": "1.0.0",
16
- "changelog": "Added multi-perspective review skill with committee + safety guard synthesis; enables adversarial evaluation without permanent agent files; affects catalog skill coverage for review and quality workflows",
15
+ "version": "1.1.0",
16
+ "changelog": "Added DECISIONS.md registry ownership guidance; preserves durable review insights and anti-slop decisions across sessions; affects review-rangers workflow, install scaffolding, and project memory usage",
17
17
  "auto-invoke": "Reviewing code, decisions, or artifacts where adversarial multi-perspective evaluation adds value",
18
18
  "allowed-tools": [
19
19
  "Read",
20
+ "Edit",
21
+ "Write",
20
22
  "Grep",
21
23
  "Glob",
22
24
  "Bash",
@@ -1,4 +1,5 @@
1
1
  ---
2
+ name: "skill-creator"
2
3
  description: "Create and standardize AI skills with reusable structure, metadata rules, and templates."
3
4
  skillMetadata:
4
5
  author: "skilly-hand"
@@ -115,7 +116,7 @@ Top-level `SKILL.md` files now include managed YAML frontmatter mirrored from `m
115
116
  Rules:
116
117
 
117
118
  - `manifest.json` is the single source of truth.
118
- - Mirror only `description` and `skillMetadata.{author,last-edit,license,version,changelog,auto-invoke,allowed-tools}`.
119
+ - Mirror only `name` (from `manifest.id`), `description`, and `skillMetadata.{author,last-edit,license,version,changelog,auto-invoke,allowed-tools}`.
119
120
  - Do not manually edit mirrored frontmatter in `SKILL.md`; run sync automation instead.
120
121
  - Keep instruction body content in `SKILL.md` focused on workflow guidance.
121
122
 
@@ -1,7 +1,7 @@
1
1
  # {Name of the Skill} Guide
2
2
 
3
3
  <!--
4
- Managed frontmatter is mirrored from manifest.json by automation.
4
+ Managed frontmatter is mirrored from manifest.json by automation (`name` is derived from `manifest.id`).
5
5
  Do not hand-author frontmatter in this template.
6
6
  -->
7
7
 
@@ -1,4 +1,5 @@
1
1
  ---
2
+ name: "spec-driven-development"
2
3
  description: "Plan, execute, and verify multi-step work through versioned specs with small, testable tasks."
3
4
  skillMetadata:
4
5
  author: "skilly-hand"
@@ -1,4 +1,5 @@
1
1
  ---
2
+ name: "test-driven-development"
2
3
  description: "Guide implementation using the RED → GREEN → REFACTOR TDD cycle: write a failing test first, write the minimum code to pass, then refactor while tests stay green."
3
4
  skillMetadata:
4
5
  author: "skilly-hand"
@@ -1,4 +1,5 @@
1
1
  ---
2
+ name: "token-optimizer"
2
3
  description: "Classify task complexity and right-size reasoning depth, context gathering, and response detail to reduce wasted tokens."
3
4
  skillMetadata:
4
5
  author: "skilly-hand"
@@ -1,4 +1,5 @@
1
1
  ---
2
+ name: "user-story-crafting"
2
3
  description: "Create and refine user stories with structured quality gates, splitting heuristics, and lightweight story mapping for release slicing. Trigger: writing, restructuring, splitting, or sequencing user stories for delivery-ready backlog work."
3
4
  skillMetadata:
4
5
  author: "skilly-hand"
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "@skilly-hand/skilly-hand",
3
- "version": "0.23.2",
3
+ "version": "0.24.0",
4
4
  "license": "CC-BY-NC-4.0",
5
5
  "type": "module",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/Davecelot/skilly-hand.git"
9
+ },
6
10
  "publishConfig": {
7
11
  "access": "public"
8
12
  },
@@ -18,7 +22,8 @@
18
22
  "SECURITY.md"
19
23
  ],
20
24
  "workspaces": [
21
- "packages/*"
25
+ "packages/*",
26
+ "site"
22
27
  ],
23
28
  "engines": {
24
29
  "node": ">=22.0.0"
@@ -47,7 +52,10 @@
47
52
  "cli": "node ./packages/cli/src/bin.js",
48
53
  "detect": "node ./packages/cli/src/bin.js detect",
49
54
  "list": "node ./packages/cli/src/bin.js list",
50
- "doctor": "node ./packages/cli/src/bin.js doctor"
55
+ "doctor": "node ./packages/cli/src/bin.js doctor",
56
+ "site:dev": "npm run dev -w @skilly-hand/site",
57
+ "site:build": "npm run build -w @skilly-hand/site",
58
+ "site:preview": "npm run preview -w @skilly-hand/site"
51
59
  },
52
60
  "dependencies": {
53
61
  "inquirer": "13.4.1"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skilly-hand/catalog",
3
- "version": "0.23.2",
3
+ "version": "0.24.0",
4
4
  "private": true,
5
5
  "type": "module"
6
6
  }
@@ -128,6 +128,10 @@ function assertFrontmatterFields(manifest) {
128
128
  throw new Error("Invalid manifest while building SKILL.md frontmatter");
129
129
  }
130
130
 
131
+ if (typeof manifest.id !== "string" || manifest.id.trim().length === 0) {
132
+ throw new Error(`Skill "${manifest.id}" is missing required manifest.id for frontmatter mirroring`);
133
+ }
134
+
131
135
  if (typeof manifest.description !== "string" || manifest.description.length === 0) {
132
136
  throw new Error(`Skill "${manifest.id}" is missing required manifest.description for frontmatter mirroring`);
133
137
  }
@@ -163,6 +167,7 @@ function assertFrontmatterFields(manifest) {
163
167
  export function buildSkillFrontmatterPayload(manifest) {
164
168
  assertFrontmatterFields(manifest);
165
169
  return {
170
+ name: manifest.id,
166
171
  description: manifest.description,
167
172
  skillMetadata: {
168
173
  author: manifest.skillMetadata.author,
@@ -178,6 +183,7 @@ export function buildSkillFrontmatterPayload(manifest) {
178
183
 
179
184
  function renderSkillFrontmatterInner(payload) {
180
185
  const lines = [
186
+ `name: ${yamlQuote(payload.name)}`,
181
187
  `description: ${yamlQuote(payload.description)}`,
182
188
  "skillMetadata:",
183
189
  ` author: ${yamlQuote(payload.skillMetadata.author)}`,
@@ -206,6 +212,7 @@ export function splitSkillMarkdown(content) {
206
212
  const source = normalized.startsWith("\uFEFF") ? normalized.slice(1) : normalized;
207
213
  const lines = splitLinesWithOffsets(source);
208
214
  const mirroredKeys = new Set([
215
+ "name",
209
216
  "description",
210
217
  "skillMetadata",
211
218
  "author",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skilly-hand/cli",
3
- "version": "0.23.2",
3
+ "version": "0.24.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "bin": {
@@ -131,11 +131,24 @@ function buildHelpText(renderer, appVersion) {
131
131
 
132
132
  function buildInstallResultDoc(result, flags, detectionGridText = "") {
133
133
  const mode = flags.dryRun ? "dry-run" : "apply";
134
+ const decisionsRegistry = result.plan.decisionsRegistry || {
135
+ relativePath: ".ai/DECISIONS.md",
136
+ exists: false,
137
+ willCreate: false
138
+ };
139
+ const decisionsRegistryStatus = decisionsRegistry.created
140
+ ? "created"
141
+ : decisionsRegistry.exists
142
+ ? "existing"
143
+ : decisionsRegistry.willCreate
144
+ ? "will create"
145
+ : "not reported";
134
146
  return createResultDoc("Install", [
135
147
  section("Install Preflight", [
136
148
  kvBlock([
137
149
  ["Project", result.plan.cwd],
138
150
  ["Install root", result.plan.installRoot],
151
+ ["Decisions registry", `${decisionsRegistry.relativePath} (${decisionsRegistryStatus})`],
139
152
  ["Agents", result.plan.agents.join(", ") || "none"],
140
153
  ["Include tags", flags.include.join(", ") || "none"],
141
154
  ["Exclude tags", flags.exclude.join(", ") || "none"],
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skilly-hand/core",
3
- "version": "0.23.2",
3
+ "version": "0.24.0",
4
4
  "private": true,
5
5
  "type": "module"
6
6
  }
@@ -6,6 +6,35 @@ import { detectProject, inspectProjectFiles } from "../../detectors/src/index.js
6
6
  export const DEFAULT_AGENTS = ["standard", "codex", "claude", "cursor", "gemini", "copilot", "antigravity", "windsurf", "trae"];
7
7
  const MANAGED_MARKER = "<!-- Managed by skilly-hand.";
8
8
  const NATIVE_SETUP_MARKER = "<!-- Managed by skilly-hand native setup.";
9
+ const DECISIONS_REGISTRY_RELATIVE_PATH = ".ai/DECISIONS.md";
10
+ const DECISIONS_REGISTRY_TEMPLATE = `# AI Decisions
11
+
12
+ Durable project memory for \`review-rangers\`. Use this file to record breaking changes, mid/high-interest solutions, and important review insights that future agents should reuse.
13
+
14
+ ## Entry Criteria
15
+
16
+ - Add entries only for breaking changes, mid/high-interest solutions, architectural decisions, repeated issue patterns, or project-specific conventions with future value.
17
+ - Do not add minimal, obvious, one-off, or insignificant changes.
18
+ - Do not paste full review transcripts.
19
+ - Every change to this file must update the changelog at the end.
20
+
21
+ ## Entry Template
22
+
23
+ \`\`\`md
24
+ ## YYYY-MM-DD - Short Decision Title
25
+
26
+ - Interest level: Mid | High | Breaking
27
+ - Context:
28
+ - Decision / Insight:
29
+ - Rationale:
30
+ - Avoid repeating:
31
+ - Source:
32
+ \`\`\`
33
+
34
+ ## Changelog
35
+
36
+ - YYYY-MM-DD: Created/updated entry "<title>" because <why>.
37
+ `;
9
38
  const AGENT_INSTALL_PROFILES = {
10
39
  standard: {
11
40
  instructionFiles: [["AGENTS.md"]],
@@ -263,10 +292,60 @@ export function buildInstallPlan({ cwd, detections, skills, agents }) {
263
292
  tags: skill.tags
264
293
  })),
265
294
  installRoot: path.join(cwd, ".skilly-hand"),
295
+ decisionsRegistry: {
296
+ path: path.join(cwd, ".ai", "DECISIONS.md"),
297
+ relativePath: DECISIONS_REGISTRY_RELATIVE_PATH,
298
+ exists: false,
299
+ willCreate: true
300
+ },
266
301
  generatedAt: nowIso()
267
302
  };
268
303
  }
269
304
 
305
+ async function planDecisionsRegistry(cwd) {
306
+ const aiDir = path.join(cwd, ".ai");
307
+ const registryPath = path.join(cwd, ".ai", "DECISIONS.md");
308
+
309
+ if (await exists(aiDir)) {
310
+ const info = await lstat(aiDir);
311
+ if (!info.isDirectory()) {
312
+ throw new Error("Cannot create decisions registry because .ai exists and is not a directory.");
313
+ }
314
+ }
315
+
316
+ let registryExists = false;
317
+ if (await exists(registryPath)) {
318
+ const info = await lstat(registryPath);
319
+ if (!info.isFile()) {
320
+ throw new Error("Cannot use decisions registry because .ai/DECISIONS.md exists and is not a file.");
321
+ }
322
+ registryExists = true;
323
+ }
324
+
325
+ return {
326
+ path: registryPath,
327
+ relativePath: DECISIONS_REGISTRY_RELATIVE_PATH,
328
+ exists: registryExists,
329
+ willCreate: !registryExists
330
+ };
331
+ }
332
+
333
+ async function ensureDecisionsRegistry(cwd) {
334
+ const registry = await planDecisionsRegistry(cwd);
335
+ if (registry.exists) {
336
+ return registry;
337
+ }
338
+
339
+ await mkdir(path.dirname(registry.path), { recursive: true });
340
+ await writeFile(registry.path, DECISIONS_REGISTRY_TEMPLATE, "utf8");
341
+ return {
342
+ ...registry,
343
+ exists: true,
344
+ willCreate: false,
345
+ created: true
346
+ };
347
+ }
348
+
270
349
  async function backupPathIfNeeded(targetPath, backupsDir, lockData) {
271
350
  if (!(await exists(targetPath))) {
272
351
  return null;
@@ -600,6 +679,7 @@ export async function installProject({
600
679
  excludeTags: parseTags(excludeTags)
601
680
  });
602
681
  const plan = buildInstallPlan({ cwd, detections, skills, agents: selectedAgents });
682
+ plan.decisionsRegistry = await planDecisionsRegistry(cwd);
603
683
 
604
684
  if (dryRun) {
605
685
  return { plan, applied: false };
@@ -621,6 +701,8 @@ export async function installProject({
621
701
  await mkdir(installRoot, { recursive: true });
622
702
  await mkdir(targetCatalogDir, { recursive: true });
623
703
  await mkdir(backupsDir, { recursive: true });
704
+ const decisionsRegistry = await ensureDecisionsRegistry(cwd);
705
+ plan.decisionsRegistry = decisionsRegistry;
624
706
 
625
707
  for (const skill of skills) {
626
708
  await copySkillTo(targetCatalogDir, skill.id);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skilly-hand/detectors",
3
- "version": "0.23.2",
3
+ "version": "0.24.0",
4
4
  "private": true,
5
5
  "type": "module"
6
6
  }