@triedotdev/mcp 1.0.138 → 1.0.140
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +184 -38
- package/dist/{autonomy-config-TZ6HF4FA.js → autonomy-config-ZCOSTMPD.js} +2 -2
- package/dist/{chunk-X3F5QDER.js → chunk-4O2KRHK4.js} +934 -132
- package/dist/chunk-4O2KRHK4.js.map +1 -0
- package/dist/{chunk-J5EMP4XW.js → chunk-5KJ4UJOY.js} +9 -4
- package/dist/chunk-5KJ4UJOY.js.map +1 -0
- package/dist/chunk-62POBLFC.js +1925 -0
- package/dist/chunk-62POBLFC.js.map +1 -0
- package/dist/{chunk-GFFUDJMK.js → chunk-75ADWWUF.js} +13 -13
- package/dist/chunk-75ADWWUF.js.map +1 -0
- package/dist/{chunk-D3AS5LY7.js → chunk-7OJ6JIPL.js} +39 -604
- package/dist/chunk-7OJ6JIPL.js.map +1 -0
- package/dist/{chunk-3RRXWX3V.js → chunk-AF2APASP.js} +38 -4
- package/dist/{chunk-3RRXWX3V.js.map → chunk-AF2APASP.js.map} +1 -1
- package/dist/{chunk-QSWUPSLK.js → chunk-FH335WL5.js} +9 -1
- package/dist/chunk-FH335WL5.js.map +1 -0
- package/dist/{chunk-Y32FM3MR.js → chunk-FPEMP54L.js} +21 -15
- package/dist/chunk-FPEMP54L.js.map +1 -0
- package/dist/{chunk-EDDT4ZIH.js → chunk-GXF6JOCN.js} +21 -323
- package/dist/chunk-GXF6JOCN.js.map +1 -0
- package/dist/chunk-LD7ZEFNY.js +132 -0
- package/dist/chunk-LD7ZEFNY.js.map +1 -0
- package/dist/chunk-NKHO34UZ.js +467 -0
- package/dist/chunk-NKHO34UZ.js.map +1 -0
- package/dist/{chunk-YOKQ25IW.js → chunk-OQ4A3RDY.js} +14 -14
- package/dist/{chunk-6LLH3TBZ.js → chunk-UOSTOLU7.js} +12 -12
- package/dist/{chunk-67GSG2ST.js → chunk-XTTZAQWJ.js} +18 -15
- package/dist/chunk-XTTZAQWJ.js.map +1 -0
- package/dist/{chunk-FOCXXIXY.js → chunk-YEIJW6X6.js} +2 -2
- package/dist/chunk-YOJGSRZK.js +216 -0
- package/dist/chunk-YOJGSRZK.js.map +1 -0
- package/dist/cli/main.js +573 -59
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/yolo-daemon.js +15 -13
- package/dist/cli/yolo-daemon.js.map +1 -1
- package/dist/{client-JTU5TRLB.js → client-INNE2GGZ.js} +2 -2
- package/dist/{codebase-index-FNJ4GCBE.js → codebase-index-5SEOESWM.js} +3 -3
- package/dist/fast-analyzer-AYLZB5TW.js +216 -0
- package/dist/fast-analyzer-AYLZB5TW.js.map +1 -0
- package/dist/github-ingester-J2ZFYXVE.js +11 -0
- package/dist/{goal-manager-6BJQ36AH.js → goal-manager-ZBWKWEML.js} +3 -3
- package/dist/{goal-validator-GISXYANK.js → goal-validator-HNXXUCPW.js} +3 -3
- package/dist/{graph-X2FMRQLG.js → graph-J4OGTYCO.js} +2 -2
- package/dist/{hypothesis-K3KQJOXJ.js → hypothesis-JCUMZKTG.js} +3 -3
- package/dist/index.js +1090 -108
- package/dist/index.js.map +1 -1
- package/dist/{issue-store-BO5OWLJW.js → issue-store-LZWZIGM7.js} +2 -2
- package/dist/linear-ingester-JRDQAIAA.js +11 -0
- package/dist/linear-ingester-JRDQAIAA.js.map +1 -0
- package/dist/{trie-agent-XMSGMD7E.js → trie-agent-M6PHM6UD.js} +10 -10
- package/dist/trie-agent-M6PHM6UD.js.map +1 -0
- package/package.json +15 -8
- package/dist/chunk-67GSG2ST.js.map +0 -1
- package/dist/chunk-D3AS5LY7.js.map +0 -1
- package/dist/chunk-EDDT4ZIH.js.map +0 -1
- package/dist/chunk-GFFUDJMK.js.map +0 -1
- package/dist/chunk-J5EMP4XW.js.map +0 -1
- package/dist/chunk-QSWUPSLK.js.map +0 -1
- package/dist/chunk-X3F5QDER.js.map +0 -1
- package/dist/chunk-Y32FM3MR.js.map +0 -1
- package/dist/chunk-Z2P4WST6.js +0 -883
- package/dist/chunk-Z2P4WST6.js.map +0 -1
- /package/dist/{autonomy-config-TZ6HF4FA.js.map → autonomy-config-ZCOSTMPD.js.map} +0 -0
- /package/dist/{chunk-YOKQ25IW.js.map → chunk-OQ4A3RDY.js.map} +0 -0
- /package/dist/{chunk-6LLH3TBZ.js.map → chunk-UOSTOLU7.js.map} +0 -0
- /package/dist/{chunk-FOCXXIXY.js.map → chunk-YEIJW6X6.js.map} +0 -0
- /package/dist/{client-JTU5TRLB.js.map → client-INNE2GGZ.js.map} +0 -0
- /package/dist/{codebase-index-FNJ4GCBE.js.map → codebase-index-5SEOESWM.js.map} +0 -0
- /package/dist/{goal-manager-6BJQ36AH.js.map → github-ingester-J2ZFYXVE.js.map} +0 -0
- /package/dist/{goal-validator-GISXYANK.js.map → goal-manager-ZBWKWEML.js.map} +0 -0
- /package/dist/{graph-X2FMRQLG.js.map → goal-validator-HNXXUCPW.js.map} +0 -0
- /package/dist/{hypothesis-K3KQJOXJ.js.map → graph-J4OGTYCO.js.map} +0 -0
- /package/dist/{issue-store-BO5OWLJW.js.map → hypothesis-JCUMZKTG.js.map} +0 -0
- /package/dist/{trie-agent-XMSGMD7E.js.map → issue-store-LZWZIGM7.js.map} +0 -0
|
@@ -2,9 +2,6 @@ import {
|
|
|
2
2
|
getTrieDirectory,
|
|
3
3
|
getWorkingDirectory
|
|
4
4
|
} from "./chunk-SH7H3WRU.js";
|
|
5
|
-
import {
|
|
6
|
-
isInteractiveMode
|
|
7
|
-
} from "./chunk-APMV77PU.js";
|
|
8
5
|
|
|
9
6
|
// src/utils/project-info.ts
|
|
10
7
|
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
@@ -313,449 +310,10 @@ async function getContextForAI() {
|
|
|
313
310
|
return lines.join("\n");
|
|
314
311
|
}
|
|
315
312
|
|
|
316
|
-
// src/config/loader.ts
|
|
317
|
-
import { readFile as readFile3, writeFile as writeFile2, mkdir as mkdir3 } from "fs/promises";
|
|
318
|
-
import { existsSync as existsSync4 } from "fs";
|
|
319
|
-
import { join as join4, dirname } from "path";
|
|
320
|
-
|
|
321
|
-
// src/config/validation.ts
|
|
322
|
-
import { z } from "zod";
|
|
323
|
-
import { existsSync as existsSync3, readFileSync, mkdirSync } from "fs";
|
|
324
|
-
import { resolve, join as join3 } from "path";
|
|
325
|
-
var API_KEY_PATTERNS = {
|
|
326
|
-
anthropic: /^sk-ant-api\d{2}-[\w-]{95}$/,
|
|
327
|
-
openai: /^sk-[\w]{48}$/,
|
|
328
|
-
github: /^ghp_[\w]{36}$/,
|
|
329
|
-
vercel: /^[\w]{24}$/,
|
|
330
|
-
linear: /^lin_api_[\w]{40,60}$/
|
|
331
|
-
};
|
|
332
|
-
var ApiKeysSchema = z.object({
|
|
333
|
-
anthropic: z.string().regex(API_KEY_PATTERNS.anthropic, "Invalid Anthropic API key format").optional(),
|
|
334
|
-
openai: z.string().regex(API_KEY_PATTERNS.openai, "Invalid OpenAI API key format").optional(),
|
|
335
|
-
github: z.string().regex(API_KEY_PATTERNS.github, "Invalid GitHub token format").optional(),
|
|
336
|
-
vercel: z.string().regex(API_KEY_PATTERNS.vercel, "Invalid Vercel token format").optional(),
|
|
337
|
-
linear: z.string().optional()
|
|
338
|
-
// Linear keys can vary, so we'll be flexible but allow storage
|
|
339
|
-
});
|
|
340
|
-
var AgentConfigSchema = z.object({
|
|
341
|
-
enabled: z.array(z.string()).optional().default([]),
|
|
342
|
-
disabled: z.array(z.string()).optional().default([]),
|
|
343
|
-
parallel: z.boolean().optional().default(true),
|
|
344
|
-
maxConcurrency: z.number().int().min(1).max(20).optional().default(4),
|
|
345
|
-
timeout: z.number().int().min(1e3).max(3e5).optional().default(12e4),
|
|
346
|
-
// 2 minutes
|
|
347
|
-
cache: z.boolean().optional().default(true)
|
|
348
|
-
});
|
|
349
|
-
var ComplianceSchema = z.object({
|
|
350
|
-
standards: z.array(z.enum(["SOC2", "GDPR", "HIPAA", "CCPA", "PCI-DSS"])).optional().default(["SOC2"]),
|
|
351
|
-
enforceCompliance: z.boolean().optional().default(false),
|
|
352
|
-
reportFormat: z.enum(["json", "sarif", "csv", "html"]).optional().default("json")
|
|
353
|
-
});
|
|
354
|
-
var OutputSchema = z.object({
|
|
355
|
-
format: z.enum(["console", "json", "sarif", "junit"]).optional().default("console"),
|
|
356
|
-
level: z.enum(["critical", "serious", "moderate", "low", "all"]).optional().default("all"),
|
|
357
|
-
interactive: z.boolean().optional().default(false),
|
|
358
|
-
streaming: z.boolean().optional().default(true),
|
|
359
|
-
colors: z.boolean().optional().default(true)
|
|
360
|
-
});
|
|
361
|
-
var PathsSchema = z.object({
|
|
362
|
-
include: z.array(z.string()).optional().default([]),
|
|
363
|
-
exclude: z.array(z.string()).optional().default(["node_modules", "dist", "build", ".git"]),
|
|
364
|
-
configDir: z.string().optional().default(".trie"),
|
|
365
|
-
outputDir: z.string().optional().default("trie-reports")
|
|
366
|
-
});
|
|
367
|
-
var IntegrationsSchema = z.object({
|
|
368
|
-
github: z.object({
|
|
369
|
-
enabled: z.boolean().optional().default(false),
|
|
370
|
-
token: z.string().optional(),
|
|
371
|
-
webhook: z.string().url().optional()
|
|
372
|
-
}).optional(),
|
|
373
|
-
slack: z.object({
|
|
374
|
-
enabled: z.boolean().optional().default(false),
|
|
375
|
-
webhook: z.string().url().optional(),
|
|
376
|
-
channel: z.string().optional()
|
|
377
|
-
}).optional(),
|
|
378
|
-
jira: z.object({
|
|
379
|
-
enabled: z.boolean().optional().default(false),
|
|
380
|
-
url: z.string().url().optional(),
|
|
381
|
-
token: z.string().optional(),
|
|
382
|
-
project: z.string().optional()
|
|
383
|
-
}).optional()
|
|
384
|
-
});
|
|
385
|
-
var UserSchema = z.object({
|
|
386
|
-
name: z.string().min(1).optional(),
|
|
387
|
-
email: z.string().email().optional(),
|
|
388
|
-
role: z.enum([
|
|
389
|
-
"developer",
|
|
390
|
-
"designer",
|
|
391
|
-
"qa",
|
|
392
|
-
"devops",
|
|
393
|
-
"security",
|
|
394
|
-
"architect",
|
|
395
|
-
"manager",
|
|
396
|
-
"contributor"
|
|
397
|
-
]).optional().default("developer"),
|
|
398
|
-
github: z.string().optional(),
|
|
399
|
-
// GitHub username
|
|
400
|
-
url: z.string().url().optional()
|
|
401
|
-
// Personal/portfolio URL
|
|
402
|
-
});
|
|
403
|
-
var TrieConfigSchema = z.object({
|
|
404
|
-
version: z.string().optional().default("1.0.0"),
|
|
405
|
-
apiKeys: ApiKeysSchema.optional(),
|
|
406
|
-
agents: AgentConfigSchema.optional(),
|
|
407
|
-
compliance: ComplianceSchema.optional(),
|
|
408
|
-
output: OutputSchema.optional(),
|
|
409
|
-
paths: PathsSchema.optional(),
|
|
410
|
-
integrations: IntegrationsSchema.optional(),
|
|
411
|
-
user: UserSchema.optional()
|
|
412
|
-
// User identity for attribution
|
|
413
|
-
});
|
|
414
|
-
var ConfigValidator = class {
|
|
415
|
-
/**
|
|
416
|
-
* Validate configuration object
|
|
417
|
-
*/
|
|
418
|
-
validateConfig(config) {
|
|
419
|
-
try {
|
|
420
|
-
const validated = TrieConfigSchema.parse(config);
|
|
421
|
-
const businessErrors = this.validateBusinessLogic(validated);
|
|
422
|
-
if (businessErrors.length > 0) {
|
|
423
|
-
return { success: false, errors: businessErrors };
|
|
424
|
-
}
|
|
425
|
-
return { success: true, data: validated };
|
|
426
|
-
} catch (error) {
|
|
427
|
-
if (error instanceof z.ZodError) {
|
|
428
|
-
const errors = error.errors.map(
|
|
429
|
-
(err) => `${err.path.join(".")}: ${err.message}`
|
|
430
|
-
);
|
|
431
|
-
return { success: false, errors };
|
|
432
|
-
}
|
|
433
|
-
return {
|
|
434
|
-
success: false,
|
|
435
|
-
errors: [`Configuration validation failed: ${error instanceof Error ? error.message : "Unknown error"}`]
|
|
436
|
-
};
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
/**
|
|
440
|
-
* Validate environment variables for API keys
|
|
441
|
-
*/
|
|
442
|
-
validateEnvironment() {
|
|
443
|
-
const warnings = [];
|
|
444
|
-
const errors = [];
|
|
445
|
-
const exposedPatterns = [
|
|
446
|
-
"NEXT_PUBLIC_ANTHROPIC",
|
|
447
|
-
"REACT_APP_ANTHROPIC",
|
|
448
|
-
"VITE_ANTHROPIC",
|
|
449
|
-
"PUBLIC_ANTHROPIC"
|
|
450
|
-
];
|
|
451
|
-
for (const pattern of exposedPatterns) {
|
|
452
|
-
const envVars = Object.keys(process.env).filter((key) => key.includes(pattern));
|
|
453
|
-
for (const envVar of envVars) {
|
|
454
|
-
errors.push(`[!] Security risk: API key in client-side environment variable: ${envVar}`);
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
let anthropicKey = process.env.ANTHROPIC_API_KEY;
|
|
458
|
-
if (!anthropicKey) {
|
|
459
|
-
try {
|
|
460
|
-
const configPath = join3(getTrieDirectory(getWorkingDirectory(void 0, true)), "config.json");
|
|
461
|
-
if (existsSync3(configPath)) {
|
|
462
|
-
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
463
|
-
anthropicKey = config.apiKeys?.anthropic;
|
|
464
|
-
}
|
|
465
|
-
} catch {
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
if (anthropicKey && !API_KEY_PATTERNS.anthropic.test(anthropicKey)) {
|
|
469
|
-
errors.push("ANTHROPIC_API_KEY does not match expected format");
|
|
470
|
-
}
|
|
471
|
-
if (!anthropicKey) {
|
|
472
|
-
warnings.push("ANTHROPIC_API_KEY not set - AI features will be disabled. Set in environment, .trie/config.json, or .env file");
|
|
473
|
-
}
|
|
474
|
-
if (!process.env.GITHUB_TOKEN && process.env.CI) {
|
|
475
|
-
warnings.push("GITHUB_TOKEN not set - GitHub integration disabled");
|
|
476
|
-
}
|
|
477
|
-
return {
|
|
478
|
-
valid: errors.length === 0,
|
|
479
|
-
warnings,
|
|
480
|
-
errors
|
|
481
|
-
};
|
|
482
|
-
}
|
|
483
|
-
/**
|
|
484
|
-
* Validate file paths in configuration
|
|
485
|
-
*/
|
|
486
|
-
validatePaths(paths) {
|
|
487
|
-
const errors = [];
|
|
488
|
-
if (paths?.include) {
|
|
489
|
-
for (const path of paths.include) {
|
|
490
|
-
const resolvedPath = resolve(path);
|
|
491
|
-
if (!existsSync3(resolvedPath)) {
|
|
492
|
-
errors.push(`Include path does not exist: ${path}`);
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
if (paths?.configDir) {
|
|
497
|
-
const configPath = resolve(paths.configDir);
|
|
498
|
-
if (!existsSync3(configPath)) {
|
|
499
|
-
try {
|
|
500
|
-
mkdirSync(configPath, { recursive: true });
|
|
501
|
-
} catch {
|
|
502
|
-
errors.push(`Cannot create config directory: ${paths.configDir}`);
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
return {
|
|
507
|
-
valid: errors.length === 0,
|
|
508
|
-
errors
|
|
509
|
-
};
|
|
510
|
-
}
|
|
511
|
-
/**
|
|
512
|
-
* Validate integration configurations
|
|
513
|
-
*/
|
|
514
|
-
validateIntegrations(integrations) {
|
|
515
|
-
const errors = [];
|
|
516
|
-
if (integrations?.github?.enabled) {
|
|
517
|
-
if (!integrations.github.token) {
|
|
518
|
-
errors.push("GitHub integration enabled but no token provided");
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
if (integrations?.slack?.enabled) {
|
|
522
|
-
if (!integrations.slack.webhook) {
|
|
523
|
-
errors.push("Slack integration enabled but no webhook URL provided");
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
if (integrations?.jira?.enabled) {
|
|
527
|
-
if (!integrations.jira.url || !integrations.jira.token || !integrations.jira.project) {
|
|
528
|
-
errors.push("JIRA integration enabled but missing required fields (url, token, project)");
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
return {
|
|
532
|
-
valid: errors.length === 0,
|
|
533
|
-
errors
|
|
534
|
-
};
|
|
535
|
-
}
|
|
536
|
-
/**
|
|
537
|
-
* Business logic validation
|
|
538
|
-
*/
|
|
539
|
-
validateBusinessLogic(config) {
|
|
540
|
-
const errors = [];
|
|
541
|
-
if (config.agents?.enabled && config.agents?.disabled) {
|
|
542
|
-
const overlap = config.agents.enabled.filter(
|
|
543
|
-
(agent) => config.agents?.disabled?.includes(agent)
|
|
544
|
-
);
|
|
545
|
-
if (overlap.length > 0) {
|
|
546
|
-
errors.push(`Agents cannot be both enabled and disabled: ${overlap.join(", ")}`);
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
if (config.agents?.maxConcurrency && config.agents.maxConcurrency > 10) {
|
|
550
|
-
errors.push("maxConcurrency should not exceed 10 for optimal performance");
|
|
551
|
-
}
|
|
552
|
-
if (config.compliance?.standards) {
|
|
553
|
-
const invalidStandards = config.compliance.standards.filter(
|
|
554
|
-
(standard) => !["SOC2", "GDPR", "HIPAA", "CCPA", "PCI-DSS"].includes(standard)
|
|
555
|
-
);
|
|
556
|
-
if (invalidStandards.length > 0) {
|
|
557
|
-
errors.push(`Invalid compliance standards: ${invalidStandards.join(", ")}`);
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
if (config.paths) {
|
|
561
|
-
const pathValidation = this.validatePaths(config.paths);
|
|
562
|
-
errors.push(...pathValidation.errors);
|
|
563
|
-
}
|
|
564
|
-
if (config.integrations) {
|
|
565
|
-
const integrationValidation = this.validateIntegrations(config.integrations);
|
|
566
|
-
errors.push(...integrationValidation.errors);
|
|
567
|
-
}
|
|
568
|
-
return errors;
|
|
569
|
-
}
|
|
570
|
-
/**
|
|
571
|
-
* Generate configuration template
|
|
572
|
-
*/
|
|
573
|
-
generateTemplate() {
|
|
574
|
-
return {
|
|
575
|
-
version: "1.0.0",
|
|
576
|
-
agents: {
|
|
577
|
-
enabled: ["security", "bugs", "types"],
|
|
578
|
-
disabled: [],
|
|
579
|
-
parallel: true,
|
|
580
|
-
maxConcurrency: 4,
|
|
581
|
-
timeout: 12e4,
|
|
582
|
-
cache: true
|
|
583
|
-
},
|
|
584
|
-
compliance: {
|
|
585
|
-
standards: ["SOC2"],
|
|
586
|
-
enforceCompliance: false,
|
|
587
|
-
reportFormat: "json"
|
|
588
|
-
},
|
|
589
|
-
output: {
|
|
590
|
-
format: "console",
|
|
591
|
-
level: "all",
|
|
592
|
-
interactive: false,
|
|
593
|
-
streaming: true,
|
|
594
|
-
colors: true
|
|
595
|
-
},
|
|
596
|
-
paths: {
|
|
597
|
-
include: [],
|
|
598
|
-
exclude: ["node_modules", "dist", "build", ".git"],
|
|
599
|
-
configDir: ".trie",
|
|
600
|
-
outputDir: "trie-reports"
|
|
601
|
-
}
|
|
602
|
-
};
|
|
603
|
-
}
|
|
604
|
-
/**
|
|
605
|
-
* Validate and provide suggestions for improvement
|
|
606
|
-
*/
|
|
607
|
-
analyze(config) {
|
|
608
|
-
const suggestions = [];
|
|
609
|
-
const securityIssues = [];
|
|
610
|
-
const optimizations = [];
|
|
611
|
-
let score = 100;
|
|
612
|
-
let hasApiKey = Boolean(config.apiKeys?.anthropic || process.env.ANTHROPIC_API_KEY);
|
|
613
|
-
if (!hasApiKey) {
|
|
614
|
-
try {
|
|
615
|
-
const workDir = getWorkingDirectory(void 0, true);
|
|
616
|
-
const envFiles = [".env", ".env.local", ".env.production"];
|
|
617
|
-
for (const envFile of envFiles) {
|
|
618
|
-
const envPath = join3(workDir, envFile);
|
|
619
|
-
if (existsSync3(envPath)) {
|
|
620
|
-
const envContent = readFileSync(envPath, "utf-8");
|
|
621
|
-
if (envContent.includes("ANTHROPIC_API_KEY=")) {
|
|
622
|
-
hasApiKey = true;
|
|
623
|
-
break;
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
} catch {
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
if (!hasApiKey) {
|
|
631
|
-
suggestions.push("Add ANTHROPIC_API_KEY to enable AI-powered analysis for better issue detection. Set in environment, .trie/config.json, or .env file");
|
|
632
|
-
score -= 10;
|
|
633
|
-
}
|
|
634
|
-
if (config.agents?.parallel === false) {
|
|
635
|
-
optimizations.push("Enable parallel agent execution for 3-5x faster scans");
|
|
636
|
-
score -= 15;
|
|
637
|
-
}
|
|
638
|
-
if (config.agents?.cache === false) {
|
|
639
|
-
optimizations.push("Enable result caching to speed up repeated scans");
|
|
640
|
-
score -= 10;
|
|
641
|
-
}
|
|
642
|
-
if (!config.compliance?.standards || config.compliance.standards.length === 0) {
|
|
643
|
-
suggestions.push("Configure compliance standards (SOC2, GDPR, etc.) for regulatory requirements");
|
|
644
|
-
score -= 5;
|
|
645
|
-
}
|
|
646
|
-
const hasIntegrations = config.integrations && (config.integrations.github?.enabled || config.integrations.slack?.enabled || config.integrations.jira?.enabled);
|
|
647
|
-
if (!hasIntegrations) {
|
|
648
|
-
suggestions.push("Consider enabling GitHub/Slack/JIRA integrations for better team collaboration");
|
|
649
|
-
score -= 5;
|
|
650
|
-
}
|
|
651
|
-
if (config.apiKeys) {
|
|
652
|
-
securityIssues.push("API keys in config file - consider using environment variables instead");
|
|
653
|
-
score -= 20;
|
|
654
|
-
}
|
|
655
|
-
return {
|
|
656
|
-
score: Math.max(0, score),
|
|
657
|
-
suggestions,
|
|
658
|
-
securityIssues,
|
|
659
|
-
optimizations
|
|
660
|
-
};
|
|
661
|
-
}
|
|
662
|
-
};
|
|
663
|
-
var DEFAULT_CONFIG = {
|
|
664
|
-
version: "1.0.0",
|
|
665
|
-
agents: {
|
|
666
|
-
enabled: [],
|
|
667
|
-
disabled: [],
|
|
668
|
-
parallel: true,
|
|
669
|
-
maxConcurrency: 4,
|
|
670
|
-
timeout: 12e4,
|
|
671
|
-
cache: true
|
|
672
|
-
},
|
|
673
|
-
compliance: {
|
|
674
|
-
standards: ["SOC2"],
|
|
675
|
-
enforceCompliance: false,
|
|
676
|
-
reportFormat: "json"
|
|
677
|
-
},
|
|
678
|
-
output: {
|
|
679
|
-
format: "console",
|
|
680
|
-
level: "all",
|
|
681
|
-
interactive: false,
|
|
682
|
-
streaming: true,
|
|
683
|
-
colors: true
|
|
684
|
-
},
|
|
685
|
-
paths: {
|
|
686
|
-
include: [],
|
|
687
|
-
exclude: ["node_modules", "dist", "build", ".git", ".next", ".nuxt", "coverage"],
|
|
688
|
-
configDir: ".trie",
|
|
689
|
-
outputDir: "trie-reports"
|
|
690
|
-
}
|
|
691
|
-
};
|
|
692
|
-
|
|
693
|
-
// src/config/loader.ts
|
|
694
|
-
async function loadConfig() {
|
|
695
|
-
const validator = new ConfigValidator();
|
|
696
|
-
const configPath = join4(getTrieDirectory(getWorkingDirectory(void 0, true)), "config.json");
|
|
697
|
-
try {
|
|
698
|
-
if (!existsSync4(configPath)) {
|
|
699
|
-
return DEFAULT_CONFIG;
|
|
700
|
-
}
|
|
701
|
-
const configFile = await readFile3(configPath, "utf-8");
|
|
702
|
-
const userConfig = JSON.parse(configFile);
|
|
703
|
-
const merged = mergeConfig(DEFAULT_CONFIG, userConfig);
|
|
704
|
-
const result = validator.validateConfig(merged);
|
|
705
|
-
if (!result.success) {
|
|
706
|
-
if (!isInteractiveMode()) {
|
|
707
|
-
console.error("Configuration validation failed:");
|
|
708
|
-
for (const error of result.errors) {
|
|
709
|
-
console.error(` - ${error}`);
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
return DEFAULT_CONFIG;
|
|
713
|
-
}
|
|
714
|
-
if (!isInteractiveMode()) {
|
|
715
|
-
const envValidation = validator.validateEnvironment();
|
|
716
|
-
for (const warning of envValidation.warnings) {
|
|
717
|
-
console.warn(warning);
|
|
718
|
-
}
|
|
719
|
-
for (const error of envValidation.errors) {
|
|
720
|
-
console.error(error);
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
return result.data;
|
|
724
|
-
} catch (error) {
|
|
725
|
-
if (!isInteractiveMode()) {
|
|
726
|
-
console.error("Failed to load config, using defaults:", error);
|
|
727
|
-
}
|
|
728
|
-
return DEFAULT_CONFIG;
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
async function saveConfig(config) {
|
|
732
|
-
const configPath = join4(getTrieDirectory(getWorkingDirectory(void 0, true)), "config.json");
|
|
733
|
-
const dir = dirname(configPath);
|
|
734
|
-
if (!existsSync4(dir)) {
|
|
735
|
-
await mkdir3(dir, { recursive: true });
|
|
736
|
-
}
|
|
737
|
-
await writeFile2(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
738
|
-
}
|
|
739
|
-
function mergeConfig(defaults, user) {
|
|
740
|
-
if (typeof user !== "object" || user === null || Array.isArray(user)) {
|
|
741
|
-
return { ...defaults };
|
|
742
|
-
}
|
|
743
|
-
const result = { ...defaults };
|
|
744
|
-
for (const [key, value] of Object.entries(user)) {
|
|
745
|
-
const defaultValue = defaults[key];
|
|
746
|
-
if (typeof value === "object" && value !== null && !Array.isArray(value) && typeof defaultValue === "object" && defaultValue !== null) {
|
|
747
|
-
result[key] = mergeConfig(defaultValue, value);
|
|
748
|
-
} else {
|
|
749
|
-
result[key] = value;
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
return result;
|
|
753
|
-
}
|
|
754
|
-
|
|
755
313
|
// src/bootstrap/stack-detector.ts
|
|
756
|
-
import { readFile as
|
|
757
|
-
import { existsSync as
|
|
758
|
-
import { join as
|
|
314
|
+
import { readFile as readFile3 } from "fs/promises";
|
|
315
|
+
import { existsSync as existsSync3 } from "fs";
|
|
316
|
+
import { join as join3 } from "path";
|
|
759
317
|
var SKILL_MAPPINGS = {
|
|
760
318
|
// Frontend Frameworks - React/Next.js
|
|
761
319
|
"next": [
|
|
@@ -1062,39 +620,39 @@ async function detectStack(projectDir) {
|
|
|
1062
620
|
suggestedAgents: ["security", "bugs"],
|
|
1063
621
|
dependencies: /* @__PURE__ */ new Set()
|
|
1064
622
|
};
|
|
1065
|
-
if (
|
|
623
|
+
if (existsSync3(join3(projectDir, "tsconfig.json"))) {
|
|
1066
624
|
stack.language = "TypeScript";
|
|
1067
625
|
stack.suggestedSkills.push("wshobson/agents typescript-advanced-types");
|
|
1068
|
-
} else if (
|
|
626
|
+
} else if (existsSync3(join3(projectDir, "package.json"))) {
|
|
1069
627
|
stack.language = "JavaScript";
|
|
1070
|
-
} else if (
|
|
628
|
+
} else if (existsSync3(join3(projectDir, "requirements.txt")) || existsSync3(join3(projectDir, "pyproject.toml"))) {
|
|
1071
629
|
stack.language = "Python";
|
|
1072
|
-
} else if (
|
|
630
|
+
} else if (existsSync3(join3(projectDir, "go.mod"))) {
|
|
1073
631
|
stack.language = "Go";
|
|
1074
|
-
} else if (
|
|
632
|
+
} else if (existsSync3(join3(projectDir, "Cargo.toml"))) {
|
|
1075
633
|
stack.language = "Rust";
|
|
1076
634
|
}
|
|
1077
|
-
if (
|
|
635
|
+
if (existsSync3(join3(projectDir, "Package.swift")) || existsSync3(join3(projectDir, "project.pbxproj")) || existsSync3(join3(projectDir, "*.xcodeproj"))) {
|
|
1078
636
|
stack.language = "Swift";
|
|
1079
637
|
stack.suggestedSkills.push("dimillian/skills swiftui-ui-patterns");
|
|
1080
638
|
stack.suggestedSkills.push("dimillian/skills swiftui-liquid-glass");
|
|
1081
639
|
}
|
|
1082
|
-
if (
|
|
640
|
+
if (existsSync3(join3(projectDir, "pnpm-lock.yaml"))) {
|
|
1083
641
|
stack.packageManager = "pnpm";
|
|
1084
|
-
} else if (
|
|
642
|
+
} else if (existsSync3(join3(projectDir, "yarn.lock"))) {
|
|
1085
643
|
stack.packageManager = "yarn";
|
|
1086
|
-
} else if (
|
|
644
|
+
} else if (existsSync3(join3(projectDir, "bun.lockb"))) {
|
|
1087
645
|
stack.packageManager = "bun";
|
|
1088
|
-
} else if (
|
|
646
|
+
} else if (existsSync3(join3(projectDir, "package-lock.json"))) {
|
|
1089
647
|
stack.packageManager = "npm";
|
|
1090
648
|
}
|
|
1091
|
-
if (
|
|
649
|
+
if (existsSync3(join3(projectDir, ".github", "workflows"))) {
|
|
1092
650
|
stack.suggestedSkills.push("wshobson/agents github-actions-templates");
|
|
1093
651
|
}
|
|
1094
652
|
try {
|
|
1095
|
-
const pkgPath =
|
|
1096
|
-
if (
|
|
1097
|
-
const pkgContent = await
|
|
653
|
+
const pkgPath = join3(projectDir, "package.json");
|
|
654
|
+
if (existsSync3(pkgPath)) {
|
|
655
|
+
const pkgContent = await readFile3(pkgPath, "utf-8");
|
|
1098
656
|
const pkg = JSON.parse(pkgContent);
|
|
1099
657
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
1100
658
|
for (const dep of Object.keys(deps)) {
|
|
@@ -1155,9 +713,9 @@ async function detectStack(projectDir) {
|
|
|
1155
713
|
} catch {
|
|
1156
714
|
}
|
|
1157
715
|
if (!stack.database) {
|
|
1158
|
-
if (
|
|
716
|
+
if (existsSync3(join3(projectDir, "prisma", "schema.prisma"))) {
|
|
1159
717
|
stack.database = "Prisma ORM";
|
|
1160
|
-
} else if (
|
|
718
|
+
} else if (existsSync3(join3(projectDir, "drizzle.config.ts"))) {
|
|
1161
719
|
stack.database = "Drizzle ORM";
|
|
1162
720
|
}
|
|
1163
721
|
}
|
|
@@ -1173,9 +731,9 @@ function getSkillCategories() {
|
|
|
1173
731
|
}
|
|
1174
732
|
|
|
1175
733
|
// src/bootstrap/files.ts
|
|
1176
|
-
import { readFile as
|
|
1177
|
-
import { existsSync as
|
|
1178
|
-
import { join as
|
|
734
|
+
import { readFile as readFile4, writeFile as writeFile2, unlink, mkdir as mkdir3 } from "fs/promises";
|
|
735
|
+
import { existsSync as existsSync4 } from "fs";
|
|
736
|
+
import { join as join4 } from "path";
|
|
1179
737
|
var BOOTSTRAP_FILES = [
|
|
1180
738
|
{ name: "PROJECT.md", type: "user", description: "Project overview and conventions" },
|
|
1181
739
|
{ name: "RULES.md", type: "user", description: "Coding standards agents enforce" },
|
|
@@ -1190,15 +748,15 @@ async function loadBootstrapContext(workDir) {
|
|
|
1190
748
|
const contentParts = [];
|
|
1191
749
|
let needsBootstrap2 = false;
|
|
1192
750
|
for (const file of BOOTSTRAP_FILES) {
|
|
1193
|
-
const filePath =
|
|
1194
|
-
const exists =
|
|
751
|
+
const filePath = join4(trieDir, file.name);
|
|
752
|
+
const exists = existsSync4(filePath);
|
|
1195
753
|
if (file.name === "BOOTSTRAP.md" && exists) {
|
|
1196
754
|
needsBootstrap2 = true;
|
|
1197
755
|
}
|
|
1198
756
|
let content;
|
|
1199
757
|
if (exists) {
|
|
1200
758
|
try {
|
|
1201
|
-
content = await
|
|
759
|
+
content = await readFile4(filePath, "utf-8");
|
|
1202
760
|
if (content.trim() && file.type !== "one-time") {
|
|
1203
761
|
contentParts.push(`<!-- ${file.name} -->
|
|
1204
762
|
${content}`);
|
|
@@ -1224,13 +782,13 @@ ${content}`);
|
|
|
1224
782
|
async function initializeBootstrapFiles(options = {}) {
|
|
1225
783
|
const projectDir = options.workDir || getWorkingDirectory(void 0, true);
|
|
1226
784
|
const trieDir = getTrieDirectory(projectDir);
|
|
1227
|
-
await
|
|
785
|
+
await mkdir3(trieDir, { recursive: true });
|
|
1228
786
|
const created = [];
|
|
1229
787
|
const skipped = [];
|
|
1230
788
|
const stack = await detectStack(projectDir);
|
|
1231
789
|
for (const file of BOOTSTRAP_FILES) {
|
|
1232
|
-
const filePath =
|
|
1233
|
-
const exists =
|
|
790
|
+
const filePath = join4(trieDir, file.name);
|
|
791
|
+
const exists = existsSync4(filePath);
|
|
1234
792
|
if (exists && !options.force) {
|
|
1235
793
|
skipped.push(file.name);
|
|
1236
794
|
continue;
|
|
@@ -1245,7 +803,7 @@ async function initializeBootstrapFiles(options = {}) {
|
|
|
1245
803
|
}
|
|
1246
804
|
const template = getFileTemplate(file.name, stack);
|
|
1247
805
|
if (template) {
|
|
1248
|
-
await
|
|
806
|
+
await writeFile2(filePath, template);
|
|
1249
807
|
created.push(file.name);
|
|
1250
808
|
}
|
|
1251
809
|
}
|
|
@@ -1253,7 +811,7 @@ async function initializeBootstrapFiles(options = {}) {
|
|
|
1253
811
|
}
|
|
1254
812
|
async function completeBootstrap(workDir) {
|
|
1255
813
|
const projectDir = workDir || getWorkingDirectory(void 0, true);
|
|
1256
|
-
const bootstrapPath =
|
|
814
|
+
const bootstrapPath = join4(getTrieDirectory(projectDir), "BOOTSTRAP.md");
|
|
1257
815
|
try {
|
|
1258
816
|
await unlink(bootstrapPath);
|
|
1259
817
|
return true;
|
|
@@ -1263,15 +821,15 @@ async function completeBootstrap(workDir) {
|
|
|
1263
821
|
}
|
|
1264
822
|
function needsBootstrap(workDir) {
|
|
1265
823
|
const projectDir = workDir || getWorkingDirectory(void 0, true);
|
|
1266
|
-
const bootstrapPath =
|
|
1267
|
-
return
|
|
824
|
+
const bootstrapPath = join4(getTrieDirectory(projectDir), "BOOTSTRAP.md");
|
|
825
|
+
return existsSync4(bootstrapPath);
|
|
1268
826
|
}
|
|
1269
827
|
async function loadRules(workDir) {
|
|
1270
828
|
const projectDir = workDir || getWorkingDirectory(void 0, true);
|
|
1271
|
-
const rulesPath =
|
|
829
|
+
const rulesPath = join4(getTrieDirectory(projectDir), "RULES.md");
|
|
1272
830
|
try {
|
|
1273
|
-
if (
|
|
1274
|
-
return await
|
|
831
|
+
if (existsSync4(rulesPath)) {
|
|
832
|
+
return await readFile4(rulesPath, "utf-8");
|
|
1275
833
|
}
|
|
1276
834
|
} catch {
|
|
1277
835
|
}
|
|
@@ -1279,10 +837,10 @@ async function loadRules(workDir) {
|
|
|
1279
837
|
}
|
|
1280
838
|
async function loadTeamInfo(workDir) {
|
|
1281
839
|
const projectDir = workDir || getWorkingDirectory(void 0, true);
|
|
1282
|
-
const teamPath =
|
|
840
|
+
const teamPath = join4(getTrieDirectory(projectDir), "TEAM.md");
|
|
1283
841
|
try {
|
|
1284
|
-
if (
|
|
1285
|
-
return await
|
|
842
|
+
if (existsSync4(teamPath)) {
|
|
843
|
+
return await readFile4(teamPath, "utf-8");
|
|
1286
844
|
}
|
|
1287
845
|
} catch {
|
|
1288
846
|
}
|
|
@@ -1413,129 +971,7 @@ function getBootstrapTemplate(stack) {
|
|
|
1413
971
|
return lines.join("\n");
|
|
1414
972
|
}
|
|
1415
973
|
|
|
1416
|
-
// src/ingest/linear-ingester.ts
|
|
1417
|
-
var LinearIngester = class {
|
|
1418
|
-
graph;
|
|
1419
|
-
constructor(_projectPath, graph) {
|
|
1420
|
-
this.graph = graph;
|
|
1421
|
-
}
|
|
1422
|
-
async syncTickets() {
|
|
1423
|
-
const apiKey = await this.getApiKey();
|
|
1424
|
-
if (!apiKey) {
|
|
1425
|
-
console.warn('Linear API key not found. Run "trie linear auth <key>" to enable ticket sync.');
|
|
1426
|
-
return;
|
|
1427
|
-
}
|
|
1428
|
-
const tickets = await this.fetchActiveTickets(apiKey);
|
|
1429
|
-
for (const ticket of tickets) {
|
|
1430
|
-
await this.ingestTicket(ticket);
|
|
1431
|
-
}
|
|
1432
|
-
}
|
|
1433
|
-
async getApiKey() {
|
|
1434
|
-
const config = await loadConfig();
|
|
1435
|
-
return config.apiKeys?.linear || process.env.LINEAR_API_KEY || null;
|
|
1436
|
-
}
|
|
1437
|
-
async fetchActiveTickets(apiKey) {
|
|
1438
|
-
const query = `
|
|
1439
|
-
query {
|
|
1440
|
-
issues(filter: { state: { type: { in: ["started", "unstarted"] } } }) {
|
|
1441
|
-
nodes {
|
|
1442
|
-
id
|
|
1443
|
-
identifier
|
|
1444
|
-
title
|
|
1445
|
-
description
|
|
1446
|
-
priority
|
|
1447
|
-
status {
|
|
1448
|
-
name
|
|
1449
|
-
}
|
|
1450
|
-
assignee {
|
|
1451
|
-
name
|
|
1452
|
-
}
|
|
1453
|
-
labels {
|
|
1454
|
-
nodes {
|
|
1455
|
-
name
|
|
1456
|
-
}
|
|
1457
|
-
}
|
|
1458
|
-
createdAt
|
|
1459
|
-
updatedAt
|
|
1460
|
-
}
|
|
1461
|
-
}
|
|
1462
|
-
}
|
|
1463
|
-
`;
|
|
1464
|
-
const response = await fetch("https://api.linear.app/graphql", {
|
|
1465
|
-
method: "POST",
|
|
1466
|
-
headers: {
|
|
1467
|
-
"Content-Type": "application/json",
|
|
1468
|
-
"Authorization": apiKey
|
|
1469
|
-
},
|
|
1470
|
-
body: JSON.stringify({ query })
|
|
1471
|
-
});
|
|
1472
|
-
if (!response.ok) {
|
|
1473
|
-
throw new Error(`Linear API error: ${response.statusText}`);
|
|
1474
|
-
}
|
|
1475
|
-
const data = await response.json();
|
|
1476
|
-
return data.data.issues.nodes;
|
|
1477
|
-
}
|
|
1478
|
-
async ingestTicket(ticket) {
|
|
1479
|
-
const labels = ticket.labels.nodes.map((l) => l.name);
|
|
1480
|
-
const intentVibe = this.extractIntentVibes(ticket.title, ticket.description, labels);
|
|
1481
|
-
const linkedFiles = this.extractLinkedFiles(ticket.description);
|
|
1482
|
-
const data = {
|
|
1483
|
-
ticketId: ticket.identifier,
|
|
1484
|
-
title: ticket.title,
|
|
1485
|
-
description: ticket.description || "",
|
|
1486
|
-
priority: this.mapPriority(ticket.priority),
|
|
1487
|
-
labels,
|
|
1488
|
-
intentVibe,
|
|
1489
|
-
linkedFiles,
|
|
1490
|
-
status: ticket.status.name,
|
|
1491
|
-
assignee: ticket.assignee?.name || null,
|
|
1492
|
-
createdAt: ticket.createdAt,
|
|
1493
|
-
updatedAt: ticket.updatedAt
|
|
1494
|
-
};
|
|
1495
|
-
await this.graph.addNode("linear-ticket", data);
|
|
1496
|
-
for (const file of linkedFiles) {
|
|
1497
|
-
const fileNode = await this.graph.getNode("file", file);
|
|
1498
|
-
if (fileNode) {
|
|
1499
|
-
await this.graph.addEdge(`linear:${ticket.identifier}`, fileNode.id, "relatedTo");
|
|
1500
|
-
}
|
|
1501
|
-
}
|
|
1502
|
-
}
|
|
1503
|
-
extractIntentVibes(title, description, labels) {
|
|
1504
|
-
const vibes = /* @__PURE__ */ new Set();
|
|
1505
|
-
const text = (title + " " + (description || "") + " " + labels.join(" ")).toLowerCase();
|
|
1506
|
-
if (text.includes("performance") || text.includes("slow") || text.includes("optimize")) vibes.add("performance");
|
|
1507
|
-
if (text.includes("security") || text.includes("auth") || text.includes("vulnerability")) vibes.add("security");
|
|
1508
|
-
if (text.includes("refactor") || text.includes("cleanup") || text.includes("debt")) vibes.add("refactor");
|
|
1509
|
-
if (text.includes("feature") || text.includes("new")) vibes.add("feature");
|
|
1510
|
-
if (text.includes("bug") || text.includes("fix") || text.includes("broken")) vibes.add("bug");
|
|
1511
|
-
if (text.includes("breaking") || text.includes("major change")) vibes.add("breaking-change");
|
|
1512
|
-
return Array.from(vibes);
|
|
1513
|
-
}
|
|
1514
|
-
extractLinkedFiles(description) {
|
|
1515
|
-
if (!description) return [];
|
|
1516
|
-
const matches = description.match(/[\\w./_-]+\\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs)/gi);
|
|
1517
|
-
if (!matches) return [];
|
|
1518
|
-
return Array.from(new Set(matches.map((m) => m.replace(/^\.\/+/, ""))));
|
|
1519
|
-
}
|
|
1520
|
-
mapPriority(priority) {
|
|
1521
|
-
switch (priority) {
|
|
1522
|
-
case 1:
|
|
1523
|
-
return "urgent";
|
|
1524
|
-
case 2:
|
|
1525
|
-
return "high";
|
|
1526
|
-
case 3:
|
|
1527
|
-
return "medium";
|
|
1528
|
-
case 4:
|
|
1529
|
-
return "low";
|
|
1530
|
-
default:
|
|
1531
|
-
return "none";
|
|
1532
|
-
}
|
|
1533
|
-
}
|
|
1534
|
-
};
|
|
1535
|
-
|
|
1536
974
|
export {
|
|
1537
|
-
loadConfig,
|
|
1538
|
-
saveConfig,
|
|
1539
975
|
projectInfoExists,
|
|
1540
976
|
loadProjectInfo,
|
|
1541
977
|
initProjectInfo,
|
|
@@ -1551,8 +987,7 @@ export {
|
|
|
1551
987
|
needsBootstrap,
|
|
1552
988
|
loadRules,
|
|
1553
989
|
loadTeamInfo,
|
|
1554
|
-
LinearIngester,
|
|
1555
990
|
loadContextState,
|
|
1556
991
|
getContextForAI
|
|
1557
992
|
};
|
|
1558
|
-
//# sourceMappingURL=chunk-
|
|
993
|
+
//# sourceMappingURL=chunk-7OJ6JIPL.js.map
|