@ai-sdlc/orchestrator 0.5.0 → 0.9.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 (227) hide show
  1. package/dist/action-enforcement.d.ts +26 -0
  2. package/dist/action-enforcement.js +70 -0
  3. package/dist/admission-composite.d.ts +67 -0
  4. package/dist/admission-composite.js +158 -0
  5. package/dist/admission-enrichment.d.ts +142 -0
  6. package/dist/admission-enrichment.js +331 -0
  7. package/dist/admission-hc.d.ts +62 -0
  8. package/dist/admission-hc.js +83 -0
  9. package/dist/admission-score.d.ts +148 -0
  10. package/dist/admission-score.js +237 -0
  11. package/dist/analysis/analyzer.js +3 -2
  12. package/dist/analysis/convention-detector.d.ts +85 -2
  13. package/dist/analysis/convention-detector.js +375 -70
  14. package/dist/analysis/diff-analyzer.d.ts +33 -0
  15. package/dist/analysis/diff-analyzer.js +122 -0
  16. package/dist/analysis/hotspot-analyzer.js +3 -1
  17. package/dist/analysis/index.d.ts +2 -1
  18. package/dist/analysis/index.js +2 -1
  19. package/dist/artifacts/index.d.ts +65 -0
  20. package/dist/artifacts/index.js +142 -0
  21. package/dist/backlog-adapter.d.ts +121 -0
  22. package/dist/backlog-adapter.js +438 -0
  23. package/dist/calibration.d.ts +43 -0
  24. package/dist/calibration.js +76 -0
  25. package/dist/cli/commands/agents.d.ts +24 -0
  26. package/dist/cli/commands/agents.js +66 -1
  27. package/dist/cli/commands/git-remote.d.ts +49 -0
  28. package/dist/cli/commands/git-remote.js +91 -0
  29. package/dist/cli/commands/health.d.ts +4 -0
  30. package/dist/cli/commands/health.js +13 -1
  31. package/dist/cli/commands/init.d.ts +26 -0
  32. package/dist/cli/commands/init.js +164 -22
  33. package/dist/cli/commands/mcp-setup.d.ts +31 -0
  34. package/dist/cli/commands/mcp-setup.js +78 -8
  35. package/dist/cli/formatters/table.js +15 -2
  36. package/dist/cli/index.d.ts +14 -1
  37. package/dist/cli/index.js +81 -20
  38. package/dist/cli/versions.d.ts +57 -0
  39. package/dist/cli/versions.js +128 -0
  40. package/dist/code-area-classifier.d.ts +21 -0
  41. package/dist/code-area-classifier.js +48 -0
  42. package/dist/config.d.ts +33 -1
  43. package/dist/config.js +78 -8
  44. package/dist/cycle-utils.d.ts +51 -0
  45. package/dist/cycle-utils.js +77 -0
  46. package/dist/database/adapters/external.d.ts +24 -0
  47. package/dist/database/adapters/external.js +80 -0
  48. package/dist/database/adapters/neon.d.ts +41 -0
  49. package/dist/database/adapters/neon.js +98 -0
  50. package/dist/database/adapters/pg-snapshot-restore.d.ts +28 -0
  51. package/dist/database/adapters/pg-snapshot-restore.js +68 -0
  52. package/dist/database/adapters/sqlite-copy.d.ts +32 -0
  53. package/dist/database/adapters/sqlite-copy.js +145 -0
  54. package/dist/database/connection-injection.d.ts +35 -0
  55. package/dist/database/connection-injection.js +93 -0
  56. package/dist/database/index.d.ts +12 -0
  57. package/dist/database/index.js +23 -0
  58. package/dist/database/registry.d.ts +13 -0
  59. package/dist/database/registry.js +27 -0
  60. package/dist/database/topology.d.ts +52 -0
  61. package/dist/database/topology.js +44 -0
  62. package/dist/database/types.d.ts +89 -0
  63. package/dist/database/types.js +26 -0
  64. package/dist/defaults.d.ts +5 -0
  65. package/dist/defaults.js +5 -0
  66. package/dist/design-authority.d.ts +40 -0
  67. package/dist/design-authority.js +71 -0
  68. package/dist/design-lookahead.d.ts +64 -0
  69. package/dist/design-lookahead.js +86 -0
  70. package/dist/design-quality-trend.d.ts +87 -0
  71. package/dist/design-quality-trend.js +190 -0
  72. package/dist/design-system-context.d.ts +46 -0
  73. package/dist/design-system-context.js +80 -0
  74. package/dist/design-system-correction-loop.d.ts +64 -0
  75. package/dist/design-system-correction-loop.js +128 -0
  76. package/dist/design-system-metrics.d.ts +61 -0
  77. package/dist/design-system-metrics.js +104 -0
  78. package/dist/design-system-stewardship.d.ts +22 -0
  79. package/dist/design-system-stewardship.js +85 -0
  80. package/dist/design-system-validation.d.ts +37 -0
  81. package/dist/design-system-validation.js +88 -0
  82. package/dist/dispatch/index.d.ts +4 -0
  83. package/dist/dispatch/index.js +4 -0
  84. package/dist/dispatch/merge-gate.d.ts +46 -0
  85. package/dist/dispatch/merge-gate.js +90 -0
  86. package/dist/dispatch/requeue.d.ts +57 -0
  87. package/dist/dispatch/requeue.js +131 -0
  88. package/dist/dispatch/worker-pool.d.ts +62 -0
  89. package/dist/dispatch/worker-pool.js +60 -0
  90. package/dist/execute.d.ts +40 -0
  91. package/dist/execute.js +295 -30
  92. package/dist/fix-ci.js +40 -3
  93. package/dist/fix-review.d.ts +66 -0
  94. package/dist/fix-review.js +448 -0
  95. package/dist/harness/adapters/claude-code.d.ts +29 -0
  96. package/dist/harness/adapters/claude-code.js +191 -0
  97. package/dist/harness/adapters/codex.d.ts +25 -0
  98. package/dist/harness/adapters/codex.js +61 -0
  99. package/dist/harness/independence.d.ts +51 -0
  100. package/dist/harness/independence.js +67 -0
  101. package/dist/harness/index.d.ts +14 -0
  102. package/dist/harness/index.js +20 -0
  103. package/dist/harness/registry.d.ts +17 -0
  104. package/dist/harness/registry.js +31 -0
  105. package/dist/harness/types.d.ts +123 -0
  106. package/dist/harness/types.js +8 -0
  107. package/dist/harness/version-probe.d.ts +14 -0
  108. package/dist/harness/version-probe.js +123 -0
  109. package/dist/index.d.ts +39 -5
  110. package/dist/index.js +48 -3
  111. package/dist/models/classifier.d.ts +76 -0
  112. package/dist/models/classifier.js +221 -0
  113. package/dist/models/index.d.ts +3 -0
  114. package/dist/models/index.js +3 -0
  115. package/dist/models/registry.d.ts +97 -0
  116. package/dist/models/registry.js +173 -0
  117. package/dist/pillar-breakdown.d.ts +63 -0
  118. package/dist/pillar-breakdown.js +153 -0
  119. package/dist/pipeline-cycle-detector.d.ts +70 -0
  120. package/dist/pipeline-cycle-detector.js +111 -0
  121. package/dist/priority.d.ts +7 -76
  122. package/dist/priority.js +18 -5
  123. package/dist/review-meta.d.ts +65 -0
  124. package/dist/review-meta.js +149 -0
  125. package/dist/review.d.ts +35 -0
  126. package/dist/review.js +84 -0
  127. package/dist/runners/claude-code-sdk.d.ts +31 -0
  128. package/dist/runners/claude-code-sdk.js +238 -0
  129. package/dist/runners/claude-code.d.ts +3 -0
  130. package/dist/runners/claude-code.js +319 -73
  131. package/dist/runners/codex.js +4 -1
  132. package/dist/runners/copilot.js +4 -1
  133. package/dist/runners/cursor.js +4 -1
  134. package/dist/runners/git-utils.d.ts +81 -0
  135. package/dist/runners/git-utils.js +201 -0
  136. package/dist/runners/index.d.ts +5 -1
  137. package/dist/runners/index.js +4 -0
  138. package/dist/runners/review-agent.d.ts +67 -0
  139. package/dist/runners/review-agent.js +350 -0
  140. package/dist/runners/runner-registry.js +10 -0
  141. package/dist/runners/sdk-review-runner.d.ts +65 -0
  142. package/dist/runners/sdk-review-runner.js +185 -0
  143. package/dist/runners/security-triage.d.ts +20 -4
  144. package/dist/runners/security-triage.js +42 -14
  145. package/dist/runners/types.d.ts +25 -0
  146. package/dist/runtime/attestations.d.ts +274 -0
  147. package/dist/runtime/attestations.js +460 -0
  148. package/dist/runtime/git-env.d.ts +53 -0
  149. package/dist/runtime/git-env.js +60 -0
  150. package/dist/runtime/index.d.ts +7 -0
  151. package/dist/runtime/index.js +7 -0
  152. package/dist/runtime/parallelism-flag.d.ts +10 -0
  153. package/dist/runtime/parallelism-flag.js +18 -0
  154. package/dist/runtime/port-allocator.d.ts +21 -0
  155. package/dist/runtime/port-allocator.js +66 -0
  156. package/dist/runtime/worktree-pool.d.ts +86 -0
  157. package/dist/runtime/worktree-pool.js +204 -0
  158. package/dist/runtime/worktree.d.ts +25 -0
  159. package/dist/runtime/worktree.js +111 -0
  160. package/dist/sa-scoring/auto-calibrate.d.ts +69 -0
  161. package/dist/sa-scoring/auto-calibrate.js +107 -0
  162. package/dist/sa-scoring/c1-sa2-computable.d.ts +42 -0
  163. package/dist/sa-scoring/c1-sa2-computable.js +59 -0
  164. package/dist/sa-scoring/composite.d.ts +107 -0
  165. package/dist/sa-scoring/composite.js +139 -0
  166. package/dist/sa-scoring/depparse-client.d.ts +79 -0
  167. package/dist/sa-scoring/depparse-client.js +187 -0
  168. package/dist/sa-scoring/did-compiler.d.ts +122 -0
  169. package/dist/sa-scoring/did-compiler.js +286 -0
  170. package/dist/sa-scoring/drift-monitor.d.ts +84 -0
  171. package/dist/sa-scoring/drift-monitor.js +186 -0
  172. package/dist/sa-scoring/exemplar-bank.d.ts +78 -0
  173. package/dist/sa-scoring/exemplar-bank.js +154 -0
  174. package/dist/sa-scoring/feedback-store.d.ts +100 -0
  175. package/dist/sa-scoring/feedback-store.js +156 -0
  176. package/dist/sa-scoring/index.d.ts +71 -0
  177. package/dist/sa-scoring/index.js +158 -0
  178. package/dist/sa-scoring/layer1-deterministic.d.ts +115 -0
  179. package/dist/sa-scoring/layer1-deterministic.js +298 -0
  180. package/dist/sa-scoring/layer2-structural.d.ts +71 -0
  181. package/dist/sa-scoring/layer2-structural.js +151 -0
  182. package/dist/sa-scoring/layer3-llm.d.ts +86 -0
  183. package/dist/sa-scoring/layer3-llm.js +282 -0
  184. package/dist/sa-scoring/rescore-orchestrator.d.ts +52 -0
  185. package/dist/sa-scoring/rescore-orchestrator.js +47 -0
  186. package/dist/scheduling/burn-down.d.ts +27 -0
  187. package/dist/scheduling/burn-down.js +43 -0
  188. package/dist/scheduling/calibration.d.ts +42 -0
  189. package/dist/scheduling/calibration.js +150 -0
  190. package/dist/scheduling/index.d.ts +8 -0
  191. package/dist/scheduling/index.js +8 -0
  192. package/dist/scheduling/ledger.d.ts +59 -0
  193. package/dist/scheduling/ledger.js +216 -0
  194. package/dist/scheduling/off-peak.d.ts +27 -0
  195. package/dist/scheduling/off-peak.js +112 -0
  196. package/dist/scheduling/schedule-decision.d.ts +39 -0
  197. package/dist/scheduling/schedule-decision.js +89 -0
  198. package/dist/scheduling/tier-analysis.d.ts +47 -0
  199. package/dist/scheduling/tier-analysis.js +81 -0
  200. package/dist/scheduling/types.d.ts +140 -0
  201. package/dist/scheduling/types.js +11 -0
  202. package/dist/shared.d.ts +13 -0
  203. package/dist/shared.js +32 -0
  204. package/dist/state/index.d.ts +1 -1
  205. package/dist/state/schema.d.ts +6 -1
  206. package/dist/state/schema.js +276 -1
  207. package/dist/state/store.d.ts +71 -1
  208. package/dist/state/store.js +464 -7
  209. package/dist/state/types.d.ts +174 -0
  210. package/dist/types.d.ts +1 -1
  211. package/dist/validate-agent-output.js +4 -1
  212. package/dist/watch.js +6 -0
  213. package/dist/workflow-patterns/artifact-writer.d.ts +16 -0
  214. package/dist/workflow-patterns/artifact-writer.js +34 -0
  215. package/dist/workflow-patterns/classifiers.d.ts +10 -0
  216. package/dist/workflow-patterns/classifiers.js +72 -0
  217. package/dist/workflow-patterns/detector.d.ts +27 -0
  218. package/dist/workflow-patterns/detector.js +186 -0
  219. package/dist/workflow-patterns/index.d.ts +8 -0
  220. package/dist/workflow-patterns/index.js +7 -0
  221. package/dist/workflow-patterns/proposal-generator.d.ts +15 -0
  222. package/dist/workflow-patterns/proposal-generator.js +183 -0
  223. package/dist/workflow-patterns/telemetry-ingest.d.ts +27 -0
  224. package/dist/workflow-patterns/telemetry-ingest.js +103 -0
  225. package/dist/workflow-patterns/types.d.ts +61 -0
  226. package/dist/workflow-patterns/types.js +11 -0
  227. package/package.json +2 -2
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Issue admission scoring — maps GitHub issue fields to PPA dimensions
3
+ * and determines whether an issue should enter the pipeline.
4
+ *
5
+ * Extracted from dogfood/scripts/ppa-score.ts for reuse across CLI
6
+ * scripts and workflows.
7
+ */
8
+ import { computeAdmissionComposite } from './admission-composite.js';
9
+ import { computePillarBreakdown } from './pillar-breakdown.js';
10
+ // ── Mapping ──────────────────────────────────────────────────────────
11
+ /**
12
+ * Map GitHub issue fields to PPA PriorityInput dimensions.
13
+ *
14
+ * Heuristics (ported from dogfood/scripts/ppa-score.ts):
15
+ * - Labels → bug severity, soul alignment hints, builder conviction
16
+ * - Reactions → team consensus, customer request count
17
+ * - Comments → demand signal
18
+ * - Body complexity section → complexity score
19
+ * - Issue age → competitive drift
20
+ */
21
+ export function mapIssueToPriorityInput(input) {
22
+ const labels = input.labels;
23
+ const assoc = input.authorAssociation ?? 'NONE';
24
+ const backlog = input.backlogContext;
25
+ // ── Backlog status veto ─────────────────────────────────────
26
+ // Drafts aren't ready to admit; orchestrator should ignore them.
27
+ if (backlog?.status === 'Draft') {
28
+ return {
29
+ itemId: `#${input.issueNumber}`,
30
+ title: input.title,
31
+ description: input.body ?? '',
32
+ labels,
33
+ soulAlignment: 0,
34
+ };
35
+ }
36
+ // ── Trust-based signal boosting ────────────────────────────────
37
+ // Trusted sources (project team) get baseline conviction and demand.
38
+ // Untrusted sources need external validation (reactions, comments).
39
+ const isTrusted = assoc === 'OWNER' || assoc === 'MEMBER' || assoc === 'COLLABORATOR';
40
+ const isContributor = assoc === 'CONTRIBUTOR';
41
+ // ── Complexity from issue body, AC count, or backlog context ─
42
+ const complexityMatch = input.body?.match(/###?\s*Complexity\s*\n+\s*(\d+)/i);
43
+ let complexity = complexityMatch ? Number(complexityMatch[1]) : undefined;
44
+ // Backlog tasks rarely include a `### Complexity` header — fall back to AC count
45
+ // (each AC is roughly one logical unit; clamp at 10).
46
+ if (complexity === undefined && backlog?.acceptanceCriteriaCount !== undefined) {
47
+ complexity = Math.min(10, Math.max(1, Math.ceil(backlog.acceptanceCriteriaCount * 1.2)));
48
+ }
49
+ // ── Bug severity from labels ─────────────────────────────────
50
+ let bugSeverity;
51
+ if (labels.includes('critical') || labels.includes('P0'))
52
+ bugSeverity = 5;
53
+ else if (labels.includes('bug'))
54
+ bugSeverity = 3;
55
+ // ── Soul alignment heuristic from labels ─────────────────────
56
+ let soulAlignment = 0.5;
57
+ if (labels.includes('security') || labels.includes('security-triage'))
58
+ soulAlignment = 0.7;
59
+ if (labels.includes('enhancement'))
60
+ soulAlignment = 0.6;
61
+ if (labels.includes('governance') || labels.includes('compliance'))
62
+ soulAlignment = 0.85;
63
+ if (labels.includes('spec') || labels.includes('rfc'))
64
+ soulAlignment = 0.9;
65
+ // Backlog-specific labels — RFC process work directly serves project mission;
66
+ // tech-debt is operationally important but not mission-defining.
67
+ if (labels.includes('rfc-process') || labels.includes('architecture'))
68
+ soulAlignment = 0.85;
69
+ if (labels.includes('tech-debt') && soulAlignment < 0.55)
70
+ soulAlignment = 0.55;
71
+ // Trusted authors get a soul alignment floor — they know the project mission
72
+ if (isTrusted && soulAlignment < 0.6)
73
+ soulAlignment = 0.6;
74
+ // ── Reactions → demand / consensus ───────────────────────────
75
+ const reactionConsensus = Math.min(1, input.reactionCount / 5);
76
+ // Trusted sources carry implicit team consensus
77
+ const teamConsensus = isTrusted ? Math.max(0.5, reactionConsensus) : reactionConsensus;
78
+ // ── Comment count → demand signal ────────────────────────────
79
+ const commentDemand = Math.min(1, input.commentCount / 5);
80
+ // Trusted sources filing an issue IS demand — they wouldn't file it otherwise
81
+ const demandSignal = isTrusted
82
+ ? Math.max(0.4, commentDemand)
83
+ : isContributor
84
+ ? Math.max(0.2, commentDemand)
85
+ : commentDemand;
86
+ // ── Builder conviction ─────────────────────────────────────────
87
+ // Trusted: high conviction (they're the builders)
88
+ // Contributor: moderate (proven track record)
89
+ // ai-eligible label: explicit signal
90
+ // Default: low (needs validation)
91
+ let builderConviction = labels.includes('ai-eligible')
92
+ ? 0.8
93
+ : isTrusted
94
+ ? 0.8
95
+ : isContributor
96
+ ? 0.6
97
+ : 0.4;
98
+ // Backlog tasks blocked by other work get a conviction penalty — the team
99
+ // can't confidently dispatch them until upstream lands.
100
+ if (backlog?.dependencyCount && backlog.dependencyCount > 0) {
101
+ builderConviction = Math.max(0.2, builderConviction - 0.3);
102
+ }
103
+ // ── Age → competitive drift ──────────────────────────────────
104
+ const ageMs = Date.now() - new Date(input.createdAt).getTime();
105
+ const ageDays = ageMs / (1000 * 60 * 60 * 24);
106
+ const competitiveDrift = Math.min(1, Math.max(0, (ageDays - 30) / 180));
107
+ // ── Security-rejected veto ───────────────────────────────────
108
+ if (labels.includes('security-rejected')) {
109
+ return {
110
+ itemId: `#${input.issueNumber}`,
111
+ title: input.title,
112
+ description: input.body ?? '',
113
+ labels,
114
+ soulAlignment: 0, // veto
115
+ };
116
+ }
117
+ // ── Explicit priority — labels first, then backlog frontmatter ──
118
+ let explicitPriority;
119
+ if (labels.includes('high'))
120
+ explicitPriority = 0.8;
121
+ else if (labels.includes('low'))
122
+ explicitPriority = 0.2;
123
+ else if (backlog?.priority) {
124
+ explicitPriority = mapBacklogPriorityToScalar(backlog.priority);
125
+ }
126
+ return {
127
+ itemId: `#${input.issueNumber}`,
128
+ title: input.title,
129
+ description: input.body ?? '',
130
+ labels,
131
+ soulAlignment,
132
+ bugSeverity,
133
+ customerRequestCount: input.reactionCount,
134
+ demandSignal,
135
+ builderConviction,
136
+ complexity,
137
+ competitiveDrift,
138
+ teamConsensus,
139
+ explicitPriority,
140
+ };
141
+ }
142
+ /** Map backlog frontmatter priority string to a scalar in [0,1]. */
143
+ function mapBacklogPriorityToScalar(p) {
144
+ switch (p) {
145
+ case 'critical':
146
+ return 1.0;
147
+ case 'high':
148
+ return 0.8;
149
+ case 'medium':
150
+ return 0.5;
151
+ case 'low':
152
+ return 0.2;
153
+ default:
154
+ return 0.5;
155
+ }
156
+ }
157
+ // ── Suggestions ──────────────────────────────────────────────────────
158
+ function generateSuggestions(input, score) {
159
+ const suggestions = [];
160
+ const d = score.dimensions;
161
+ if (score.confidence < 0.2) {
162
+ suggestions.push('Add more detail to improve scoring confidence (complexity, acceptance criteria, labels)');
163
+ }
164
+ if (!input.body?.match(/###?\s*Complexity\s*\n/i)) {
165
+ suggestions.push('Add a `### Complexity` section with a score from 1-10');
166
+ }
167
+ if (!input.body?.match(/###?\s*Acceptance Criteria/i)) {
168
+ suggestions.push('Add an `### Acceptance Criteria` section with testable criteria');
169
+ }
170
+ if (input.body.length < 50) {
171
+ suggestions.push('Provide a more detailed description of the problem or feature');
172
+ }
173
+ const assoc = input.authorAssociation ?? 'NONE';
174
+ const isTrusted = assoc === 'OWNER' || assoc === 'MEMBER' || assoc === 'COLLABORATOR';
175
+ if (d.demandPressure < 0.3 && !isTrusted) {
176
+ suggestions.push('Low demand signal — add reactions or comments to show interest');
177
+ }
178
+ if (d.soulAlignment < 0.5) {
179
+ suggestions.push('Add labels that indicate alignment with the project mission (e.g., governance, spec, security)');
180
+ }
181
+ return suggestions;
182
+ }
183
+ // ── Public API ───────────────────────────────────────────────────────
184
+ /**
185
+ * Score a GitHub issue for pipeline admission using the RFC-0008 §A.6
186
+ * admission-subset composite.
187
+ *
188
+ * P_admission = SA × D-pi_adjusted × ER × (1 + HC)
189
+ *
190
+ * M-phi, E-tau, C-kappa are deferred to runtime scoring — they apply
191
+ * when an admitted issue is picked up for execution, not at the gate.
192
+ *
193
+ * Returns whether the issue is admitted (score and confidence above
194
+ * thresholds) along with the full score and, if rejected, suggestions
195
+ * for improvement.
196
+ */
197
+ export function scoreIssueForAdmission(input, thresholds, priorityConfig, options) {
198
+ const composite = computeAdmissionComposite(input, priorityConfig, options);
199
+ const { score } = composite;
200
+ const pillarBreakdown = computePillarBreakdown(composite);
201
+ const scorePasses = score.composite >= thresholds.minimumScore;
202
+ const confidencePasses = score.confidence >= thresholds.minimumConfidence;
203
+ const admitted = scorePasses && confidencePasses;
204
+ if (admitted) {
205
+ return {
206
+ admitted: true,
207
+ score,
208
+ reason: `Score ${score.composite.toFixed(4)} meets threshold ${thresholds.minimumScore} with ${(score.confidence * 100).toFixed(0)}% confidence`,
209
+ pillarBreakdown,
210
+ };
211
+ }
212
+ const reasons = [];
213
+ if (!scorePasses) {
214
+ reasons.push(`score ${score.composite.toFixed(4)} below minimum ${thresholds.minimumScore}`);
215
+ }
216
+ if (!confidencePasses) {
217
+ reasons.push(`confidence ${(score.confidence * 100).toFixed(0)}% below minimum ${(thresholds.minimumConfidence * 100).toFixed(0)}%`);
218
+ }
219
+ return {
220
+ admitted: false,
221
+ score,
222
+ reason: `Not admitted: ${reasons.join('; ')}`,
223
+ suggestions: generateSuggestions(input, score),
224
+ pillarBreakdown,
225
+ };
226
+ }
227
+ /** Map backlog frontmatter priority string to the typed BacklogContext shape. */
228
+ export function normalizeBacklogPriority(p) {
229
+ if (!p)
230
+ return undefined;
231
+ const lower = p.toLowerCase().trim();
232
+ if (lower === 'critical' || lower === 'high' || lower === 'medium' || lower === 'low') {
233
+ return lower;
234
+ }
235
+ return undefined;
236
+ }
237
+ //# sourceMappingURL=admission-score.js.map
@@ -30,8 +30,9 @@ export async function analyzeCodebase(options) {
30
30
  const moduleGraph = await buildModuleGraph(files, modules, options.repoPath);
31
31
  // Step 5: Detect architectural patterns
32
32
  const architecturalPatterns = detectPatterns(files, modules);
33
- // Step 6: Detect conventions
34
- const conventions = detectConventions(files);
33
+ // Step 6: Detect conventions (project-config-aware: package.json, vite.config.*,
34
+ // tsconfig.json, jsconfig.json, webpack.config.* — see AISDLC-80).
35
+ const conventions = await detectConventions(files, { repoPath: options.repoPath });
35
36
  // Step 7: Analyze hotspots
36
37
  const hotspots = await analyzeHotspots(options.repoPath, files, importsByFile, {
37
38
  historyDays,
@@ -1,9 +1,92 @@
1
1
  /**
2
2
  * Detect coding conventions: naming style, test organization, import style.
3
+ *
4
+ * The detector accepts an optional `repoPath` so it can read project-level
5
+ * configuration (`package.json`, `vite.config.{js,ts}`, `tsconfig.json`,
6
+ * `jsconfig.json`, `webpack.config.*`) to interpret the file list more
7
+ * accurately. When `repoPath` is omitted the detector falls back to a pure
8
+ * file-name analysis (the original v1 behaviour).
9
+ *
10
+ * Three classes of false-positives motivated the project-config plumbing
11
+ * (AISDLC-80):
12
+ *
13
+ * 1. React projects mix PascalCase (components) with camelCase (hooks/stores
14
+ * and plain modules) — the v1 detector flagged this as `mixed`. With
15
+ * `package.json` `dependencies.react` visible we treat the dual-pattern
16
+ * case as the expected React convention.
17
+ * 2. Many repos host tests in multiple directories (`tests/`, `tests/e2e/`,
18
+ * `src/tests/`, `cypress/`, ...) plus collocated `*.test.*`. The v1
19
+ * detector picked one bucket and called it `mixed` when the proportions
20
+ * were close. We now enumerate the FULL set of locations.
21
+ * 3. Vite / TS / webpack path aliases (`@components`, `@engine`, ...) were
22
+ * classified as external imports because the v1 detector never read the
23
+ * alias maps. We now parse the alias map from each known config file and
24
+ * report alias usage as its own bucket.
3
25
  */
4
26
  import type { FileInfo, DetectedConvention } from './types.js';
5
27
  /**
6
- * Detect coding conventions from the file list.
28
+ * Each entry describes ONE place tests live in the repo. We enumerate ALL of
29
+ * them rather than flatten to a single label — a repo with `tests/`,
30
+ * `tests/e2e/`, `src/tests/` and a few collocated `*.test.*` files is reported
31
+ * with all four buckets visible (AISDLC-80).
7
32
  */
8
- export declare function detectConventions(files: FileInfo[]): DetectedConvention[];
33
+ export interface TestLocationSummary {
34
+ /** Stable label for the bucket (e.g. `__tests__/`, `tests/e2e/`, `co-located`). */
35
+ label: string;
36
+ /** Number of test files matched against this bucket. */
37
+ count: number;
38
+ /** Up to three example file paths from this bucket. */
39
+ examples: string[];
40
+ }
41
+ /**
42
+ * Classify every test file found into ALL the locations it actually lives,
43
+ * preserving the multi-directory reality of real projects. Returns the
44
+ * complete set sorted by file count (descending) with examples for each.
45
+ */
46
+ export declare function enumerateTestLocations(files: FileInfo[]): TestLocationSummary[];
47
+ /** Map of alias prefix (e.g. `@components`) → resolved target glob. */
48
+ export type PathAliasMap = Record<string, string>;
49
+ /**
50
+ * Parse `compilerOptions.paths` from a `tsconfig.json` / `jsconfig.json`.
51
+ * The TS config format maps `"@components/*": ["src/components/*"]` — we
52
+ * normalise to `@components` → `src/components/*`.
53
+ */
54
+ export declare function parseTsConfigAliases(content: string): PathAliasMap;
55
+ /**
56
+ * Extract `resolve.alias` (object literal form) from a Vite or webpack config
57
+ * file. We use a regex rather than a full JS parser because the contents are
58
+ * config files written in a small, well-known shape — the v1 detector's
59
+ * "regex over AST" tradeoff carries forward.
60
+ *
61
+ * Recognises both:
62
+ * resolve: { alias: { '@components': path.resolve(__dirname, 'src/components') } }
63
+ * alias: { '@engine': '/abs/path' }
64
+ */
65
+ export declare function parseViteOrWebpackAliases(content: string): PathAliasMap;
66
+ /**
67
+ * Read every alias source we know about and merge into a single map. Sources
68
+ * are read in parallel; later sources take precedence if there is overlap.
69
+ */
70
+ export declare function loadProjectAliases(repoPath: string): Promise<PathAliasMap>;
71
+ /**
72
+ * Read `package.json` and decide whether this is a React project. Looks at
73
+ * `dependencies` AND `devDependencies` because Vite-driven SPAs sometimes
74
+ * declare React as a dev dep via templates.
75
+ */
76
+ export declare function detectReactProject(repoPath: string): Promise<boolean>;
77
+ export interface DetectConventionsOptions {
78
+ /**
79
+ * Absolute path to the repo root. When provided the detector reads project
80
+ * configs (`package.json`, vite/tsconfig/jsconfig/webpack) for context-aware
81
+ * decisions. Without it the detector falls back to pure file-name analysis.
82
+ */
83
+ repoPath?: string;
84
+ }
85
+ /**
86
+ * Detect coding conventions from the file list. When `options.repoPath` is
87
+ * supplied the detector additionally reads project-level configuration to
88
+ * suppress the three classes of false-positives described at the top of this
89
+ * file (AISDLC-80).
90
+ */
91
+ export declare function detectConventions(files: FileInfo[], options?: DetectConventionsOptions): Promise<DetectedConvention[]>;
9
92
  //# sourceMappingURL=convention-detector.d.ts.map