@triedotdev/mcp 1.0.7 → 1.0.8

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.
package/dist/index.js CHANGED
@@ -5,12 +5,14 @@ import {
5
5
  parseDocument
6
6
  } from "./chunk-EYNAGEQK.js";
7
7
  import {
8
+ CRITICAL_REVIEW_CHECKLIST,
9
+ SuperReviewerAgent,
8
10
  TrieFixTool,
9
11
  TrieScanTool,
10
12
  getAgentRegistry,
11
13
  getPrompt,
12
14
  getSystemPrompt
13
- } from "./chunk-EDWYG3KK.js";
15
+ } from "./chunk-Z3GM6UVW.js";
14
16
  import "./chunk-3CS6Z2SL.js";
15
17
  import "./chunk-MR755QGT.js";
16
18
  import "./chunk-6NLHFIYA.js";
@@ -25,8 +27,8 @@ import {
25
27
  ListResourcesRequestSchema,
26
28
  ReadResourceRequestSchema
27
29
  } from "@modelcontextprotocol/sdk/types.js";
28
- import { readdir as readdir2, readFile as readFile6 } from "fs/promises";
29
- import { join as join6 } from "path";
30
+ import { readdir as readdir2, readFile as readFile7 } from "fs/promises";
31
+ import { join as join7 } from "path";
30
32
 
31
33
  // src/tools/explain.ts
32
34
  import { readFile } from "fs/promises";
@@ -2066,7 +2068,8 @@ var AGENT_TO_AI_TYPE = {
2066
2068
  "security": "security",
2067
2069
  "privacy": "privacy",
2068
2070
  "legal": "legal",
2069
- "design-engineer": "accessibility",
2071
+ "accessibility": "accessibility",
2072
+ "design-engineer": "design-engineer",
2070
2073
  "software-architect": "architecture",
2071
2074
  "bug-finding": "bugs",
2072
2075
  "user-testing": "ux",
@@ -2074,7 +2077,8 @@ var AGENT_TO_AI_TYPE = {
2074
2077
  "devops": "devops",
2075
2078
  "comprehension": "explain",
2076
2079
  "test": "test",
2077
- "trie_clean": "vibe"
2080
+ "trie_clean": "vibe",
2081
+ "super-reviewer": "pr_review"
2078
2082
  };
2079
2083
  var TrieAgentTool = class {
2080
2084
  agentRegistry = getAgentRegistry();
@@ -2300,7 +2304,8 @@ trie_scan # Full scan with smart triaging
2300
2304
  "security": "trie_security",
2301
2305
  "privacy": "trie_privacy",
2302
2306
  "legal": "trie_legal",
2303
- "design-engineer": "trie_accessibility",
2307
+ "accessibility": "trie_accessibility",
2308
+ "design-engineer": "trie_design",
2304
2309
  "software-architect": "trie_architecture",
2305
2310
  "bug-finding": "trie_bugs",
2306
2311
  "user-testing": "trie_ux",
@@ -2422,7 +2427,8 @@ ${issue.fix}
2422
2427
  "security": "\u{1F512}",
2423
2428
  "privacy": "\u{1F464}",
2424
2429
  "legal": "\u2696\uFE0F",
2425
- "design-engineer": "\u267F",
2430
+ "accessibility": "\u267F",
2431
+ "design-engineer": "\u{1F3A8}",
2426
2432
  "software-architect": "\u{1F3D7}\uFE0F",
2427
2433
  "bug-finding": "\u{1F41B}",
2428
2434
  "user-testing": "\u{1F3AF}",
@@ -2935,7 +2941,7 @@ var TrieListAgentsTool = class {
2935
2941
  { name: "legal", displayName: "Legal Agent", category: "compliance", isCustom: false },
2936
2942
  { name: "typecheck", displayName: "TypeCheck Agent", category: "quality", isCustom: false },
2937
2943
  { name: "comprehension", displayName: "Comprehension Agent", category: "communication", isCustom: false },
2938
- { name: "design-engineer", displayName: "Design Engineer Agent", category: "accessibility", isCustom: false },
2944
+ { name: "accessibility", displayName: "Accessibility Agent", category: "accessibility", isCustom: false },
2939
2945
  { name: "test", displayName: "Test Agent", category: "testing", isCustom: false },
2940
2946
  { name: "software-architect", displayName: "Software Architect Agent", category: "architecture", isCustom: false },
2941
2947
  { name: "devops", displayName: "DevOps Agent", category: "devops", isCustom: false },
@@ -3007,6 +3013,402 @@ var TrieListAgentsTool = class {
3007
3013
  }
3008
3014
  };
3009
3015
 
3016
+ // src/tools/pr-review.ts
3017
+ import { readFile as readFile5 } from "fs/promises";
3018
+ import { existsSync as existsSync6 } from "fs";
3019
+ import { join as join5, basename as basename6, resolve as resolve4, isAbsolute as isAbsolute4 } from "path";
3020
+ import { execSync } from "child_process";
3021
+ var TriePRReviewTool = class {
3022
+ agent = new SuperReviewerAgent();
3023
+ async execute(args) {
3024
+ const {
3025
+ pr,
3026
+ worktree,
3027
+ mode,
3028
+ files: specificFiles
3029
+ } = args;
3030
+ try {
3031
+ const prInfo = await this.getPRInfo(pr, worktree);
3032
+ if (!prInfo.success) {
3033
+ return {
3034
+ content: [{
3035
+ type: "text",
3036
+ text: `\u274C ${prInfo.error}
3037
+
3038
+ Usage:
3039
+ - \`pr_review 12345\` \u2014 review specific PR
3040
+ - \`pr_review\` \u2014 review PR for current branch
3041
+ - \`pr_review ../worktree\` \u2014 review worktree changes`
3042
+ }]
3043
+ };
3044
+ }
3045
+ const changes = await this.getChanges(prInfo);
3046
+ if (changes.files.length === 0) {
3047
+ return {
3048
+ content: [{
3049
+ type: "text",
3050
+ text: `\u2139\uFE0F No changes found to review.`
3051
+ }]
3052
+ };
3053
+ }
3054
+ const designDocs = await this.findDesignDocs(changes.files, prInfo);
3055
+ const workflow = await this.agent.buildReviewWorkflow(
3056
+ changes.files,
3057
+ {
3058
+ prNumber: prInfo.number,
3059
+ prTitle: prInfo.title,
3060
+ prAuthor: prInfo.author,
3061
+ baseBranch: prInfo.baseBranch,
3062
+ headBranch: prInfo.headBranch,
3063
+ mode: mode || "own",
3064
+ designDocs
3065
+ }
3066
+ );
3067
+ const fileContents = await this.preloadFiles(changes.files.map((f) => f.path));
3068
+ const reviewPrompt = this.generateReviewPrompt(workflow, changes, fileContents);
3069
+ return {
3070
+ content: [{
3071
+ type: "text",
3072
+ text: reviewPrompt
3073
+ }]
3074
+ };
3075
+ } catch (error) {
3076
+ return {
3077
+ content: [{
3078
+ type: "text",
3079
+ text: `\u274C Error: ${error instanceof Error ? error.message : String(error)}`
3080
+ }]
3081
+ };
3082
+ }
3083
+ }
3084
+ /**
3085
+ * Get PR information from GitHub or local worktree
3086
+ */
3087
+ async getPRInfo(pr, worktree) {
3088
+ if (worktree) {
3089
+ const worktreePath = isAbsolute4(worktree) ? worktree : resolve4(process.cwd(), worktree);
3090
+ if (!existsSync6(worktreePath)) {
3091
+ return { success: false, error: `Worktree not found: ${worktreePath}` };
3092
+ }
3093
+ return {
3094
+ success: true,
3095
+ type: "worktree",
3096
+ path: worktreePath,
3097
+ title: `Local changes in ${basename6(worktreePath)}`,
3098
+ author: this.getGitUser(),
3099
+ baseBranch: "HEAD~1",
3100
+ headBranch: "HEAD"
3101
+ };
3102
+ }
3103
+ if (pr) {
3104
+ return this.getPRFromGitHub(pr);
3105
+ }
3106
+ try {
3107
+ const branch = execSync("git branch --show-current", { encoding: "utf-8" }).trim();
3108
+ const prJson = execSync(`gh pr view --json number,title,author,headRefName,baseRefName`, {
3109
+ encoding: "utf-8",
3110
+ stdio: ["pipe", "pipe", "pipe"]
3111
+ }).trim();
3112
+ const prData = JSON.parse(prJson);
3113
+ return {
3114
+ success: true,
3115
+ type: "github",
3116
+ number: String(prData.number),
3117
+ title: prData.title,
3118
+ author: prData.author?.login || "unknown",
3119
+ baseBranch: prData.baseRefName,
3120
+ headBranch: prData.headRefName
3121
+ };
3122
+ } catch {
3123
+ return {
3124
+ success: true,
3125
+ type: "local",
3126
+ title: "Local uncommitted changes",
3127
+ author: this.getGitUser(),
3128
+ baseBranch: "HEAD",
3129
+ headBranch: "working tree"
3130
+ };
3131
+ }
3132
+ }
3133
+ /**
3134
+ * Get PR info from GitHub CLI
3135
+ */
3136
+ async getPRFromGitHub(prNumber) {
3137
+ try {
3138
+ const prJson = execSync(`gh pr view ${prNumber} --json number,title,author,headRefName,baseRefName`, {
3139
+ encoding: "utf-8",
3140
+ stdio: ["pipe", "pipe", "pipe"]
3141
+ }).trim();
3142
+ const prData = JSON.parse(prJson);
3143
+ return {
3144
+ success: true,
3145
+ type: "github",
3146
+ number: String(prData.number),
3147
+ title: prData.title,
3148
+ author: prData.author?.login || "unknown",
3149
+ baseBranch: prData.baseRefName,
3150
+ headBranch: prData.headRefName
3151
+ };
3152
+ } catch (error) {
3153
+ return {
3154
+ success: false,
3155
+ error: `Failed to get PR #${prNumber}. Is \`gh\` CLI installed and authenticated?`
3156
+ };
3157
+ }
3158
+ }
3159
+ /**
3160
+ * Get changes (diff) for the PR or local changes
3161
+ */
3162
+ async getChanges(prInfo) {
3163
+ let diffOutput;
3164
+ try {
3165
+ if (prInfo.type === "github" && prInfo.number) {
3166
+ diffOutput = execSync(`gh pr diff ${prInfo.number}`, {
3167
+ encoding: "utf-8",
3168
+ maxBuffer: 50 * 1024 * 1024
3169
+ // 50MB buffer for large PRs
3170
+ });
3171
+ } else if (prInfo.type === "worktree" && prInfo.path) {
3172
+ diffOutput = execSync(`git diff HEAD`, {
3173
+ encoding: "utf-8",
3174
+ cwd: prInfo.path,
3175
+ maxBuffer: 50 * 1024 * 1024
3176
+ });
3177
+ } else {
3178
+ diffOutput = execSync(`git diff HEAD`, {
3179
+ encoding: "utf-8",
3180
+ maxBuffer: 50 * 1024 * 1024
3181
+ });
3182
+ if (!diffOutput.trim()) {
3183
+ diffOutput = execSync(`git diff --cached`, {
3184
+ encoding: "utf-8",
3185
+ maxBuffer: 50 * 1024 * 1024
3186
+ });
3187
+ }
3188
+ }
3189
+ } catch {
3190
+ diffOutput = "";
3191
+ }
3192
+ const files = this.parseDiff(diffOutput);
3193
+ return { files, fullDiff: diffOutput };
3194
+ }
3195
+ /**
3196
+ * Parse git diff output into structured file changes
3197
+ */
3198
+ parseDiff(diffOutput) {
3199
+ const files = [];
3200
+ const fileDiffs = diffOutput.split(/^diff --git /m).slice(1);
3201
+ for (const fileDiff of fileDiffs) {
3202
+ const lines = fileDiff.split("\n");
3203
+ const headerLine = lines[0] || "";
3204
+ const pathMatch = headerLine.match(/a\/(.+?) b\/(.+)/);
3205
+ if (!pathMatch) continue;
3206
+ const path = pathMatch[2];
3207
+ const diff = `diff --git ${fileDiff}`;
3208
+ let additions = 0;
3209
+ let deletions = 0;
3210
+ for (const line of lines) {
3211
+ if (line.startsWith("+") && !line.startsWith("+++")) {
3212
+ additions++;
3213
+ } else if (line.startsWith("-") && !line.startsWith("---")) {
3214
+ deletions++;
3215
+ }
3216
+ }
3217
+ files.push({ path, diff, additions, deletions });
3218
+ }
3219
+ return files;
3220
+ }
3221
+ /**
3222
+ * Find related design docs
3223
+ */
3224
+ async findDesignDocs(files, prInfo) {
3225
+ const designDocs = [];
3226
+ const cwd = prInfo.path || process.cwd();
3227
+ for (const file of files) {
3228
+ if (file.path.includes("design_docs/") || file.path.includes("docs/design/") || file.path.includes("rfcs/")) {
3229
+ designDocs.push(file.path);
3230
+ }
3231
+ }
3232
+ const designDocPaths = [
3233
+ "design_docs",
3234
+ "docs/design",
3235
+ "docs/rfcs",
3236
+ "rfcs"
3237
+ ];
3238
+ for (const docPath of designDocPaths) {
3239
+ const fullPath = join5(cwd, docPath);
3240
+ if (existsSync6(fullPath)) {
3241
+ }
3242
+ }
3243
+ return designDocs;
3244
+ }
3245
+ /**
3246
+ * Pre-load all changed files for instant responses during review
3247
+ */
3248
+ async preloadFiles(filePaths) {
3249
+ const contents = /* @__PURE__ */ new Map();
3250
+ const cwd = process.cwd();
3251
+ await Promise.all(filePaths.map(async (filePath) => {
3252
+ try {
3253
+ const fullPath = isAbsolute4(filePath) ? filePath : join5(cwd, filePath);
3254
+ if (existsSync6(fullPath)) {
3255
+ const content = await readFile5(fullPath, "utf-8");
3256
+ contents.set(filePath, content);
3257
+ }
3258
+ } catch {
3259
+ }
3260
+ }));
3261
+ return contents;
3262
+ }
3263
+ /**
3264
+ * Get git user name
3265
+ */
3266
+ getGitUser() {
3267
+ try {
3268
+ return execSync("git config user.name", { encoding: "utf-8" }).trim();
3269
+ } catch {
3270
+ return "unknown";
3271
+ }
3272
+ }
3273
+ /**
3274
+ * Generate the full review prompt for Claude to execute
3275
+ */
3276
+ generateReviewPrompt(workflow, changes, fileContents) {
3277
+ const { metadata, fileOrder, reviewInstructions } = workflow;
3278
+ let prompt = `# \u{1F50D} Super Reviewer \u2014 Interactive PR Review
3279
+
3280
+ `;
3281
+ if (metadata.prNumber) {
3282
+ prompt += `## PR #${metadata.prNumber}: ${metadata.prTitle}
3283
+
3284
+ `;
3285
+ } else {
3286
+ prompt += `## ${metadata.prTitle}
3287
+
3288
+ `;
3289
+ }
3290
+ prompt += `**Author:** ${metadata.prAuthor}
3291
+ `;
3292
+ prompt += `**Branch:** \`${metadata.headBranch}\` \u2192 \`${metadata.baseBranch}\`
3293
+ `;
3294
+ prompt += `**Scope:** ${metadata.totalFiles} files, +${metadata.totalAdditions}/-${metadata.totalDeletions} lines
3295
+
3296
+ `;
3297
+ prompt += `---
3298
+
3299
+ `;
3300
+ prompt += `## Review Mode
3301
+
3302
+ `;
3303
+ prompt += `**Current Mode:** ${reviewInstructions.mode === "own" ? "1" : "2"}. ${reviewInstructions.description}
3304
+
3305
+ `;
3306
+ prompt += `> To switch modes, say "mode 1" for your own PR or "mode 2" for someone else's
3307
+
3308
+ `;
3309
+ prompt += `---
3310
+
3311
+ `;
3312
+ prompt += `## Files to Review (ordered for understanding)
3313
+
3314
+ `;
3315
+ prompt += `| # | File | Why this order |
3316
+ `;
3317
+ prompt += `|---|------|----------------|
3318
+ `;
3319
+ for (const file of fileOrder) {
3320
+ const stats = `+${changes.files.find((f) => f.path === file.path)?.additions || 0}/-${changes.files.find((f) => f.path === file.path)?.deletions || 0}`;
3321
+ prompt += `| ${file.index} | \`${file.path}\` (${stats}) | ${file.reason} |
3322
+ `;
3323
+ }
3324
+ prompt += `
3325
+ ---
3326
+
3327
+ `;
3328
+ prompt += `## \u{1F3AF} Critical Review Mindset
3329
+
3330
+ `;
3331
+ prompt += `As we go through each file, I'll actively look for:
3332
+
3333
+ `;
3334
+ prompt += `**State & Lifecycle:**
3335
+ `;
3336
+ for (const check of CRITICAL_REVIEW_CHECKLIST.stateAndLifecycle) {
3337
+ prompt += `- ${check}
3338
+ `;
3339
+ }
3340
+ prompt += `
3341
+ **Edge Cases & Races:**
3342
+ `;
3343
+ for (const check of CRITICAL_REVIEW_CHECKLIST.edgeCasesAndRaces) {
3344
+ prompt += `- ${check}
3345
+ `;
3346
+ }
3347
+ prompt += `
3348
+ **Missing Pieces:**
3349
+ `;
3350
+ for (const check of CRITICAL_REVIEW_CHECKLIST.missingPieces) {
3351
+ prompt += `- ${check}
3352
+ `;
3353
+ }
3354
+ prompt += `
3355
+ ---
3356
+
3357
+ `;
3358
+ prompt += `## File Diffs (pre-loaded for instant review)
3359
+
3360
+ `;
3361
+ prompt += `<details>
3362
+ <summary>\u{1F4C1} All file diffs (click to expand)</summary>
3363
+
3364
+ `;
3365
+ for (const file of fileOrder) {
3366
+ const fileChange = changes.files.find((f) => f.path === file.path);
3367
+ if (fileChange) {
3368
+ prompt += `### ${file.path}
3369
+
3370
+ `;
3371
+ prompt += `\`\`\`diff
3372
+ ${fileChange.diff}
3373
+ \`\`\`
3374
+
3375
+ `;
3376
+ }
3377
+ }
3378
+ prompt += `</details>
3379
+
3380
+ `;
3381
+ prompt += `---
3382
+
3383
+ `;
3384
+ prompt += `## Ready to Begin
3385
+
3386
+ `;
3387
+ prompt += `I'll walk you through each file, explaining what changed and why. After each file, I'll pause for your questions.
3388
+
3389
+ `;
3390
+ prompt += `**Commands during review:**
3391
+ `;
3392
+ prompt += `- \`yes\` or \`y\` \u2014 continue to next file
3393
+ `;
3394
+ prompt += `- \`skip to [filename]\` \u2014 jump to specific file
3395
+ `;
3396
+ prompt += `- \`questions?\` \u2014 ask about current file
3397
+ `;
3398
+ prompt += `- \`reorder\` \u2014 change the file order
3399
+ `;
3400
+ prompt += `- \`done\` \u2014 end review and show summary
3401
+
3402
+ `;
3403
+ prompt += `**Ready for File 1?** (\`${fileOrder[0]?.path || "no files"}\`)
3404
+
3405
+ `;
3406
+ prompt += `*(say "yes" to start, or ask me anything)*
3407
+ `;
3408
+ return prompt;
3409
+ }
3410
+ };
3411
+
3010
3412
  // src/utils/ai-tool-detector.ts
3011
3413
  function detectAITool() {
3012
3414
  if (process.env.CLAUDE_CODE_VERSION || process.env.CLAUDE_CODE) {
@@ -3075,8 +3477,8 @@ function detectAITool() {
3075
3477
  }
3076
3478
 
3077
3479
  // src/config/loader.ts
3078
- import { readFile as readFile5 } from "fs/promises";
3079
- import { join as join5 } from "path";
3480
+ import { readFile as readFile6 } from "fs/promises";
3481
+ import { join as join6 } from "path";
3080
3482
 
3081
3483
  // src/config/defaults.ts
3082
3484
  var DEFAULT_CONFIG = {
@@ -3095,7 +3497,7 @@ var DEFAULT_CONFIG = {
3095
3497
  security: { enabled: true },
3096
3498
  privacy: { enabled: true },
3097
3499
  legal: { enabled: true },
3098
- "design-engineer": { enabled: true },
3500
+ "accessibility": { enabled: true },
3099
3501
  "software-architect": { enabled: true },
3100
3502
  comprehension: { enabled: true },
3101
3503
  devops: { enabled: true },
@@ -3131,8 +3533,8 @@ var DEFAULT_CONFIG = {
3131
3533
  // src/config/loader.ts
3132
3534
  async function loadConfig() {
3133
3535
  try {
3134
- const configPath = join5(process.cwd(), ".trie", "config.json");
3135
- const configFile = await readFile5(configPath, "utf-8");
3536
+ const configPath = join6(process.cwd(), ".trie", "config.json");
3537
+ const configFile = await readFile6(configPath, "utf-8");
3136
3538
  const userConfig = JSON.parse(configFile);
3137
3539
  return mergeConfig(DEFAULT_CONFIG, userConfig);
3138
3540
  } catch (error) {
@@ -3179,6 +3581,7 @@ var agentTool = new TrieAgentTool();
3179
3581
  var createAgentTool = new TrieCreateAgentTool();
3180
3582
  var saveAgentTool = new TrieSaveAgentTool();
3181
3583
  var listAgentsTool = new TrieListAgentsTool();
3584
+ var prReviewTool = new TriePRReviewTool();
3182
3585
  var tools = [
3183
3586
  {
3184
3587
  name: "scan",
@@ -3422,6 +3825,22 @@ var tools = [
3422
3825
  }
3423
3826
  }
3424
3827
  },
3828
+ {
3829
+ name: "design",
3830
+ description: "\u{1F3A8} Run design engineer agent: Awwwards-level polish, design systems, motion design, creative CSS",
3831
+ inputSchema: {
3832
+ type: "object",
3833
+ properties: {
3834
+ files: { type: "array", items: { type: "string" }, description: "Files to scan" },
3835
+ directory: { type: "string", description: "Directory to scan" },
3836
+ output: {
3837
+ type: "string",
3838
+ enum: ["summary", "full"],
3839
+ description: "summary = concise (default), full = includes AI prompt/code (large output)"
3840
+ }
3841
+ }
3842
+ }
3843
+ },
3425
3844
  {
3426
3845
  name: "architecture",
3427
3846
  description: "Run architecture agent: code organization, SOLID principles, N+1 queries, scalability",
@@ -3625,6 +4044,34 @@ var tools = [
3625
4044
  }
3626
4045
  }
3627
4046
  }
4047
+ },
4048
+ // PR Review — Interactive AI-guided code review
4049
+ {
4050
+ name: "pr_review",
4051
+ description: "\u{1F50D} Interactive PR review: walks through changes file-by-file, explains each chunk, pauses for cross-examination. Makes large PR reviews a delight.",
4052
+ inputSchema: {
4053
+ type: "object",
4054
+ properties: {
4055
+ pr: {
4056
+ type: "string",
4057
+ description: 'PR number to review (e.g., "12345"). If omitted, reviews current branch PR or local changes.'
4058
+ },
4059
+ worktree: {
4060
+ type: "string",
4061
+ description: "Path to worktree directory to review local changes"
4062
+ },
4063
+ mode: {
4064
+ type: "string",
4065
+ enum: ["own", "others"],
4066
+ description: `Review mode: "own" = your PR (I explain, you verify), "others" = someone else's PR (I flag issues, you comment)`
4067
+ },
4068
+ files: {
4069
+ type: "array",
4070
+ items: { type: "string" },
4071
+ description: "Specific files to review (optional, defaults to all changed files)"
4072
+ }
4073
+ }
4074
+ }
3628
4075
  }
3629
4076
  ];
3630
4077
  server.setRequestHandler(ListToolsRequestSchema, async () => {
@@ -3653,6 +4100,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
3653
4100
  "## Trie Menu",
3654
4101
  "",
3655
4102
  "- `trie_scan` or `scan`: Full intelligent scan (auto triage agents)",
4103
+ "- `pr_review`: \u{1F50D} Interactive PR review \u2014 walks through changes file-by-file",
3656
4104
  "- `fix`: Apply high-confidence fixes",
3657
4105
  "- `explain`: Explain code/issues/risks",
3658
4106
  "- `watch`: Watch mode (scan on change)",
@@ -3685,6 +4133,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
3685
4133
  case "legal":
3686
4134
  return await agentTool.execute({ ...args, agent: "legal" });
3687
4135
  case "accessibility":
4136
+ return await agentTool.execute({ ...args, agent: "accessibility" });
4137
+ case "design":
3688
4138
  return await agentTool.execute({ ...args, agent: "design-engineer" });
3689
4139
  case "architecture":
3690
4140
  return await agentTool.execute({ ...args, agent: "software-architect" });
@@ -3707,6 +4157,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
3707
4157
  return await saveAgentTool.execute(args);
3708
4158
  case "list_agents":
3709
4159
  return await listAgentsTool.execute(args);
4160
+ case "pr_review":
4161
+ return await prReviewTool.execute(args);
3710
4162
  default:
3711
4163
  throw new Error(`Unknown tool: ${name}`);
3712
4164
  }
@@ -3749,7 +4201,7 @@ async function getAvailableResources() {
3749
4201
  mimeType: "application/json"
3750
4202
  });
3751
4203
  try {
3752
- const reportsDir = join6(process.cwd(), "trie-reports");
4204
+ const reportsDir = join7(process.cwd(), "trie-reports");
3753
4205
  const files = await readdir2(reportsDir);
3754
4206
  const reportFiles = files.filter((f) => f.endsWith(".txt") || f.endsWith(".json"));
3755
4207
  for (const file of reportFiles.slice(0, 10)) {
@@ -3826,8 +4278,8 @@ async function readResourceContent(uri) {
3826
4278
  }
3827
4279
  if (parsedUri === "cache/stats") {
3828
4280
  try {
3829
- const cachePath = join6(process.cwd(), ".trie", ".trie-cache.json");
3830
- const cacheContent = await readFile6(cachePath, "utf-8");
4281
+ const cachePath = join7(process.cwd(), ".trie", ".trie-cache.json");
4282
+ const cacheContent = await readFile7(cachePath, "utf-8");
3831
4283
  const cache = JSON.parse(cacheContent);
3832
4284
  const fileCount = Object.keys(cache.files || {}).length;
3833
4285
  const totalVulns = Object.values(cache.files || {}).reduce((acc, file) => {
@@ -3879,9 +4331,9 @@ async function readResourceContent(uri) {
3879
4331
  }
3880
4332
  if (parsedUri.startsWith("reports/")) {
3881
4333
  const fileName = parsedUri.replace("reports/", "");
3882
- const reportPath = join6(process.cwd(), "trie-reports", fileName);
4334
+ const reportPath = join7(process.cwd(), "trie-reports", fileName);
3883
4335
  try {
3884
- const content = await readFile6(reportPath, "utf-8");
4336
+ const content = await readFile7(reportPath, "utf-8");
3885
4337
  return {
3886
4338
  contents: [{
3887
4339
  uri,