brunovskyoliver 0.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.
Files changed (108) hide show
  1. package/README.md +50 -0
  2. package/bin/install-skills.mjs +191 -0
  3. package/package.json +18 -0
  4. package/skills/deprecated/README.md +8 -0
  5. package/skills/deprecated/design-an-interface/SKILL.md +94 -0
  6. package/skills/deprecated/qa/SKILL.md +130 -0
  7. package/skills/deprecated/request-refactor-plan/SKILL.md +68 -0
  8. package/skills/deprecated/ubiquitous-language/SKILL.md +93 -0
  9. package/skills/design/frontend-design/LICENSE.txt +177 -0
  10. package/skills/design/frontend-design/SKILL.md +42 -0
  11. package/skills/design/ui-ux-pro-max/SKILL.md +674 -0
  12. package/skills/design/ui-ux-pro-max/data/_sync_all.py +414 -0
  13. package/skills/design/ui-ux-pro-max/data/app-interface.csv +31 -0
  14. package/skills/design/ui-ux-pro-max/data/charts.csv +26 -0
  15. package/skills/design/ui-ux-pro-max/data/colors.csv +162 -0
  16. package/skills/design/ui-ux-pro-max/data/design.csv +1776 -0
  17. package/skills/design/ui-ux-pro-max/data/draft.csv +1779 -0
  18. package/skills/design/ui-ux-pro-max/data/google-fonts.csv +1924 -0
  19. package/skills/design/ui-ux-pro-max/data/icons.csv +106 -0
  20. package/skills/design/ui-ux-pro-max/data/landing.csv +35 -0
  21. package/skills/design/ui-ux-pro-max/data/products.csv +162 -0
  22. package/skills/design/ui-ux-pro-max/data/react-performance.csv +45 -0
  23. package/skills/design/ui-ux-pro-max/data/stacks/angular.csv +51 -0
  24. package/skills/design/ui-ux-pro-max/data/stacks/astro.csv +54 -0
  25. package/skills/design/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  26. package/skills/design/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  27. package/skills/design/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  28. package/skills/design/ui-ux-pro-max/data/stacks/laravel.csv +51 -0
  29. package/skills/design/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  30. package/skills/design/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  31. package/skills/design/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  32. package/skills/design/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  33. package/skills/design/ui-ux-pro-max/data/stacks/react.csv +54 -0
  34. package/skills/design/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  35. package/skills/design/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  36. package/skills/design/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  37. package/skills/design/ui-ux-pro-max/data/stacks/threejs.csv +54 -0
  38. package/skills/design/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  39. package/skills/design/ui-ux-pro-max/data/styles.csv +85 -0
  40. package/skills/design/ui-ux-pro-max/data/typography.csv +74 -0
  41. package/skills/design/ui-ux-pro-max/data/ui-reasoning.csv +162 -0
  42. package/skills/design/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  43. package/skills/design/ui-ux-pro-max/scripts/core.py +262 -0
  44. package/skills/design/ui-ux-pro-max/scripts/design_system.py +1148 -0
  45. package/skills/design/ui-ux-pro-max/scripts/search.py +114 -0
  46. package/skills/engineering/README.md +25 -0
  47. package/skills/engineering/ask-matt/SKILL.md +61 -0
  48. package/skills/engineering/codebase-design/DEEPENING.md +37 -0
  49. package/skills/engineering/codebase-design/DESIGN-IT-TWICE.md +44 -0
  50. package/skills/engineering/codebase-design/SKILL.md +114 -0
  51. package/skills/engineering/diagnosing-bugs/SKILL.md +134 -0
  52. package/skills/engineering/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
  53. package/skills/engineering/domain-modeling/ADR-FORMAT.md +47 -0
  54. package/skills/engineering/domain-modeling/CONTEXT-FORMAT.md +60 -0
  55. package/skills/engineering/domain-modeling/SKILL.md +74 -0
  56. package/skills/engineering/grill-with-docs/SKILL.md +7 -0
  57. package/skills/engineering/implement/SKILL.md +15 -0
  58. package/skills/engineering/improve-codebase-architecture/HTML-REPORT.md +123 -0
  59. package/skills/engineering/improve-codebase-architecture/SKILL.md +66 -0
  60. package/skills/engineering/prototype/LOGIC.md +79 -0
  61. package/skills/engineering/prototype/SKILL.md +31 -0
  62. package/skills/engineering/prototype/UI.md +112 -0
  63. package/skills/engineering/resolving-merge-conflicts/SKILL.md +14 -0
  64. package/skills/engineering/setup-matt-pocock-skills/SKILL.md +127 -0
  65. package/skills/engineering/setup-matt-pocock-skills/domain.md +51 -0
  66. package/skills/engineering/setup-matt-pocock-skills/issue-tracker-github.md +34 -0
  67. package/skills/engineering/setup-matt-pocock-skills/issue-tracker-gitlab.md +35 -0
  68. package/skills/engineering/setup-matt-pocock-skills/issue-tracker-local.md +21 -0
  69. package/skills/engineering/setup-matt-pocock-skills/triage-labels.md +15 -0
  70. package/skills/engineering/tdd/SKILL.md +108 -0
  71. package/skills/engineering/tdd/mocking.md +59 -0
  72. package/skills/engineering/tdd/refactoring.md +10 -0
  73. package/skills/engineering/tdd/tests.md +61 -0
  74. package/skills/engineering/to-issues/SKILL.md +98 -0
  75. package/skills/engineering/to-prd/SKILL.md +75 -0
  76. package/skills/engineering/triage/AGENT-BRIEF.md +207 -0
  77. package/skills/engineering/triage/OUT-OF-SCOPE.md +105 -0
  78. package/skills/engineering/triage/SKILL.md +112 -0
  79. package/skills/in-progress/README.md +10 -0
  80. package/skills/in-progress/decision-mapping/SKILL.md +84 -0
  81. package/skills/in-progress/loop-me/SKILL.md +32 -0
  82. package/skills/in-progress/review/SKILL.md +69 -0
  83. package/skills/in-progress/writing-beats/SKILL.md +67 -0
  84. package/skills/in-progress/writing-fragments/SKILL.md +79 -0
  85. package/skills/in-progress/writing-shape/SKILL.md +79 -0
  86. package/skills/misc/README.md +8 -0
  87. package/skills/misc/git-guardrails-claude-code/SKILL.md +95 -0
  88. package/skills/misc/git-guardrails-claude-code/scripts/block-dangerous-git.sh +25 -0
  89. package/skills/misc/migrate-to-shoehorn/SKILL.md +118 -0
  90. package/skills/misc/ralph/SKILL.md +83 -0
  91. package/skills/misc/ralph/references/default-prompt.md +22 -0
  92. package/skills/misc/ralph/scripts/afk.sh +41 -0
  93. package/skills/misc/scaffold-exercises/SKILL.md +106 -0
  94. package/skills/misc/setup-pre-commit/SKILL.md +91 -0
  95. package/skills/personal/README.md +6 -0
  96. package/skills/personal/edit-article/SKILL.md +15 -0
  97. package/skills/personal/obsidian-vault/SKILL.md +59 -0
  98. package/skills/productivity/README.md +18 -0
  99. package/skills/productivity/grill-me/SKILL.md +7 -0
  100. package/skills/productivity/grilling/SKILL.md +10 -0
  101. package/skills/productivity/handoff/SKILL.md +16 -0
  102. package/skills/productivity/teach/GLOSSARY-FORMAT.md +35 -0
  103. package/skills/productivity/teach/LEARNING-RECORD-FORMAT.md +46 -0
  104. package/skills/productivity/teach/MISSION-FORMAT.md +31 -0
  105. package/skills/productivity/teach/RESOURCES-FORMAT.md +32 -0
  106. package/skills/productivity/teach/SKILL.md +140 -0
  107. package/skills/productivity/writing-great-skills/GLOSSARY.md +195 -0
  108. package/skills/productivity/writing-great-skills/SKILL.md +82 -0
@@ -0,0 +1,69 @@
1
+ ---
2
+ name: review
3
+ description: Review the changes since a fixed point (commit, branch, tag, or merge-base) along two axes — Standards (does the code follow this repo's documented coding standards?) and Spec (does the code match what the originating issue/PRD asked for?). Runs both reviews in parallel sub-agents and reports them side by side. Use when the user wants to review a branch, a PR, work-in-progress changes, or asks to "review since X".
4
+ ---
5
+
6
+ Two-axis review of the diff between `HEAD` and a fixed point the user supplies:
7
+
8
+ - **Standards** — does the code conform to this repo's documented coding standards?
9
+ - **Spec** — does the code faithfully implement the originating issue / PRD / spec?
10
+
11
+ Both axes run as **parallel sub-agents** so they don't pollute each other's context, then this skill aggregates their findings.
12
+
13
+ The issue tracker should have been provided to you — run `/setup-matt-pocock-skills` if `docs/agents/issue-tracker.md` is missing.
14
+
15
+ ## Process
16
+
17
+ ### 1. Pin the fixed point
18
+
19
+ Whatever the user said is the fixed point — a commit SHA, branch name, tag, `main`, `HEAD~5`, etc. If they didn't specify one, ask for it.
20
+
21
+ Capture the diff command once: `git diff <fixed-point>...HEAD` (three-dot, so the comparison is against the merge-base). Also note the list of commits via `git log <fixed-point>..HEAD --oneline`.
22
+
23
+ Before going further, confirm the fixed point resolves (`git rev-parse <fixed-point>`) and the diff is non-empty. A bad ref or empty diff should fail here — not inside two parallel sub-agents.
24
+
25
+ ### 2. Identify the spec source
26
+
27
+ Look for the originating spec, in this order:
28
+
29
+ 1. Issue references in the commit messages (`#123`, `Closes #45`, GitLab `!67`, etc.) — fetch via the workflow in `docs/agents/issue-tracker.md`.
30
+ 2. A path the user passed as an argument.
31
+ 3. A PRD/spec file under `docs/`, `specs/`, or `.scratch/` matching the branch name or feature.
32
+ 4. If nothing is found, ask the user where the spec is. If they say there isn't one, the **Spec** sub-agent will skip and report "no spec available".
33
+
34
+ ### 3. Identify the standards sources
35
+
36
+ Anything in the repo that documents how code should be written, such as `CODING_STANDARDS.md` or `CONTRIBUTING.md`.
37
+
38
+ ### 4. Spawn both sub-agents in parallel
39
+
40
+ Send a single message with two `Agent` tool calls. Use the `general-purpose` subagent for both.
41
+
42
+ **Standards sub-agent prompt** — include:
43
+
44
+ - The full diff command and commit list.
45
+ - The list of standards-source files you found in step 3.
46
+ - The brief: "Report — per file/hunk where relevant — every place the diff violates a documented standard. Cite the standard (file + the rule). Distinguish hard violations from judgement calls. Skip anything tooling enforces. Under 400 words."
47
+
48
+ **Spec sub-agent prompt** — include:
49
+
50
+ - The diff command and commit list.
51
+ - The path or fetched contents of the spec.
52
+ - The brief: "Report: (a) requirements the spec asked for that are missing or partial; (b) behaviour in the diff that wasn't asked for (scope creep); (c) requirements that look implemented but where the implementation looks wrong. Quote the spec line for each finding. Under 400 words."
53
+
54
+ If the spec is missing, skip the Spec sub-agent and note this in the final report.
55
+
56
+ ### 5. Aggregate
57
+
58
+ Present the two reports under `## Standards` and `## Spec` headings, verbatim or lightly cleaned. Do **not** merge or rerank findings — the two axes are deliberately separate (see _Why two axes_).
59
+
60
+ End with a one-line summary: total findings per axis, and the worst issue _within each axis_ (if any). Don't pick a single winner across axes — that's the reranking the separation exists to prevent.
61
+
62
+ ## Why two axes
63
+
64
+ A change can pass one axis and fail the other:
65
+
66
+ - Code that follows every standard but implements the wrong thing → **Standards pass, Spec fail.**
67
+ - Code that does exactly what the issue asked but breaks the project's conventions → **Spec pass, Standards fail.**
68
+
69
+ Reporting them separately stops one axis from masking the other.
@@ -0,0 +1,67 @@
1
+ ---
2
+ name: writing-beats
3
+ description: Writing, exploit — assemble raw material into a journey of beats, grounding each term before a beat leans on it.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ <what-to-do>
8
+
9
+ The user has passed (or will pass) a markdown file of raw material. This is **exploit**: the exploring is done, the pile is fixed — commit to a path through it and mine the pile to fill each beat.
10
+
11
+ If the user did not say where to save the article, ask once and remember the path.
12
+
13
+ Then run a beat-by-beat journey, choose-your-own-adventure style:
14
+
15
+ 1. **Establish the prerequisites.** Before any beats, settle with the user what the audience already knows walking in — the concepts that are **grounded** from the start. Everything else must be grounded by a beat before a later beat can use it. See [Grounding](#grounding).
16
+ 2. Write 2–3 candidate **starting beats**, drawn from the raw material. Each is a different entry point into the article. Each may only lean on grounded concepts; note what new concepts each one grounds. Show the user the beats before writing to the article file. The user picks one. Preview what beats that pick unlocks — as if the user is seeing a little way down the path.
17
+ 3. Once the user picks a starting beat, write **only that beat** to the article file. A beat may be one sentence or several paragraphs — whatever that beat naturally is. Stop there.
18
+ 4. Re-read the article file from disk. Then offer 2–3 candidate **next beats** — different directions the journey could pivot to from where the article now stands. Each must be reachable from the current grounded set; note what each one grounds.
19
+ 5. Loop steps 3–5 until the article reaches a natural end.
20
+
21
+ </what-to-do>
22
+
23
+ <supporting-info>
24
+
25
+ ## Grounding
26
+
27
+ Every **concept** has to be **grounded** before a beat can lean on it: the audience either walked in knowing it or met it in an earlier beat. A beat that reaches for an ungrounded concept loses the reader — that is the one move the journey can't make. The unit is the concept, not the word for it: a beat can lean on an idea the reader lacks even with no jargon in sight. Where a concept has a name — a **term** — grounding it means landing the idea and the term together.
28
+
29
+ A concept gets grounded one of two ways:
30
+
31
+ - **Prerequisite** — grounded before the first beat. The audience brings it. Fixed at the start.
32
+ - **Introduced** — a beat establishes it, and from then on it's grounded for every later beat.
33
+
34
+ So each beat does two jobs: it **requires** concepts that are already grounded, and it **grounds** new ones. Keep a running list of what's grounded so far, and update it each time a beat lands.
35
+
36
+ This is what shapes the choose-your-own-adventure. A candidate beat is only reachable if everything it requires is already grounded; picking a beat that grounds concept X unlocks every beat that was waiting on X. When you offer next beats, they must all be reachable from the current grounded set — and say what each one grounds, so the user can see which paths it opens.
37
+
38
+ The big lever is what you make a prerequisite versus what you ground inside the piece. Demand too much up front and you shut out readers who don't have it; ground too much inside and the early beats drown in definitions. Settle this with the user when you establish prerequisites, and revisit it whenever a tempting beat turns out to require a concept nothing has grounded yet — the fix is either a grounding beat before it, or promoting the concept to a prerequisite.
39
+
40
+ ## What is a beat
41
+
42
+ A beat is one move in the journey. It does one thing — sets a scene, lands a point, asks a question, drops an aside, twists the angle. Then it stops, leaving the reader at a place where the next beat can pivot.
43
+
44
+ A beat is sized by what it needs:
45
+
46
+ - A single sentence if that's all the move is ("And then nothing happened for three weeks.").
47
+ - A short paragraph if the move needs setup.
48
+ - Multiple paragraphs if the beat is a self-contained vignette, argument, or example.
49
+
50
+ If a "beat" needs five paragraphs and three subheadings, it's not a beat — it's two beats glued together. Split it.
51
+
52
+ ## Pulling from the pile
53
+
54
+ Pull material from the raw pile to populate each beat. You can paraphrase, split, recombine, or quote. The pile is a quarry.
55
+
56
+ ## Ending the journey
57
+
58
+ The article ends when the journey is complete — not when the pile is empty. Most piles will have leftover fragments that don't make it in. That is fine; that is the point of having more raw material than you need.
59
+
60
+ ## Writing rhythm
61
+
62
+ - Append one beat at a time. Never write ahead.
63
+ - Re-read the article file from disk before every write. Preserve user edits absolutely.
64
+ - If the user edits a previous beat substantially, let it change what comes next.
65
+ - If the user says "rewrite that beat" or "go back and try a different beat 3", do it — edit in place, leave the rest alone.
66
+
67
+ </supporting-info>
@@ -0,0 +1,79 @@
1
+ ---
2
+ name: writing-fragments
3
+ description: Writing, explore — mine raw fragments, no structure yet.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ <what-to-do>
8
+
9
+ This is pure **explore**: widen the space of what could be written without committing to structure — committing is _exploit_, a separate skill's job. Run a grilling session that produces fragments, interviewing the user relentlessly about whatever they want to write about. Imposing phases, outlines, or article structure is out of scope here.
10
+
11
+ As fragments emerge from either side of the conversation, append them to a single markdown file.
12
+
13
+ If the user did not pass a path, ask once where to save the document, then remember it for the rest of the session.
14
+
15
+ Capture fragments from the very first thing the user says, including the initial prompt.
16
+
17
+ On first write, put a single H1 at the top with a working title (it can change later) and nothing else — no metadata, no TOC, no date.
18
+
19
+ </what-to-do>
20
+
21
+ <supporting-info>
22
+
23
+ ## What is a fragment
24
+
25
+ A fragment is any piece of text that might survive into the final article. It must be _readable by the author_ — the author can tell what it means — but it does not need to define its terms or be comprehensible to a cold reader. The bar is "is this a piece of good writing?", not "is this a self-contained argument?"
26
+
27
+ Fragments are deliberately heterogeneous. Examples of what could be a fragment:
28
+
29
+ - A sharp sentence you'd want to deploy somewhere but don't yet know where.
30
+ - A claim with a one-line justification.
31
+ - A vignette: a thing that happened, a code snippet, a scenario, an analogy.
32
+ - A half-thought: "something about how X feels like Y, work this out later."
33
+ - A quote, a piece of dialogue, an overheard line.
34
+ - A list of related observations that hang together by feel.
35
+ - A complaint, a confession, a punchline.
36
+ - A **leading word** — a compact metaphor or coinage the whole piece can hang on (one term that names the idea, the way _tracer bullets_ or _fog of war_ names a whole pattern).
37
+
38
+ Of these, the leading word is the most valuable fragment to land. It is load-bearing: name the right one in explore and it shapes the structure, the transitions, and the title later — paying dividends through the entire exploit phase. When the conversation circles a recurring idea, push to coin a word for it.
39
+
40
+ The novelist's diary is the model: years of unstructured noticings that later get mined for raw material. Fragments are noticings.
41
+
42
+ ## File format
43
+
44
+ ```markdown
45
+ # Working title
46
+
47
+ A first fragment lives here.
48
+
49
+ It can be multiple paragraphs. It can include lists, code, quotes — whatever
50
+ shape the fragment naturally takes.
51
+
52
+ ---
53
+
54
+ A second fragment.
55
+
56
+ ---
57
+
58
+ > A quoted line that the user wants to keep around.
59
+
60
+ A reaction to it.
61
+
62
+ ---
63
+
64
+ - A cluster of related observations
65
+ - That hang together by feel
66
+ - And want to be near each other
67
+ ```
68
+
69
+ Fragments are separated by a horizontal rule (`\n---\n`). No headings inside the body. No tags. No order beyond the order they were added.
70
+
71
+ ## Writing rhythm
72
+
73
+ Append silently. Don't ask permission for each fragment. Mention what you added in passing ("adding that"), but don't interrupt the conversation with save dialogs.
74
+
75
+ Before every write: re-read the file from disk. The user may have edited, reordered, or deleted fragments between turns — preserve their changes. Never overwrite the file; only append (or, if the user asks, edit a specific fragment in place).
76
+
77
+ The user can say "cut the last one", "rewrite that one sharper", "merge those two" at any time. Treat those as first-class instructions.
78
+
79
+ </supporting-info>
@@ -0,0 +1,79 @@
1
+ ---
2
+ name: writing-shape
3
+ description: Writing, exploit — shape raw material into an article, paragraph by paragraph.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ <what-to-do>
8
+
9
+ The user has passed (or will pass) a markdown file of raw material. Treat it as the input pile — anything from a tidy list of fragments to a wall of unstructured prose to a transcript. The format does not matter. Read it end-to-end before doing anything else.
10
+
11
+ Then run a shaping session that produces a separate article document. This is **exploit**: the exploring is done, the pile is fixed — commit to a structure and mine the pile to fill it. Do not edit the raw material file — it is read-only to this skill.
12
+
13
+ If the user did not say where to save the article, ask once and remember the path.
14
+
15
+ </what-to-do>
16
+
17
+ <supporting-info>
18
+
19
+ ## The loop
20
+
21
+ 1. **Read the pile.** Read the input file in full. Form a sense of what's in it.
22
+ 2. **Establish the prerequisites.** Settle with the user what the reader knows walking in — the concepts that are **grounded** from the start. Everything else must be grounded by a block before a later block can lean on it. See [Grounding](#grounding).
23
+ 3. **Draft 2–3 candidate openings.** Each opening should imply a different thesis or angle for the article. Show all of them. Force the user to pick or compose a hybrid. The chosen opening defines what the rest of the article must do.
24
+ 4. **Grow paragraph by paragraph.** After the opening lands, ask "given this opening, what does the reader need to hear next?" Pull material from the pile to answer. The next block may only lean on grounded concepts, and grounds new ones as it lands. Argue about the form the next block takes — a paragraph, a list, a table, a callout, a quote, a code block. Each format choice should be deliberate and defensible.
25
+ 5. **Append to the article file as you go.** Don't batch. Write each agreed paragraph or block immediately so the user can see the article taking shape.
26
+ 6. **Loop step 4 until the article is done.** The user decides when it's done.
27
+
28
+ ## Grounding
29
+
30
+ Every **concept** has to be **grounded** before a block can lean on it: the reader either walked in knowing it or met it in an earlier block. A block that reaches for an ungrounded concept loses the reader. The unit is the concept, not the word for it — a block can lean on an idea the reader lacks even with no jargon in sight. Where a concept has a name — a **term** — grounding it means landing the idea and the term together.
31
+
32
+ A concept gets grounded one of two ways:
33
+
34
+ - **Prerequisite** — grounded before the opening. The reader brings it. Fixed at the start.
35
+ - **Introduced** — a block establishes it, and from then on it's grounded for the rest of the article.
36
+
37
+ Keep a running list of what's grounded. When you ask "what does the reader need to hear next?", an ungrounded concept the next move needs is itself the answer: ground it first — here or in an earlier block — or you can't make the move. This is the gap-naming of [Pulling from the pile](#pulling-from-the-pile) one level up: there the pile is missing material; here the article is missing a foundation.
38
+
39
+ The lever is what you make a prerequisite versus what you ground inside the article. Demand too much up front and you shut readers out; ground too much inside and the opening drowns in definitions. Settle it with the user when you establish prerequisites.
40
+
41
+ ## Conversational feel
42
+
43
+ This is a grilling session inverted. In ideation, the question was "what are you actually noticing?" Here it's "what is this article actually arguing, and in what order does the reader need to hear it?" Push back. Refuse to let weak transitions slide. If a paragraph doesn't earn its place, cut it.
44
+
45
+ Specific moves to keep using:
46
+
47
+ - "What does this paragraph do for the reader that the previous one didn't?"
48
+ - "If I cut this, what breaks?"
49
+ - "Is this prose, or should it be a list? Why prose?"
50
+ - "This sentence is doing two jobs — split it or pick one."
51
+ - "The opening promised X. We've drifted to Y. Either re-thread it or change the opening."
52
+
53
+ ## Pulling from the pile
54
+
55
+ Treat the raw material as a quarry, not a script. Pull a fragment, rework it to fit the surrounding paragraph, and place it. A fragment may be split across multiple paragraphs, merged with another, or paraphrased. The pile's job is to be mined; the article's job is to read as one voice.
56
+
57
+ If the pile lacks something the article needs, name the gap explicitly: "We need an example here and the pile doesn't have one — give me one now or we cut this section."
58
+
59
+ ## Format arguments to actually have
60
+
61
+ When choosing how to render a block, weigh these tradeoffs out loud with the user, not silently:
62
+
63
+ - **Prose vs. list.** Prose carries argument; lists carry parallel items. If items aren't truly parallel, prose is better. If they are, a list is faster to scan.
64
+ - **Inline vs. callout.** Tips, warnings, and asides go in callouts (`> [!TIP]`, `> [!NOTE]`) — but only if they'd genuinely derail the main argument inline. Otherwise leave them inline.
65
+ - **Table vs. repeated structure.** If the same shape repeats 3+ times with the same fields, a table. Otherwise prose with bold leads.
66
+ - **Quote vs. paraphrase.** Quote when the original wording is the point. Paraphrase when only the idea matters.
67
+ - **Code block vs. inline code.** Multi-line, runnable, or illustrative → block. Single token or identifier → inline.
68
+
69
+ ## Writing rhythm
70
+
71
+ Append to the article file as each block is agreed. Re-read the file from disk before every write — the user may have edited between turns. Never overwrite blindly. If the user wants a paragraph rewritten, edit that specific paragraph in place; leave the rest alone.
72
+
73
+ ## Out of scope
74
+
75
+ - Mining for new fragments that aren't in the pile (handle gaps as in "Pulling from the pile").
76
+ - Editing the raw material file.
77
+ - Publishing, formatting for a specific platform, or adding frontmatter the user didn't ask for.
78
+
79
+ </supporting-info>
@@ -0,0 +1,8 @@
1
+ # Misc
2
+
3
+ Tools I keep around but rarely use.
4
+
5
+ - **[git-guardrails-claude-code](./git-guardrails-claude-code/SKILL.md)** — Set up Claude Code hooks to block dangerous git commands (push, reset --hard, clean, etc.) before they execute.
6
+ - **[migrate-to-shoehorn](./migrate-to-shoehorn/SKILL.md)** — Migrate test files from `as` type assertions to @total-typescript/shoehorn.
7
+ - **[scaffold-exercises](./scaffold-exercises/SKILL.md)** — Create exercise directory structures with sections, problems, solutions, and explainers.
8
+ - **[setup-pre-commit](./setup-pre-commit/SKILL.md)** — Set up Husky pre-commit hooks with lint-staged, Prettier, type checking, and tests.
@@ -0,0 +1,95 @@
1
+ ---
2
+ name: git-guardrails-claude-code
3
+ description: Set up Claude Code hooks to block dangerous git commands (push, reset --hard, clean, branch -D, etc.) before they execute. Use when user wants to prevent destructive git operations, add git safety hooks, or block git push/reset in Claude Code.
4
+ ---
5
+
6
+ # Setup Git Guardrails
7
+
8
+ Sets up a PreToolUse hook that intercepts and blocks dangerous git commands before Claude executes them.
9
+
10
+ ## What Gets Blocked
11
+
12
+ - `git push` (all variants including `--force`)
13
+ - `git reset --hard`
14
+ - `git clean -f` / `git clean -fd`
15
+ - `git branch -D`
16
+ - `git checkout .` / `git restore .`
17
+
18
+ When blocked, Claude sees a message telling it that it does not have authority to access these commands.
19
+
20
+ ## Steps
21
+
22
+ ### 1. Ask scope
23
+
24
+ Ask the user: install for **this project only** (`.claude/settings.json`) or **all projects** (`~/.claude/settings.json`)?
25
+
26
+ ### 2. Copy the hook script
27
+
28
+ The bundled script is at: [scripts/block-dangerous-git.sh](scripts/block-dangerous-git.sh)
29
+
30
+ Copy it to the target location based on scope:
31
+
32
+ - **Project**: `.claude/hooks/block-dangerous-git.sh`
33
+ - **Global**: `~/.claude/hooks/block-dangerous-git.sh`
34
+
35
+ Make it executable with `chmod +x`.
36
+
37
+ ### 3. Add hook to settings
38
+
39
+ Add to the appropriate settings file:
40
+
41
+ **Project** (`.claude/settings.json`):
42
+
43
+ ```json
44
+ {
45
+ "hooks": {
46
+ "PreToolUse": [
47
+ {
48
+ "matcher": "Bash",
49
+ "hooks": [
50
+ {
51
+ "type": "command",
52
+ "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-dangerous-git.sh"
53
+ }
54
+ ]
55
+ }
56
+ ]
57
+ }
58
+ }
59
+ ```
60
+
61
+ **Global** (`~/.claude/settings.json`):
62
+
63
+ ```json
64
+ {
65
+ "hooks": {
66
+ "PreToolUse": [
67
+ {
68
+ "matcher": "Bash",
69
+ "hooks": [
70
+ {
71
+ "type": "command",
72
+ "command": "~/.claude/hooks/block-dangerous-git.sh"
73
+ }
74
+ ]
75
+ }
76
+ ]
77
+ }
78
+ }
79
+ ```
80
+
81
+ If the settings file already exists, merge the hook into existing `hooks.PreToolUse` array — don't overwrite other settings.
82
+
83
+ ### 4. Ask about customization
84
+
85
+ Ask if user wants to add or remove any patterns from the blocked list. Edit the copied script accordingly.
86
+
87
+ ### 5. Verify
88
+
89
+ Run a quick test:
90
+
91
+ ```bash
92
+ echo '{"tool_input":{"command":"git push origin main"}}' | <path-to-script>
93
+ ```
94
+
95
+ Should exit with code 2 and print a BLOCKED message to stderr.
@@ -0,0 +1,25 @@
1
+ #!/bin/bash
2
+
3
+ INPUT=$(cat)
4
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command')
5
+
6
+ DANGEROUS_PATTERNS=(
7
+ "git push"
8
+ "git reset --hard"
9
+ "git clean -fd"
10
+ "git clean -f"
11
+ "git branch -D"
12
+ "git checkout \."
13
+ "git restore \."
14
+ "push --force"
15
+ "reset --hard"
16
+ )
17
+
18
+ for pattern in "${DANGEROUS_PATTERNS[@]}"; do
19
+ if echo "$COMMAND" | grep -qE "$pattern"; then
20
+ echo "BLOCKED: '$COMMAND' matches dangerous pattern '$pattern'. The user has prevented you from doing this." >&2
21
+ exit 2
22
+ fi
23
+ done
24
+
25
+ exit 0
@@ -0,0 +1,118 @@
1
+ ---
2
+ name: migrate-to-shoehorn
3
+ description: Migrate test files from `as` type assertions to @total-typescript/shoehorn. Use when user mentions shoehorn, wants to replace `as` in tests, or needs partial test data.
4
+ ---
5
+
6
+ # Migrate to Shoehorn
7
+
8
+ ## Why shoehorn?
9
+
10
+ `shoehorn` lets you pass partial data in tests while keeping TypeScript happy. It replaces `as` assertions with type-safe alternatives.
11
+
12
+ **Test code only.** Never use shoehorn in production code.
13
+
14
+ Problems with `as` in tests:
15
+
16
+ - Trained not to use it
17
+ - Must manually specify target type
18
+ - Double-as (`as unknown as Type`) for intentionally wrong data
19
+
20
+ ## Install
21
+
22
+ ```bash
23
+ npm i @total-typescript/shoehorn
24
+ ```
25
+
26
+ ## Migration patterns
27
+
28
+ ### Large objects with few needed properties
29
+
30
+ Before:
31
+
32
+ ```ts
33
+ type Request = {
34
+ body: { id: string };
35
+ headers: Record<string, string>;
36
+ cookies: Record<string, string>;
37
+ // ...20 more properties
38
+ };
39
+
40
+ it("gets user by id", () => {
41
+ // Only care about body.id but must fake entire Request
42
+ getUser({
43
+ body: { id: "123" },
44
+ headers: {},
45
+ cookies: {},
46
+ // ...fake all 20 properties
47
+ });
48
+ });
49
+ ```
50
+
51
+ After:
52
+
53
+ ```ts
54
+ import { fromPartial } from "@total-typescript/shoehorn";
55
+
56
+ it("gets user by id", () => {
57
+ getUser(
58
+ fromPartial({
59
+ body: { id: "123" },
60
+ }),
61
+ );
62
+ });
63
+ ```
64
+
65
+ ### `as Type` → `fromPartial()`
66
+
67
+ Before:
68
+
69
+ ```ts
70
+ getUser({ body: { id: "123" } } as Request);
71
+ ```
72
+
73
+ After:
74
+
75
+ ```ts
76
+ import { fromPartial } from "@total-typescript/shoehorn";
77
+
78
+ getUser(fromPartial({ body: { id: "123" } }));
79
+ ```
80
+
81
+ ### `as unknown as Type` → `fromAny()`
82
+
83
+ Before:
84
+
85
+ ```ts
86
+ getUser({ body: { id: 123 } } as unknown as Request); // wrong type on purpose
87
+ ```
88
+
89
+ After:
90
+
91
+ ```ts
92
+ import { fromAny } from "@total-typescript/shoehorn";
93
+
94
+ getUser(fromAny({ body: { id: 123 } }));
95
+ ```
96
+
97
+ ## When to use each
98
+
99
+ | Function | Use case |
100
+ | --------------- | -------------------------------------------------- |
101
+ | `fromPartial()` | Pass partial data that still type-checks |
102
+ | `fromAny()` | Pass intentionally wrong data (keeps autocomplete) |
103
+ | `fromExact()` | Force full object (swap with fromPartial later) |
104
+
105
+ ## Workflow
106
+
107
+ 1. **Gather requirements** - ask user:
108
+ - What test files have `as` assertions causing problems?
109
+ - Are they dealing with large objects where only some properties matter?
110
+ - Do they need to pass intentionally wrong data for error testing?
111
+
112
+ 2. **Install and migrate**:
113
+ - [ ] Install: `npm i @total-typescript/shoehorn`
114
+ - [ ] Find test files with `as` assertions: `grep -r " as [A-Z]" --include="*.test.ts" --include="*.spec.ts"`
115
+ - [ ] Replace `as Type` with `fromPartial()`
116
+ - [ ] Replace `as unknown as Type` with `fromAny()`
117
+ - [ ] Add imports from `@total-typescript/shoehorn`
118
+ - [ ] Run type check to verify
@@ -0,0 +1,83 @@
1
+ ---
2
+ name: ralph
3
+ description: AFK engineering agent. Reads issues/, selects the highest-priority open tasks, implements them with TDD, runs feedback loops, commits, and updates issue files until no tasks remain. Also scaffolds new projects with "ralph setup". Triggers when user says "ralph", "do ralph", "run ralph", "ralph setup", or asks for autonomous issue resolution.
4
+ ---
5
+
6
+ You are **Ralph**, an autonomous engineering agent. Check the user's intent first:
7
+
8
+ - "ralph setup" → follow **Setup Mode** below
9
+ - "ralph one", "one iteration", or an explicit request for a single issue → follow **One Iteration** below
10
+ - anything else → follow **AFK multi-iteration** below
11
+
12
+ ## Setup Mode
13
+
14
+ Scaffold ralph for the current project:
15
+
16
+ 1. Create `ralph/` directory if missing
17
+ 2. If `ralph/prompt.md` is missing, create it from [default-prompt.md](references/default-prompt.md) — then ask the user to review and customise the feedback loop commands for their stack
18
+ 3. Create `issues/` and `issues/done/` directories if missing
19
+ 4. Confirm what was created and tell the user to populate `issues/` with `.md` files (one per task)
20
+
21
+ ---
22
+
23
+ ## One Iteration
24
+
25
+ ### 1. Read context
26
+
27
+ ```bash
28
+ git log -n 5 --format="%H%n%ad%n%B---" --date=short 2>/dev/null
29
+ ```
30
+
31
+ Read all `issues/*.md` files (skip `issues/done/`).
32
+
33
+ If `ralph/prompt.md` exists in the project, read and follow it. Otherwise use [default-prompt.md](references/default-prompt.md).
34
+
35
+ ### 2. Assess
36
+
37
+ Any open AFK tasks? Issues marked HITL or "needs info" are not for you.
38
+
39
+ If none remain, output: `<promise>NO MORE TASKS</promise>` and stop.
40
+
41
+ ### 3. Pick ONE task — priority order
42
+
43
+ 1. Critical bugfixes
44
+ 2. Dev infrastructure (types, tests, scripts)
45
+ 3. Tracer bullets for new features (thin end-to-end slices)
46
+ 4. Polish and quick wins
47
+ 5. Refactors
48
+
49
+ Announce which task and why.
50
+
51
+ ### 4. Explore → Implement → Test
52
+
53
+ Read relevant files first. Implement vertically (one test → one impl → repeat). Run the project's feedback loops (tests + typecheck) and fix all failures before committing.
54
+
55
+ ### 5. Commit
56
+
57
+ Message must include: key decisions, files changed, blockers/notes for next iteration.
58
+
59
+ ### 6. Update the issue
60
+
61
+ - Done → move to `issues/done/`
62
+ - Partial → append progress note to the issue file
63
+
64
+ ### 7. Report
65
+
66
+ 2-3 sentences: what was done.
67
+
68
+ ---
69
+
70
+ ## AFK multi-iteration
71
+
72
+ By default, run Ralph autonomously in a loop until no tasks remain:
73
+
74
+ 1. Run the bundled script from the project root:
75
+
76
+ ```bash
77
+ ~/.codex/skills/ralph/scripts/afk.sh # run until no tasks
78
+ ~/.codex/skills/ralph/scripts/afk.sh 5 # cap at 5 iterations
79
+ ```
80
+
81
+ 2. If the script is unavailable or fails before starting, fall back to repeating **One Iteration** manually until there are no open AFK tasks, preserving the one-commit-per-issue rhythm.
82
+ 3. Stop when the script or manual loop reports `<promise>NO MORE TASKS</promise>`.
83
+ 4. Report the completed issues, commits, verification performed, and any remaining blocked or HITL issues.
@@ -0,0 +1,22 @@
1
+ # Ralph — Default Prompt
2
+
3
+ Fallback when no `ralph/prompt.md` exists in the project. Copy to `ralph/prompt.md` and customise for your stack.
4
+
5
+ ---
6
+
7
+ Work on **AFK issues only** — fully specified, no human input needed. Skip HITL or "needs info" issues.
8
+
9
+ Pick ONE task per iteration. Priority: bugfixes → dev infra → tracer bullets → polish → refactors.
10
+
11
+ Before committing, run whatever feedback loops exist:
12
+ - `cargo test --workspace` / `cargo build --workspace`
13
+ - `npm test` / `npm run typecheck`
14
+ - `pytest` / `go test ./...`
15
+
16
+ Commit message must include: key decisions, files changed, blockers for next iteration.
17
+
18
+ Move completed issues to `issues/done/`. Append progress notes to partial ones.
19
+
20
+ If all AFK tasks are done, output `<promise>NO MORE TASKS</promise>`.
21
+
22
+ ONLY WORK ON A SINGLE TASK.