@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
@@ -1,2124 +0,0 @@
1
- import {
2
- CacheManager
3
- } from "./chunk-HFQ5ORON.js";
4
- import {
5
- CustomSkill,
6
- getSkillRegistry,
7
- loadContextState
8
- } from "./chunk-BG2BHWCC.js";
9
- import {
10
- getGlobalMemoryStats
11
- } from "./chunk-LT7MKIXU.js";
12
- import {
13
- getHistoricalInsights,
14
- getMemoryStats,
15
- getRecentIssues,
16
- searchIssues
17
- } from "./chunk-LP4MVJDW.js";
18
- import {
19
- getTrieDirectory,
20
- getWorkingDirectory
21
- } from "./chunk-RDOJCRKJ.js";
22
- import {
23
- isInteractiveMode
24
- } from "./chunk-D25EIBPO.js";
25
- import {
26
- __require
27
- } from "./chunk-DGUM43GV.js";
28
-
29
- // src/utils/trie-init.ts
30
- import { existsSync } from "fs";
31
- import { join } from "path";
32
- var INIT_MARKERS = [
33
- "PROJECT.md",
34
- "RULES.md",
35
- "TEAM.md",
36
- "BOOTSTRAP.md",
37
- "AGENTS.md",
38
- "config.json"
39
- ];
40
- function isTrieInitialized(workDir) {
41
- const dir = workDir || getWorkingDirectory(void 0, true);
42
- const trieDir = getTrieDirectory(dir);
43
- return INIT_MARKERS.some((marker) => existsSync(join(trieDir, marker)));
44
- }
45
-
46
- // src/config/loader.ts
47
- import { readFile, writeFile, mkdir } from "fs/promises";
48
- import { existsSync as existsSync3 } from "fs";
49
- import { join as join3, dirname } from "path";
50
-
51
- // src/config/validation.ts
52
- import { z } from "zod";
53
- import { existsSync as existsSync2, readFileSync } from "fs";
54
- import { resolve, join as join2 } from "path";
55
- var API_KEY_PATTERNS = {
56
- anthropic: /^sk-ant-api\d{2}-[\w-]{95}$/,
57
- openai: /^sk-[\w]{48}$/,
58
- github: /^ghp_[\w]{36}$/,
59
- vercel: /^[\w]{24}$/,
60
- linear: /^lin_api_[\w]{40,60}$/
61
- };
62
- var ApiKeysSchema = z.object({
63
- anthropic: z.string().regex(API_KEY_PATTERNS.anthropic, "Invalid Anthropic API key format").optional(),
64
- openai: z.string().regex(API_KEY_PATTERNS.openai, "Invalid OpenAI API key format").optional(),
65
- github: z.string().regex(API_KEY_PATTERNS.github, "Invalid GitHub token format").optional(),
66
- vercel: z.string().regex(API_KEY_PATTERNS.vercel, "Invalid Vercel token format").optional(),
67
- linear: z.string().optional()
68
- // Linear keys can vary, so we'll be flexible but allow storage
69
- });
70
- var AgentConfigSchema = z.object({
71
- enabled: z.array(z.string()).optional().default([]),
72
- disabled: z.array(z.string()).optional().default([]),
73
- parallel: z.boolean().optional().default(true),
74
- maxConcurrency: z.number().int().min(1).max(20).optional().default(4),
75
- timeout: z.number().int().min(1e3).max(3e5).optional().default(12e4),
76
- // 2 minutes
77
- cache: z.boolean().optional().default(true)
78
- });
79
- var ComplianceSchema = z.object({
80
- standards: z.array(z.enum(["SOC2", "GDPR", "HIPAA", "CCPA", "PCI-DSS"])).optional().default(["SOC2"]),
81
- enforceCompliance: z.boolean().optional().default(false),
82
- reportFormat: z.enum(["json", "sarif", "csv", "html"]).optional().default("json")
83
- });
84
- var OutputSchema = z.object({
85
- format: z.enum(["console", "json", "sarif", "junit"]).optional().default("console"),
86
- level: z.enum(["critical", "serious", "moderate", "low", "all"]).optional().default("all"),
87
- interactive: z.boolean().optional().default(false),
88
- streaming: z.boolean().optional().default(true),
89
- colors: z.boolean().optional().default(true)
90
- });
91
- var PathsSchema = z.object({
92
- include: z.array(z.string()).optional().default([]),
93
- exclude: z.array(z.string()).optional().default(["node_modules", "dist", "build", ".git"]),
94
- configDir: z.string().optional().default(".trie"),
95
- outputDir: z.string().optional().default("trie-reports")
96
- });
97
- var IntegrationsSchema = z.object({
98
- github: z.object({
99
- enabled: z.boolean().optional().default(false),
100
- token: z.string().optional(),
101
- webhook: z.string().url().optional()
102
- }).optional(),
103
- slack: z.object({
104
- enabled: z.boolean().optional().default(false),
105
- webhook: z.string().url().optional(),
106
- channel: z.string().optional()
107
- }).optional(),
108
- jira: z.object({
109
- enabled: z.boolean().optional().default(false),
110
- url: z.string().url().optional(),
111
- token: z.string().optional(),
112
- project: z.string().optional()
113
- }).optional()
114
- });
115
- var UserSchema = z.object({
116
- name: z.string().min(1).optional(),
117
- email: z.string().email().optional(),
118
- role: z.enum([
119
- "developer",
120
- "designer",
121
- "qa",
122
- "devops",
123
- "security",
124
- "architect",
125
- "manager",
126
- "contributor"
127
- ]).optional().default("developer"),
128
- github: z.string().optional(),
129
- // GitHub username
130
- url: z.string().url().optional()
131
- // Personal/portfolio URL
132
- });
133
- var TrieConfigSchema = z.object({
134
- version: z.string().optional().default("1.0.0"),
135
- apiKeys: ApiKeysSchema.optional(),
136
- agents: AgentConfigSchema.optional(),
137
- compliance: ComplianceSchema.optional(),
138
- output: OutputSchema.optional(),
139
- paths: PathsSchema.optional(),
140
- integrations: IntegrationsSchema.optional(),
141
- user: UserSchema.optional()
142
- // User identity for attribution
143
- });
144
- var ConfigValidator = class {
145
- /**
146
- * Validate configuration object
147
- */
148
- validateConfig(config) {
149
- try {
150
- const validated = TrieConfigSchema.parse(config);
151
- const businessErrors = this.validateBusinessLogic(validated);
152
- if (businessErrors.length > 0) {
153
- return { success: false, errors: businessErrors };
154
- }
155
- return { success: true, data: validated };
156
- } catch (error) {
157
- if (error instanceof z.ZodError) {
158
- const errors = error.errors.map(
159
- (err) => `${err.path.join(".")}: ${err.message}`
160
- );
161
- return { success: false, errors };
162
- }
163
- return {
164
- success: false,
165
- errors: [`Configuration validation failed: ${error instanceof Error ? error.message : "Unknown error"}`]
166
- };
167
- }
168
- }
169
- /**
170
- * Validate environment variables for API keys
171
- */
172
- validateEnvironment() {
173
- const warnings = [];
174
- const errors = [];
175
- const exposedPatterns = [
176
- "NEXT_PUBLIC_ANTHROPIC",
177
- "REACT_APP_ANTHROPIC",
178
- "VITE_ANTHROPIC",
179
- "PUBLIC_ANTHROPIC"
180
- ];
181
- for (const pattern of exposedPatterns) {
182
- const envVars = Object.keys(process.env).filter((key) => key.includes(pattern));
183
- for (const envVar of envVars) {
184
- errors.push(`[!] Security risk: API key in client-side environment variable: ${envVar}`);
185
- }
186
- }
187
- let anthropicKey = process.env.ANTHROPIC_API_KEY;
188
- if (!anthropicKey) {
189
- try {
190
- const configPath = join2(getTrieDirectory(getWorkingDirectory(void 0, true)), "config.json");
191
- if (existsSync2(configPath)) {
192
- const config = JSON.parse(readFileSync(configPath, "utf-8"));
193
- anthropicKey = config.apiKeys?.anthropic;
194
- }
195
- } catch {
196
- }
197
- }
198
- if (anthropicKey && !API_KEY_PATTERNS.anthropic.test(anthropicKey)) {
199
- errors.push("ANTHROPIC_API_KEY does not match expected format");
200
- }
201
- if (!anthropicKey) {
202
- warnings.push("ANTHROPIC_API_KEY not set - AI features will be disabled. Set in environment, .trie/config.json, or .env file");
203
- }
204
- if (!process.env.GITHUB_TOKEN && process.env.CI) {
205
- warnings.push("GITHUB_TOKEN not set - GitHub integration disabled");
206
- }
207
- return {
208
- valid: errors.length === 0,
209
- warnings,
210
- errors
211
- };
212
- }
213
- /**
214
- * Validate file paths in configuration
215
- */
216
- validatePaths(paths) {
217
- const errors = [];
218
- if (paths?.include) {
219
- for (const path of paths.include) {
220
- const resolvedPath = resolve(path);
221
- if (!existsSync2(resolvedPath)) {
222
- errors.push(`Include path does not exist: ${path}`);
223
- }
224
- }
225
- }
226
- if (paths?.configDir) {
227
- const configPath = resolve(paths.configDir);
228
- if (!existsSync2(configPath)) {
229
- try {
230
- __require("fs").mkdirSync(configPath, { recursive: true });
231
- } catch {
232
- errors.push(`Cannot create config directory: ${paths.configDir}`);
233
- }
234
- }
235
- }
236
- return {
237
- valid: errors.length === 0,
238
- errors
239
- };
240
- }
241
- /**
242
- * Validate integration configurations
243
- */
244
- validateIntegrations(integrations) {
245
- const errors = [];
246
- if (integrations?.github?.enabled) {
247
- if (!integrations.github.token) {
248
- errors.push("GitHub integration enabled but no token provided");
249
- }
250
- }
251
- if (integrations?.slack?.enabled) {
252
- if (!integrations.slack.webhook) {
253
- errors.push("Slack integration enabled but no webhook URL provided");
254
- }
255
- }
256
- if (integrations?.jira?.enabled) {
257
- if (!integrations.jira.url || !integrations.jira.token || !integrations.jira.project) {
258
- errors.push("JIRA integration enabled but missing required fields (url, token, project)");
259
- }
260
- }
261
- return {
262
- valid: errors.length === 0,
263
- errors
264
- };
265
- }
266
- /**
267
- * Business logic validation
268
- */
269
- validateBusinessLogic(config) {
270
- const errors = [];
271
- if (config.agents?.enabled && config.agents?.disabled) {
272
- const overlap = config.agents.enabled.filter(
273
- (agent) => config.agents?.disabled?.includes(agent)
274
- );
275
- if (overlap.length > 0) {
276
- errors.push(`Agents cannot be both enabled and disabled: ${overlap.join(", ")}`);
277
- }
278
- }
279
- if (config.agents?.maxConcurrency && config.agents.maxConcurrency > 10) {
280
- errors.push("maxConcurrency should not exceed 10 for optimal performance");
281
- }
282
- if (config.compliance?.standards) {
283
- const invalidStandards = config.compliance.standards.filter(
284
- (standard) => !["SOC2", "GDPR", "HIPAA", "CCPA", "PCI-DSS"].includes(standard)
285
- );
286
- if (invalidStandards.length > 0) {
287
- errors.push(`Invalid compliance standards: ${invalidStandards.join(", ")}`);
288
- }
289
- }
290
- if (config.paths) {
291
- const pathValidation = this.validatePaths(config.paths);
292
- errors.push(...pathValidation.errors);
293
- }
294
- if (config.integrations) {
295
- const integrationValidation = this.validateIntegrations(config.integrations);
296
- errors.push(...integrationValidation.errors);
297
- }
298
- return errors;
299
- }
300
- /**
301
- * Generate configuration template
302
- */
303
- generateTemplate() {
304
- return {
305
- version: "1.0.0",
306
- agents: {
307
- enabled: ["security", "bugs", "types"],
308
- disabled: [],
309
- parallel: true,
310
- maxConcurrency: 4,
311
- timeout: 12e4,
312
- cache: true
313
- },
314
- compliance: {
315
- standards: ["SOC2"],
316
- enforceCompliance: false,
317
- reportFormat: "json"
318
- },
319
- output: {
320
- format: "console",
321
- level: "all",
322
- interactive: false,
323
- streaming: true,
324
- colors: true
325
- },
326
- paths: {
327
- include: [],
328
- exclude: ["node_modules", "dist", "build", ".git"],
329
- configDir: ".trie",
330
- outputDir: "trie-reports"
331
- }
332
- };
333
- }
334
- /**
335
- * Validate and provide suggestions for improvement
336
- */
337
- analyze(config) {
338
- const suggestions = [];
339
- const securityIssues = [];
340
- const optimizations = [];
341
- let score = 100;
342
- let hasApiKey = Boolean(config.apiKeys?.anthropic || process.env.ANTHROPIC_API_KEY);
343
- if (!hasApiKey) {
344
- try {
345
- const workDir = getWorkingDirectory(void 0, true);
346
- const envFiles = [".env", ".env.local", ".env.production"];
347
- for (const envFile of envFiles) {
348
- const envPath = join2(workDir, envFile);
349
- if (existsSync2(envPath)) {
350
- const envContent = readFileSync(envPath, "utf-8");
351
- if (envContent.includes("ANTHROPIC_API_KEY=")) {
352
- hasApiKey = true;
353
- break;
354
- }
355
- }
356
- }
357
- } catch {
358
- }
359
- }
360
- if (!hasApiKey) {
361
- suggestions.push("Add ANTHROPIC_API_KEY to enable AI-powered analysis for better issue detection. Set in environment, .trie/config.json, or .env file");
362
- score -= 10;
363
- }
364
- if (config.agents?.parallel === false) {
365
- optimizations.push("Enable parallel agent execution for 3-5x faster scans");
366
- score -= 15;
367
- }
368
- if (config.agents?.cache === false) {
369
- optimizations.push("Enable result caching to speed up repeated scans");
370
- score -= 10;
371
- }
372
- if (!config.compliance?.standards || config.compliance.standards.length === 0) {
373
- suggestions.push("Configure compliance standards (SOC2, GDPR, etc.) for regulatory requirements");
374
- score -= 5;
375
- }
376
- const hasIntegrations = config.integrations && (config.integrations.github?.enabled || config.integrations.slack?.enabled || config.integrations.jira?.enabled);
377
- if (!hasIntegrations) {
378
- suggestions.push("Consider enabling GitHub/Slack/JIRA integrations for better team collaboration");
379
- score -= 5;
380
- }
381
- if (config.apiKeys) {
382
- securityIssues.push("API keys in config file - consider using environment variables instead");
383
- score -= 20;
384
- }
385
- return {
386
- score: Math.max(0, score),
387
- suggestions,
388
- securityIssues,
389
- optimizations
390
- };
391
- }
392
- };
393
- var DEFAULT_CONFIG = {
394
- version: "1.0.0",
395
- agents: {
396
- enabled: [],
397
- disabled: [],
398
- parallel: true,
399
- maxConcurrency: 4,
400
- timeout: 12e4,
401
- cache: true
402
- },
403
- compliance: {
404
- standards: ["SOC2"],
405
- enforceCompliance: false,
406
- reportFormat: "json"
407
- },
408
- output: {
409
- format: "console",
410
- level: "all",
411
- interactive: false,
412
- streaming: true,
413
- colors: true
414
- },
415
- paths: {
416
- include: [],
417
- exclude: ["node_modules", "dist", "build", ".git", ".next", ".nuxt", "coverage"],
418
- configDir: ".trie",
419
- outputDir: "trie-reports"
420
- }
421
- };
422
-
423
- // src/config/loader.ts
424
- async function loadConfig() {
425
- const validator = new ConfigValidator();
426
- const configPath = join3(getTrieDirectory(getWorkingDirectory(void 0, true)), "config.json");
427
- try {
428
- if (!existsSync3(configPath)) {
429
- return DEFAULT_CONFIG;
430
- }
431
- const configFile = await readFile(configPath, "utf-8");
432
- const userConfig = JSON.parse(configFile);
433
- const merged = mergeConfig(DEFAULT_CONFIG, userConfig);
434
- const result = validator.validateConfig(merged);
435
- if (!result.success) {
436
- if (!isInteractiveMode()) {
437
- console.error("Configuration validation failed:");
438
- for (const error of result.errors) {
439
- console.error(` - ${error}`);
440
- }
441
- }
442
- return DEFAULT_CONFIG;
443
- }
444
- if (!isInteractiveMode()) {
445
- const envValidation = validator.validateEnvironment();
446
- for (const warning of envValidation.warnings) {
447
- console.warn(warning);
448
- }
449
- for (const error of envValidation.errors) {
450
- console.error(error);
451
- }
452
- }
453
- return result.data;
454
- } catch (error) {
455
- if (!isInteractiveMode()) {
456
- console.error("Failed to load config, using defaults:", error);
457
- }
458
- return DEFAULT_CONFIG;
459
- }
460
- }
461
- async function saveConfig(config) {
462
- const configPath = join3(getTrieDirectory(getWorkingDirectory(void 0, true)), "config.json");
463
- const dir = dirname(configPath);
464
- if (!existsSync3(dir)) {
465
- await mkdir(dir, { recursive: true });
466
- }
467
- await writeFile(configPath, JSON.stringify(config, null, 2), "utf-8");
468
- }
469
- function mergeConfig(defaults, user) {
470
- if (typeof user !== "object" || user === null || Array.isArray(user)) {
471
- return { ...defaults };
472
- }
473
- const result = { ...defaults };
474
- for (const [key, value] of Object.entries(user)) {
475
- const defaultValue = defaults[key];
476
- if (typeof value === "object" && value !== null && !Array.isArray(value) && typeof defaultValue === "object" && defaultValue !== null) {
477
- result[key] = mergeConfig(defaultValue, value);
478
- } else {
479
- result[key] = value;
480
- }
481
- }
482
- return result;
483
- }
484
-
485
- // src/orchestrator/triager.ts
486
- var Triager = class {
487
- agentRegistry = getSkillRegistry();
488
- config;
489
- customSkillsLoaded = false;
490
- contextState = null;
491
- memoryInsights = null;
492
- constructor(config) {
493
- this.config = {
494
- minConfidence: 0.15,
495
- maxAgents: 11,
496
- timeoutMs: 6e4,
497
- enableCostAware: false,
498
- enableDependencies: true,
499
- ...config
500
- };
501
- }
502
- /**
503
- * Load previous context state for smart triaging
504
- */
505
- async loadPreviousContext() {
506
- if (this.contextState === null) {
507
- try {
508
- this.contextState = await loadContextState();
509
- } catch {
510
- this.contextState = null;
511
- }
512
- }
513
- }
514
- /**
515
- * Load memory insights for memory-influenced triaging
516
- */
517
- async loadMemoryInsights() {
518
- if (this.memoryInsights !== null) return;
519
- try {
520
- const [stats, recent, historical, global] = await Promise.all([
521
- getMemoryStats().catch(() => null),
522
- getRecentIssues({ limit: 20 }).catch(() => []),
523
- getHistoricalInsights(process.cwd()).catch(() => null),
524
- getGlobalMemoryStats().catch(() => null)
525
- ]);
526
- const recentAgents = /* @__PURE__ */ new Set();
527
- for (const issue of recent) {
528
- recentAgents.add(issue.agent);
529
- }
530
- const recurringPatternAgents = /* @__PURE__ */ new Set();
531
- if (historical?.recurringPatterns) {
532
- for (const pattern of historical.recurringPatterns) {
533
- recurringPatternAgents.add(pattern.agent);
534
- }
535
- }
536
- const crossProjectAgents = /* @__PURE__ */ new Set();
537
- if (global?.patternsByAgent) {
538
- for (const [agent, count] of Object.entries(global.patternsByAgent)) {
539
- if (count >= 2) {
540
- crossProjectAgents.add(agent);
541
- }
542
- }
543
- }
544
- this.memoryInsights = {
545
- issuesByAgent: stats?.issuesByAgent || {},
546
- recentAgents,
547
- recurringPatternAgents,
548
- trend: historical?.improvementTrend || "unknown",
549
- crossProjectAgents
550
- };
551
- } catch {
552
- this.memoryInsights = {
553
- issuesByAgent: {},
554
- recentAgents: /* @__PURE__ */ new Set(),
555
- recurringPatternAgents: /* @__PURE__ */ new Set(),
556
- trend: "unknown",
557
- crossProjectAgents: /* @__PURE__ */ new Set()
558
- };
559
- }
560
- }
561
- /**
562
- * Ensure custom skills are loaded before triaging
563
- */
564
- async ensureCustomSkillsLoaded() {
565
- if (!this.customSkillsLoaded) {
566
- await this.agentRegistry.loadCustomSkills();
567
- this.customSkillsLoaded = true;
568
- }
569
- }
570
- async selectAgents(context, riskLevel) {
571
- await this.ensureCustomSkillsLoaded();
572
- await Promise.all([
573
- this.loadPreviousContext(),
574
- this.loadMemoryInsights()
575
- ]);
576
- let effectiveRiskLevel = riskLevel;
577
- if (this.contextState?.healthScore !== void 0 && this.contextState.healthScore < 50) {
578
- if (riskLevel === "low" || riskLevel === "medium") {
579
- effectiveRiskLevel = "high";
580
- if (!isInteractiveMode()) {
581
- console.error(` Health score ${this.contextState.healthScore}% - escalating to ${effectiveRiskLevel.toUpperCase()} risk`);
582
- }
583
- }
584
- }
585
- if (effectiveRiskLevel === "critical" || effectiveRiskLevel === "high") {
586
- if (!isInteractiveMode()) {
587
- console.error(` ${effectiveRiskLevel.toUpperCase()} risk - activating all scouts for comprehensive review`);
588
- }
589
- return this.getAllAgents().filter((agent) => agent.shouldActivate(context));
590
- }
591
- const scores = this.scoreAgents(context, effectiveRiskLevel);
592
- this.boostAgentsWithHistory(scores);
593
- this.boostAgentsWithMemory(scores);
594
- this.logAgentScoring(scores);
595
- const qualified = scores.filter((s) => s.confidence >= this.config.minConfidence);
596
- qualified.sort((a, b) => {
597
- if (a.tier !== b.tier) return a.tier - b.tier;
598
- return b.confidence - a.confidence;
599
- });
600
- if (this.config.enableDependencies) {
601
- return this.resolveDependencies(qualified.map((s) => s.agent));
602
- }
603
- return qualified.map((s) => s.agent);
604
- }
605
- /**
606
- * Boost confidence for agents that found issues in previous scans
607
- */
608
- boostAgentsWithHistory(scores) {
609
- if (!this.contextState?.agentStatus) return;
610
- for (const score of scores) {
611
- const previousRun = this.contextState.agentStatus[score.agent.name];
612
- if (previousRun?.issuesFound && previousRun.issuesFound > 0) {
613
- const boost = Math.min(0.3, previousRun.issuesFound * 0.05);
614
- score.confidence = Math.min(1, score.confidence + boost);
615
- score.reasons.push(`found ${previousRun.issuesFound} issues in last scan`);
616
- }
617
- }
618
- }
619
- /**
620
- * Boost confidence for agents based on memory patterns
621
- */
622
- boostAgentsWithMemory(scores) {
623
- if (!this.memoryInsights) return;
624
- for (const score of scores) {
625
- const agentName = score.agent.name;
626
- const historicalCount = this.memoryInsights.issuesByAgent[agentName] || 0;
627
- if (historicalCount >= 10) {
628
- const boost = Math.min(0.2, historicalCount * 0.01);
629
- score.confidence = Math.min(1, score.confidence + boost);
630
- score.reasons.push(`${historicalCount} historical issues`);
631
- }
632
- if (this.memoryInsights.recentAgents.has(agentName)) {
633
- score.confidence = Math.min(1, score.confidence + 0.1);
634
- score.reasons.push("recent activity");
635
- }
636
- if (this.memoryInsights.recurringPatternAgents.has(agentName)) {
637
- score.confidence = Math.min(1, score.confidence + 0.15);
638
- score.reasons.push("recurring patterns");
639
- }
640
- if (this.memoryInsights.crossProjectAgents.has(agentName)) {
641
- score.confidence = Math.min(1, score.confidence + 0.1);
642
- score.reasons.push("cross-project pattern");
643
- }
644
- }
645
- if (this.memoryInsights.trend === "declining") {
646
- for (const score of scores) {
647
- if (score.confidence > 0) {
648
- score.confidence = Math.min(1, score.confidence + 0.05);
649
- }
650
- }
651
- }
652
- }
653
- scoreAgents(context, riskLevel) {
654
- const allAgents = this.getAllAgents();
655
- const scores = [];
656
- for (const agent of allAgents) {
657
- const score = this.scoreAgent(agent, context, riskLevel);
658
- scores.push(score);
659
- }
660
- return scores;
661
- }
662
- scoreAgent(agent, context, riskLevel) {
663
- if (agent instanceof CustomSkill) {
664
- return this.scoreCustomSkill(agent, context, riskLevel);
665
- }
666
- return this.scoreBuiltinAgent(agent, context, riskLevel);
667
- }
668
- /**
669
- * Score custom skills using their activation rules
670
- */
671
- scoreCustomSkill(agent, context, riskLevel) {
672
- const reasons = [];
673
- let confidence = agent.getActivationConfidence(context);
674
- if (confidence > 0) {
675
- reasons.push(`custom skill: ${agent.getMetadata().category}`);
676
- const meta = agent.getMetadata();
677
- if (meta.patternCount > 0) {
678
- reasons.push(`${meta.patternCount} detection patterns`);
679
- }
680
- }
681
- if (riskLevel === "high" && confidence > 0) {
682
- confidence = Math.min(1, confidence * 1.2);
683
- }
684
- return {
685
- agent,
686
- confidence,
687
- reasons,
688
- tier: agent.priority.tier,
689
- isCustom: true
690
- };
691
- }
692
- /**
693
- * Score built-in agents
694
- */
695
- scoreBuiltinAgent(agent, context, riskLevel) {
696
- const reasons = [];
697
- let confidence = 0;
698
- let tier = 3;
699
- if (agent.name === "typecheck") {
700
- tier = 1;
701
- confidence = 1;
702
- reasons.push("fundamental type safety");
703
- }
704
- if (agent.name === "comprehension") {
705
- tier = 1;
706
- confidence = 1;
707
- reasons.push("stakeholder communication");
708
- }
709
- if (agent.name === "security") {
710
- tier = 2;
711
- if (context.touchesAuth) {
712
- confidence += 0.4;
713
- reasons.push("auth code");
714
- }
715
- if (context.touchesPayments) {
716
- confidence += 0.4;
717
- reasons.push("payment code");
718
- }
719
- if (context.touchesAPI) {
720
- confidence += 0.3;
721
- reasons.push("API endpoints");
722
- }
723
- if (context.touchesDatabase) {
724
- confidence += 0.25;
725
- reasons.push("database access");
726
- }
727
- if (context.touchesCrypto) {
728
- confidence += 0.35;
729
- reasons.push("cryptographic operations");
730
- }
731
- if (context.touchesUserData) {
732
- confidence += 0.3;
733
- reasons.push("user data");
734
- }
735
- if (context.touchesSecurityConfig) {
736
- confidence += 0.4;
737
- reasons.push("security config");
738
- }
739
- if (context.touchesThirdPartyAPI) {
740
- confidence += 0.2;
741
- reasons.push("third-party integration");
742
- }
743
- if (context.patterns?.hasFileUploads) {
744
- confidence += 0.3;
745
- reasons.push("file uploads");
746
- }
747
- if (riskLevel === "high") confidence *= 1.2;
748
- }
749
- if (agent.name === "privacy") {
750
- tier = 2;
751
- if (context.touchesUserData) {
752
- confidence += 0.5;
753
- reasons.push("PII handling");
754
- }
755
- if (context.touchesAuth) {
756
- confidence += 0.3;
757
- reasons.push("credentials");
758
- }
759
- if (context.touchesLogging) {
760
- confidence += 0.25;
761
- reasons.push("logging (may expose data)");
762
- }
763
- if (context.patterns?.hasEmailHandling) {
764
- confidence += 0.3;
765
- reasons.push("email handling");
766
- }
767
- if (context.patterns?.hasFormHandling) {
768
- confidence += 0.2;
769
- reasons.push("form data");
770
- }
771
- }
772
- if (agent.name === "legal") {
773
- tier = 2;
774
- if (context.touchesUserData) {
775
- confidence += 0.4;
776
- reasons.push("GDPR/CCPA");
777
- }
778
- if (context.touchesPayments) {
779
- confidence += 0.35;
780
- reasons.push("PCI-DSS");
781
- }
782
- if (context.patterns?.hasEmailHandling) {
783
- confidence += 0.25;
784
- reasons.push("CAN-SPAM");
785
- }
786
- }
787
- if (agent.name === "accessibility") {
788
- tier = 2;
789
- if (context.touchesUI) {
790
- confidence += 0.6;
791
- reasons.push("UI components");
792
- }
793
- if (context.framework === "react" || context.framework === "vue") {
794
- confidence += 0.2;
795
- reasons.push(`${context.framework} framework`);
796
- }
797
- if (context.patterns?.hasFormHandling) {
798
- confidence += 0.2;
799
- reasons.push("form UX");
800
- }
801
- }
802
- if (agent.name === "test") {
803
- tier = 2;
804
- if (context.isNewFeature) {
805
- confidence += 0.4;
806
- reasons.push("new feature");
807
- }
808
- if (context.touchesAuth) {
809
- confidence += 0.35;
810
- reasons.push("auth needs tests");
811
- }
812
- if (context.touchesPayments) {
813
- confidence += 0.4;
814
- reasons.push("payments need tests");
815
- }
816
- if (context.touchesAPI) {
817
- confidence += 0.3;
818
- reasons.push("API testing");
819
- }
820
- if (!context.hasTests) {
821
- confidence += 0.2;
822
- reasons.push("no existing tests");
823
- }
824
- if (context.complexity === "high") {
825
- confidence += 0.25;
826
- reasons.push("complex code");
827
- }
828
- }
829
- if (agent.name === "software-architect") {
830
- tier = 2;
831
- if (context.isNewFeature) {
832
- confidence += 0.35;
833
- reasons.push("architecture review");
834
- }
835
- if (context.touchesDatabase) {
836
- confidence += 0.35;
837
- reasons.push("data modeling");
838
- }
839
- if (context.linesChanged > 200) {
840
- confidence += 0.3;
841
- reasons.push("large change");
842
- }
843
- if (context.touchesAPI) {
844
- confidence += 0.25;
845
- reasons.push("API design");
846
- }
847
- if (context.patterns?.hasWebSockets) {
848
- confidence += 0.3;
849
- reasons.push("real-time architecture");
850
- }
851
- if (context.patterns?.hasQueue) {
852
- confidence += 0.3;
853
- reasons.push("async architecture");
854
- }
855
- }
856
- if (agent.name === "devops") {
857
- tier = 2;
858
- if (context.touchesSecurityConfig) {
859
- confidence += 0.4;
860
- reasons.push("security config");
861
- }
862
- if (context.touchesFileSystem) {
863
- confidence += 0.3;
864
- reasons.push("file operations");
865
- }
866
- if (context.touchesLogging) {
867
- confidence += 0.25;
868
- reasons.push("logging");
869
- }
870
- if (context.touchesErrorHandling) {
871
- confidence += 0.2;
872
- reasons.push("error handling");
873
- }
874
- if (context.patterns?.hasCaching) {
875
- confidence += 0.25;
876
- reasons.push("caching");
877
- }
878
- if (context.patterns?.hasRateLimiting) {
879
- confidence += 0.3;
880
- reasons.push("rate limiting");
881
- }
882
- }
883
- if (agent.name === "bug-finding") {
884
- tier = 2;
885
- if (context.touchesPayments) {
886
- confidence += 0.5;
887
- reasons.push("payments = zero bugs");
888
- }
889
- if (context.isNewFeature) {
890
- confidence += 0.3;
891
- reasons.push("new code");
892
- }
893
- if (context.patterns?.hasAsyncCode) {
894
- confidence += 0.35;
895
- reasons.push("async patterns");
896
- }
897
- if (context.complexity === "high") {
898
- confidence += 0.3;
899
- reasons.push("complex logic");
900
- }
901
- if (context.touchesDatabase) {
902
- confidence += 0.25;
903
- reasons.push("data mutations");
904
- }
905
- }
906
- if (agent.name === "user-testing") {
907
- tier = 3;
908
- if (context.touchesUI) {
909
- confidence += 0.5;
910
- reasons.push("UI changes");
911
- }
912
- if (context.isNewFeature && context.touchesUI) {
913
- confidence += 0.3;
914
- reasons.push("new UI feature");
915
- }
916
- if (context.patterns?.hasFormHandling) {
917
- confidence += 0.25;
918
- reasons.push("form UX");
919
- }
920
- }
921
- if (agent.name === "trie_clean") {
922
- tier = 2;
923
- if (context.touchesUI) {
924
- confidence += 0.4;
925
- reasons.push("UI code");
926
- }
927
- if (context.isNewFeature) {
928
- confidence += 0.3;
929
- reasons.push("new feature");
930
- }
931
- if (context.framework === "react") {
932
- confidence += 0.2;
933
- reasons.push("React code");
934
- }
935
- }
936
- if (agent.name === "soc2") {
937
- tier = 2;
938
- if (context.touchesAuth) {
939
- confidence += 0.4;
940
- reasons.push("authentication");
941
- }
942
- if (context.touchesSecurityConfig) {
943
- confidence += 0.4;
944
- reasons.push("security config");
945
- }
946
- if (context.touchesLogging) {
947
- confidence += 0.3;
948
- reasons.push("logging");
949
- }
950
- if (context.touchesAPI) {
951
- confidence += 0.25;
952
- reasons.push("API endpoints");
953
- }
954
- if (context.touchesDatabase) {
955
- confidence += 0.2;
956
- reasons.push("data access");
957
- }
958
- }
959
- if (agent.name === "moneybags") {
960
- tier = 3;
961
- if (context.touchesPayments) {
962
- confidence += 0.6;
963
- reasons.push("payment code = high cost risk");
964
- }
965
- if (context.touchesAuth) {
966
- confidence += 0.4;
967
- reasons.push("auth bugs are expensive");
968
- }
969
- if (context.touchesHealthData) {
970
- confidence += 0.5;
971
- reasons.push("HIPAA violations");
972
- }
973
- if (context.touchesUserData) {
974
- confidence += 0.3;
975
- reasons.push("PII exposure costs");
976
- }
977
- if (context.touchesDatabase) {
978
- confidence += 0.25;
979
- reasons.push("data loss risk");
980
- }
981
- if (context.isNewFeature) {
982
- confidence += 0.2;
983
- reasons.push("new code risk");
984
- }
985
- if (riskLevel === "high" || riskLevel === "critical") {
986
- confidence *= 1.3;
987
- reasons.push("high-stakes context");
988
- }
989
- }
990
- if (agent.name === "production-ready") {
991
- tier = 3;
992
- if (context.touchesAPI) {
993
- confidence += 0.4;
994
- reasons.push("API deployment");
995
- }
996
- if (context.touchesDatabase) {
997
- confidence += 0.35;
998
- reasons.push("database operations");
999
- }
1000
- if (context.touchesAuth) {
1001
- confidence += 0.35;
1002
- reasons.push("auth system");
1003
- }
1004
- if (context.touchesPayments) {
1005
- confidence += 0.5;
1006
- reasons.push("payment processing");
1007
- }
1008
- if (context.linesChanged > 200) {
1009
- confidence += 0.3;
1010
- reasons.push("significant changes");
1011
- }
1012
- if (riskLevel === "high" || riskLevel === "critical") {
1013
- confidence += 0.4;
1014
- reasons.push("production gate check");
1015
- }
1016
- }
1017
- confidence = Math.min(1, confidence);
1018
- return { agent, confidence, reasons, tier, isCustom: false };
1019
- }
1020
- logAgentScoring(scores) {
1021
- if (isInteractiveMode()) return;
1022
- console.error("\n Agent Confidence Scores:");
1023
- const sorted = [...scores].sort((a, b) => b.confidence - a.confidence);
1024
- for (const score of sorted) {
1025
- const bar = this.getConfidenceBar(score.confidence);
1026
- const status = score.confidence >= this.config.minConfidence ? "\u2713" : "\u2717";
1027
- const tierLabel = score.tier === 1 ? "[T1]" : score.tier === 2 ? "[T2]" : "[T3]";
1028
- const customLabel = score.isCustom ? " \u{1F4DA}" : "";
1029
- console.error(` ${status} ${score.agent.name.padEnd(18)} ${tierLabel} ${bar} ${(score.confidence * 100).toFixed(0)}%${customLabel}`);
1030
- if (score.reasons.length > 0 && score.confidence > 0) {
1031
- console.error(` \u2514\u2500 ${score.reasons.join(", ")}`);
1032
- }
1033
- }
1034
- console.error("");
1035
- }
1036
- getConfidenceBar(confidence) {
1037
- const filled = Math.round(confidence * 10);
1038
- const empty = 10 - filled;
1039
- return "\u2588".repeat(filled) + "\u2591".repeat(empty);
1040
- }
1041
- resolveDependencies(agents) {
1042
- const agentNames = new Set(agents.map((a) => a.name));
1043
- const resolved = [];
1044
- const added = /* @__PURE__ */ new Set();
1045
- const dependencies = {
1046
- "legal": ["privacy"],
1047
- // legal should see privacy issues first
1048
- "test": ["bug-finding"],
1049
- // find bugs before writing tests
1050
- "user-testing": ["accessibility"]
1051
- // accessibility before UX
1052
- };
1053
- for (const agent of agents) {
1054
- const deps = dependencies[agent.name] || [];
1055
- for (const depName of deps) {
1056
- if (!added.has(depName)) {
1057
- const depAgent = this.agentRegistry.getAgent(depName);
1058
- if (depAgent && agentNames.has(depName)) {
1059
- resolved.push(depAgent);
1060
- added.add(depName);
1061
- }
1062
- }
1063
- }
1064
- if (!added.has(agent.name)) {
1065
- resolved.push(agent);
1066
- added.add(agent.name);
1067
- }
1068
- }
1069
- return resolved;
1070
- }
1071
- getTriagingReason(context, riskLevel) {
1072
- if (riskLevel === "critical") {
1073
- return "Critical risk detected - activating all scouts for comprehensive review";
1074
- }
1075
- const reasons = [];
1076
- if (context.touchesAuth) reasons.push("authentication");
1077
- if (context.touchesPayments) reasons.push("payments");
1078
- if (context.touchesDatabase) reasons.push("database");
1079
- if (context.touchesUserData) reasons.push("user data");
1080
- if (context.touchesUI) reasons.push("UI");
1081
- if (context.touchesAPI) reasons.push("API");
1082
- if (context.isNewFeature) reasons.push("new feature");
1083
- if (context.touchesCrypto) reasons.push("cryptography");
1084
- if (context.touchesThirdPartyAPI) reasons.push("3rd party API");
1085
- if (reasons.length === 0) {
1086
- return `${riskLevel} risk - general code changes`;
1087
- }
1088
- return `${riskLevel} risk: ${reasons.join(", ")}`;
1089
- }
1090
- async getSkippedAgents(context, riskLevel) {
1091
- await this.ensureCustomSkillsLoaded();
1092
- if (riskLevel === "critical") return [];
1093
- const scores = this.scoreAgents(context, riskLevel);
1094
- return scores.filter((s) => s.confidence < this.config.minConfidence).map((s) => s.agent.name);
1095
- }
1096
- async getTriagingConfidence(context, riskLevel) {
1097
- await this.ensureCustomSkillsLoaded();
1098
- const scores = this.scoreAgents(context, riskLevel);
1099
- const qualified = scores.filter((s) => s.confidence >= this.config.minConfidence);
1100
- if (qualified.length === 0) return 0.5;
1101
- const avgConfidence = qualified.reduce((sum, s) => sum + s.confidence, 0) / qualified.length;
1102
- const contextStrength = this.getContextStrength(context);
1103
- return Math.min(1, avgConfidence * 0.7 + contextStrength * 0.3);
1104
- }
1105
- getContextStrength(context) {
1106
- let signals = 0;
1107
- const checks = [
1108
- context.touchesAuth,
1109
- context.touchesPayments,
1110
- context.touchesDatabase,
1111
- context.touchesAPI,
1112
- context.touchesUI,
1113
- context.touchesUserData,
1114
- context.touchesHealthData,
1115
- context.touchesSecurityConfig,
1116
- context.touchesCrypto,
1117
- context.touchesFileSystem,
1118
- context.isNewFeature
1119
- ];
1120
- for (const check of checks) {
1121
- if (check) signals++;
1122
- }
1123
- return signals > 0 ? Math.min(1, signals / 3) : 0.3;
1124
- }
1125
- getAllAgents() {
1126
- return this.agentRegistry.getAllAgents();
1127
- }
1128
- /**
1129
- * Get custom skills count
1130
- */
1131
- getCustomSkillCount() {
1132
- return this.agentRegistry.getCustomSkills().length;
1133
- }
1134
- // Backward compatibility alias
1135
- getCustomAgentCount() {
1136
- return this.getCustomSkillCount();
1137
- }
1138
- /**
1139
- * Reload custom skills
1140
- */
1141
- async reloadCustomSkills() {
1142
- await this.agentRegistry.reloadCustomSkills();
1143
- }
1144
- // Backward compatibility alias
1145
- async reloadCustomAgents() {
1146
- return this.reloadCustomSkills();
1147
- }
1148
- };
1149
-
1150
- // src/utils/parallel-executor.ts
1151
- import { Worker } from "worker_threads";
1152
- import { cpus } from "os";
1153
- import { existsSync as existsSync4 } from "fs";
1154
- import { fileURLToPath } from "url";
1155
- var ParallelExecutor = class {
1156
- maxWorkers;
1157
- cache;
1158
- streaming;
1159
- activeWorkers = /* @__PURE__ */ new Set();
1160
- cacheEnabled = true;
1161
- useWorkerThreads = false;
1162
- workerAvailable = null;
1163
- warnedWorkerFallback = false;
1164
- constructor(cacheManager, maxWorkers = Math.max(2, Math.min(cpus().length - 1, 8)), options) {
1165
- this.maxWorkers = maxWorkers;
1166
- this.cache = cacheManager;
1167
- this.cacheEnabled = options?.cacheEnabled ?? true;
1168
- this.useWorkerThreads = options?.useWorkerThreads ?? false;
1169
- }
1170
- /**
1171
- * Set streaming manager for real-time updates
1172
- */
1173
- setStreaming(streaming) {
1174
- this.streaming = streaming;
1175
- }
1176
- /**
1177
- * Execute agents in parallel with intelligent scheduling
1178
- */
1179
- async executeAgents(agents, files, context) {
1180
- if (agents.length === 0) {
1181
- return /* @__PURE__ */ new Map();
1182
- }
1183
- if (this.streaming && this.streaming.getProgress().totalFiles === 0) {
1184
- this.streaming.startScan(files.length);
1185
- }
1186
- const cacheResults = /* @__PURE__ */ new Map();
1187
- const uncachedTasks = [];
1188
- for (const agent of agents) {
1189
- const cached = await this.checkAgentCache(agent, files);
1190
- if (cached) {
1191
- cacheResults.set(agent.name, cached);
1192
- this.streaming?.completeAgent(agent.name, cached.issues);
1193
- } else {
1194
- uncachedTasks.push({
1195
- agent,
1196
- files,
1197
- context,
1198
- priority: agent.priority?.tier || 2,
1199
- timeoutMs: context?.config?.timeoutMs || 12e4
1200
- });
1201
- }
1202
- }
1203
- uncachedTasks.sort((a, b) => a.priority - b.priority);
1204
- const parallelResults = await this.executeTasksParallel(uncachedTasks);
1205
- await this.cacheResults(parallelResults);
1206
- const allResults = /* @__PURE__ */ new Map();
1207
- for (const [agent, result] of cacheResults) {
1208
- allResults.set(agent, result);
1209
- }
1210
- for (const result of parallelResults) {
1211
- allResults.set(result.agent, result.result);
1212
- }
1213
- const allIssues = Array.from(allResults.values()).flatMap((r) => r.issues);
1214
- this.streaming?.completeScan(allIssues);
1215
- return allResults;
1216
- }
1217
- /**
1218
- * Check if agent has cached results for given files
1219
- */
1220
- async checkAgentCache(agent, files) {
1221
- if (!this.cacheEnabled || !this.cache) {
1222
- return null;
1223
- }
1224
- const cachedIssues = await this.cache.getCachedBatch(files, agent.name);
1225
- if (cachedIssues.size === files.length) {
1226
- const allIssues = Array.from(cachedIssues.values()).flat();
1227
- return {
1228
- agent: agent.name,
1229
- issues: allIssues,
1230
- executionTime: 0,
1231
- // Cached
1232
- success: true,
1233
- metadata: {
1234
- filesAnalyzed: files.length,
1235
- linesAnalyzed: 0
1236
- }
1237
- };
1238
- }
1239
- return null;
1240
- }
1241
- /**
1242
- * Execute tasks in parallel batches
1243
- */
1244
- async executeTasksParallel(tasks) {
1245
- if (tasks.length === 0) {
1246
- return [];
1247
- }
1248
- const results = [];
1249
- const batches = this.createBatches(tasks, this.maxWorkers);
1250
- for (const batch of batches) {
1251
- const batchResults = await Promise.all(
1252
- batch.map((task) => this.executeTask(task))
1253
- );
1254
- results.push(...batchResults);
1255
- }
1256
- return results;
1257
- }
1258
- /**
1259
- * Create batches for parallel execution
1260
- */
1261
- createBatches(tasks, batchSize) {
1262
- const batches = [];
1263
- for (let i = 0; i < tasks.length; i += batchSize) {
1264
- batches.push(tasks.slice(i, i + batchSize));
1265
- }
1266
- return batches;
1267
- }
1268
- /**
1269
- * Execute a single task
1270
- */
1271
- async executeTask(task) {
1272
- const startTime = Date.now();
1273
- this.streaming?.startAgent(task.agent.name);
1274
- try {
1275
- const result = this.canUseWorkers() ? await this.executeTaskInWorker(task) : await task.agent.scan(task.files, task.context);
1276
- const executionTime = Date.now() - startTime;
1277
- this.streaming?.completeAgent(task.agent.name, result.issues);
1278
- return {
1279
- agent: task.agent.name,
1280
- result,
1281
- fromCache: false,
1282
- executionTime
1283
- };
1284
- } catch (error) {
1285
- const executionTime = Date.now() - startTime;
1286
- const errorMessage = error instanceof Error ? error.message : String(error);
1287
- this.streaming?.reportError(new Error(errorMessage), `Agent: ${task.agent.name}`);
1288
- return {
1289
- agent: task.agent.name,
1290
- result: {
1291
- agent: task.agent.name,
1292
- issues: [],
1293
- executionTime,
1294
- success: false,
1295
- error: errorMessage
1296
- },
1297
- fromCache: false,
1298
- executionTime
1299
- };
1300
- }
1301
- }
1302
- canUseWorkers() {
1303
- if (!this.useWorkerThreads) {
1304
- return false;
1305
- }
1306
- if (this.workerAvailable !== null) {
1307
- return this.workerAvailable;
1308
- }
1309
- const workerUrl = this.getWorkerUrl();
1310
- this.workerAvailable = existsSync4(fileURLToPath(workerUrl));
1311
- if (!this.workerAvailable && !this.warnedWorkerFallback && !isInteractiveMode()) {
1312
- console.error("Worker threads unavailable; falling back to in-process agents.");
1313
- this.warnedWorkerFallback = true;
1314
- }
1315
- return this.workerAvailable;
1316
- }
1317
- getWorkerUrl() {
1318
- const distDir = new URL(".", import.meta.url);
1319
- return new URL("workers/agent-worker.js", distDir);
1320
- }
1321
- async executeTaskInWorker(task) {
1322
- const workerUrl = this.getWorkerUrl();
1323
- return new Promise((resolve2, reject) => {
1324
- const worker = new Worker(workerUrl, {
1325
- workerData: {
1326
- agentName: task.agent.name,
1327
- files: task.files,
1328
- context: task.context
1329
- }
1330
- });
1331
- this.activeWorkers.add(worker);
1332
- const timeout = setTimeout(() => {
1333
- worker.terminate().catch(() => void 0);
1334
- reject(new Error(`Agent ${task.agent.name} timed out after ${task.timeoutMs}ms`));
1335
- }, task.timeoutMs);
1336
- worker.on("message", (message) => {
1337
- if (message?.type === "result") {
1338
- clearTimeout(timeout);
1339
- resolve2(message.result);
1340
- } else if (message?.type === "error") {
1341
- clearTimeout(timeout);
1342
- reject(new Error(message.error));
1343
- }
1344
- });
1345
- worker.on("error", (error) => {
1346
- clearTimeout(timeout);
1347
- reject(error);
1348
- });
1349
- worker.on("exit", (code) => {
1350
- this.activeWorkers.delete(worker);
1351
- if (code !== 0) {
1352
- clearTimeout(timeout);
1353
- reject(new Error(`Worker stopped with exit code ${code}`));
1354
- }
1355
- });
1356
- });
1357
- }
1358
- /**
1359
- * Cache results for future use
1360
- */
1361
- async cacheResults(results) {
1362
- if (!this.cacheEnabled || !this.cache) {
1363
- return;
1364
- }
1365
- const cachePromises = results.filter((r) => r.result.success && !r.fromCache).map((r) => {
1366
- const issuesByFile = this.groupIssuesByFile(r.result.issues);
1367
- const perFilePromises = Object.entries(issuesByFile).map(
1368
- ([file, issues]) => this.cache.setCached(file, r.agent, issues, r.executionTime)
1369
- );
1370
- return Promise.all(perFilePromises);
1371
- });
1372
- await Promise.allSettled(cachePromises);
1373
- }
1374
- /**
1375
- * Cleanup resources
1376
- */
1377
- async cleanup() {
1378
- const terminationPromises = Array.from(this.activeWorkers).map(
1379
- (worker) => worker.terminate()
1380
- );
1381
- await Promise.allSettled(terminationPromises);
1382
- this.activeWorkers.clear();
1383
- }
1384
- groupIssuesByFile(issues) {
1385
- const grouped = {};
1386
- for (const issue of issues) {
1387
- if (!grouped[issue.file]) {
1388
- grouped[issue.file] = [];
1389
- }
1390
- grouped[issue.file].push(issue);
1391
- }
1392
- return grouped;
1393
- }
1394
- };
1395
- function calculateOptimalConcurrency() {
1396
- const numCPUs = cpus().length;
1397
- const availableMemoryGB = process.memoryUsage().rss / 1024 / 1024 / 1024;
1398
- let optimal = Math.max(2, Math.min(numCPUs - 1, 8));
1399
- if (availableMemoryGB < 2) {
1400
- optimal = Math.max(2, Math.floor(optimal / 2));
1401
- }
1402
- if (numCPUs > 8) {
1403
- optimal = Math.min(optimal + 2, 12);
1404
- }
1405
- return optimal;
1406
- }
1407
-
1408
- // src/orchestrator/executor.ts
1409
- var Executor = class {
1410
- async executeAgents(agents, files, context, options) {
1411
- const parallel = options?.parallel ?? true;
1412
- const cacheEnabled = options?.cacheEnabled ?? true;
1413
- const maxConcurrency = options?.maxConcurrency ?? calculateOptimalConcurrency();
1414
- const useWorkerThreads = options?.useWorkerThreads ?? false;
1415
- if (!isInteractiveMode()) {
1416
- console.error(`Executing ${agents.length} scouts ${parallel ? "in parallel" : "sequentially"}...`);
1417
- }
1418
- if (parallel) {
1419
- const cacheManager = cacheEnabled ? new CacheManager(context.workingDir) : null;
1420
- const executor = new ParallelExecutor(cacheManager, maxConcurrency, {
1421
- cacheEnabled,
1422
- useWorkerThreads
1423
- });
1424
- if (options?.streaming) {
1425
- executor.setStreaming(options.streaming);
1426
- }
1427
- const results = await executor.executeAgents(agents, files, {
1428
- ...context,
1429
- config: { timeoutMs: options?.timeoutMs ?? 12e4 }
1430
- });
1431
- return agents.map((agent) => results.get(agent.name)).filter(Boolean);
1432
- }
1433
- const promises = agents.map(
1434
- (agent) => this.executeAgentWithTimeout(agent, files, context, options?.timeoutMs ?? 3e4)
1435
- );
1436
- try {
1437
- const results = await Promise.allSettled(promises);
1438
- return results.map((result, index) => {
1439
- if (result.status === "fulfilled") {
1440
- if (!isInteractiveMode()) {
1441
- console.error(`${agents[index].name} completed in ${result.value.executionTime}ms`);
1442
- }
1443
- return result.value;
1444
- } else {
1445
- if (!isInteractiveMode()) {
1446
- console.error(`${agents[index].name} failed:`, result.reason);
1447
- }
1448
- return {
1449
- agent: agents[index].name,
1450
- issues: [],
1451
- executionTime: 0,
1452
- success: false,
1453
- error: result.reason instanceof Error ? result.reason.message : String(result.reason)
1454
- };
1455
- }
1456
- });
1457
- } catch (error) {
1458
- if (!isInteractiveMode()) {
1459
- console.error("Executor error:", error);
1460
- }
1461
- return agents.map((agent) => ({
1462
- agent: agent.name,
1463
- issues: [],
1464
- executionTime: 0,
1465
- success: false,
1466
- error: "Execution failed"
1467
- }));
1468
- }
1469
- }
1470
- async executeAgentWithTimeout(agent, files, context, timeoutMs = 3e4) {
1471
- return new Promise(async (resolve2, reject) => {
1472
- const timeout = setTimeout(() => {
1473
- reject(new Error(`Agent ${agent.name} timed out after ${timeoutMs}ms`));
1474
- }, timeoutMs);
1475
- try {
1476
- const result = await agent.scan(files, context);
1477
- clearTimeout(timeout);
1478
- resolve2(result);
1479
- } catch (error) {
1480
- clearTimeout(timeout);
1481
- reject(error);
1482
- }
1483
- });
1484
- }
1485
- };
1486
-
1487
- // src/bootstrap/stack-detector.ts
1488
- import { readFile as readFile2 } from "fs/promises";
1489
- import { existsSync as existsSync5 } from "fs";
1490
- import { join as join4 } from "path";
1491
- var SKILL_MAPPINGS = {
1492
- // Frontend Frameworks - React/Next.js
1493
- "next": [
1494
- "vercel-labs/agent-skills vercel-react-best-practices",
1495
- "vercel-labs/agent-skills web-design-guidelines",
1496
- "anthropics/skills frontend-design",
1497
- "wshobson/agents nextjs-app-router-patterns"
1498
- ],
1499
- "react": [
1500
- "vercel-labs/agent-skills vercel-react-best-practices",
1501
- "anthropics/skills frontend-design",
1502
- "wshobson/agents react-state-management"
1503
- ],
1504
- // Vue/Nuxt Ecosystem
1505
- "vue": [
1506
- "hyf0/vue-skills vue-best-practices",
1507
- "hyf0/vue-skills pinia-best-practices",
1508
- "hyf0/vue-skills vueuse-best-practices",
1509
- "onmax/nuxt-skills vue"
1510
- ],
1511
- "nuxt": [
1512
- "onmax/nuxt-skills nuxt",
1513
- "onmax/nuxt-skills nuxt-ui",
1514
- "onmax/nuxt-skills nuxt-content",
1515
- "onmax/nuxt-skills nuxt-modules",
1516
- "onmax/nuxt-skills nuxt-better-auth",
1517
- "onmax/nuxt-skills nuxthub"
1518
- ],
1519
- "pinia": [
1520
- "hyf0/vue-skills pinia-best-practices"
1521
- ],
1522
- "@vueuse/core": [
1523
- "hyf0/vue-skills vueuse-best-practices",
1524
- "onmax/nuxt-skills vueuse"
1525
- ],
1526
- // Mobile - Expo
1527
- "expo": [
1528
- "expo/skills building-native-ui",
1529
- "expo/skills upgrading-expo",
1530
- "expo/skills native-data-fetching",
1531
- "expo/skills expo-dev-client",
1532
- "expo/skills expo-deployment",
1533
- "expo/skills expo-api-routes",
1534
- "expo/skills expo-tailwind-setup",
1535
- "expo/skills expo-cicd-workflows",
1536
- "expo/skills use-dom"
1537
- ],
1538
- // Mobile - React Native
1539
- "react-native": [
1540
- "callstackincubator/agent-skills react-native-best-practices",
1541
- "wshobson/agents react-native-architecture"
1542
- ],
1543
- // Backend Frameworks
1544
- "@nestjs/core": [
1545
- "kadajett/agent-nestjs-skills nestjs-best-practices"
1546
- ],
1547
- "nestjs": [
1548
- "kadajett/agent-nestjs-skills nestjs-best-practices"
1549
- ],
1550
- "elysia": [
1551
- "elysiajs/skills elysiajs"
1552
- ],
1553
- "hono": [
1554
- "elysiajs/skills elysiajs"
1555
- ],
1556
- // Database/BaaS
1557
- "@supabase/supabase-js": [
1558
- "supabase/agent-skills supabase-postgres-best-practices"
1559
- ],
1560
- "convex": [
1561
- "waynesutton/convexskills convex-best-practices"
1562
- ],
1563
- "pg": [
1564
- "wshobson/agents postgresql-table-design"
1565
- ],
1566
- "postgres": [
1567
- "wshobson/agents postgresql-table-design"
1568
- ],
1569
- // Auth
1570
- "better-auth": [
1571
- "better-auth/skills better-auth-best-practices",
1572
- "better-auth/skills create-auth-skill"
1573
- ],
1574
- // Payments
1575
- "stripe": [
1576
- "stripe/ai stripe-best-practices"
1577
- ],
1578
- "@stripe/stripe-js": [
1579
- "stripe/ai stripe-best-practices"
1580
- ],
1581
- // Media/Graphics
1582
- "remotion": [
1583
- "remotion-dev/skills remotion-best-practices"
1584
- ],
1585
- "three": [
1586
- "cloudai-x/threejs-skills threejs-fundamentals",
1587
- "cloudai-x/threejs-skills threejs-animation",
1588
- "cloudai-x/threejs-skills threejs-materials",
1589
- "cloudai-x/threejs-skills threejs-shaders",
1590
- "cloudai-x/threejs-skills threejs-lighting",
1591
- "cloudai-x/threejs-skills threejs-geometry",
1592
- "cloudai-x/threejs-skills threejs-textures",
1593
- "cloudai-x/threejs-skills threejs-loaders",
1594
- "cloudai-x/threejs-skills threejs-interaction",
1595
- "cloudai-x/threejs-skills threejs-postprocessing"
1596
- ],
1597
- // UI Libraries
1598
- "tailwindcss": [
1599
- "wshobson/agents tailwind-design-system",
1600
- "jezweb/claude-skills tailwind-v4-shadcn",
1601
- "wshobson/agents responsive-design"
1602
- ],
1603
- "@shadcn/ui": [
1604
- "giuseppe-trisciuoglio/developer-kit shadcn-ui"
1605
- ],
1606
- "shadcn": [
1607
- "giuseppe-trisciuoglio/developer-kit shadcn-ui"
1608
- ],
1609
- "@radix-ui/react-slot": [
1610
- "onmax/nuxt-skills reka-ui"
1611
- ],
1612
- // State Management
1613
- "@tanstack/react-query": [
1614
- "jezweb/claude-skills tanstack-query"
1615
- ],
1616
- // Testing
1617
- "playwright": [
1618
- "anthropics/skills webapp-testing",
1619
- "wshobson/agents e2e-testing-patterns"
1620
- ],
1621
- "puppeteer": [
1622
- "anthropics/skills webapp-testing"
1623
- ],
1624
- "vitest": [
1625
- "wshobson/agents e2e-testing-patterns"
1626
- ],
1627
- "jest": [
1628
- "wshobson/agents e2e-testing-patterns"
1629
- ],
1630
- // DevTools/MCP
1631
- "@modelcontextprotocol/sdk": [
1632
- "anthropics/skills mcp-builder"
1633
- ],
1634
- // Security
1635
- "semgrep": [
1636
- "trailofbits/skills semgrep"
1637
- ],
1638
- // Monorepos
1639
- "turbo": [
1640
- "wshobson/agents monorepo-management"
1641
- ],
1642
- "nx": [
1643
- "wshobson/agents monorepo-management"
1644
- ],
1645
- "lerna": [
1646
- "wshobson/agents monorepo-management"
1647
- ],
1648
- // TypeScript (handled separately based on tsconfig.json)
1649
- "typescript": [
1650
- "wshobson/agents typescript-advanced-types"
1651
- ]
1652
- };
1653
- var SKILL_CATEGORIES = {
1654
- documents: [
1655
- "anthropics/skills pdf",
1656
- "anthropics/skills xlsx",
1657
- "anthropics/skills pptx",
1658
- "anthropics/skills docx",
1659
- "anthropics/skills doc-coauthoring"
1660
- ],
1661
- design: [
1662
- "anthropics/skills canvas-design",
1663
- "anthropics/skills theme-factory",
1664
- "anthropics/skills web-artifacts-builder",
1665
- "anthropics/skills algorithmic-art",
1666
- "anthropics/skills brand-guidelines",
1667
- "anthropics/skills slack-gif-creator",
1668
- "nextlevelbuilder/ui-ux-pro-max ui-ux-pro-max",
1669
- "superdesigndev/superdesign-skill superdesign",
1670
- "wshobson/agents design-system-patterns"
1671
- ],
1672
- marketing: [
1673
- "coreyhaines31/marketingskills seo-audit",
1674
- "coreyhaines31/marketingskills copywriting",
1675
- "coreyhaines31/marketingskills marketing-psychology",
1676
- "coreyhaines31/marketingskills programmatic-seo",
1677
- "coreyhaines31/marketingskills marketing-ideas",
1678
- "coreyhaines31/marketingskills copy-editing",
1679
- "coreyhaines31/marketingskills pricing-strategy",
1680
- "coreyhaines31/marketingskills social-content",
1681
- "coreyhaines31/marketingskills launch-strategy",
1682
- "coreyhaines31/marketingskills page-cro",
1683
- "coreyhaines31/marketingskills competitor-alternatives",
1684
- "coreyhaines31/marketingskills analytics-tracking",
1685
- "coreyhaines31/marketingskills schema-markup",
1686
- "coreyhaines31/marketingskills onboarding-cro",
1687
- "coreyhaines31/marketingskills email-sequence",
1688
- "coreyhaines31/marketingskills paid-ads",
1689
- "coreyhaines31/marketingskills signup-flow-cro",
1690
- "coreyhaines31/marketingskills free-tool-strategy",
1691
- "coreyhaines31/marketingskills form-cro",
1692
- "coreyhaines31/marketingskills paywall-upgrade-cro",
1693
- "coreyhaines31/marketingskills referral-program",
1694
- "coreyhaines31/marketingskills popup-cro",
1695
- "coreyhaines31/marketingskills ab-test-setup"
1696
- ],
1697
- development: [
1698
- "obra/superpowers brainstorming",
1699
- "obra/superpowers test-driven-development",
1700
- "obra/superpowers systematic-debugging",
1701
- "obra/superpowers writing-plans",
1702
- "obra/superpowers executing-plans",
1703
- "obra/superpowers verification-before-completion",
1704
- "obra/superpowers using-superpowers",
1705
- "obra/superpowers subagent-driven-development",
1706
- "obra/superpowers requesting-code-review",
1707
- "obra/superpowers writing-skills",
1708
- "obra/superpowers dispatching-parallel-agents",
1709
- "obra/superpowers receiving-code-review",
1710
- "obra/superpowers using-git-worktrees",
1711
- "obra/superpowers finishing-a-development-branch",
1712
- "wshobson/agents code-review-excellence",
1713
- "wshobson/agents api-design-principles",
1714
- "wshobson/agents architecture-patterns",
1715
- "wshobson/agents error-handling-patterns",
1716
- "wshobson/agents nodejs-backend-patterns",
1717
- "wshobson/agents microservices-patterns",
1718
- "wshobson/agents modern-javascript-patterns",
1719
- "wshobson/agents web-component-design",
1720
- "wshobson/agents async-python-patterns",
1721
- "wshobson/agents python-testing-patterns",
1722
- "boristane/agent-skills logging-best-practices"
1723
- ],
1724
- productivity: [
1725
- "softaworks/agent-toolkit daily-meeting-update",
1726
- "softaworks/agent-toolkit agent-md-refactor",
1727
- "softaworks/agent-toolkit session-handoff",
1728
- "softaworks/agent-toolkit meme-factory",
1729
- "softaworks/agent-toolkit qa-test-planner",
1730
- "softaworks/agent-toolkit writing-clearly-and-concisely",
1731
- "softaworks/agent-toolkit commit-work",
1732
- "softaworks/agent-toolkit mermaid-diagrams",
1733
- "softaworks/agent-toolkit dependency-updater",
1734
- "softaworks/agent-toolkit crafting-effective-readmes",
1735
- "softaworks/agent-toolkit reducing-entropy",
1736
- "softaworks/agent-toolkit feedback-mastery",
1737
- "softaworks/agent-toolkit marp-slide",
1738
- "softaworks/agent-toolkit professional-communication",
1739
- "softaworks/agent-toolkit difficult-workplace-conversations",
1740
- "anthropics/skills internal-comms",
1741
- "othmanadi/planning-with-files planning-with-files"
1742
- ],
1743
- security: [
1744
- "trailofbits/skills semgrep",
1745
- "trailofbits/skills secure-workflow-guide",
1746
- "trailofbits/skills codeql",
1747
- "trailofbits/skills property-based-testing",
1748
- "trailofbits/skills variant-analysis",
1749
- "trailofbits/skills guidelines-advisor",
1750
- "trailofbits/skills sharp-edges",
1751
- "trailofbits/skills differential-review",
1752
- "trailofbits/skills ask-questions-if-underspecified",
1753
- "squirrelscan/skills audit-website"
1754
- ],
1755
- mobile: [
1756
- "wshobson/agents mobile-ios-design",
1757
- "wshobson/agents mobile-android-design",
1758
- "dimillian/skills swiftui-ui-patterns",
1759
- "dimillian/skills swiftui-liquid-glass"
1760
- ],
1761
- obsidian: [
1762
- "kepano/obsidian-skills obsidian-markdown",
1763
- "kepano/obsidian-skills obsidian-bases",
1764
- "kepano/obsidian-skills json-canvas"
1765
- ],
1766
- prompts: [
1767
- "f/awesome-chatgpt-prompts skill-lookup",
1768
- "f/awesome-chatgpt-prompts prompt-lookup",
1769
- "wshobson/agents prompt-engineering-patterns"
1770
- ],
1771
- browser: [
1772
- "vercel-labs/agent-browser agent-browser"
1773
- ],
1774
- content: [
1775
- "op7418/humanizer-zh humanizer-zh",
1776
- "blader/humanizer humanizer",
1777
- "op7418/youtube-clipper-skill youtube-clipper",
1778
- "jimliu/baoyu-skills baoyu-slide-deck",
1779
- "jimliu/baoyu-skills baoyu-article-illustrator",
1780
- "jimliu/baoyu-skills baoyu-cover-image",
1781
- "jimliu/baoyu-skills baoyu-comic",
1782
- "jimliu/baoyu-skills baoyu-infographic",
1783
- "jimliu/baoyu-skills baoyu-image-gen"
1784
- ],
1785
- integrations: [
1786
- "intellectronica/agent-skills context7",
1787
- "softaworks/agent-toolkit gemini",
1788
- "softaworks/agent-toolkit codex"
1789
- ]
1790
- };
1791
- async function detectStack(projectDir) {
1792
- const stack = {
1793
- suggestedSkills: [],
1794
- suggestedAgents: ["security", "privacy", "bugs"],
1795
- dependencies: /* @__PURE__ */ new Set()
1796
- };
1797
- if (existsSync5(join4(projectDir, "tsconfig.json"))) {
1798
- stack.language = "TypeScript";
1799
- stack.suggestedAgents.push("typecheck");
1800
- stack.suggestedSkills.push("wshobson/agents typescript-advanced-types");
1801
- } else if (existsSync5(join4(projectDir, "package.json"))) {
1802
- stack.language = "JavaScript";
1803
- } else if (existsSync5(join4(projectDir, "requirements.txt")) || existsSync5(join4(projectDir, "pyproject.toml"))) {
1804
- stack.language = "Python";
1805
- } else if (existsSync5(join4(projectDir, "go.mod"))) {
1806
- stack.language = "Go";
1807
- } else if (existsSync5(join4(projectDir, "Cargo.toml"))) {
1808
- stack.language = "Rust";
1809
- }
1810
- if (existsSync5(join4(projectDir, "Package.swift")) || existsSync5(join4(projectDir, "project.pbxproj")) || existsSync5(join4(projectDir, "*.xcodeproj"))) {
1811
- stack.language = "Swift";
1812
- stack.suggestedSkills.push("dimillian/skills swiftui-ui-patterns");
1813
- stack.suggestedSkills.push("dimillian/skills swiftui-liquid-glass");
1814
- }
1815
- if (existsSync5(join4(projectDir, "pnpm-lock.yaml"))) {
1816
- stack.packageManager = "pnpm";
1817
- } else if (existsSync5(join4(projectDir, "yarn.lock"))) {
1818
- stack.packageManager = "yarn";
1819
- } else if (existsSync5(join4(projectDir, "bun.lockb"))) {
1820
- stack.packageManager = "bun";
1821
- } else if (existsSync5(join4(projectDir, "package-lock.json"))) {
1822
- stack.packageManager = "npm";
1823
- }
1824
- if (existsSync5(join4(projectDir, ".github", "workflows"))) {
1825
- stack.suggestedSkills.push("wshobson/agents github-actions-templates");
1826
- }
1827
- try {
1828
- const pkgPath = join4(projectDir, "package.json");
1829
- if (existsSync5(pkgPath)) {
1830
- const pkgContent = await readFile2(pkgPath, "utf-8");
1831
- const pkg = JSON.parse(pkgContent);
1832
- const deps = { ...pkg.dependencies, ...pkg.devDependencies };
1833
- for (const dep of Object.keys(deps)) {
1834
- stack.dependencies.add(dep);
1835
- }
1836
- for (const dep of Object.keys(deps)) {
1837
- const skills = SKILL_MAPPINGS[dep];
1838
- if (skills) {
1839
- stack.suggestedSkills.push(...skills);
1840
- }
1841
- }
1842
- if (deps["next"]) {
1843
- stack.framework = `Next.js ${deps["next"].replace("^", "")}`;
1844
- stack.suggestedAgents.push("accessibility", "design");
1845
- } else if (deps["react"]) {
1846
- stack.framework = `React ${deps["react"].replace("^", "")}`;
1847
- stack.suggestedAgents.push("accessibility");
1848
- } else if (deps["vue"]) {
1849
- stack.framework = `Vue ${deps["vue"].replace("^", "")}`;
1850
- } else if (deps["nuxt"]) {
1851
- stack.framework = `Nuxt ${deps["nuxt"].replace("^", "")}`;
1852
- } else if (deps["svelte"]) {
1853
- stack.framework = "Svelte";
1854
- } else if (deps["express"]) {
1855
- stack.framework = "Express.js";
1856
- } else if (deps["fastify"]) {
1857
- stack.framework = "Fastify";
1858
- } else if (deps["hono"]) {
1859
- stack.framework = "Hono";
1860
- } else if (deps["elysia"]) {
1861
- stack.framework = "Elysia";
1862
- } else if (deps["@nestjs/core"]) {
1863
- stack.framework = "NestJS";
1864
- }
1865
- if (deps["next-auth"] || deps["@auth/core"]) {
1866
- stack.auth = "NextAuth.js";
1867
- } else if (deps["passport"]) {
1868
- stack.auth = "Passport.js";
1869
- } else if (deps["@clerk/nextjs"] || deps["@clerk/clerk-react"]) {
1870
- stack.auth = "Clerk";
1871
- } else if (deps["better-auth"]) {
1872
- stack.auth = "Better Auth";
1873
- }
1874
- if (deps["prisma"] || deps["@prisma/client"]) {
1875
- stack.database = "Prisma ORM";
1876
- } else if (deps["drizzle-orm"]) {
1877
- stack.database = "Drizzle ORM";
1878
- } else if (deps["@supabase/supabase-js"]) {
1879
- stack.database = "Supabase";
1880
- } else if (deps["mongoose"]) {
1881
- stack.database = "MongoDB (Mongoose)";
1882
- } else if (deps["pg"]) {
1883
- stack.database = "PostgreSQL";
1884
- } else if (deps["convex"]) {
1885
- stack.database = "Convex";
1886
- }
1887
- if (deps["stripe"] || deps["@stripe/stripe-js"]) {
1888
- stack.suggestedAgents.push("moneybags");
1889
- }
1890
- }
1891
- } catch {
1892
- }
1893
- if (!stack.database) {
1894
- if (existsSync5(join4(projectDir, "prisma", "schema.prisma"))) {
1895
- stack.database = "Prisma ORM";
1896
- } else if (existsSync5(join4(projectDir, "drizzle.config.ts"))) {
1897
- stack.database = "Drizzle ORM";
1898
- }
1899
- }
1900
- stack.suggestedSkills = [...new Set(stack.suggestedSkills)];
1901
- stack.suggestedAgents = [...new Set(stack.suggestedAgents)];
1902
- return stack;
1903
- }
1904
- function getSkillsByCategory(category) {
1905
- return SKILL_CATEGORIES[category] || [];
1906
- }
1907
- function getSkillCategories() {
1908
- return Object.entries(SKILL_CATEGORIES).map(([name, skills]) => ({
1909
- name,
1910
- count: skills.length
1911
- }));
1912
- }
1913
-
1914
- // src/patterns/saved-patterns.ts
1915
- import { createHash } from "crypto";
1916
- import { readFile as readFile3, writeFile as writeFile2 } from "fs/promises";
1917
- import { existsSync as existsSync6 } from "fs";
1918
- import { join as join5, basename } from "path";
1919
- async function loadSavedPatterns(workDir) {
1920
- const patternsPath = join5(getTrieDirectory(workDir), "saved-patterns.json");
1921
- try {
1922
- if (existsSync6(patternsPath)) {
1923
- const content = await readFile3(patternsPath, "utf-8");
1924
- return JSON.parse(content);
1925
- }
1926
- } catch {
1927
- }
1928
- return [];
1929
- }
1930
- async function savePatternsToProject(patterns, workDir) {
1931
- const { mkdir: mkdir2 } = await import("fs/promises");
1932
- const patternsPath = join5(getTrieDirectory(workDir), "saved-patterns.json");
1933
- await mkdir2(getTrieDirectory(workDir), { recursive: true });
1934
- await writeFile2(patternsPath, JSON.stringify(patterns, null, 2));
1935
- }
1936
- async function savePatternToProject(pattern, workDir) {
1937
- const patterns = await loadSavedPatterns(workDir);
1938
- const existing = patterns.findIndex((p) => p.id === pattern.id);
1939
- if (existing >= 0) {
1940
- patterns[existing] = {
1941
- ...patterns[existing],
1942
- ...pattern,
1943
- occurrences: patterns[existing].occurrences + 1
1944
- };
1945
- } else {
1946
- patterns.push(pattern);
1947
- }
1948
- await savePatternsToProject(patterns, workDir);
1949
- }
1950
- function detectPatternType(target, workDir) {
1951
- const scoutNames = [
1952
- "security",
1953
- "privacy",
1954
- "legal",
1955
- "accessibility",
1956
- "bug-finding",
1957
- "architecture",
1958
- "types",
1959
- "clean",
1960
- "devops",
1961
- "performance",
1962
- "ux",
1963
- "design",
1964
- "production-ready",
1965
- "agent-smith"
1966
- ];
1967
- if (scoutNames.includes(target.toLowerCase())) {
1968
- return "detection-rule";
1969
- }
1970
- const fullPath = join5(workDir, target);
1971
- if (existsSync6(fullPath) || target.includes("/") || target.includes("*") || target.endsWith(".ts") || target.endsWith(".js")) {
1972
- return "file-structure";
1973
- }
1974
- return "code-pattern";
1975
- }
1976
- function generatePatternId(target, type) {
1977
- const hash = createHash("sha256").update(`${type}:${target}`).digest("hex").slice(0, 12);
1978
- return `${type}-${hash}`;
1979
- }
1980
- function getDetectionRuleAgents(patterns) {
1981
- return patterns.filter((p) => p.type === "detection-rule").map((p) => p.detectionRule?.agent || p.name).filter(Boolean);
1982
- }
1983
- async function createSavedPattern(target, note, workDir) {
1984
- const projectName = basename(workDir);
1985
- const patternType = detectPatternType(target, workDir);
1986
- const savedPattern = {
1987
- id: generatePatternId(target, patternType),
1988
- type: patternType,
1989
- name: target,
1990
- description: note || `Pattern saved from ${projectName}`,
1991
- validated: false,
1992
- projects: [projectName],
1993
- occurrences: 1,
1994
- savedAt: (/* @__PURE__ */ new Date()).toISOString(),
1995
- savedBy: projectName
1996
- };
1997
- if (patternType === "file-structure") {
1998
- savedPattern.filePatterns = [target];
1999
- savedPattern.architecture = {
2000
- structure: `Files matching ${target}`,
2001
- rationale: note || "File structure pattern that worked well"
2002
- };
2003
- } else if (patternType === "code-pattern") {
2004
- const issues = await searchIssues(target, { limit: 5 });
2005
- if (issues.length > 0) {
2006
- const latestIssue = issues[0];
2007
- savedPattern.codePattern = {
2008
- pattern: latestIssue?.issue.issue || target,
2009
- fix: latestIssue?.issue.fix || "Review and apply similar fix",
2010
- context: note || "Code pattern that worked well"
2011
- };
2012
- } else {
2013
- savedPattern.codePattern = {
2014
- pattern: target,
2015
- fix: "Review and apply similar fix",
2016
- context: note || "Code pattern that worked well"
2017
- };
2018
- }
2019
- } else if (patternType === "detection-rule") {
2020
- savedPattern.detectionRule = {
2021
- agent: target,
2022
- rule: `Detection rules from ${target} scout`,
2023
- severity: "moderate"
2024
- };
2025
- }
2026
- return savedPattern;
2027
- }
2028
- async function buildSavedPatternIssues(patterns, files, readFileContent) {
2029
- const issues = [];
2030
- for (const pattern of patterns) {
2031
- if (pattern.type === "detection-rule") continue;
2032
- const targetFiles = filterFilesForPattern(files, pattern);
2033
- if (targetFiles.length === 0) continue;
2034
- if (pattern.type === "file-structure") {
2035
- for (const file of targetFiles) {
2036
- issues.push(createPatternIssue(pattern, file, void 0));
2037
- }
2038
- continue;
2039
- }
2040
- if (pattern.type === "code-pattern" && pattern.codePattern) {
2041
- for (const file of targetFiles) {
2042
- const content = await readFileContent(file);
2043
- const match = findPatternMatch(content, pattern.codePattern.pattern);
2044
- if (match) {
2045
- issues.push(createPatternIssue(pattern, file, match.line));
2046
- }
2047
- }
2048
- }
2049
- }
2050
- return issues;
2051
- }
2052
- function filterFilesForPattern(files, pattern) {
2053
- if (pattern.type === "file-structure" && pattern.filePatterns) {
2054
- return files.filter((file) => pattern.filePatterns.some((p) => matchesFilePattern(file, p)));
2055
- }
2056
- if (pattern.type === "code-pattern") {
2057
- return files;
2058
- }
2059
- return [];
2060
- }
2061
- function matchesFilePattern(filePath, pattern) {
2062
- const normalized = filePath.replace(/\\/g, "/");
2063
- const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "___DOUBLESTAR___").replace(/\*/g, "[^/]*").replace(/___DOUBLESTAR___/g, ".*");
2064
- const regex = new RegExp(`^${escaped}$`, "i");
2065
- return regex.test(normalized) || normalized.includes(pattern.replace(/\*+/g, ""));
2066
- }
2067
- function findPatternMatch(content, pattern) {
2068
- try {
2069
- const regex = new RegExp(pattern, "i");
2070
- const match = regex.exec(content);
2071
- if (!match || match.index === void 0) return null;
2072
- const line = getLineNumber(content, match.index);
2073
- return { line };
2074
- } catch {
2075
- const index = content.toLowerCase().indexOf(pattern.toLowerCase());
2076
- if (index === -1) return null;
2077
- const line = getLineNumber(content, index);
2078
- return { line };
2079
- }
2080
- }
2081
- function getLineNumber(content, index) {
2082
- return content.slice(0, index).split("\n").length;
2083
- }
2084
- function createPatternIssue(pattern, file, line) {
2085
- const description = pattern.description || `Saved pattern: ${pattern.name}`;
2086
- const fix = pattern.codePattern?.fix || "Apply the saved pattern from your other project.";
2087
- const issue = {
2088
- id: `saved-${pattern.id}-${hashFile(file)}`,
2089
- severity: "low",
2090
- issue: `Saved pattern suggestion: ${description}`,
2091
- fix,
2092
- file,
2093
- confidence: 0.6,
2094
- autoFixable: false,
2095
- agent: "saved-patterns",
2096
- category: "pattern-sharing"
2097
- };
2098
- if (line !== void 0) {
2099
- issue.line = line;
2100
- }
2101
- return issue;
2102
- }
2103
- function hashFile(file) {
2104
- return createHash("sha256").update(file).digest("hex").slice(0, 8);
2105
- }
2106
-
2107
- export {
2108
- loadConfig,
2109
- saveConfig,
2110
- Triager,
2111
- Executor,
2112
- isTrieInitialized,
2113
- SKILL_CATEGORIES,
2114
- detectStack,
2115
- getSkillsByCategory,
2116
- getSkillCategories,
2117
- loadSavedPatterns,
2118
- savePatternsToProject,
2119
- savePatternToProject,
2120
- getDetectionRuleAgents,
2121
- createSavedPattern,
2122
- buildSavedPatternIssues
2123
- };
2124
- //# sourceMappingURL=chunk-CUXXRM3T.js.map