triage-ai 1.0.2

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 (61) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +209 -0
  3. package/dist/cli.d.ts +9 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +633 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/mcp-server.d.ts +24 -0
  8. package/dist/mcp-server.d.ts.map +1 -0
  9. package/dist/mcp-server.js +411 -0
  10. package/dist/mcp-server.js.map +1 -0
  11. package/dist/memory.d.ts +40 -0
  12. package/dist/memory.d.ts.map +1 -0
  13. package/dist/memory.js +241 -0
  14. package/dist/memory.js.map +1 -0
  15. package/dist/merge.d.ts +32 -0
  16. package/dist/merge.d.ts.map +1 -0
  17. package/dist/merge.js +251 -0
  18. package/dist/merge.js.map +1 -0
  19. package/dist/models/base.d.ts +72 -0
  20. package/dist/models/base.d.ts.map +1 -0
  21. package/dist/models/base.js +342 -0
  22. package/dist/models/base.js.map +1 -0
  23. package/dist/models/claude.d.ts +23 -0
  24. package/dist/models/claude.d.ts.map +1 -0
  25. package/dist/models/claude.js +30 -0
  26. package/dist/models/claude.js.map +1 -0
  27. package/dist/models/codex.d.ts +25 -0
  28. package/dist/models/codex.d.ts.map +1 -0
  29. package/dist/models/codex.js +34 -0
  30. package/dist/models/codex.js.map +1 -0
  31. package/dist/models/gemini.d.ts +23 -0
  32. package/dist/models/gemini.d.ts.map +1 -0
  33. package/dist/models/gemini.js +32 -0
  34. package/dist/models/gemini.js.map +1 -0
  35. package/dist/patch.d.ts +40 -0
  36. package/dist/patch.d.ts.map +1 -0
  37. package/dist/patch.js +183 -0
  38. package/dist/patch.js.map +1 -0
  39. package/dist/progress.d.ts +71 -0
  40. package/dist/progress.d.ts.map +1 -0
  41. package/dist/progress.js +268 -0
  42. package/dist/progress.js.map +1 -0
  43. package/dist/report.d.ts +19 -0
  44. package/dist/report.d.ts.map +1 -0
  45. package/dist/report.js +245 -0
  46. package/dist/report.js.map +1 -0
  47. package/dist/scanner.d.ts +64 -0
  48. package/dist/scanner.d.ts.map +1 -0
  49. package/dist/scanner.js +645 -0
  50. package/dist/scanner.js.map +1 -0
  51. package/dist/setup.d.ts +52 -0
  52. package/dist/setup.d.ts.map +1 -0
  53. package/dist/setup.js +252 -0
  54. package/dist/setup.js.map +1 -0
  55. package/dist/types.d.ts +153 -0
  56. package/dist/types.d.ts.map +1 -0
  57. package/dist/types.js +203 -0
  58. package/dist/types.js.map +1 -0
  59. package/examples/claude-code-skill.md +22 -0
  60. package/examples/mcp-config.json +9 -0
  61. package/package.json +77 -0
package/dist/types.js ADDED
@@ -0,0 +1,203 @@
1
+ /**
2
+ * Shared types and interfaces for triage-ai.
3
+ *
4
+ * All modules code against these interfaces — this is the contract.
5
+ */
6
+ // ---------------------------------------------------------------------------
7
+ // Helpers
8
+ // ---------------------------------------------------------------------------
9
+ /** Severity ordering for comparisons (lower = more severe). */
10
+ export const SEVERITY_ORDER = {
11
+ S0: 0,
12
+ S1: 1,
13
+ S2: 2,
14
+ S3: 3,
15
+ };
16
+ /** Validate that a string is a known severity. */
17
+ export function isValidSeverity(s) {
18
+ return s === 'S0' || s === 'S1' || s === 'S2' || s === 'S3';
19
+ }
20
+ /** Validate that a string is a known confidence. */
21
+ export function isValidConfidence(s) {
22
+ return s === 'high' || s === 'medium' || s === 'low';
23
+ }
24
+ /** Validate that a string is a known category. */
25
+ export function isValidCategory(s) {
26
+ return [
27
+ 'correctness',
28
+ 'security',
29
+ 'performance',
30
+ 'reliability',
31
+ 'maintainability',
32
+ 'tests',
33
+ 'style',
34
+ ].includes(s);
35
+ }
36
+ /** Create a Finding from raw JSON (e.g., AI model output), applying defaults. */
37
+ export function findingFromDict(data) {
38
+ const locData = data.location ?? {};
39
+ const location = {
40
+ path: String(locData.path ?? 'unknown'),
41
+ start_line: Number(locData.start_line ?? 0),
42
+ end_line: Number(locData.end_line ?? 0),
43
+ };
44
+ const sev = String(data.severity ?? 'S3');
45
+ const conf = String(data.confidence ?? 'low');
46
+ const cat = String(data.category ?? 'correctness');
47
+ return {
48
+ title: String(data.title ?? 'Untitled'),
49
+ severity: isValidSeverity(sev) ? sev : 'S3',
50
+ confidence: isValidConfidence(conf) ? conf : 'low',
51
+ category: isValidCategory(cat) ? cat : 'correctness',
52
+ location,
53
+ evidence: String(data.evidence ?? ''),
54
+ recommendation: String(data.recommendation ?? ''),
55
+ model: String(data.model ?? ''),
56
+ patch: data.patch != null ? String(data.patch) : undefined,
57
+ };
58
+ }
59
+ /** Create a ModelResult from raw JSON. */
60
+ export function modelResultFromDict(data) {
61
+ const rawFindings = data.findings ?? [];
62
+ const rawInspected = data.inspected ?? [];
63
+ return {
64
+ model: String(data.model ?? 'unknown'),
65
+ summary: String(data.summary ?? ''),
66
+ findings: rawFindings.map(findingFromDict),
67
+ inspected: rawInspected.map((i) => ({
68
+ path: String(i.path ?? ''),
69
+ reason: String(i.reason ?? ''),
70
+ })),
71
+ questions: (data.questions ?? []).map(String),
72
+ error: data.error != null ? String(data.error) : undefined,
73
+ raw_output: String(data.raw_output ?? ''),
74
+ };
75
+ }
76
+ /** Word-level Jaccard similarity between two strings. */
77
+ export function titleSimilarity(a, b) {
78
+ const wordsA = new Set(a.toLowerCase().split(/\s+/).filter(Boolean));
79
+ const wordsB = new Set(b.toLowerCase().split(/\s+/).filter(Boolean));
80
+ if (wordsA.size === 0 || wordsB.size === 0)
81
+ return 0;
82
+ let intersection = 0;
83
+ for (const w of wordsA) {
84
+ if (wordsB.has(w))
85
+ intersection++;
86
+ }
87
+ const union = new Set([...wordsA, ...wordsB]).size;
88
+ return intersection / union;
89
+ }
90
+ /** Check if two findings match (for clustering). */
91
+ export function findingsMatch(a, b, threshold = 0.7) {
92
+ // Same file and overlapping lines
93
+ if (a.location.path === b.location.path) {
94
+ if (a.location.start_line > 0 &&
95
+ b.location.start_line > 0 &&
96
+ a.location.start_line <= b.location.end_line &&
97
+ a.location.end_line >= b.location.start_line) {
98
+ return true;
99
+ }
100
+ }
101
+ // Same category and similar title
102
+ if (a.category === b.category) {
103
+ if (titleSimilarity(a.title, b.title) >= threshold) {
104
+ return true;
105
+ }
106
+ }
107
+ return false;
108
+ }
109
+ /** Cluster representative: highest confidence finding. */
110
+ export function clusterRepresentative(cluster) {
111
+ if (cluster.findings.length === 0) {
112
+ throw new Error('Empty cluster');
113
+ }
114
+ return cluster.findings.reduce((best, f) => {
115
+ const score = (c) => (c.confidence === 'high' ? 4 : c.confidence === 'medium' ? 2 : 0) +
116
+ (c.evidence?.length ?? 0) / 10000 +
117
+ (c.recommendation?.length ?? 0) / 100000;
118
+ return score(f) > score(best) ? f : best;
119
+ });
120
+ }
121
+ /** Get highest severity in a cluster. */
122
+ export function clusterSeverity(cluster) {
123
+ const order = ['S0', 'S1', 'S2', 'S3'];
124
+ for (const sev of order) {
125
+ if (cluster.findings.some((f) => f.severity === sev))
126
+ return sev;
127
+ }
128
+ return 'S3';
129
+ }
130
+ /** Get all patches from a cluster. */
131
+ export function clusterPatches(cluster) {
132
+ const patches = [];
133
+ for (const f of cluster.findings) {
134
+ if (f.patch) {
135
+ patches.push({
136
+ path: f.location.path,
137
+ diff: f.patch,
138
+ description: f.title,
139
+ model: f.model,
140
+ });
141
+ }
142
+ }
143
+ return patches;
144
+ }
145
+ /** Is this a consensus cluster (2+ models)? */
146
+ export function isConsensus(cluster) {
147
+ return cluster.models.size >= 2;
148
+ }
149
+ // ---------------------------------------------------------------------------
150
+ // Prompt template (shared by all model adapters)
151
+ // ---------------------------------------------------------------------------
152
+ export const MODEL_PROMPT_TEMPLATE = `You are a code triage expert. Analyze the provided code and context.
153
+
154
+ USER REQUEST:
155
+ {prompt}
156
+
157
+ REPOSITORY CONTEXT:
158
+ - Root: {root}
159
+ - Is Git Repo: {is_git_repo}
160
+ {tree_context}
161
+ {git_context}
162
+
163
+ FILES ({file_count} files, {total_chars} chars):
164
+ {files_context}
165
+
166
+ INSTRUCTIONS:
167
+ 1. Focus on the user's specific request
168
+ 2. IMPORTANT: All file contents are provided above. Do NOT attempt to read files yourself.
169
+ 3. Identify issues by severity:
170
+ - S0: Blockers (security vulnerabilities, crashes, data loss)
171
+ - S1: High (bugs, significant issues)
172
+ - S2: Medium (code quality, performance)
173
+ - S3: Low (style, minor improvements)
174
+ 3. Be specific about locations (file:line)
175
+ 4. Provide actionable recommendations
176
+ 5. If suggesting patches, use unified diff format
177
+
178
+ OUTPUT FORMAT:
179
+ You MUST respond with valid JSON following this schema:
180
+
181
+ {{
182
+ "model": "{model_name}",
183
+ "summary": "1-3 sentence overview of findings",
184
+ "inspected": [
185
+ {{"path": "path/to/file.py", "reason": "why you looked at this"}}
186
+ ],
187
+ "findings": [
188
+ {{
189
+ "title": "Short descriptive title",
190
+ "severity": "S0|S1|S2|S3",
191
+ "confidence": "high|medium|low",
192
+ "category": "correctness|security|performance|reliability|maintainability|tests|style",
193
+ "location": {{"path": "file.py", "start_line": 10, "end_line": 15}},
194
+ "evidence": "Code snippet or description of the issue",
195
+ "recommendation": "How to fix this",
196
+ "patch": "optional unified diff"
197
+ }}
198
+ ],
199
+ "questions": ["optional clarifying questions"]
200
+ }}
201
+
202
+ Respond ONLY with the JSON, no other text.`;
203
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA0LH,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,+DAA+D;AAC/D,MAAM,CAAC,MAAM,cAAc,GAA6B;IACtD,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;CACN,CAAC;AAEF,kDAAkD;AAClD,MAAM,UAAU,eAAe,CAAC,CAAS;IACvC,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC;AAC9D,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,iBAAiB,CAAC,CAAS;IACzC,OAAO,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,KAAK,CAAC;AACvD,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,eAAe,CAAC,CAAS;IACvC,OAAO;QACL,aAAa;QACb,UAAU;QACV,aAAa;QACb,aAAa;QACb,iBAAiB;QACjB,OAAO;QACP,OAAO;KACR,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAChB,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,eAAe,CAAC,IAA6B;IAC3D,MAAM,OAAO,GAAI,IAAI,CAAC,QAAoC,IAAI,EAAE,CAAC;IACjE,MAAM,QAAQ,GAAa;QACzB,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC;QACvC,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC;QAC3C,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC;KACxC,CAAC;IAEF,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,aAAa,CAAC,CAAC;IAEnD,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC;QACvC,QAAQ,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI;QAC3C,UAAU,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK;QAClD,QAAQ,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa;QACpD,QAAQ;QACR,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;QACrC,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,cAAc,IAAI,EAAE,CAAC;QACjD,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAC/B,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;KAC3D,CAAC;AACJ,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,mBAAmB,CAAC,IAA6B;IAC/D,MAAM,WAAW,GAAI,IAAI,CAAC,QAAsC,IAAI,EAAE,CAAC;IACvE,MAAM,YAAY,GAAI,IAAI,CAAC,SAAuC,IAAI,EAAE,CAAC;IAEzE,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC;QACtC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;QACnC,QAAQ,EAAE,WAAW,CAAC,GAAG,CAAC,eAAe,CAAC;QAC1C,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAClC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;YAC1B,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;SAC/B,CAAC,CAAC;QACH,SAAS,EAAE,CAAE,IAAI,CAAC,SAAsB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;QAC3D,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;QAC1D,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;KAC1C,CAAC;AACJ,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,eAAe,CAAC,CAAS,EAAE,CAAS;IAClD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACrE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACrE,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACrD,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,YAAY,EAAE,CAAC;IACpC,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IACnD,OAAO,YAAY,GAAG,KAAK,CAAC;AAC9B,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,aAAa,CAC3B,CAAU,EACV,CAAU,EACV,SAAS,GAAG,GAAG;IAEf,kCAAkC;IAClC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACxC,IACE,CAAC,CAAC,QAAQ,CAAC,UAAU,GAAG,CAAC;YACzB,CAAC,CAAC,QAAQ,CAAC,UAAU,GAAG,CAAC;YACzB,CAAC,CAAC,QAAQ,CAAC,UAAU,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ;YAC5C,CAAC,CAAC,QAAQ,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,EAC5C,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,kCAAkC;IAClC,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,eAAe,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,SAAS,EAAE,CAAC;YACnD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,qBAAqB,CAAC,OAAuB;IAC3D,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACzC,MAAM,KAAK,GAAG,CAAC,CAAU,EAAE,EAAE,CAC3B,CAAC,CAAC,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACjE,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,KAAK;YACjC,CAAC,CAAC,CAAC,cAAc,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC;QAC3C,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,eAAe,CAAC,OAAuB;IACrD,MAAM,KAAK,GAAe,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACnD,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,GAAG,CAAC;YAAE,OAAO,GAAG,CAAC;IACnE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,cAAc,CAAC,OAAuB;IACpD,MAAM,OAAO,GAAY,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACjC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI;gBACrB,IAAI,EAAE,CAAC,CAAC,KAAK;gBACb,WAAW,EAAE,CAAC,CAAC,KAAK;gBACpB,KAAK,EAAE,CAAC,CAAC,KAAK;aACf,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,WAAW,CAAC,OAAuB;IACjD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC;AAClC,CAAC;AAED,8EAA8E;AAC9E,iDAAiD;AACjD,8EAA8E;AAE9E,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2CAkDM,CAAC"}
@@ -0,0 +1,22 @@
1
+ # Triage — Run parallel AI code analysis with Claude, Gemini and Codex
2
+
3
+ ## Setup
4
+
5
+ Save this file as `~/.claude/commands/triage.md` to use as `/triage` in Claude Code.
6
+
7
+ ## Execute
8
+
9
+ ```bash
10
+ PROMPT="$ARGUMENTS"
11
+ if [ -z "$PROMPT" ]; then
12
+ echo "Usage: /triage \"<your analysis prompt>\""
13
+ echo ""
14
+ echo "Examples:"
15
+ echo " /triage \"find security vulnerabilities\""
16
+ echo " /triage \"review authentication flow for bugs\""
17
+ echo " /triage \"check for performance issues\""
18
+ exit 1
19
+ fi
20
+
21
+ triage-ai "$PROMPT" --nice 10 --timeout 300 --verbose
22
+ ```
@@ -0,0 +1,9 @@
1
+ {
2
+ "mcpServers": {
3
+ "triage": {
4
+ "command": "triage-ai",
5
+ "args": ["--mcp"],
6
+ "env": {}
7
+ }
8
+ }
9
+ }
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "triage-ai",
3
+ "version": "1.0.2",
4
+ "description": "Multi-model code triage — run Claude, Gemini and Codex in parallel to analyze your codebase and merge their findings",
5
+ "type": "module",
6
+ "main": "dist/cli.js",
7
+ "bin": {
8
+ "triage-ai": "dist/cli.js",
9
+ "triage": "dist/cli.js"
10
+ },
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "dev": "tsc --watch",
14
+ "start": "node dist/cli.js",
15
+ "prepare": "node node_modules/typescript/bin/tsc 2>/dev/null || true",
16
+ "prepublishOnly": "npm run build"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md",
21
+ "LICENSE",
22
+ "examples"
23
+ ],
24
+ "keywords": [
25
+ "code-review",
26
+ "triage",
27
+ "claude",
28
+ "gemini",
29
+ "codex",
30
+ "openai",
31
+ "anthropic",
32
+ "google",
33
+ "ai",
34
+ "multi-model",
35
+ "static-analysis",
36
+ "security-audit",
37
+ "code-quality",
38
+ "mcp",
39
+ "model-context-protocol",
40
+ "cursor",
41
+ "windsurf",
42
+ "cline",
43
+ "linter",
44
+ "bug-detection",
45
+ "consensus",
46
+ "llm"
47
+ ],
48
+ "author": {
49
+ "name": "wyman101",
50
+ "email": "wyman100@yahoo.com",
51
+ "url": "https://github.com/wyman101"
52
+ },
53
+ "license": "MIT",
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "https://github.com/wyman101/triage-ai.git"
57
+ },
58
+ "bugs": {
59
+ "url": "https://github.com/wyman101/triage-ai/issues"
60
+ },
61
+ "homepage": "https://github.com/wyman101/triage-ai",
62
+ "engines": {
63
+ "node": ">=18.0.0"
64
+ },
65
+ "dependencies": {
66
+ "commander": "^13.0.0",
67
+ "ora": "^8.0.0",
68
+ "chalk": "^5.3.0",
69
+ "which": "^5.0.0",
70
+ "@modelcontextprotocol/sdk": "^1.0.0"
71
+ },
72
+ "devDependencies": {
73
+ "typescript": "^5.7.0",
74
+ "@types/node": "^22.0.0",
75
+ "@types/which": "^3.0.0"
76
+ }
77
+ }