@skilly-hand/skilly-hand 0.24.0 → 0.25.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.25.0] - 2026-04-27
20
+ [View on npm](https://www.npmjs.com/package/@skilly-hand/skilly-hand/v/0.25.0)
21
+
22
+ ### Added
23
+ - Added the `roaster` planning challenge skill to critique plans, assumptions, sequencing, risks, and verification before implementation.
24
+ - Added native skill hook/rule metadata support so installed skills can surface required guidance in generated native adapter files.
25
+
26
+ ### Changed
27
+ - Updated native setup output and CLI guidance to describe rule/hook adapters alongside native instruction files.
28
+ - Exported deterministic native hook collection from core and included `nativeHooks` plus `nativeHooksStatus` in native setup plan output.
29
+
30
+ ### Fixed
31
+ - _None._
32
+
33
+ ### Removed
34
+ - _None._
35
+
19
36
  ## [0.24.0] - 2026-04-26
20
37
  [View on npm](https://www.npmjs.com/package/@skilly-hand/skilly-hand/v/0.24.0)
21
38
 
package/catalog/README.md CHANGED
@@ -14,6 +14,7 @@ Published portable skills consumed by the `skilly-hand` CLI.
14
14
  | `project-teacher` | 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. | core, workflow, education | all |
15
15
  | `react-guidelines` | Guide React code generation and review using latest stable React verification and modern framework best practices. | react, frontend, workflow, best-practices | all |
16
16
  | `review-rangers` | Review code, decisions, and artifacts through a multi-perspective committee and a domain expert safety guard, then synthesize a structured verdict. | core, workflow, review, quality | all |
17
+ | `roaster` | Challenge plans with constructive roast-style critique that exposes weak assumptions, missing angles, shallow sequencing, and unclear success criteria. Trigger: when the user proposes, requests, or evaluates a plan of any kind. | core, workflow, planning, quality | all |
17
18
  | `skill-creator` | Create and standardize AI skills with reusable structure, metadata rules, and templates. | core, workflow, authoring | all |
18
19
  | `spec-driven-development` | Plan, execute, and verify multi-step work through versioned specs with small, testable tasks. | core, workflow, planning | all |
19
20
  | `test-driven-development` | 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. | testing, workflow, quality, core | all |
@@ -9,6 +9,7 @@
9
9
  "project-teacher",
10
10
  "react-guidelines",
11
11
  "review-rangers",
12
+ "roaster",
12
13
  "skill-creator",
13
14
  "spec-driven-development",
14
15
  "test-driven-development",
@@ -0,0 +1,180 @@
1
+ ---
2
+ name: "roaster"
3
+ description: "Challenge plans with constructive roast-style critique that exposes weak assumptions, missing angles, shallow sequencing, and unclear success criteria. Trigger: when the user proposes, requests, or evaluates a plan of any kind."
4
+ skillMetadata:
5
+ author: "skilly-hand"
6
+ last-edit: "2026-04-27"
7
+ license: "Apache-2.0"
8
+ version: "1.0.0"
9
+ changelog: "Added roaster planning challenge skill; improves plan quality by forcing constructive skepticism before agreement; affects planning critique workflows and auto-invoke routing"
10
+ auto-invoke: "When the user proposes, requests, or evaluates a plan of any kind"
11
+ allowed-tools:
12
+ - "Read"
13
+ - "Edit"
14
+ - "Write"
15
+ - "Glob"
16
+ - "Grep"
17
+ - "Bash"
18
+ - "Task"
19
+ ---
20
+ # Roaster Guide
21
+
22
+ ## When to Use
23
+
24
+ Use this skill when:
25
+
26
+ - The user proposes, requests, or evaluates a plan.
27
+ - A plan sounds under-specified, too agreeable, or too easy.
28
+ - The user needs stronger assumptions, sharper scope, or better sequencing.
29
+ - The work would benefit from a skeptical partner before execution.
30
+
31
+ Do not use this skill for:
32
+
33
+ - Emergencies where speed matters more than critique.
34
+ - Trivial one-step tasks with no meaningful planning surface.
35
+ - Sensitive emotional, medical, legal, or crisis conversations where roast tone would be inappropriate.
36
+ - Personal attacks, identity jokes, humiliation, slurs, or cruelty.
37
+
38
+ ---
39
+
40
+ ## Critical Patterns
41
+
42
+ ### Pattern 1: Challenge First, Agree Second
43
+
44
+ Default posture:
45
+
46
+ ```text
47
+ Do not start with "yes, you are right."
48
+ First identify the weakest part of the plan.
49
+ Then acknowledge what works, if anything works.
50
+ End with a stronger version of the plan or the questions needed to make one.
51
+ ```
52
+
53
+ The target is the plan, not the person. Roast the gap between ambition and current rigor.
54
+
55
+ ### Pattern 2: Constructive Roast Boundaries
56
+
57
+ Allowed:
58
+
59
+ - Witty, direct critique of vague goals, missing constraints, shallow sequencing, or lazy acceptance criteria.
60
+ - High standards, pointed questions, and clear pushback.
61
+ - Humor that helps the user think harder.
62
+
63
+ Not allowed:
64
+
65
+ - Insults about intelligence, identity, background, appearance, worth, or mental health.
66
+ - Discriminatory, sexual, threatening, or demeaning language.
67
+ - Sarcasm that leaves the user with no actionable next step.
68
+
69
+ ### Pattern 3: Full-Angle Critique
70
+
71
+ Check every real plan against these angles:
72
+
73
+ | Angle | Challenge |
74
+ | --- | --- |
75
+ | Goal | Is the outcome specific enough to judge success? |
76
+ | Assumptions | What is being treated as true without evidence? |
77
+ | Stakeholders | Who is affected, blocked, or missing from the plan? |
78
+ | Scope | What is included, excluded, and dangerously implied? |
79
+ | Risks | What can fail technically, socially, financially, or operationally? |
80
+ | Sequencing | Are steps ordered by dependency, learning value, and risk reduction? |
81
+ | Alternatives | Is there a simpler, more complete, or more durable path? |
82
+ | Verification | How will the user prove the result is good enough? |
83
+
84
+ ### Pattern 4: Escalate With Stakes
85
+
86
+ Use light critique for small plans. Escalate to deeper challenge when the plan affects:
87
+
88
+ - Architecture or long-term maintainability.
89
+ - Security, privacy, or safety.
90
+ - Delivery timelines, money, reputation, or users.
91
+ - Irreversible decisions or broad organizational impact.
92
+
93
+ ---
94
+
95
+ ## Response Format
96
+
97
+ Use this structure by default:
98
+
99
+ ```text
100
+ Verdict: {short judgment}
101
+
102
+ Roast: {constructive jab at the weakest part}
103
+
104
+ Blind Spots:
105
+ - {missing angle}
106
+ - {missing angle}
107
+
108
+ Upgrade:
109
+ - {specific improvement}
110
+ - {specific improvement}
111
+
112
+ Questions:
113
+ - {question that materially improves the plan}
114
+ ```
115
+
116
+ Keep it compact unless the plan is high-risk or the user asks for a deeper review.
117
+
118
+ ---
119
+
120
+ ## Decision Tree
121
+
122
+ ```text
123
+ Is this a plan or planning request? -> Use roaster
124
+ Is it trivial and one-step? -> Skip or give one-line challenge
125
+ Does it affect high-stakes outcomes? -> Deep critique across all angles
126
+ Is the user asking for validation only? -> Challenge before validating
127
+ Is roast tone unsafe for the situation? -> Switch to firm, compassionate critique
128
+ Otherwise -> Constructive roast with actionable upgrade
129
+ ```
130
+
131
+ ---
132
+
133
+ ## Examples
134
+
135
+ ### Example 1: Vague Product Plan
136
+
137
+ ```text
138
+ Verdict: Promising, but currently held together with vibes and hope.
139
+
140
+ Roast: "Launch the feature" is not a plan; it is a calendar event wearing a fake mustache.
141
+
142
+ Blind Spots:
143
+ - No target user or success metric.
144
+ - No rollback or support path.
145
+
146
+ Upgrade:
147
+ - Define the primary user, the measurable outcome, and the smallest launch slice.
148
+ - Add one validation step before build and one verification step after release.
149
+
150
+ Questions:
151
+ - What evidence would prove this is worth building before you spend the full effort?
152
+ ```
153
+
154
+ ### Example 2: Technical Refactor Plan
155
+
156
+ ```text
157
+ Verdict: The direction is reasonable, but the blast radius is undercooked.
158
+
159
+ Roast: "Refactor the service" is how regressions enter the room wearing a nice jacket.
160
+
161
+ Blind Spots:
162
+ - No compatibility strategy for existing callers.
163
+ - No test boundary around current behavior.
164
+
165
+ Upgrade:
166
+ - Capture current behavior with focused tests before changing internals.
167
+ - Refactor behind the existing public interface first, then evaluate API changes separately.
168
+
169
+ Questions:
170
+ - Which behavior must remain identical after the refactor?
171
+ ```
172
+
173
+ ---
174
+
175
+ ## Commands
176
+
177
+ ```bash
178
+ rg -n "plan|proposal|roadmap|strategy|approach" .
179
+ rg -n "success criteria|acceptance criteria|risks|assumptions" .
180
+ ```
@@ -0,0 +1,41 @@
1
+ {
2
+ "id": "roaster",
3
+ "title": "Roaster",
4
+ "description": "Challenge plans with constructive roast-style critique that exposes weak assumptions, missing angles, shallow sequencing, and unclear success criteria. Trigger: when the user proposes, requests, or evaluates a plan of any kind.",
5
+ "portable": true,
6
+ "tags": ["core", "workflow", "planning", "quality"],
7
+ "detectors": ["always"],
8
+ "detectionTriggers": ["always"],
9
+ "installsFor": ["all"],
10
+ "agentSupport": ["codex", "claude", "cursor", "gemini", "copilot", "antigravity", "windsurf", "trae"],
11
+ "nativeHooks": [
12
+ {
13
+ "id": "plan-challenge",
14
+ "trigger": "When the user proposes, requests, or evaluates a plan of any kind",
15
+ "instruction": "Invoke roaster to critique assumptions, scope, sequencing, risks, and verification before agreeing with the plan.",
16
+ "priority": 30,
17
+ "enforcement": "required"
18
+ }
19
+ ],
20
+ "skillMetadata": {
21
+ "author": "skilly-hand",
22
+ "last-edit": "2026-04-27",
23
+ "license": "Apache-2.0",
24
+ "version": "1.0.0",
25
+ "changelog": "Added roaster planning challenge skill; improves plan quality by forcing constructive skepticism before agreement; affects planning critique workflows and auto-invoke routing",
26
+ "auto-invoke": "When the user proposes, requests, or evaluates a plan of any kind",
27
+ "allowed-tools": [
28
+ "Read",
29
+ "Edit",
30
+ "Write",
31
+ "Glob",
32
+ "Grep",
33
+ "Bash",
34
+ "Task"
35
+ ]
36
+ },
37
+ "files": [
38
+ { "path": "SKILL.md", "kind": "instruction" }
39
+ ],
40
+ "dependencies": []
41
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skilly-hand/skilly-hand",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "license": "CC-BY-NC-4.0",
5
5
  "type": "module",
6
6
  "repository": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skilly-hand/catalog",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "private": true,
5
5
  "type": "module"
6
6
  }
@@ -80,6 +80,8 @@ export function validateSkillManifest(manifest) {
80
80
  throw new Error(`Skill "${manifest.id}" must declare files`);
81
81
  }
82
82
 
83
+ validateNativeHooks(manifest);
84
+
83
85
  const hasSkillInstruction = manifest.files.some((file) => file.path === "SKILL.md" && file.kind === "instruction");
84
86
  if (!hasSkillInstruction) {
85
87
  throw new Error(`Skill "${manifest.id}" must include files entry for SKILL.md as instruction`);
@@ -90,6 +92,36 @@ export function validateSkillManifest(manifest) {
90
92
  return true;
91
93
  }
92
94
 
95
+ function validateNativeHooks(manifest) {
96
+ if (!("nativeHooks" in manifest)) {
97
+ return;
98
+ }
99
+
100
+ if (!Array.isArray(manifest.nativeHooks)) {
101
+ throw new Error(`Skill "${manifest.id}" must declare nativeHooks as an array when present`);
102
+ }
103
+
104
+ for (const hook of manifest.nativeHooks) {
105
+ if (!hook || typeof hook !== "object" || Array.isArray(hook)) {
106
+ throw new Error(`Skill "${manifest.id}" has invalid nativeHooks entry; expected an object`);
107
+ }
108
+
109
+ for (const key of ["id", "trigger", "instruction", "enforcement"]) {
110
+ if (typeof hook[key] !== "string" || hook[key].trim().length === 0) {
111
+ throw new Error(`Skill "${manifest.id}" has invalid nativeHooks.${key}; expected a non-empty string`);
112
+ }
113
+ }
114
+
115
+ if (!["required", "recommended"].includes(hook.enforcement)) {
116
+ throw new Error(`Skill "${manifest.id}" has invalid nativeHooks.enforcement; expected required or recommended`);
117
+ }
118
+
119
+ if (!Number.isFinite(hook.priority)) {
120
+ throw new Error(`Skill "${manifest.id}" has invalid nativeHooks.priority; expected a finite number`);
121
+ }
122
+ }
123
+ }
124
+
93
125
  function toLf(text) {
94
126
  return text.replaceAll("\r\n", "\n");
95
127
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skilly-hand/cli",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "bin": {
@@ -186,7 +186,7 @@ function buildInstallResultDoc(result, flags, detectionGridText = "") {
186
186
  result.applied
187
187
  ? [
188
188
  "Review generated AGENTS and assistant instruction files.",
189
- "Run `npx skilly-hand native setup` to scaffold native instruction/rule adapters.",
189
+ "Run `npx skilly-hand native setup` to scaffold native instruction/rule/hook adapters.",
190
190
  "Run `npx skilly-hand doctor` to validate installation health.",
191
191
  "Use `npx skilly-hand uninstall` to restore backed-up files if needed."
192
192
  ]
@@ -228,7 +228,7 @@ function buildNativeSetupResultDoc(result, flags) {
228
228
  ]),
229
229
  section("Status", [
230
230
  result.applied
231
- ? statusBlock("success", "Native setup completed.", "Native rule/instruction files are synchronized.")
231
+ ? statusBlock("success", "Native setup completed.", "Native rule/hook/instruction files are synchronized.")
232
232
  : statusBlock("info", "Native setup dry run complete.", "No files were written.")
233
233
  ]),
234
234
  section("Next Steps", [
@@ -236,10 +236,10 @@ function buildNativeSetupResultDoc(result, flags) {
236
236
  result.applied
237
237
  ? [
238
238
  "Run `npx skilly-hand doctor` to verify native coverage.",
239
- "Re-run `npx skilly-hand native setup` after changing agent targets."
239
+ "Re-run `npx skilly-hand native setup` after changing agent targets or skill hook metadata."
240
240
  ]
241
241
  : [
242
- "Run `npx skilly-hand native setup` to apply these native adapter changes."
242
+ "Run `npx skilly-hand native setup` to apply these native rule/hook adapter changes."
243
243
  ]
244
244
  )
245
245
  ])
@@ -10,7 +10,7 @@ const CLI_COMMANDS = [
10
10
  {
11
11
  value: "native-setup",
12
12
  label: "Native Setup",
13
- description: "Sync native assistant adapters and instruction files.",
13
+ description: "Sync native assistant adapters, rules, hooks, and instruction files.",
14
14
  bestFor: "After install or when assistant targets change",
15
15
  aliases: ["native", "adapters"],
16
16
  usage: "npx skilly-hand native setup"
@@ -105,4 +105,3 @@ export function formatHelpUsageLines() {
105
105
  ...CLI_COMMANDS.map((command) => command.usage)
106
106
  ];
107
107
  }
108
-
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skilly-hand/core",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "private": true,
5
5
  "type": "module"
6
6
  }
@@ -178,19 +178,57 @@ function resolveNativeAdapterTarget(cwd, adapter) {
178
178
  return path.join(cwd, ...adapter.targetPath);
179
179
  }
180
180
 
181
- function buildNativeRuleContent(agent, adapter) {
181
+ export function collectNativeHooks({ catalog, skillIds = [] }) {
182
+ const selected = new Set(skillIds);
183
+ return catalog
184
+ .filter((skill) => selected.has(skill.id))
185
+ .flatMap((skill) => (skill.nativeHooks || []).map((hook) => ({
186
+ skillId: skill.id,
187
+ skillTitle: skill.title,
188
+ id: hook.id,
189
+ trigger: hook.trigger,
190
+ instruction: hook.instruction,
191
+ priority: hook.priority,
192
+ enforcement: hook.enforcement
193
+ })))
194
+ .sort((a, b) => (
195
+ a.priority - b.priority ||
196
+ a.skillId.localeCompare(b.skillId) ||
197
+ a.id.localeCompare(b.id)
198
+ ));
199
+ }
200
+
201
+ function renderNativeHookLines(nativeHooks, nativeHooksStatus) {
202
+ if (nativeHooks.length === 0) {
203
+ const emptyMessage = nativeHooksStatus === "not-installed"
204
+ ? "No installed skill hooks found. Run `npx skilly-hand install` before native setup to enable skill-driven rules."
205
+ : "No installed skills declare native hooks or rules.";
206
+ return [`- ${emptyMessage}`];
207
+ }
208
+
209
+ return nativeHooks.flatMap((hook) => [
210
+ `- [${hook.enforcement}] ${hook.skillId}/${hook.id}`,
211
+ ` - Trigger: ${hook.trigger}`,
212
+ ` - Rule: ${hook.instruction}`
213
+ ]);
214
+ }
215
+
216
+ function buildNativeRuleContent(agent, adapter, nativeHooks = [], nativeHooksStatus = "not-installed") {
182
217
  const trigger = "Run token-optimizer before review-rangers when doing risk-heavy review passes.";
183
218
  return [
184
219
  `${NATIVE_SETUP_MARKER} Re-run \`npx skilly-hand native setup\` to regenerate. -->`,
185
220
  `# skilly-hand Native Bootstrap (${agent})`,
186
221
  "",
187
- `This file is managed by skilly-hand to keep native ${adapter.mode.replace("_", " ")} behavior consistent.`,
222
+ `This file is managed by skilly-hand to keep native ${adapter.mode.replace("_", " ")} rules/hooks consistent.`,
188
223
  "",
189
224
  "## Always-On Defaults",
190
225
  "- Apply AGENTS guidance from the repository root before task routing.",
191
226
  "- Enforce optimizer gate order: `token-optimizer` then `output-optimizer`.",
192
227
  "- Keep output concise by default (`step-brief`) unless user asks otherwise.",
193
228
  "",
229
+ "## Skill Hooks / Rules",
230
+ ...renderNativeHookLines(nativeHooks, nativeHooksStatus),
231
+ "",
194
232
  "## Token-Safe Review Stage",
195
233
  `- ${trigger}`,
196
234
  "- Keep review verdicts concise unless a blocker requires expanded rationale.",
@@ -572,6 +610,10 @@ export async function setupNativeProject({
572
610
  const lockPath = path.join(installRoot, "manifest.lock.json");
573
611
  const previousLock = await exists(lockPath) ? await readJson(lockPath) : null;
574
612
  const selectedAgents = normalizeAgentList(agents ?? previousLock?.agents);
613
+ const catalog = await loadAllSkills();
614
+ const installedSkillIds = previousLock?.skills || [];
615
+ const nativeHooks = collectNativeHooks({ catalog, skillIds: installedSkillIds });
616
+ const nativeHooksStatus = installedSkillIds.length > 0 ? "loaded" : "not-installed";
575
617
  const selectedNativeTargets = selectedAgents
576
618
  .map((agent) => NATIVE_ADAPTER_REGISTRY[agent])
577
619
  .filter((adapter) => adapter && adapter.supported)
@@ -584,7 +626,9 @@ export async function setupNativeProject({
584
626
  generatedAt,
585
627
  agents: selectedAgents,
586
628
  installRoot,
587
- nativeStatus: nativeStatusBefore
629
+ nativeStatus: nativeStatusBefore,
630
+ nativeHooks,
631
+ nativeHooksStatus
588
632
  };
589
633
 
590
634
  if (dryRun) {
@@ -637,7 +681,7 @@ export async function setupNativeProject({
637
681
  }
638
682
 
639
683
  const targetPath = resolveNativeAdapterTarget(cwd, adapter);
640
- const content = buildNativeRuleContent(agent, adapter);
684
+ const content = buildNativeRuleContent(agent, adapter, nativeHooks, nativeHooksStatus);
641
685
  await ensureManagedTextFile(targetPath, content, backupsDir, lockData, "managedNativeFiles");
642
686
  lockData.nativeProfiles[agent] = {
643
687
  status: "configured",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skilly-hand/detectors",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "private": true,
5
5
  "type": "module"
6
6
  }