@triedotdev/mcp 1.0.168 → 1.0.170

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 (149) hide show
  1. package/README.md +54 -500
  2. package/dist/chunk-2YXOBNKW.js +619 -0
  3. package/dist/chunk-2YXOBNKW.js.map +1 -0
  4. package/dist/chunk-QR64Y5TI.js +363 -0
  5. package/dist/chunk-QR64Y5TI.js.map +1 -0
  6. package/dist/cli/main.d.ts +0 -15
  7. package/dist/cli/main.js +356 -3100
  8. package/dist/cli/main.js.map +1 -1
  9. package/dist/index.js +2 -36
  10. package/dist/index.js.map +1 -1
  11. package/dist/server/mcp-server.js +2 -36
  12. package/package.json +8 -31
  13. package/dist/autonomy-config-FSERX3O3.js +0 -30
  14. package/dist/autonomy-config-FSERX3O3.js.map +0 -1
  15. package/dist/chat-store-JNGNTDSN.js +0 -15
  16. package/dist/chat-store-JNGNTDSN.js.map +0 -1
  17. package/dist/chunk-2HF65EHQ.js +0 -311
  18. package/dist/chunk-2HF65EHQ.js.map +0 -1
  19. package/dist/chunk-43X6JBEM.js +0 -36
  20. package/dist/chunk-43X6JBEM.js.map +0 -1
  21. package/dist/chunk-4MXH2ZPT.js +0 -1827
  22. package/dist/chunk-4MXH2ZPT.js.map +0 -1
  23. package/dist/chunk-575YT2SD.js +0 -737
  24. package/dist/chunk-575YT2SD.js.map +0 -1
  25. package/dist/chunk-5BRRRTN6.js +0 -354
  26. package/dist/chunk-5BRRRTN6.js.map +0 -1
  27. package/dist/chunk-6NLHFIYA.js +0 -344
  28. package/dist/chunk-6NLHFIYA.js.map +0 -1
  29. package/dist/chunk-7WITSO22.js +0 -824
  30. package/dist/chunk-7WITSO22.js.map +0 -1
  31. package/dist/chunk-DGUM43GV.js +0 -11
  32. package/dist/chunk-DGUM43GV.js.map +0 -1
  33. package/dist/chunk-EFWVF6TI.js +0 -267
  34. package/dist/chunk-EFWVF6TI.js.map +0 -1
  35. package/dist/chunk-F6WFNUAY.js +0 -216
  36. package/dist/chunk-F6WFNUAY.js.map +0 -1
  37. package/dist/chunk-FQ45QP5A.js +0 -361
  38. package/dist/chunk-FQ45QP5A.js.map +0 -1
  39. package/dist/chunk-G2TGF6TR.js +0 -573
  40. package/dist/chunk-G2TGF6TR.js.map +0 -1
  41. package/dist/chunk-GTKYBOXL.js +0 -700
  42. package/dist/chunk-GTKYBOXL.js.map +0 -1
  43. package/dist/chunk-HVCDY3AK.js +0 -850
  44. package/dist/chunk-HVCDY3AK.js.map +0 -1
  45. package/dist/chunk-JVMBCWKS.js +0 -348
  46. package/dist/chunk-JVMBCWKS.js.map +0 -1
  47. package/dist/chunk-KDHN2ZQE.js +0 -313
  48. package/dist/chunk-KDHN2ZQE.js.map +0 -1
  49. package/dist/chunk-LQIMKE3P.js +0 -12524
  50. package/dist/chunk-LQIMKE3P.js.map +0 -1
  51. package/dist/chunk-ME2OERF5.js +0 -345
  52. package/dist/chunk-ME2OERF5.js.map +0 -1
  53. package/dist/chunk-MRHKX5M5.js +0 -662
  54. package/dist/chunk-MRHKX5M5.js.map +0 -1
  55. package/dist/chunk-OBQ74FOU.js +0 -27
  56. package/dist/chunk-OBQ74FOU.js.map +0 -1
  57. package/dist/chunk-OMR4YCBS.js +0 -987
  58. package/dist/chunk-OMR4YCBS.js.map +0 -1
  59. package/dist/chunk-Q5EKA5YA.js +0 -254
  60. package/dist/chunk-Q5EKA5YA.js.map +0 -1
  61. package/dist/chunk-Q63FFI6D.js +0 -132
  62. package/dist/chunk-Q63FFI6D.js.map +0 -1
  63. package/dist/chunk-SY6KQG44.js +0 -983
  64. package/dist/chunk-SY6KQG44.js.map +0 -1
  65. package/dist/chunk-T63OHG4Q.js +0 -440
  66. package/dist/chunk-T63OHG4Q.js.map +0 -1
  67. package/dist/chunk-TN5WEKWI.js +0 -173
  68. package/dist/chunk-TN5WEKWI.js.map +0 -1
  69. package/dist/chunk-VUL52BQL.js +0 -402
  70. package/dist/chunk-VUL52BQL.js.map +0 -1
  71. package/dist/chunk-VVITXIHN.js +0 -189
  72. package/dist/chunk-VVITXIHN.js.map +0 -1
  73. package/dist/chunk-WCN7S3EI.js +0 -14
  74. package/dist/chunk-WCN7S3EI.js.map +0 -1
  75. package/dist/chunk-XE6KQRKZ.js +0 -816
  76. package/dist/chunk-XE6KQRKZ.js.map +0 -1
  77. package/dist/chunk-XPZZFPBZ.js +0 -491
  78. package/dist/chunk-XPZZFPBZ.js.map +0 -1
  79. package/dist/chunk-XTFWT2XM.js +0 -727
  80. package/dist/chunk-XTFWT2XM.js.map +0 -1
  81. package/dist/chunk-YDHUCDHM.js +0 -4011
  82. package/dist/chunk-YDHUCDHM.js.map +0 -1
  83. package/dist/chunk-YZ6Y2H3P.js +0 -1289
  84. package/dist/chunk-YZ6Y2H3P.js.map +0 -1
  85. package/dist/chunk-ZJF5FTBX.js +0 -1396
  86. package/dist/chunk-ZJF5FTBX.js.map +0 -1
  87. package/dist/chunk-ZV2K6M7T.js +0 -74
  88. package/dist/chunk-ZV2K6M7T.js.map +0 -1
  89. package/dist/cli/create-agent.d.ts +0 -1
  90. package/dist/cli/create-agent.js +0 -1050
  91. package/dist/cli/create-agent.js.map +0 -1
  92. package/dist/cli/yolo-daemon.d.ts +0 -1
  93. package/dist/cli/yolo-daemon.js +0 -423
  94. package/dist/cli/yolo-daemon.js.map +0 -1
  95. package/dist/client-NJPZE5JT.js +0 -28
  96. package/dist/client-NJPZE5JT.js.map +0 -1
  97. package/dist/codebase-index-VAPF32XX.js +0 -12
  98. package/dist/codebase-index-VAPF32XX.js.map +0 -1
  99. package/dist/fast-analyzer-XXYMOXRK.js +0 -216
  100. package/dist/fast-analyzer-XXYMOXRK.js.map +0 -1
  101. package/dist/git-EO5SRFMN.js +0 -28
  102. package/dist/git-EO5SRFMN.js.map +0 -1
  103. package/dist/github-ingester-ZOKK6GRS.js +0 -11
  104. package/dist/github-ingester-ZOKK6GRS.js.map +0 -1
  105. package/dist/goal-manager-YOB7VWK7.js +0 -25
  106. package/dist/goal-manager-YOB7VWK7.js.map +0 -1
  107. package/dist/goal-validator-ULKIBDPX.js +0 -24
  108. package/dist/goal-validator-ULKIBDPX.js.map +0 -1
  109. package/dist/graph-B3NA4S7I.js +0 -10
  110. package/dist/graph-B3NA4S7I.js.map +0 -1
  111. package/dist/hypothesis-7BFFT5JY.js +0 -23
  112. package/dist/hypothesis-7BFFT5JY.js.map +0 -1
  113. package/dist/incident-index-EFNUSGWL.js +0 -11
  114. package/dist/incident-index-EFNUSGWL.js.map +0 -1
  115. package/dist/insight-store-EC4PLSAW.js +0 -22
  116. package/dist/insight-store-EC4PLSAW.js.map +0 -1
  117. package/dist/issue-store-ZIRP23EP.js +0 -36
  118. package/dist/issue-store-ZIRP23EP.js.map +0 -1
  119. package/dist/ledger-TWZTGDFA.js +0 -58
  120. package/dist/ledger-TWZTGDFA.js.map +0 -1
  121. package/dist/linear-ingester-XXPAZZRW.js +0 -11
  122. package/dist/linear-ingester-XXPAZZRW.js.map +0 -1
  123. package/dist/output-manager-RVJ37XKA.js +0 -13
  124. package/dist/output-manager-RVJ37XKA.js.map +0 -1
  125. package/dist/parse-goal-violation-SACGFG3C.js +0 -8
  126. package/dist/parse-goal-violation-SACGFG3C.js.map +0 -1
  127. package/dist/pattern-discovery-F7LU5K6E.js +0 -8
  128. package/dist/pattern-discovery-F7LU5K6E.js.map +0 -1
  129. package/dist/progress-SRQ2V3BP.js +0 -18
  130. package/dist/progress-SRQ2V3BP.js.map +0 -1
  131. package/dist/project-state-AHPA77SM.js +0 -28
  132. package/dist/project-state-AHPA77SM.js.map +0 -1
  133. package/dist/sync-M2FSWPBC.js +0 -12
  134. package/dist/sync-M2FSWPBC.js.map +0 -1
  135. package/dist/terminal-spawn-5YXDMUCF.js +0 -157
  136. package/dist/terminal-spawn-5YXDMUCF.js.map +0 -1
  137. package/dist/tiered-storage-Z3YCR465.js +0 -12
  138. package/dist/tiered-storage-Z3YCR465.js.map +0 -1
  139. package/dist/trie-agent-3YDPEGHJ.js +0 -28
  140. package/dist/trie-agent-3YDPEGHJ.js.map +0 -1
  141. package/dist/ui/chat.html +0 -1014
  142. package/dist/ui/goals.html +0 -967
  143. package/dist/ui/hypotheses.html +0 -1011
  144. package/dist/ui/ledger.html +0 -954
  145. package/dist/ui/nudges.html +0 -995
  146. package/dist/vibe-code-signatures-F6URTBW3.js +0 -16
  147. package/dist/vibe-code-signatures-F6URTBW3.js.map +0 -1
  148. package/dist/vulnerability-signatures-T7SKHORW.js +0 -18
  149. package/dist/vulnerability-signatures-T7SKHORW.js.map +0 -1
@@ -1,727 +0,0 @@
1
- import {
2
- getInsightStore
3
- } from "./chunk-T63OHG4Q.js";
4
- import {
5
- searchIssues
6
- } from "./chunk-XE6KQRKZ.js";
7
- import {
8
- getProjectState
9
- } from "./chunk-GTKYBOXL.js";
10
-
11
- // src/agent/hypothesis.ts
12
- import { dirname } from "path";
13
- var HYPOTHESIS_TEMPLATES = [
14
- {
15
- category: "timing",
16
- statement: "Issues spike after weekend deployments",
17
- testCriteria: "Compare Monday issue counts to other days",
18
- minConfidence: 0.3,
19
- dataRequired: ["issue_timestamps", "deployment_data"]
20
- },
21
- {
22
- category: "timing",
23
- statement: "Code quality declines on Fridays",
24
- testCriteria: "Compare Friday issue introduction rate to weekly average",
25
- minConfidence: 0.3,
26
- dataRequired: ["issue_timestamps"]
27
- },
28
- {
29
- category: "pattern",
30
- statement: "Auth-related code has the highest incident rate",
31
- testCriteria: "Compare auth/ issue count to other directories",
32
- minConfidence: 0.4,
33
- dataRequired: ["issue_files"]
34
- },
35
- {
36
- category: "pattern",
37
- statement: "Security issues cluster in specific directories",
38
- testCriteria: "Check if security issues are concentrated (>50% in <3 dirs)",
39
- minConfidence: 0.4,
40
- dataRequired: ["issue_files", "issue_agents"]
41
- },
42
- {
43
- category: "code",
44
- statement: "Files with multiple authors have more issues",
45
- testCriteria: "Correlate file author count with issue count",
46
- minConfidence: 0.4,
47
- dataRequired: ["issue_files", "git_blame"]
48
- },
49
- {
50
- category: "code",
51
- statement: "Recently modified files are more likely to have issues",
52
- testCriteria: "Compare issue rate for recent vs old files",
53
- minConfidence: 0.3,
54
- dataRequired: ["issue_timestamps", "file_modification_times"]
55
- },
56
- {
57
- category: "pattern",
58
- statement: "Critical issues often come in clusters",
59
- testCriteria: "Check temporal clustering of critical issues",
60
- minConfidence: 0.3,
61
- dataRequired: ["issue_timestamps", "issue_severities"]
62
- }
63
- ];
64
- var HypothesisEngine = class {
65
- projectPath;
66
- projectState;
67
- insightStore;
68
- constructor(projectPath) {
69
- this.projectPath = projectPath;
70
- this.projectState = getProjectState(projectPath);
71
- this.insightStore = getInsightStore(projectPath);
72
- }
73
- /**
74
- * Create a new hypothesis
75
- */
76
- async createHypothesis(statement, options) {
77
- const hypothesis = {
78
- id: `hyp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
79
- statement,
80
- confidence: options?.initialConfidence ?? 0,
81
- status: "proposed",
82
- evidence: [],
83
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
84
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
85
- testCriteria: options?.testCriteria,
86
- category: options?.category ?? "general",
87
- autoGenerated: options?.autoGenerated ?? false
88
- };
89
- await this.projectState.addHypothesis(hypothesis);
90
- return hypothesis;
91
- }
92
- /**
93
- * Auto-generate hypotheses based on detected patterns
94
- */
95
- async autoGenerateHypotheses() {
96
- const generated = [];
97
- try {
98
- await this.projectState.load();
99
- const existing = this.projectState.getAllHypotheses();
100
- const existingStatements = new Set(existing.map((h) => h.statement.toLowerCase()));
101
- const issues = await searchIssues("", {
102
- workDir: this.projectPath,
103
- limit: 500,
104
- includeResolved: true
105
- });
106
- if (issues.length < 10) {
107
- return generated;
108
- }
109
- for (const template of HYPOTHESIS_TEMPLATES) {
110
- if (existingStatements.has(template.statement.toLowerCase())) {
111
- continue;
112
- }
113
- const evidence = await this.gatherInitialEvidence(template, issues);
114
- if (evidence.length > 0 && evidence[0].weight >= template.minConfidence) {
115
- const hypothesis = await this.createHypothesis(template.statement, {
116
- category: template.category,
117
- testCriteria: template.testCriteria,
118
- initialConfidence: evidence[0].weight,
119
- autoGenerated: true
120
- });
121
- for (const e of evidence) {
122
- await this.projectState.addEvidence(hypothesis.id, e);
123
- }
124
- generated.push(hypothesis);
125
- if (generated.length >= 4) break;
126
- }
127
- }
128
- } catch (error) {
129
- }
130
- return generated;
131
- }
132
- /**
133
- * Use Claude AI to generate novel hypotheses from observed patterns
134
- * This enables fully agentic hypothesis creation based on actual codebase observations
135
- */
136
- async generateHypothesesWithAI(context) {
137
- const { isAIAvailable, runAIAnalysis } = await import("./client-NJPZE5JT.js");
138
- if (!isAIAvailable()) {
139
- return [];
140
- }
141
- const generated = [];
142
- try {
143
- await this.projectState.load();
144
- const existing = this.projectState.getAllHypotheses();
145
- const existingStatements = existing.map((h) => h.statement);
146
- const issues = context.recentIssues || await searchIssues("", {
147
- workDir: this.projectPath,
148
- limit: 100,
149
- includeResolved: true
150
- });
151
- if (issues.length < 5) {
152
- return generated;
153
- }
154
- const issuesSummary = this.summarizeIssuesForAI(issues);
155
- const patternsSummary = context.patterns?.join("\n") || "No explicit patterns provided";
156
- const observationsSummary = context.observations?.join("\n") || "No explicit observations provided";
157
- const prompt = `You are an AI agent observing a codebase over time. Based on the patterns below, generate 1-3 testable hypotheses about this codebase's quality patterns.
158
-
159
- ## Recent Issues Summary
160
- ${issuesSummary}
161
-
162
- ## Observed Patterns
163
- ${patternsSummary}
164
-
165
- ## Additional Observations
166
- ${observationsSummary}
167
-
168
- ## Existing Hypotheses (avoid duplicates)
169
- ${existingStatements.length > 0 ? existingStatements.map((s) => `- ${s}`).join("\n") : "None yet"}
170
-
171
- Generate hypotheses that are:
172
- 1. Specific and testable (can be validated with data)
173
- 2. Actionable (if validated, can guide improvements)
174
- 3. Novel (not duplicates of existing hypotheses)
175
- 4. Based on real patterns in the data above
176
-
177
- Return ONLY a JSON array of hypotheses. Each hypothesis must have:
178
- - "statement": Clear, concise hypothesis statement
179
- - "category": One of: "timing", "pattern", "team", "code", "general"
180
- - "testCriteria": How to test this hypothesis
181
- - "confidence": Initial confidence (0-1)
182
- - "reasoning": Why you think this hypothesis is worth testing
183
-
184
- Example format:
185
- [
186
- {
187
- "statement": "Authentication code changes correlate with security issues",
188
- "category": "pattern",
189
- "testCriteria": "Track auth file changes and subsequent security issue rates",
190
- "confidence": 0.6,
191
- "reasoning": "65% of security issues occur in files modified in the past week"
192
- }
193
- ]
194
-
195
- Return empty array [] if no novel hypotheses can be generated from the data.`;
196
- const result = await runAIAnalysis({
197
- systemPrompt: "You are an expert code quality analyst who identifies patterns and generates testable hypotheses.",
198
- userPrompt: prompt,
199
- maxTokens: 2048,
200
- // Increased to prevent truncation of hypothesis generation
201
- temperature: 0.7
202
- // Higher temperature for creative hypothesis generation
203
- });
204
- if (!result.success || !result.content.trim()) {
205
- return generated;
206
- }
207
- let aiHypotheses = [];
208
- try {
209
- const cleaned = result.content.replace(/```json?\n?|\n?```/g, "").trim();
210
- aiHypotheses = JSON.parse(cleaned);
211
- if (!Array.isArray(aiHypotheses)) aiHypotheses = [];
212
- } catch {
213
- return generated;
214
- }
215
- for (const aiHypo of aiHypotheses.slice(0, 5)) {
216
- const isDuplicate = existingStatements.some(
217
- (existing2) => existing2.toLowerCase() === aiHypo.statement.toLowerCase() || existing2.toLowerCase().includes(aiHypo.statement.toLowerCase()) || aiHypo.statement.toLowerCase().includes(existing2.toLowerCase())
218
- );
219
- if (isDuplicate) continue;
220
- const hypothesis = await this.createHypothesis(aiHypo.statement, {
221
- category: aiHypo.category,
222
- testCriteria: aiHypo.testCriteria,
223
- initialConfidence: Math.max(0.3, Math.min(0.7, aiHypo.confidence)),
224
- autoGenerated: true
225
- });
226
- await this.projectState.addEvidence(hypothesis.id, {
227
- type: "supporting",
228
- description: `AI observed: ${aiHypo.reasoning}`,
229
- weight: aiHypo.confidence
230
- });
231
- generated.push(hypothesis);
232
- }
233
- } catch (error) {
234
- }
235
- return generated;
236
- }
237
- /**
238
- * Summarize issues for AI context
239
- */
240
- summarizeIssuesForAI(issues) {
241
- const totalIssues = issues.length;
242
- const severityCounts = {};
243
- for (const { issue } of issues) {
244
- severityCounts[issue.severity] = (severityCounts[issue.severity] || 0) + 1;
245
- }
246
- const agentCounts = {};
247
- for (const { issue } of issues) {
248
- agentCounts[issue.agent] = (agentCounts[issue.agent] || 0) + 1;
249
- }
250
- const fileCounts = {};
251
- for (const { issue } of issues) {
252
- const dir = dirname(issue.file);
253
- fileCounts[dir] = (fileCounts[dir] || 0) + 1;
254
- }
255
- const dayOfWeekCounts = {};
256
- for (const { issue } of issues) {
257
- const date = new Date(issue.timestamp);
258
- const day = date.getDay();
259
- dayOfWeekCounts[day] = (dayOfWeekCounts[day] || 0) + 1;
260
- }
261
- const dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
262
- const dayDistribution = Object.entries(dayOfWeekCounts).sort(([a], [b]) => Number(a) - Number(b)).map(([day, count]) => `${dayNames[Number(day)]}: ${count}`).join(", ");
263
- const topDirs = Object.entries(fileCounts).sort(([, a], [, b]) => b - a).slice(0, 8).map(([dir, count]) => `${dir}: ${count}`).join(", ");
264
- const topAgents = Object.entries(agentCounts).sort(([, a], [, b]) => b - a).slice(0, 8).map(([agent, count]) => `${agent}: ${count}`).join(", ");
265
- return `Total Issues: ${totalIssues}
266
- Severities: ${Object.entries(severityCounts).map(([s, c]) => `${s}=${c}`).join(", ")}
267
- Top Agents: ${topAgents}
268
- Top Directories: ${topDirs}
269
- Day Distribution: ${dayDistribution}`;
270
- }
271
- /**
272
- * Gather initial evidence for a hypothesis template
273
- */
274
- async gatherInitialEvidence(template, issues) {
275
- const evidence = [];
276
- switch (template.category) {
277
- case "timing":
278
- evidence.push(...this.analyzeTimingPatterns(template, issues));
279
- break;
280
- case "pattern":
281
- evidence.push(...this.analyzeLocationPatterns(template, issues));
282
- break;
283
- case "code":
284
- evidence.push(...this.analyzeCodePatterns(template, issues));
285
- break;
286
- }
287
- return evidence;
288
- }
289
- /**
290
- * Analyze timing patterns in issues
291
- */
292
- analyzeTimingPatterns(template, issues) {
293
- const evidence = [];
294
- const dayOfWeekCounts = {};
295
- for (const { issue } of issues) {
296
- const date = new Date(issue.timestamp);
297
- const day = date.getDay();
298
- dayOfWeekCounts[day] = (dayOfWeekCounts[day] || 0) + 1;
299
- }
300
- if (template.statement.includes("Friday")) {
301
- const fridayCount = dayOfWeekCounts[5] || 0;
302
- const avgOtherDays = (Object.values(dayOfWeekCounts).reduce((a, b) => a + b, 0) - fridayCount) / 4;
303
- if (fridayCount > avgOtherDays * 1.5) {
304
- evidence.push({
305
- type: "supporting",
306
- description: `Friday has ${((fridayCount / avgOtherDays - 1) * 100).toFixed(0)}% more issues than average`,
307
- weight: Math.min(0.8, 0.3 + (fridayCount / avgOtherDays - 1) * 0.2),
308
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
309
- });
310
- } else {
311
- evidence.push({
312
- type: "contradicting",
313
- description: "Friday issue count is not significantly higher",
314
- weight: 0.3,
315
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
316
- });
317
- }
318
- }
319
- if (template.statement.includes("weekend") || template.statement.includes("Monday")) {
320
- const mondayCount = dayOfWeekCounts[1] || 0;
321
- const avgOtherDays = (Object.values(dayOfWeekCounts).reduce((a, b) => a + b, 0) - mondayCount) / 4;
322
- if (mondayCount > avgOtherDays * 1.5) {
323
- evidence.push({
324
- type: "supporting",
325
- description: `Monday has ${((mondayCount / avgOtherDays - 1) * 100).toFixed(0)}% more issues than average`,
326
- weight: Math.min(0.8, 0.3 + (mondayCount / avgOtherDays - 1) * 0.2),
327
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
328
- });
329
- }
330
- }
331
- return evidence;
332
- }
333
- /**
334
- * Analyze location patterns in issues
335
- */
336
- analyzeLocationPatterns(template, issues) {
337
- const evidence = [];
338
- const dirCounts = {};
339
- for (const { issue } of issues) {
340
- const dir = dirname(issue.file);
341
- dirCounts[dir] = (dirCounts[dir] || 0) + 1;
342
- }
343
- const sortedDirs = Object.entries(dirCounts).sort(([, a], [, b]) => b - a);
344
- if (template.statement.includes("Auth")) {
345
- const authDirs = sortedDirs.filter(
346
- ([dir]) => dir.toLowerCase().includes("auth") || dir.toLowerCase().includes("login") || dir.toLowerCase().includes("session")
347
- );
348
- const authCount = authDirs.reduce((sum, [, count]) => sum + count, 0);
349
- const percentage = authCount / issues.length * 100;
350
- if (percentage >= 20) {
351
- evidence.push({
352
- type: "supporting",
353
- description: `Auth-related code has ${percentage.toFixed(0)}% of issues`,
354
- weight: Math.min(0.85, 0.4 + percentage / 100),
355
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
356
- });
357
- }
358
- }
359
- if (template.statement.includes("cluster")) {
360
- const topThreeDirs = sortedDirs.slice(0, 3);
361
- const topThreeCount = topThreeDirs.reduce((sum, [, count]) => sum + count, 0);
362
- const percentage = topThreeCount / issues.length * 100;
363
- if (percentage >= 50) {
364
- evidence.push({
365
- type: "supporting",
366
- description: `Top 3 directories have ${percentage.toFixed(0)}% of issues`,
367
- weight: Math.min(0.8, 0.3 + percentage / 100),
368
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
369
- });
370
- }
371
- }
372
- return evidence;
373
- }
374
- /**
375
- * Analyze code patterns
376
- */
377
- analyzeCodePatterns(template, issues) {
378
- const evidence = [];
379
- if (template.statement.includes("cluster")) {
380
- const criticalIssues = issues.filter((r) => r.issue.severity === "critical");
381
- if (criticalIssues.length >= 3) {
382
- const timestamps = criticalIssues.map((r) => new Date(r.issue.timestamp).getTime()).sort((a, b) => a - b);
383
- let clusteredCount = 0;
384
- for (let i = 1; i < timestamps.length; i++) {
385
- if (timestamps[i] - timestamps[i - 1] < 24 * 60 * 60 * 1e3) {
386
- clusteredCount++;
387
- }
388
- }
389
- const clusterRatio = clusteredCount / (timestamps.length - 1);
390
- if (clusterRatio >= 0.5) {
391
- evidence.push({
392
- type: "supporting",
393
- description: `${(clusterRatio * 100).toFixed(0)}% of critical issues occur within 24h of another`,
394
- weight: Math.min(0.75, 0.3 + clusterRatio * 0.4),
395
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
396
- });
397
- }
398
- }
399
- }
400
- return evidence;
401
- }
402
- /**
403
- * Update confidence scores based on new data
404
- */
405
- async updateConfidenceFromOutcomes() {
406
- const analyses = [];
407
- try {
408
- await this.projectState.load();
409
- const activeHypotheses = this.projectState.getActiveHypotheses();
410
- for (const hypothesis of activeHypotheses) {
411
- const analysis = await this.analyzeHypothesis(hypothesis);
412
- analyses.push(analysis);
413
- if (analysis.statusChange && this.insightStore.canCreateInsight("hypothesis-update")) {
414
- const insight = this.createHypothesisInsight(analysis);
415
- await this.insightStore.addInsight(insight);
416
- await this.insightStore.markInsightCreated("hypothesis-update");
417
- }
418
- }
419
- await this.projectState.updateHypothesisAccuracy();
420
- } catch (error) {
421
- }
422
- return analyses;
423
- }
424
- /**
425
- * Analyze a single hypothesis
426
- */
427
- async analyzeHypothesis(hypothesis, signal) {
428
- if (signal?.aborted) throw new DOMException("Scan cancelled", "AbortError");
429
- const issues = await searchIssues("", {
430
- workDir: this.projectPath,
431
- limit: 100,
432
- includeResolved: false
433
- });
434
- if (signal?.aborted) throw new DOMException("Scan cancelled", "AbortError");
435
- const template = HYPOTHESIS_TEMPLATES.find(
436
- (t) => t.statement.toLowerCase() === hypothesis.statement.toLowerCase()
437
- );
438
- const recentEvidence = [];
439
- if (template) {
440
- recentEvidence.push(...await this.gatherInitialEvidence(template, issues));
441
- } else {
442
- recentEvidence.push(...this.gatherSemanticEvidence(hypothesis, issues));
443
- }
444
- const oldConfidence = hypothesis.confidence;
445
- let newConfidence = oldConfidence;
446
- for (const evidence of recentEvidence) {
447
- if (evidence.type === "supporting") {
448
- newConfidence = Math.min(1, newConfidence + evidence.weight * 0.1);
449
- } else {
450
- newConfidence = Math.max(0, newConfidence - evidence.weight * 0.1);
451
- }
452
- }
453
- let statusChange;
454
- if (signal?.aborted) throw new DOMException("Scan cancelled", "AbortError");
455
- if (newConfidence >= 0.8 && hypothesis.evidence.length >= 3) {
456
- statusChange = "validated";
457
- await this.projectState.updateHypothesis(hypothesis.id, {
458
- status: "validated",
459
- confidence: newConfidence,
460
- validatedAt: (/* @__PURE__ */ new Date()).toISOString()
461
- });
462
- } else if (newConfidence <= 0.2 && hypothesis.evidence.length >= 3) {
463
- statusChange = "invalidated";
464
- await this.projectState.updateHypothesis(hypothesis.id, {
465
- status: "invalidated",
466
- confidence: newConfidence
467
- });
468
- } else {
469
- await this.projectState.updateHypothesis(hypothesis.id, {
470
- confidence: newConfidence
471
- });
472
- }
473
- for (const evidence of recentEvidence) {
474
- await this.projectState.addEvidence(hypothesis.id, evidence);
475
- }
476
- const analysis = {
477
- hypothesis: { ...hypothesis, confidence: newConfidence },
478
- recentEvidence,
479
- confidenceChange: newConfidence - oldConfidence,
480
- actionRequired: statusChange !== void 0
481
- };
482
- if (statusChange) {
483
- analysis.statusChange = statusChange;
484
- }
485
- return analysis;
486
- }
487
- /**
488
- * Gather evidence for user-created hypotheses using semantic matching
489
- *
490
- * This enables agentic tracking for natural language hypotheses like:
491
- * - "Mondays have more bugs than Fridays"
492
- * - "Code reviews reduce bug rate"
493
- * - "Security issues cluster in auth code"
494
- */
495
- gatherSemanticEvidence(hypothesis, issues) {
496
- const evidence = [];
497
- const stmt = hypothesis.statement.toLowerCase();
498
- if (stmt.includes("monday") || stmt.includes("friday") || stmt.includes("weekend") || stmt.includes("morning") || stmt.includes("afternoon")) {
499
- const dayNames = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
500
- const dayOfWeekCounts = { 0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0 };
501
- for (const { issue } of issues) {
502
- const date = new Date(issue.timestamp);
503
- const day = date.getDay();
504
- dayOfWeekCounts[day] = (dayOfWeekCounts[day] || 0) + 1;
505
- }
506
- const totalIssues = Object.values(dayOfWeekCounts).reduce((a, b) => a + b, 0);
507
- const avgPerDay = totalIssues / 7;
508
- for (let dayIdx = 0; dayIdx < 7; dayIdx++) {
509
- const dayName = dayNames[dayIdx];
510
- if (stmt.includes(dayName)) {
511
- const dayCount = dayOfWeekCounts[dayIdx] || 0;
512
- if (stmt.includes("more") || stmt.includes("higher") || stmt.includes("spike")) {
513
- if (dayCount > avgPerDay * 1.3) {
514
- evidence.push({
515
- type: "supporting",
516
- description: `${dayName.charAt(0).toUpperCase() + dayName.slice(1)} has ${dayCount} issues (${((dayCount / avgPerDay - 1) * 100).toFixed(0)}% above average)`,
517
- weight: Math.min(0.7, 0.3 + (dayCount / avgPerDay - 1) * 0.3),
518
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
519
- });
520
- } else {
521
- evidence.push({
522
- type: "contradicting",
523
- description: `${dayName.charAt(0).toUpperCase() + dayName.slice(1)} has average or below average issue count`,
524
- weight: 0.3,
525
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
526
- });
527
- }
528
- } else if (stmt.includes("fewer") || stmt.includes("less") || stmt.includes("reduce")) {
529
- if (dayCount < avgPerDay * 0.7) {
530
- evidence.push({
531
- type: "supporting",
532
- description: `${dayName.charAt(0).toUpperCase() + dayName.slice(1)} has ${dayCount} issues (${((1 - dayCount / avgPerDay) * 100).toFixed(0)}% below average)`,
533
- weight: Math.min(0.7, 0.3 + (1 - dayCount / avgPerDay) * 0.3),
534
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
535
- });
536
- }
537
- }
538
- }
539
- }
540
- }
541
- if (stmt.includes("review") || stmt.includes("pr") || stmt.includes("pull request")) {
542
- const recentIssues = issues.slice(0, 30);
543
- const olderIssues = issues.slice(30);
544
- if (recentIssues.length >= 10 && olderIssues.length >= 10) {
545
- const recentRate = recentIssues.length;
546
- const olderRate = olderIssues.length;
547
- if (stmt.includes("reduce") || stmt.includes("fewer") || stmt.includes("less")) {
548
- if (recentRate < olderRate) {
549
- evidence.push({
550
- type: "supporting",
551
- description: `Recent period has ${((1 - recentRate / olderRate) * 100).toFixed(0)}% fewer issues`,
552
- weight: Math.min(0.6, 0.3 + (1 - recentRate / olderRate) * 0.3),
553
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
554
- });
555
- } else {
556
- evidence.push({
557
- type: "contradicting",
558
- description: `Issue rate has not decreased recently`,
559
- weight: 0.2,
560
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
561
- });
562
- }
563
- }
564
- }
565
- }
566
- if (stmt.includes("cluster") || stmt.includes("concentrate") || stmt.includes("auth") || stmt.includes("specific") || stmt.includes("certain files")) {
567
- const dirCounts = {};
568
- for (const { issue } of issues) {
569
- const dir = dirname(issue.file);
570
- dirCounts[dir] = (dirCounts[dir] || 0) + 1;
571
- }
572
- const sortedDirs = Object.entries(dirCounts).sort(([, a], [, b]) => b - a);
573
- const topThreeCount = sortedDirs.slice(0, 3).reduce((sum, [, count]) => sum + count, 0);
574
- const totalCount = issues.length;
575
- const concentration = topThreeCount / totalCount;
576
- if (concentration >= 0.5) {
577
- evidence.push({
578
- type: "supporting",
579
- description: `Top 3 directories have ${(concentration * 100).toFixed(0)}% of issues (concentrated)`,
580
- weight: Math.min(0.7, 0.3 + concentration * 0.4),
581
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
582
- });
583
- } else {
584
- evidence.push({
585
- type: "contradicting",
586
- description: `Issues are distributed across many directories`,
587
- weight: 0.3,
588
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
589
- });
590
- }
591
- }
592
- if (stmt.includes("critical") || stmt.includes("security") || stmt.includes("severity")) {
593
- const criticalCount = issues.filter((r) => r.issue.severity === "critical").length;
594
- const seriousCount = issues.filter((r) => r.issue.severity === "serious").length;
595
- const highSeverityRatio = (criticalCount + seriousCount) / issues.length;
596
- if (stmt.includes("increase") || stmt.includes("more") || stmt.includes("rise")) {
597
- if (highSeverityRatio > 0.3) {
598
- evidence.push({
599
- type: "supporting",
600
- description: `${(highSeverityRatio * 100).toFixed(0)}% of issues are high severity`,
601
- weight: Math.min(0.7, 0.3 + highSeverityRatio),
602
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
603
- });
604
- }
605
- } else if (stmt.includes("decrease") || stmt.includes("fewer") || stmt.includes("reduce")) {
606
- if (highSeverityRatio < 0.2) {
607
- evidence.push({
608
- type: "supporting",
609
- description: `Only ${(highSeverityRatio * 100).toFixed(0)}% of issues are high severity`,
610
- weight: 0.5,
611
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
612
- });
613
- }
614
- }
615
- }
616
- const agents = ["security", "performance", "accessibility", "test", "typecheck", "bug-finding"];
617
- for (const agent of agents) {
618
- if (stmt.includes(agent) || stmt.includes(agent.replace("-", " "))) {
619
- const agentIssues = issues.filter((r) => r.issue.agent === agent);
620
- const agentRatio = agentIssues.length / issues.length;
621
- if (stmt.includes("most") || stmt.includes("majority") || stmt.includes("main")) {
622
- if (agentRatio > 0.4) {
623
- evidence.push({
624
- type: "supporting",
625
- description: `${agent} accounts for ${(agentRatio * 100).toFixed(0)}% of issues`,
626
- weight: Math.min(0.7, 0.3 + agentRatio),
627
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
628
- });
629
- } else {
630
- evidence.push({
631
- type: "contradicting",
632
- description: `${agent} only accounts for ${(agentRatio * 100).toFixed(0)}% of issues`,
633
- weight: 0.3,
634
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
635
- });
636
- }
637
- }
638
- }
639
- }
640
- return evidence;
641
- }
642
- /**
643
- * Create an insight for hypothesis status change
644
- */
645
- createHypothesisInsight(analysis) {
646
- const isValidated = analysis.statusChange === "validated";
647
- return {
648
- id: `insight-hyp-${analysis.hypothesis.id}`,
649
- type: isValidated ? "celebration" : "observation",
650
- message: isValidated ? `Hypothesis confirmed: "${analysis.hypothesis.statement}"` : `Hypothesis disproven: "${analysis.hypothesis.statement}"`,
651
- context: `Confidence: ${(analysis.hypothesis.confidence * 100).toFixed(0)}%. ${analysis.recentEvidence.length} evidence points analyzed.`,
652
- relatedIssues: [],
653
- priority: 5,
654
- timestamp: Date.now(),
655
- dismissed: false,
656
- category: "pattern",
657
- details: {
658
- examples: analysis.recentEvidence.map((e) => `${e.type}: ${e.description}`)
659
- }
660
- };
661
- }
662
- /**
663
- * Get hypothesis by ID
664
- */
665
- async getHypothesis(hypothesisId) {
666
- await this.projectState.load();
667
- return this.projectState.getHypothesis(hypothesisId);
668
- }
669
- /**
670
- * Get all hypotheses
671
- */
672
- async getAllHypotheses() {
673
- await this.projectState.load();
674
- return this.projectState.getAllHypotheses();
675
- }
676
- /**
677
- * Get validated hypotheses
678
- */
679
- async getValidatedHypotheses() {
680
- await this.projectState.load();
681
- return this.projectState.getValidatedHypotheses();
682
- }
683
- /**
684
- * Get hypothesis accuracy stats
685
- */
686
- getAccuracy() {
687
- const metrics = this.projectState.getMetrics();
688
- return metrics.hypothesisAccuracy;
689
- }
690
- };
691
- var hypothesisEngines = /* @__PURE__ */ new Map();
692
- function getHypothesisEngine(projectPath) {
693
- let engine = hypothesisEngines.get(projectPath);
694
- if (!engine) {
695
- engine = new HypothesisEngine(projectPath);
696
- hypothesisEngines.set(projectPath, engine);
697
- }
698
- return engine;
699
- }
700
- function clearHypothesisEngines() {
701
- hypothesisEngines.clear();
702
- }
703
- async function gatherEvidenceForHypothesis(hypothesisId, projectPath, signal) {
704
- if (signal?.aborted) throw new DOMException("Scan cancelled", "AbortError");
705
- const engine = getHypothesisEngine(projectPath);
706
- const projectState = getProjectState(projectPath);
707
- await projectState.load();
708
- if (signal?.aborted) throw new DOMException("Scan cancelled", "AbortError");
709
- const hypothesis = projectState.getAllHypotheses().find((h) => h.id === hypothesisId);
710
- if (!hypothesis) {
711
- throw new Error(`Hypothesis ${hypothesisId} not found`);
712
- }
713
- const analysis = await engine.analyzeHypothesis(hypothesis, signal);
714
- return analysis.recentEvidence.map((e) => ({
715
- supports: e.type === "supporting",
716
- description: e.description,
717
- weight: e.weight
718
- }));
719
- }
720
-
721
- export {
722
- HypothesisEngine,
723
- getHypothesisEngine,
724
- clearHypothesisEngines,
725
- gatherEvidenceForHypothesis
726
- };
727
- //# sourceMappingURL=chunk-XTFWT2XM.js.map