@ketecode/loom 0.1.0 → 0.2.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 (211) hide show
  1. package/README.md +111 -11
  2. package/agents/code-reviewer/evals/behavior.json +60 -0
  3. package/agents/inbox-triager/AGENT.md +98 -0
  4. package/agents/inbox-triager/evals/triggers.json +16 -0
  5. package/agents/spec-reviewer/AGENT.md +95 -0
  6. package/agents/spec-reviewer/evals/behavior.json +57 -0
  7. package/agents/spec-reviewer/evals/triggers.json +16 -0
  8. package/agents/task-implementer/AGENT.md +89 -0
  9. package/agents/task-implementer/evals/behavior.json +47 -0
  10. package/agents/task-implementer/evals/triggers.json +16 -0
  11. package/bin/kete-loom.js +46 -6
  12. package/commands/brainstorm.md +25 -0
  13. package/commands/debug.md +27 -0
  14. package/commands/dual-review.md +34 -0
  15. package/commands/feature-dev.md +8 -7
  16. package/commands/finish-branch.md +26 -0
  17. package/commands/fix-bug.md +38 -0
  18. package/commands/production-readiness.md +45 -0
  19. package/commands/usage-report.md +43 -0
  20. package/hooks/block-foreground-servers/HOOK.md +34 -0
  21. package/hooks/block-foreground-servers/cases.json +31 -0
  22. package/hooks/block-foreground-servers/hook.js +41 -0
  23. package/hooks/capture-lessons/HOOK.md +24 -0
  24. package/hooks/capture-lessons/hook.js +48 -0
  25. package/hooks/notify-on-stop/HOOK.md +25 -0
  26. package/hooks/notify-on-stop/hook.js +27 -0
  27. package/hooks/protect-lint-config/HOOK.md +29 -0
  28. package/hooks/protect-lint-config/cases.json +18 -0
  29. package/hooks/protect-lint-config/fixtures/.eslintrc.json +1 -0
  30. package/hooks/protect-lint-config/fixtures/.golangci.yml +1 -0
  31. package/hooks/protect-lint-config/fixtures/.prettierrc +1 -0
  32. package/hooks/protect-lint-config/fixtures/.rubocop.yml +1 -0
  33. package/hooks/protect-lint-config/fixtures/biome.json +1 -0
  34. package/hooks/protect-lint-config/fixtures/eslint.config.mjs +1 -0
  35. package/hooks/protect-lint-config/fixtures/ruff.toml +1 -0
  36. package/hooks/protect-lint-config/hook.js +25 -0
  37. package/hooks/read-before-edit/HOOK.md +26 -0
  38. package/hooks/read-before-edit/cases.json +15 -0
  39. package/hooks/read-before-edit/hook.js +50 -0
  40. package/hooks/run.js +22 -6
  41. package/hooks/verify-before-stop/HOOK.md +32 -0
  42. package/hooks/verify-before-stop/hook.js +70 -0
  43. package/mcp/clickhouse.json +11 -0
  44. package/mcp/exa.json +11 -0
  45. package/mcp/firecrawl.json +11 -0
  46. package/mcp/vercel.json +11 -0
  47. package/package.json +6 -4
  48. package/profiles.json +54 -5
  49. package/rules/use-skills.md +23 -0
  50. package/scripts/lib/behavior.js +52 -0
  51. package/scripts/lib/hooks-install.js +9 -7
  52. package/scripts/lib/lint.js +24 -2
  53. package/scripts/lib/mcp-install.js +5 -1
  54. package/scripts/lib/render.js +6 -0
  55. package/scripts/lib/skills.js +1 -0
  56. package/scripts/lib/targets.js +10 -0
  57. package/skills/agent-failure-debugging/SKILL.md +92 -0
  58. package/skills/agent-failure-debugging/evals/triggers.json +16 -0
  59. package/skills/agent-outbound-messaging/SKILL.md +92 -0
  60. package/skills/agent-outbound-messaging/evals/triggers.json +16 -0
  61. package/skills/agent-security/SKILL.md +117 -0
  62. package/skills/agent-security/evals/triggers.json +16 -0
  63. package/skills/agent-security/references/host-configs.md +37 -0
  64. package/skills/api-client-integration/SKILL.md +86 -0
  65. package/skills/api-client-integration/evals/triggers.json +16 -0
  66. package/skills/api-client-integration/references/resilience.md +57 -0
  67. package/skills/blender-automation/SKILL.md +100 -0
  68. package/skills/blender-automation/evals/triggers.json +16 -0
  69. package/skills/blender-automation/references/batch-and-render.md +77 -0
  70. package/skills/blender-automation/references/bpy-inspection.md +91 -0
  71. package/skills/blender-automation/references/rig-and-retarget-checks.md +23 -0
  72. package/skills/brand-strategy/SKILL.md +83 -0
  73. package/skills/brand-strategy/evals/triggers.json +16 -0
  74. package/skills/change-impact-analysis/SKILL.md +89 -0
  75. package/skills/change-impact-analysis/evals/triggers.json +16 -0
  76. package/skills/change-impact-analysis/references/graph-commands.md +28 -0
  77. package/skills/contract-drafting/SKILL.md +96 -0
  78. package/skills/contract-drafting/evals/triggers.json +16 -0
  79. package/skills/contract-drafting/references/term-sheets.md +68 -0
  80. package/skills/contract-first-development/SKILL.md +86 -0
  81. package/skills/contract-first-development/evals/triggers.json +16 -0
  82. package/skills/contract-first-development/references/tooling.md +46 -0
  83. package/skills/decision-council/SKILL.md +98 -0
  84. package/skills/decision-council/evals/triggers.json +16 -0
  85. package/skills/design-brainstorming/SKILL.md +132 -0
  86. package/skills/design-brainstorming/evals/behavior.json +55 -0
  87. package/skills/design-brainstorming/evals/triggers.json +16 -0
  88. package/skills/design-brainstorming/references/visual-mockups.md +34 -0
  89. package/skills/desktop-app-testing/SKILL.md +104 -0
  90. package/skills/desktop-app-testing/evals/triggers.json +16 -0
  91. package/skills/desktop-app-testing/references/drivers.md +81 -0
  92. package/skills/document-processing/SKILL.md +100 -0
  93. package/skills/document-processing/evals/triggers.json +17 -0
  94. package/skills/document-processing/references/extraction-and-ocr.md +71 -0
  95. package/skills/document-processing/references/forms-and-conversion.md +69 -0
  96. package/skills/document-processing/references/redaction.md +61 -0
  97. package/skills/energy-procurement/SKILL.md +106 -0
  98. package/skills/energy-procurement/evals/triggers.json +16 -0
  99. package/skills/finishing-a-branch/SKILL.md +127 -0
  100. package/skills/finishing-a-branch/evals/behavior.json +49 -0
  101. package/skills/finishing-a-branch/evals/triggers.json +16 -0
  102. package/skills/freight-carrier-management/SKILL.md +107 -0
  103. package/skills/freight-carrier-management/evals/triggers.json +16 -0
  104. package/skills/git-worktrees/SKILL.md +130 -0
  105. package/skills/git-worktrees/evals/behavior.json +56 -0
  106. package/skills/git-worktrees/evals/triggers.json +16 -0
  107. package/skills/google-workspace-integration/SKILL.md +65 -0
  108. package/skills/google-workspace-integration/evals/triggers.json +17 -0
  109. package/skills/google-workspace-integration/references/api.md +121 -0
  110. package/skills/harmonyos-arkts/SKILL.md +117 -0
  111. package/skills/harmonyos-arkts/evals/triggers.json +16 -0
  112. package/skills/harmonyos-arkts/references/build-errors.md +42 -0
  113. package/skills/implementation-plans/SKILL.md +117 -0
  114. package/skills/implementation-plans/evals/behavior.json +54 -0
  115. package/skills/implementation-plans/evals/triggers.json +16 -0
  116. package/skills/ios-platform-features/SKILL.md +99 -0
  117. package/skills/ios-platform-features/evals/triggers.json +16 -0
  118. package/skills/ios-platform-features/references/foundation-models.md +90 -0
  119. package/skills/jvm-sql-mappers/SKILL.md +98 -0
  120. package/skills/jvm-sql-mappers/evals/triggers.json +16 -0
  121. package/skills/jvm-sql-mappers/references/examples.md +129 -0
  122. package/skills/mobile-accessibility/SKILL.md +94 -0
  123. package/skills/mobile-accessibility/evals/triggers.json +16 -0
  124. package/skills/network-design/SKILL.md +98 -0
  125. package/skills/network-design/evals/triggers.json +16 -0
  126. package/skills/observability/SKILL.md +125 -0
  127. package/skills/observability/evals/triggers.json +17 -0
  128. package/skills/observability/references/otel-setup.md +87 -0
  129. package/skills/observability/references/slo-alerts.md +70 -0
  130. package/skills/open-source-release/SKILL.md +107 -0
  131. package/skills/open-source-release/evals/triggers.json +15 -0
  132. package/skills/open-source-release/references/history-scrub.md +65 -0
  133. package/skills/patent-research/SKILL.md +94 -0
  134. package/skills/patent-research/evals/triggers.json +16 -0
  135. package/skills/patent-research/references/databases-and-queries.md +52 -0
  136. package/skills/prospect-research/SKILL.md +87 -0
  137. package/skills/prospect-research/evals/triggers.json +16 -0
  138. package/skills/python-app-distribution/SKILL.md +107 -0
  139. package/skills/python-app-distribution/evals/triggers.json +16 -0
  140. package/skills/python-app-distribution/references/pypi-trusted-publishing.md +55 -0
  141. package/skills/python-app-distribution/references/windows-macos-signing.md +70 -0
  142. package/skills/quality-nonconformance/SKILL.md +107 -0
  143. package/skills/quality-nonconformance/evals/triggers.json +16 -0
  144. package/skills/quality-nonconformance/references/8d-and-capa.md +46 -0
  145. package/skills/react-testing/SKILL.md +121 -0
  146. package/skills/react-testing/evals/triggers.json +18 -0
  147. package/skills/react-testing/references/msw.md +64 -0
  148. package/skills/react-testing/references/queries.md +41 -0
  149. package/skills/react-testing/references/setup.md +74 -0
  150. package/skills/recommender-systems/SKILL.md +119 -0
  151. package/skills/recommender-systems/evals/triggers.json +16 -0
  152. package/skills/recommender-systems/references/evaluation.md +39 -0
  153. package/skills/refactoring-safely/evals/behavior.json +57 -0
  154. package/skills/reproducible-dev-environments/SKILL.md +132 -0
  155. package/skills/reproducible-dev-environments/evals/triggers.json +16 -0
  156. package/skills/responding-to-code-review/SKILL.md +124 -0
  157. package/skills/responding-to-code-review/evals/behavior.json +54 -0
  158. package/skills/responding-to-code-review/evals/triggers.json +16 -0
  159. package/skills/security-review/evals/behavior.json +56 -0
  160. package/skills/session-handoff/evals/behavior.json +55 -0
  161. package/skills/skill-authoring/SKILL.md +13 -2
  162. package/skills/skill-authoring/evals/triggers.json +2 -1
  163. package/skills/skill-authoring/references/pressure-testing.md +87 -0
  164. package/skills/slide-decks/SKILL.md +107 -0
  165. package/skills/slide-decks/evals/triggers.json +18 -0
  166. package/skills/slide-decks/references/html-decks.md +86 -0
  167. package/skills/slide-decks/references/layouts.md +45 -0
  168. package/skills/slide-decks/references/pptx.md +87 -0
  169. package/skills/subagent-driven-development/SKILL.md +109 -0
  170. package/skills/subagent-driven-development/evals/behavior.json +53 -0
  171. package/skills/subagent-driven-development/evals/triggers.json +15 -0
  172. package/skills/subagent-driven-development/references/implementer-brief.md +60 -0
  173. package/skills/subagent-driven-development/references/reviewer-briefs.md +52 -0
  174. package/skills/systematic-debugging/SKILL.md +92 -0
  175. package/skills/systematic-debugging/evals/behavior.json +59 -0
  176. package/skills/systematic-debugging/evals/triggers.json +16 -0
  177. package/skills/systematic-debugging/references/condition-waiting.md +52 -0
  178. package/skills/systematic-debugging/references/root-cause-tracing.md +49 -0
  179. package/skills/systematic-debugging/references/test-pollution.md +46 -0
  180. package/skills/tdd-workflow/SKILL.md +3 -1
  181. package/skills/tdd-workflow/evals/behavior.json +55 -0
  182. package/skills/tdd-workflow/evals/triggers.json +2 -1
  183. package/skills/tdd-workflow/references/testing-anti-patterns.md +87 -0
  184. package/skills/transactional-email/SKILL.md +68 -0
  185. package/skills/transactional-email/evals/triggers.json +17 -0
  186. package/skills/transactional-email/references/providers.md +63 -0
  187. package/skills/ui-demo-recording/SKILL.md +93 -0
  188. package/skills/ui-demo-recording/evals/triggers.json +16 -0
  189. package/skills/ui-demo-recording/references/cursor-and-captions.md +48 -0
  190. package/skills/ui-demo-recording/references/playwright-recording.md +63 -0
  191. package/skills/ui-demo-recording/references/post-processing.md +57 -0
  192. package/skills/ui-design-polish/SKILL.md +113 -0
  193. package/skills/ui-design-polish/evals/triggers.json +18 -0
  194. package/skills/ui-design-polish/references/detail-checklist.md +45 -0
  195. package/skills/ui-design-polish/references/tokens.md +68 -0
  196. package/skills/ui-flow-audit/SKILL.md +112 -0
  197. package/skills/ui-flow-audit/evals/triggers.json +17 -0
  198. package/skills/ui-motion/SKILL.md +103 -0
  199. package/skills/ui-motion/evals/triggers.json +18 -0
  200. package/skills/ui-motion/references/patterns.md +138 -0
  201. package/skills/ui-motion/references/tokens.md +52 -0
  202. package/skills/unicode-text-processing/SKILL.md +103 -0
  203. package/skills/unicode-text-processing/evals/triggers.json +17 -0
  204. package/skills/unicode-text-processing/references/apis.md +89 -0
  205. package/skills/unicode-text-processing/references/script-notes.md +50 -0
  206. package/skills/verification-loop/evals/behavior.json +52 -0
  207. package/skills/video-editing/SKILL.md +111 -0
  208. package/skills/video-editing/evals/triggers.json +16 -0
  209. package/skills/video-editing/references/edl-and-logging.md +44 -0
  210. package/skills/video-editing/references/ffmpeg-edit-recipes.md +92 -0
  211. package/skills/video-editing/references/resolve-scripting.md +53 -0
@@ -0,0 +1,27 @@
1
+ ---
2
+ name: debug
3
+ description: Find the root cause of a bug, failing test or unexpected behaviour by evidence before proposing or making any fix.
4
+ license: MIT
5
+ metadata:
6
+ kete-loom/version: "0.1.0"
7
+ kete-loom/category: coding
8
+ kete-loom/risk: runs-commands
9
+ kete-loom/argument-hint: "<symptom, error message or failing test>"
10
+ kete-loom/owner: "Kete-org"
11
+ ---
12
+
13
+ Find the root cause of the problem below before fixing anything.
14
+
15
+ If the user gave no symptom, ask for the error, the failing test or the steps that reproduce it, and stop.
16
+
17
+ If the `systematic-debugging` skill is available, follow it. Otherwise:
18
+
19
+ 1. Read the full error and stack trace. Reproduce the failure reliably and write down the exact command or steps.
20
+ 2. Check what changed: `git log`, `git diff`, recent dependency or config changes. For a regression, consider `git bisect run <script>`.
21
+ 3. Trace the bad value back to where it first goes wrong, adding temporary logging at component boundaries if needed. Compare with similar code that works.
22
+ 4. State one hypothesis and test it with the smallest possible change or experiment. If it is wrong, form a new one; do not stack fixes.
23
+ 5. State the root cause in one sentence with file:line. To fix it, write a failing test first (`/fix-bug` or the `tdd-workflow` skill). If three fixes in a row fail, stop and question the design with the user.
24
+
25
+ Report: reproduction, root cause, evidence, proposed fix, and what is still unknown.
26
+
27
+ Problem from the user: $ARGUMENTS
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: dual-review
3
+ description: Two independent reviewers, optionally on different models or providers, review the same change against one rubric; fix and repeat until both approve or the round limit is hit, then report disagreements.
4
+ license: MIT
5
+ metadata:
6
+ kete-loom/version: "0.1.0"
7
+ kete-loom/category: coding
8
+ kete-loom/risk: runs-commands
9
+ kete-loom/requires: "git"
10
+ kete-loom/argument-hint: "[scope] [--rounds N] [--models a,b]"
11
+ kete-loom/owner: "Kete-org"
12
+ ---
13
+
14
+ Run a dual review of the change below. Default: 3 rounds at most.
15
+
16
+ 1. **Scope.** Use the files, commit range or PR in the arguments; otherwise `git diff HEAD` plus untracked files from `git status --short`; if empty, the branch diff against its merge base with the default branch. If there is nothing to review, say so and stop.
17
+ 2. **Rubric.** Write one rubric and give it to both reviewers unchanged: correctness, security, error handling, tests for changed behaviour, breaking changes for callers. Each finding needs `path:line`, severity (blocking | should fix | nit) and a concrete fix. Verdict: approve | request changes.
18
+ 3. **Reviewers.** Start two reviewers in separate contexts, at the same time, with the same scope and rubric, and never show either the other's output. Use the matching Kete Loom reviewer agent for the language (as `/review` routes: `typescript-reviewer`, `python-reviewer`, `payments-reviewer` and so on), else `code-reviewer`. If `--models` names two models or the host has a second provider configured, run one reviewer on each; otherwise use two separate subagents and say the independence is weaker. If subagents aren't available, tell the user and stop rather than reviewing twice in one context.
19
+ 4. **Reconcile.** Merge findings. Mark each as *both*, *A only* or *B only*. Check every single-reviewer finding against the code yourself before acting on it; drop ones you can disprove and note why.
20
+ 5. **Fix.** Show the user the blocking and should-fix list and ask before editing. Apply the smallest fix per finding, run the project's tests, and don't touch code outside the scope.
21
+ 6. **Repeat.** Re-run both reviewers on the updated diff with fresh contexts. Stop when both approve, at the round limit, or when a round fixes nothing new (the same blocking findings keep coming back); in the last two cases list every unresolved blocking finding under Open. Never weaken the rubric to get an approval.
22
+
23
+ Report:
24
+
25
+ ```
26
+ ## Dual review: <scope> Rounds: <n>/<max> Reviewers: <A agent/model>, <B agent/model>
27
+ Verdict: both approve | A approves, B requests changes | both request changes
28
+ Fixed: path:line — issue (found by A|B|both)
29
+ Open: path:line — issue — why not fixed
30
+ Disagreements: <finding> — A says ..., B says ..., your assessment
31
+ Tests: <command> → <result>
32
+ ```
33
+
34
+ Scope and options: $ARGUMENTS
@@ -3,20 +3,21 @@ name: feature-dev
3
3
  description: Build a feature end to end: plan it, implement it test-first, review it and verify it, stopping for approval between stages.
4
4
  license: MIT
5
5
  metadata:
6
- kete-loom/version: "0.1.0"
6
+ kete-loom/version: "0.2.0"
7
7
  kete-loom/category: coding
8
8
  kete-loom/risk: writes-files
9
9
  kete-loom/argument-hint: "<the feature>"
10
10
  kete-loom/owner: "Kete-org"
11
11
  ---
12
12
 
13
- Build the feature below in four stages. Stop after each stage, show the result, and wait for the user before starting the next.
13
+ Build the feature below in stages. Stop after each stage, show the result, and wait for the user before starting the next.
14
14
 
15
- 1. **Plan.** Use the `planner` agent if available (otherwise plan it yourself): files to touch, tests to add, risks, and anything to ask. Ask the open questions now.
16
- 2. **Build test-first.** Follow the `tdd-workflow` skill: a failing test for each behaviour, the smallest change that passes it, then refactor with the suite green. Keep to the plan; if the plan turns out wrong, stop and say so.
17
- 3. **Review.** Run `/review` (or the language reviewer agent, or `code-reviewer`) on the change. Fix what it finds that is in scope, and list the rest.
18
- 4. **Verify.** Run the project's checks with the `verification-loop` skill (or `/verify`) and report pass or fail per check.
15
+ 1. **Design.** If the feature is more than a small, well-defined change, agree the design first with the `design-brainstorming` skill (one question at a time, two or three approaches, approval per section). Skip this for small changes.
16
+ 2. **Plan.** Write the plan with the `implementation-plans` skill, or use the `planner` agent (otherwise plan it yourself): files to touch, tests to add, risks, and anything to ask. Ask the open questions now. For larger work, offer an isolated workspace with the `git-worktrees` skill.
17
+ 3. **Build test-first.** Follow the `tdd-workflow` skill: a failing test for each behaviour, the smallest change that passes it, then refactor with the suite green. For a plan with several tasks on a host with subagents, run it with the `subagent-driven-development` skill. Keep to the plan; if the plan turns out wrong, stop and say so.
18
+ 4. **Review.** Run `/review` (or the language reviewer agent, or `code-reviewer`) on the change. Fix what it finds that is in scope, and list the rest.
19
+ 5. **Verify.** Run the project's checks with the `verification-loop` skill (or `/verify`) and report pass or fail per check.
19
20
 
20
- Finish with a short summary: what changed, the tests added, the checks run, and anything left. Don't commit or push unless the user asks.
21
+ Finish with a short summary: what changed, the tests added, the checks run, and anything left. Don't commit or push unless the user asks; when they want to wrap up, use the `finishing-a-branch` skill (or `/finish-branch`).
21
22
 
22
23
  Feature: $ARGUMENTS
@@ -0,0 +1,26 @@
1
+ ---
2
+ name: finish-branch
3
+ description: Finish the current branch - run the checks, confirm the base, then merge locally, open a pull request, keep it or discard it, with cleanup and no force-push or deletion without consent.
4
+ license: MIT
5
+ metadata:
6
+ kete-loom/version: "0.1.0"
7
+ kete-loom/category: coding
8
+ kete-loom/risk: runs-commands
9
+ kete-loom/requires: "git"
10
+ kete-loom/argument-hint: "[base branch]"
11
+ kete-loom/owner: "Kete-org"
12
+ ---
13
+
14
+ Finish the work on the current branch.
15
+
16
+ If the `finishing-a-branch` skill is available, follow it. Otherwise:
17
+
18
+ 1. If the working tree has uncommitted changes, ask what to do with them. Run the project's checks (`/verify`); if any fail, report them and stop.
19
+ 2. Confirm the base branch (the one given below, else the repository's default branch), and ask if unsure. Show `git log --oneline <base>..HEAD`.
20
+ 3. Offer exactly four choices and wait: merge into the base locally, push and open a pull request, keep the branch as it is, or discard it.
21
+ 4. Merge: switch to the base, `git merge <branch>`, re-run the checks, then delete the branch with `git branch -d`. Pull request: `git push -u origin <branch>` and create it as `/pr` does. Keep: change nothing. Discard: list the commits and files that will be lost and require the user to type `discard <branch>` before `git branch -D`.
22
+ 5. Remove the branch's worktree (`git worktree remove`, then `git worktree prune`) only after a merge or a confirmed discard; keep it for a pull request.
23
+
24
+ Never force-push, delete a remote branch or use `--force` without the user's explicit consent.
25
+
26
+ Base branch from the user, if any: $ARGUMENTS
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: fix-bug
3
+ description: Fix a reported bug by reproducing it as a failing regression test, finding the root cause, making the smallest fix, verifying, reviewing the diff and offering a commit.
4
+ license: MIT
5
+ metadata:
6
+ kete-loom/version: "0.1.0"
7
+ kete-loom/category: coding
8
+ kete-loom/risk: runs-commands
9
+ kete-loom/requires: "git"
10
+ kete-loom/argument-hint: "<bug report, issue link or failing behaviour>"
11
+ kete-loom/owner: "Kete-org"
12
+ ---
13
+
14
+ Fix the bug described below. If no bug was given, ask for the report (what happened, what was expected, how to trigger it) and stop.
15
+
16
+ 1. **Understand.** Restate the bug as: input or steps, expected result, actual result. If you can't, ask the user for the missing detail. Run the existing test suite once; if it already fails, report which tests fail and ask before going on.
17
+ 2. **Reproduce as a failing test.** Write a regression test that reproduces the bug exactly as reported, next to the existing tests for that code and in their style. Run it and confirm it fails for the reported reason, not a typo or import error. If the `tdd-workflow` skill is available, follow its red step. If the bug can't be captured in an automated test (timing, environment, external service), write down the manual reproduction, show it failing, and tell the user why there is no test.
18
+ 3. **Find the root cause.** Trace from the failing test to where the wrong value first appears; read the code, add temporary logging, or use `git log -L` or `git bisect run <script>` when the bug is a regression (keep the new test in a script or file outside the tracked tree, since older commits don't contain it). Search the codebase for every caller of the function you will change and for the same mistake elsewhere. State the root cause in one sentence before editing. Fix the cause, not the symptom (no special-casing the reported input).
19
+ 4. **Smallest fix.** Change only what the root cause requires. No refactors, renames or dependency upgrades in the same change. Never weaken, skip or delete an existing test to get green; if one conflicts with the fix, stop and ask.
20
+ 5. **Verify.** Run the new test (now passing), the tests for the changed module and its callers, then the full check set. If the `verification-loop` skill is available, follow it; otherwise run the project's build, lint, type-check and test commands. If the fix touches a shared module, consider the `change-impact-analysis` skill for its consumers.
21
+ 6. **Review the diff.** Delegate to the `code-reviewer` agent if it is available (or the reviewer for that language); otherwise read `git diff` yourself for correctness, error paths, and leftover debug code. Remove temporary logging.
22
+ 7. **Offer a commit.** Propose a message such as `fix(<area>): <what was wrong>` with the root cause in the body and the issue reference if given. Commit only if the user agrees; never push.
23
+
24
+ Stop and ask the user if the fix changes documented or public behaviour, needs a data migration or a dependency change, or if three focused attempts haven't found the root cause.
25
+
26
+ Report:
27
+
28
+ ```
29
+ ## Bug fix: <summary>
30
+ Reproduction: <test path::name, or manual steps>
31
+ Root cause: <one sentence, file:line>
32
+ Fix: <files changed: what>
33
+ Verification: <commands> -> <pass/fail counts>
34
+ Review: <findings addressed, or none>
35
+ Commit: <proposed message> (committed: yes/no)
36
+ ```
37
+
38
+ Bug report from the user: $ARGUMENTS
@@ -0,0 +1,45 @@
1
+ ---
2
+ name: production-readiness
3
+ description: Audit a service before launch for health checks, observability, rollback, backups, limits, secrets and runbooks, and return a go/no-go list with evidence.
4
+ license: MIT
5
+ metadata:
6
+ kete-loom/version: "0.1.0"
7
+ kete-loom/category: devops
8
+ kete-loom/risk: runs-commands
9
+ kete-loom/argument-hint: "[service path or name]"
10
+ kete-loom/owner: "Kete-org"
11
+ ---
12
+
13
+ Audit this service for production readiness. Do not edit files and do not run anything that changes infrastructure or data; read the code, config and docs, and run only read-only commands.
14
+
15
+ 1. Find the service: the path or name below, or the repository root. Identify how it is built, deployed (Dockerfile, Kubernetes manifests, Helm, Terraform, CI workflows) and configured.
16
+ 2. Check each area, using the matching Kete Loom skill as the standard when it is available:
17
+ - **Health checks**: liveness and readiness endpoints, wired into the deploy config, readiness checking real dependencies (`kubernetes-patterns`, `deployment-strategies`).
18
+ - **Observability**: structured logs with trace IDs, RED metrics, traces, SLOs, alerts that link to runbooks, an on-call dashboard (`observability`).
19
+ - **Rollback**: a tested way back to the previous version, and schema changes that the old version survives (`deployment-strategies`, `database-migrations`).
20
+ - **Backups**: automated backups of every stateful store, retention, and a restore that has actually been tested.
21
+ - **Limits**: CPU and memory requests and limits, timeouts and retries with backoff on outbound calls, rate limits, connection pool sizes, autoscaling bounds.
22
+ - **Secrets**: no secrets in the repo or images, read from a secret store or environment, rotation possible (`security-review` for depth).
23
+ - **Runbooks and ownership**: an owner, an on-call rotation, a runbook for each paging alert (`runbook-writing`).
24
+ - **Dependencies and images**: pinned base images, no known critical vulnerabilities (`dependency-audit`, `docker-patterns`).
25
+ 3. For deeper infrastructure review delegate to the `infra-reviewer` agent if it is available. If none of the skills are installed, apply the checks above directly.
26
+ 4. Mark each item from evidence: a file and line, a command output, or a link. If you cannot find evidence, mark it **unknown**, not pass. Ask the user about anything that lives outside the repo (backup restore tests, on-call rotation).
27
+
28
+ Return:
29
+
30
+ ```
31
+ ## Production readiness: <service>
32
+ Verdict: GO | GO WITH CONDITIONS | NO-GO
33
+ Blockers (must fix before launch)
34
+ - <area>: <finding>. Evidence: <path:line or output>. Fix: <action>
35
+ Conditions (fix within <agreed time> after launch)
36
+ - ...
37
+ Passed
38
+ - <area>: <evidence>
39
+ Unknown (needs an answer from the team)
40
+ - <question>
41
+ ```
42
+
43
+ Any blocker means NO-GO. Health checks, rollback, backups for stateful data and secrets handling are blockers when missing.
44
+
45
+ Service or focus from the user, if any: $ARGUMENTS
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: usage-report
3
+ description: Summarise token usage and estimated cost per session, project and model from local agent session logs (Claude Code, Codex, Gemini CLI, OpenCode, Kete Code), read-only.
4
+ license: MIT
5
+ metadata:
6
+ kete-loom/version: "0.1.0"
7
+ kete-loom/category: ai
8
+ kete-loom/risk: runs-commands
9
+ kete-loom/argument-hint: "[today | 7d | 30d | since YYYY-MM-DD] [host] [project]"
10
+ kete-loom/owner: "Kete-org"
11
+ ---
12
+
13
+ Build a token usage report from local agent session logs. Read-only: never edit, move or delete a log, and never send log contents anywhere. Logs contain prompts and code; only print aggregates, never message text.
14
+
15
+ Default period: last 7 days, all hosts found. Formats change between releases, so inspect one record before parsing and say if a format looks different from below.
16
+
17
+ **Where to look**
18
+
19
+ - **Claude Code**: `~/.claude/projects/<project-slug>/*.jsonl` (subagent logs may sit in subfolders). Assistant lines carry `message.model` and `message.usage` with `input_tokens`, `output_tokens`, `cache_creation_input_tokens`, `cache_read_input_tokens`. One response can span several lines with the same `message.id` and repeated usage; count each `message.id` (plus `requestId` if present) once. Skip lines whose model is `<synthetic>`. Project = `cwd` field, or the slug.
20
+ - **Codex**: `~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl`. `event_msg` records with `payload.type == "token_count"` hold `info.total_token_usage` (cumulative: `input_tokens`, `cached_input_tokens`, `output_tokens`, `reasoning_output_tokens`); take the last non-null `info` per file, not the sum (early records can have `info: null`). Model and `cwd` come from `turn_context` records.
21
+ - **Gemini CLI**: `~/.gemini/tmp/<project-hash>/chats/` (session files with per-message token counts). Check whether files are `.json` or `.jsonl` before parsing. Read only `chats/`; `/chat save` and checkpoint files elsewhere under the project folder repeat the same conversation and would double-count.
22
+ - **OpenCode**: SQLite at the path `opencode db path` prints (usually `~/.local/share/opencode/opencode.db`); older versions used JSON under `~/.local/share/opencode/storage/`. **Kete Code**: `~/.local/share/kete/kete.db`; table `session_v2` has `directory`, `cost`, `tokens_input`, `tokens_output`, `tokens_reasoning`, `tokens_cache_read`, `tokens_cache_write`. Open databases read-only (`sqlite3 -readonly`); inspect `.tables` and `.schema` first.
23
+
24
+ **Steps**
25
+
26
+ 1. Find which of these exist; skip missing ones and list them under "Not found".
27
+ 2. Write a small throwaway script in a temporary directory (Node or Python, no installs) that streams the files, filters by timestamp to the period, and aggregates by host, project, model, and session. Don't load huge files into memory at once.
28
+ 3. Keep input, cache write, cache read, output and reasoning tokens as separate columns; they are priced differently.
29
+ 4. Cost: use a cost the log itself records where present (OpenCode, Kete Code). Otherwise estimate with per-million-token prices for each model, and state the prices used and their date. Prices change: tell the user to check them against each provider's current pricing page; never present the estimate as a bill. Subscription plans aren't billed per token, so say the figure is the API-equivalent cost.
30
+
31
+ **Report**
32
+
33
+ ```
34
+ ## Agent usage: <period>
35
+ Totals: <sessions>, input <n>, cache write <n>, cache read <n>, output <n>, est. cost <$>
36
+ By host and model: table (host, model, sessions, tokens by type, est. cost)
37
+ By project: top 10 by est. cost
38
+ Top sessions: top 5 (date, host, project, model, tokens, est. cost)
39
+ Prices used: <model: $in/$out/$cache per 1M, source, date>; check current provider price pages
40
+ Not found / unparsed: <hosts, files skipped and why>
41
+ ```
42
+
43
+ Period, host or project filter: $ARGUMENTS
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: block-foreground-servers
3
+ description: Stops the agent from starting a dev server or file watcher in the foreground, where it never exits and hangs the agent's shell, and tells it to run it in the background with output going to a log.
4
+ license: MIT
5
+ metadata:
6
+ kete-loom/version: "0.1.0"
7
+ kete-loom/category: devops
8
+ kete-loom/risk: read-only
9
+ kete-loom/event: "pre-shell"
10
+ kete-loom/opt-in: "true"
11
+ kete-loom/owner: "Kete-org"
12
+ ---
13
+
14
+ # Block foreground servers
15
+
16
+ Runs before every shell command. It blocks commands that start a long-running server or watcher and never return:
17
+
18
+ - `npm|pnpm|yarn|bun run dev|start|serve|watch`, `next dev`, `vite` (not `vite build`), `ng serve`, `webpack serve`, `nodemon`;
19
+ - `rails server`, `php artisan serve`, `flask run`, `uvicorn`, `python -m http.server`, `manage.py runserver`;
20
+ - `docker compose up` without `-d`, `hugo server`, `jekyll serve`, `tsc --watch`, test runners in `--watch` mode.
21
+
22
+ They are allowed when they are already backgrounded:
23
+
24
+ - with a trailing `&` or `nohup`;
25
+ - under `setsid`, `tmux`, `screen`, `pm2` or `timeout`;
26
+ - by the host's own background option (for example Claude Code's background shell).
27
+
28
+ When it blocks, the agent is told to start the server in the background with its output in a log file, wait for it to be ready, and stop it when done:
29
+
30
+ ```bash
31
+ npm run dev > .dev-server.log 2>&1 &
32
+ ```
33
+
34
+ Opt-in: `--hooks` leaves it out; install it by name with `--hook` or with `--profile strict`.
@@ -0,0 +1,31 @@
1
+ {
2
+ "should_block": [
3
+ "npm run dev",
4
+ "pnpm dev",
5
+ "yarn start",
6
+ "bun run dev --port 3001",
7
+ "cd web && npx next dev",
8
+ "npx vite",
9
+ "ng serve --open",
10
+ "rails server -p 4000",
11
+ "python -m http.server 8000",
12
+ "uvicorn app.main:app --reload",
13
+ "docker compose up",
14
+ "npx tsc --watch",
15
+ "npx vitest --watch"
16
+ ],
17
+ "should_allow": [
18
+ "npm run build",
19
+ "npm test",
20
+ "npx vite build",
21
+ "npm run dev > .dev-server.log 2>&1 &",
22
+ "nohup python -m http.server 8000 > http.log 2>&1 &",
23
+ "docker compose up -d",
24
+ "docker compose up --detach db",
25
+ "timeout 20 npm start",
26
+ "tmux new -d -s web 'npm run dev'",
27
+ "npm run start:prod -- --help",
28
+ "grep -r 'npm run dev' README.md",
29
+ "npx vitest run"
30
+ ]
31
+ }
@@ -0,0 +1,41 @@
1
+ 'use strict';
2
+
3
+ // Blocks shell commands that start a dev server or watcher in the foreground (they never return and
4
+ // hang the agent's shell) unless they are already backgrounded. check({ command, background }) -> verdict.
5
+
6
+ const SERVER = [
7
+ /\b(?:npm|pnpm|yarn|bun)\s+(?:run\s+)?(?:dev|start|serve|watch)\b(?!:)/,
8
+ /\bnext\s+dev\b/,
9
+ /(?:^|[\s;&|(])(?:npx\s+)?vite(?:\s+(?:dev|serve|--\S+|\.)|\s*$)/,
10
+ /\bng\s+serve\b/,
11
+ /\bwebpack(?:-dev-server|\s+serve)\b/,
12
+ /\bnodemon\b/,
13
+ /\brails\s+s(?:erver)?\b/,
14
+ /\bartisan\s+serve\b/,
15
+ /\bflask\s+run\b/,
16
+ /\buvicorn\b/,
17
+ /\bpython3?\s+-m\s+http\.server\b/,
18
+ /\bmanage\.py\s+runserver\b/,
19
+ /\bdocker[\s-]compose\s+(?:\S+\s+)*?up\b(?![^;&|]*\s(?:-d|--detach)\b)/,
20
+ /\bhugo\s+server\b/,
21
+ /\bjekyll\s+serve\b/,
22
+ /\btsc\b[^;&|]*\s(?:--watch|-w)\b/,
23
+ /\b(?:vitest|jest)\b[^;&|]*\s--watch\b/,
24
+ ];
25
+ const BACKGROUNDED = /(?:^|\s)(?:nohup|setsid|tmux|screen|pm2|timeout)\s|&\s*(?:disown\s*)?$|&\s*(?:;|$)/;
26
+
27
+ function check(event) {
28
+ const command = String(event.command || '');
29
+ if (event.background) return { block: false };
30
+ if (BACKGROUNDED.test(command.trim())) return { block: false };
31
+ // shortcut: quoted text is ignored (so `grep 'npm run dev'` passes), which also lets `sh -c "npm run dev"` through.
32
+ const bare = command.replace(/'[^']*'|"(?:[^"\\]|\\.)*"/g, "''");
33
+ const hit = SERVER.find((re) => re.test(bare));
34
+ if (!hit) return { block: false };
35
+ return {
36
+ block: true,
37
+ reason: 'Blocked by kete-loom (block-foreground-servers): this starts a server or watcher that never exits and would hang the shell. Run it in the background with output in a log, e.g. `npm run dev > .dev-server.log 2>&1 &`, poll the log or the port until it is ready, and stop it when you are done.',
38
+ };
39
+ }
40
+
41
+ module.exports = { check };
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: capture-lessons
3
+ description: Once per session, when the agent finishes with changes in the repository, asks it to propose up to three reusable lessons from the session for /learn, saving nothing unless you approve.
4
+ license: MIT
5
+ metadata:
6
+ kete-loom/version: "0.1.0"
7
+ kete-loom/category: meta
8
+ kete-loom/risk: writes-files
9
+ kete-loom/event: "stop-gate"
10
+ kete-loom/opt-in: "true"
11
+ kete-loom/owner: "Kete-org"
12
+ ---
13
+
14
+ # Capture lessons
15
+
16
+ Runs when the agent ends its turn, in a git repository with uncommitted changes. Once per session, it sends the agent back with one request: propose at most three lessons this session taught. Each lesson can be a mistake it made, a correction you gave, or something it had to work out about the project. A lesson is written as one line plus the evidence for it, or as "No lessons".
17
+
18
+ The agent saves nothing on its own. You turn the lessons you want into rules, skills or AGENTS.md entries with `/learn`.
19
+
20
+ It remembers which sessions it has asked in `~/.kete-loom/state/capture-lessons.json` (set `KETE_LOOM_STATE_DIR` to move it). It keeps them per session when the host sends a session id, otherwise once per project per day. It reads no files and never uses the network.
21
+
22
+ Available in Claude Code, Codex, Gemini CLI, Cursor and GitHub Copilot. Kete Code's and OpenCode's stop hooks can't send the agent back to work.
23
+
24
+ Opt-in: `--hooks` leaves it out; install it by name with `--hook`.
@@ -0,0 +1,48 @@
1
+ 'use strict';
2
+
3
+ // Once per session, when the agent finishes with uncommitted changes, asks it to propose up to three
4
+ // lessons for /learn. Saves nothing itself. check({ cwd, session, again }) -> verdict.
5
+
6
+ const fs = require('fs');
7
+ const os = require('os');
8
+ const path = require('path');
9
+ const { execFileSync } = require('child_process');
10
+
11
+ const KEEP_MS = 14 * 24 * 60 * 60 * 1000;
12
+
13
+ const stateFile = () => path.join(process.env.KETE_LOOM_STATE_DIR || path.join(os.homedir(), '.kete-loom', 'state'), 'capture-lessons.json');
14
+
15
+ function check(event, now = Date.now()) {
16
+ if (event.again) return { block: false };
17
+ const cwd = path.resolve(event.cwd || process.cwd());
18
+ let status;
19
+ try {
20
+ status = execFileSync('git', ['status', '--porcelain'], { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 5000 });
21
+ } catch {
22
+ return { block: false };
23
+ }
24
+ if (!status.trim()) return { block: false };
25
+ const file = stateFile();
26
+ let asked = {};
27
+ try {
28
+ asked = JSON.parse(fs.readFileSync(file, 'utf8'));
29
+ } catch {
30
+ // first run
31
+ }
32
+ for (const k of Object.keys(asked)) if (!(now - asked[k] < KEEP_MS)) delete asked[k];
33
+ const key = event.session || `${cwd}@${new Date(now).toISOString().slice(0, 10)}`;
34
+ if (asked[key]) return { block: false };
35
+ asked[key] = now;
36
+ try {
37
+ fs.mkdirSync(path.dirname(file), { recursive: true });
38
+ fs.writeFileSync(file, JSON.stringify(asked));
39
+ } catch {
40
+ return { block: false }; // without the record it would ask on every stop
41
+ }
42
+ return {
43
+ block: true,
44
+ reason: 'kete-loom (capture-lessons): before you finish, list at most 3 lessons from this session worth keeping for next time: a mistake you made, a correction the user gave, or a non-obvious fact about this project. One line each, with the evidence. Do not save them anywhere; the user decides with /learn. If there is nothing worth keeping, reply "No lessons" and stop.',
45
+ };
46
+ }
47
+
48
+ module.exports = { check };
@@ -0,0 +1,25 @@
1
+ ---
2
+ name: notify-on-stop
3
+ description: Shows a desktop notification when the agent finishes its turn, so you can switch away during long tasks and come back when it is your move.
4
+ license: MIT
5
+ metadata:
6
+ kete-loom/version: "0.1.0"
7
+ kete-loom/category: meta
8
+ kete-loom/risk: runs-commands
9
+ kete-loom/event: "stop"
10
+ kete-loom/opt-in: "true"
11
+ kete-loom/owner: "Kete-org"
12
+ ---
13
+
14
+ # Notify on stop
15
+
16
+ Runs when the agent ends its turn and shows a notification naming the project folder:
17
+
18
+ - on macOS through `osascript`;
19
+ - on Linux through `notify-send`, when it is installed.
20
+
21
+ On Windows and on machines with neither, it does nothing. It never blocks, never changes files and never uses the network.
22
+
23
+ Available in Claude Code, Codex, Gemini CLI, Kete Code, Cursor and GitHub Copilot.
24
+
25
+ Opt-in: `--hooks` leaves it out; install it by name with `--hook`.
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+
3
+ // Desktop notification when the agent finishes its turn. Never blocks. check({ cwd }) -> {}
4
+
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const { execFileSync } = require('child_process');
8
+
9
+ function notifier(platform = process.platform, env = process.env) {
10
+ if (platform === 'darwin') return (title, body) => ['osascript', ['-e', `display notification ${JSON.stringify(body)} with title ${JSON.stringify(title)}`]];
11
+ if (platform === 'linux' && (env.PATH || '').split(path.delimiter).some((d) => d && fs.existsSync(path.join(d, 'notify-send')))) return (title, body) => ['notify-send', [title, body]];
12
+ return null; // shortcut: no Windows toast (it needs a PowerShell module); add one if Windows users ask
13
+ }
14
+
15
+ function check(event) {
16
+ const make = notifier();
17
+ if (!make) return {};
18
+ const [program, args] = make('Agent finished', `${path.basename(path.resolve(event.cwd || process.cwd()))}: your turn`);
19
+ try {
20
+ execFileSync(program, args, { stdio: 'ignore', timeout: 3000 });
21
+ } catch {
22
+ // a notification that can't be shown is not worth failing over
23
+ }
24
+ return {};
25
+ }
26
+
27
+ module.exports = { check, notifier };
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: protect-lint-config
3
+ description: Stops the agent from editing existing linter, formatter and type-checker configs, so it fixes the code that breaks a rule instead of weakening or switching off the rule.
4
+ license: MIT
5
+ metadata:
6
+ kete-loom/version: "0.1.0"
7
+ kete-loom/category: coding
8
+ kete-loom/risk: read-only
9
+ kete-loom/event: "pre-edit"
10
+ kete-loom/opt-in: "true"
11
+ kete-loom/owner: "Kete-org"
12
+ ---
13
+
14
+ # Protect lint config
15
+
16
+ Runs before every file write or edit. It blocks changes to existing quality-gate configs:
17
+
18
+ | Tool | Files |
19
+ |---|---|
20
+ | ESLint | `.eslintrc*`, `eslint.config.*` |
21
+ | Biome, Prettier, Stylelint | `biome.json(c)`, `.prettierrc*`, `prettier.config.*`, `.stylelintrc*`, `stylelint.config.*` |
22
+ | Python | `ruff.toml`, `.ruff.toml`, `.flake8`, `.pylintrc`, `mypy.ini`, `.mypy.ini` |
23
+ | Go, Rust, Ruby, PHP | `.golangci.yml/.yaml/.toml`, `clippy.toml`, `.clippy.toml`, `rustfmt.toml`, `.rubocop.yml`, `phpstan.neon(.dist)` |
24
+
25
+ The agent is told to fix the code that breaks the rule instead. If you asked for the config change yourself, the agent says so, and you make the edit or turn this hook off.
26
+
27
+ Creating a config that doesn't exist yet is allowed, so setting up a new project still works. Settings inside `pyproject.toml` or `package.json` are not covered, because those files hold much more than lint settings.
28
+
29
+ Opt-in: `--hooks` leaves it out; install it by name with `--hook` or with `--profile strict`. Not available in Cursor, which has no documented hook before an edit.
@@ -0,0 +1,18 @@
1
+ {
2
+ "should_block": [
3
+ { "cwd": "hooks/protect-lint-config/fixtures", "files": [{ "path": ".eslintrc.json", "content": "{\"rules\":{}}" }] },
4
+ { "cwd": "hooks/protect-lint-config/fixtures", "files": [{ "path": "eslint.config.mjs", "content": "export default []" }] },
5
+ { "cwd": "hooks/protect-lint-config/fixtures", "files": [{ "path": "biome.json", "content": "{}" }] },
6
+ { "cwd": "hooks/protect-lint-config/fixtures", "files": [{ "path": ".prettierrc", "content": "{}" }] },
7
+ { "cwd": "hooks/protect-lint-config/fixtures", "files": [{ "path": "ruff.toml", "content": "ignore = [\"E501\"]" }] },
8
+ { "cwd": "hooks/protect-lint-config/fixtures", "files": [{ "path": ".golangci.yml", "content": "linters: {}" }] },
9
+ { "cwd": "hooks/protect-lint-config/fixtures", "files": [{ "path": "src/a.ts", "content": "x" }, { "path": ".rubocop.yml", "content": "" }] }
10
+ ],
11
+ "should_allow": [
12
+ { "cwd": "hooks/protect-lint-config/fixtures", "files": [{ "path": "src/app.ts", "content": "x" }] },
13
+ { "cwd": "hooks/protect-lint-config/fixtures", "files": [{ "path": "tsconfig.json", "content": "{}" }] },
14
+ { "cwd": "hooks/protect-lint-config/fixtures", "files": [{ "path": ".stylelintrc.json", "content": "{}" }] },
15
+ { "cwd": "hooks/protect-lint-config/fixtures", "files": [{ "path": "docs/eslint-rules.md", "content": "x" }] },
16
+ { "cwd": "hooks/protect-lint-config/fixtures", "files": [{ "path": "pyproject.toml", "content": "[tool.ruff]" }] }
17
+ ]
18
+ }
@@ -0,0 +1,25 @@
1
+ 'use strict';
2
+
3
+ // Blocks edits to existing linter, formatter and type-checker configs, so the agent fixes the code
4
+ // instead of weakening the rule. New configs are allowed. check({ files: [{ path }], cwd }) -> verdict.
5
+
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+
9
+ const CONFIG = /^(?:\.eslintrc(?:\.[a-z]+)?|eslint\.config\.[cm]?[jt]s|biome\.jsonc?|\.prettierrc(?:\.[a-z]+)?|prettier\.config\.[cm]?[jt]s|\.stylelintrc(?:\.[a-z]+)?|stylelint\.config\.[cm]?js|\.?ruff\.toml|\.flake8|\.pylintrc|\.?mypy\.ini|\.golangci\.(?:ya?ml|toml|json)|\.?clippy\.toml|\.?rustfmt\.toml|\.rubocop\.yml|phpstan\.neon(?:\.dist)?)$/;
10
+
11
+ function check(event) {
12
+ const cwd = event.cwd || process.cwd();
13
+ for (const f of event.files || []) {
14
+ if (!f || typeof f.path !== 'string') continue;
15
+ const base = path.basename(f.path);
16
+ if (!CONFIG.test(base) || !fs.existsSync(path.resolve(cwd, f.path))) continue;
17
+ return {
18
+ block: true,
19
+ reason: `Blocked by kete-loom (protect-lint-config): \`${f.path}\` configures a linter or formatter. Fix the code that breaks the rule instead of changing the rule. If the user asked for this config change, tell them this hook blocks it so they can make the edit themselves.`,
20
+ };
21
+ }
22
+ return { block: false };
23
+ }
24
+
25
+ module.exports = { check };
@@ -0,0 +1,26 @@
1
+ ---
2
+ name: read-before-edit
3
+ description: Stops the first edit of each existing file in a session and tells the agent to read the file and search for its callers first, so changes are grounded in the real code rather than a guess.
4
+ license: MIT
5
+ metadata:
6
+ kete-loom/version: "0.1.0"
7
+ kete-loom/category: coding
8
+ kete-loom/risk: writes-files
9
+ kete-loom/event: "pre-edit"
10
+ kete-loom/opt-in: "true"
11
+ kete-loom/owner: "Kete-org"
12
+ ---
13
+
14
+ # Read before edit
15
+
16
+ Runs before every file write or edit. The first time in a session the agent tries to change a file that already exists, the edit is refused with this instruction:
17
+
18
+ 1. Read the whole file.
19
+ 2. Search the codebase for everything that imports, calls or configures it.
20
+ 3. Then make the same edit again.
21
+
22
+ The retry goes through, and so does every later edit of that file in the session. New files are never blocked.
23
+
24
+ It remembers which files it has seen in `~/.kete-loom/state/read-before-edit.json` (set `KETE_LOOM_STATE_DIR` to move it). It keeps them per session when the host sends a session id, otherwise per project per day. Entries older than two days are dropped. It reads no file contents and never uses the network.
25
+
26
+ Expect one extra round trip per file. Opt-in: `--hooks` leaves it out; install it by name with `--hook` or with `--profile strict`. Not available in Cursor, which has no documented hook before an edit.