@bonesofspring/ai-rules 0.1.40 → 0.1.41

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 (119) hide show
  1. package/README.md +2 -2
  2. package/bin/cli.js +22 -1
  3. package/package.json +2 -1
  4. package/presets/claude/next/CLAUDE.md +11 -7
  5. package/presets/claude/next/README.md +2 -2
  6. package/presets/claude/next/agents/README.md +50 -1
  7. package/presets/claude/next/agents/accessibility-reviewer.md +65 -0
  8. package/presets/claude/next/agents/api-contract-reviewer.md +69 -0
  9. package/presets/claude/next/agents/build-verifier.md +62 -0
  10. package/presets/claude/next/agents/ci-investigator.md +62 -0
  11. package/presets/claude/next/agents/code-reviewer.md +7 -1
  12. package/presets/claude/next/agents/debugger.md +7 -2
  13. package/presets/claude/next/agents/feature-developer.md +11 -16
  14. package/presets/claude/next/agents/migration-specialist.md +69 -0
  15. package/presets/claude/next/agents/performance-auditor.md +68 -0
  16. package/presets/claude/next/agents/qa-tester.md +4 -2
  17. package/presets/claude/next/agents/security-reviewer.md +64 -0
  18. package/presets/claude/next/agents/task-analyst.md +6 -2
  19. package/presets/claude/next/agents/task-router.md +83 -16
  20. package/presets/claude/next/agents/tech-writer.md +60 -0
  21. package/presets/claude/next/agents/unit-test-generator.md +37 -0
  22. package/presets/claude/next/agents/unit-test-healer.md +38 -0
  23. package/presets/claude/next/agents/unit-test-planner.md +62 -0
  24. package/presets/claude/next/commands/README.md +1 -1
  25. package/presets/claude/next/commands/feature-continue.md +5 -0
  26. package/presets/claude/next/commands/feature-start.md +5 -0
  27. package/presets/claude/next/commands/task-continue.md +8 -2
  28. package/presets/claude/next/commands/task.md +10 -0
  29. package/presets/claude/next/commands/technical-retro.md +6 -1
  30. package/presets/claude/next/hooks/README.md +5 -8
  31. package/presets/claude/next/hooks/chain-team-phases.sh +258 -39
  32. package/presets/claude/next/hooks/guard-shell-command.sh +77 -0
  33. package/presets/claude/next/rules/README.md +20 -44
  34. package/presets/claude/next/rules/architecture/api-public-imports.md +6 -0
  35. package/presets/claude/next/rules/architecture/architecture-boundaries.md +5 -0
  36. package/presets/claude/next/rules/architecture/feature-delivery-workflow.md +5 -0
  37. package/presets/claude/next/rules/architecture/layer-barrel-exports.md +5 -0
  38. package/presets/claude/next/rules/architecture/reference-features.md +34 -0
  39. package/presets/claude/next/rules/architecture/types-public-imports.md +6 -0
  40. package/presets/claude/next/rules/stack/arrow-functions.md +5 -0
  41. package/presets/claude/next/rules/stack/navigation-router.md +5 -0
  42. package/presets/claude/next/rules/stack/next-app-router.md +36 -0
  43. package/presets/claude/next/rules/stack/no-type-assertion.md +6 -0
  44. package/presets/claude/next/rules/testing/playwright-agents.md +5 -0
  45. package/presets/claude/next/rules/tooling-and-review/agent-team-orchestrator.md +32 -8
  46. package/presets/claude/next/rules/ui-and-accessibility/component-styles.md +6 -0
  47. package/presets/claude/next/rules/ui-and-accessibility/css-property-order.md +6 -0
  48. package/presets/claude/next/rules/ui-and-accessibility/no-props-spread.md +5 -0
  49. package/presets/claude/next/rules/ui-and-accessibility/react-a11y-coding.md +37 -0
  50. package/presets/claude/next/skills/README.md +11 -1
  51. package/presets/claude/next/skills/ci-investigation/SKILL.md +36 -0
  52. package/presets/claude/next/skills/code-review/SKILL.md +26 -0
  53. package/presets/claude/next/skills/debug-investigation/SKILL.md +28 -0
  54. package/presets/claude/next/skills/feature-delivery/SKILL.md +30 -0
  55. package/presets/claude/next/skills/playwright-e2e/SKILL.md +31 -0
  56. package/presets/claude/next/skills/technical-retro/SKILL.md +40 -0
  57. package/presets/claude/next/skills/unit-testing/SKILL.md +32 -0
  58. package/presets/claude/next/team/README.md +25 -43
  59. package/presets/cursor/next/AGENTS.md +43 -0
  60. package/presets/cursor/next/BUGBOT.md +14 -0
  61. package/presets/cursor/next/agents/README.md +52 -0
  62. package/presets/cursor/next/agents/accessibility-reviewer.md +67 -0
  63. package/presets/cursor/next/agents/api-contract-reviewer.md +71 -0
  64. package/presets/cursor/next/agents/build-verifier.md +64 -0
  65. package/presets/cursor/next/agents/ci-investigator.md +64 -0
  66. package/presets/cursor/next/agents/code-reviewer.md +8 -1
  67. package/presets/cursor/next/agents/debugger.md +7 -2
  68. package/presets/cursor/next/agents/feature-developer.md +10 -8
  69. package/presets/cursor/next/agents/migration-specialist.md +71 -0
  70. package/presets/cursor/next/agents/performance-auditor.md +70 -0
  71. package/presets/cursor/next/agents/playwright-test-generator.md +26 -0
  72. package/presets/cursor/next/agents/playwright-test-healer.md +26 -0
  73. package/presets/cursor/next/agents/playwright-test-planner.md +28 -0
  74. package/presets/cursor/next/agents/qa-tester.md +4 -2
  75. package/presets/cursor/next/agents/security-reviewer.md +66 -0
  76. package/presets/cursor/next/agents/task-analyst.md +3 -2
  77. package/presets/cursor/next/agents/task-router.md +84 -17
  78. package/presets/cursor/next/agents/tech-writer.md +62 -0
  79. package/presets/cursor/next/agents/unit-test-generator.md +39 -0
  80. package/presets/cursor/next/agents/unit-test-healer.md +40 -0
  81. package/presets/cursor/next/agents/unit-test-planner.md +64 -0
  82. package/presets/cursor/next/commands/README.md +17 -1
  83. package/presets/cursor/next/commands/feature-continue.md +5 -0
  84. package/presets/cursor/next/commands/feature-start.md +5 -0
  85. package/presets/cursor/next/commands/task-continue.md +8 -2
  86. package/presets/cursor/next/commands/task.md +10 -0
  87. package/presets/cursor/next/commands/technical-retro.md +6 -1
  88. package/presets/cursor/next/hooks/README.md +8 -0
  89. package/presets/cursor/next/hooks/chain-team-phases.sh +192 -28
  90. package/presets/cursor/next/hooks/guard-shell-command.sh +77 -0
  91. package/presets/cursor/next/hooks.json +7 -1
  92. package/presets/cursor/next/rules/README.md +16 -6
  93. package/presets/cursor/next/rules/agent-team-orchestrator.mdc +32 -8
  94. package/presets/cursor/next/rules/api-public-imports.mdc +2 -1
  95. package/presets/cursor/next/rules/architecture-boundaries.mdc +2 -1
  96. package/presets/cursor/next/rules/arrow-functions.mdc +2 -1
  97. package/presets/cursor/next/rules/code-review-mr.mdc +1 -1
  98. package/presets/cursor/next/rules/css-property-order-stylelint.mdc +4 -1
  99. package/presets/cursor/next/rules/feature-delivery-flow.mdc +1 -1
  100. package/presets/cursor/next/rules/feature-delivery-workflow.mdc +2 -2
  101. package/presets/cursor/next/rules/layer-barrel-exports.mdc +2 -1
  102. package/presets/cursor/next/rules/navigation-router-stack.mdc +2 -1
  103. package/presets/cursor/next/rules/next-app-router.mdc +36 -0
  104. package/presets/cursor/next/rules/no-cross-component-styles-import.mdc +4 -1
  105. package/presets/cursor/next/rules/no-props-spread.mdc +1 -1
  106. package/presets/cursor/next/rules/no-type-assertion-as-import-export.mdc +2 -1
  107. package/presets/cursor/next/rules/playwright-agents.mdc +2 -1
  108. package/presets/cursor/next/rules/react-a11y-coding.mdc +37 -0
  109. package/presets/cursor/next/rules/reference-features.mdc +35 -0
  110. package/presets/cursor/next/rules/types-public-imports.mdc +2 -1
  111. package/presets/cursor/next/skills/README.md +15 -0
  112. package/presets/cursor/next/skills/ci-investigation/SKILL.md +36 -0
  113. package/presets/cursor/next/skills/code-review/SKILL.md +26 -0
  114. package/presets/cursor/next/skills/debug-investigation/SKILL.md +28 -0
  115. package/presets/cursor/next/skills/feature-delivery/SKILL.md +30 -0
  116. package/presets/cursor/next/skills/playwright-e2e/SKILL.md +31 -0
  117. package/presets/cursor/next/skills/technical-retro/SKILL.md +40 -0
  118. package/presets/cursor/next/skills/unit-testing/SKILL.md +32 -0
  119. package/presets/cursor/next/team/README.md +38 -40
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env bash
2
2
  # Chains agent team phases after subagent completion when wired into Claude Code hooks.
3
- # Reads stdin JSON from a subagent-stop style hook; writes followup_message to stdout.
4
3
 
5
4
  set -euo pipefail
6
5
 
@@ -10,6 +9,8 @@ INPUT="$input" node <<'NODE'
10
9
  const fs = require('fs');
11
10
  const path = require('path');
12
11
 
12
+ const TEAM_ROOT = path.join(process.cwd(), '.claude', 'team');
13
+
13
14
  const inputRaw = process.env.INPUT || '';
14
15
  let hookInput;
15
16
  try {
@@ -24,8 +25,7 @@ if (hookInput.status !== 'completed') {
24
25
  process.exit(0);
25
26
  }
26
27
 
27
- const teamRoot = path.join(process.cwd(), '.claude', 'team');
28
- const activePath = path.join(teamRoot, 'active-task.json');
28
+ const activePath = path.join(TEAM_ROOT, 'active-task.json');
29
29
 
30
30
  if (!fs.existsSync(activePath)) {
31
31
  process.stdout.write('{}');
@@ -46,7 +46,10 @@ if (!slug) {
46
46
  process.exit(0);
47
47
  }
48
48
 
49
- const statusPath = path.join(teamRoot, 'tasks', slug, 'status.json');
49
+ const taskDir = path.join(TEAM_ROOT, 'tasks', slug);
50
+ const statusPath = path.join(taskDir, 'status.json');
51
+ const pipelinePath = path.join(taskDir, 'pipeline.json');
52
+
50
53
  if (!fs.existsSync(statusPath)) {
51
54
  process.stdout.write('{}');
52
55
  process.exit(0);
@@ -63,61 +66,277 @@ try {
63
66
  const now = new Date().toISOString();
64
67
 
65
68
  function writeStatus(next) {
66
- fs.writeFileSync(statusPath, JSON.stringify({ ...status, ...next, slug, updatedAt: now }, null, 2) + '\n');
69
+ status = { ...status, ...next, slug, updatedAt: now };
70
+ fs.writeFileSync(statusPath, JSON.stringify(status, null, 2) + '\n');
67
71
  }
68
72
 
69
73
  function out(message) {
70
74
  process.stdout.write(JSON.stringify({ followup_message: message }));
71
75
  }
72
76
 
73
- // Human gate: do not auto-chain during analysis or explicit approval waits.
74
- if (status.phase === 'analysis' || status.state === 'awaiting_approval') {
77
+ function readArtifact(name) {
78
+ const p = path.join(taskDir, name);
79
+ if (!fs.existsSync(p)) return '';
80
+ try {
81
+ return fs.readFileSync(p, 'utf8');
82
+ } catch {
83
+ return '';
84
+ }
85
+ }
86
+
87
+ function getStepAgents(step) {
88
+ if (!step) return [];
89
+ return Array.isArray(step.agent) ? step.agent : [step.agent];
90
+ }
91
+
92
+ function skipIfMatches(skipIf) {
93
+ if (!skipIf) return false;
94
+ if (skipIf === 'debugger.fixed') {
95
+ const text = readArtifact('debug-report.md');
96
+ return /fixApplied:\s*true/i.test(text) || /\*\*Fix applied:\*\*\s*true/i.test(text);
97
+ }
98
+ if (skipIf === 'ci-investigator.resolved') {
99
+ const text = readArtifact('ci-report.md');
100
+ return /fixApplied:\s*true/i.test(text) || /## Verdict\s*\nPASS/i.test(text);
101
+ }
102
+ return false;
103
+ }
104
+
105
+ function findNextExecutableStep(steps, startIdx) {
106
+ for (let i = startIdx; i < steps.length; i++) {
107
+ if (!skipIfMatches(steps[i].skipIf)) {
108
+ return { step: steps[i], index: i };
109
+ }
110
+ }
111
+ return null;
112
+ }
113
+
114
+ const AGENT_HANDOFF = {
115
+ 'task-analyst': (s) =>
116
+ `Invoke task-analyst for slug "${s}". Write brief.md and decomposition.md under .claude/team/tasks/${s}/. ` +
117
+ `Set status.json: phase executing, state awaiting_approval if human gate applies.`,
118
+ debugger: (s) =>
119
+ `Invoke debugger subagent for slug "${s}". Write debug-report.md with fixApplied: true/false. Update status.json when done.`,
120
+ 'solution-architect': (s) =>
121
+ `Invoke solution-architect for slug "${s}". Read brief.md; write architecture.md. Update status.json when done.`,
122
+ 'migration-specialist': (s) =>
123
+ `Invoke migration-specialist for slug "${s}". Read brief.md; write migration-plan.md. Update status.json when done.`,
124
+ 'api-contract-reviewer': (s) =>
125
+ `Invoke api-contract-reviewer for slug "${s}". Write api-contract-review.md. Update status.json when done.`,
126
+ 'ci-investigator': (s) =>
127
+ `Invoke ci-investigator for slug "${s}". Use ci-investigation skill. Write ci-report.md. Update status.json when done.`,
128
+ 'feature-developer': (s) =>
129
+ `Invoke feature-developer for slug "${s}". Read brief.md, decomposition.md, validation-report.md, review.md if present. ` +
130
+ `Follow rules/architecture/feature-delivery-workflow.md and architecture/reference-features.md. Include unit tests before handoff. Update status.json when done.`,
131
+ 'build-verifier': (s) =>
132
+ `Invoke build-verifier for slug "${s}". Run lint:js, lint:css, type-check, targeted unit tests from app/. ` +
133
+ `Write validation-report.md. Set state completed or validation_failed. Do not edit production code.`,
134
+ 'accessibility-reviewer': (s) =>
135
+ `Invoke accessibility-reviewer for slug "${s}". Write a11y-review.md. Update status.json when done.`,
136
+ 'performance-auditor': (s) =>
137
+ `Invoke performance-auditor for slug "${s}". Write perf-report.md. Update status.json when done.`,
138
+ 'code-reviewer': (s) =>
139
+ `Invoke code-reviewer for slug "${s}". Review git diff per rules/tooling-and-review/code-review-mr.md. Update status.json when done.`,
140
+ 'security-reviewer': (s) =>
141
+ `Invoke security-reviewer for slug "${s}". Write security-review.md. Update status.json when done.`,
142
+ 'qa-tester': (s, scope) =>
143
+ `Invoke qa-tester for slug "${s}"${scope ? ` (scope: ${scope})` : ''}. Update status.json when done.`,
144
+ 'unit-test-planner': (s) =>
145
+ `Invoke unit-test-planner for slug "${s}". Use unit-testing skill. Update status.json when done.`,
146
+ 'unit-test-generator': (s) =>
147
+ `Invoke unit-test-generator for slug "${s}". Use unit-testing skill. Update status.json when done.`,
148
+ 'unit-test-healer': (s) =>
149
+ `Invoke unit-test-healer for slug "${s}". Use unit-testing and debug-investigation skills. Update status.json when done.`,
150
+ 'playwright-test-planner': (s) =>
151
+ `Invoke playwright-test-planner for slug "${s}". Follow rules/testing/playwright-agents.md and playwright-e2e skill. Update status.json when done.`,
152
+ 'playwright-test-generator': (s) =>
153
+ `Invoke playwright-test-generator for slug "${s}". Use Playwright MCP tools when available. Update status.json when done.`,
154
+ 'playwright-test-healer': (s) =>
155
+ `Invoke playwright-test-healer for slug "${s}". Use Playwright MCP when available. Update status.json when done.`,
156
+ 'tech-writer': (s) =>
157
+ `Invoke tech-writer for slug "${s}". Write documentation.md. Update status.json when done.`,
158
+ };
159
+
160
+ const REVIEW_AGENTS = new Set([
161
+ 'code-reviewer',
162
+ 'accessibility-reviewer',
163
+ 'security-reviewer',
164
+ 'api-contract-reviewer',
165
+ ]);
166
+
167
+ function handoffForAgent(agent, scope) {
168
+ const fn = AGENT_HANDOFF[agent];
169
+ return fn ? fn(slug, scope) : `Invoke ${agent} subagent for slug "${slug}". Update status.json when done.`;
170
+ }
171
+
172
+ function handoffForParallelStep(step) {
173
+ const agents = getStepAgents(step);
174
+ return (
175
+ `Invoke IN PARALLEL (one message, multiple Task calls): ${agents.join(' AND ')} for slug "${slug}". ` +
176
+ `Each agent appends itself to status.json parallelCompleted when done.`
177
+ );
178
+ }
179
+
180
+ function hasGateAfter(agent, humanGates) {
181
+ return Array.isArray(humanGates) && humanGates.includes(`after:${agent}`);
182
+ }
183
+
184
+ function hasGateAfterStep(step, humanGates) {
185
+ return getStepAgents(step).some((a) => hasGateAfter(a, humanGates));
186
+ }
187
+
188
+ function legacyFlow() {
189
+ if (status.phase === 'development' && status.state === 'completed') {
190
+ writeStatus({ phase: 'executing', state: 'in_progress', currentAgent: 'build-verifier' });
191
+ out(handoffForAgent('build-verifier'));
192
+ process.exit(0);
193
+ }
194
+ if (status.currentAgent === 'build-verifier' && status.state === 'completed') {
195
+ writeStatus({ phase: 'executing', state: 'in_progress', currentAgent: 'code-reviewer' });
196
+ out(handoffForAgent('code-reviewer'));
197
+ process.exit(0);
198
+ }
199
+ if (status.phase === 'review' && status.state === 'completed') {
200
+ writeStatus({ phase: 'executing', state: 'in_progress', currentAgent: 'qa-tester' });
201
+ out(handoffForAgent('qa-tester'));
202
+ process.exit(0);
203
+ }
204
+ if (status.state === 'changes_requested' && REVIEW_AGENTS.has(status.currentAgent)) {
205
+ writeStatus({
206
+ currentAgent: 'feature-developer',
207
+ state: 'in_progress',
208
+ phase: 'executing',
209
+ retryAfterFix: status.currentAgent,
210
+ });
211
+ out(handoffForAgent('feature-developer') + ` After fixes, re-run ${status.currentAgent}.`);
212
+ process.exit(0);
213
+ }
214
+ if (status.state === 'validation_failed') {
215
+ writeStatus({
216
+ currentAgent: 'feature-developer',
217
+ state: 'in_progress',
218
+ retryAfterFix: 'build-verifier',
219
+ });
220
+ out(handoffForAgent('feature-developer') + ` Read validation-report.md. Re-run build-verifier after fixes.`);
221
+ process.exit(0);
222
+ }
223
+ if (status.state === 'completed' && status.retryAfterFix) {
224
+ const retry = status.retryAfterFix;
225
+ writeStatus({ currentAgent: retry, state: 'in_progress', retryAfterFix: null });
226
+ out(handoffForAgent(retry));
227
+ process.exit(0);
228
+ }
229
+ if (status.phase === 'testing' && status.state === 'completed') {
230
+ writeStatus({ phase: 'done', state: 'completed' });
231
+ out(`Pipeline complete for "${slug}". Run /technical-retro ${slug}.`);
232
+ process.exit(0);
233
+ }
75
234
  process.stdout.write('{}');
76
235
  process.exit(0);
77
236
  }
78
237
 
79
- // Legacy mode without pipeline.json.
80
- if (status.phase === 'development' && status.state === 'completed') {
81
- writeStatus({ phase: 'review', state: 'in_progress' });
82
- out(
83
- `Subagent development phase finished for slug "${slug}". ` +
84
- `Invoke the code-reviewer subagent. ` +
85
- `Read .claude/team/tasks/${slug}/brief.md and decomposition.md. ` +
86
- `Review git diff against acceptance criteria per rules/tooling-and-review/code-review-mr.md. ` +
87
- `Update status.json when done.`,
88
- );
238
+ if (!fs.existsSync(pipelinePath)) {
239
+ legacyFlow();
240
+ }
241
+
242
+ let pipeline;
243
+ try {
244
+ pipeline = JSON.parse(fs.readFileSync(pipelinePath, 'utf8'));
245
+ } catch {
246
+ legacyFlow();
247
+ }
248
+
249
+ const steps = pipeline.steps || [];
250
+ if (steps.length === 0 || pipeline.autoChain === false) {
251
+ process.stdout.write('{}');
89
252
  process.exit(0);
90
253
  }
91
254
 
92
- if (status.phase === 'review' && status.state === 'completed') {
93
- writeStatus({ phase: 'testing', state: 'in_progress' });
94
- out(
95
- `Code review completed for slug "${slug}". ` +
96
- `Invoke the qa-tester subagent. ` +
97
- `Add or update unit and e2e tests per brief acceptance criteria. ` +
98
- `Follow rules/testing/playwright-agents.md and rules/testing/tests-e2e-structure.md. ` +
99
- `Update status.json when done.`,
100
- );
255
+ if (status.awaitingHumanGate || status.state === 'awaiting_approval') {
256
+ process.stdout.write('{}');
101
257
  process.exit(0);
102
258
  }
103
259
 
104
- if (status.phase === 'review' && status.state === 'changes_requested') {
105
- out(
106
- `Review requested changes for slug "${slug}". ` +
107
- `Invoke feature-developer with the review fix list, then re-run code-reviewer.`,
108
- );
260
+ if (status.state === 'changes_requested' && REVIEW_AGENTS.has(status.currentAgent)) {
261
+ const reviewer = status.currentAgent;
262
+ writeStatus({
263
+ currentAgent: 'feature-developer',
264
+ state: 'in_progress',
265
+ phase: 'executing',
266
+ retryAfterFix: reviewer,
267
+ });
268
+ out(handoffForAgent('feature-developer') + ` After fixes, re-run ${reviewer}.`);
109
269
  process.exit(0);
110
270
  }
111
271
 
112
- if (status.phase === 'testing' && status.state === 'completed') {
113
- writeStatus({ phase: 'done', state: 'completed' });
114
- out(
115
- `QA phase completed for slug "${slug}". ` +
116
- `Suggest running /technical-retro with this slug. ` +
117
- `Read team artifacts under .claude/team/tasks/${slug}/ and git diff for the retro.`,
118
- );
272
+ if (status.state === 'validation_failed' && status.currentAgent === 'build-verifier') {
273
+ writeStatus({
274
+ currentAgent: 'feature-developer',
275
+ state: 'in_progress',
276
+ phase: 'executing',
277
+ retryAfterFix: 'build-verifier',
278
+ });
279
+ out(handoffForAgent('feature-developer') + ` Read validation-report.md. Re-run build-verifier after fixes.`);
280
+ process.exit(0);
281
+ }
282
+
283
+ if (status.state === 'completed' && status.retryAfterFix) {
284
+ const retry = status.retryAfterFix;
285
+ writeStatus({ currentAgent: retry, state: 'in_progress', retryAfterFix: null });
286
+ out(handoffForAgent(retry));
287
+ process.exit(0);
288
+ }
289
+
290
+ const idx = typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0;
291
+ const currentStep = steps[idx];
292
+ if (!currentStep) {
293
+ writeStatus({ phase: 'done', state: 'completed', currentAgent: null });
294
+ out(`Pipeline complete for "${slug}". Run /technical-retro ${slug}.`);
119
295
  process.exit(0);
120
296
  }
121
297
 
122
- process.stdout.write('{}');
298
+ const completedAgent = status.currentAgent || getStepAgents(currentStep)[0];
299
+ const stepAgents = getStepAgents(currentStep);
300
+
301
+ if (currentStep.parallel && stepAgents.length > 1) {
302
+ const done = [...(status.parallelCompleted || [])];
303
+ if (completedAgent && !done.includes(completedAgent)) done.push(completedAgent);
304
+ writeStatus({ parallelCompleted: done });
305
+ if (stepAgents.filter((a) => !done.includes(a)).length > 0) {
306
+ process.stdout.write('{}');
307
+ process.exit(0);
308
+ }
309
+ writeStatus({ parallelCompleted: [] });
310
+ }
311
+
312
+ if (hasGateAfterStep(currentStep, pipeline.humanGates)) {
313
+ writeStatus({ awaitingHumanGate: true, state: 'awaiting_approval', currentAgent: completedAgent });
314
+ process.stdout.write('{}');
315
+ process.exit(0);
316
+ }
317
+
318
+ const next = findNextExecutableStep(steps, idx + 1);
319
+ if (!next) {
320
+ writeStatus({ pipelineIndex: steps.length, phase: 'done', state: 'completed', currentAgent: null });
321
+ out(`Pipeline complete for "${slug}". Run /technical-retro ${slug}.`);
322
+ process.exit(0);
323
+ }
324
+
325
+ const { step: nextStep, index: nextIdx } = next;
326
+ const nextAgents = getStepAgents(nextStep);
327
+
328
+ writeStatus({
329
+ pipelineIndex: nextIdx,
330
+ currentAgent: nextAgents[0],
331
+ phase: 'executing',
332
+ state: 'in_progress',
333
+ awaitingHumanGate: false,
334
+ parallelCompleted: [],
335
+ });
336
+
337
+ if (nextStep.parallel && nextAgents.length > 1) {
338
+ out(handoffForParallelStep(nextStep));
339
+ } else {
340
+ out(handoffForAgent(nextAgents[0], nextStep.scope));
341
+ }
123
342
  NODE
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env bash
2
+ # Lightweight shell guard for Claude projects using this preset.
3
+
4
+ set -euo pipefail
5
+
6
+ input=$(cat)
7
+
8
+ INPUT="$input" node <<'NODE'
9
+ const fs = require('fs');
10
+
11
+ const raw = process.env.INPUT || '';
12
+ let event;
13
+ try {
14
+ event = JSON.parse(raw);
15
+ } catch {
16
+ process.stdout.write('{ "permission": "allow" }');
17
+ process.exit(0);
18
+ }
19
+
20
+ const command = String(event.command || event.input?.command || '');
21
+ if (!command.trim()) {
22
+ process.stdout.write('{ "permission": "allow" }');
23
+ process.exit(0);
24
+ }
25
+
26
+ function out(permission, userMessage, agentMessage) {
27
+ process.stdout.write(JSON.stringify({
28
+ permission,
29
+ user_message: userMessage,
30
+ agent_message: agentMessage || userMessage,
31
+ }));
32
+ }
33
+
34
+ const dangerousGit = /\bgit\s+(reset\s+--hard|clean\s+-[^\n]*f|push\s+--force|push\s+-f|checkout\s+--\s+)/;
35
+ if (dangerousGit.test(command)) {
36
+ out(
37
+ 'ask',
38
+ 'This command looks destructive for git state. Review it before continuing.',
39
+ 'A project hook flagged a destructive git command. Ask the user before running it.',
40
+ );
41
+ process.exit(0);
42
+ }
43
+
44
+ const managerByFile = [
45
+ ['yarn.lock', 'yarn'],
46
+ ['pnpm-lock.yaml', 'pnpm'],
47
+ ['package-lock.json', 'npm'],
48
+ ].find(([file]) => fs.existsSync(file));
49
+
50
+ let expected = managerByFile?.[1];
51
+ if (!expected && fs.existsSync('package.json')) {
52
+ try {
53
+ const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
54
+ const pm = typeof pkg.packageManager === 'string' ? pkg.packageManager : '';
55
+ expected = pm.split('@')[0] || undefined;
56
+ } catch {
57
+ // Ignore invalid package.json in the hook; the agent can diagnose it later.
58
+ }
59
+ }
60
+
61
+ if (!expected) {
62
+ process.stdout.write('{ "permission": "allow" }');
63
+ process.exit(0);
64
+ }
65
+
66
+ const used = command.match(/(^|[;&|]\s*)(npm|yarn|pnpm)\s+/)?.[2];
67
+ if (used && used !== expected) {
68
+ out(
69
+ 'ask',
70
+ `This repository appears to use ${expected}, but the command uses ${used}. Confirm before continuing.`,
71
+ `Use ${expected} for package scripts and installs unless the user explicitly approves ${used}.`,
72
+ );
73
+ process.exit(0);
74
+ }
75
+
76
+ process.stdout.write('{ "permission": "allow" }');
77
+ NODE
@@ -1,54 +1,30 @@
1
1
  # `.claude/rules` (preset next)
2
2
 
3
- В Claude Code все `.md` под `rules/` **обнаруживаются рекурсивно**. Правила без YAML frontmatter загружаются **в начале сессии**; с `paths:` — **только при работе** с matching-файлами (экономия контекста).
3
+ В Claude Code все `.md` под `rules/` **обнаруживаются рекурсивно**. Правила без YAML frontmatter загружаются **в начале сессии**; с `paths:` — **только при работе** с matching-файлами.
4
4
 
5
- Соответствие пресету Cursor (`.cursor/rules/*.mdc`):
5
+ ## Loading strategy
6
6
 
7
- | Папка | О чём | Загрузка |
8
- |-------|--------|----------|
9
- | `architecture/` | границы слоёв, barrel, импорты, доставка фичи | session start |
10
- | `stack/` | Next.js, TS, навигация, JSDoc типов | core — session; `types-jsdoc.md` — `paths: app/src/types/**` |
11
- | `api-and-data/` | HTTP, сервисы, store | `paths:` по каталогам слоя |
12
- | `ui-and-accessibility/` | React UI, стили, a11y, пропсы | core — session; `react-ui.md` — `paths: app/src/ui/**` |
13
- | `testing/` | unit, e2e, Playwright agents | `tests-unit.md`, `tests-e2e-structure.md` — `paths:`; `playwright-agents.md` — session start |
14
- | `tooling-and-review/` | lint, package manager, качество, MR review | session start |
7
+ - **Session start (no `paths:`):** `next-app-core`, `post-change-lint`, `package-manager`, `agent-team-intake`, `code-quality`, orchestrator
8
+ - **`paths:` on-demand:** architecture, imports, UI, tests, feature-delivery-workflow, reference-features, next-app-router, react-a11y-coding
9
+ - **Skills:** long workflows (`feature-delivery`, `code-review`, …)
15
10
 
16
- On-demand сценарии вне постоянного контекста — в `commands/` (например `technical-retro.md`).
11
+ ## С чего начать
17
12
 
18
- ## С чего начать новую фичу
13
+ - **`commands/task.md`** router `pipeline.json` → agents
14
+ - **`architecture/reference-features.md`** — заполнить TBD после init
15
+ - **`architecture/feature-delivery-workflow.md`** — порядок слоёв
19
16
 
20
- Для обычной задачи **`commands/task.md`**: router → `pipeline.json` → нужные agents. Для ручной реализации без team workflow — **`architecture/feature-delivery-workflow.md`**.
21
-
22
- ## Каталог правил
17
+ ## Каталог (новые и ключевые)
23
18
 
24
19
  | Файл | Назначение |
25
20
  |------|------------|
26
- | `tooling-and-review/package-manager.md` | Менеджер пакетов перед install/run |
27
- | `tooling-and-review/agent-team-intake.md` | Когда использовать `/task` и task-router |
28
- | `tooling-and-review/agent-team-orchestrator.md` | Dynamic pipeline, subagents, gates, handoff artifacts |
29
- | `architecture/feature-delivery-workflow.md` | Сквозной порядок работ по фиче, mermaid, матрица слой → правило |
30
- | `stack/next-app-core.md` | Стек, слои, порты‑адаптеры, работа агента |
31
- | `tooling-and-review/post-change-lint.md` | **Обязательный** ESLint + Stylelint после изменений |
32
- | `architecture/architecture-boundaries.md` | Границы UI / store / API, импорты, фича как срез |
33
- | `api-and-data/http-client.md` | Единый HTTP‑стек, контракты из `@/types` |
34
- | `api-and-data/api-services.md` | Сервисы, мапперы, прикладные API‑клиенты |
35
- | `api-and-data/store-rtk.md` | Redux Toolkit, thunk’и, типизация ошибок |
36
- | `architecture/types-public-imports.md` | Импорты только через barrel `@/types` |
37
- | `architecture/api-public-imports.md` | Импорты только через barrel `@/api` |
38
- | `architecture/layer-barrel-exports.md` | Двухуровневые barrel для слоёв с public API |
39
- | `stack/types-jsdoc.md` | JSDoc для типов в `app/src/types` |
40
- | `stack/no-type-assertion.md` | Ограничение `as`, `instanceof` для ошибок транспорта |
41
- | `tooling-and-review/code-review-mr.md` | Чеклист ревью MR |
42
- | `testing/tests-unit.md` | Unit‑тесты и behavior‑тесты HTTP‑клиента |
43
- | `testing/playwright-agents.md`, `testing/tests-e2e-structure.md` | E2e |
44
- | `ui-and-accessibility/react-ui.md` | React/Next UI: структура, `.data.ts` / `.utils.ts`, стили |
45
- | `ui-and-accessibility/no-props-spread.md` | Без spread пропов в компонентах |
46
- | `ui-and-accessibility/component-styles.md` | Колокация стилей, `Root` |
47
- | `ui-and-accessibility/css-property-order.md` | Порядок CSS (Stylelint) |
48
- | `stack/arrow-functions.md` | Стрелочные функции |
49
- | `stack/navigation-router.md` | Навигация по стеку проекта |
50
- | `tooling-and-review/code-quality.md` | Качество кода и рефакторинг |
51
-
52
- **Коллизии:** импорт типов — **`architecture/types-public-imports.md`**; импорт API вне `app/src/api/**` — **`architecture/api-public-imports.md`**.
53
-
54
- Задачи на **сеть, HTTP, эндпоинты**: **`api-and-data/http-client.md`** + **`api-and-data/api-services.md`** + **`api-and-data/store-rtk.md`**.
21
+ | `architecture/reference-features.md` | Эталонные пути UI/store/API |
22
+ | `stack/next-app-router.md` | App Router, RSC |
23
+ | `ui-and-accessibility/react-a11y-coding.md` | A11y при кодинге UI |
24
+ | `architecture/feature-delivery-workflow.md` | Сквозной чеклист (paths) |
25
+ | `tooling-and-review/agent-team-orchestrator.md` | Pipeline, build-verifier, parallel |
26
+ | `agents/build-verifier.md` | Validation gate agent |
27
+
28
+ Полный список — см. подпапки `architecture/`, `stack/`, `api-and-data/`, `ui-and-accessibility/`, `testing/`, `tooling-and-review/`.
29
+
30
+ **Коллизии:** импорт типов — `architecture/types-public-imports.md`; API вне `app/src/api/**` `architecture/api-public-imports.md`.
@@ -1,3 +1,9 @@
1
+ ---
2
+ paths:
3
+ - app/src/**/*.ts
4
+ - app/src/**/*.tsx
5
+ ---
6
+
1
7
  # Импорты из `@/api`
2
8
 
3
9
  - **Публичный API слоя API** — barrel `app/src/api/index.ts`. Для файлов **вне** `app/src/api/**` импортировать сервисы, клиенты, эндпоинты и публичные типы API **только** как `import … from '@/api'` (или `from '@/api/index'` при необходимости явного пути).
@@ -1,3 +1,8 @@
1
+ ---
2
+ paths:
3
+ - app/src/**/*
4
+ ---
5
+
1
6
  # Границы между слоями
2
7
 
3
8
  ## UI (`app/src/ui/**`)
@@ -1,3 +1,8 @@
1
+ ---
2
+ paths:
3
+ - app/src/**/*
4
+ ---
5
+
1
6
  # Доставка фичи (сквозной порядок)
2
7
 
3
8
  Типичная фича с данными с backend и общим состоянием. Детали слоёв — в `architecture/architecture-boundaries.md`, `stack/next-app-core.md`.
@@ -1,3 +1,8 @@
1
+ ---
2
+ paths:
3
+ - app/src/**/*
4
+ ---
5
+
1
6
  # Barrel-экспорты слоёв с public API
2
7
 
3
8
  ## Когда применять
@@ -0,0 +1,34 @@
1
+ ---
2
+ paths:
3
+ - app/src/**/*
4
+ ---
5
+
6
+ # Эталонные фичи (reference features)
7
+
8
+ Перед реализацией найди фичу того же типа и **повтори её структуру**, не изобретая новую организацию файлов.
9
+
10
+ ## Таблица эталонов
11
+
12
+ Замени **TBD** на реальные пути после договорённости в команде (или при `ai-rules init` в целевом репо):
13
+
14
+ | Слой | Эталон | Что копировать |
15
+ |------|--------|----------------|
16
+ | UI page | **TBD** `app/src/ui/pages/<Example>/` | `components/`, `*.data.ts`, `styles.ts`, barrel |
17
+ | Store slice | **TBD** `app/src/store/slices/<example>/` | slice, thunks, selectors, types |
18
+ | API service | **TBD** `app/src/api/services/<example>/` | service, mappers, barrel |
19
+ | Types module | **TBD** `app/src/types/<example>/` | domain types, JSDoc, barrel export |
20
+ | Unit tests | **TBD** рядом с эталонным mapper/service | `*.spec.ts`, describe/it naming |
21
+ | E2E area | **TBD** `app/__tests__/e2e/<Area>/` | `*.cases.md`, page objects, `_shared/` |
22
+
23
+ ## Как использовать
24
+
25
+ 1. Определи затронутые слои из `decomposition.md` или задачи.
26
+ 2. Открой эталон из таблицы (после заполнения путей).
27
+ 3. Зеркаль именование, порядок файлов, паттерны импортов и тестов.
28
+ 4. Если эталона нет — выбери **самую близкую** существующую фичу того же слоя и зафиксируй выбор в handoff.
29
+
30
+ ## Связанные правила
31
+
32
+ - `tooling-and-review/code-quality.md` — повторять паттерны, не deep-import.
33
+ - `architecture/feature-delivery-workflow.md` — порядок слоёв.
34
+ - skill `feature-delivery` — end-to-end сценарий.
@@ -1,3 +1,9 @@
1
+ ---
2
+ paths:
3
+ - app/src/**/*.ts
4
+ - app/src/**/*.tsx
5
+ ---
6
+
1
7
  # Импорты из `@/types`
2
8
 
3
9
  - **Публичный API типов** — barrel `app/src/types/index.ts`, импортировать типы и интерфейсы только как `@/types` (или `@/types/index` при необходимости явного пути).
@@ -1,3 +1,8 @@
1
+ ---
2
+ paths:
3
+ - app/src/**/*.{ts,tsx,js,jsx}
4
+ ---
5
+
1
6
  # Стрелочные функции
2
7
 
3
8
  При разработке **использовать стрелочный синтаксис** для функций, где это допустимо в TypeScript/JavaScript.
@@ -1,3 +1,8 @@
1
+ ---
2
+ paths:
3
+ - app/src/ui/**/*
4
+ ---
5
+
1
6
  # Навигация и роутинг: сначала стек проекта
2
7
 
3
8
  **При любой задаче, связанной с навигацией, переходами между страницами, URL, редиректами, хлебными крошками, защищёнными маршрутами или программной сменой маршрута** — перед предложением кода или импортов **нельзя** опираться на «типичный React» по умолчанию. Нужно **явно свериться со стеком целевого репозитория** и использовать **один** согласованный с проектом механизм.
@@ -0,0 +1,36 @@
1
+ ---
2
+ paths:
3
+ - app/src/app/**/*
4
+ - app/**/app/**/*
5
+ ---
6
+
7
+ # Next.js App Router
8
+
9
+ Применять при работе с `app/src/app/**` или маршрутами App Router в целевом репо.
10
+
11
+ ## Server vs Client
12
+
13
+ - **Server Components по умолчанию** — без `'use client'`, если не нужны hooks, browser API, event handlers.
14
+ - **`'use client'`** — только для интерактива, `useState`/`useEffect`, browser-only API.
15
+ - Не тянуть store/RTK и тяжёлый client-state в Server Components без необходимости.
16
+
17
+ ## Data fetching
18
+
19
+ - Предпочитать fetch/data-loader на **server** (RSC, route handlers, server actions — по принятому в репо паттерну).
20
+ - **Не дублировать** один запрос в RSC и client без причины.
21
+ - Кеш и revalidate — как в существующих страницах репо (`fetch` options, `revalidate`, tags).
22
+
23
+ ## Маршруты и UX
24
+
25
+ - Для async routes использовать **`loading.tsx`**, **`error.tsx`**, **`not-found.tsx`** по образцу соседних routes.
26
+ - **Suspense** — для медленных client/server секций; fallback согласован с дизайн-системой.
27
+ - Навигация — `stack/navigation-router.md` + router/link паттерны проекта.
28
+
29
+ ## Границы слоёв
30
+
31
+ - RSC/route handlers **не импортируют UI-компоненты с client-only зависимостями** напрямую в server tree без `'use client'` границы.
32
+ - Доменные типы — `@/types`; вызовы backend — через `@/api` / services, не raw `fetch` из page.tsx без слоя API.
33
+
34
+ ## Эталон
35
+
36
+ Смотри существующий route той же сложности в `app/src/app/**` и повтори структуру (`architecture/reference-features.md`).
@@ -1,3 +1,9 @@
1
+ ---
2
+ paths:
3
+ - app/src/**/*.ts
4
+ - app/src/**/*.tsx
5
+ ---
6
+
1
7
  # Не использовать `as` для приведения типов при экспорте и импорте
2
8
 
3
9
  ## О чём речь