@triedotdev/mcp 1.0.93 → 1.0.97

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 (84) hide show
  1. package/README.md +145 -137
  2. package/dist/chunk-APMV77PU.js +313 -0
  3. package/dist/chunk-APMV77PU.js.map +1 -0
  4. package/dist/{chunk-MZI46HQT.js → chunk-B3MNN3XB.js} +13 -18
  5. package/dist/{chunk-MZI46HQT.js.map → chunk-B3MNN3XB.js.map} +1 -1
  6. package/dist/{chunk-5Z7O66DE.js → chunk-F4NJ4CBP.js} +2 -2
  7. package/dist/{chunk-YTJXD664.js → chunk-FNCCZ3XB.js} +1222 -75
  8. package/dist/chunk-FNCCZ3XB.js.map +1 -0
  9. package/dist/chunk-G76DYVGX.js +136 -0
  10. package/dist/chunk-G76DYVGX.js.map +1 -0
  11. package/dist/chunk-HSNE46VE.js +956 -0
  12. package/dist/chunk-HSNE46VE.js.map +1 -0
  13. package/dist/{chunk-LVVG2DMW.js → chunk-IXO4G4D3.js} +2 -2
  14. package/dist/{chunk-LP4MVJDW.js → chunk-JDHR5BDR.js} +2 -3
  15. package/dist/chunk-NIASHOAB.js +1304 -0
  16. package/dist/chunk-NIASHOAB.js.map +1 -0
  17. package/dist/{chunk-NMGINYYX.js → chunk-OVRG5RP3.js} +6 -7
  18. package/dist/chunk-OVRG5RP3.js.map +1 -0
  19. package/dist/{chunk-T5UOH56R.js → chunk-R3I2GCZC.js} +3 -3
  20. package/dist/{chunk-RDOJCRKJ.js → chunk-R4AAPFXC.js} +2 -2
  21. package/dist/{chunk-R6AUYN3R.js → chunk-SLL2MDJD.js} +786 -4668
  22. package/dist/chunk-SLL2MDJD.js.map +1 -0
  23. package/dist/cli/create-agent.js +931 -7
  24. package/dist/cli/create-agent.js.map +1 -1
  25. package/dist/cli/main.js +151 -383
  26. package/dist/cli/main.js.map +1 -1
  27. package/dist/cli/yolo-daemon.js +13 -20
  28. package/dist/cli/yolo-daemon.js.map +1 -1
  29. package/dist/{goal-manager-ESJCJXFS.js → goal-manager-LAOT4QQX.js} +6 -6
  30. package/dist/guardian-agent-M352CBE5.js +19 -0
  31. package/dist/index.js +1025 -1550
  32. package/dist/index.js.map +1 -1
  33. package/dist/{issue-store-JZ2LCQEG.js → issue-store-W2X33X2X.js} +4 -4
  34. package/dist/{progress-PH6NNWZM.js → progress-PQVEM7BR.js} +2 -2
  35. package/dist/{vibe-code-signatures-K4UIWKJZ.js → vibe-code-signatures-ELEWJFGZ.js} +3 -3
  36. package/dist/{vulnerability-signatures-ZKVLMBRG.js → vulnerability-signatures-EIJQX2TS.js} +3 -3
  37. package/dist/workers/agent-worker.js +2 -11
  38. package/dist/workers/agent-worker.js.map +1 -1
  39. package/package.json +2 -2
  40. package/dist/agent-smith-QYDXPFPJ.js +0 -14
  41. package/dist/agent-smith-runner-GXGDJTSR.js +0 -573
  42. package/dist/agent-smith-runner-GXGDJTSR.js.map +0 -1
  43. package/dist/cache-manager-7SKX3IGO.js +0 -10
  44. package/dist/chunk-74NPKTZV.js +0 -141
  45. package/dist/chunk-74NPKTZV.js.map +0 -1
  46. package/dist/chunk-BG2BHWCC.js +0 -10879
  47. package/dist/chunk-BG2BHWCC.js.map +0 -1
  48. package/dist/chunk-CUXXRM3T.js +0 -2124
  49. package/dist/chunk-CUXXRM3T.js.map +0 -1
  50. package/dist/chunk-D25EIBPO.js +0 -183
  51. package/dist/chunk-D25EIBPO.js.map +0 -1
  52. package/dist/chunk-F55XBLIA.js +0 -536
  53. package/dist/chunk-F55XBLIA.js.map +0 -1
  54. package/dist/chunk-HFQ5ORON.js +0 -279
  55. package/dist/chunk-HFQ5ORON.js.map +0 -1
  56. package/dist/chunk-IOUOVBJZ.js +0 -175
  57. package/dist/chunk-IOUOVBJZ.js.map +0 -1
  58. package/dist/chunk-KWDNYWOR.js +0 -2270
  59. package/dist/chunk-KWDNYWOR.js.map +0 -1
  60. package/dist/chunk-LT7MKIXU.js +0 -266
  61. package/dist/chunk-LT7MKIXU.js.map +0 -1
  62. package/dist/chunk-MURGTWG4.js +0 -279
  63. package/dist/chunk-MURGTWG4.js.map +0 -1
  64. package/dist/chunk-NMGINYYX.js.map +0 -1
  65. package/dist/chunk-R6AUYN3R.js.map +0 -1
  66. package/dist/chunk-SJFJ6GLR.js +0 -955
  67. package/dist/chunk-SJFJ6GLR.js.map +0 -1
  68. package/dist/chunk-YTJXD664.js.map +0 -1
  69. package/dist/git-PZV3BBYI.js +0 -29
  70. package/dist/guardian-agent-ZHJXLBOU.js +0 -21
  71. package/dist/progress-PH6NNWZM.js.map +0 -1
  72. package/dist/vibe-code-signatures-K4UIWKJZ.js.map +0 -1
  73. package/dist/vulnerability-signatures-ZKVLMBRG.js.map +0 -1
  74. /package/dist/{chunk-5Z7O66DE.js.map → chunk-F4NJ4CBP.js.map} +0 -0
  75. /package/dist/{chunk-LVVG2DMW.js.map → chunk-IXO4G4D3.js.map} +0 -0
  76. /package/dist/{chunk-LP4MVJDW.js.map → chunk-JDHR5BDR.js.map} +0 -0
  77. /package/dist/{chunk-T5UOH56R.js.map → chunk-R3I2GCZC.js.map} +0 -0
  78. /package/dist/{chunk-RDOJCRKJ.js.map → chunk-R4AAPFXC.js.map} +0 -0
  79. /package/dist/{agent-smith-QYDXPFPJ.js.map → goal-manager-LAOT4QQX.js.map} +0 -0
  80. /package/dist/{cache-manager-7SKX3IGO.js.map → guardian-agent-M352CBE5.js.map} +0 -0
  81. /package/dist/{git-PZV3BBYI.js.map → issue-store-W2X33X2X.js.map} +0 -0
  82. /package/dist/{goal-manager-ESJCJXFS.js.map → progress-PQVEM7BR.js.map} +0 -0
  83. /package/dist/{guardian-agent-ZHJXLBOU.js.map → vibe-code-signatures-ELEWJFGZ.js.map} +0 -0
  84. /package/dist/{issue-store-JZ2LCQEG.js.map → vulnerability-signatures-EIJQX2TS.js.map} +0 -0
package/dist/index.js CHANGED
@@ -1,9 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- listCustomAgents,
4
- loadAgentConfig,
5
- parseDocument
6
- } from "./chunk-SJFJ6GLR.js";
7
2
  import {
8
3
  IncidentIndex,
9
4
  LearningEngine,
@@ -17,6 +12,7 @@ import {
17
12
  initializeBootstrapFiles,
18
13
  listCheckpoints,
19
14
  loadBootstrapContext,
15
+ loadConfig,
20
16
  loadRules,
21
17
  loadTeamInfo,
22
18
  needsBootstrap,
@@ -24,50 +20,45 @@ import {
24
20
  reasonAboutChangesHumanReadable,
25
21
  saveCheckpoint,
26
22
  trackIssueOccurrence
27
- } from "./chunk-YTJXD664.js";
23
+ } from "./chunk-FNCCZ3XB.js";
28
24
  import {
29
25
  InteractiveDashboard,
30
26
  StreamingManager,
31
- TrieScanTool
32
- } from "./chunk-R6AUYN3R.js";
33
- import "./chunk-MZI46HQT.js";
34
- import "./chunk-NMGINYYX.js";
35
- import {
36
- isTrieInitialized,
37
- loadConfig
38
- } from "./chunk-CUXXRM3T.js";
39
- import "./chunk-HFQ5ORON.js";
40
- import "./chunk-IOUOVBJZ.js";
41
- import {
42
- ContextGraph
43
- } from "./chunk-F55XBLIA.js";
44
- import "./chunk-5Z7O66DE.js";
45
- import "./chunk-T5UOH56R.js";
27
+ TrieScanTool,
28
+ getOutputManager,
29
+ listInstalledSkills
30
+ } from "./chunk-SLL2MDJD.js";
31
+ import "./chunk-B3MNN3XB.js";
46
32
  import {
47
- CRITICAL_REVIEW_CHECKLIST,
48
- SuperReviewerSkill,
49
33
  appendToSection,
50
34
  getContextForAI,
51
35
  getProjectInfoStructured,
52
36
  getProjectSection,
53
37
  getProjectSections,
54
- getSkillRegistry,
55
38
  initProjectInfo,
56
- listInstalledSkills,
39
+ isTrieInitialized,
57
40
  loadContextState,
58
41
  loadProjectInfo,
59
42
  projectInfoExists,
43
+ runShellCommandSync,
60
44
  updateProjectSection
61
- } from "./chunk-BG2BHWCC.js";
62
- import {
63
- runShellCommandSync
64
- } from "./chunk-MURGTWG4.js";
45
+ } from "./chunk-HSNE46VE.js";
65
46
  import {
47
+ ContextGraph,
66
48
  findCrossProjectPatterns,
67
49
  getGlobalMemoryStats,
50
+ getStorage,
68
51
  listTrackedProjects,
69
52
  searchGlobalPatterns
70
- } from "./chunk-LT7MKIXU.js";
53
+ } from "./chunk-NIASHOAB.js";
54
+ import "./chunk-F4NJ4CBP.js";
55
+ import "./chunk-IXO4G4D3.js";
56
+ import "./chunk-6NLHFIYA.js";
57
+ import {
58
+ getSkillRegistry
59
+ } from "./chunk-G76DYVGX.js";
60
+ import "./chunk-OVRG5RP3.js";
61
+ import "./chunk-R3I2GCZC.js";
71
62
  import {
72
63
  findSimilarIssues,
73
64
  getMemoryStats,
@@ -75,20 +66,14 @@ import {
75
66
  markIssueResolved,
76
67
  purgeIssues,
77
68
  searchIssues
78
- } from "./chunk-LP4MVJDW.js";
79
- import "./chunk-LVVG2DMW.js";
80
- import "./chunk-6NLHFIYA.js";
81
- import {
82
- getOutputManager
83
- } from "./chunk-KWDNYWOR.js";
84
- import "./chunk-74NPKTZV.js";
69
+ } from "./chunk-JDHR5BDR.js";
85
70
  import {
86
71
  getTrieDirectory,
87
72
  getWorkingDirectory
88
- } from "./chunk-RDOJCRKJ.js";
73
+ } from "./chunk-R4AAPFXC.js";
89
74
  import {
90
75
  isInteractiveMode
91
- } from "./chunk-D25EIBPO.js";
76
+ } from "./chunk-APMV77PU.js";
92
77
  import "./chunk-DGUM43GV.js";
93
78
 
94
79
  // src/server/mcp-server.ts
@@ -223,43 +208,6 @@ Provide:
223
208
  1. The exact code fix (ready to apply)
224
209
  2. Explanation of why this fix works
225
210
  3. Any additional hardening recommendations`
226
- },
227
- privacy: {
228
- system: `You are a data privacy officer and GDPR/HIPAA compliance expert.
229
- Analyze code for privacy violations and data protection issues.
230
-
231
- Key regulations to enforce:
232
- - GDPR (EU data protection)
233
- - CCPA (California privacy)
234
- - HIPAA (health data)
235
- - COPPA (children's privacy)
236
- - PCI DSS (payment data)
237
-
238
- Look for:
239
- - PII without encryption
240
- - Missing consent mechanisms
241
- - Data retention violations
242
- - Cross-border data transfer issues
243
- - Third-party data sharing without disclosure`,
244
- analysis: `## Privacy Compliance Audit
245
-
246
- Analyze this code for privacy/compliance issues:
247
-
248
- \`\`\`{{language}}
249
- {{code}}
250
- \`\`\`
251
-
252
- **File:** {{filePath}}
253
- **Data Types Detected:** {{dataTypes}}
254
-
255
- For each issue:
256
- 1. Regulation violated (e.g., GDPR Article 32)
257
- 2. Specific requirement not met
258
- 3. Risk level and potential fine exposure
259
- 4. Remediation steps with code examples
260
- 5. Documentation requirements
261
-
262
- Reference current regulatory guidance when applicable.`
263
211
  },
264
212
  legal: {
265
213
  system: `You are a tech-focused legal compliance analyst.
@@ -2518,27 +2466,585 @@ trie_test action:"run" files:["src/utils.test.ts"]
2518
2466
  }
2519
2467
  };
2520
2468
 
2521
- // src/tools/register-agent.ts
2522
- var TrieRegisterAgentTool = class {
2523
- async execute(args) {
2524
- const { name, path: path3 } = args;
2469
+ // src/tools/watch.ts
2470
+ import { watch, existsSync as existsSync4, readFileSync } from "fs";
2471
+ import { stat, readFile as readFile4 } from "fs/promises";
2472
+ import { join as join2, extname as extname4, basename as basename2 } from "path";
2473
+
2474
+ // src/extraction/signal-extractor.ts
2475
+ import Anthropic from "@anthropic-ai/sdk";
2476
+ var EXTRACTION_PROMPT = `You are a signal extraction system. Your job is to extract structured information from raw content.
2477
+
2478
+ Extract:
2479
+ 1. DECISIONS - Clear choices made during development
2480
+ - What was decided
2481
+ - Why it was decided (reasoning/tradeoffs)
2482
+ - What alternatives were considered but NOT chosen
2483
+ - Which files are affected
2484
+
2485
+ 2. FACTS - Concrete, verifiable information
2486
+ - Technical constraints (e.g., "Stripe requires TLS 1.2+")
2487
+ - API requirements
2488
+ - Business rules
2489
+ - Dependencies
2490
+
2491
+ 3. BLOCKERS - Things preventing progress
2492
+ - What's blocked
2493
+ - Impact level (critical/high/medium/low)
2494
+ - What areas are affected
2495
+
2496
+ 4. QUESTIONS - Open items needing resolution
2497
+ - What's unclear
2498
+ - Context around the question
2499
+
2500
+ CRITICAL: Extract rich metadata:
2501
+ - Tags: Use specific, searchable tags (e.g., "auth", "payments", "eu-compliance", "validation")
2502
+ - Files: Full paths when mentioned (e.g., "src/auth/validator.ts")
2503
+ - Tradeoffs: What was considered but rejected
2504
+ - Related terms: Alternative names/keywords (e.g., "password" + "credentials" + "auth")
2505
+
2506
+ Format as JSON:
2507
+ {
2508
+ "decisions": [{
2509
+ "decision": "Use bcrypt for password hashing",
2510
+ "context": "Security requirement for user authentication",
2511
+ "reasoning": "Industry standard, resistant to GPU attacks",
2512
+ "files": ["src/auth/hash.ts", "src/models/user.ts"],
2513
+ "tags": ["security", "auth", "passwords", "encryption"],
2514
+ "tradeoffs": ["Considered argon2 but bcrypt has better library support"]
2515
+ }],
2516
+ "facts": [{
2517
+ "fact": "Stripe requires TLS 1.2+ for all API calls",
2518
+ "source": "Stripe API docs",
2519
+ "tags": ["payments", "stripe", "security", "api"],
2520
+ "confidence": 0.95
2521
+ }],
2522
+ "blockers": [{
2523
+ "blocker": "Missing VAT calculation endpoint",
2524
+ "impact": "high",
2525
+ "affectedAreas": ["checkout", "eu-payments"],
2526
+ "tags": ["payments", "eu", "compliance", "vat"]
2527
+ }],
2528
+ "questions": [{
2529
+ "question": "Should we cache user sessions in Redis or memory?",
2530
+ "context": "Performance optimization for auth layer",
2531
+ "tags": ["auth", "performance", "caching", "sessions"]
2532
+ }]
2533
+ }
2534
+
2535
+ Be specific with tags. Use concrete technical terms. Extract ALL file paths mentioned.
2536
+ Empty arrays are fine if nothing to extract.`;
2537
+ var SignalExtractor = class {
2538
+ client = null;
2539
+ model;
2540
+ constructor(model = "claude-3-haiku-20240307") {
2541
+ this.model = model;
2542
+ const apiKey = process.env.ANTHROPIC_API_KEY;
2543
+ if (apiKey) {
2544
+ this.client = new Anthropic({ apiKey });
2545
+ }
2546
+ }
2547
+ /**
2548
+ * Extract structured signals from raw content
2549
+ */
2550
+ async extract(content, sourceType, sourceId) {
2551
+ if (!this.client) {
2552
+ return this.basicExtraction(content, sourceType, sourceId);
2553
+ }
2554
+ try {
2555
+ const response = await this.client.messages.create({
2556
+ model: this.model,
2557
+ max_tokens: 2048,
2558
+ temperature: 0.3,
2559
+ messages: [{
2560
+ role: "user",
2561
+ content: `${EXTRACTION_PROMPT}
2562
+
2563
+ Content to analyze:
2564
+ ${content}`
2565
+ }]
2566
+ });
2567
+ const firstBlock = response.content[0];
2568
+ const text = firstBlock && firstBlock.type === "text" ? firstBlock.text : "";
2569
+ const extracted = this.parseExtraction(text);
2570
+ const now = (/* @__PURE__ */ new Date()).toISOString();
2571
+ const metadata = {
2572
+ extractedAt: now,
2573
+ sourceType,
2574
+ extractionModel: this.model
2575
+ };
2576
+ if (sourceId !== void 0) {
2577
+ metadata.sourceId = sourceId;
2578
+ }
2579
+ const signal = {
2580
+ decisions: extracted.decisions.map((d, i) => ({
2581
+ id: `dec-${Date.now()}-${i}`,
2582
+ decision: d.decision || "",
2583
+ context: d.context || "",
2584
+ files: d.files || [],
2585
+ tags: d.tags || [],
2586
+ ...d,
2587
+ when: now,
2588
+ status: "active"
2589
+ })),
2590
+ facts: extracted.facts.map((f, i) => ({
2591
+ id: `fact-${Date.now()}-${i}`,
2592
+ fact: f.fact || "",
2593
+ source: f.source || sourceType,
2594
+ tags: f.tags || [],
2595
+ confidence: f.confidence ?? 0.8,
2596
+ ...f,
2597
+ when: now
2598
+ })),
2599
+ blockers: extracted.blockers.map((b, i) => ({
2600
+ id: `block-${Date.now()}-${i}`,
2601
+ blocker: b.blocker || "",
2602
+ impact: b.impact || "medium",
2603
+ affectedAreas: b.affectedAreas || [],
2604
+ tags: b.tags || [],
2605
+ ...b,
2606
+ when: now
2607
+ })),
2608
+ questions: extracted.questions.map((q, i) => ({
2609
+ id: `q-${Date.now()}-${i}`,
2610
+ question: q.question || "",
2611
+ context: q.context || "",
2612
+ tags: q.tags || [],
2613
+ ...q,
2614
+ when: now
2615
+ })),
2616
+ metadata
2617
+ };
2618
+ return signal;
2619
+ } catch (error) {
2620
+ console.error("Extraction failed, using basic extraction:", error);
2621
+ return this.basicExtraction(content, sourceType, sourceId);
2622
+ }
2623
+ }
2624
+ /**
2625
+ * Parse extraction from model response
2626
+ */
2627
+ parseExtraction(text) {
2628
+ try {
2629
+ const jsonMatch = text.match(/\{[\s\S]*\}/);
2630
+ if (jsonMatch) {
2631
+ return JSON.parse(jsonMatch[0]);
2632
+ }
2633
+ } catch (e) {
2634
+ }
2525
2635
  return {
2526
- content: [
2527
- {
2528
- type: "text",
2529
- text: `\u{1F916} Register agent tool called with name: ${name}, path: ${path3}
2636
+ decisions: [],
2637
+ facts: [],
2638
+ blockers: [],
2639
+ questions: []
2640
+ };
2641
+ }
2642
+ /**
2643
+ * Basic extraction without AI (fallback)
2644
+ */
2645
+ basicExtraction(content, sourceType, sourceId) {
2646
+ const now = (/* @__PURE__ */ new Date()).toISOString();
2647
+ const hasDecision = /\b(decided|decision|chose|picked)\b/i.test(content);
2648
+ const hasBlocker = /\b(blocked|blocker|blocked by|can't|cannot|unable)\b/i.test(content);
2649
+ const hasQuestion = /\?|what|how|why|should we/i.test(content);
2650
+ const decisions = [];
2651
+ const facts = [];
2652
+ const blockers = [];
2653
+ const questions = [];
2654
+ if (hasDecision) {
2655
+ decisions.push({
2656
+ id: `dec-${Date.now()}`,
2657
+ decision: content.substring(0, 200),
2658
+ context: sourceType,
2659
+ when: now,
2660
+ files: [],
2661
+ tags: [sourceType],
2662
+ status: "active"
2663
+ });
2664
+ }
2665
+ if (hasBlocker) {
2666
+ blockers.push({
2667
+ id: `block-${Date.now()}`,
2668
+ blocker: content.substring(0, 200),
2669
+ impact: "medium",
2670
+ affectedAreas: [],
2671
+ when: now,
2672
+ tags: [sourceType]
2673
+ });
2674
+ }
2675
+ if (hasQuestion) {
2676
+ questions.push({
2677
+ id: `q-${Date.now()}`,
2678
+ question: content.substring(0, 200),
2679
+ context: sourceType,
2680
+ when: now,
2681
+ tags: [sourceType]
2682
+ });
2683
+ }
2684
+ const metadata = {
2685
+ extractedAt: now,
2686
+ sourceType,
2687
+ extractionModel: "basic"
2688
+ };
2689
+ if (sourceId !== void 0) {
2690
+ metadata.sourceId = sourceId;
2691
+ }
2692
+ return {
2693
+ decisions,
2694
+ facts,
2695
+ blockers,
2696
+ questions,
2697
+ metadata
2698
+ };
2699
+ }
2700
+ /**
2701
+ * Extract from incident report (trie tell)
2702
+ */
2703
+ async extractFromIncident(incidentText) {
2704
+ return this.extract(incidentText, "incident");
2705
+ }
2706
+ /**
2707
+ * Extract from commit message and diff
2708
+ */
2709
+ async extractFromCommit(message, diff, commitId) {
2710
+ const content = diff ? `${message}
2711
+
2712
+ Changes:
2713
+ ${diff}` : message;
2714
+ return this.extract(content, "commit", commitId);
2715
+ }
2716
+ /**
2717
+ * Extract from PR description and comments
2718
+ */
2719
+ async extractFromPR(title, description, comments, prNumber) {
2720
+ const content = `
2721
+ Title: ${title}
2722
+
2723
+ Description:
2724
+ ${description}
2725
+
2726
+ Comments:
2727
+ ${comments.join("\n\n")}
2728
+ `.trim();
2729
+ return this.extract(content, "pr", prNumber);
2730
+ }
2731
+ };
2732
+
2733
+ // src/extraction/metadata-enricher.ts
2734
+ var MetadataEnricher = class {
2735
+ tagSynonyms;
2736
+ constructor() {
2737
+ this.tagSynonyms = this.initializeTagSynonyms();
2738
+ }
2739
+ /**
2740
+ * Enrich an extracted signal with additional metadata
2741
+ */
2742
+ async enrichSignal(signal, context) {
2743
+ const gitContext = {};
2744
+ if (context?.gitBranch) gitContext.branch = context.gitBranch;
2745
+ if (context?.gitCommit) gitContext.commit = context.gitCommit;
2746
+ const metadata = {
2747
+ relatedFiles: await this.findRelatedFiles(signal),
2748
+ dependencies: await this.extractDependencies(signal),
2749
+ expandedTags: this.expandTags(signal),
2750
+ codebaseArea: this.inferCodebaseArea(signal),
2751
+ domain: this.inferDomain(signal),
2752
+ relatedDecisions: [],
2753
+ // Will be populated by storage layer
2754
+ extractedAt: (/* @__PURE__ */ new Date()).toISOString()
2755
+ };
2756
+ if (Object.keys(gitContext).length > 0) {
2757
+ metadata.gitContext = gitContext;
2758
+ }
2759
+ return {
2760
+ signal,
2761
+ metadata
2762
+ };
2763
+ }
2764
+ /**
2765
+ * Expand tags with synonyms and related terms
2766
+ * This is our "semantic" layer without embeddings
2767
+ */
2768
+ expandTags(signal) {
2769
+ const allTags = /* @__PURE__ */ new Set();
2770
+ for (const decision of signal.decisions) {
2771
+ decision.tags.forEach((tag) => allTags.add(tag.toLowerCase()));
2772
+ }
2773
+ for (const fact of signal.facts) {
2774
+ fact.tags.forEach((tag) => allTags.add(tag.toLowerCase()));
2775
+ }
2776
+ for (const blocker of signal.blockers) {
2777
+ blocker.tags.forEach((tag) => allTags.add(tag.toLowerCase()));
2778
+ }
2779
+ for (const question of signal.questions) {
2780
+ question.tags.forEach((tag) => allTags.add(tag.toLowerCase()));
2781
+ }
2782
+ const expandedTags = new Set(allTags);
2783
+ for (const tag of allTags) {
2784
+ const synonyms = this.tagSynonyms.get(tag) || [];
2785
+ synonyms.forEach((syn) => expandedTags.add(syn));
2786
+ }
2787
+ return Array.from(expandedTags);
2788
+ }
2789
+ /**
2790
+ * Find related files based on signal content
2791
+ */
2792
+ async findRelatedFiles(signal) {
2793
+ const relatedFiles = /* @__PURE__ */ new Set();
2794
+ for (const decision of signal.decisions) {
2795
+ decision.files.forEach((file) => relatedFiles.add(file));
2796
+ }
2797
+ const inferredFiles = await this.inferFilesFromTags(signal);
2798
+ inferredFiles.forEach((file) => relatedFiles.add(file));
2799
+ return Array.from(relatedFiles);
2800
+ }
2801
+ /**
2802
+ * Extract dependencies from signal
2803
+ */
2804
+ async extractDependencies(signal) {
2805
+ const dependencies = /* @__PURE__ */ new Set();
2806
+ const allText = [
2807
+ ...signal.decisions.map((d) => `${d.decision} ${d.context} ${d.reasoning}`),
2808
+ ...signal.facts.map((f) => `${f.fact} ${f.source}`)
2809
+ ].join(" ");
2810
+ const packagePatterns = [
2811
+ /\b(react|vue|angular|next|express|fastify|stripe|bcrypt|jwt|redis|prisma)\b/gi
2812
+ ];
2813
+ for (const pattern of packagePatterns) {
2814
+ const matches = allText.match(pattern) || [];
2815
+ matches.forEach((dep) => dependencies.add(dep.toLowerCase()));
2816
+ }
2817
+ return Array.from(dependencies);
2818
+ }
2819
+ /**
2820
+ * Infer codebase area from file paths and tags
2821
+ */
2822
+ inferCodebaseArea(signal) {
2823
+ const areas = /* @__PURE__ */ new Set();
2824
+ for (const decision of signal.decisions) {
2825
+ for (const file of decision.files) {
2826
+ const area = this.filePathToArea(file);
2827
+ if (area) areas.add(area);
2828
+ }
2829
+ }
2830
+ const areaKeywords = ["frontend", "backend", "api", "ui", "database", "auth", "payments"];
2831
+ const allTags = this.expandTags(signal);
2832
+ for (const tag of allTags) {
2833
+ if (areaKeywords.includes(tag)) {
2834
+ areas.add(tag);
2835
+ }
2836
+ }
2837
+ return Array.from(areas);
2838
+ }
2839
+ /**
2840
+ * Infer domain from tags and content
2841
+ */
2842
+ inferDomain(signal) {
2843
+ const domains = /* @__PURE__ */ new Set();
2844
+ const domainKeywords = [
2845
+ "payments",
2846
+ "billing",
2847
+ "compliance",
2848
+ "security",
2849
+ "auth",
2850
+ "analytics",
2851
+ "notifications",
2852
+ "messaging",
2853
+ "search"
2854
+ ];
2855
+ const allTags = this.expandTags(signal);
2856
+ for (const tag of allTags) {
2857
+ if (domainKeywords.includes(tag)) {
2858
+ domains.add(tag);
2859
+ }
2860
+ }
2861
+ return Array.from(domains);
2862
+ }
2863
+ /**
2864
+ * Convert file path to codebase area
2865
+ */
2866
+ filePathToArea(filePath) {
2867
+ const normalized = filePath.toLowerCase();
2868
+ if (normalized.includes("/frontend/") || normalized.includes("/client/") || normalized.includes("/ui/")) {
2869
+ return "frontend";
2870
+ }
2871
+ if (normalized.includes("/backend/") || normalized.includes("/server/") || normalized.includes("/api/")) {
2872
+ return "backend";
2873
+ }
2874
+ if (normalized.includes("/database/") || normalized.includes("/models/") || normalized.includes("/schema/")) {
2875
+ return "database";
2876
+ }
2877
+ if (normalized.includes("/auth/")) {
2878
+ return "auth";
2879
+ }
2880
+ return null;
2881
+ }
2882
+ /**
2883
+ * Infer related files from tags
2884
+ */
2885
+ async inferFilesFromTags(_signal) {
2886
+ return [];
2887
+ }
2888
+ /**
2889
+ * Initialize tag synonyms and related terms
2890
+ * This is our "semantic" understanding without embeddings
2891
+ */
2892
+ initializeTagSynonyms() {
2893
+ return /* @__PURE__ */ new Map([
2894
+ // Auth & Security
2895
+ ["auth", ["authentication", "login", "signin", "credentials", "password"]],
2896
+ ["password", ["credentials", "auth", "hashing", "bcrypt"]],
2897
+ ["security", ["vulnerability", "exploit", "attack", "protection"]],
2898
+ ["encryption", ["crypto", "hashing", "encoding", "security"]],
2899
+ // Payments
2900
+ ["payments", ["billing", "checkout", "stripe", "pricing"]],
2901
+ ["stripe", ["payments", "billing", "api", "checkout"]],
2902
+ ["vat", ["tax", "eu", "compliance", "billing"]],
2903
+ // Database & Performance
2904
+ ["database", ["db", "sql", "query", "storage", "persistence"]],
2905
+ ["cache", ["caching", "redis", "memory", "performance"]],
2906
+ ["performance", ["optimization", "speed", "latency", "cache"]],
2907
+ // Frontend
2908
+ ["ui", ["frontend", "interface", "component", "view"]],
2909
+ ["component", ["ui", "react", "vue", "frontend"]],
2910
+ ["validation", ["form", "input", "error", "ui"]],
2911
+ // Backend & API
2912
+ ["api", ["endpoint", "route", "backend", "server"]],
2913
+ ["endpoint", ["api", "route", "url", "backend"]],
2914
+ ["backend", ["server", "api", "service"]],
2915
+ // Compliance & Legal
2916
+ ["compliance", ["gdpr", "hipaa", "legal", "regulation"]],
2917
+ ["gdpr", ["compliance", "privacy", "eu", "data-protection"]],
2918
+ ["privacy", ["gdpr", "compliance", "data-protection", "security"]]
2919
+ ]);
2920
+ }
2921
+ };
2530
2922
 
2531
- TODO: Implement register agent functionality`
2923
+ // src/extraction/pipeline.ts
2924
+ import { randomBytes } from "crypto";
2925
+ var ExtractionPipeline = class {
2926
+ extractor;
2927
+ enricher;
2928
+ storage;
2929
+ workDir;
2930
+ constructor(options) {
2931
+ this.extractor = new SignalExtractor(options.anthropicApiKey);
2932
+ this.enricher = new MetadataEnricher();
2933
+ this.storage = getStorage(options.workingDirectory);
2934
+ this.workDir = options.workingDirectory;
2935
+ }
2936
+ /**
2937
+ * Process raw content through the entire pipeline
2938
+ */
2939
+ async process(content, context) {
2940
+ console.log("\u{1F50D} Extracting signals from content...");
2941
+ let extractedSignal = await this.extractor.extract(content, context.sourceType, context.sourceId);
2942
+ extractedSignal = this.addIds(extractedSignal, context);
2943
+ console.log(` \u2713 Extracted ${extractedSignal.decisions.length} decisions, ${extractedSignal.facts.length} facts, ${extractedSignal.blockers.length} blockers, ${extractedSignal.questions.length} questions`);
2944
+ console.log("\u{1F3F7}\uFE0F Enriching with metadata...");
2945
+ const { metadata: enrichedMeta } = await this.enricher.enrichSignal(extractedSignal, {
2946
+ workingDirectory: this.workDir
2947
+ });
2948
+ if (enrichedMeta.expandedTags.length > 0) {
2949
+ console.log(` \u2713 Expanded tags: ${enrichedMeta.expandedTags.slice(0, 5).join(", ")}${enrichedMeta.expandedTags.length > 5 ? "..." : ""}`);
2950
+ }
2951
+ if (enrichedMeta.dependencies.length > 0) {
2952
+ console.log(` \u2713 Dependencies: ${enrichedMeta.dependencies.join(", ")}`);
2953
+ }
2954
+ if (enrichedMeta.codebaseArea.length > 0) {
2955
+ console.log(` \u2713 Codebase areas: ${enrichedMeta.codebaseArea.join(", ")}`);
2956
+ }
2957
+ if (enrichedMeta.domain.length > 0) {
2958
+ console.log(` \u2713 Domains: ${enrichedMeta.domain.join(", ")}`);
2959
+ }
2960
+ console.log("\u{1F4BE} Storing in decision ledger...");
2961
+ await this.storage.storeSignal(extractedSignal, {
2962
+ expandedTags: enrichedMeta.expandedTags,
2963
+ dependencies: enrichedMeta.dependencies,
2964
+ codebaseArea: enrichedMeta.codebaseArea,
2965
+ domain: enrichedMeta.domain
2966
+ });
2967
+ console.log("\u2705 Successfully stored in decision ledger");
2968
+ return extractedSignal;
2969
+ }
2970
+ /**
2971
+ * Add IDs and metadata to extracted signal
2972
+ */
2973
+ addIds(signal, context) {
2974
+ const now = (/* @__PURE__ */ new Date()).toISOString();
2975
+ const metadata = {
2976
+ extractedAt: now,
2977
+ sourceType: context.sourceType,
2978
+ extractionModel: "claude-haiku"
2979
+ };
2980
+ if (context.sourceId !== void 0) {
2981
+ metadata.sourceId = context.sourceId;
2982
+ }
2983
+ return {
2984
+ decisions: signal.decisions.map((d) => {
2985
+ const decision = {
2986
+ ...d,
2987
+ id: d.id || this.generateId(),
2988
+ when: d.when || now,
2989
+ status: d.status || "active"
2990
+ };
2991
+ if (context.who !== void 0) {
2992
+ decision.who = d.who || context.who;
2532
2993
  }
2533
- ]
2994
+ return decision;
2995
+ }),
2996
+ facts: signal.facts.map((f) => ({
2997
+ ...f,
2998
+ id: f.id || this.generateId(),
2999
+ when: f.when || now,
3000
+ confidence: f.confidence ?? 0.8
3001
+ })),
3002
+ blockers: signal.blockers.map((b) => ({
3003
+ ...b,
3004
+ id: b.id || this.generateId(),
3005
+ when: b.when || now
3006
+ })),
3007
+ questions: signal.questions.map((q) => ({
3008
+ ...q,
3009
+ id: q.id || this.generateId(),
3010
+ when: q.when || now
3011
+ })),
3012
+ metadata
2534
3013
  };
2535
3014
  }
3015
+ /**
3016
+ * Generate a unique ID
3017
+ */
3018
+ generateId() {
3019
+ return randomBytes(8).toString("hex");
3020
+ }
3021
+ /**
3022
+ * Initialize storage
3023
+ */
3024
+ async initialize() {
3025
+ await this.storage.initialize();
3026
+ }
3027
+ /**
3028
+ * Close storage connections
3029
+ */
3030
+ close() {
3031
+ this.storage.close();
3032
+ }
2536
3033
  };
3034
+ async function processIncident(incidentDescription, options) {
3035
+ const pipeline = new ExtractionPipeline(options);
3036
+ await pipeline.initialize();
3037
+ try {
3038
+ return await pipeline.process(incidentDescription, {
3039
+ sourceType: "incident",
3040
+ sourceId: `incident-${Date.now()}`
3041
+ });
3042
+ } finally {
3043
+ pipeline.close();
3044
+ }
3045
+ }
2537
3046
 
2538
3047
  // src/tools/watch.ts
2539
- import { watch, existsSync as existsSync4, readFileSync } from "fs";
2540
- import { stat } from "fs/promises";
2541
- import { join as join2, extname as extname4, basename as basename2 } from "path";
2542
3048
  var WATCH_EXTENSIONS = /* @__PURE__ */ new Set([
2543
3049
  ".ts",
2544
3050
  ".tsx",
@@ -2565,6 +3071,7 @@ var SKIP_DIRS = /* @__PURE__ */ new Set([
2565
3071
  ]);
2566
3072
  var TrieWatchTool = class {
2567
3073
  scanTool = new TrieScanTool();
3074
+ extractionPipeline = null;
2568
3075
  state = {
2569
3076
  isRunning: false,
2570
3077
  lastScan: /* @__PURE__ */ new Map(),
@@ -2622,6 +3129,14 @@ var TrieWatchTool = class {
2622
3129
  }]
2623
3130
  };
2624
3131
  }
3132
+ const anthropicApiKey = process.env.ANTHROPIC_API_KEY;
3133
+ if (anthropicApiKey) {
3134
+ this.extractionPipeline = new ExtractionPipeline({
3135
+ workingDirectory: directory,
3136
+ anthropicApiKey
3137
+ });
3138
+ await this.extractionPipeline.initialize();
3139
+ }
2625
3140
  this.state.isRunning = true;
2626
3141
  this.state.issueCache.clear();
2627
3142
  this.state.totalIssuesFound = 0;
@@ -2633,6 +3148,7 @@ var TrieWatchTool = class {
2633
3148
  console.error("TRIE AGENT - NOW WATCHING");
2634
3149
  console.error("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n");
2635
3150
  console.error("Your Trie agent is now watching over your codebase.");
3151
+ console.error("Signal extraction: ENABLED (building decision ledger)");
2636
3152
  console.error(`Watching: ${directory}`);
2637
3153
  console.error(`Debounce: ${debounceMs}ms`);
2638
3154
  console.error("");
@@ -2671,23 +3187,30 @@ var TrieWatchTool = class {
2671
3187
  return {
2672
3188
  content: [{
2673
3189
  type: "text",
2674
- text: `**TRIE AGENT ACTIVATED**
3190
+ text: `**TRIE AGENT ACTIVATED**
2675
3191
 
2676
- Your Trie agent is now watching over your codebase. It will warn you about risky changes, remember what broke before, and nudge you when something looks dangerous.
3192
+ Your Trie agent is now autonomously watching and learning from your codebase.
2677
3193
 
2678
3194
  **Watching:** \`${directory}\`
2679
3195
  **Debounce:** ${debounceMs}ms (waits for you to stop typing)
3196
+ **Signal Extraction:** ${process.env.ANTHROPIC_API_KEY ? "\u2713 ENABLED" : "\u26A0\uFE0F LIMITED (set ANTHROPIC_API_KEY for full extraction)"}
2680
3197
 
2681
- ### How it works:
3198
+ ### How the agent works:
2682
3199
  1. [*] You write/edit code
2683
- 2. [#] Guardian detects the change
2684
- 3. [?] Scans for risks based on your project's history
2685
- 4. [>] Nudges you in plain English if something looks risky
3200
+ 2. [#] Agent detects the change
3201
+ 3. [\u{1F9E0}] Extracts decisions, facts, blockers \u2192 stores in ledger
3202
+ 4. [?] Predicts risks based on historical patterns
3203
+ 5. [>] Nudges you in plain English if something looks risky
3204
+
3205
+ ### The agent learns:
3206
+ - Every commit builds the decision ledger
3207
+ - \`trie gotcha\` queries the ledger for predictions
3208
+ - \`trie ok\` / \`trie bad\` teach the agent what matters (coming soon)
2686
3209
 
2687
3210
  ### Commands:
2688
- - \`trie_watch status\` - See guardian status
3211
+ - \`trie_watch status\` - See agent status
2689
3212
  - \`trie_watch issues\` - Get all issues found so far
2690
- - \`trie_watch stop\` - Stop the guardian
3213
+ - \`trie_watch stop\` - Stop the agent
2691
3214
 
2692
3215
  ---
2693
3216
 
@@ -2717,8 +3240,8 @@ ${initialResult.content?.[0]?.text || "Initial scan complete."}`
2717
3240
  }, debounceMs);
2718
3241
  });
2719
3242
  this.watchers.set(dir, watcher);
2720
- const { readdir: readdir3 } = await import("fs/promises");
2721
- const entries = await readdir3(dir, { withFileTypes: true });
3243
+ const { readdir: readdir2 } = await import("fs/promises");
3244
+ const entries = await readdir2(dir, { withFileTypes: true });
2722
3245
  for (const entry of entries) {
2723
3246
  if (entry.isDirectory()) {
2724
3247
  await this.watchDirectory(join2(dir, entry.name), debounceMs);
@@ -2747,6 +3270,52 @@ Detected changes in ${files.length} file(s):`);
2747
3270
  console.error("");
2748
3271
  }
2749
3272
  try {
3273
+ if (this.extractionPipeline) {
3274
+ try {
3275
+ const fileContents = await Promise.all(
3276
+ files.map(async (file) => {
3277
+ try {
3278
+ const content = await readFile4(file, "utf-8");
3279
+ return { file, content };
3280
+ } catch {
3281
+ return null;
3282
+ }
3283
+ })
3284
+ );
3285
+ const validFiles = fileContents.filter((f) => f !== null);
3286
+ if (validFiles.length > 0) {
3287
+ const combinedContent = validFiles.map(
3288
+ (f) => `File: ${basename2(f.file)}
3289
+ ${f.content.slice(0, 1e3)}`
3290
+ // First 1KB of each file
3291
+ ).join("\n\n---\n\n");
3292
+ if (!isInteractiveMode()) {
3293
+ console.error("\u{1F9E0} Extracting signals from changes...");
3294
+ }
3295
+ const signal = await this.extractionPipeline.process(combinedContent, {
3296
+ sourceType: "file",
3297
+ sourceId: `watch-${Date.now()}`
3298
+ });
3299
+ if (signal.decisions.length > 0 || signal.facts.length > 0 || signal.blockers.length > 0) {
3300
+ if (!isInteractiveMode()) {
3301
+ console.error(` \u2713 Extracted: ${signal.decisions.length} decisions, ${signal.facts.length} facts, ${signal.blockers.length} blockers`);
3302
+ }
3303
+ if (this.streamingManager) {
3304
+ this.streamingManager.reportSignalExtraction({
3305
+ decisions: signal.decisions.length,
3306
+ facts: signal.facts.length,
3307
+ blockers: signal.blockers.length,
3308
+ questions: signal.questions.length
3309
+ });
3310
+ }
3311
+ }
3312
+ }
3313
+ } catch (error) {
3314
+ if (!isInteractiveMode()) {
3315
+ console.error(` \u26A0\uFE0F Signal extraction failed: ${error}`);
3316
+ }
3317
+ }
3318
+ }
2750
3319
  if (this.streamingManager) {
2751
3320
  for (const file of files) {
2752
3321
  this.streamingManager.reportWatchChange(file);
@@ -2921,6 +3490,10 @@ Found ${newIssues} issues in changed files!`);
2921
3490
  watcher.close();
2922
3491
  }
2923
3492
  this.watchers.clear();
3493
+ if (this.extractionPipeline) {
3494
+ this.extractionPipeline.close();
3495
+ this.extractionPipeline = null;
3496
+ }
2924
3497
  if (this.state.scanDebounceTimer) {
2925
3498
  clearTimeout(this.state.scanDebounceTimer);
2926
3499
  }
@@ -2941,14 +3514,16 @@ Found ${newIssues} issues in changed files!`);
2941
3514
  return {
2942
3515
  content: [{
2943
3516
  type: "text",
2944
- text: `[*] **AUTONOMOUS WATCH MODE STOPPED**
3517
+ text: `[*] **TRIE AGENT STOPPED** \u{1F916}
2945
3518
 
2946
3519
  ### Session Summary:
2947
3520
  - Files scanned: ${this.state.filesScanned}
2948
3521
  - Total issues found: ${this.state.totalIssuesFound}
2949
3522
  - Directories watched: ${this.watchers.size}
3523
+ - Decision ledger: Updated continuously
2950
3524
 
2951
- Use \`trie_watch start\` to start watching again.`
3525
+ The agent's learning has been stored in the decision ledger.
3526
+ Use \`trie_watch start\` to resume autonomous operation.`
2952
3527
  }]
2953
3528
  };
2954
3529
  }
@@ -2972,7 +3547,7 @@ Use \`trie_watch start\` to begin autonomous scanning.`
2972
3547
  ).join("\n");
2973
3548
  let agencyStatus = "";
2974
3549
  try {
2975
- const { getGuardian } = await import("./guardian-agent-ZHJXLBOU.js");
3550
+ const { getGuardian } = await import("./guardian-agent-M352CBE5.js");
2976
3551
  const guardian = getGuardian(getWorkingDirectory(void 0, true));
2977
3552
  await guardian.initialize();
2978
3553
  const status = await guardian.getAgencyStatus();
@@ -3018,1226 +3593,66 @@ ${recentNudges || "(none)"}
3018
3593
  text: `[#] Recent nudges (${this.state.nudges.length} this session)
3019
3594
  ` + (this.state.nudges.length ? this.state.nudges.map(
3020
3595
  (n) => `- ${basename2(n.file)} [${n.severity}] @ ${n.timestamp}
3021
- ${n.message}`
3022
- ).join("\n") : "(none)")
3023
- },
3024
- {
3025
- type: "json",
3026
- json: this.state.nudges
3027
- }
3028
- ]
3029
- };
3030
- }
3031
- getCurrentIssues() {
3032
- return {
3033
- content: [{
3034
- type: "text",
3035
- text: `[L] **Issues Found This Session**
3036
-
3037
- Total issues: ${this.state.totalIssuesFound}
3038
- Files scanned: ${this.state.filesScanned}
3039
-
3040
- To get a full report, run \`trie_scan\` on your codebase.`
3041
- }]
3042
- };
3043
- }
3044
- };
3045
-
3046
- // src/tools/agent.ts
3047
- import { readdir, readFile as readFile4 } from "fs/promises";
3048
- import { existsSync as existsSync5 } from "fs";
3049
- import { join as join3, extname as extname5, isAbsolute as isAbsolute4, resolve as resolve4, basename as basename3 } from "path";
3050
-
3051
- // src/knowledge/index.ts
3052
- var SECURITY_SOURCES = [
3053
- {
3054
- name: "OWASP Top 10",
3055
- url: "https://owasp.org/Top10/",
3056
- description: "Most critical web application security risks"
3057
- },
3058
- {
3059
- name: "NIST NVD",
3060
- url: "https://nvd.nist.gov/",
3061
- description: "National Vulnerability Database"
3062
- },
3063
- {
3064
- name: "CVE Database",
3065
- url: "https://cve.mitre.org/",
3066
- description: "Common Vulnerabilities and Exposures"
3067
- },
3068
- {
3069
- name: "Snyk Vulnerability DB",
3070
- url: "https://security.snyk.io/",
3071
- description: "Open source vulnerability database"
3072
- },
3073
- {
3074
- name: "GitHub Advisory Database",
3075
- url: "https://github.com/advisories",
3076
- description: "Security advisories from GitHub"
3077
- }
3078
- ];
3079
- var DOCS_SOURCES = {
3080
- react: [
3081
- { name: "React Docs", url: "https://react.dev/", description: "Official React documentation" },
3082
- { name: "React Security", url: "https://react.dev/reference/react-dom/components/common#dangerously-setting-the-inner-html", description: "React security guidance" }
3083
- ],
3084
- nextjs: [
3085
- { name: "Next.js Docs", url: "https://nextjs.org/docs", description: "Official Next.js documentation" },
3086
- { name: "Next.js Security", url: "https://nextjs.org/docs/advanced-features/security-headers", description: "Next.js security headers" }
3087
- ],
3088
- express: [
3089
- { name: "Express Docs", url: "https://expressjs.com/", description: "Official Express.js documentation" },
3090
- { name: "Express Security", url: "https://expressjs.com/en/advanced/best-practice-security.html", description: "Express security best practices" }
3091
- ],
3092
- node: [
3093
- { name: "Node.js Docs", url: "https://nodejs.org/docs/", description: "Official Node.js documentation" },
3094
- { name: "Node.js Security", url: "https://nodejs.org/en/docs/guides/security/", description: "Node.js security guidance" }
3095
- ],
3096
- typescript: [
3097
- { name: "TypeScript Docs", url: "https://www.typescriptlang.org/docs/", description: "Official TypeScript documentation" }
3098
- ]
3099
- };
3100
- var COMPLIANCE_SOURCES = {
3101
- gdpr: [
3102
- { name: "GDPR Official Text", url: "https://gdpr.eu/", description: "Complete GDPR regulation text" },
3103
- { name: "GDPR Checklist", url: "https://gdpr.eu/checklist/", description: "GDPR compliance checklist" }
3104
- ],
3105
- hipaa: [
3106
- { name: "HIPAA Guidelines", url: "https://www.hhs.gov/hipaa/", description: "Official HIPAA guidance" }
3107
- ],
3108
- wcag: [
3109
- { name: "WCAG 2.1", url: "https://www.w3.org/WAI/WCAG21/quickref/", description: "WCAG 2.1 quick reference" }
3110
- ],
3111
- pci: [
3112
- { name: "PCI DSS", url: "https://www.pcisecuritystandards.org/", description: "Payment Card Industry standards" }
3113
- ]
3114
- };
3115
- function generateCVELookup(library, version) {
3116
- let prompt = `## \u{1F512} Security Vulnerability Lookup
3117
-
3118
- `;
3119
- prompt += `**Library:** ${library}
3120
- `;
3121
- if (version) prompt += `**Version:** ${version}
3122
- `;
3123
- prompt += `
3124
- `;
3125
- prompt += `### Action Required
3126
-
3127
- `;
3128
- prompt += `Please check for known vulnerabilities:
3129
-
3130
- `;
3131
- prompt += `1. Search the **NIST NVD** (https://nvd.nist.gov/) for CVEs affecting \`${library}\`
3132
- `;
3133
- prompt += `2. Check **Snyk** (https://security.snyk.io/) for vulnerability reports
3134
- `;
3135
- prompt += `3. Review **GitHub Advisory Database** for any security advisories
3136
- `;
3137
- prompt += `4. Check npm audit / yarn audit if it's an npm package
3138
-
3139
- `;
3140
- prompt += `### Report Format
3141
-
3142
- `;
3143
- prompt += `For each vulnerability found, provide:
3144
- `;
3145
- prompt += `- CVE ID (if applicable)
3146
- `;
3147
- prompt += `- Severity (Critical/High/Medium/Low)
3148
- `;
3149
- prompt += `- Affected versions
3150
- `;
3151
- prompt += `- Description of the vulnerability
3152
- `;
3153
- prompt += `- Remediation (upgrade version, patches, mitigations)
3154
- `;
3155
- return prompt;
3156
- }
3157
- function generateDocsLookup(topic, framework) {
3158
- let prompt = `## \u{1F4DA} Documentation Lookup
3159
-
3160
- `;
3161
- prompt += `**Topic:** ${topic}
3162
- `;
3163
- if (framework) prompt += `**Framework:** ${framework}
3164
- `;
3165
- prompt += `
3166
- `;
3167
- const sources = framework ? DOCS_SOURCES[framework.toLowerCase()] : [];
3168
- if (sources && sources.length > 0) {
3169
- prompt += `### Recommended Sources
3170
-
3171
- `;
3172
- for (const source of sources) {
3173
- prompt += `- [${source.name}](${source.url}) - ${source.description}
3174
- `;
3175
- }
3176
- prompt += `
3177
- `;
3178
- }
3179
- prompt += `### Information Needed
3180
-
3181
- `;
3182
- prompt += `Please look up the latest documentation and provide:
3183
-
3184
- `;
3185
- prompt += `1. Current best practices for "${topic}"
3186
- `;
3187
- prompt += `2. Common pitfalls to avoid
3188
- `;
3189
- prompt += `3. Code examples demonstrating correct usage
3190
- `;
3191
- prompt += `4. Any recent changes or deprecations
3192
- `;
3193
- return prompt;
3194
- }
3195
- function generateSecurityLookup(pattern, context) {
3196
- let prompt = `## \u{1F6E1}\uFE0F Security Best Practices Lookup
3197
-
3198
- `;
3199
- prompt += `**Pattern:** ${pattern}
3200
- `;
3201
- if (context) prompt += `**Context:** ${context}
3202
- `;
3203
- prompt += `
3204
- `;
3205
- prompt += `### Reference Sources
3206
-
3207
- `;
3208
- for (const source of SECURITY_SOURCES.slice(0, 3)) {
3209
- prompt += `- [${source.name}](${source.url})
3210
- `;
3211
- }
3212
- prompt += `
3213
- `;
3214
- prompt += `### Analysis Requested
3215
-
3216
- `;
3217
- prompt += `Please research and provide:
3218
-
3219
- `;
3220
- prompt += `1. **OWASP guidance** for this security pattern
3221
- `;
3222
- prompt += `2. **Attack vectors** - how this could be exploited
3223
- `;
3224
- prompt += `3. **Defense strategies** - recommended mitigations
3225
- `;
3226
- prompt += `4. **Code examples** - secure implementation patterns
3227
- `;
3228
- prompt += `5. **Testing approaches** - how to verify security
3229
- `;
3230
- return prompt;
3231
- }
3232
- function generateComplianceLookup(regulation, requirement) {
3233
- let prompt = `## \u2696\uFE0F Compliance Requirement Lookup
3234
-
3235
- `;
3236
- prompt += `**Regulation:** ${regulation}
3237
- `;
3238
- if (requirement) prompt += `**Specific Requirement:** ${requirement}
3239
- `;
3240
- prompt += `
3241
- `;
3242
- const sources = COMPLIANCE_SOURCES[regulation.toLowerCase()];
3243
- if (sources && sources.length > 0) {
3244
- prompt += `### Official Sources
3245
-
3246
- `;
3247
- for (const source of sources) {
3248
- prompt += `- [${source.name}](${source.url})
3249
- `;
3250
- }
3251
- prompt += `
3252
- `;
3253
- }
3254
- prompt += `### Compliance Information Needed
3255
-
3256
- `;
3257
- prompt += `Please research and provide:
3258
-
3259
- `;
3260
- prompt += `1. **Specific requirement text** from the regulation
3261
- `;
3262
- prompt += `2. **Technical requirements** for compliance
3263
- `;
3264
- prompt += `3. **Implementation guidance** with code examples
3265
- `;
3266
- prompt += `4. **Documentation requirements** - what records to keep
3267
- `;
3268
- prompt += `5. **Penalties** for non-compliance
3269
- `;
3270
- return prompt;
3271
- }
3272
- function generateChangelogLookup(library, fromVersion, toVersion) {
3273
- let prompt = `## \u{1F4CB} Changelog Lookup
3274
-
3275
- `;
3276
- prompt += `**Library:** ${library}
3277
- `;
3278
- prompt += `**Current Version:** ${fromVersion}
3279
- `;
3280
- if (toVersion) prompt += `**Target Version:** ${toVersion}
3281
- `;
3282
- prompt += `
3283
- `;
3284
- prompt += `### Information Needed
3285
-
3286
- `;
3287
- prompt += `Please find the changelog/release notes and provide:
3288
-
3289
- `;
3290
- prompt += `1. **Breaking changes** between versions
3291
- `;
3292
- prompt += `2. **New features** added
3293
- `;
3294
- prompt += `3. **Deprecations** to be aware of
3295
- `;
3296
- prompt += `4. **Security fixes** included
3297
- `;
3298
- prompt += `5. **Migration guide** if available
3299
- `;
3300
- prompt += `6. **Known issues** with the upgrade
3301
- `;
3302
- return prompt;
3303
- }
3304
- function lookupKnowledge(request2) {
3305
- const { type, query, context = {} } = request2;
3306
- switch (type) {
3307
- case "cve":
3308
- return generateCVELookup(query, context.version);
3309
- case "docs":
3310
- return generateDocsLookup(query, context.framework);
3311
- case "security":
3312
- return generateSecurityLookup(query, context.context);
3313
- case "best-practices":
3314
- return generateComplianceLookup(query, context.requirement);
3315
- case "changelog":
3316
- return generateChangelogLookup(query, context.fromVersion || "current", context.toVersion);
3317
- default:
3318
- return `Unknown knowledge request type: ${type}`;
3319
- }
3320
- }
3321
-
3322
- // src/tools/agent.ts
3323
- var SCANNABLE_EXTENSIONS = /* @__PURE__ */ new Set([
3324
- ".ts",
3325
- ".tsx",
3326
- ".js",
3327
- ".jsx",
3328
- ".mjs",
3329
- ".cjs",
3330
- ".vue",
3331
- ".svelte",
3332
- ".astro",
3333
- ".py",
3334
- ".go",
3335
- ".rs"
3336
- ]);
3337
- var SKIP_DIRS2 = /* @__PURE__ */ new Set([
3338
- "node_modules",
3339
- ".git",
3340
- "dist",
3341
- "build",
3342
- ".next",
3343
- ".nuxt",
3344
- "coverage",
3345
- ".nyc_output",
3346
- "__pycache__",
3347
- ".pytest_cache",
3348
- "vendor",
3349
- ".venv",
3350
- "venv",
3351
- "target",
3352
- ".turbo",
3353
- ".cache"
3354
- ]);
3355
- var TrieAgentTool = class {
3356
- agentRegistry = getSkillRegistry();
3357
- customSkillsLoaded = false;
3358
- /**
3359
- * Ensure custom skills are loaded before using the registry
3360
- */
3361
- async ensureCustomSkillsLoaded() {
3362
- if (!this.customSkillsLoaded) {
3363
- await this.agentRegistry.loadCustomSkills();
3364
- this.customSkillsLoaded = true;
3365
- }
3366
- }
3367
- async execute(args) {
3368
- const { agent, files, directory, depth: _depth = "standard", lookup, output = "full" } = args;
3369
- if (lookup) {
3370
- return this.handleKnowledgeLookup(lookup);
3371
- }
3372
- await this.ensureCustomSkillsLoaded();
3373
- if (!agent) {
3374
- return this.listSkills();
3375
- }
3376
- const agentInstance = this.agentRegistry.getSkill(agent);
3377
- if (!agentInstance) {
3378
- return {
3379
- content: [{
3380
- type: "text",
3381
- text: `Skill not found: ${agent}
3382
-
3383
- Available skills:
3384
- ${this.agentRegistry.getSkillNames().map((n) => `- ${n}`).join("\n")}`
3385
- }]
3386
- };
3387
- }
3388
- const workDir = getWorkingDirectory(directory);
3389
- let filesToScan = files || [];
3390
- if (!filesToScan.length) {
3391
- console.error(`
3392
- Discovering files in: ${workDir}`);
3393
- filesToScan = await this.discoverFiles(workDir);
3394
- console.error(` Found ${filesToScan.length} files
3395
- `);
3396
- } else {
3397
- filesToScan = filesToScan.map(
3398
- (f) => isAbsolute4(f) ? f : resolve4(workDir, f)
3399
- );
3400
- }
3401
- const validFiles = filesToScan.filter((f) => existsSync5(f));
3402
- if (validFiles.length === 0) {
3403
- return {
3404
- content: [{
3405
- type: "text",
3406
- text: `No valid files found to scan.`
3407
- }]
3408
- };
3409
- }
3410
- const startTime = Date.now();
3411
- return this.runSkillScan(agentInstance, validFiles, startTime, output);
3412
- }
3413
- /**
3414
- * Run agent scan using the new hybrid AI system
3415
- * All agents now use scan() which has pattern detection + optional AI enhancement
3416
- */
3417
- async runSkillScan(agentInstance, files, startTime, _outputMode) {
3418
- console.error(`
3419
- \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501`);
3420
- console.error(`Running ${agentInstance.name.toUpperCase()} analysis`);
3421
- console.error(`\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
3422
- `);
3423
- console.error(`${agentInstance.description}`);
3424
- console.error(`\u{1F4C2} Scanning ${files.length} files...`);
3425
- console.error(` (Pattern detection + AI enhancement if API key is set)
3426
- `);
3427
- try {
3428
- const result = await agentInstance.scan(files, { workingDir: getWorkingDirectory(void 0, true) });
3429
- const executionTime = Date.now() - startTime;
3430
- return {
3431
- content: [{
3432
- type: "text",
3433
- text: await this.formatSkillResult(agentInstance.name, result.issues, files, executionTime)
3434
- }]
3435
- };
3436
- } catch (error) {
3437
- return {
3438
- content: [{
3439
- type: "text",
3440
- text: `Skill error: ${error instanceof Error ? error.message : String(error)}`
3441
- }]
3442
- };
3443
- }
3444
- }
3445
- handleKnowledgeLookup(lookup) {
3446
- const result = lookupKnowledge({
3447
- type: lookup.type,
3448
- query: lookup.query,
3449
- context: lookup.context ?? {}
3450
- });
3451
- return {
3452
- content: [{
3453
- type: "text",
3454
- text: result
3455
- }]
3456
- };
3457
- }
3458
- listSkills() {
3459
- const skills = this.agentRegistry.getSkillDescriptions();
3460
- const skillList = skills.map((a) => {
3461
- const command = this.getSkillCommand(a.name);
3462
- return `| \`${command}\` | [PATTERN+AI] ${a.name} | ${a.description} |`;
3463
- }).join("\n");
3464
- return {
3465
- content: [{
3466
- type: "text",
3467
- text: `# \u{1F916} Available Skills
3468
-
3469
- | Command | Skill | Description |
3470
- |---------|-------|-------------|
3471
- ${skillList}
3472
-
3473
- **Legend:** [PATTERN+AI] = Pattern detection + AI enhancement (if ANTHROPIC_API_KEY is set)
3474
-
3475
- ## Usage
3476
-
3477
- ### Run a specific skill:
3478
- \`\`\`
3479
- trie_security # Security vulnerabilities
3480
- trie_privacy # Privacy/GDPR compliance
3481
- trie_accessibility # WCAG accessibility audit
3482
- trie_bugs # Bug detection
3483
- trie_ux # User experience testing
3484
- trie_types # Type safety analysis
3485
- trie_architecture # Architecture review
3486
- trie_devops # DevOps readiness
3487
- trie_legal # Legal compliance
3488
- \`\`\`
3489
-
3490
- ### With options:
3491
- \`\`\`
3492
- trie_security files:["src/auth.ts"] depth:"deep"
3493
- \`\`\`
3494
-
3495
- ### Knowledge lookup:
3496
- \`\`\`
3497
- trie_security lookup:{type:"cve", query:"lodash"}
3498
- trie_security lookup:{type:"docs", query:"XSS prevention", context:{framework:"react"}}
3499
- \`\`\`
3500
-
3501
- ### Run all skills:
3502
- \`\`\`
3503
- trie_scan # Full scan with smart triaging
3504
- \`\`\``
3505
- }]
3506
- };
3507
- }
3508
- getSkillCommand(agentName) {
3509
- const commandMap = {
3510
- "security": "trie_security",
3511
- "privacy": "trie_privacy",
3512
- "legal": "trie_legal",
3513
- "accessibility": "trie_accessibility",
3514
- "design-engineer": "trie_design",
3515
- "software-architect": "trie_architecture",
3516
- "bug-finding": "trie_bugs",
3517
- "user-testing": "trie_ux",
3518
- "typecheck": "trie_types",
3519
- "devops": "trie_devops",
3520
- "comprehension": "trie_explain",
3521
- "test": "trie_test"
3522
- };
3523
- return commandMap[agentName] || `trie_scan --skill ${agentName}`;
3524
- }
3525
- async formatSkillResult(agentName, issues, files, executionTime) {
3526
- const critical = issues.filter((i) => i.severity === "critical").length;
3527
- const serious = issues.filter((i) => i.severity === "serious").length;
3528
- const moderate = issues.filter((i) => i.severity === "moderate").length;
3529
- const low = issues.filter((i) => i.severity === "low").length;
3530
- const agentEmoji = this.getSkillEmoji(agentName);
3531
- let output = `
3532
- `;
3533
- output += `# ${agentEmoji} ${agentName.toUpperCase()} SCAN
3534
-
3535
- `;
3536
- output += `**Files:** ${files.length} | **Time:** ${(executionTime / 1e3).toFixed(2)}s
3537
-
3538
- `;
3539
- if (issues.length === 0) {
3540
- output += `## No Issues Found
3541
-
3542
- `;
3543
- output += `Your code passed all ${agentName} checks.
3544
-
3545
- `;
3546
- return output;
3547
- }
3548
- output += `## ${issues.length} Issues Found
3549
-
3550
- `;
3551
- if (critical > 0) output += `[!] ${critical} Critical `;
3552
- if (serious > 0) output += `[!] ${serious} Serious `;
3553
- if (moderate > 0) output += `[~] ${moderate} Moderate `;
3554
- if (low > 0) output += `[-] ${low} Low`;
3555
- output += `
3556
-
3557
- `;
3558
- const sorted = [...issues].sort((a, b) => {
3559
- const severityOrder = { critical: 0, serious: 1, moderate: 2, low: 3 };
3560
- if (severityOrder[a.severity] !== severityOrder[b.severity]) {
3561
- return severityOrder[a.severity] - severityOrder[b.severity];
3562
- }
3563
- return (a.line || 0) - (b.line || 0);
3564
- });
3565
- for (const issue of sorted) {
3566
- const icon = { critical: "[!]", serious: "[!]", moderate: "[~]", low: "[-]" }[issue.severity];
3567
- output += `---
3568
-
3569
- `;
3570
- output += `${icon} **${issue.issue}**
3571
-
3572
- `;
3573
- output += `\`${issue.file}:${issue.line || "?"}\`
3574
-
3575
- `;
3576
- const snippet = await this.getCodeSnippet(issue.file, issue.line);
3577
- if (snippet) {
3578
- output += `\`\`\`
3579
- ${snippet}
3580
- \`\`\`
3581
-
3582
- `;
3583
- }
3584
- output += `**Fix:** ${issue.fix}
3585
-
3586
- `;
3587
- if (issue.cwe) output += `CWE: ${issue.cwe}
3588
- `;
3589
- if (issue.regulation) output += `Regulation: ${issue.regulation}
3590
- `;
3591
- output += `<details>
3592
- <summary>Prompt to fix this</summary>
3593
-
3594
- `;
3595
- output += `\`\`\`
3596
- Fix the ${issue.issue.toLowerCase()} in ${basename3(issue.file)}${issue.line ? ` at line ${issue.line}` : ""}.
3597
-
3598
- ${issue.fix}
3599
- \`\`\`
3600
-
3601
- `;
3602
- output += `</details>
3603
-
3604
- `;
3605
- }
3606
- output += `---
3607
- `;
3608
- output += `*${agentName} scan completed in ${(executionTime / 1e3).toFixed(2)}s*
3609
- `;
3610
- return output;
3611
- }
3612
- /**
3613
- * Get a code snippet around a specific line
3614
- */
3615
- async getCodeSnippet(filePath, line) {
3616
- if (!line || !existsSync5(filePath)) return null;
3617
- try {
3618
- const content = await readFile4(filePath, "utf-8");
3619
- const lines = content.split("\n");
3620
- const start = Math.max(0, line - 3);
3621
- const end = Math.min(lines.length, line + 2);
3622
- return lines.slice(start, end).map((l, idx) => {
3623
- const lineNum = start + idx + 1;
3624
- const marker = lineNum === line ? "\u2192" : " ";
3625
- return `${marker} ${lineNum.toString().padStart(4)} | ${l}`;
3626
- }).join("\n");
3627
- } catch {
3628
- return null;
3629
- }
3630
- }
3631
- getSkillEmoji(agentName) {
3632
- const emojis = {
3633
- "security": "[SEC]",
3634
- "privacy": "[PRIV]",
3635
- "legal": "[LEGAL]",
3636
- "accessibility": "[A11Y]",
3637
- "design-engineer": "[DESIGN]",
3638
- "software-architect": "[ARCH]",
3639
- "bug-finding": "[BUG]",
3640
- "user-testing": "[TEST]",
3641
- "typecheck": "[TYPE]",
3642
- "devops": "[OPS]",
3643
- "comprehension": "[DOC]",
3644
- "test": "[TEST]"
3645
- };
3646
- return emojis[agentName] || "[?]";
3647
- }
3648
- async discoverFiles(dir, maxFiles = 200) {
3649
- const files = [];
3650
- async function walk(currentDir) {
3651
- if (files.length >= maxFiles) return;
3652
- try {
3653
- const entries = await readdir(currentDir, { withFileTypes: true });
3654
- for (const entry of entries) {
3655
- if (files.length >= maxFiles) break;
3656
- const fullPath = join3(currentDir, entry.name);
3657
- if (entry.isDirectory()) {
3658
- if (!SKIP_DIRS2.has(entry.name) && !entry.name.startsWith(".")) {
3659
- await walk(fullPath);
3660
- }
3661
- } else if (entry.isFile()) {
3662
- const ext = extname5(entry.name).toLowerCase();
3663
- if (SCANNABLE_EXTENSIONS.has(ext)) {
3664
- files.push(fullPath);
3665
- }
3666
- }
3667
- }
3668
- } catch (error) {
3669
- }
3670
- }
3671
- await walk(dir);
3672
- return files;
3673
- }
3674
- };
3675
-
3676
- // src/tools/create-agent.ts
3677
- import { existsSync as existsSync6 } from "fs";
3678
- import { mkdir, writeFile } from "fs/promises";
3679
- import { join as join4, basename as basename4, extname as extname6 } from "path";
3680
- var TrieCreateAgentTool = class {
3681
- async execute(args) {
3682
- const { filePath, documentContent, agentName, displayName, description, category } = args;
3683
- if (!agentName) {
3684
- return this.errorResponse("Missing required parameter: agentName");
3685
- }
3686
- if (!filePath && !documentContent) {
3687
- return this.errorResponse(
3688
- "Provide either filePath (path to PDF/TXT/MD file) or documentContent (raw text from drag-and-drop)"
3689
- );
3690
- }
3691
- try {
3692
- let rawText;
3693
- let title = agentName;
3694
- let wordCount = 0;
3695
- if (filePath) {
3696
- if (!existsSync6(filePath)) {
3697
- return this.errorResponse(`File not found: ${filePath}`);
3698
- }
3699
- const ext = filePath.toLowerCase().split(".").pop();
3700
- if (!["pdf", "txt", "md", "markdown", "rtf"].includes(ext || "")) {
3701
- return this.errorResponse(
3702
- `Unsupported file type: .${ext}
3703
- Supported types: .pdf, .txt, .md, .rtf`
3704
- );
3705
- }
3706
- const document = await parseDocument(filePath);
3707
- rawText = document.rawText;
3708
- title = document.metadata.title || basename4(filePath, extname6(filePath));
3709
- wordCount = document.metadata.wordCount;
3710
- } else {
3711
- rawText = documentContent;
3712
- wordCount = rawText.split(/\s+/).filter((w) => w.length > 0).length;
3713
- const firstLine = rawText.split("\n")[0]?.trim();
3714
- if (firstLine && firstLine.length < 100) {
3715
- title = firstLine;
3716
- }
3717
- }
3718
- const chunks = this.chunkText(rawText, 6e3);
3719
- const extractionPrompt = this.buildExtractionPrompt(
3720
- chunks,
3721
- title,
3722
- agentName,
3723
- category,
3724
- displayName,
3725
- description
3726
- );
3727
- return {
3728
- content: [
3729
- {
3730
- type: "text",
3731
- text: this.formatExtractionRequest(
3732
- agentName,
3733
- title,
3734
- wordCount,
3735
- chunks.length,
3736
- extractionPrompt
3737
- )
3738
- }
3739
- ]
3740
- };
3741
- } catch (error) {
3742
- const errorMessage = error instanceof Error ? error.message : String(error);
3743
- return this.errorResponse(`Failed to parse document: ${errorMessage}`);
3744
- }
3745
- }
3746
- /**
3747
- * Chunk text into manageable pieces
3748
- */
3749
- chunkText(text, maxChunkSize) {
3750
- if (text.length <= maxChunkSize) {
3751
- return [text];
3752
- }
3753
- const chunks = [];
3754
- const paragraphs = text.split(/\n\s*\n/);
3755
- let currentChunk = "";
3756
- for (const para of paragraphs) {
3757
- if (currentChunk.length + para.length + 2 > maxChunkSize) {
3758
- if (currentChunk) chunks.push(currentChunk.trim());
3759
- currentChunk = para;
3760
- } else {
3761
- currentChunk += (currentChunk ? "\n\n" : "") + para;
3762
- }
3763
- }
3764
- if (currentChunk) chunks.push(currentChunk.trim());
3765
- return chunks;
3766
- }
3767
- /**
3768
- * Build the extraction prompt for Claude
3769
- */
3770
- buildExtractionPrompt(chunks, title, agentName, category, displayName, description) {
3771
- const prefix = agentName.toUpperCase().replace(/[^A-Z]/g, "").slice(0, 4) || "CUST";
3772
- const documentContent = chunks.length === 1 ? chunks[0] : chunks.map((c, i) => `--- SECTION ${i + 1}/${chunks.length} ---
3773
- ${c}`).join("\n\n");
3774
- return `# Create Code Review Agent: "${displayName || this.formatDisplayName(agentName)}"
3775
-
3776
- ## Your Task
3777
- Analyze the following document and extract structured knowledge to create a code review agent.
3778
-
3779
- ## Document Information
3780
- - **Title**: ${title}
3781
- - **Agent Name**: ${agentName}
3782
- - **Category**: ${category || "auto-detect"}
3783
- ${description ? `- **Description**: ${description}` : ""}
3784
-
3785
- ## Document Content
3786
- ${documentContent}
3787
-
3788
- ---
3789
-
3790
- ## Instructions
3791
-
3792
- Please analyze this document and produce a **single JSON object** with the following structure. This will be used to create a custom code review agent.
3793
-
3794
- **IMPORTANT**: Your response should be ONLY the JSON object, no other text.
3795
-
3796
- \`\`\`json
3797
- {
3798
- "agentConfig": {
3799
- "name": "${this.sanitizeAgentName(agentName)}",
3800
- "displayName": "${displayName || this.formatDisplayName(agentName)}",
3801
- "description": "${description || `Code review agent based on ${title}`}",
3802
- "version": "1.0.0",
3803
- "category": "string (technical | legal | policy | security | architecture | general)"
3804
- },
3805
- "knowledge": {
3806
- "domain": "string (technical | legal | policy | security | architecture | general)",
3807
- "summary": "2-3 paragraph summary of the document's key insights for code review",
3808
- "coreConcepts": [
3809
- {
3810
- "name": "string",
3811
- "description": "string",
3812
- "importance": "critical | important | supplementary",
3813
- "keywords": ["string"]
3814
- }
3815
- ],
3816
- "bestPractices": [
3817
- {
3818
- "name": "string",
3819
- "description": "string",
3820
- "rationale": "why this is important",
3821
- "codeExample": "optional code example or null"
3822
- }
3823
- ],
3824
- "antiPatterns": [
3825
- {
3826
- "name": "string",
3827
- "description": "string",
3828
- "whyBad": "why to avoid",
3829
- "betterAlternative": "what to do instead"
3830
- }
3831
- ],
3832
- "glossary": {
3833
- "term": "definition"
3834
- }
3835
- },
3836
- "detectionRules": [
3837
- {
3838
- "id": "${prefix}-001",
3839
- "name": "Rule Name",
3840
- "description": "What this rule detects",
3841
- "severity": "critical | serious | moderate | low | info",
3842
- "patterns": {
3843
- "regex": ["JavaScript regex patterns"],
3844
- "keywords": ["words that indicate this issue"],
3845
- "semantic": "Natural language description for AI detection"
3846
- },
3847
- "fix": {
3848
- "description": "How to fix this issue",
3849
- "example": "Code example or null",
3850
- "autoFixable": false
3851
- },
3852
- "category": "string"
3853
- }
3854
- ],
3855
- "prompts": {
3856
- "systemPrompt": "You are an expert code reviewer specializing in [topic]. Your role is to...",
3857
- "analysisPrompt": "Review this code for issues related to [topic]. Look for: ...\\n\\nCode:\\n\\\`\\\`\\\`{{language}}\\n{{code}}\\n\\\`\\\`\\\`\\n\\nFile: {{filePath}}",
3858
- "fixPrompt": "Fix this issue: {{issue}}\\n\\nCode:\\n\\\`\\\`\\\`{{language}}\\n{{code}}\\n\\\`\\\`\\\`"
3859
- }
3860
- }
3861
- \`\`\`
3862
-
3863
- ## Guidelines
3864
-
3865
- 1. **Core Concepts**: Extract 10-20 key concepts that are fundamental to the material
3866
- 2. **Best Practices**: Extract 10-15 recommended approaches with rationale
3867
- 3. **Anti-Patterns**: Extract 10-15 things to avoid with explanations
3868
- 4. **Detection Rules**: Generate 15-30 rules with regex patterns that could detect issues in code
3869
- 5. **Prompts**: Create prompts that embody the expertise from this document
3870
-
3871
- Focus on extracting actionable, code-reviewable knowledge. The agent should be able to find violations of the principles in this document.
3872
-
3873
- **Output ONLY the JSON object, starting with \`{\` and ending with \`}\`.**`;
3874
- }
3875
- /**
3876
- * Format the extraction request output
3877
- */
3878
- formatExtractionRequest(agentName, title, wordCount, chunkCount, prompt) {
3879
- return `
3880
- **Document Parsed Successfully**
3881
-
3882
- ${"\u2501".repeat(50)}
3883
-
3884
- **Creating Skill:** \`${agentName}\`
3885
- **Source Document:** ${title}
3886
- **Word Count:** ${wordCount.toLocaleString()}
3887
- **Processing Chunks:** ${chunkCount}
3888
-
3889
- ${"\u2501".repeat(50)}
3890
-
3891
- ## Next Step
3892
-
3893
- I've prepared the document for analysis. Please process the following prompt to extract the knowledge, then pass the result to \`trie_save_skill\` to save the custom skill.
3894
-
3895
- ${"\u2500".repeat(50)}
3896
-
3897
- ${prompt}
3898
- `;
3899
- }
3900
- sanitizeAgentName(name) {
3901
- return name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
3902
- }
3903
- formatDisplayName(name) {
3904
- return name.split(/[-_]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
3905
- }
3906
- errorResponse(message) {
3907
- return {
3908
- content: [
3909
- {
3910
- type: "text",
3911
- text: `\u274C **Error:** ${message}`
3912
- }
3913
- ],
3914
- isError: true
3915
- };
3916
- }
3917
- };
3918
- var TrieSaveAgentTool = class {
3919
- async execute(args) {
3920
- const { agentConfig, knowledge, detectionRules, prompts, sourceFile } = args;
3921
- if (!agentConfig?.name) {
3922
- return this.errorResponse("Missing agentConfig.name");
3923
- }
3924
- if (!knowledge?.summary) {
3925
- return this.errorResponse("Missing knowledge.summary");
3926
- }
3927
- if (!prompts?.systemPrompt) {
3928
- return this.errorResponse("Missing prompts.systemPrompt");
3929
- }
3930
- try {
3931
- const fullConfig = {
3932
- name: this.sanitizeAgentName(agentConfig.name),
3933
- displayName: agentConfig.displayName || this.formatDisplayName(agentConfig.name),
3934
- description: agentConfig.description,
3935
- version: agentConfig.version || "1.0.0",
3936
- category: agentConfig.category || knowledge.domain || "general",
3937
- source: {
3938
- type: "document",
3939
- originalFile: sourceFile || "user-provided",
3940
- fileType: "txt",
3941
- compressedAt: (/* @__PURE__ */ new Date()).toISOString()
3942
- },
3943
- systemPrompt: prompts.systemPrompt,
3944
- analysisPrompt: prompts.analysisPrompt,
3945
- fixPrompt: prompts.fixPrompt,
3946
- activationRules: this.buildActivationRules(knowledge, detectionRules),
3947
- patterns: detectionRules.map((rule, i) => {
3948
- const fixObj = {
3949
- description: rule.fix?.description || "Review and fix manually",
3950
- autoFixable: rule.fix?.autoFixable || false
3951
- };
3952
- if (rule.fix?.example) {
3953
- fixObj.example = rule.fix.example;
3954
- }
3955
- return {
3956
- id: rule.id || `CUST-${String(i + 1).padStart(3, "0")}`,
3957
- name: rule.name,
3958
- description: rule.description,
3959
- severity: rule.severity || "moderate",
3960
- patterns: {
3961
- regex: rule.patterns?.regex || [],
3962
- keywords: rule.patterns?.keywords || [],
3963
- semantic: rule.patterns?.semantic || ""
3964
- },
3965
- fix: fixObj,
3966
- category: rule.category || agentConfig.category
3967
- };
3968
- }),
3969
- knowledge: {
3970
- domain: knowledge.domain || "general",
3971
- summary: knowledge.summary,
3972
- coreConcepts: knowledge.coreConcepts.map((c) => ({
3973
- name: c.name,
3974
- description: c.description,
3975
- importance: c.importance || "important",
3976
- relatedPatterns: c.relatedPatterns || [],
3977
- keywords: c.keywords || []
3978
- })),
3979
- bestPractices: knowledge.bestPractices.map((bp) => {
3980
- const practice = {
3981
- name: bp.name,
3982
- description: bp.description,
3983
- rationale: bp.rationale,
3984
- category: bp.category || agentConfig.category
3985
- };
3986
- if (bp.codeExample) {
3987
- practice.codeExample = bp.codeExample;
3988
- }
3989
- return practice;
3990
- }),
3991
- antiPatterns: knowledge.antiPatterns.map((ap) => ({
3992
- name: ap.name,
3993
- description: ap.description,
3994
- whyBad: ap.whyBad,
3995
- betterAlternative: ap.betterAlternative
3996
- })),
3997
- detectionRules: [],
3998
- glossary: knowledge.glossary || {},
3999
- sourceDocument: {
4000
- title: agentConfig.displayName || agentConfig.name,
4001
- wordCount: 0,
4002
- compressionRatio: 0
4003
- }
4004
- }
4005
- };
4006
- const configPath = await this.saveAgentConfig(fullConfig);
4007
- return {
4008
- content: [
4009
- {
4010
- type: "text",
4011
- text: this.formatSuccessResponse(fullConfig, configPath)
4012
- }
4013
- ]
4014
- };
4015
- } catch (error) {
4016
- const errorMessage = error instanceof Error ? error.message : String(error);
4017
- return this.errorResponse(`Failed to save skill: ${errorMessage}`);
4018
- }
4019
- }
4020
- buildActivationRules(knowledge, detectionRules) {
4021
- const domainRules = {
4022
- technical: {
4023
- filePatterns: ["*.ts", "*.tsx", "*.js", "*.jsx", "*.py", "*.go", "*.rs"],
4024
- contextSignals: ["touchesUI", "touchesAPI"],
4025
- priority: 2
4026
- },
4027
- legal: {
4028
- filePatterns: ["*"],
4029
- contextSignals: ["touchesUserData", "touchesAuth", "touchesPayments"],
4030
- priority: 2
4031
- },
4032
- policy: {
4033
- filePatterns: ["*"],
4034
- contextSignals: ["touchesAuth", "touchesAPI", "touchesDatabase"],
4035
- priority: 3
4036
- },
4037
- security: {
4038
- filePatterns: ["*"],
4039
- contextSignals: ["touchesAuth", "touchesCrypto", "touchesAPI", "touchesDatabase"],
4040
- priority: 1
4041
- },
4042
- architecture: {
4043
- filePatterns: ["*.ts", "*.tsx", "*.js", "*.jsx", "*.py", "*.go"],
4044
- contextSignals: ["touchesAPI", "touchesDatabase"],
4045
- priority: 2
4046
- },
4047
- general: {
4048
- filePatterns: ["*"],
4049
- contextSignals: [],
4050
- priority: 3
4051
- }
4052
- };
4053
- const defaults = domainRules[knowledge.domain] || domainRules.general;
4054
- const contentPatterns = [];
4055
- for (const rule of detectionRules) {
4056
- if (rule.patterns?.keywords) {
4057
- contentPatterns.push(...rule.patterns.keywords.slice(0, 3));
4058
- }
4059
- }
4060
- for (const concept of knowledge.coreConcepts.slice(0, 5)) {
4061
- if (concept.keywords) {
4062
- contentPatterns.push(...concept.keywords.slice(0, 2));
4063
- }
4064
- }
4065
- return {
4066
- filePatterns: defaults.filePatterns || ["*"],
4067
- contentPatterns: [...new Set(contentPatterns)].slice(0, 20),
4068
- contextSignals: defaults.contextSignals || [],
4069
- minConfidence: 0.3,
4070
- priority: defaults.priority || 2
4071
- };
4072
- }
4073
- async saveAgentConfig(config) {
4074
- const trieDir = join4(getTrieDirectory(getWorkingDirectory(void 0, true)), "agents");
4075
- await mkdir(trieDir, { recursive: true });
4076
- const configPath = join4(trieDir, `${config.name}.json`);
4077
- await writeFile(configPath, JSON.stringify(config, null, 2));
4078
- return configPath;
4079
- }
4080
- formatSuccessResponse(config, configPath) {
4081
- return `
4082
- **Custom Skill Created Successfully**
4083
-
4084
- ${"\u2501".repeat(50)}
4085
-
4086
- **Skill Name:** \`${config.name}\`
4087
- **Display Name:** ${config.displayName}
4088
- **Category:** ${config.category}
4089
- **Config Saved To:** \`${configPath}\`
4090
-
4091
- **Statistics:**
4092
- - Core concepts: ${config.knowledge.coreConcepts.length}
4093
- - Best practices: ${config.knowledge.bestPractices.length}
4094
- - Anti-patterns: ${config.knowledge.antiPatterns.length}
4095
- - Detection rules: ${config.patterns.length}
4096
-
4097
- **Next Steps:**
4098
- 1. The skill is now registered and will activate during scans
4099
- 2. Run \`trie_scan\` to test the new skill
4100
- 3. Edit \`${configPath}\` to customize detection rules
4101
-
4102
- **Usage:**
4103
- The skill will automatically activate when scanning code that matches its patterns.
4104
- Use \`trie_list_skills\` to see all registered skills.
4105
- `.trim();
4106
- }
4107
- sanitizeAgentName(name) {
4108
- return name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
4109
- }
4110
- formatDisplayName(name) {
4111
- return name.split(/[-_]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
4112
- }
4113
- errorResponse(message) {
4114
- return {
4115
- content: [
3596
+ ${n.message}`
3597
+ ).join("\n") : "(none)")
3598
+ },
4116
3599
  {
4117
- type: "text",
4118
- text: `\u274C **Error:** ${message}`
3600
+ type: "json",
3601
+ json: this.state.nudges
4119
3602
  }
4120
- ],
4121
- isError: true
3603
+ ]
4122
3604
  };
4123
3605
  }
4124
- };
4125
- var TrieListAgentsTool = class {
4126
- async execute(args) {
4127
- const { includeBuiltin = true } = args;
4128
- try {
4129
- const customAgentNames = await listCustomAgents();
4130
- const customAgents = await Promise.all(
4131
- customAgentNames.map(async (name) => {
4132
- const config = await loadAgentConfig(name);
4133
- return config ? {
4134
- name: config.name,
4135
- displayName: config.displayName,
4136
- category: config.category,
4137
- source: config.source.originalFile,
4138
- patterns: config.patterns.length,
4139
- isCustom: true
4140
- } : null;
4141
- })
4142
- );
4143
- const validCustomAgents = customAgents.filter(Boolean);
4144
- const builtinAgents = includeBuiltin ? [
4145
- // Security & Compliance
4146
- { name: "security", displayName: "Security Agent", category: "security", isCustom: false },
4147
- { name: "privacy", displayName: "Privacy Agent", category: "privacy", isCustom: false },
4148
- { name: "soc2", displayName: "SOC 2 Agent", category: "compliance", isCustom: false },
4149
- { name: "legal", displayName: "Legal Agent", category: "compliance", isCustom: false },
4150
- // Code Quality
4151
- { name: "software-architect", displayName: "Architecture Agent", category: "architecture", isCustom: false },
4152
- { name: "bug-finding", displayName: "Bug Finding Agent", category: "quality", isCustom: false },
4153
- { name: "typecheck", displayName: "TypeCheck Agent", category: "quality", isCustom: false },
4154
- { name: "trie-clean", displayName: "Clean Agent", category: "ai-code", isCustom: false },
4155
- { name: "data-flow", displayName: "Data Flow Agent", category: "quality", isCustom: false },
4156
- // Design & UX
4157
- { name: "design-engineer", displayName: "Design Engineer Agent", category: "design", isCustom: false },
4158
- { name: "accessibility", displayName: "Accessibility Agent", category: "accessibility", isCustom: false },
4159
- { name: "user-testing", displayName: "UX Agent", category: "ux", isCustom: false },
4160
- { name: "visual-qa", displayName: "Visual QA Agent", category: "visual", isCustom: false },
4161
- // DevOps & Testing
4162
- { name: "devops", displayName: "DevOps Agent", category: "devops", isCustom: false },
4163
- { name: "test", displayName: "Test Agent", category: "testing", isCustom: false },
4164
- { name: "e2e", displayName: "E2E Agent", category: "testing", isCustom: false },
4165
- { name: "performance", displayName: "Performance Agent", category: "performance", isCustom: false },
4166
- // Review & Explanation
4167
- { name: "super-reviewer", displayName: "Super Reviewer", category: "review", isCustom: false },
4168
- { name: "agent-smith", displayName: "Agent Smith", category: "review", isCustom: false },
4169
- { name: "comprehension", displayName: "Comprehension Agent", category: "communication", isCustom: false }
4170
- ] : [];
4171
- let response = `# Registered Agents & Skills
4172
-
4173
- `;
4174
- if (builtinAgents.length > 0) {
4175
- response += `## Built-in Agents (${builtinAgents.length})
4176
-
4177
- `;
4178
- for (const agent of builtinAgents) {
4179
- response += `- **${agent.displayName}** (\`${agent.name}\`) - ${agent.category}
4180
- `;
4181
- }
4182
- response += "\n";
4183
- }
4184
- response += `## Custom Skills (${validCustomAgents.length})
4185
-
4186
- `;
4187
- if (validCustomAgents.length === 0) {
4188
- response += `_No custom skills created yet._
3606
+ getCurrentIssues() {
3607
+ return {
3608
+ content: [{
3609
+ type: "text",
3610
+ text: `[L] **Issues Found This Session**
4189
3611
 
4190
- `;
4191
- response += `Create one with: \`trie_create_skill\`
4192
- `;
4193
- response += ` - Provide a PDF, TXT, or MD file path
4194
- `;
4195
- response += ` - Or paste/drag document content directly
4196
- `;
4197
- } else {
4198
- for (const agent of validCustomAgents) {
4199
- if (agent) {
4200
- response += `- **${agent.displayName}** (\`${agent.name}\`)
4201
- `;
4202
- response += ` - Category: ${agent.category}
4203
- `;
4204
- response += ` - Patterns: ${agent.patterns}
4205
- `;
4206
- response += ` - Source: ${agent.source}
3612
+ Total issues: ${this.state.totalIssuesFound}
3613
+ Files scanned: ${this.state.filesScanned}
4207
3614
 
4208
- `;
4209
- }
4210
- }
4211
- }
4212
- return {
4213
- content: [
4214
- {
4215
- type: "text",
4216
- text: response
4217
- }
4218
- ]
4219
- };
4220
- } catch (error) {
4221
- const errorMessage = error instanceof Error ? error.message : String(error);
4222
- return {
4223
- content: [
4224
- {
4225
- type: "text",
4226
- text: `\u274C Error listing agents: ${errorMessage}`
4227
- }
4228
- ],
4229
- isError: true
4230
- };
4231
- }
3615
+ To get a full report, run \`trie_scan\` on your codebase.`
3616
+ }]
3617
+ };
4232
3618
  }
4233
3619
  };
4234
3620
 
4235
3621
  // src/tools/pr-review.ts
4236
3622
  import { readFile as readFile5 } from "fs/promises";
4237
- import { existsSync as existsSync7 } from "fs";
4238
- import { join as join5, basename as basename5, resolve as resolve5, isAbsolute as isAbsolute5 } from "path";
3623
+ import { existsSync as existsSync5 } from "fs";
3624
+ import { join as join3, basename as basename3, resolve as resolve4, isAbsolute as isAbsolute4 } from "path";
3625
+
3626
+ // src/skills/built-in/super-reviewer.ts
3627
+ var CRITICAL_REVIEW_CHECKLIST = {
3628
+ stateAndLifecycle: [
3629
+ "Uninitialized state accessed before setup",
3630
+ "Missing cleanup on unmount/dispose",
3631
+ "State mutations in wrong lifecycle phase"
3632
+ ],
3633
+ edgeCasesAndRaces: [
3634
+ "Race conditions in async operations",
3635
+ "Missing error handling for edge cases",
3636
+ "Unhandled promise rejections"
3637
+ ],
3638
+ missingPieces: [
3639
+ "Missing input validation",
3640
+ "Missing error handling",
3641
+ "Missing logging/monitoring"
3642
+ ]
3643
+ };
3644
+ var SuperReviewerAgent = class {
3645
+ async review(_files) {
3646
+ return { issues: [] };
3647
+ }
3648
+ async buildReviewWorkflow(files, context) {
3649
+ return { files, context };
3650
+ }
3651
+ };
3652
+
3653
+ // src/tools/pr-review.ts
4239
3654
  var TriePRReviewTool = class {
4240
- agent = new SuperReviewerSkill();
3655
+ agent = new SuperReviewerAgent();
4241
3656
  exec(command, cwd, maxBuffer) {
4242
3657
  const opts = {
4243
3658
  captureOutput: false,
@@ -4319,15 +3734,15 @@ Usage:
4319
3734
  */
4320
3735
  async getPRInfo(pr, worktree) {
4321
3736
  if (worktree) {
4322
- const worktreePath = isAbsolute5(worktree) ? worktree : resolve5(getWorkingDirectory(void 0, true), worktree);
4323
- if (!existsSync7(worktreePath)) {
3737
+ const worktreePath = isAbsolute4(worktree) ? worktree : resolve4(getWorkingDirectory(void 0, true), worktree);
3738
+ if (!existsSync5(worktreePath)) {
4324
3739
  return { success: false, error: `Worktree not found: ${worktreePath}` };
4325
3740
  }
4326
3741
  return {
4327
3742
  success: true,
4328
3743
  type: "worktree",
4329
3744
  path: worktreePath,
4330
- title: `Local changes in ${basename5(worktreePath)}`,
3745
+ title: `Local changes in ${basename3(worktreePath)}`,
4331
3746
  author: this.getGitUser(),
4332
3747
  baseBranch: "HEAD~1",
4333
3748
  headBranch: "HEAD"
@@ -4431,7 +3846,7 @@ Usage:
4431
3846
  deletions++;
4432
3847
  }
4433
3848
  }
4434
- files.push({ path: path3, diff, additions, deletions });
3849
+ files.push({ path: path3, diff, additions, deletions, status: "modified" });
4435
3850
  }
4436
3851
  return files;
4437
3852
  }
@@ -4453,8 +3868,8 @@ Usage:
4453
3868
  "rfcs"
4454
3869
  ];
4455
3870
  for (const docPath of designDocPaths) {
4456
- const fullPath = join5(cwd, docPath);
4457
- if (existsSync7(fullPath)) {
3871
+ const fullPath = join3(cwd, docPath);
3872
+ if (existsSync5(fullPath)) {
4458
3873
  }
4459
3874
  }
4460
3875
  return designDocs;
@@ -4467,8 +3882,8 @@ Usage:
4467
3882
  const cwd = getWorkingDirectory(void 0, true);
4468
3883
  await Promise.all(filePaths.map(async (filePath) => {
4469
3884
  try {
4470
- const fullPath = isAbsolute5(filePath) ? filePath : join5(cwd, filePath);
4471
- if (existsSync7(fullPath)) {
3885
+ const fullPath = isAbsolute4(filePath) ? filePath : join3(cwd, filePath);
3886
+ if (existsSync5(fullPath)) {
4472
3887
  const content = await readFile5(fullPath, "utf-8");
4473
3888
  contents.set(filePath, content);
4474
3889
  }
@@ -5379,6 +4794,20 @@ var TrieTellTool = class {
5379
4794
  const now = (/* @__PURE__ */ new Date()).toISOString();
5380
4795
  const change = (await graph.getRecentChanges(1))[0];
5381
4796
  const linkedFiles = /* @__PURE__ */ new Set();
4797
+ console.log("\n\u{1F9E0} Processing incident with signal extraction...");
4798
+ let extractedSignal = null;
4799
+ try {
4800
+ const apiKey = process.env.ANTHROPIC_API_KEY;
4801
+ const options = {
4802
+ workingDirectory: projectPath
4803
+ };
4804
+ if (apiKey) {
4805
+ options.anthropicApiKey = apiKey;
4806
+ }
4807
+ extractedSignal = await processIncident(description, options);
4808
+ } catch (error) {
4809
+ console.warn("\u26A0\uFE0F Signal extraction failed, continuing with basic incident tracking:", error);
4810
+ }
5382
4811
  const incident = await graph.addNode("incident", {
5383
4812
  description,
5384
4813
  severity: "major",
@@ -5407,13 +4836,32 @@ var TrieTellTool = class {
5407
4836
  }
5408
4837
  const mentionedFiles = extractFilePathsFromDescription(description);
5409
4838
  mentionedFiles.forEach((f) => linkedFiles.add(f));
4839
+ if (extractedSignal) {
4840
+ for (const decision of extractedSignal.decisions) {
4841
+ decision.files.forEach((f) => linkedFiles.add(f));
4842
+ }
4843
+ }
5410
4844
  const incidentIndex = new IncidentIndex(graph, projectPath);
5411
4845
  incidentIndex.addIncidentToTrie(incident, Array.from(linkedFiles));
5412
4846
  await exportToJson(graph);
4847
+ let responseText = `Incident recorded${change ? ` and linked to change ${change.id}` : ""}.`;
4848
+ if (extractedSignal) {
4849
+ const counts = [
4850
+ extractedSignal.decisions.length > 0 ? `${extractedSignal.decisions.length} decision(s)` : null,
4851
+ extractedSignal.facts.length > 0 ? `${extractedSignal.facts.length} fact(s)` : null,
4852
+ extractedSignal.blockers.length > 0 ? `${extractedSignal.blockers.length} blocker(s)` : null,
4853
+ extractedSignal.questions.length > 0 ? `${extractedSignal.questions.length} question(s)` : null
4854
+ ].filter(Boolean).join(", ");
4855
+ if (counts) {
4856
+ responseText += `
4857
+
4858
+ \u{1F4CA} Extracted and stored: ${counts}`;
4859
+ }
4860
+ }
5413
4861
  return {
5414
4862
  content: [{
5415
4863
  type: "text",
5416
- text: `Incident recorded${change ? ` and linked to change ${change.id}` : ""}.`
4864
+ text: responseText
5417
4865
  }]
5418
4866
  };
5419
4867
  } catch (error) {
@@ -5535,6 +4983,178 @@ var LinearSyncTool = class {
5535
4983
  }
5536
4984
  };
5537
4985
 
4986
+ // src/tools/query-tools.ts
4987
+ var TrieGetDecisionsTool = class {
4988
+ async execute(input) {
4989
+ const workDir = input.directory || getWorkingDirectory(void 0, true);
4990
+ const storage = getStorage(workDir);
4991
+ await storage.initialize();
4992
+ let timeWindow;
4993
+ if (input.since) {
4994
+ const now = /* @__PURE__ */ new Date();
4995
+ if (input.since.endsWith("d")) {
4996
+ const days = parseInt(input.since);
4997
+ const start = new Date(now);
4998
+ start.setDate(start.getDate() - days);
4999
+ timeWindow = { start: start.toISOString() };
5000
+ } else {
5001
+ timeWindow = { start: input.since };
5002
+ }
5003
+ }
5004
+ const query = {
5005
+ limit: input.limit || 10
5006
+ };
5007
+ if (input.relatedTo) query.relatedTo = input.relatedTo;
5008
+ if (input.tags) query.tags = input.tags;
5009
+ if (timeWindow) query.timeWindow = timeWindow;
5010
+ const decisions = await storage.queryDecisions(query);
5011
+ return {
5012
+ content: [{
5013
+ type: "text",
5014
+ text: this.formatDecisions(decisions)
5015
+ }]
5016
+ };
5017
+ }
5018
+ formatDecisions(decisions) {
5019
+ if (decisions.length === 0) {
5020
+ return "No decisions found matching query.";
5021
+ }
5022
+ let output = `Found ${decisions.length} decision(s):
5023
+
5024
+ `;
5025
+ for (const dec of decisions) {
5026
+ const when = new Date(dec.when).toLocaleDateString();
5027
+ output += `\u{1F4CB} ${dec.decision}
5028
+ `;
5029
+ output += ` Context: ${dec.context}
5030
+ `;
5031
+ if (dec.reasoning) {
5032
+ output += ` Reasoning: ${dec.reasoning}
5033
+ `;
5034
+ }
5035
+ if (dec.tradeoffs && dec.tradeoffs.length > 0) {
5036
+ output += ` Tradeoffs considered: ${dec.tradeoffs.join(", ")}
5037
+ `;
5038
+ }
5039
+ output += ` When: ${when}
5040
+ `;
5041
+ if (dec.files.length > 0) {
5042
+ output += ` Files: ${dec.files.join(", ")}
5043
+ `;
5044
+ }
5045
+ output += ` Tags: ${dec.tags.join(", ")}
5046
+ `;
5047
+ output += `
5048
+ `;
5049
+ }
5050
+ return output;
5051
+ }
5052
+ };
5053
+ var TrieGetBlockersTool = class {
5054
+ async execute(input) {
5055
+ const workDir = input.directory || getWorkingDirectory(void 0, true);
5056
+ const storage = getStorage(workDir);
5057
+ await storage.initialize();
5058
+ const query = {
5059
+ limit: input.limit || 5
5060
+ };
5061
+ if (input.tags) query.tags = input.tags;
5062
+ const blockers = await storage.queryBlockers(query);
5063
+ return {
5064
+ content: [{
5065
+ type: "text",
5066
+ text: this.formatBlockers(blockers)
5067
+ }]
5068
+ };
5069
+ }
5070
+ formatBlockers(blockers) {
5071
+ if (blockers.length === 0) {
5072
+ return "\u2705 No active blockers found.";
5073
+ }
5074
+ let output = `\u26A0\uFE0F Found ${blockers.length} active blocker(s):
5075
+
5076
+ `;
5077
+ for (const blocker of blockers) {
5078
+ const impact = blocker.impact.toUpperCase();
5079
+ const emoji = blocker.impact === "critical" ? "\u{1F534}" : blocker.impact === "high" ? "\u{1F7E0}" : blocker.impact === "medium" ? "\u{1F7E1}" : "\u{1F7E2}";
5080
+ output += `${emoji} [${impact}] ${blocker.blocker}
5081
+ `;
5082
+ if (blocker.affectedAreas.length > 0) {
5083
+ output += ` Affects: ${blocker.affectedAreas.join(", ")}
5084
+ `;
5085
+ }
5086
+ output += ` Since: ${new Date(blocker.when).toLocaleDateString()}
5087
+ `;
5088
+ output += `
5089
+ `;
5090
+ }
5091
+ return output;
5092
+ }
5093
+ };
5094
+ var TrieGetRelatedDecisionsTool = class {
5095
+ async execute(input) {
5096
+ const workDir = input.directory || getWorkingDirectory(void 0, true);
5097
+ const storage = getStorage(workDir);
5098
+ await storage.initialize();
5099
+ const query = {
5100
+ limit: input.limit || 5
5101
+ };
5102
+ const relatedTo = input.file || input.topic;
5103
+ if (relatedTo) query.relatedTo = relatedTo;
5104
+ const decisions = await storage.queryDecisions(query);
5105
+ return {
5106
+ content: [{
5107
+ type: "text",
5108
+ text: new TrieGetDecisionsTool().formatDecisions(decisions)
5109
+ }]
5110
+ };
5111
+ }
5112
+ };
5113
+ var TrieQueryContextTool = class {
5114
+ async execute(input) {
5115
+ const workDir = input.directory || getWorkingDirectory(void 0, true);
5116
+ const storage = getStorage(workDir);
5117
+ await storage.initialize();
5118
+ const keywords = input.query.toLowerCase().split(/\s+/);
5119
+ let output = `Query: "${input.query}"
5120
+
5121
+ `;
5122
+ if (!input.type || input.type === "decisions" || input.type === "all") {
5123
+ const decisions = await storage.queryDecisions({ limit: input.limit || 5 });
5124
+ const matches = decisions.filter(
5125
+ (d) => keywords.some(
5126
+ (kw) => d.decision.toLowerCase().includes(kw) || d.context.toLowerCase().includes(kw) || d.tags.some((t) => t.toLowerCase().includes(kw))
5127
+ )
5128
+ );
5129
+ if (matches.length > 0) {
5130
+ output += `\u{1F4CB} DECISIONS (${matches.length}):
5131
+ `;
5132
+ output += new TrieGetDecisionsTool().formatDecisions(matches);
5133
+ output += "\n";
5134
+ }
5135
+ }
5136
+ if (!input.type || input.type === "blockers" || input.type === "all") {
5137
+ const blockers = await storage.queryBlockers({ limit: input.limit || 5 });
5138
+ const matches = blockers.filter(
5139
+ (b) => keywords.some(
5140
+ (kw) => b.blocker.toLowerCase().includes(kw) || b.tags.some((t) => t.toLowerCase().includes(kw))
5141
+ )
5142
+ );
5143
+ if (matches.length > 0) {
5144
+ output += `\u26A0\uFE0F BLOCKERS (${matches.length}):
5145
+ `;
5146
+ output += new TrieGetBlockersTool().formatBlockers(matches);
5147
+ }
5148
+ }
5149
+ return {
5150
+ content: [{
5151
+ type: "text",
5152
+ text: output.trim() || "No matches found."
5153
+ }]
5154
+ };
5155
+ }
5156
+ };
5157
+
5538
5158
  // src/server/tool-registry.ts
5539
5159
  var TrieCheckpointTool = class {
5540
5160
  async execute(input) {
@@ -5559,15 +5179,7 @@ var ToolRegistry = class {
5559
5179
  this.tools.set("fix", new TrieFixTool());
5560
5180
  this.tools.set("explain", new TrieExplainTool());
5561
5181
  this.tools.set("test", new TrieTestTool());
5562
- this.tools.set("register_agent", new TrieRegisterAgentTool());
5563
5182
  this.tools.set("watch", new TrieWatchTool());
5564
- this.tools.set("agent", new TrieAgentTool());
5565
- this.tools.set("create_skill", new TrieCreateAgentTool());
5566
- this.tools.set("create_agent", new TrieCreateAgentTool());
5567
- this.tools.set("save_skill", new TrieSaveAgentTool());
5568
- this.tools.set("save_agent", new TrieSaveAgentTool());
5569
- this.tools.set("list_skills", new TrieListAgentsTool());
5570
- this.tools.set("list_agents", new TrieListAgentsTool());
5571
5183
  this.tools.set("pr_review", new TriePRReviewTool());
5572
5184
  this.tools.set("project", new TrieProjectInfoTool());
5573
5185
  this.tools.set("init", new TrieInitTool());
@@ -5581,6 +5193,10 @@ var ToolRegistry = class {
5581
5193
  this.tools.set("ok", new TrieFeedbackTool());
5582
5194
  this.tools.set("bad", new TrieFeedbackTool());
5583
5195
  this.tools.set("linear_sync", new LinearSyncTool());
5196
+ this.tools.set("get_decisions", new TrieGetDecisionsTool());
5197
+ this.tools.set("get_blockers", new TrieGetBlockersTool());
5198
+ this.tools.set("get_related_decisions", new TrieGetRelatedDecisionsTool());
5199
+ this.tools.set("query_context", new TrieQueryContextTool());
5584
5200
  }
5585
5201
  defineToolSchemas() {
5586
5202
  this.definitions = [
@@ -5667,7 +5283,7 @@ var ToolRegistry = class {
5667
5283
  properties: {
5668
5284
  action: {
5669
5285
  type: "string",
5670
- description: "Optional quick action: scan, security, privacy, bugs, types, devops, architecture, ux, clean, soc2, performance, e2e, visual_qa, data_flow, agent_smith, pr_review, watch, fix, explain"
5286
+ description: "Optional quick action: scan, security, legal, bugs, types, devops, architecture, ux, clean, soc2, performance, e2e, visual_qa, data_flow, agent_smith, pr_review, watch, fix, explain"
5671
5287
  },
5672
5288
  agent: {
5673
5289
  type: "string",
@@ -5847,31 +5463,6 @@ var ToolRegistry = class {
5847
5463
  required: ["action"]
5848
5464
  }
5849
5465
  },
5850
- {
5851
- name: "trie_register_agent",
5852
- description: "Register an agent by name and path. Alias: register_agent",
5853
- inputSchema: {
5854
- type: "object",
5855
- properties: {
5856
- name: { type: "string", description: "Name of the agent" },
5857
- path: { type: "string", description: "Path to the agent implementation" }
5858
- },
5859
- required: ["name", "path"]
5860
- }
5861
- },
5862
- {
5863
- name: "trie_list_skills",
5864
- description: "List all skills (external and custom). Alias: list_skills, list_agents",
5865
- inputSchema: {
5866
- type: "object",
5867
- properties: {
5868
- includeBuiltin: {
5869
- type: "boolean",
5870
- description: "Include built-in agents (default true)"
5871
- }
5872
- }
5873
- }
5874
- },
5875
5466
  {
5876
5467
  name: "trie_project",
5877
5468
  description: "View and manage project information (.trie/PROJECT.md). Store project context for AI assistants. Alias: project",
@@ -6009,105 +5600,9 @@ var ToolRegistry = class {
6009
5600
  }
6010
5601
  },
6011
5602
  // Add remaining tool definitions...
6012
- this.createAgentToolDefinitions(),
6013
- this.createCustomSkillDefinitions(),
6014
5603
  this.createSpecialAgentDefinitions()
6015
5604
  ].flat();
6016
5605
  }
6017
- createAgentToolDefinitions() {
6018
- const agentTypes = [
6019
- { name: "security", desc: "detect vulnerabilities, injection risks, auth issues, hardcoded secrets" },
6020
- { name: "privacy", desc: "PII handling, GDPR/HIPAA compliance, data encryption" },
6021
- { name: "legal", desc: "GDPR, CCPA, consent patterns, data retention compliance" },
6022
- { name: "accessibility", desc: "WCAG 2.1 compliance, keyboard nav, screen readers, color contrast" },
6023
- { name: "design", desc: "Awwwards-level polish, design systems, motion design, creative CSS" },
6024
- { name: "architecture", desc: "code organization, SOLID principles, N+1 queries, scalability" },
6025
- { name: "bugs", desc: "null safety, edge cases, common bugs, async issues" },
6026
- { name: "ux", desc: "simulate happy path, security tester, confused user, impatient user" },
6027
- { name: "types", desc: "type errors, missing annotations, null checks" },
6028
- { name: "devops", desc: "config issues, logging, environment variables, deployment patterns" },
6029
- { name: "clean", desc: "\u{1F9F9} Clean up AI-generated code: find common mistakes, bad patterns, and quick fixes" },
6030
- { name: "soc2", desc: "SOC 2 compliance: access controls, secrets management, encryption, logging, change management" }
6031
- ];
6032
- return agentTypes.map((agent) => ({
6033
- name: `trie_${agent.name}`,
6034
- description: `Run ${agent.name} agent: ${agent.desc}. Alias: ${agent.name}`,
6035
- inputSchema: {
6036
- type: "object",
6037
- properties: {
6038
- files: { type: "array", items: { type: "string" }, description: "Files to scan" },
6039
- directory: { type: "string", description: "Directory to scan" },
6040
- output: {
6041
- type: "string",
6042
- enum: ["summary", "full"],
6043
- description: "summary = concise (default), full = includes AI prompt/code (large output)"
6044
- }
6045
- }
6046
- }
6047
- }));
6048
- }
6049
- createCustomSkillDefinitions() {
6050
- return [
6051
- {
6052
- name: "trie_create_skill",
6053
- description: "Create a custom skill from a document. Returns extraction prompt for Claude to process. Alias: create_skill, create_agent",
6054
- inputSchema: {
6055
- type: "object",
6056
- properties: {
6057
- filePath: {
6058
- type: "string",
6059
- description: "Path to the document file (PDF, TXT, MD, or RTF)"
6060
- },
6061
- documentContent: {
6062
- type: "string",
6063
- description: "Raw document text (for drag-and-drop content). Use this OR filePath."
6064
- },
6065
- skillName: {
6066
- type: "string",
6067
- description: 'Name for the new skill (e.g., "react-fundamentals")'
6068
- },
6069
- displayName: { type: "string", description: "Optional display name" },
6070
- description: { type: "string", description: "Optional description" },
6071
- category: { type: "string", description: 'Optional category (e.g., "security", "react")' }
6072
- },
6073
- required: ["skillName"]
6074
- }
6075
- },
6076
- {
6077
- name: "trie_save_skill",
6078
- description: "Save a custom skill config after Claude extracts knowledge. Alias: save_skill, save_agent",
6079
- inputSchema: {
6080
- type: "object",
6081
- properties: {
6082
- skillConfig: {
6083
- type: "object",
6084
- description: "Skill configuration",
6085
- properties: {
6086
- name: { type: "string" },
6087
- displayName: { type: "string" },
6088
- description: { type: "string" },
6089
- version: { type: "string" },
6090
- category: { type: "string" }
6091
- },
6092
- required: ["name", "category"]
6093
- },
6094
- knowledge: { type: "object", description: "Extracted knowledge" },
6095
- detectionRules: { type: "array", description: "Detection rules array" },
6096
- prompts: {
6097
- type: "object",
6098
- properties: {
6099
- systemPrompt: { type: "string" },
6100
- analysisPrompt: { type: "string" },
6101
- fixPrompt: { type: "string" }
6102
- },
6103
- required: ["systemPrompt", "analysisPrompt", "fixPrompt"]
6104
- }
6105
- },
6106
- required: ["skillConfig", "knowledge", "detectionRules", "prompts"]
6107
- }
6108
- }
6109
- ];
6110
- }
6111
5606
  createSpecialAgentDefinitions() {
6112
5607
  return [
6113
5608
  {
@@ -6153,76 +5648,72 @@ var ToolRegistry = class {
6153
5648
  }
6154
5649
  },
6155
5650
  {
6156
- name: "trie_agent_smith",
6157
- description: '\u{1F574}\uFE0F Agent Smith: Relentless pattern hunter. "It is... inevitable." Alias: agent_smith',
5651
+ name: "trie_linear_sync",
5652
+ description: "Sync active Linear tickets to build context for JIT defect prediction. Alias: linear_sync",
6158
5653
  inputSchema: {
6159
5654
  type: "object",
6160
5655
  properties: {
6161
- files: {
6162
- type: "array",
6163
- items: { type: "string" },
6164
- description: "Files to scan (defaults to entire codebase)"
6165
- },
6166
- directory: {
6167
- type: "string",
6168
- description: "Directory to scan. Pass the workspace/project root path for accurate results."
6169
- },
6170
- clear_memory: {
6171
- type: "boolean",
6172
- description: "Clear Agent Smith's memory bank"
6173
- },
6174
- show_stats: {
6175
- type: "boolean",
6176
- description: "Show memory statistics"
6177
- }
5656
+ directory: { type: "string", description: "Project directory" }
6178
5657
  }
6179
5658
  }
6180
5659
  },
6181
5660
  {
6182
- name: "trie_smith",
6183
- description: "\u{1F574}\uFE0F Agent Smith (alias): Hunt AI-generated code anti-patterns. 43 specialized hunters. Alias: smith",
5661
+ name: "trie_get_decisions",
5662
+ description: "Query decisions from decision ledger with targeted retrieval. Prevents context pollution by returning only relevant decisions.",
6184
5663
  inputSchema: {
6185
5664
  type: "object",
6186
5665
  properties: {
6187
- files: {
6188
- type: "array",
6189
- items: { type: "string" },
6190
- description: "Files to scan (defaults to entire codebase)"
6191
- },
6192
- directory: {
6193
- type: "string",
6194
- description: "Directory to scan. Pass the workspace/project root path for accurate results."
6195
- }
5666
+ relatedTo: { type: "string", description: "File path or topic to find related decisions" },
5667
+ tags: { type: "array", items: { type: "string" }, description: "Filter by tags" },
5668
+ since: { type: "string", description: 'Time filter: ISO date or "7d", "30d", "90d"' },
5669
+ limit: { type: "number", description: "Max results (default 10)" },
5670
+ directory: { type: "string", description: "Working directory" }
6196
5671
  }
6197
5672
  }
6198
5673
  },
6199
5674
  {
6200
- name: "trie_linear_sync",
6201
- description: "Sync active Linear tickets to build context for JIT defect prediction. Alias: linear_sync",
5675
+ name: "trie_get_blockers",
5676
+ description: "Get active blockers from decision ledger. Returns only unresolved blockers to avoid noise.",
6202
5677
  inputSchema: {
6203
5678
  type: "object",
6204
5679
  properties: {
6205
- directory: { type: "string", description: "Project directory" }
5680
+ tags: { type: "array", items: { type: "string" }, description: "Filter by tags" },
5681
+ limit: { type: "number", description: "Max results (default 5)" },
5682
+ directory: { type: "string", description: "Working directory" }
6206
5683
  }
6207
5684
  }
6208
5685
  },
6209
5686
  {
6210
- name: "trie_super_reviewer",
6211
- description: "\u{1F50D} Super Reviewer: Interactive PR review with cross-examination. Walks through changes file-by-file.",
5687
+ name: "trie_get_related_decisions",
5688
+ description: "Find decisions related to a specific decision, file, or topic. Targeted context retrieval.",
6212
5689
  inputSchema: {
6213
5690
  type: "object",
6214
5691
  properties: {
6215
- files: {
6216
- type: "array",
6217
- items: { type: "string" },
6218
- description: "Files to review (defaults to changed files)"
6219
- },
6220
- directory: {
6221
- type: "string",
6222
- description: "Directory to review. Pass the workspace/project root path."
6223
- }
5692
+ decisionId: { type: "string", description: "Decision ID to find related decisions" },
5693
+ file: { type: "string", description: "File path to find related decisions" },
5694
+ topic: { type: "string", description: "Topic to find related decisions" },
5695
+ limit: { type: "number", description: "Max results (default 5)" },
5696
+ directory: { type: "string", description: "Working directory" }
6224
5697
  }
6225
5698
  }
5699
+ },
5700
+ {
5701
+ name: "trie_query_context",
5702
+ description: "Query decision ledger with natural language. Returns targeted signal, not full dump.",
5703
+ inputSchema: {
5704
+ type: "object",
5705
+ properties: {
5706
+ query: { type: "string", description: "Natural language query" },
5707
+ type: {
5708
+ type: "string",
5709
+ enum: ["decisions", "blockers", "facts", "questions", "all"],
5710
+ description: "Type of context to query (default: all)"
5711
+ },
5712
+ limit: { type: "number", description: "Max results per type (default 5)" },
5713
+ directory: { type: "string", description: "Working directory" }
5714
+ },
5715
+ required: ["query"]
5716
+ }
6226
5717
  }
6227
5718
  ];
6228
5719
  }
@@ -6241,9 +5732,9 @@ var ToolRegistry = class {
6241
5732
  };
6242
5733
 
6243
5734
  // src/server/resource-manager.ts
6244
- import { readdir as readdir2, readFile as readFile6 } from "fs/promises";
6245
- import { existsSync as existsSync8 } from "fs";
6246
- import { join as join6, dirname as dirname2 } from "path";
5735
+ import { readdir, readFile as readFile6 } from "fs/promises";
5736
+ import { existsSync as existsSync6 } from "fs";
5737
+ import { join as join4, dirname as dirname2 } from "path";
6247
5738
  import { fileURLToPath } from "url";
6248
5739
  var UI_APPS = {
6249
5740
  "scan-dashboard": {
@@ -6357,8 +5848,8 @@ var ResourceManager = class {
6357
5848
  }
6358
5849
  async getScanReportResources() {
6359
5850
  try {
6360
- const reportsDir = join6(getWorkingDirectory(void 0, true), "trie-reports");
6361
- const files = await readdir2(reportsDir);
5851
+ const reportsDir = join4(getWorkingDirectory(void 0, true), "trie-reports");
5852
+ const files = await readdir(reportsDir);
6362
5853
  const reportFiles = files.filter((f) => f.endsWith(".txt") || f.endsWith(".json"));
6363
5854
  return reportFiles.slice(0, 10).map((file) => ({
6364
5855
  uri: `trie://reports/${file}`,
@@ -6457,10 +5948,10 @@ var ResourceManager = class {
6457
5948
  async getUIAppResource(uri, appId) {
6458
5949
  const currentFile = fileURLToPath(import.meta.url);
6459
5950
  const distDir = dirname2(dirname2(currentFile));
6460
- const uiDir = join6(distDir, "ui");
6461
- const htmlPath = join6(uiDir, `${appId}.html`);
5951
+ const uiDir = join4(distDir, "ui");
5952
+ const htmlPath = join4(uiDir, `${appId}.html`);
6462
5953
  try {
6463
- if (!existsSync8(htmlPath)) {
5954
+ if (!existsSync6(htmlPath)) {
6464
5955
  return {
6465
5956
  contents: [{
6466
5957
  uri,
@@ -6650,9 +6141,9 @@ var ResourceManager = class {
6650
6141
  } catch {
6651
6142
  }
6652
6143
  summary.push("---", "", "# Detailed Context", "");
6653
- const agentsMdPath = join6(getTrieDirectory(workDir), "AGENTS.md");
6144
+ const agentsMdPath = join4(getTrieDirectory(workDir), "AGENTS.md");
6654
6145
  try {
6655
- if (existsSync8(agentsMdPath)) {
6146
+ if (existsSync6(agentsMdPath)) {
6656
6147
  const agentsContent = await readFile6(agentsMdPath, "utf-8");
6657
6148
  summary.push(agentsContent);
6658
6149
  } else {
@@ -6778,7 +6269,7 @@ This information is automatically available to Claude Code, Cursor, and other AI
6778
6269
  }
6779
6270
  async getCacheStatsResource(uri) {
6780
6271
  try {
6781
- const cachePath = join6(getTrieDirectory(getWorkingDirectory(void 0, true)), ".trie-cache.json");
6272
+ const cachePath = join4(getTrieDirectory(getWorkingDirectory(void 0, true)), ".trie-cache.json");
6782
6273
  const cacheContent = await readFile6(cachePath, "utf-8");
6783
6274
  const cache = JSON.parse(cacheContent);
6784
6275
  const fileCount = Object.keys(cache.files || {}).length;
@@ -6813,8 +6304,8 @@ This information is automatically available to Claude Code, Cursor, and other AI
6813
6304
  }
6814
6305
  }
6815
6306
  async getSignaturesResource(uri) {
6816
- const { getVulnerabilityStats } = await import("./vulnerability-signatures-ZKVLMBRG.js");
6817
- const { getVibeCodeStats } = await import("./vibe-code-signatures-K4UIWKJZ.js");
6307
+ const { getVulnerabilityStats } = await import("./vulnerability-signatures-EIJQX2TS.js");
6308
+ const { getVibeCodeStats } = await import("./vibe-code-signatures-ELEWJFGZ.js");
6818
6309
  const vulnStats = getVulnerabilityStats();
6819
6310
  const vibeStats = getVibeCodeStats();
6820
6311
  return {
@@ -6858,7 +6349,7 @@ This information is automatically available to Claude Code, Cursor, and other AI
6858
6349
  }
6859
6350
  async getScanReportResource(uri, parsedUri) {
6860
6351
  const fileName = parsedUri.replace("reports/", "");
6861
- const reportPath = join6(getWorkingDirectory(void 0, true), "trie-reports", fileName);
6352
+ const reportPath = join4(getWorkingDirectory(void 0, true), "trie-reports", fileName);
6862
6353
  try {
6863
6354
  const content = await readFile6(reportPath, "utf-8");
6864
6355
  return {
@@ -7007,32 +6498,32 @@ async function findOpenPort() {
7007
6498
  return portChecks.find((port) => port !== null) || null;
7008
6499
  }
7009
6500
  async function checkPort(port) {
7010
- return new Promise((resolve6) => {
6501
+ return new Promise((resolve5) => {
7011
6502
  const testServer = createServer();
7012
6503
  let portInUse = false;
7013
6504
  testServer.once("error", (err) => {
7014
6505
  if (err.code === "EADDRINUSE") {
7015
6506
  portInUse = true;
7016
- testHttpPort(port).then(resolve6).catch(() => resolve6(false));
6507
+ testHttpPort(port).then(resolve5).catch(() => resolve5(false));
7017
6508
  } else {
7018
- resolve6(false);
6509
+ resolve5(false);
7019
6510
  }
7020
6511
  });
7021
6512
  testServer.once("listening", () => {
7022
6513
  testServer.close();
7023
- resolve6(false);
6514
+ resolve5(false);
7024
6515
  });
7025
6516
  setTimeout(() => {
7026
6517
  if (!portInUse) {
7027
6518
  testServer.close();
7028
- resolve6(false);
6519
+ resolve5(false);
7029
6520
  }
7030
6521
  }, 1e3);
7031
6522
  testServer.listen(port, "127.0.0.1");
7032
6523
  });
7033
6524
  }
7034
6525
  async function testHttpPort(port) {
7035
- return new Promise((resolve6) => {
6526
+ return new Promise((resolve5) => {
7036
6527
  const req = request({
7037
6528
  hostname: "localhost",
7038
6529
  port,
@@ -7040,18 +6531,18 @@ async function testHttpPort(port) {
7040
6531
  method: "GET",
7041
6532
  timeout: 2e3
7042
6533
  }, (res) => {
7043
- resolve6(res.statusCode !== void 0);
6534
+ resolve5(res.statusCode !== void 0);
7044
6535
  res.on("data", () => {
7045
6536
  });
7046
6537
  res.on("end", () => {
7047
6538
  });
7048
6539
  });
7049
6540
  req.on("error", () => {
7050
- resolve6(false);
6541
+ resolve5(false);
7051
6542
  });
7052
6543
  req.on("timeout", () => {
7053
6544
  req.destroy();
7054
- resolve6(false);
6545
+ resolve5(false);
7055
6546
  });
7056
6547
  req.end();
7057
6548
  });
@@ -7339,8 +6830,6 @@ var RequestHandlers = class {
7339
6830
  // Individual agent commands
7340
6831
  case "security":
7341
6832
  return await this.toolRegistry.getTool("agent").execute({ ...args, agent: "security" });
7342
- case "privacy":
7343
- return await this.toolRegistry.getTool("agent").execute({ ...args, agent: "privacy" });
7344
6833
  case "legal":
7345
6834
  return await this.toolRegistry.getTool("agent").execute({ ...args, agent: "legal" });
7346
6835
  case "accessibility":
@@ -7535,7 +7024,7 @@ npx playwright install chromium
7535
7024
  '- `action: "visual_qa_browser"` \u2014 screenshots for visual QA',
7536
7025
  "",
7537
7026
  "**Built-in skills:**",
7538
- "`security`, `privacy`, `legal`, `accessibility`, `design`, `architecture`, `bugs`, `ux`, `types`, `devops`, `clean`, `soc2`, `performance`, `e2e`, `visual_qa`, `data_flow`",
7027
+ "`security`, `legal`, `accessibility`, `design`, `architecture`, `bugs`, `ux`, `types`, `devops`, `clean`, `soc2`, `performance`, `e2e`, `visual_qa`, `data_flow`",
7539
7028
  "",
7540
7029
  "**Special skills:**",
7541
7030
  "`agent_smith` \u2014 35 vibe code hunters with cross-file detection",
@@ -7546,37 +7035,23 @@ npx playwright install chromium
7546
7035
  }]
7547
7036
  };
7548
7037
  }
7549
- async handleAgentSmith(smithArgs) {
7550
- const { AgentSmithSkill } = await import("./agent-smith-QYDXPFPJ.js");
7551
- if (smithArgs.clear_memory) {
7552
- const smith = new AgentSmithSkill();
7553
- const result = await smith.clearMemory();
7554
- return {
7555
- content: [{ type: "text", text: result.message }]
7556
- };
7557
- }
7558
- if (smithArgs.show_stats) {
7559
- const smith = new AgentSmithSkill();
7560
- const stats = await smith.getMemoryStats();
7561
- return {
7562
- content: [{
7563
- type: "text",
7564
- text: [
7565
- "\u{1F574}\uFE0F Agent Smith Memory Statistics",
7566
- "\u2550".repeat(40),
7567
- `Tracked issues: ${stats.issueCount}`,
7568
- `Dismissed issues: ${stats.dismissedCount}`,
7569
- `Resurrected issues: ${stats.resurrectedCount}`,
7570
- `Oldest issue: ${stats.oldestIssue ? new Date(stats.oldestIssue).toLocaleDateString() : "N/A"}`,
7571
- `Memory file size: ${stats.fileSizeKB} KB`,
7572
- "",
7573
- "To clear memory: trie_agent_smith with clear_memory:true"
7574
- ].join("\n")
7575
- }]
7576
- };
7577
- }
7578
- const agentSmithRunner = await import("./agent-smith-runner-GXGDJTSR.js");
7579
- return await agentSmithRunner.runAgentSmith(smithArgs);
7038
+ async handleAgentSmith(_smithArgs) {
7039
+ return {
7040
+ content: [{
7041
+ type: "text",
7042
+ text: [
7043
+ "\u{1F916} Agent Smith functionality has been integrated into the decision ledger.",
7044
+ "",
7045
+ "The autonomous agent now:",
7046
+ "- Extracts patterns automatically via `trie watch`",
7047
+ "- Builds decision ledger from every change",
7048
+ "- Predicts problems via `trie gotcha`",
7049
+ "",
7050
+ "Start the agent: `trie_watch start`",
7051
+ "Query the ledger: `trie_gotcha`"
7052
+ ].join("\n")
7053
+ }]
7054
+ };
7580
7055
  }
7581
7056
  };
7582
7057