liteagents 3.0.0 → 3.5.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 (154) hide show
  1. package/CHANGELOG.md +122 -1
  2. package/README.md +113 -169
  3. package/installer/cli.js +4 -2
  4. package/package.json +4 -3
  5. package/packages/ampcode/AGENT.md +10 -18
  6. package/packages/ampcode/agents/code-developer.md +11 -17
  7. package/packages/ampcode/agents/orchestrator.md +1 -1
  8. package/packages/ampcode/agents/quality-assurance.md +3 -1
  9. package/packages/ampcode/{commands/brainstorming.md → skills/brainstorming/SKILL.md} +2 -3
  10. package/packages/ampcode/{commands/branch-review.md → skills/branch-review/SKILL.md} +13 -13
  11. package/packages/{claude/commands/docs-builder.md → ampcode/skills/docs-builder/SKILL.md} +1 -1
  12. package/packages/ampcode/{commands/live-canvas.md → skills/live-canvas/SKILL.md} +8 -4
  13. package/packages/ampcode/{commands/refactor.md → skills/refactor/SKILL.md} +49 -7
  14. package/packages/ampcode/{commands/release.md → skills/release/SKILL.md} +4 -4
  15. package/packages/{claude/commands → ampcode/skills}/remember/AGENT_RULES.md +44 -84
  16. package/packages/ampcode/{commands/remember.md → skills/remember/SKILL.md} +11 -6
  17. package/packages/ampcode/{commands → skills}/remember/friction.cjs +0 -0
  18. package/packages/ampcode/{commands → skills}/remember/stub-check.cjs +28 -19
  19. package/packages/ampcode/{commands → skills}/remember/sync-rules.cjs +28 -19
  20. package/packages/{claude/commands → ampcode/skills}/remember/version-check.cjs +1 -1
  21. package/packages/ampcode/skills/root-cause/SKILL.md +220 -0
  22. package/packages/ampcode/{commands/trace-back → skills/root-cause}/find-polluter.sh +0 -0
  23. package/packages/{claude/commands/security.md → ampcode/skills/security/SKILL.md} +1 -1
  24. package/packages/{claude/commands/ship.md → ampcode/skills/ship/SKILL.md} +1 -1
  25. package/packages/ampcode/skills/skill-creator/LICENSE.txt +202 -0
  26. package/packages/ampcode/{commands/skill-creator.md → skills/skill-creator/SKILL.md} +1 -2
  27. package/packages/ampcode/{commands → skills}/skill-creator/scripts/init_skill.py +0 -0
  28. package/packages/ampcode/{commands → skills}/skill-creator/scripts/package_skill.py +0 -0
  29. package/packages/ampcode/{commands → skills}/skill-creator/scripts/quick_validate.py +0 -0
  30. package/packages/ampcode/{commands/stash.md → skills/stash/SKILL.md} +2 -1
  31. package/packages/{claude/commands/test-generate.md → ampcode/skills/test-generate/SKILL.md} +2 -2
  32. package/packages/ampcode/variants.json +2 -2
  33. package/packages/claude/CLAUDE.md +10 -17
  34. package/packages/claude/agents/code-developer.md +11 -17
  35. package/packages/claude/agents/orchestrator.md +2 -3
  36. package/packages/claude/agents/quality-assurance.md +3 -1
  37. package/packages/claude/skills/brainstorming/SKILL.md +1 -2
  38. package/packages/claude/{commands/branch-review.md → skills/branch-review/SKILL.md} +1 -1
  39. package/packages/{ampcode/commands/docs-builder.md → claude/skills/docs-builder/SKILL.md} +7 -7
  40. package/packages/claude/skills/live-canvas/SKILL.md +5 -1
  41. package/packages/claude/{commands/refactor.md → skills/refactor/SKILL.md} +45 -3
  42. package/packages/claude/{commands/release.md → skills/release/SKILL.md} +1 -1
  43. package/packages/{ampcode/commands → claude/skills}/remember/AGENT_RULES.md +38 -78
  44. package/packages/claude/{commands/remember.md → skills/remember/SKILL.md} +11 -6
  45. package/packages/claude/{commands → skills}/remember/friction.cjs +0 -0
  46. package/packages/claude/{commands → skills}/remember/stub-check.cjs +28 -19
  47. package/packages/claude/{commands → skills}/remember/sync-rules.cjs +28 -19
  48. package/packages/{ampcode/commands → claude/skills}/remember/version-check.cjs +3 -3
  49. package/packages/claude/skills/root-cause/SKILL.md +220 -0
  50. package/packages/{ampcode/commands/security.md → claude/skills/security/SKILL.md} +2 -2
  51. package/packages/{ampcode/commands/ship.md → claude/skills/ship/SKILL.md} +2 -2
  52. package/packages/claude/skills/skill-creator/SKILL.md +1 -2
  53. package/packages/claude/{commands/stash.md → skills/stash/SKILL.md} +2 -1
  54. package/packages/{ampcode/commands/test-generate.md → claude/skills/test-generate/SKILL.md} +3 -3
  55. package/packages/claude/variants.json +1 -2
  56. package/packages/droid/AGENTS.md +10 -15
  57. package/packages/droid/commands/brainstorming.md +1 -4
  58. package/packages/droid/commands/branch-review.md +11 -14
  59. package/packages/droid/commands/docs-builder.md +0 -3
  60. package/packages/droid/commands/live-canvas.md +7 -5
  61. package/packages/droid/commands/refactor.md +47 -8
  62. package/packages/droid/commands/release.md +2 -5
  63. package/packages/droid/commands/remember/AGENT_RULES.md +38 -78
  64. package/packages/droid/commands/remember/stub-check.cjs +28 -19
  65. package/packages/droid/commands/remember/sync-rules.cjs +28 -19
  66. package/packages/droid/commands/remember/version-check.cjs +1 -1
  67. package/packages/droid/commands/remember.md +6 -4
  68. package/packages/droid/commands/root-cause.md +218 -0
  69. package/packages/droid/commands/security.md +0 -3
  70. package/packages/droid/commands/ship.md +0 -3
  71. package/packages/droid/commands/skill-creator/LICENSE.txt +202 -0
  72. package/packages/droid/commands/skill-creator.md +0 -4
  73. package/packages/droid/commands/stash.md +0 -2
  74. package/packages/droid/commands/test-generate.md +1 -4
  75. package/packages/droid/droids/1-create-prd.md +6 -2
  76. package/packages/droid/droids/2-generate-tasks.md +1 -2
  77. package/packages/droid/droids/3-process-task-list.md +1 -2
  78. package/packages/droid/droids/code-developer.md +12 -19
  79. package/packages/droid/droids/feature-planner.md +1 -2
  80. package/packages/droid/droids/market-researcher.md +1 -2
  81. package/packages/droid/droids/orchestrator.md +1 -2
  82. package/packages/droid/droids/quality-assurance.md +4 -3
  83. package/packages/droid/droids/system-architect.md +1 -2
  84. package/packages/droid/droids/ui-designer.md +1 -2
  85. package/packages/opencode/AGENTS.md +10 -15
  86. package/packages/opencode/agent/code-developer.md +11 -17
  87. package/packages/opencode/agent/quality-assurance.md +3 -1
  88. package/packages/opencode/command/brainstorming.md +1 -4
  89. package/packages/opencode/command/branch-review.md +11 -15
  90. package/packages/opencode/command/docs-builder.md +0 -4
  91. package/packages/opencode/command/live-canvas.md +7 -5
  92. package/packages/opencode/command/refactor.md +47 -9
  93. package/packages/opencode/command/release.md +2 -5
  94. package/packages/opencode/command/remember/AGENT_RULES.md +38 -78
  95. package/packages/opencode/command/remember/stub-check.cjs +28 -19
  96. package/packages/opencode/command/remember/sync-rules.cjs +28 -19
  97. package/packages/opencode/command/remember/version-check.cjs +1 -1
  98. package/packages/opencode/command/remember.md +6 -4
  99. package/packages/opencode/command/root-cause.md +218 -0
  100. package/packages/opencode/command/security.md +0 -4
  101. package/packages/opencode/command/ship.md +0 -3
  102. package/packages/opencode/command/skill-creator/LICENSE.txt +202 -0
  103. package/packages/opencode/command/skill-creator.md +0 -4
  104. package/packages/opencode/command/stash.md +0 -3
  105. package/packages/opencode/command/test-generate.md +1 -5
  106. package/packages/opencode/opencode.jsonc +4 -24
  107. package/packages/subagentic-manual.md +147 -314
  108. package/packages/ampcode/commands/debug-method.md +0 -297
  109. package/packages/ampcode/commands/live-canvas/README.md +0 -264
  110. package/packages/ampcode/commands/optimize.md +0 -61
  111. package/packages/ampcode/commands/tdd-flow.md +0 -390
  112. package/packages/ampcode/commands/test-traps/example.ts +0 -158
  113. package/packages/ampcode/commands/test-traps.md +0 -378
  114. package/packages/ampcode/commands/trace-back.md +0 -176
  115. package/packages/ampcode/commands/verify-done.md +0 -152
  116. package/packages/claude/commands/optimize.md +0 -61
  117. package/packages/claude/plugins/live-canvas-marketplace/plugins/live-canvas-channel/README.md +0 -89
  118. package/packages/claude/skills/debug-method/CREATION-LOG.md +0 -119
  119. package/packages/claude/skills/debug-method/SKILL.md +0 -296
  120. package/packages/claude/skills/debug-method/test-academic.md +0 -14
  121. package/packages/claude/skills/debug-method/test-pressure-1.md +0 -58
  122. package/packages/claude/skills/debug-method/test-pressure-2.md +0 -68
  123. package/packages/claude/skills/debug-method/test-pressure-3.md +0 -69
  124. package/packages/claude/skills/live-canvas/README.md +0 -269
  125. package/packages/claude/skills/tdd-flow/SKILL.md +0 -392
  126. package/packages/claude/skills/test-traps/SKILL.md +0 -378
  127. package/packages/claude/skills/test-traps/example.ts +0 -158
  128. package/packages/claude/skills/trace-back/SKILL.md +0 -176
  129. package/packages/claude/skills/verify-done/SKILL.md +0 -152
  130. package/packages/droid/commands/debug-method.md +0 -297
  131. package/packages/droid/commands/live-canvas/README.md +0 -264
  132. package/packages/droid/commands/optimize.md +0 -61
  133. package/packages/droid/commands/tdd-flow.md +0 -390
  134. package/packages/droid/commands/test-traps/example.ts +0 -158
  135. package/packages/droid/commands/test-traps.md +0 -378
  136. package/packages/droid/commands/trace-back.md +0 -176
  137. package/packages/droid/commands/verify-done.md +0 -152
  138. package/packages/opencode/command/debug-method.md +0 -297
  139. package/packages/opencode/command/live-canvas/README.md +0 -264
  140. package/packages/opencode/command/optimize.md +0 -61
  141. package/packages/opencode/command/tdd-flow.md +0 -390
  142. package/packages/opencode/command/test-traps/example.ts +0 -158
  143. package/packages/opencode/command/test-traps.md +0 -378
  144. package/packages/opencode/command/trace-back.md +0 -176
  145. package/packages/opencode/command/verify-done.md +0 -152
  146. /package/packages/ampcode/{commands → skills}/docs-builder/docs-builder.cjs +0 -0
  147. /package/packages/ampcode/{commands → skills}/live-canvas/DESIGN_PRINCIPLES.md +0 -0
  148. /package/packages/ampcode/{commands → skills}/live-canvas/dev/post-variants.html +0 -0
  149. /package/packages/ampcode/{commands → skills}/live-canvas/templates/lab-banner.html +0 -0
  150. /package/packages/ampcode/{commands → skills}/live-canvas/templates/overlay-vanilla.js +0 -0
  151. /package/packages/claude/{commands → skills}/docs-builder/docs-builder.cjs +0 -0
  152. /package/packages/claude/skills/{trace-back → root-cause}/find-polluter.sh +0 -0
  153. /package/packages/droid/commands/{trace-back → root-cause}/find-polluter.sh +0 -0
  154. /package/packages/opencode/command/{trace-back → root-cause}/find-polluter.sh +0 -0
@@ -60,31 +60,40 @@ function lexists(p) {
60
60
  * "the file is absent" and is still followed on write — or any parent
61
61
  * directory may be a link pointing elsewhere. This runs across a whole fleet
62
62
  * of repos, so a relative link only has to reach a sibling checkout.
63
+ *
64
+ * A link that stays INSIDE the repo is not an escape: a repo that keeps its
65
+ * rules or its config behind an in-repo symlink is an ordinary setup, and
66
+ * refusing it would strand that repo forever. So the leaf is followed by hand
67
+ * with readlink — which works on a dangling link, where realpath cannot — and
68
+ * each hop re-resolves the parents, because the file a link points at can sit
69
+ * behind a linked directory of its own.
63
70
  */
64
71
  function escapesRepo(repo, target) {
65
72
  let root;
66
73
  try { root = fs.realpathSync(repo); } catch (e) { return true; }
67
74
 
68
- // Walk up to the deepest ancestor that exists; anything below it cannot be
69
- // a link yet, so only the existing part needs resolving.
70
- const tail = [];
71
- let dir = path.dirname(target);
72
- while (!lexists(dir)) {
73
- tail.unshift(path.basename(dir));
74
- const up = path.dirname(dir);
75
- if (up === dir) return true; // walked off the filesystem root
76
- dir = up;
77
- }
78
-
79
- let resolved;
80
- try { resolved = path.join(fs.realpathSync(dir), ...tail, path.basename(target)); }
81
- catch (e) { return true; } // an ancestor is a dangling link
82
-
83
- // The last component can be a link even when every directory above it is
84
- // clean — that is the dangling-file case.
85
- try { if (fs.lstatSync(resolved).isSymbolicLink()) return true; } catch (e) { /* absent: fine */ }
75
+ let p = path.resolve(target);
76
+ for (let hop = 0; hop < 40; hop++) {
77
+ // Resolve the existing part of the path. Walk up to the deepest ancestor
78
+ // that exists; anything below it cannot be a link yet.
79
+ const tail = [];
80
+ let dir = path.dirname(p);
81
+ while (!lexists(dir)) {
82
+ tail.unshift(path.basename(dir));
83
+ const up = path.dirname(dir);
84
+ if (up === dir) return true; // walked off the filesystem root
85
+ dir = up;
86
+ }
87
+ try { p = path.join(fs.realpathSync(dir), ...tail, path.basename(p)); }
88
+ catch (e) { return true; } // an ancestor is a dangling link
86
89
 
87
- return resolved !== root && !resolved.startsWith(root + path.sep);
90
+ let to;
91
+ try { to = fs.readlinkSync(p); } catch (e) {
92
+ return p !== root && !p.startsWith(root + path.sep); // not a link: decide here
93
+ }
94
+ p = path.resolve(path.dirname(p), to);
95
+ }
96
+ return true; // a link cycle: refuse
88
97
  }
89
98
 
90
99
  /** Index range of the lines strictly between a marker pair, or null. */
@@ -50,31 +50,40 @@ function lexists(p) {
50
50
  * "the file is absent" and is still followed on write — or any parent
51
51
  * directory may be a link pointing elsewhere. This runs across a whole fleet
52
52
  * of repos, so a relative link only has to reach a sibling checkout.
53
+ *
54
+ * A link that stays INSIDE the repo is not an escape: a repo that keeps its
55
+ * rules or its config behind an in-repo symlink is an ordinary setup, and
56
+ * refusing it would strand that repo forever. So the leaf is followed by hand
57
+ * with readlink — which works on a dangling link, where realpath cannot — and
58
+ * each hop re-resolves the parents, because the file a link points at can sit
59
+ * behind a linked directory of its own.
53
60
  */
54
61
  function escapesRepo(repo, target) {
55
62
  let root;
56
63
  try { root = fs.realpathSync(repo); } catch (e) { return true; }
57
64
 
58
- // Walk up to the deepest ancestor that exists; anything below it cannot be
59
- // a link yet, so only the existing part needs resolving.
60
- const tail = [];
61
- let dir = path.dirname(target);
62
- while (!lexists(dir)) {
63
- tail.unshift(path.basename(dir));
64
- const up = path.dirname(dir);
65
- if (up === dir) return true; // walked off the filesystem root
66
- dir = up;
67
- }
68
-
69
- let resolved;
70
- try { resolved = path.join(fs.realpathSync(dir), ...tail, path.basename(target)); }
71
- catch (e) { return true; } // an ancestor is a dangling link
72
-
73
- // The last component can be a link even when every directory above it is
74
- // clean — that is the dangling-file case.
75
- try { if (fs.lstatSync(resolved).isSymbolicLink()) return true; } catch (e) { /* absent: fine */ }
65
+ let p = path.resolve(target);
66
+ for (let hop = 0; hop < 40; hop++) {
67
+ // Resolve the existing part of the path. Walk up to the deepest ancestor
68
+ // that exists; anything below it cannot be a link yet.
69
+ const tail = [];
70
+ let dir = path.dirname(p);
71
+ while (!lexists(dir)) {
72
+ tail.unshift(path.basename(dir));
73
+ const up = path.dirname(dir);
74
+ if (up === dir) return true; // walked off the filesystem root
75
+ dir = up;
76
+ }
77
+ try { p = path.join(fs.realpathSync(dir), ...tail, path.basename(p)); }
78
+ catch (e) { return true; } // an ancestor is a dangling link
76
79
 
77
- return resolved !== root && !resolved.startsWith(root + path.sep);
80
+ let to;
81
+ try { to = fs.readlinkSync(p); } catch (e) {
82
+ return p !== root && !p.startsWith(root + path.sep); // not a link: decide here
83
+ }
84
+ p = path.resolve(path.dirname(p), to);
85
+ }
86
+ return true; // a link cycle: refuse
78
87
  }
79
88
 
80
89
  function templatePath() {
@@ -35,7 +35,7 @@ const path = require('path');
35
35
 
36
36
  const PKG = 'liteagents';
37
37
  // Per-kit config dir. This is the ONE line that differs across packages.
38
- const CONFIG_DIR = '.config/amp';
38
+ const CONFIG_DIR = '.claude';
39
39
  const TTL_MS = 24 * 60 * 60 * 1000;
40
40
  const DEADLINE_MS = 2000;
41
41
  const NPM_LOOKUP_MS = 3000;
@@ -62,7 +62,7 @@ function isNewer(a, b) {
62
62
  // --- installed version ---------------------------------------------------
63
63
 
64
64
  // Walk up from this file looking for our own package.json. Finds it when
65
- // running from a checkout; finds nothing when installed into ~/.config/amp, which
65
+ // running from a checkout; finds nothing when installed into ~/.claude, which
66
66
  // is why the npm fallback exists.
67
67
  function versionFromPackageJson() {
68
68
  let dir = __dirname;
@@ -79,7 +79,7 @@ function versionFromPackageJson() {
79
79
  }
80
80
 
81
81
  // The installer stamps the release it wrote into <install root>/manifest.json.
82
- // version-check.cjs sits at <root>/<commands|command>/remember/, so the root is
82
+ // version-check.cjs sits at <root>/<skills|commands|command>/remember/, so the root
83
83
  // two levels up. This is the fast path: reading a file beats spawning npm.
84
84
  function versionFromManifest() {
85
85
  try {
@@ -0,0 +1,220 @@
1
+ ---
2
+ name: root-cause
3
+ description: Use when any test fails, bug appears, or behaviour surprises you, before proposing a fix - find the cause and prove it, by reading real evidence, tracing bad values back to their origin, comparing against a working case, and testing one hypothesis at a time
4
+ allowed-tools: Read, Grep, Glob
5
+ ---
6
+
7
+ # Root Cause
8
+
9
+ **Find the cause before you change any code.**
10
+
11
+ ## The Law
12
+
13
+ ```
14
+ NO FIX WITHOUT A CAUSE YOU CAN POINT AT
15
+ ```
16
+
17
+ A fix at the place the error *appeared* is a symptom fix. It is a failure even when
18
+ the symptom goes away, because the real cause is still there and will surface
19
+ somewhere else, later, with less context.
20
+
21
+ You cannot propose a fix until Phase 1 is done.
22
+
23
+ ## When to Use
24
+
25
+ Any technical issue: a failing test, a production bug, unexpected behaviour, a
26
+ performance problem, a broken build, an integration that will not talk.
27
+
28
+ **Especially when it feels like overkill:**
29
+ - Under time pressure — emergencies are exactly when guessing is most tempting and most expensive
30
+ - "Just one quick fix" looks obvious
31
+ - You have already tried a fix and it did not work
32
+ - You do not fully understand the issue
33
+
34
+ Simple bugs have root causes too, and finding one takes minutes. Guess-and-check
35
+ takes hours and leaves damage behind.
36
+
37
+ ---
38
+
39
+ ## Phase 1 — Gather Evidence
40
+
41
+ Do all of this **before** forming any opinion about the fix.
42
+
43
+ ### 1. Read the error completely
44
+
45
+ Do not skim past it. Read the whole message, the whole stack trace, every warning
46
+ above it. Note line numbers, file paths, error codes. The answer is often written
47
+ there in full.
48
+
49
+ ### 2. Reproduce it consistently
50
+
51
+ Can you trigger it on demand? What are the exact steps? Does it happen every time?
52
+
53
+ If it is not reproducible, gather more data. Do not start guessing — an
54
+ intermittent bug you cannot trigger is a bug you cannot prove you fixed.
55
+
56
+ ### 3. Check what changed
57
+
58
+ Recent commits, the working diff, new dependencies, config edits, environment
59
+ differences between the place it works and the place it does not.
60
+
61
+ Be careful here: the most recent change is the most *available* suspect, not the
62
+ most likely one. Recency is a lead to test, never a conclusion.
63
+
64
+ ### 4. Instrument the boundaries (multi-component systems)
65
+
66
+ When the path crosses components — CI → build → sign, API → service → database,
67
+ workflow → script → tool — do not reason about where it breaks. Measure it.
68
+
69
+ For each boundary, log what goes **in** and what comes **out**, and confirm
70
+ configuration and environment actually propagated across it.
71
+
72
+ ```bash
73
+ echo "=== layer 1: is the secret present in the workflow? ==="
74
+ echo "IDENTITY: ${IDENTITY:+SET}${IDENTITY:-UNSET}"
75
+
76
+ echo "=== layer 2: did it survive into the build script? ==="
77
+ env | grep IDENTITY || echo "IDENTITY not in environment"
78
+
79
+ echo "=== layer 3: what does the tool actually see? ==="
80
+ security find-identity -v
81
+ ```
82
+
83
+ Run it **once** to find which boundary fails, then investigate only that
84
+ component. This turns "somewhere in the pipeline" into a named layer.
85
+
86
+ ### 5. Trace the bad value back to where it was born
87
+
88
+ When the error surfaces deep in the call stack, the place it exploded is almost
89
+ never the place it went wrong. Walk backwards.
90
+
91
+ **The chain:**
92
+
93
+ 1. **Observe the symptom** — `git init` ran in the source directory
94
+ 2. **Find the immediate cause** — the code that directly did it:
95
+ `execFileAsync('git', ['init'], { cwd: projectDir })`
96
+ 3. **Ask what called this, and with what value** — `projectDir` was `''`, and an
97
+ empty `cwd` silently resolves to the process's own directory
98
+ 4. **Keep going up** — who passed the empty string? and who gave it to *them*?
99
+ 5. **Stop at the origin** — the point where a correct value first became wrong
100
+
101
+ Fix it **there**. Then, if the value is dangerous, validate it at each layer on
102
+ the way down as well, so the same mistake cannot recur through a different path.
103
+
104
+ **When you cannot trace it by reading, instrument it:**
105
+
106
+ ```typescript
107
+ async function gitInit(directory: string) {
108
+ console.error('DEBUG git init:', {
109
+ directory,
110
+ cwd: process.cwd(),
111
+ stack: new Error().stack,
112
+ });
113
+ await execFileAsync('git', ['init'], { cwd: directory });
114
+ }
115
+ ```
116
+
117
+ - Capture the **stack**, not just the value — it names the caller you are looking for
118
+ - Log **before** the dangerous operation, not in its failure handler
119
+ - Include surrounding context: the directory, the working directory, relevant environment
120
+ - In tests, write to standard error directly; a project logger may be suppressed
121
+
122
+ **When something pollutes a test run but you cannot tell which test:** bisect.
123
+ Run the tests one at a time and stop at the first one that leaves the mess behind.
124
+ `find-polluter.sh` in this skill's directory does exactly that.
125
+
126
+ ---
127
+
128
+ ## Phase 2 — Compare Against Something That Works
129
+
130
+ You are looking for a difference, and the fastest way to see one is a side-by-side.
131
+
132
+ - **Find a working example** — similar code in the same codebase that behaves correctly
133
+ - **Read the reference completely** if you are following a pattern. Every line. Skimming a
134
+ reference and adapting "the idea" is how half-understood patterns ship
135
+ - **List every difference**, however small. Do not filter by "that can't matter" — that
136
+ judgement is exactly what you do not have yet
137
+ - **Check the dependencies**: what config, what environment, what other components does
138
+ the working one have that the broken one does not?
139
+
140
+ ---
141
+
142
+ ## Phase 3 — One Hypothesis, One Variable
143
+
144
+ - **State it in writing:** "I think X is the cause, because Y." Specific, not vague.
145
+ - **Test it with the smallest possible change.** One variable. A controlled test that
146
+ isolates your suspect beats a plausible story about the most recent commit.
147
+ - **Read the result honestly.** Confirmed → Phase 4. Not confirmed → form a *new*
148
+ hypothesis. Never stack a second fix on top of an unconfirmed first one.
149
+ - **Say when you do not know.** "I don't understand why X happens" is a real state and a
150
+ useful thing to report. Pretending to know produces confident wrong fixes.
151
+
152
+ ---
153
+
154
+ ## Phase 4 — Fix at the Source
155
+
156
+ ### 1. Write the failing test first
157
+
158
+ The simplest reproduction you can manage — an automated test if there is a suite, a
159
+ throwaway script if there is not.
160
+
161
+ **Run it against the unfixed code and watch it fail, for the reason you expect.** A
162
+ test written after the fix, or one that passes both before and after, proves nothing.
163
+ This is the step that converts your hypothesis into evidence.
164
+
165
+ ### 2. Make one change
166
+
167
+ Fix the cause you identified. One change. No "while I'm here" improvements, no bundled
168
+ refactoring — those make it impossible to tell what actually worked.
169
+
170
+ ### 3. Verify
171
+
172
+ Does the new test pass? Does the rest of the suite still pass? Is the original symptom
173
+ actually gone — checked, not assumed?
174
+
175
+ ### 4. If the fix did not work, stop and count
176
+
177
+ Under three attempts: return to Phase 1 with what you just learned. The failed attempt
178
+ is evidence.
179
+
180
+ **Three or more failed fixes means you have the wrong model of the problem.** Do not
181
+ attempt a fourth. The pattern to watch for: each fix uncovers a new problem somewhere
182
+ else, or each one needs "just a bit of refactoring" to land.
183
+
184
+ That is an architecture question, not a hypothesis question. Stop and raise it.
185
+
186
+ ---
187
+
188
+ ## Red Flags — Stop and Return to Phase 1
189
+
190
+ - "Quick fix now, investigate later"
191
+ - "Just try changing X and see"
192
+ - Several changes at once, then run the tests
193
+ - "Skip the test, I'll check it by hand"
194
+ - "It's probably X" — probably is not a cause
195
+ - "I don't fully understand this, but this might work"
196
+ - Listing fixes before tracing where the bad value came from
197
+ - "One more attempt" when two have already failed
198
+ - Each fix revealing a new problem somewhere else
199
+
200
+ ## Quick Reference
201
+
202
+ | Phase | You do | Done when |
203
+ |---|---|---|
204
+ | **1. Evidence** | Read the error, reproduce, check changes, instrument boundaries, trace the value back | You can say what happened and where it started |
205
+ | **2. Compare** | Find a working case, read it fully, list every difference | You know what is different |
206
+ | **3. Hypothesis** | State one cause, test one variable | Confirmed, or you have a new hypothesis |
207
+ | **4. Fix** | Failing test first, one change, verify | The test that failed now passes, and nothing else broke |
208
+
209
+ ## When There Really Is No Root Cause
210
+
211
+ It happens — a genuine race, an upstream bug, a hardware fault. But roughly nineteen
212
+ times in twenty, "no root cause" means the investigation stopped early.
213
+
214
+ Before you conclude it: can you reproduce it? Did you instrument every boundary? Did
215
+ you trace the value to its origin, or only to the last function you recognised?
216
+
217
+ ## Related
218
+
219
+ - **AGENT_RULES.md → Testing Standards** — what makes the Phase 4 test a real one
220
+ - **`/test-generate`** — build out the suite once the cause is fixed
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: security
3
3
  description: Security audit — recurring six, injection, auth, trust boundaries
4
- usage: /security
5
4
  argument-hint: [file, directory, or leave empty for full scan]
6
- allowed-tools: Read, Grep, Glob, Bash(git log *), Bash(git grep *), Bash(rg *)
5
+ allowed-tools: Read, Grep, Glob, Bash(git log:*), Bash(git grep:*), Bash(rg:*)
6
+ disable-model-invocation: true
7
7
  ---
8
8
  Audit $ARGUMENTS for security vulnerabilities. **Reports, never edits** — it
9
9
  verifies every claim, then hands the findings to whoever asked.
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  name: ship
3
3
  description: Mechanical pre-deploy gate — tests, build, tree state
4
- usage: /ship
5
- allowed-tools: Read, Grep, Glob, Bash(git *), Bash(npm *), Bash(pnpm *), Bash(yarn *), Bash(pytest *), Bash(python *), Bash(go *), Bash(cargo *), Bash(make *)
4
+ allowed-tools: Read, Grep, Glob, Bash(git:*), Bash(npm:*), Bash(pnpm:*), Bash(yarn:*), Bash(pytest:*), Bash(python:*), Bash(go:*), Bash(cargo:*), Bash(make:*)
5
+ disable-model-invocation: true
6
6
  ---
7
7
  Mechanical pre-deploy / pre-merge gate. Every item here is answerable by
8
8
  **running a command** and reading its exit code — no code judgment. Code
@@ -1,9 +1,8 @@
1
1
  ---
2
2
  name: skill-creator
3
3
  description: Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.
4
- usage: /skill-creator <skill-type> <skill-description>
5
- auto_trigger: false
6
4
  license: Complete terms in LICENSE.txt
5
+ allowed-tools: Read, Grep, Glob
7
6
  ---
8
7
 
9
8
  # Skill Creator
@@ -1,8 +1,9 @@
1
1
  ---
2
2
  name: stash
3
3
  description: Stash session context [name]
4
- usage: /stash ["optional-name"]
5
4
  argument-hint: [optional stash name]
5
+ allowed-tools: Read, Grep, Glob
6
+ disable-model-invocation: true
6
7
  ---
7
8
 
8
9
  Save session context for compaction recovery or handoffs.
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: test-generate
3
3
  description: Generate and run tests [file]
4
- usage: /test-generate <file>
5
4
  argument-hint: [file or symbol to test]
6
- allowed-tools: Read, Edit, Write, Grep, Glob, Bash(npm test *), Bash(npx jest *), Bash(npx vitest *), Bash(pnpm test *), Bash(yarn test *), Bash(pytest *), Bash(python *), Bash(go test *), Bash(cargo test *), Bash(make test *)
5
+ allowed-tools: Read, Edit, Write, Grep, Glob, Bash(npm test:*), Bash(npx jest:*), Bash(npx vitest:*), Bash(pnpm test:*), Bash(yarn test:*), Bash(pytest:*), Bash(python:*), Bash(go test:*), Bash(cargo test:*), Bash(make test:*)
6
+ disable-model-invocation: true
7
7
  ---
8
8
  Generate tests for $ARGUMENTS, then run them. This is a generate → run →
9
9
  verify loop, not just file generation.
@@ -28,7 +28,7 @@ Match existing patterns:
28
28
  or new test-runner config.
29
29
  - Do **not** add test-only public methods or exports to production code to
30
30
  make a test possible — if the test wants a hook the prod code doesn't
31
- expose, stop and ask (`test-traps` territory).
31
+ expose, stop and ask.
32
32
 
33
33
  ## 3. Run
34
34
  Execute the project's real test command, scoped to just the new tests
@@ -1,10 +1,9 @@
1
1
  {
2
2
  "pro": {
3
3
  "name": "Pro",
4
- "description": "Complete installation with all agents, skills, and commands",
4
+ "description": "Complete installation with all agents and skills",
5
5
  "agents": "*",
6
6
  "skills": "*",
7
- "commands": "*",
8
7
  "plugins": "*"
9
8
  }
10
9
  }
@@ -21,28 +21,23 @@ These subagents are available when using Claude Code CLI. Droid can reference th
21
21
  | system-architect | Architect | Use for system design, architecture documents, technology selection, API design, and infrastructure planning |
22
22
  | ui-designer | UX Expert | Use for UI/UX design, wireframes, prototypes, front-end specifications, and user experience optimization |
23
23
 
24
- ## Droid Commands (18 total)
25
-
26
- | ID | Description | Usage | Auto |
27
- |---|---|---|---|
28
- | brainstorming | Refines rough ideas into fully-formed designs through collaborative questioning | /brainstorming <session-type> <topic> | false |
29
- | docs-builder | Reorg a docs corpus, split an oversized doc, search it, keep pages current, index them | /docs-builder [reorg \| cleanup <file.md>] | false |
30
- | live-canvas | Design UI variations and collect click-to-annotate feedback from the browser (batch mode only on Droid) | /live-canvas | false |
31
- | optimize | Analyze and optimize performance issues | /optimize <target-area> | - |
32
- | refactor | Refactor code while maintaining behavior and tests | /refactor <code-section> | - |
24
+ ## Droid Commands (13 total)
25
+
26
+ | ID | Description | Usage |
27
+ |---|---|---|
28
+ | brainstorming | Refines rough ideas into fully-formed designs through collaborative questioning | /brainstorming <session-type> <topic> |
29
+ | docs-builder | Reorg a docs corpus, split an oversized doc, search it, keep pages current, index them | /docs-builder [reorg \| cleanup <file.md>] |
30
+ | live-canvas | Design UI variations and collect click-to-annotate feedback from the browser (batch mode only on Droid) | /live-canvas |
31
+ | refactor | Refactor and optimize code while maintaining behavior and tests | /refactor <code-section> | - |
33
32
  | remember | Consolidate stashes + friction into project memory | /remember | - |
34
33
  | branch-review | Pre-merge review: general review + full security audit, verify pass, no fixes | /branch-review [target] [level] | - |
35
- | trace-back | Systematically traces bugs backward through call stack to identify source | /trace-back <issue-description> | false |
34
+ | root-cause | Find the cause before changing code - evidence, backward trace, one hypothesis, fix at the source | /root-cause <bug-or-error-description> |
36
35
  | security | Security audit — recurring six, injection, auth, trust boundaries; reports, never fixes | /security [target] | - |
37
36
  | ship | Mechanical pre-deploy gate — tests, build, tree state | /ship | - |
38
37
  | release | Verify, sweep docs, cut a version — then hand back the merge/tag/publish sequence | /release | - |
39
- | skill-creator | Guide for creating effective skills and extending Claude capabilities | /skill-creator <skill-type> <skill-description> | false |
38
+ | skill-creator | Guide for creating effective skills and extending Claude capabilities | /skill-creator <skill-type> <skill-description> |
40
39
  | stash | Save session context for compaction recovery or handoffs | /stash ["optional-name"] | - |
41
- | debug-method | Four-phase debugging framework - investigate root cause before any fixes | /debug-method <bug-or-error-description> | false |
42
- | tdd-flow | Write test first, watch it fail, write minimal code to pass | /tdd-flow <feature-or-behavior-to-test> | true |
43
40
  | test-generate | Generate tests, run them, verify each one actually exercises the code | /test-generate <file> | - |
44
- | test-traps | Prevents testing mock behavior and production pollution with test-only methods | /test-traps <testing-scenario> | true |
45
- | verify-done | Requires running verification commands before making any success claims | /verify-done <work-to-verify> | true |
46
41
 
47
42
  All resources are auto-discovered from frontmatter in their respective directories:
48
43
  - **Agents**: `./droids/*.md`
@@ -1,8 +1,5 @@
1
1
  ---
2
- name: brainstorming
3
2
  description: Use when creating or developing, before writing code or implementation plans - refines rough ideas into fully-formed designs through collaborative questioning, alternative exploration, and incremental validation. Don't use during clear 'mechanical' processes
4
- usage: /brainstorming <session-type> <topic>
5
- auto_trigger: false
6
3
  ---
7
4
 
8
5
  # Brainstorming Ideas Into Designs
@@ -43,7 +40,7 @@ Start by understanding the current project context, then ask questions one at a
43
40
 
44
41
  **Implementation (if continuing):**
45
42
  - Ask: "Ready to set up for implementation?"
46
- - Create isolated workspace (use git worktrees if needed)
43
+ - Create isolated workspace for implementation
47
44
  - Create detailed implementation plan
48
45
 
49
46
  ## Key Principles
@@ -1,9 +1,6 @@
1
1
  ---
2
- name: branch-review
3
2
  description: Review a branch before merge [target] [level]
4
- usage: /branch-review [target] [low|medium|high|max]
5
3
  argument-hint: [file, branch (e.g. main), range (main..HEAD), or empty] [effort level]
6
- allowed-tools: Read, Grep, Glob, Agent, Bash(git diff *), Bash(git log *), Bash(git show *), Bash(git status *), Bash(git grep *), Bash(git rev-parse *), Bash(git merge-base *), Bash(rg *)
7
4
  ---
8
5
  Pre-merge review gate. Two stages — **general review** then a **full security
9
6
  audit** — followed by an adversarial verify pass. It **never edits code**: it
@@ -11,7 +8,7 @@ reports findings and hands them back. Fixing is a separate, separately
11
8
  authorized action.
12
9
 
13
10
  Only **Critical** and **High** findings block the merge. Everything else is
14
- appended to the **fix ledger** (`.claude/remember/fix-ledger.md`) — a local,
11
+ appended to the **fix ledger** (`.factory/remember/fix-ledger.md`) — a local,
15
12
  cumulative list, living beside `MEMORY.md`, that `/refactor` (no arguments)
16
13
  works through between features. Like its neighbours it is a private working
17
14
  artifact, usually gitignored; it persists across reviews, it is not a
@@ -44,17 +41,17 @@ at the current HEAD SHA.
44
41
  review of a report. (Same rule `/security` carries inside stage 2.)
45
42
  - **No edits — two exceptions.** You have no authorization to change code,
46
43
  even for a finding you are certain about. Report it. The only files you may
47
- write are `.claude/remember/fix-ledger.md` (append bullets; never rewrite or
48
- delete) and `.claude/remember/last-review.md` (overwrite; the review record
44
+ write are `.factory/remember/fix-ledger.md` (append bullets; never rewrite or
45
+ delete) and `.factory/remember/last-review.md` (overwrite; the review record
49
46
  described at the end of this file).
50
47
  - **Prove it with two checks, because neither sees what the other does.**
51
48
  `git status --porcelain`, at start and again before you report, proves no
52
49
  **tracked** file changed — that is the "never edits code" guarantee, and it
53
- is the one that matters. It cannot police your own two writes: `.claude/`
50
+ is the one that matters. It cannot police your own two writes: `.factory/`
54
51
  is normally gitignored, so porcelain stays empty whether you wrote the
55
52
  allowed files, wrote nothing, or overwrote `MEMORY.md`. `git status
56
- --ignored` does not close it either — it collapses to `!! .claude/`, the
57
- directory, not the files. So also take `md5sum .claude/remember/*` before
53
+ --ignored` does not close it either — it collapses to `!! .factory/`, the
54
+ directory, not the files. So also take `md5sum .factory/remember/*` before
58
55
  you start and again before you report, and show the comparison: only
59
56
  `fix-ledger.md` and `last-review.md` may differ.
60
57
 
@@ -95,7 +92,7 @@ Record the **HEAD SHA** you reviewed, and **report the target you resolved**
95
92
  (the literal range or path) in your output, so the orchestrator can see what
96
93
  was actually read rather than assuming.
97
94
 
98
- **Re-review after fixes: read `.claude/remember/last-review.md` first.** Its
95
+ **Re-review after fixes: read `.factory/remember/last-review.md` first.** Its
99
96
  `sha:` line is the previously-reviewed commit and its `blockers:` list is what
100
97
  you owe an answer on — take both from the file, never from the orchestrator's
101
98
  recollection, for the same reason `/release` does. Then:
@@ -231,7 +228,7 @@ check before escalating.
231
228
 
232
229
  ### Ledger (non-blocking — medium / low)
233
230
  Not in the report. **Append** each one as a single bullet to
234
- `.claude/remember/fix-ledger.md` (create the file with the header below if
231
+ `.factory/remember/fix-ledger.md` (create the file with the header below if
235
232
  missing):
236
233
 
237
234
  ```
@@ -256,7 +253,7 @@ with `UNVERIFIED:` so `/refactor` retests before acting.
256
253
  The **snippet is the anchor**: 20–60 verbatim characters from the line,
257
254
  unique enough for `git grep -F` to find it after lines shift. No line
258
255
  numbers, no TODO comments in code — the ledger is the single writer. Before
259
- appending, dedupe with **plain `grep -F "<snippet>" .claude/remember/fix-ledger.md`**;
256
+ appending, dedupe with **plain `grep -F "<snippet>" .factory/remember/fix-ledger.md`**;
260
257
  if it is already there, skip it. Do not touch existing bullets.
261
258
 
262
259
  **A bullet you disprove is deleted, not annotated.** If you establish that an
@@ -280,7 +277,7 @@ Then a coverage line: stage 1 at level `<level>`, stage 2 full, stage 3 —
280
277
  each `ran ✓/✗` with its evidence. A stage you did not actually run is a **✗**, never an
281
278
  assumed pass.
282
279
 
283
- **Write the review record** to `.claude/remember/last-review.md`, overwriting
280
+ **Write the review record** to `.factory/remember/last-review.md`, overwriting
284
281
  it. `/release` reads this file; a SHA that lives only in a chat message is
285
282
  gone after a compaction or a handover, and the only remaining source is the
286
283
  orchestrator — the one party this command already refuses to take a review's
@@ -326,7 +323,7 @@ does not move — which means nothing was fixed, which is the correct outcome.
326
323
 
327
324
  End with:
328
325
  - **Reviewed at HEAD `<sha>` on `<branch>`, target `<resolved range or path>`,
329
- tree clean at start; at exit clean or the two `.claude/remember/` paths
326
+ tree clean at start; at exit clean or the two `.factory/remember/` paths
330
327
  only.**
331
328
  - **Fix ledger: N open, M added this run** (N = bullet count). When N > 0,
332
329
  add: "N fixes waiting — run `/refactor` between features." The ledger is a
@@ -1,9 +1,6 @@
1
1
  ---
2
- name: docs-builder
3
2
  description: Reorg a docs corpus, split an oversized doc, search it, keep pages current, index them
4
- usage: /docs-builder [reorg | cleanup <file.md> | search <query words...>]
5
3
  argument-hint: [reorg | cleanup <file.md> | search <query words...> — empty asks first run vs. drift]
6
- allowed-tools: Read, Write, Edit, Grep, Glob, Task, AskUserQuestion, Bash(node:*), Bash(git:*), Bash(rg:*)
7
4
  ---
8
5
 
9
6
  # docs-builder