@erclx/aitk 3.10.0 → 3.11.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.
Files changed (52) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/claude-markdown-propose/REQUIREMENT.md +48 -0
  3. package/claude/skills/claude-markdown-propose/SKILL.md +118 -0
  4. package/claude/skills/claude-markdown-propose/references/format.md +107 -0
  5. package/claude/skills/claude-pr-review/SKILL.md +1 -1
  6. package/claude/skills/claude-teach/SKILL.md +1 -1
  7. package/claude/skills/claude-worktree/SKILL.md +1 -1
  8. package/claude/skills/create-snippet/SKILL.md +1 -1
  9. package/claude/skills/git-branch/SKILL.md +1 -1
  10. package/claude/skills/git-commit/SKILL.md +1 -1
  11. package/claude/skills/git-issue/SKILL.md +2 -2
  12. package/claude/skills/git-pr/SKILL.md +5 -5
  13. package/claude/skills/git-split/SKILL.md +2 -2
  14. package/claude/skills/git-stage/SKILL.md +1 -1
  15. package/docs/agents/audits.md +2 -2
  16. package/docs/agents/records.md +1 -1
  17. package/docs/agents/teach.md +1 -1
  18. package/docs/ai-workflow.md +7 -6
  19. package/package.json +1 -1
  20. package/scripts/core/check-skill-paths.sh +1 -2
  21. package/scripts/core/verify.sh +0 -5
  22. package/src/audits/catalog.ts +20 -0
  23. package/src/claude/skills-audit.ts +7 -0
  24. package/src/commands/claude.ts +20 -6
  25. package/src/commands/comments.ts +6 -0
  26. package/src/commands/context.ts +32 -7
  27. package/src/commands/gov.ts +2 -2
  28. package/src/commands/markdown.ts +18 -2
  29. package/src/context/audit.ts +16 -0
  30. package/src/gov/test-order.ts +31 -7
  31. package/src/markdown/files.ts +10 -0
  32. package/src/records/backup.ts +1 -0
  33. package/src/records/validate.ts +1 -3
  34. package/{claude/skills/git-split/references → standards}/branch.md +0 -1
  35. package/{claude/skills/git-commit/references → standards}/commit.md +0 -1
  36. package/{claude/skills/claude-teach/references → standards}/glossary.md +0 -1
  37. package/standards/index.md +6 -0
  38. package/standards/{bundled/issue.md → issue.md} +0 -1
  39. package/standards/{bundled/pr.md → pr.md} +0 -1
  40. package/standards/{bundled/snippets.md → snippets.md} +0 -1
  41. package/claude/skills/claude-worktree/references/branch.md +0 -60
  42. package/claude/skills/create-snippet/references/snippets.md +0 -78
  43. package/claude/skills/git-branch/references/branch.md +0 -60
  44. package/claude/skills/git-issue/references/issue.md +0 -95
  45. package/claude/skills/git-pr/references/branch.md +0 -60
  46. package/claude/skills/git-pr/references/pr.md +0 -139
  47. package/claude/skills/git-split/references/pr.md +0 -139
  48. package/claude/skills/git-stage/references/commit.md +0 -73
  49. package/scripts/core/regen-skill-references.sh +0 -27
  50. package/standards/bundled/branch.md +0 -60
  51. package/standards/bundled/commit.md +0 -73
  52. package/standards/bundled/glossary.md +0 -76
@@ -20,6 +20,7 @@ import {
20
20
  REQUIREMENT_SECTIONS,
21
21
  type SkillFinding,
22
22
  type SkillsAudit,
23
+ type SkillsAuditRefusal,
23
24
  } from '@/claude/skills-audit'
24
25
  import {
25
26
  type RoutingRefusal,
@@ -862,8 +863,11 @@ async function runSkillsAudit(
862
863
 
863
864
  if (report.corpora.length === 0) {
864
865
  return refuseAudit(
866
+ 'no-corpus',
865
867
  `No skill corpus under ${root}. Looked for ${CORPORA.join(' and ')}.`,
866
868
  gateOnly,
869
+ root,
870
+ opts.json ?? false,
867
871
  )
868
872
  }
869
873
 
@@ -910,16 +914,26 @@ async function runSkillsAudit(
910
914
  return auditExitCode(report)
911
915
  }
912
916
 
913
- function refuseAudit(message: string, gateOnly: boolean): number {
917
+ function refuseAudit(
918
+ reason: SkillsAuditRefusal,
919
+ message: string,
920
+ gateOnly: boolean,
921
+ root: string,
922
+ emitJson: boolean,
923
+ ): number {
914
924
  if (gateOnly) {
915
925
  frameError(message)
916
- return 1
926
+ } else {
927
+ intro('aitk claude skills audit')
928
+ logStep('Refused')
929
+ logWarn(message)
930
+ outro()
931
+ }
932
+
933
+ if (emitJson) {
934
+ process.stdout.write(`${JSON.stringify({ root, reason, message })}\n`)
917
935
  }
918
936
 
919
- intro('aitk claude skills audit')
920
- logStep('Refused')
921
- logWarn(message)
922
- outro()
923
937
  return 1
924
938
  }
925
939
 
@@ -88,6 +88,12 @@ async function runScan(
88
88
  logStep('Refused')
89
89
  logWarn(languages)
90
90
  outro()
91
+
92
+ if (emitJson) {
93
+ process.stdout.write(
94
+ `${JSON.stringify({ root, reason: 'bad-languages', message: languages })}\n`,
95
+ )
96
+ }
91
97
  return 1
92
98
  }
93
99
 
@@ -1,6 +1,7 @@
1
1
  import { resolve } from 'node:path'
2
2
  import type { Command } from 'commander'
3
3
  import {
4
+ type ContextAuditRefusal,
4
5
  type EntryReport,
5
6
  governsContent,
6
7
  type LengthCause,
@@ -157,12 +158,17 @@ async function runAudit(
157
158
  // short a required section, which is the pass a gate exists to prevent.
158
159
  if (gateOnly && widened) {
159
160
  return refuse(
161
+ 'conflicting-options',
160
162
  '--citations-only runs the citation check alone, so --gate would widen the gate to findings the run never measures. Pass one.',
161
163
  gateOnly,
164
+ root,
165
+ opts.json ?? false,
162
166
  )
163
167
  }
164
168
 
165
- if (typeof names === 'string') return refuse(names, gateOnly)
169
+ if (typeof names === 'string') {
170
+ return refuse('bad-folder-list', names, gateOnly, root, opts.json ?? false)
171
+ }
166
172
 
167
173
  // The root base is opt-in. A target carrying a root `wireframes/` would
168
174
  // otherwise be audited against a standard it never adopted, on a bare run
@@ -173,8 +179,11 @@ async function runAudit(
173
179
  })
174
180
  if (folders.length === 0) {
175
181
  return refuse(
182
+ 'no-folders',
176
183
  `No audited folder found ${named ? 'under .claude/ or the project root' : 'under .claude/'}. Looked for: ${names.join(', ')}.`,
177
184
  gateOnly,
185
+ root,
186
+ opts.json ?? false,
178
187
  )
179
188
  }
180
189
 
@@ -190,16 +199,22 @@ async function runAudit(
190
199
  const cited = presentNames(folders)
191
200
  if (gateOnly && cited.length === 0) {
192
201
  return refuse(
202
+ 'no-citation-scope',
193
203
  `The citation check spells the .claude/ prefix and no audited folder resolved there. Looked for: ${names.join(', ')}.`,
194
204
  gateOnly,
205
+ root,
206
+ opts.json ?? false,
195
207
  )
196
208
  }
197
209
 
198
210
  const citations = await auditCitations(root, cited)
199
211
  if (citations.kind === 'unavailable') {
200
212
  return refuse(
213
+ 'no-git',
201
214
  'git could not list the tree, so no citation was checked. Run inside a git repository.',
202
215
  gateOnly,
216
+ root,
217
+ opts.json ?? false,
203
218
  )
204
219
  }
205
220
 
@@ -308,16 +323,26 @@ async function runAudit(
308
323
  return gating ? EXIT_GATE : 0
309
324
  }
310
325
 
311
- function refuse(message: string, gateOnly: boolean): number {
326
+ function refuse(
327
+ reason: ContextAuditRefusal,
328
+ message: string,
329
+ gateOnly: boolean,
330
+ root: string,
331
+ emitJson: boolean,
332
+ ): number {
312
333
  if (gateOnly) {
313
334
  frameError(message)
314
- return 1
335
+ } else {
336
+ intro('aitk context audit')
337
+ logStep('Refused')
338
+ logWarn(message)
339
+ outro()
340
+ }
341
+
342
+ if (emitJson) {
343
+ process.stdout.write(`${JSON.stringify({ root, reason, message })}\n`)
315
344
  }
316
345
 
317
- intro('aitk context audit')
318
- logStep('Refused')
319
- logWarn(message)
320
- outro()
321
346
  return 1
322
347
  }
323
348
 
@@ -506,12 +506,12 @@ function runTestOrder(opts: TestOrderOptions): number {
506
506
  if (report.kind === 'unreadable') {
507
507
  intro('aitk gov test-order')
508
508
  logStep('Refused')
509
- logError(report.reason)
509
+ logError(report.message)
510
510
  outro()
511
511
 
512
512
  if (emitJson) {
513
513
  process.stdout.write(
514
- `${JSON.stringify({ ok: false, reason: report.reason })}\n`,
514
+ `${JSON.stringify({ root, reason: report.reason, message: report.message })}\n`,
515
515
  )
516
516
  }
517
517
 
@@ -2,7 +2,7 @@ import { readFile } from 'node:fs/promises'
2
2
  import { resolve } from 'node:path'
3
3
  import type { Command } from 'commander'
4
4
  import { BAN_SETS, emptyBanSets } from '@/markdown/bans'
5
- import { resolveMarkdown } from '@/markdown/files'
5
+ import { type MarkdownAuditRefusal, resolveMarkdown } from '@/markdown/files'
6
6
  import { isGating } from '@/markdown/gate'
7
7
  import {
8
8
  type BanFinding,
@@ -119,15 +119,21 @@ async function runAudit(
119
119
 
120
120
  if (scope.kind === 'unavailable') {
121
121
  return refuse(
122
+ 'no-git',
122
123
  'git could not list the tree, so no corpus was built. Run inside a git repository.',
124
+ root,
125
+ opts.json ?? false,
123
126
  )
124
127
  }
125
128
 
126
129
  if (scope.files.length === 0) {
127
130
  return refuse(
131
+ paths.length === 0 ? 'no-markdown' : 'no-match',
128
132
  paths.length === 0
129
133
  ? 'No markdown file in the tree.'
130
134
  : `No markdown file matched: ${scope.unmatched.join(', ')}`,
135
+ root,
136
+ opts.json ?? false,
131
137
  )
132
138
  }
133
139
 
@@ -203,11 +209,21 @@ async function runAudit(
203
209
  return gating ? EXIT_GATE : 0
204
210
  }
205
211
 
206
- function refuse(message: string): number {
212
+ function refuse(
213
+ reason: MarkdownAuditRefusal,
214
+ message: string,
215
+ root: string,
216
+ emitJson: boolean,
217
+ ): number {
207
218
  intro('aitk markdown audit')
208
219
  logStep('Refused')
209
220
  logWarn(message)
210
221
  outro()
222
+
223
+ if (emitJson) {
224
+ process.stdout.write(`${JSON.stringify({ root, reason, message })}\n`)
225
+ }
226
+
211
227
  return EXIT_REFUSED
212
228
  }
213
229
 
@@ -15,6 +15,22 @@ import { isStubSeed } from '@/seed-marker'
15
15
  * any markdown file, so they are stated at the attribute tier and measured by
16
16
  * `aitk markdown audit` rather than here.
17
17
  */
18
+ /**
19
+ * Every reason `aitk context audit` refuses for.
20
+ *
21
+ * `no-folders` is the one ordinary absence: a project that never adopted
22
+ * `.claude/context/`, `.claude/diagrams/`, or `.claude/wireframes/` names no
23
+ * corpus this audit can measure, the same state `no-skills` reads for the
24
+ * skill corpora. The other four are a malformed invocation or a checkout git
25
+ * cannot read, which stay a break rather than an absence.
26
+ */
27
+ export type ContextAuditRefusal =
28
+ | 'conflicting-options'
29
+ | 'bad-folder-list'
30
+ | 'no-folders'
31
+ | 'no-citation-scope'
32
+ | 'no-git'
33
+
18
34
  export const LENGTH_CHECKPOINT = 150
19
35
 
20
36
  /**
@@ -44,6 +44,21 @@ export interface Scope {
44
44
  readonly testSuffixes: readonly string[]
45
45
  }
46
46
 
47
+ /**
48
+ * Every reason `aitk gov test-order` refuses for.
49
+ *
50
+ * None is an ordinary absence. A depth-1 checkout falls back to the root
51
+ * commit and reports zero rather than reaching any of these, so what remains
52
+ * is a repository with no commit at all or a git operation that failed
53
+ * outright, both a broken checkout rather than a target's ordinary state.
54
+ */
55
+ export type TestOrderRefusal =
56
+ | 'no-history'
57
+ | 'no-log'
58
+ | 'no-tree'
59
+ | 'bad-base'
60
+ | 'no-base'
61
+
47
62
  export type TestOrderReport =
48
63
  | {
49
64
  readonly kind: 'measured'
@@ -56,7 +71,11 @@ export type TestOrderReport =
56
71
  /** Changed paths outside the pairing's reach, named rather than counted. */
57
72
  readonly ignored: readonly string[]
58
73
  }
59
- | { readonly kind: 'unreadable'; readonly reason: string }
74
+ | {
75
+ readonly kind: 'unreadable'
76
+ readonly reason: TestOrderRefusal
77
+ readonly message: string
78
+ }
60
79
 
61
80
  export interface TestOrderOptions {
62
81
  /** The far side of the range, defaulting to the merge base against the trunk. */
@@ -258,7 +277,8 @@ export function readTestOrder(
258
277
  if (head === undefined) {
259
278
  return {
260
279
  kind: 'unreadable',
261
- reason: `No git history under ${root}. History is the only surface carrying the ordering, so there is nothing to read.`,
280
+ reason: 'no-history',
281
+ message: `No git history under ${root}. History is the only surface carrying the ordering, so there is nothing to read.`,
262
282
  }
263
283
  }
264
284
 
@@ -277,7 +297,8 @@ export function readTestOrder(
277
297
  if (log === undefined) {
278
298
  return {
279
299
  kind: 'unreadable',
280
- reason: `Reading history between ${base} and HEAD failed under ${root}.`,
300
+ reason: 'no-log',
301
+ message: `Reading history between ${base} and HEAD failed under ${root}.`,
281
302
  }
282
303
  }
283
304
 
@@ -285,7 +306,8 @@ export function readTestOrder(
285
306
  if (tree === undefined) {
286
307
  return {
287
308
  kind: 'unreadable',
288
- reason: `Reading the tree at ${base} failed under ${root}. Without it a test written before the range reads as absent.`,
309
+ reason: 'no-tree',
310
+ message: `Reading the tree at ${base} failed under ${root}. Without it a test written before the range reads as absent.`,
289
311
  }
290
312
  }
291
313
 
@@ -323,13 +345,14 @@ function resolveBase(
323
345
  root: string,
324
346
  ref: string | undefined,
325
347
  head: string,
326
- ): string | { kind: 'unreadable'; reason: string } {
348
+ ): string | { kind: 'unreadable'; reason: TestOrderRefusal; message: string } {
327
349
  if (ref !== undefined) {
328
350
  const resolved = revParse(root, ref)
329
351
  if (resolved === undefined) {
330
352
  return {
331
353
  kind: 'unreadable',
332
- reason: `Ref ${ref} resolves to no commit in ${root}. Pass a commit this tree carries.`,
354
+ reason: 'bad-base',
355
+ message: `Ref ${ref} resolves to no commit in ${root}. Pass a commit this tree carries.`,
333
356
  }
334
357
  }
335
358
  return resolved
@@ -345,7 +368,8 @@ function resolveBase(
345
368
  if (rootCommits === undefined || rootCommits === '') {
346
369
  return {
347
370
  kind: 'unreadable',
348
- reason: `No base resolves against ${root}. Fetch origin or pass --base.`,
371
+ reason: 'no-base',
372
+ message: `No base resolves against ${root}. Fetch origin or pass --base.`,
349
373
  }
350
374
  }
351
375
 
@@ -19,6 +19,16 @@ export type FileScope =
19
19
  }
20
20
  | { readonly kind: 'unavailable' }
21
21
 
22
+ /**
23
+ * Every reason `aitk markdown audit` refuses for.
24
+ *
25
+ * None is an ordinary absence. `no-git` is a broken checkout the way it is
26
+ * for the secret scan, and a tree tracked by git carrying no markdown file at
27
+ * all, or an argument matching none, is a corpus this run could not build
28
+ * rather than a target that adopted none of the convention this check reads.
29
+ */
30
+ export type MarkdownAuditRefusal = 'no-git' | 'no-markdown' | 'no-match'
31
+
22
32
  function isDirectory(path: string): boolean {
23
33
  try {
24
34
  return statSync(path).isDirectory()
@@ -32,6 +32,7 @@ export const BACKED_FOLDERS = [
32
32
  'intake',
33
33
  'memory',
34
34
  'plans',
35
+ 'proposals',
35
36
  'review',
36
37
  'tasks',
37
38
  'teach',
@@ -1115,9 +1115,7 @@ export async function validateRecords(
1115
1115
  )
1116
1116
  }
1117
1117
 
1118
- // The walk stays flat, matching install and the catalog. `standards/bundled/`
1119
- // is a subfolder whose members are named for the skill that reads them rather
1120
- // than for a path they govern, so the derivation below reports every one.
1118
+ // The walk stays flat, matching install and the catalog.
1121
1119
  if (kind === 'standards') {
1122
1120
  return validateFiles(
1123
1121
  dir,
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  title: Branch reference
3
3
  description: Branch naming format and type conventions
4
- consumers: git-branch, git-split, git-pr, claude-worktree
5
4
  ---
6
5
 
7
6
  # Branch reference
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  title: Commit reference
3
3
  description: Commit message format and type conventions
4
- consumers: git-commit, git-stage
5
4
  ---
6
5
 
7
6
  # Commit message reference
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  title: Glossary reference
3
3
  description: Frontmatter, entry shape, ordering, and the rules deciding which terms a glossary carries
4
- consumers: claude-teach
5
4
  ---
6
5
 
7
6
  # Glossary reference
@@ -8,14 +8,19 @@ subtitle: Reference docs for consistent authoring across the toolkit and target
8
8
  Reference docs for consistent authoring across the toolkit and target projects.
9
9
 
10
10
  - [Architecture reference](architecture.md): Shape and content rules for .claude/ARCHITECTURE.md
11
+ - [Branch reference](branch.md): Branch naming format and type conventions
12
+ - [Commit reference](commit.md): Commit message format and type conventions
11
13
  - [Context entry reference](context.md): Shape and content rules for .claude/context/<domain>.md entries
12
14
  - [Design reference](design.md): Shape and content rules for .claude/DESIGN.md
13
15
  - [Diagram reference](diagrams.md): Shape and content rules for .claude/diagrams/<kind>.md files
16
+ - [Glossary reference](glossary.md): Frontmatter, entry shape, ordering, and the rules deciding which terms a glossary carries
14
17
  - [Groundwork reference](groundwork.md): Folder layout, reserved numbering, frontmatter and dating, required file contents, and conventions for a measurement track
15
18
  - [Intake reference](intake.md): Folder layout, reserved index number, frontmatter and dating, the item template, the answer contract, and retrieval
19
+ - [Issue reference](issue.md): GitHub issue title, labels, and body conventions
16
20
  - [Markdown reference](markdown.md): Headings, paragraph and list structure, code spans, the date form, punctuation, emphasis, file references, banned words, and frontmatter wording
17
21
  - [Memory reference](memory.md): Filename and type prefix, frontmatter, the body shape per type, links between entries, and the lifecycle from write to retire
18
22
  - [Plan reference](plan.md): Filename and slug, required sections, the suggested-and-answer contract, and the lifecycle from the live folder to the archive
23
+ - [Pull request reference](pr.md): Pull request title and body conventions
19
24
  - [Publish reference](publish.md): Scan an author runs against finished text, the cross-reference form each destination takes, and the response to an unreadable source
20
25
  - [Readme reference](readme.md): Readme voice, structure, and content conventions
21
26
  - [Requirements reference](requirements.md): Shape and content rules for .claude/REQUIREMENTS.md
@@ -23,6 +28,7 @@ Reference docs for consistent authoring across the toolkit and target projects.
23
28
  - [Session map reference](session.md): Filename and location, the sections a handoff carries, the write and read procedures, and how a role extends it
24
29
  - [Claude skill reference](skill.md): Claude skill structure and authoring rules
25
30
  - [Slug reference](slug.md): Transform from a git branch name to a slug, and the three responses to an empty result
31
+ - [Snippet reference](snippets.md): Snippet reference and authoring conventions
26
32
  - [Standard reference](standard.md): Shape and content rules for authoring a standard
27
33
  - [Tasks reference](tasks.md): Folder layout, filename convention, readiness groups, and content rules for .claude/tasks/
28
34
  - [Teach reference](teach.md): Workspace layout, ordinal naming, frontmatter, and the mission and learning-record formats for a learning workspace
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  title: Issue reference
3
3
  description: GitHub issue title, labels, and body conventions
4
- consumers: git-issue
5
4
  ---
6
5
 
7
6
  # Issue reference
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  title: Pull request reference
3
3
  description: Pull request title and body conventions
4
- consumers: git-split, git-pr
5
4
  ---
6
5
 
7
6
  # Pull request reference
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  title: Snippet reference
3
3
  description: Snippet reference and authoring conventions
4
- consumers: create-snippet
5
4
  ---
6
5
 
7
6
  # Snippet reference
@@ -1,60 +0,0 @@
1
- ---
2
- title: Branch reference
3
- description: Branch naming format and type conventions
4
- consumers: git-branch, git-split, git-pr, claude-worktree
5
- ---
6
-
7
- # Branch reference
8
-
9
- ## Scope
10
-
11
- Governs a git branch name: its structure, its length, and the type vocabulary it draws from.
12
-
13
- Does not govern:
14
-
15
- - Commit subject format, which shares the type vocabulary: `commit.md`
16
- - Pull request title and body: `pr.md`
17
- - Whether a phase label may appear in a branch name: `versioning.md`
18
- - Deriving a slug from a branch name for use in an output filename: `slug.md`
19
-
20
- ## Format
21
-
22
- - Structure: `<type>/<description>` or `<type>/<ticket>-<description>`
23
- - Length: 50 characters maximum
24
- - Casing: kebab-case only, no underscores or camelCase
25
- - Description: 2 words maximum, 3 only when genuinely needed for specificity
26
- - Capture the core change, not the commit message verbatim
27
- - For branches with multiple commits, use the unifying concern as the description.
28
- - Do not duplicate type in description (e.g., `feat/feature-login`)
29
-
30
- ## Types
31
-
32
- - `feat`: new feature or capability
33
- - `fix`: bug fix
34
- - `refactor`: structural changes (not a fix or feature)
35
- - `docs`: documentation only (README)
36
- - `chore`: maintenance tasks (deps, tooling, configs)
37
- - `perf`: performance improvements
38
- - `test`: add or modify tests
39
- - `style`: code formatting (whitespace, semicolons)
40
- - `build`: build system changes (webpack, npm scripts)
41
- - `ci`: CI/CD pipeline changes (GitHub Actions)
42
- - `revert`: revert a previous commit
43
-
44
- ## Examples
45
-
46
- ### Correct
47
-
48
- ```plaintext
49
- feat/jwt-expiration # clear feature scope
50
- fix/AUTH-123-connection-pool # includes ticket ID
51
- refactor/remove-deprecated-endpoints # clear refactor intent
52
- ```
53
-
54
- ### Incorrect
55
-
56
- ```plaintext
57
- feature/auth_stuff # wrong type + underscore
58
- feat/feature-add-login # duplicates type in description
59
- fix/DB-456-fix-the-database-connection-pool-memory-leak # exceeds 50 chars + verbatim message
60
- ```
@@ -1,78 +0,0 @@
1
- ---
2
- title: Snippet reference
3
- description: Snippet reference and authoring conventions
4
- consumers: create-snippet
5
- ---
6
-
7
- # Snippet reference
8
-
9
- ## Scope
10
-
11
- Governs a snippet file: what one is for, whether a prompt qualifies as one, how it is invoked, and the structure of its body.
12
-
13
- Does not govern:
14
-
15
- - Skill folders, which carry frontmatter, references, and scripts a snippet has none of: `skill.md`
16
- - Voice, rhythm, and sentence construction in snippet prose: the `write-human` skill
17
- - Punctuation, formatting, and word choice in snippet prose: `markdown.md`
18
-
19
- ## What a snippet is
20
-
21
- A snippet is a short, focused prompt stored as a plain markdown file. Invoke one to insert a prepared instruction into any AI chat without retyping it. Each snippet covers one purpose. If a prompt needs headers or multiple goals, use a system prompt instead.
22
-
23
- ## Admission
24
-
25
- Two tests decide whether a prompt becomes a snippet, and both have to pass. Apply them when adding one and when auditing the catalog.
26
-
27
- - Cadence: a prompt invoked many times across sessions qualifies. A one-shot audit, migration, or bootstrap prompt does not, and belongs in notes outside the catalog.
28
- - Audience: a prompt the consuming project would invoke ships in `snippets/`. One only the authoring repository can run stays outside every installable folder, which is a rule for a repository that authors snippets for others rather than for one that only consumes them.
29
-
30
- A subfolder under `snippets/` names where a prompt is invoked rather than what it is about. A prompt that reads or writes the project's own files goes in a folder, and one carrying its whole context in the message goes at the root.
31
-
32
- Overlapping a skill that does the same job is not disqualifying on its own. A snippet fires when a person asks for it by name and a skill fires on a description match, so the two coexist when those paths differ and the outputs do. Record the reason where the project keeps its decisions, or drop the snippet.
33
-
34
- ## Invocation channels
35
-
36
- - Chrome extension: type `>slug` in a supported chat UI (claude.ai, gemini.google.com) to insert the snippet text inline
37
- - Claude Code terminal: prefix the install path with `@` (e.g. `@.claude/snippets/claude/feature`)
38
- - Snippets install preserving the source folder structure. A snippet at `claude/edit.md` installs as `.claude/snippets/claude/edit.md` and is invoked as `@.claude/snippets/claude/edit`
39
-
40
- ## Use patterns
41
-
42
- - Run-as-is: invoke and send immediately. The snippet is self-contained and needs no extra context.
43
- - Invoke-then-add-context: invoke the snippet, then append specifics in the same message (e.g. invoke `claude-feature`, then add the feature name or extra constraints)
44
- - Invoke-on-history: invoke after a discussion. The snippet uses prior conversation as implicit context with no additional input needed (e.g. invoke `claude-figma` after discussing a design).
45
-
46
- ## Authoring
47
-
48
- - One focused purpose per snippet. If it needs headers or multiple goals, use a system prompt instead.
49
- - Self-contained. No references to external files or assumed prior context.
50
- - No user fill-in placeholders. If a value depends on context, the user adds it after invocation.
51
- - Plain markdown only. No YAML frontmatter, no headers, no nested structure.
52
- - Filename is the slug: kebab-case, no capitals, no underscores
53
-
54
- ## Structure
55
-
56
- - Lead with a verb. Open with an imperative that states the job immediately.
57
- - One instruction per sentence. Do not stack multiple actions into one sentence.
58
- - For sequential steps, use a numbered list with one action per item.
59
- - When the output has a fixed shape, show it in a fenced code block with a language identifier.
60
- - Put constraints and exclusions last, not inline with the main instructions.
61
-
62
- ## Examples
63
-
64
- ### Correct
65
-
66
- ```markdown
67
- I want to implement the following. Scan relevant files and list conflicts. Do not implement. # user adds feature after invocation
68
- Scan relevant files and list conflicts. Do not implement. # run-as-is, no context needed
69
- ```
70
-
71
- ### Incorrect
72
-
73
- ```markdown
74
- I want to implement: <feature or task name> # redundant fill-in, add context after invocation instead
75
- See ARCHITECTURE.md before starting. # external dependency, not self-contained
76
-
77
- ## Overview\n## Steps # headers belong in a system prompt, not a snippet
78
- ```
@@ -1,60 +0,0 @@
1
- ---
2
- title: Branch reference
3
- description: Branch naming format and type conventions
4
- consumers: git-branch, git-split, git-pr, claude-worktree
5
- ---
6
-
7
- # Branch reference
8
-
9
- ## Scope
10
-
11
- Governs a git branch name: its structure, its length, and the type vocabulary it draws from.
12
-
13
- Does not govern:
14
-
15
- - Commit subject format, which shares the type vocabulary: `commit.md`
16
- - Pull request title and body: `pr.md`
17
- - Whether a phase label may appear in a branch name: `versioning.md`
18
- - Deriving a slug from a branch name for use in an output filename: `slug.md`
19
-
20
- ## Format
21
-
22
- - Structure: `<type>/<description>` or `<type>/<ticket>-<description>`
23
- - Length: 50 characters maximum
24
- - Casing: kebab-case only, no underscores or camelCase
25
- - Description: 2 words maximum, 3 only when genuinely needed for specificity
26
- - Capture the core change, not the commit message verbatim
27
- - For branches with multiple commits, use the unifying concern as the description.
28
- - Do not duplicate type in description (e.g., `feat/feature-login`)
29
-
30
- ## Types
31
-
32
- - `feat`: new feature or capability
33
- - `fix`: bug fix
34
- - `refactor`: structural changes (not a fix or feature)
35
- - `docs`: documentation only (README)
36
- - `chore`: maintenance tasks (deps, tooling, configs)
37
- - `perf`: performance improvements
38
- - `test`: add or modify tests
39
- - `style`: code formatting (whitespace, semicolons)
40
- - `build`: build system changes (webpack, npm scripts)
41
- - `ci`: CI/CD pipeline changes (GitHub Actions)
42
- - `revert`: revert a previous commit
43
-
44
- ## Examples
45
-
46
- ### Correct
47
-
48
- ```plaintext
49
- feat/jwt-expiration # clear feature scope
50
- fix/AUTH-123-connection-pool # includes ticket ID
51
- refactor/remove-deprecated-endpoints # clear refactor intent
52
- ```
53
-
54
- ### Incorrect
55
-
56
- ```plaintext
57
- feature/auth_stuff # wrong type + underscore
58
- feat/feature-add-login # duplicates type in description
59
- fix/DB-456-fix-the-database-connection-pool-memory-leak # exceeds 50 chars + verbatim message
60
- ```