create-pathfinder 4.0.0 → 4.1.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/CLAUDE.md +1 -0
- package/package.json +1 -1
- package/skills/hooksmith/SKILL.md +265 -0
package/CLAUDE.md
CHANGED
|
@@ -103,4 +103,5 @@ An adapter carries the canonical skill's frontmatter and a pointer to it, and no
|
|
|
103
103
|
- `role` — explicitly override the role the lifecycle would assume
|
|
104
104
|
- `whereami` — report a compact read-only snapshot of the current session
|
|
105
105
|
- `skillsmith` — teach and create small local skills
|
|
106
|
+
- `hooksmith` — turn a described guarantee into one verified hook for the active harness
|
|
106
107
|
- `setup-tracker` — choose the canonical ticket store when it is not local Markdown
|
package/package.json
CHANGED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hooksmith
|
|
3
|
+
description: Turn a plain-English automation or deterministic guarantee into the smallest working, correctly scoped, verified hook for the active AI coding harness.
|
|
4
|
+
argument-hint: [what the hook must guarantee or do]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Hooksmith
|
|
8
|
+
|
|
9
|
+
A skill is reusable reasoning. A hook is deterministic lifecycle automation.
|
|
10
|
+
|
|
11
|
+
> A skill asks. A hook guarantees.
|
|
12
|
+
|
|
13
|
+
Start from the behavior the human describes. Do not start from a harness, an
|
|
14
|
+
event name, a settings file, or a script.
|
|
15
|
+
|
|
16
|
+
A hook is trusted executable configuration: it runs automatically, with the
|
|
17
|
+
human's credentials, every time its trigger matches, and nothing asks first.
|
|
18
|
+
Build one the way you would accept a change to CI.
|
|
19
|
+
|
|
20
|
+
## 1. Decide whether this should be a hook
|
|
21
|
+
|
|
22
|
+
Answer before anything else, out loud:
|
|
23
|
+
|
|
24
|
+
- deterministic lifecycle behavior — a guarantee, or an automatic reaction to
|
|
25
|
+
something the session did → hook candidate
|
|
26
|
+
- judgment or reasoning workflow → a skill; use `skillsmith`
|
|
27
|
+
- something a human runs when they want it → a script, a command, or a Make
|
|
28
|
+
target
|
|
29
|
+
|
|
30
|
+
Example: "never allow edits to approved Feature specs." Whether the rule holds
|
|
31
|
+
cannot depend on an agent remembering it, and the answer is a path comparison.
|
|
32
|
+
That is a hook.
|
|
33
|
+
|
|
34
|
+
Anti-example: "review whether this implementation actually satisfies the
|
|
35
|
+
Feature." That is a reading of intent against evidence. No trigger expresses it,
|
|
36
|
+
and a hook that approximates it will block correct work and pass incorrect work.
|
|
37
|
+
It belongs in a reviewer skill.
|
|
38
|
+
|
|
39
|
+
Say which of the three the request is. Concluding "this is not a hook" is a
|
|
40
|
+
successful outcome of this skill — stop there and name what to use instead.
|
|
41
|
+
|
|
42
|
+
## 2. Describe the hook without naming a harness
|
|
43
|
+
|
|
44
|
+
Write the behavior down in these terms, and only these, before looking at any
|
|
45
|
+
harness:
|
|
46
|
+
|
|
47
|
+
- **lifecycle moment** — what point in the session's life this attaches to
|
|
48
|
+
- **trigger** — what narrows it to the cases the human means
|
|
49
|
+
- **action** — what actually happens when it fires
|
|
50
|
+
- **blocking or non-blocking** — must it *stop* something, or only react to it
|
|
51
|
+
- **ownership and scope** — whose sessions this fires in
|
|
52
|
+
- **failure behavior** — what happens when the hook itself errors
|
|
53
|
+
- **verification** — what would prove it works, and what would prove it does not
|
|
54
|
+
|
|
55
|
+
The worked example becomes:
|
|
56
|
+
|
|
57
|
+
> pre-action, blocking file-mutation guard on the approved Feature spec paths,
|
|
58
|
+
> owned by the project or the kit, failing closed only if the check is trivially
|
|
59
|
+
> correct, verified by one edit that must pass and one that must be refused.
|
|
60
|
+
|
|
61
|
+
That paragraph is the portable contract: what the hook must guarantee, stated in
|
|
62
|
+
terms no harness owns. What follows it is four different things, and keeping
|
|
63
|
+
them apart is the point of the rest of this skill — translation onto one
|
|
64
|
+
harness's primitives (step 4), implementation of the action (step 5–6),
|
|
65
|
+
configuration that installs it (step 7), and verification that it actually
|
|
66
|
+
behaves that way (step 8). Only the first is translation.
|
|
67
|
+
|
|
68
|
+
Keep this description in the report. It is what survives a change of harness.
|
|
69
|
+
|
|
70
|
+
## 3. Identify the active harness and read what it can actually do
|
|
71
|
+
|
|
72
|
+
Name the harness this session is running in. Then inspect its current hook or
|
|
73
|
+
lifecycle capabilities and conventions — its documentation, its configuration
|
|
74
|
+
files, what it already has configured — rather than assuming they match another
|
|
75
|
+
harness or match what you remember.
|
|
76
|
+
|
|
77
|
+
Confirm four things before translating anything:
|
|
78
|
+
|
|
79
|
+
- which lifecycle moments it exposes, and their real names
|
|
80
|
+
- how a trigger is expressed, and how precisely it can narrow
|
|
81
|
+
- whether the moment you need can **block**, or only observe
|
|
82
|
+
- where the configuration lives, and what scopes it offers
|
|
83
|
+
|
|
84
|
+
If the harness exposes no equivalent lifecycle primitive, or exposes one that
|
|
85
|
+
cannot block when the guarantee requires blocking, say so plainly and stop. A
|
|
86
|
+
guarantee the harness cannot enforce is not a hook — it is a rule, a skill, or a
|
|
87
|
+
check the human runs. Do not build something that looks like enforcement and is
|
|
88
|
+
not.
|
|
89
|
+
|
|
90
|
+
### Claude Code
|
|
91
|
+
|
|
92
|
+
The first harness this skill supports concretely, and a reference for what a
|
|
93
|
+
translation looks like — not the definition of a hook.
|
|
94
|
+
|
|
95
|
+
Under Claude Code, read the current documentation before relying on any detail:
|
|
96
|
+
|
|
97
|
+
- https://code.claude.com/docs/en/hooks.md — reference
|
|
98
|
+
- https://code.claude.com/docs/en/hooks-guide.md — examples
|
|
99
|
+
|
|
100
|
+
That contract changes faster than any skill describing it, which is why nothing
|
|
101
|
+
here restates its event list. Once confirmed against the fetched page, use its
|
|
102
|
+
own vocabulary directly — the lifecycle event names, the matcher and condition
|
|
103
|
+
syntax, the handler types, the settings and plugin locations, the way a handler
|
|
104
|
+
receives input and returns a decision. Naming them is correct here and wrong
|
|
105
|
+
anywhere else.
|
|
106
|
+
|
|
107
|
+
Under any other harness, use that harness's native equivalent on the same terms:
|
|
108
|
+
read its documentation first, then speak its vocabulary.
|
|
109
|
+
|
|
110
|
+
#### The worked example, realized here
|
|
111
|
+
|
|
112
|
+
The step 2 description — *pre-action, blocking file-mutation guard on the
|
|
113
|
+
approved Feature spec paths, owned by the project or the kit* — becomes, under
|
|
114
|
+
this harness and no other:
|
|
115
|
+
|
|
116
|
+
| Portable term | Claude Code realization |
|
|
117
|
+
| --- | --- |
|
|
118
|
+
| lifecycle moment, pre-action | a `PreToolUse` event, which fires before the tool call and can block it |
|
|
119
|
+
| trigger | a matcher on the file-writing tools, narrowed further by an `if` condition on the spec paths |
|
|
120
|
+
| blocking | a denying permission decision, or exit code 2, returned by the handler |
|
|
121
|
+
| ownership, project or kit | `.claude/settings.json` in the repository, or the plugin's `hooks/hooks.json` |
|
|
122
|
+
|
|
123
|
+
Every cell on the right is this harness's dialect. Another harness answers the
|
|
124
|
+
same four questions with different names, or cannot answer one of them at all —
|
|
125
|
+
which is what step 3 is for. Treat the table as an illustration of the shape of
|
|
126
|
+
a translation, and confirm each cell against the documentation you just fetched
|
|
127
|
+
before relying on it; the names and the decision format change.
|
|
128
|
+
|
|
129
|
+
## 4. Translate, narrowest first
|
|
130
|
+
|
|
131
|
+
Map the description from step 2 onto what step 3 found:
|
|
132
|
+
|
|
133
|
+
- the lifecycle moment → the harness's nearest real moment, blocking-capable if
|
|
134
|
+
the guarantee needs it
|
|
135
|
+
- the trigger → the narrowest expression the harness supports; a trigger that
|
|
136
|
+
fires on everything is a noise problem that hides the cases the hook exists for
|
|
137
|
+
- ownership → the smallest scope that delivers the guarantee. Scope is a blast
|
|
138
|
+
radius: a guarantee one person wants does not belong in everyone's
|
|
139
|
+
configuration, and a project guarantee does not belong in something that ships
|
|
140
|
+
to other people's projects.
|
|
141
|
+
|
|
142
|
+
State every place the translation is imperfect. The guarantee is only as strong
|
|
143
|
+
as the trigger, so say plainly what it does not catch.
|
|
144
|
+
|
|
145
|
+
For a hook that ships with Pathfinder, prefer what the installation environment
|
|
146
|
+
already guarantees. A hook needing a runtime, a package manager, or a dependency
|
|
147
|
+
the kit does not already assume is a hook Pathfinder cannot ship.
|
|
148
|
+
|
|
149
|
+
### Two approval gates
|
|
150
|
+
|
|
151
|
+
They are independent, and either one can apply:
|
|
152
|
+
|
|
153
|
+
- **Location.** Writing outside the repository — user settings, machine
|
|
154
|
+
configuration — needs approval.
|
|
155
|
+
- **Blast radius.** Installing or changing a hook whose behavior reaches beyond
|
|
156
|
+
the human's own private, local configuration needs approval, wherever the file
|
|
157
|
+
sits. That covers a project hook committed to the repository and a hook
|
|
158
|
+
shipped by Pathfinder or a plugin: both make other people's sessions behave
|
|
159
|
+
differently, and neither is yours to decide.
|
|
160
|
+
|
|
161
|
+
Building and testing a candidate hook in a scratch or local-only place is not
|
|
162
|
+
gated. Ask at the moment of installing or modifying shared automatic behavior,
|
|
163
|
+
not before experimenting.
|
|
164
|
+
|
|
165
|
+
## 5. Choose the smallest reliable action
|
|
166
|
+
|
|
167
|
+
Prefer, in order: what the harness's own handler types give you for free; a
|
|
168
|
+
short shell command; a small script in a runtime the environment already has.
|
|
169
|
+
Choose a language because it is present and appropriate, not out of habit.
|
|
170
|
+
|
|
171
|
+
The action runs in the harness's environment, not the human's shell. Do not
|
|
172
|
+
assume a project's virtual environment, `PATH`, or dependencies are active. If
|
|
173
|
+
the hook must run a project command, run it as the human would type it, in the
|
|
174
|
+
project directory, and confirm it resolves there — a hook that always fails
|
|
175
|
+
looks exactly like a hook that always works.
|
|
176
|
+
|
|
177
|
+
## 6. Decide failure and recursion behavior
|
|
178
|
+
|
|
179
|
+
State the choice explicitly:
|
|
180
|
+
|
|
181
|
+
- **fail open** — an unexpected error allows the action. The default. A broken
|
|
182
|
+
hook must not brick a session.
|
|
183
|
+
- **fail closed** — an unexpected error blocks. Only for a real safety boundary,
|
|
184
|
+
and only when the check is simple enough to be obviously correct.
|
|
185
|
+
|
|
186
|
+
A hook attached to the end of a turn must not block the very ending it caused.
|
|
187
|
+
Find the harness's re-entry signal and exit early when it is set. A hook that
|
|
188
|
+
loops is worse than no hook.
|
|
189
|
+
|
|
190
|
+
Keep the action fast. It runs on every match.
|
|
191
|
+
|
|
192
|
+
## 7. Merge, never overwrite
|
|
193
|
+
|
|
194
|
+
Read the existing configuration before writing. Add this hook to what is already
|
|
195
|
+
there; leave every other moment and every other hook intact. Losing someone's
|
|
196
|
+
unrelated hook is a silent, hard-to-notice failure.
|
|
197
|
+
|
|
198
|
+
## 8. Prove it, both ways
|
|
199
|
+
|
|
200
|
+
Run the hook, the way this harness runs hooks. Verification is where the
|
|
201
|
+
abstraction ends: use the harness's real invocation, real input shape, and real
|
|
202
|
+
signals.
|
|
203
|
+
|
|
204
|
+
Verify both sides of the boundary:
|
|
205
|
+
|
|
206
|
+
- a case that must be **allowed** — it passes
|
|
207
|
+
- a case that must **trigger, block, or react** — it fires, with a reason a
|
|
208
|
+
reader would understand
|
|
209
|
+
|
|
210
|
+
A hook that responds identically to both is broken, whichever way it responds.
|
|
211
|
+
Fix it and re-run before reporting anything.
|
|
212
|
+
|
|
213
|
+
Never report success from reading the code. A hook that always blocks and a hook
|
|
214
|
+
that always allows are indistinguishable on the page.
|
|
215
|
+
|
|
216
|
+
## 9. Report
|
|
217
|
+
|
|
218
|
+
State:
|
|
219
|
+
|
|
220
|
+
- the harness-independent description from step 2
|
|
221
|
+
- the harness, and what its capabilities were confirmed to be
|
|
222
|
+
- what was created, and where it lives
|
|
223
|
+
- what triggers it, what it guarantees, and what it does not catch
|
|
224
|
+
- what was actually executed, and what each run proved
|
|
225
|
+
- the one line the human would edit to adjust it
|
|
226
|
+
- how the human can trigger it themselves
|
|
227
|
+
- that the hook runs automatically with their credentials, and should be
|
|
228
|
+
reviewed like any other executable configuration
|
|
229
|
+
|
|
230
|
+
Say plainly what could not be verified, and name anything the harness could not
|
|
231
|
+
enforce.
|
|
232
|
+
|
|
233
|
+
## Rules
|
|
234
|
+
|
|
235
|
+
- One hook per invocation. Finish it, verify it, report it, stop.
|
|
236
|
+
- Do not treat one harness's event names, configuration files, handler types, or
|
|
237
|
+
input and output contracts as universal. They are that harness's dialect.
|
|
238
|
+
- Do not build a cross-harness abstraction layer, runtime, adapter framework,
|
|
239
|
+
registry, or orchestration system. The abstraction is the reasoning in steps
|
|
240
|
+
1–2; everything written to disk is native to one harness.
|
|
241
|
+
- Do not write outside the repository — user settings, machine configuration —
|
|
242
|
+
without approval.
|
|
243
|
+
- Do not install or change a hook that affects anyone but the human running this
|
|
244
|
+
session — a project hook in the repository, a hook shipped by Pathfinder or a
|
|
245
|
+
plugin — without approval. Experimenting locally is free; making shared
|
|
246
|
+
automatic behavior is not.
|
|
247
|
+
- Do not add a dependency to make a hook possible. Choose a smaller hook.
|
|
248
|
+
- Do not weaken an existing hook to make a new one fit.
|
|
249
|
+
- Do not report a hook as working without having run it.
|
|
250
|
+
|
|
251
|
+
## Stop conditions
|
|
252
|
+
|
|
253
|
+
Stop and hand the decision back when:
|
|
254
|
+
|
|
255
|
+
- the behavior turns out to need judgment, and belongs in a skill
|
|
256
|
+
- the active harness has no equivalent primitive, or none that can block when
|
|
257
|
+
blocking is the point
|
|
258
|
+
- its documentation contradicts what the hook would rely on
|
|
259
|
+
- the guarantee cannot be expressed by any available trigger
|
|
260
|
+
- the correct scope is one the human has not approved, or is shared and the
|
|
261
|
+
human has not approved installing it
|
|
262
|
+
- verification cannot distinguish the allowed case from the blocked one
|
|
263
|
+
|
|
264
|
+
Keep version one small and easy to delete. A hook nobody can explain is a hook
|
|
265
|
+
nobody can trust.
|