Skip to content

Commit b2ac8d5

Browse files
committed
chore(fleet): cascade fleet-code from wheelhouse
1 parent 3adbdae commit b2ac8d5

1 file changed

Lines changed: 20 additions & 8 deletions

File tree

  • .claude/hooks/fleet/defer-to-script-nudge

.claude/hooks/fleet/defer-to-script-nudge/index.mts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,29 @@ export function maxCodeBlockLines(content: string): number {
4343
return max
4444
}
4545

46-
// True when the doc references a backing `scripts/**.mts` (the deferral target
47-
// a thin skill/command should point to). Scans the markdown content, not a
48-
// shell command line.
46+
// True when the doc references a backing `.mts` in ANY of the fleet's deferral
47+
// conventions: a `scripts/**.mts` path, a co-located `.claude/skills/**.mts`, or
48+
// a relative co-located `lib/**.mts` / `run.mts` the skill invokes (the dominant
49+
// skill-backing shape). Scans the markdown content, not a shell command line.
4950
export function referencesScript(content: string): boolean {
50-
return /\bscripts\/[^\s)'"]*\.mts\b/.test(content)
51+
return /(?:\bscripts\/[^\s)'"]*\.mts|\.claude\/skills\/[^\s)'"]*\.mts|\blib\/[^\s)'"]*\.mts|\brun\.mts)\b/.test(
52+
content,
53+
)
54+
}
55+
56+
// A `user-invocable: false` skill is a REFERENCE/doc — its fenced blocks are
57+
// examples, not an operation with logic to extract — so the thin-wrapper rule
58+
// doesn't apply and a large example block is not a smell.
59+
export function isReferenceSkill(content: string): boolean {
60+
return /^user-invocable:\s*false\b/m.test(content)
5161
}
5262

5363
export const hook = defineHook({
5464
check: editGuard((filePath, content) => {
5565
if (
5666
!content ||
5767
!isSkillOrCommandDoc(filePath) ||
68+
isReferenceSkill(content) ||
5869
maxCodeBlockLines(content) <= HEAVY_LINES ||
5970
referencesScript(content)
6071
) {
@@ -66,10 +77,11 @@ export const hook = defineHook({
6677
'',
6778
` File: ${filePath}`,
6879
'',
69-
` A fenced code block over ${HEAVY_LINES} lines with no backing`,
70-
' `scripts/**.mts` reference — inline logic in a skill/command is',
71-
' untested, unlinted, and not reusable. Move it to a script and invoke',
72-
' that from the markdown so the skill stays a thin wrapper.',
80+
` A fenced code block over ${HEAVY_LINES} lines with no backing \`.mts\``,
81+
' reference (`scripts/**.mts`, a co-located `lib/*.mts`, or `run.mts`) —',
82+
' inline logic in a skill/command is untested, unlinted, and not',
83+
' reusable. Move it to a script and invoke that from the markdown so the',
84+
' skill stays a thin wrapper.',
7385
].join('\n'),
7486
)
7587
}),

0 commit comments

Comments
 (0)