@bonesofspring/ai-rules 0.2.10 → 0.2.11

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 (152) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +3 -1
  3. package/bin/cli.js +2 -0
  4. package/package.json +1 -1
  5. package/presets/_shared/core/meta/preset-no-cross-stack-leakage.md +15 -2
  6. package/presets/_shared/core/meta/preset-twin-sync.md +2 -0
  7. package/presets/claude/go/rules/tooling-and-review/preset-no-cross-stack-leakage.md +15 -2
  8. package/presets/claude/go/rules/tooling-and-review/preset-twin-sync.md +2 -0
  9. package/presets/claude/ios-swift/rules/tooling-and-review/preset-no-cross-stack-leakage.md +15 -2
  10. package/presets/claude/ios-swift/rules/tooling-and-review/preset-twin-sync.md +2 -0
  11. package/presets/claude/java/rules/tooling-and-review/preset-no-cross-stack-leakage.md +15 -2
  12. package/presets/claude/java/rules/tooling-and-review/preset-twin-sync.md +2 -0
  13. package/presets/claude/mcp-ts/CLAUDE.md +13 -0
  14. package/presets/claude/mcp-ts/MCP.md +37 -0
  15. package/presets/claude/mcp-ts/README.md +11 -0
  16. package/presets/claude/mcp-ts/REPO_AGENTS.md +49 -0
  17. package/presets/claude/mcp-ts/agents/README.md +21 -0
  18. package/presets/claude/mcp-ts/agents/build-verifier.md +39 -0
  19. package/presets/claude/mcp-ts/agents/feature-developer.md +47 -0
  20. package/presets/claude/mcp-ts/agents/security-reviewer.md +21 -0
  21. package/presets/claude/mcp-ts/agents/solution-architect.md +23 -0
  22. package/presets/claude/mcp-ts/agents/task-analyst.md +25 -0
  23. package/presets/claude/mcp-ts/agents/task-router.md +73 -0
  24. package/presets/claude/mcp-ts/commands/README.md +11 -0
  25. package/presets/claude/mcp-ts/commands/feature-continue.md +19 -0
  26. package/presets/claude/mcp-ts/commands/feature-start.md +33 -0
  27. package/presets/claude/mcp-ts/commands/task-continue.md +49 -0
  28. package/presets/claude/mcp-ts/commands/task.md +49 -0
  29. package/presets/claude/mcp-ts/commands/technical-retro.md +81 -0
  30. package/presets/claude/mcp-ts/hooks/README.md +12 -0
  31. package/presets/claude/mcp-ts/hooks/chain-team-phases.sh +346 -0
  32. package/presets/claude/mcp-ts/hooks/examples/README.md +11 -0
  33. package/presets/claude/mcp-ts/hooks/examples/format-edited.example.sh +16 -0
  34. package/presets/claude/mcp-ts/hooks/examples/secret-guard.example.sh +10 -0
  35. package/presets/claude/mcp-ts/hooks/examples/test-on-save.example.sh +25 -0
  36. package/presets/claude/mcp-ts/hooks/guard-shell-command.sh +79 -0
  37. package/presets/claude/mcp-ts/mcp.json +11 -0
  38. package/presets/claude/mcp-ts/rules/README.md +52 -0
  39. package/presets/claude/mcp-ts/rules/api-and-data/README.md +3 -0
  40. package/presets/claude/mcp-ts/rules/api-and-data/mcp-auth-secrets.md +44 -0
  41. package/presets/claude/mcp-ts/rules/api-and-data/mcp-contract-testing.md +42 -0
  42. package/presets/claude/mcp-ts/rules/api-and-data/mcp-tool-design.md +37 -0
  43. package/presets/claude/mcp-ts/rules/api-and-data/mcp-transport-packaging.md +43 -0
  44. package/presets/claude/mcp-ts/rules/architecture/README.md +3 -0
  45. package/presets/claude/mcp-ts/rules/architecture/feature-delivery.md +45 -0
  46. package/presets/claude/mcp-ts/rules/architecture/mcp-server-boundaries.md +28 -0
  47. package/presets/claude/mcp-ts/rules/architecture/reference-features.md +33 -0
  48. package/presets/claude/mcp-ts/rules/stack/README.md +3 -0
  49. package/presets/claude/mcp-ts/rules/stack/mcp-ts-app-core.md +27 -0
  50. package/presets/claude/mcp-ts/rules/stack/mcp-ts-conventions.md +29 -0
  51. package/presets/claude/mcp-ts/rules/testing/README.md +3 -0
  52. package/presets/claude/mcp-ts/rules/testing/unit.md +30 -0
  53. package/presets/claude/mcp-ts/rules/tooling-and-review/README.md +3 -0
  54. package/presets/claude/mcp-ts/rules/tooling-and-review/agent-team-intake.md +23 -0
  55. package/presets/claude/mcp-ts/rules/tooling-and-review/agent-team-orchestrator.md +161 -0
  56. package/presets/claude/mcp-ts/rules/tooling-and-review/anti-sycophancy-discipline.md +34 -0
  57. package/presets/claude/mcp-ts/rules/tooling-and-review/code-quality.md +52 -0
  58. package/presets/claude/mcp-ts/rules/tooling-and-review/code-review.md +51 -0
  59. package/presets/claude/mcp-ts/rules/tooling-and-review/design-guidance.md +109 -0
  60. package/presets/claude/mcp-ts/rules/tooling-and-review/mcp-ts-tooling.md +31 -0
  61. package/presets/claude/mcp-ts/rules/tooling-and-review/post-change-test.md +30 -0
  62. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-layering.md +36 -0
  63. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-no-cross-stack-leakage.md +69 -0
  64. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-pr-checklist.md +39 -0
  65. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-token-budget.md +41 -0
  66. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-twin-sync.md +46 -0
  67. package/presets/claude/mcp-ts/rules/tooling-and-review/security-mcp.md +52 -0
  68. package/presets/claude/mcp-ts/rules/tooling-and-review/technical-retro.md +20 -0
  69. package/presets/claude/mcp-ts/rules/ui-and-accessibility/README.md +3 -0
  70. package/presets/claude/mcp-ts/skills/README.md +12 -0
  71. package/presets/claude/mcp-ts/skills/code-review/SKILL.md +10 -0
  72. package/presets/claude/mcp-ts/skills/debug-investigation/SKILL.md +11 -0
  73. package/presets/claude/mcp-ts/skills/feature-delivery/SKILL.md +29 -0
  74. package/presets/claude/mcp-ts/skills/unit-testing/SKILL.md +16 -0
  75. package/presets/claude/mcp-ts/team/README.md +17 -0
  76. package/presets/claude/mcp-ts/team/conventions.md +14 -0
  77. package/presets/claude/mcp-ts/team/fixtures/bugfix-standard.json +32 -0
  78. package/presets/claude/mcp-ts/team/fixtures/feature-full.json +33 -0
  79. package/presets/claude/mcp-ts/team/fixtures/feature-light.json +34 -0
  80. package/presets/claude/next/rules/tooling-and-review/preset-no-cross-stack-leakage.md +15 -2
  81. package/presets/claude/next/rules/tooling-and-review/preset-twin-sync.md +2 -0
  82. package/presets/cursor/go/rules/preset-no-cross-stack-leakage.mdc +15 -2
  83. package/presets/cursor/go/rules/preset-twin-sync.mdc +2 -0
  84. package/presets/cursor/ios-swift/rules/preset-no-cross-stack-leakage.mdc +15 -2
  85. package/presets/cursor/ios-swift/rules/preset-twin-sync.mdc +2 -0
  86. package/presets/cursor/java/rules/preset-no-cross-stack-leakage.mdc +15 -2
  87. package/presets/cursor/java/rules/preset-twin-sync.mdc +2 -0
  88. package/presets/cursor/mcp-ts/AGENTS.md +25 -0
  89. package/presets/cursor/mcp-ts/BUGBOT.md +9 -0
  90. package/presets/cursor/mcp-ts/MCP.md +37 -0
  91. package/presets/cursor/mcp-ts/README.md +19 -0
  92. package/presets/cursor/mcp-ts/REPO_AGENTS.md +49 -0
  93. package/presets/cursor/mcp-ts/agents/README.md +21 -0
  94. package/presets/cursor/mcp-ts/agents/build-verifier.md +39 -0
  95. package/presets/cursor/mcp-ts/agents/feature-developer.md +47 -0
  96. package/presets/cursor/mcp-ts/agents/security-reviewer.md +21 -0
  97. package/presets/cursor/mcp-ts/agents/solution-architect.md +23 -0
  98. package/presets/cursor/mcp-ts/agents/task-analyst.md +25 -0
  99. package/presets/cursor/mcp-ts/agents/task-router.md +73 -0
  100. package/presets/cursor/mcp-ts/commands/README.md +11 -0
  101. package/presets/cursor/mcp-ts/commands/feature-continue.md +19 -0
  102. package/presets/cursor/mcp-ts/commands/feature-start.md +33 -0
  103. package/presets/cursor/mcp-ts/commands/task-continue.md +49 -0
  104. package/presets/cursor/mcp-ts/commands/task.md +49 -0
  105. package/presets/cursor/mcp-ts/commands/technical-retro.md +81 -0
  106. package/presets/cursor/mcp-ts/hooks/README.md +12 -0
  107. package/presets/cursor/mcp-ts/hooks/chain-team-phases.sh +346 -0
  108. package/presets/cursor/mcp-ts/hooks/examples/README.md +11 -0
  109. package/presets/cursor/mcp-ts/hooks/examples/format-edited.example.sh +16 -0
  110. package/presets/cursor/mcp-ts/hooks/examples/secret-guard.example.sh +10 -0
  111. package/presets/cursor/mcp-ts/hooks/examples/test-on-save.example.sh +25 -0
  112. package/presets/cursor/mcp-ts/hooks/guard-shell-command.sh +79 -0
  113. package/presets/cursor/mcp-ts/hooks.json +17 -0
  114. package/presets/cursor/mcp-ts/mcp.json +11 -0
  115. package/presets/cursor/mcp-ts/rules/README.md +52 -0
  116. package/presets/cursor/mcp-ts/rules/agent-team-intake.mdc +21 -0
  117. package/presets/cursor/mcp-ts/rules/agent-team-orchestrator.mdc +159 -0
  118. package/presets/cursor/mcp-ts/rules/anti-sycophancy-discipline.mdc +35 -0
  119. package/presets/cursor/mcp-ts/rules/code-quality-and-refactoring.mdc +53 -0
  120. package/presets/cursor/mcp-ts/rules/code-review-mr.mdc +50 -0
  121. package/presets/cursor/mcp-ts/rules/design-guidance.mdc +108 -0
  122. package/presets/cursor/mcp-ts/rules/feature-delivery-workflow.mdc +43 -0
  123. package/presets/cursor/mcp-ts/rules/mcp-auth-secrets.mdc +45 -0
  124. package/presets/cursor/mcp-ts/rules/mcp-contract-testing.mdc +43 -0
  125. package/presets/cursor/mcp-ts/rules/mcp-server-boundaries.mdc +29 -0
  126. package/presets/cursor/mcp-ts/rules/mcp-tool-design.mdc +38 -0
  127. package/presets/cursor/mcp-ts/rules/mcp-transport-packaging.mdc +44 -0
  128. package/presets/cursor/mcp-ts/rules/mcp-ts-app-core.mdc +28 -0
  129. package/presets/cursor/mcp-ts/rules/mcp-ts-conventions.mdc +30 -0
  130. package/presets/cursor/mcp-ts/rules/mcp-ts-tooling.mdc +32 -0
  131. package/presets/cursor/mcp-ts/rules/post-change-test.mdc +26 -0
  132. package/presets/cursor/mcp-ts/rules/preset-layering.mdc +36 -0
  133. package/presets/cursor/mcp-ts/rules/preset-no-cross-stack-leakage.mdc +69 -0
  134. package/presets/cursor/mcp-ts/rules/preset-pr-checklist.mdc +39 -0
  135. package/presets/cursor/mcp-ts/rules/preset-token-budget.mdc +41 -0
  136. package/presets/cursor/mcp-ts/rules/preset-twin-sync.mdc +46 -0
  137. package/presets/cursor/mcp-ts/rules/reference-features.mdc +34 -0
  138. package/presets/cursor/mcp-ts/rules/security-mcp.mdc +53 -0
  139. package/presets/cursor/mcp-ts/rules/technical-retro.mdc +18 -0
  140. package/presets/cursor/mcp-ts/rules/tests-unit.mdc +31 -0
  141. package/presets/cursor/mcp-ts/skills/README.md +12 -0
  142. package/presets/cursor/mcp-ts/skills/code-review/SKILL.md +10 -0
  143. package/presets/cursor/mcp-ts/skills/debug-investigation/SKILL.md +11 -0
  144. package/presets/cursor/mcp-ts/skills/feature-delivery/SKILL.md +29 -0
  145. package/presets/cursor/mcp-ts/skills/unit-testing/SKILL.md +16 -0
  146. package/presets/cursor/mcp-ts/team/README.md +17 -0
  147. package/presets/cursor/mcp-ts/team/conventions.md +14 -0
  148. package/presets/cursor/mcp-ts/team/fixtures/bugfix-standard.json +32 -0
  149. package/presets/cursor/mcp-ts/team/fixtures/feature-full.json +33 -0
  150. package/presets/cursor/mcp-ts/team/fixtures/feature-light.json +34 -0
  151. package/presets/cursor/next/rules/preset-no-cross-stack-leakage.mdc +15 -2
  152. package/presets/cursor/next/rules/preset-twin-sync.mdc +2 -0
@@ -0,0 +1,346 @@
1
+ #!/usr/bin/env bash
2
+ # preset: mcp-ts (TypeScript MCP) — chain handoffs use build-verifier + security-reviewer; no contract-test-*
3
+ # Chains agent team steps from pipeline.json after subagentStop.
4
+ # Falls back to legacy phase-based flow when pipeline.json is absent.
5
+
6
+ set -euo pipefail
7
+
8
+ input=$(cat)
9
+
10
+ INPUT="$input" node <<'NODE'
11
+ const fs = require('fs');
12
+ const path = require('path');
13
+
14
+ // mcp-ts Phase-1 chain: validation via typecheck/tests + security-reviewer (no contract-test-* handoffs)
15
+ const TEAM_ROOT = path.join(process.cwd(), '.cursor', 'team');
16
+
17
+ const inputRaw = process.env.INPUT || '';
18
+ let hookInput;
19
+ try {
20
+ hookInput = JSON.parse(inputRaw);
21
+ } catch {
22
+ process.stdout.write('{}');
23
+ process.exit(0);
24
+ }
25
+
26
+ if (hookInput.status !== 'completed') {
27
+ process.stdout.write('{}');
28
+ process.exit(0);
29
+ }
30
+
31
+ const activePath = path.join(TEAM_ROOT, 'active-task.json');
32
+
33
+ if (!fs.existsSync(activePath)) {
34
+ process.stdout.write('{}');
35
+ process.exit(0);
36
+ }
37
+
38
+ let active;
39
+ try {
40
+ active = JSON.parse(fs.readFileSync(activePath, 'utf8'));
41
+ } catch {
42
+ process.stdout.write('{}');
43
+ process.exit(0);
44
+ }
45
+
46
+ const slug = active.slug;
47
+ if (!slug) {
48
+ process.stdout.write('{}');
49
+ process.exit(0);
50
+ }
51
+
52
+ const taskDir = path.join(TEAM_ROOT, 'tasks', slug);
53
+ const statusPath = path.join(taskDir, 'status.json');
54
+ const pipelinePath = path.join(taskDir, 'pipeline.json');
55
+
56
+ if (!fs.existsSync(statusPath)) {
57
+ process.stdout.write('{}');
58
+ process.exit(0);
59
+ }
60
+
61
+ let status;
62
+ try {
63
+ status = JSON.parse(fs.readFileSync(statusPath, 'utf8'));
64
+ } catch {
65
+ process.stdout.write('{}');
66
+ process.exit(0);
67
+ }
68
+
69
+ const now = new Date().toISOString();
70
+
71
+ function writeStatus(next) {
72
+ status = { ...status, ...next, slug, updatedAt: now };
73
+ fs.writeFileSync(statusPath, JSON.stringify(status, null, 2) + '\n');
74
+ }
75
+
76
+ function out(message) {
77
+ process.stdout.write(JSON.stringify({ followup_message: message }));
78
+ }
79
+
80
+ function readArtifact(name) {
81
+ const p = path.join(taskDir, name);
82
+ if (!fs.existsSync(p)) return '';
83
+ try {
84
+ return fs.readFileSync(p, 'utf8');
85
+ } catch {
86
+ return '';
87
+ }
88
+ }
89
+
90
+ function getStepAgents(step) {
91
+ if (!step) return [];
92
+ return Array.isArray(step.agent) ? step.agent : [step.agent];
93
+ }
94
+
95
+ function skipIfMatches(skipIf, dir) {
96
+ if (!skipIf) return false;
97
+ // Phase-2 reserved: debugger / ci-investigator are not in mcp-ts Phase 1 roster.
98
+ if (skipIf === 'debugger.fixed') {
99
+ const text = readArtifact('debug-report.md');
100
+ return /fixApplied:\s*true/i.test(text) || /\*\*Fix applied:\*\*\s*true/i.test(text);
101
+ }
102
+ if (skipIf === 'ci-investigator.resolved') {
103
+ const text = readArtifact('ci-report.md');
104
+ return /fixApplied:\s*true/i.test(text) || /## Verdict\s*\nPASS/i.test(text);
105
+ }
106
+ return false;
107
+ }
108
+
109
+ function findNextExecutableStep(steps, startIdx, dir) {
110
+ for (let i = startIdx; i < steps.length; i++) {
111
+ if (!skipIfMatches(steps[i].skipIf, dir)) {
112
+ return { step: steps[i], index: i };
113
+ }
114
+ }
115
+ return null;
116
+ }
117
+
118
+ const AGENT_HANDOFF = {
119
+ 'task-analyst': (s) =>
120
+ `Invoke task-analyst for slug "${s}". Write brief.md and decomposition.md under .cursor/team/tasks/${s}/. ` +
121
+ `Set status.json: phase executing, state awaiting_approval if human gate applies. Do not use legacy phase analysis.`,
122
+ 'solution-architect': (s) =>
123
+ `Invoke solution-architect for slug "${s}". Read brief.md; write architecture.md for MCP tool/resource/prompt contracts and module boundaries. Update status.json when done.`,
124
+ 'feature-developer': (s) =>
125
+ `Invoke feature-developer for slug "${s}". Read brief.md, decomposition.md, validation-report.md, architecture.md, security-review.md, debug-report.md if present. ` +
126
+ `Follow feature-delivery-workflow.mdc and reference-features.mdc. Mandatory flow: contract → schema → handler → registration → unit/contract verification → package validation. ` +
127
+ `Include schema/handler unit tests before handoff. Update status.json when done.`,
128
+ 'build-verifier': (s) =>
129
+ `Invoke build-verifier (readonly) for slug "${s}". Follow mcp-ts-tooling.mdc and post-change-test.mdc. ` +
130
+ `Discover package manager; run typecheck + project tests — never Playwright/XCUITest/Next lint recipes/Go tools as required gates. ` +
131
+ `For preset packaging: yarn check:preset-structure (mcp-ts STACKS + MCP_TS_FORBIDDEN_*). Write validation-report.md. Set state completed or validation_failed. Do not edit production code.`,
132
+ 'security-reviewer': (s) =>
133
+ `Invoke security-reviewer (readonly) for slug "${s}". Follow security-mcp.mdc and mcp-auth-secrets.mdc; write security-review.md. Update status.json when done.`,
134
+ };
135
+
136
+ const REVIEW_AGENTS = new Set([
137
+ 'security-reviewer',
138
+ ]);
139
+
140
+
141
+ function handoffForAgent(agent, scope) {
142
+ const fn = AGENT_HANDOFF[agent];
143
+ return fn ? fn(slug, scope) : `Invoke ${agent} subagent for slug "${slug}". Update status.json when done.`;
144
+ }
145
+
146
+ function handoffForParallelStep(step) {
147
+ const agents = getStepAgents(step);
148
+ return (
149
+ `Invoke IN PARALLEL (one message, multiple Task calls): ${agents.join(' AND ')} for slug "${slug}". ` +
150
+ `Each agent writes its artifact and appends itself to status.json parallelCompleted when done.`
151
+ );
152
+ }
153
+
154
+ function hasGateAfter(agent, humanGates) {
155
+ return Array.isArray(humanGates) && humanGates.includes(`after:${agent}`);
156
+ }
157
+
158
+ function hasGateAfterStep(step, humanGates) {
159
+ return getStepAgents(step).some((a) => hasGateAfter(a, humanGates));
160
+ }
161
+
162
+ function legacyFlow() {
163
+ if (status.phase === 'analysis') {
164
+ process.stdout.write('{}');
165
+ process.exit(0);
166
+ }
167
+ if (status.phase === 'development' && (status.state === 'completed' || status.state === 'in_progress')) {
168
+ writeStatus({ phase: 'executing', state: 'in_progress', currentAgent: 'build-verifier' });
169
+ out(handoffForAgent('build-verifier'));
170
+ process.exit(0);
171
+ }
172
+ if (status.currentAgent === 'build-verifier' && status.state === 'completed') {
173
+ writeStatus({ phase: 'executing', state: 'in_progress', currentAgent: 'security-reviewer' });
174
+ out(handoffForAgent('security-reviewer'));
175
+ process.exit(0);
176
+ }
177
+ if (status.phase === 'review' && status.state === 'completed') {
178
+ writeStatus({ phase: 'done', state: 'completed' });
179
+ out(`Pipeline complete for "${slug}". Run /technical-retro ${slug}.`);
180
+ process.exit(0);
181
+ }
182
+ if (status.state === 'changes_requested' && REVIEW_AGENTS.has(status.currentAgent)) {
183
+ writeStatus({
184
+ currentAgent: 'feature-developer',
185
+ state: 'in_progress',
186
+ phase: 'executing',
187
+ retryAfterFix: status.currentAgent,
188
+ });
189
+ out(
190
+ handoffForAgent('feature-developer') +
191
+ ` After fixes, re-run ${status.currentAgent}.`,
192
+ );
193
+ process.exit(0);
194
+ }
195
+ if (status.state === 'validation_failed' && status.currentAgent === 'build-verifier') {
196
+ writeStatus({
197
+ currentAgent: 'feature-developer',
198
+ state: 'in_progress',
199
+ phase: 'executing',
200
+ retryAfterFix: 'build-verifier',
201
+ });
202
+ out(
203
+ handoffForAgent('feature-developer') +
204
+ ` Read validation-report.md. After fixes, re-run build-verifier.`,
205
+ );
206
+ process.exit(0);
207
+ }
208
+ if (status.state === 'completed' && status.retryAfterFix) {
209
+ const retry = status.retryAfterFix;
210
+ writeStatus({ currentAgent: retry, state: 'in_progress', retryAfterFix: null });
211
+ out(handoffForAgent(retry));
212
+ process.exit(0);
213
+ }
214
+ if (status.phase === 'testing' && status.state === 'completed') {
215
+ writeStatus({ phase: 'done', state: 'completed' });
216
+ out(`Pipeline complete for "${slug}". Run /technical-retro ${slug}.`);
217
+ process.exit(0);
218
+ }
219
+ process.stdout.write('{}');
220
+ process.exit(0);
221
+ }
222
+
223
+ if (!fs.existsSync(pipelinePath)) {
224
+ legacyFlow();
225
+ }
226
+
227
+ let pipeline;
228
+ try {
229
+ pipeline = JSON.parse(fs.readFileSync(pipelinePath, 'utf8'));
230
+ } catch {
231
+ legacyFlow();
232
+ }
233
+
234
+ const steps = pipeline.steps || [];
235
+ if (steps.length === 0 || pipeline.autoChain === false) {
236
+ process.stdout.write('{}');
237
+ process.exit(0);
238
+ }
239
+
240
+ if (status.awaitingHumanGate || status.state === 'awaiting_approval') {
241
+ process.stdout.write('{}');
242
+ process.exit(0);
243
+ }
244
+
245
+ if (status.state === 'changes_requested' && REVIEW_AGENTS.has(status.currentAgent)) {
246
+ const reviewer = status.currentAgent;
247
+ writeStatus({
248
+ currentAgent: 'feature-developer',
249
+ state: 'in_progress',
250
+ phase: 'executing',
251
+ retryAfterFix: reviewer,
252
+ });
253
+ out(
254
+ handoffForAgent('feature-developer') +
255
+ ` After fixes, re-run ${reviewer}.`,
256
+ );
257
+ process.exit(0);
258
+ }
259
+
260
+ if (status.state === 'validation_failed' && status.currentAgent === 'build-verifier') {
261
+ writeStatus({
262
+ currentAgent: 'feature-developer',
263
+ state: 'in_progress',
264
+ phase: 'executing',
265
+ retryAfterFix: 'build-verifier',
266
+ });
267
+ out(
268
+ handoffForAgent('feature-developer') +
269
+ ` Read validation-report.md. After fixes, re-run build-verifier.`,
270
+ );
271
+ process.exit(0);
272
+ }
273
+
274
+ if (status.state === 'completed' && status.retryAfterFix) {
275
+ const retry = status.retryAfterFix;
276
+ writeStatus({ currentAgent: retry, state: 'in_progress', retryAfterFix: null });
277
+ out(handoffForAgent(retry));
278
+ process.exit(0);
279
+ }
280
+
281
+ const idx = typeof status.pipelineIndex === 'number' ? status.pipelineIndex : 0;
282
+ const currentStep = steps[idx];
283
+ if (!currentStep) {
284
+ writeStatus({ phase: 'done', state: 'completed', currentAgent: null });
285
+ out(`Pipeline complete for "${slug}". Run /technical-retro ${slug}.`);
286
+ process.exit(0);
287
+ }
288
+
289
+ const completedAgent = status.currentAgent || getStepAgents(currentStep)[0];
290
+ const stepAgents = getStepAgents(currentStep);
291
+
292
+ if (currentStep.parallel && stepAgents.length > 1) {
293
+ const done = [...(status.parallelCompleted || [])];
294
+ if (completedAgent && !done.includes(completedAgent)) {
295
+ done.push(completedAgent);
296
+ }
297
+ writeStatus({ parallelCompleted: done });
298
+ const remaining = stepAgents.filter((a) => !done.includes(a));
299
+ if (remaining.length > 0) {
300
+ process.stdout.write('{}');
301
+ process.exit(0);
302
+ }
303
+ writeStatus({ parallelCompleted: [] });
304
+ }
305
+
306
+ if (hasGateAfterStep(currentStep, pipeline.humanGates)) {
307
+ writeStatus({
308
+ awaitingHumanGate: true,
309
+ state: 'awaiting_approval',
310
+ currentAgent: completedAgent,
311
+ });
312
+ process.stdout.write('{}');
313
+ process.exit(0);
314
+ }
315
+
316
+ const next = findNextExecutableStep(steps, idx + 1, taskDir);
317
+ if (!next) {
318
+ writeStatus({
319
+ pipelineIndex: steps.length,
320
+ phase: 'done',
321
+ state: 'completed',
322
+ currentAgent: null,
323
+ awaitingHumanGate: false,
324
+ });
325
+ out(`Pipeline complete for "${slug}". Run /technical-retro ${slug}.`);
326
+ process.exit(0);
327
+ }
328
+
329
+ const { step: nextStep, index: nextIdx } = next;
330
+ const nextAgents = getStepAgents(nextStep);
331
+
332
+ writeStatus({
333
+ pipelineIndex: nextIdx,
334
+ currentAgent: nextAgents[0],
335
+ phase: 'executing',
336
+ state: 'in_progress',
337
+ awaitingHumanGate: false,
338
+ parallelCompleted: [],
339
+ });
340
+
341
+ if (nextStep.parallel && nextAgents.length > 1) {
342
+ out(handoffForParallelStep(nextStep));
343
+ } else {
344
+ out(handoffForAgent(nextAgents[0], nextStep.scope));
345
+ }
346
+ NODE
@@ -0,0 +1,11 @@
1
+ # Hook examples (mcp-ts)
2
+
3
+ Optional cookbook scripts — **not** wired into default `hooks.json`.
4
+
5
+ | Example | Idea |
6
+ |---------|------|
7
+ | `secret-guard.example.sh` | Block committing obvious secrets |
8
+ | `format-edited.example.sh` | Format touched files with project formatter |
9
+ | `test-on-save.example.sh` | Run scoped tests after edits |
10
+
11
+ Adapt commands to the repository package manager (`mcp-ts-tooling`).
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env bash
2
+ # Optional: format / lint touched TypeScript files with project tooling.
3
+ # NOT in default hooks.json. Discover package manager before running scripts.
4
+ set -euo pipefail
5
+ changed=$(git diff --name-only --diff-filter=ACMR HEAD 2>/dev/null | grep -E '\.(ts|tsx|js|mjs)$' || true)
6
+ if [[ -z "${changed:-}" ]]; then
7
+ exit 0
8
+ fi
9
+ if [[ -f yarn.lock ]]; then
10
+ yarn -s prettier --write $changed 2>/dev/null || true
11
+ elif [[ -f pnpm-lock.yaml ]]; then
12
+ pnpm exec prettier --write $changed 2>/dev/null || true
13
+ elif [[ -f package-lock.json ]]; then
14
+ npx prettier --write $changed 2>/dev/null || true
15
+ fi
16
+ exit 0
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env bash
2
+ # Optional cookbook: block committing likely secrets in staged diffs.
3
+ # NOT wired in default hooks.json — copy to hooks/ and register manually.
4
+ set -euo pipefail
5
+ PATTERN='(AKIA[0-9A-Z]{16}|-----BEGIN (RSA |OPENSSH )?PRIVATE KEY-----|api[_-]?key\s*[:=]\s*['\''\"][^'\''\"]{12,})'
6
+ if git diff --cached -U0 2>/dev/null | grep -Eiq "$PATTERN"; then
7
+ echo "secret-guard: possible secret in staged diff — review before commit" >&2
8
+ exit 1
9
+ fi
10
+ exit 0
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env bash
2
+ # Optional: scoped unit tests after TypeScript edits.
3
+ # NOT in default hooks.json. Prefer repository test scripts (Vitest/Jest).
4
+ set -euo pipefail
5
+ changed=$(git diff --name-only --diff-filter=ACMR HEAD 2>/dev/null | grep -E '\.(ts|tsx)$' || true)
6
+ if [[ -z "${changed:-}" ]]; then
7
+ exit 0
8
+ fi
9
+ run_test() {
10
+ local pm="$1"
11
+ if $pm run -s test -- --runRelated "$changed" 2>/dev/null; then
12
+ return 0
13
+ fi
14
+ $pm run -s test 2>/dev/null || true
15
+ }
16
+ if [[ -f yarn.lock ]]; then
17
+ run_test yarn
18
+ elif [[ -f pnpm-lock.yaml ]]; then
19
+ run_test pnpm
20
+ elif [[ -f package-lock.json ]]; then
21
+ npm test --silent 2>/dev/null || true
22
+ elif [[ -f bun.lockb || -f bun.lock ]]; then
23
+ bun test 2>/dev/null || true
24
+ fi
25
+ exit 0
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env bash
2
+ # Lightweight shell guard for Cursor projects using this preset.
3
+ # TypeScript MCP: allow npm/npx/node/tsc/vitest/jest; package-manager mismatch checks when lockfile exists.
4
+ # Package-manager mismatch checks apply only when a JS lockfile/package.json exists.
5
+
6
+ set -euo pipefail
7
+
8
+ input=$(cat)
9
+
10
+ INPUT="$input" node <<'NODE'
11
+ const fs = require('fs');
12
+
13
+ const raw = process.env.INPUT || '';
14
+ let event;
15
+ try {
16
+ event = JSON.parse(raw);
17
+ } catch {
18
+ process.stdout.write('{ "permission": "allow" }');
19
+ process.exit(0);
20
+ }
21
+
22
+ const command = String(event.command || event.input?.command || '');
23
+ if (!command.trim()) {
24
+ process.stdout.write('{ "permission": "allow" }');
25
+ process.exit(0);
26
+ }
27
+
28
+ function out(permission, userMessage, agentMessage) {
29
+ process.stdout.write(JSON.stringify({
30
+ permission,
31
+ user_message: userMessage,
32
+ agent_message: agentMessage || userMessage,
33
+ }));
34
+ }
35
+
36
+ const dangerousGit = /\bgit\s+(reset\s+--hard|clean\s+-[^\n]*f|push\s+--force|push\s+-f|checkout\s+--\s+)/;
37
+ if (dangerousGit.test(command)) {
38
+ out(
39
+ 'ask',
40
+ 'This command looks destructive for git state. Review it before continuing.',
41
+ 'A project hook flagged a destructive git command. Ask the user before running it.',
42
+ );
43
+ process.exit(0);
44
+ }
45
+
46
+ const managerByFile = [
47
+ ['yarn.lock', 'yarn'],
48
+ ['pnpm-lock.yaml', 'pnpm'],
49
+ ['package-lock.json', 'npm'],
50
+ ].find(([file]) => fs.existsSync(file));
51
+
52
+ let expected = managerByFile?.[1];
53
+ if (!expected && fs.existsSync('package.json')) {
54
+ try {
55
+ const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
56
+ const pm = typeof pkg.packageManager === 'string' ? pkg.packageManager : '';
57
+ expected = pm.split('@')[0] || undefined;
58
+ } catch {
59
+ // Ignore invalid package.json in the hook; the agent can diagnose it later.
60
+ }
61
+ }
62
+
63
+ if (!expected) {
64
+ process.stdout.write('{ "permission": "allow" }');
65
+ process.exit(0);
66
+ }
67
+
68
+ const used = command.match(/(^|[;&|]\s*)(npm|yarn|pnpm)\s+/)?.[2];
69
+ if (used && used !== expected) {
70
+ out(
71
+ 'ask',
72
+ `This repository appears to use ${expected}, but the command uses ${used}. Confirm before continuing.`,
73
+ `Use ${expected} for package scripts and installs unless the user explicitly approves ${used}.`,
74
+ );
75
+ process.exit(0);
76
+ }
77
+
78
+ process.stdout.write('{ "permission": "allow" }');
79
+ NODE
@@ -0,0 +1,17 @@
1
+ {
2
+ "version": 1,
3
+ "hooks": {
4
+ "beforeShellExecution": [
5
+ {
6
+ "command": ".cursor/hooks/guard-shell-command.sh",
7
+ "failClosed": true
8
+ }
9
+ ],
10
+ "subagentStop": [
11
+ {
12
+ "command": ".cursor/hooks/chain-team-phases.sh",
13
+ "loop_limit": 15
14
+ }
15
+ ]
16
+ }
17
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "mcpServers": {
3
+ "context7": {
4
+ "command": "npx",
5
+ "args": [
6
+ "-y",
7
+ "@upstash/context7-mcp@3.2.5"
8
+ ]
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,52 @@
1
+ # Rules (preset mcp-ts)
2
+
3
+ ## alwaysApply (3)
4
+
5
+ | Rule | Role |
6
+ |------|------|
7
+ | `mcp-ts-app-core` | SDK boundary, layout, stdio-first |
8
+ | `mcp-server-boundaries` | Registration / handler / capability / lifecycle |
9
+ | `code-quality-and-refactoring` | Shared quality + TS MCP notes |
10
+
11
+ **Session-start body budget:** sum of the 3 always-on bodies ≤ **140** lines (stretch ≤120).
12
+
13
+ ## Twin depth (Cursor↔Claude)
14
+
15
+ - **Domain** rules: target ≥15 non-empty body lines.
16
+ - **Thin aliases** (may be shorter): `agent-team-intake`, `technical-retro`.
17
+
18
+ ## Loading strategy
19
+
20
+ - **`alwaysApply: true`** (Cursor) / **без `paths:`** (Claude) — только базовые инварианты (**3**)
21
+ - **On-demand / requestable** — MCP domain rules, tooling, security, tests, feature-delivery, agent-team, design-guidance, anti-sycophancy
22
+ - **Preset author meta** (globs `packages/ai-rules/presets/**`, never alwaysApply): five `preset-*` wrappers
23
+ - **Skills** — `feature-delivery`, `unit-testing`, `code-review`, `debug-investigation`
24
+
25
+ ### MCP edit bundles
26
+
27
+ | When editing | Load |
28
+ |--------------|------|
29
+ | `src/tools|resources|prompts/**` | `mcp-tool-design` + `mcp-server-boundaries` |
30
+ | schemas / contracts | `mcp-ts-conventions`, `mcp-contract-testing` |
31
+ | `src/index.ts`, package `bin` | `mcp-transport-packaging` |
32
+ | auth/config | `mcp-auth-secrets`, `security-mcp` |
33
+ | After `*.ts` edits | `post-change-test` (+ `mcp-ts-tooling`) |
34
+
35
+ ## Shared core → stack mapping
36
+
37
+ | Shared core | This stack adapter | Mode |
38
+ |-------------|--------------------|------|
39
+ | `quality/code-quality-and-refactoring.md` | `code-quality-and-refactoring.mdc` | embed |
40
+ | `quality/anti-sycophancy-discipline.md` | `anti-sycophancy-discipline.mdc` | embed |
41
+ | `quality/design-guidance.md` | `design-guidance.mdc` | embed |
42
+ | `agent-team/agent-team-orchestrator.md` | `agent-team-orchestrator.mdc` | lineage |
43
+ | `agent-team/agent-team-intake.md` | `agent-team-intake.mdc` | embed |
44
+ | `architecture/feature-delivery-workflow.md` | `feature-delivery-workflow.mdc` | lineage |
45
+ | `architecture/reference-features.template.md` | `reference-features.mdc` | lineage |
46
+ | `review/code-review-mr.md` | `code-review-mr.mdc` | embed |
47
+ | `review/technical-retro.md` | `technical-retro.mdc` | embed |
48
+ | `meta/preset-*` (five) | `preset-*.mdc` | embed |
49
+
50
+ ## Catalog
51
+
52
+ See Claude `rules/README.md` mapping table for the full Cursor→Claude stem list.
@@ -0,0 +1,21 @@
1
+ ---
2
+ description: Suggest /task for work requests without a slash command (mcp-ts)
3
+ alwaysApply: false
4
+ ---
5
+
6
+ <!-- shared-core: agent-team/agent-team-intake.md -->
7
+
8
+ # Agent team intake
9
+
10
+ When the user message looks like a **work request** (implement, add, fix, refactor, review MR, write tests, spike) — not a question about how code works:
11
+
12
+ 1. Prefer **`/task <their request>`** or invoke **task-router** first.
13
+ 2. Do not jump straight to coding without router + pipeline when scope is non-trivial.
14
+ 3. Pure questions («как работает X», «объясни») — prefer agent **`codebase-analyzer`** (explain-as-is); trivial one-liners may be answered inline. Do not open `/task`.
15
+
16
+ Exceptions: user explicitly says «без pipeline», «просто сделай», or continues an active slug.
17
+
18
+ ## Stack notes
19
+
20
+ - Scope: TypeScript MCP server modules (`src/tools|resources|prompts`, `src/index.ts`) — not Next `app/src`, iOS `Features/`, Go `cmd/`/`internal/**`, or Playwright/XCUITest UI flows.
21
+ - **Phase 1 override:** no `codebase-analyzer` agent. For explain-as-is («как работает X»), answer inline or load requestable MCP rules (`mcp-server-boundaries`, `mcp-tool-design`) — do **not** invoke a missing subagent.