@skilly-hand/skilly-hand 0.23.3 → 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,23 @@ 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
+
19
36
  ## [0.23.3] - 2026-04-20
20
37
  [View on npm](https://www.npmjs.com/package/@skilly-hand/skilly-hand/v/0.23.3)
21
38
 
@@ -3,13 +3,15 @@ name: "review-rangers"
3
3
  description: "Review code, decisions, and artifacts through a multi-perspective committee and a domain expert safety guard, then synthesize a structured verdict."
4
4
  skillMetadata:
5
5
  author: "skilly-hand"
6
- last-edit: "2026-04-04"
6
+ last-edit: "2026-04-26"
7
7
  license: "Apache-2.0"
8
- version: "1.0.0"
9
- 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"
10
10
  auto-invoke: "Reviewing code, decisions, or artifacts where adversarial multi-perspective evaluation adds value"
11
11
  allowed-tools:
12
12
  - "Read"
13
+ - "Edit"
14
+ - "Write"
13
15
  - "Grep"
14
16
  - "Glob"
15
17
  - "Bash"
@@ -38,14 +40,16 @@ Do not use this skill for:
38
40
  ## Core Workflow
39
41
 
40
42
  1. Identify the target (code, decision, artifact) and its domain.
41
- 2. Determine committee size: 3 members for routine reviews, 5 for high-risk or cross-domain targets.
42
- 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.
43
- 4. Determine the expert domain for the safety guard.
44
- 5. Spawn 1 safety guard using `assets/safety-guard-template.md`. It evaluates the target from an authoritative expert position.
45
- 6. Run the committee and safety guard in parallel.
46
- 7. Collect all outputs.
47
- 8. Synthesize a structured verdict following the Synthesis Rules.
48
- 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.
49
53
 
50
54
  ---
51
55
 
@@ -142,6 +146,56 @@ RECOMMENDED ACTION:
142
146
 
143
147
  ---
144
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
+
145
199
  ## Decision Tree
146
200
 
147
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",
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "@skilly-hand/skilly-hand",
3
- "version": "0.23.3",
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.3",
3
+ "version": "0.24.0",
4
4
  "private": true,
5
5
  "type": "module"
6
6
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skilly-hand/cli",
3
- "version": "0.23.3",
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.3",
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.3",
3
+ "version": "0.24.0",
4
4
  "private": true,
5
5
  "type": "module"
6
6
  }