@triedotdev/mcp 1.0.113 → 1.0.114

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 (75) hide show
  1. package/dist/auto-fix-apply-PCAHWLXF.js +10 -0
  2. package/dist/autonomy-config-O4H3Z7YV.js +30 -0
  3. package/dist/chunk-2GIAROBF.js +173 -0
  4. package/dist/chunk-2GIAROBF.js.map +1 -0
  5. package/dist/{chunk-33WL3D7A.js → chunk-2SIFK7OW.js} +7 -419
  6. package/dist/chunk-2SIFK7OW.js.map +1 -0
  7. package/dist/chunk-43X6JBEM.js +36 -0
  8. package/dist/chunk-43X6JBEM.js.map +1 -0
  9. package/dist/{chunk-2764KZZQ.js → chunk-4SBZXIMG.js} +133 -595
  10. package/dist/chunk-4SBZXIMG.js.map +1 -0
  11. package/dist/chunk-55DOQNHJ.js +772 -0
  12. package/dist/chunk-55DOQNHJ.js.map +1 -0
  13. package/dist/chunk-6LXSA2OZ.js +425 -0
  14. package/dist/chunk-6LXSA2OZ.js.map +1 -0
  15. package/dist/{chunk-SDS3UVFY.js → chunk-AOFYU6T3.js} +113 -559
  16. package/dist/chunk-AOFYU6T3.js.map +1 -0
  17. package/dist/{chunk-6QR6QZIX.js → chunk-D3EXBJE2.js} +25 -658
  18. package/dist/chunk-D3EXBJE2.js.map +1 -0
  19. package/dist/chunk-DJ2YAGHK.js +50 -0
  20. package/dist/chunk-DJ2YAGHK.js.map +1 -0
  21. package/dist/chunk-DRDEEF6G.js +328 -0
  22. package/dist/chunk-DRDEEF6G.js.map +1 -0
  23. package/dist/chunk-DZREHOGW.js +706 -0
  24. package/dist/chunk-DZREHOGW.js.map +1 -0
  25. package/dist/chunk-KRH642MT.js +947 -0
  26. package/dist/chunk-KRH642MT.js.map +1 -0
  27. package/dist/{chunk-QYOACM2C.js → chunk-MVNJPJBK.js} +22 -252
  28. package/dist/chunk-MVNJPJBK.js.map +1 -0
  29. package/dist/chunk-NS2MSZMB.js +394 -0
  30. package/dist/chunk-NS2MSZMB.js.map +1 -0
  31. package/dist/chunk-SWSK7ANT.js +340 -0
  32. package/dist/chunk-SWSK7ANT.js.map +1 -0
  33. package/dist/chunk-VRLMTOB6.js +566 -0
  34. package/dist/chunk-VRLMTOB6.js.map +1 -0
  35. package/dist/chunk-YR4BMGYO.js +130 -0
  36. package/dist/chunk-YR4BMGYO.js.map +1 -0
  37. package/dist/chunk-ZV2K6M7T.js +74 -0
  38. package/dist/chunk-ZV2K6M7T.js.map +1 -0
  39. package/dist/cli/main.js +107 -375
  40. package/dist/cli/main.js.map +1 -1
  41. package/dist/cli/yolo-daemon.js +18 -8
  42. package/dist/cli/yolo-daemon.js.map +1 -1
  43. package/dist/client-7XZHCMD3.js +28 -0
  44. package/dist/client-7XZHCMD3.js.map +1 -0
  45. package/dist/{goal-manager-AP4LTE6U.js → goal-manager-LMS6ZJB7.js} +7 -3
  46. package/dist/goal-manager-LMS6ZJB7.js.map +1 -0
  47. package/dist/goal-validator-7UPLOVAZ.js +184 -0
  48. package/dist/goal-validator-7UPLOVAZ.js.map +1 -0
  49. package/dist/graph-U5JWSAB5.js +10 -0
  50. package/dist/graph-U5JWSAB5.js.map +1 -0
  51. package/dist/guardian-agent-EXP7APLC.js +25 -0
  52. package/dist/guardian-agent-EXP7APLC.js.map +1 -0
  53. package/dist/hypothesis-KGC3P54C.js +19 -0
  54. package/dist/hypothesis-KGC3P54C.js.map +1 -0
  55. package/dist/incident-index-PNIVT47T.js +11 -0
  56. package/dist/incident-index-PNIVT47T.js.map +1 -0
  57. package/dist/index.js +285 -16
  58. package/dist/index.js.map +1 -1
  59. package/dist/ledger-SR6OEBLO.js +15 -0
  60. package/dist/ledger-SR6OEBLO.js.map +1 -0
  61. package/dist/output-manager-BOTMXSND.js +13 -0
  62. package/dist/output-manager-BOTMXSND.js.map +1 -0
  63. package/dist/pattern-discovery-F7LU5K6E.js +8 -0
  64. package/dist/pattern-discovery-F7LU5K6E.js.map +1 -0
  65. package/package.json +1 -1
  66. package/dist/chunk-2764KZZQ.js.map +0 -1
  67. package/dist/chunk-33WL3D7A.js.map +0 -1
  68. package/dist/chunk-6JPPYG7F.js +0 -1813
  69. package/dist/chunk-6JPPYG7F.js.map +0 -1
  70. package/dist/chunk-6QR6QZIX.js.map +0 -1
  71. package/dist/chunk-QYOACM2C.js.map +0 -1
  72. package/dist/chunk-SDS3UVFY.js.map +0 -1
  73. package/dist/guardian-agent-XEYNG7RH.js +0 -18
  74. /package/dist/{goal-manager-AP4LTE6U.js.map → auto-fix-apply-PCAHWLXF.js.map} +0 -0
  75. /package/dist/{guardian-agent-XEYNG7RH.js.map → autonomy-config-O4H3Z7YV.js.map} +0 -0
@@ -1,20 +1,26 @@
1
1
  import {
2
- scanForVibeCodeIssues
3
- } from "./chunk-IXO4G4D3.js";
2
+ tryGetClient
3
+ } from "./chunk-SWSK7ANT.js";
4
4
  import {
5
- BackupManager,
6
- GlobalPatternsIndexSchema,
7
- atomicWriteJSON,
8
- safeParseAndValidate,
9
5
  searchIssues
10
- } from "./chunk-6JPPYG7F.js";
6
+ } from "./chunk-55DOQNHJ.js";
11
7
  import {
12
- getTrieDirectory,
13
- getWorkingDirectory
14
- } from "./chunk-R4AAPFXC.js";
8
+ BackupManager,
9
+ GlobalPatternsIndexSchema,
10
+ safeParseAndValidate
11
+ } from "./chunk-KRH642MT.js";
15
12
  import {
16
13
  scanForVulnerabilities
17
14
  } from "./chunk-F4NJ4CBP.js";
15
+ import {
16
+ scanForVibeCodeIssues
17
+ } from "./chunk-IXO4G4D3.js";
18
+ import {
19
+ atomicWriteJSON
20
+ } from "./chunk-43X6JBEM.js";
21
+ import {
22
+ getTrieDirectory
23
+ } from "./chunk-R4AAPFXC.js";
18
24
 
19
25
  // src/memory/global-memory.ts
20
26
  import { mkdir, writeFile, readFile, readdir } from "fs/promises";
@@ -266,256 +272,9 @@ function sanitizeName(name) {
266
272
  return name.replace(/[^a-zA-Z0-9-_]/g, "-").toLowerCase();
267
273
  }
268
274
 
269
- // src/ai/client.ts
270
- import Anthropic from "@anthropic-ai/sdk";
271
- import { readFileSync, writeFileSync, mkdirSync, existsSync as existsSync2 } from "fs";
272
- import { execSync } from "child_process";
273
- import { join as join2 } from "path";
274
- var clientInstance = null;
275
- var apiKeyChecked = false;
276
- var apiKeyAvailable = false;
277
- function isAIAvailable() {
278
- if (!apiKeyChecked) {
279
- checkAPIKey();
280
- }
281
- return apiKeyAvailable;
282
- }
283
- function getKeyFromKeychain() {
284
- if (process.platform !== "darwin") return null;
285
- try {
286
- const result = execSync(
287
- 'security find-generic-password -a "trie" -s "anthropic-api-key" -w 2>/dev/null',
288
- { encoding: "utf-8" }
289
- ).trim();
290
- return result.length > 10 ? result : null;
291
- } catch {
292
- return null;
293
- }
294
- }
295
- function saveKeyToKeychain(key) {
296
- if (process.platform !== "darwin") return false;
297
- try {
298
- try {
299
- execSync('security delete-generic-password -a "trie" -s "anthropic-api-key" 2>/dev/null');
300
- } catch {
301
- }
302
- execSync(`security add-generic-password -a "trie" -s "anthropic-api-key" -w "${key.replace(/"/g, '\\"')}"`);
303
- return true;
304
- } catch {
305
- return false;
306
- }
307
- }
308
- function setAPIKey(key) {
309
- process.env.ANTHROPIC_API_KEY = key;
310
- clientInstance = null;
311
- apiKeyChecked = true;
312
- apiKeyAvailable = true;
313
- if (saveKeyToKeychain(key)) {
314
- return { saved: true, method: "keychain" };
315
- }
316
- try {
317
- const workDir = getWorkingDirectory(void 0, true);
318
- const trieDir = getTrieDirectory(workDir);
319
- const configPath = join2(trieDir, "config.json");
320
- let config = {};
321
- if (existsSync2(configPath)) {
322
- config = JSON.parse(readFileSync(configPath, "utf-8"));
323
- }
324
- if (!config.apiKeys || typeof config.apiKeys !== "object") config.apiKeys = {};
325
- config.apiKeys.anthropic = key;
326
- mkdirSync(trieDir, { recursive: true });
327
- writeFileSync(configPath, JSON.stringify(config, null, 2));
328
- } catch {
329
- }
330
- return { saved: true, method: "config" };
331
- }
332
- function checkAPIKey() {
333
- apiKeyChecked = true;
334
- const envApiKey = process.env.ANTHROPIC_API_KEY;
335
- if (envApiKey && envApiKey.length > 10) {
336
- apiKeyAvailable = true;
337
- return;
338
- }
339
- const keychainKey = getKeyFromKeychain();
340
- if (keychainKey) {
341
- process.env.ANTHROPIC_API_KEY = keychainKey;
342
- apiKeyAvailable = true;
343
- return;
344
- }
345
- try {
346
- const workDir = getWorkingDirectory(void 0, true);
347
- const configPath = join2(getTrieDirectory(workDir), "config.json");
348
- if (existsSync2(configPath)) {
349
- const configContent = readFileSync(configPath, "utf-8");
350
- const config = JSON.parse(configContent);
351
- if (config.apiKeys?.anthropic && config.apiKeys.anthropic.length > 10) {
352
- process.env.ANTHROPIC_API_KEY = config.apiKeys.anthropic;
353
- apiKeyAvailable = true;
354
- return;
355
- }
356
- }
357
- } catch {
358
- }
359
- try {
360
- const workDir = getWorkingDirectory(void 0, true);
361
- const envFiles = [".env", ".env.local", ".env.production"];
362
- for (const envFile of envFiles) {
363
- const envPath = join2(workDir, envFile);
364
- if (existsSync2(envPath)) {
365
- const envContent = readFileSync(envPath, "utf-8");
366
- const lines = envContent.split("\n");
367
- for (const line of lines) {
368
- const match = line.match(/^\s*ANTHROPIC_API_KEY\s*=\s*(.+)$/);
369
- if (match && match[1]) {
370
- const key = match[1].trim().replace(/^["']|["']$/g, "");
371
- if (key.length > 10) {
372
- process.env.ANTHROPIC_API_KEY = key;
373
- apiKeyAvailable = true;
374
- return;
375
- }
376
- }
377
- }
378
- }
379
- }
380
- } catch {
381
- }
382
- apiKeyAvailable = false;
383
- }
384
- function tryGetClient() {
385
- if (!isAIAvailable()) {
386
- return null;
387
- }
388
- if (!clientInstance) {
389
- clientInstance = new Anthropic();
390
- }
391
- return clientInstance;
392
- }
393
- async function runAIAnalysis(request) {
394
- const client = tryGetClient();
395
- if (!client) {
396
- return {
397
- success: false,
398
- content: "",
399
- error: "AI not available - ANTHROPIC_API_KEY not set"
400
- };
401
- }
402
- try {
403
- const response = await client.messages.create({
404
- model: "claude-sonnet-4-20250514",
405
- max_tokens: request.maxTokens || 4096,
406
- temperature: request.temperature ?? 0.3,
407
- system: request.systemPrompt,
408
- messages: [
409
- {
410
- role: "user",
411
- content: request.userPrompt
412
- }
413
- ]
414
- });
415
- const textContent = response.content.filter((block) => block.type === "text").map((block) => block.text).join("\n");
416
- return {
417
- success: true,
418
- content: textContent,
419
- tokensUsed: {
420
- input: response.usage.input_tokens,
421
- output: response.usage.output_tokens
422
- }
423
- };
424
- } catch (error) {
425
- const errorMessage = error instanceof Error ? error.message : String(error);
426
- if (errorMessage.includes("authentication") || errorMessage.includes("API key")) {
427
- return {
428
- success: false,
429
- content: "",
430
- error: "Invalid API key. Check your ANTHROPIC_API_KEY."
431
- };
432
- }
433
- if (errorMessage.includes("rate limit")) {
434
- return {
435
- success: false,
436
- content: "",
437
- error: "Rate limited. Try again in a moment."
438
- };
439
- }
440
- return {
441
- success: false,
442
- content: "",
443
- error: `AI analysis failed: ${errorMessage}`
444
- };
445
- }
446
- }
447
- async function runAIWithTools(request) {
448
- const client = tryGetClient();
449
- if (!client) {
450
- return { success: false, content: "", error: "AI not available - ANTHROPIC_API_KEY not set" };
451
- }
452
- const maxRounds = request.maxToolRounds ?? 5;
453
- const messages = [...request.messages];
454
- const allToolCalls = [];
455
- try {
456
- for (let round = 0; round < maxRounds; round++) {
457
- const response = await client.messages.create({
458
- model: "claude-sonnet-4-20250514",
459
- max_tokens: request.maxTokens || 4096,
460
- temperature: 0.3,
461
- system: request.systemPrompt,
462
- messages,
463
- tools: request.tools
464
- });
465
- const toolUseBlocks = response.content.filter(
466
- (b) => b.type === "tool_use"
467
- );
468
- const textBlocks = response.content.filter(
469
- (b) => b.type === "text"
470
- );
471
- if (toolUseBlocks.length === 0) {
472
- const result2 = {
473
- success: true,
474
- content: textBlocks.map((b) => b.text).join("\n")
475
- };
476
- if (allToolCalls.length > 0) result2.toolCalls = allToolCalls;
477
- return result2;
478
- }
479
- messages.push({ role: "assistant", content: response.content });
480
- const toolResults = [];
481
- for (const block of toolUseBlocks) {
482
- const input = block.input ?? {};
483
- allToolCalls.push({ name: block.name, input });
484
- let resultText;
485
- let isError = false;
486
- try {
487
- resultText = await request.executeTool(block.name, input);
488
- } catch (err) {
489
- resultText = `Tool error: ${err instanceof Error ? err.message : String(err)}`;
490
- isError = true;
491
- }
492
- toolResults.push({
493
- type: "tool_result",
494
- tool_use_id: block.id,
495
- content: resultText,
496
- is_error: isError
497
- });
498
- }
499
- messages.push({ role: "user", content: toolResults });
500
- if (response.stop_reason === "end_turn") {
501
- const text = textBlocks.map((b) => b.text).join("\n");
502
- const result2 = { success: true, content: text || "Done." };
503
- if (allToolCalls.length > 0) result2.toolCalls = allToolCalls;
504
- return result2;
505
- }
506
- }
507
- const result = { success: true, content: "Reached maximum tool rounds." };
508
- if (allToolCalls.length > 0) result.toolCalls = allToolCalls;
509
- return result;
510
- } catch (error) {
511
- const errorMessage = error instanceof Error ? error.message : String(error);
512
- return { success: false, content: "", error: `AI tool-use failed: ${errorMessage}` };
513
- }
514
- }
515
-
516
275
  // src/storage/tiered-storage.ts
517
276
  import { writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
518
- import { join as join3 } from "path";
277
+ import { join as join2 } from "path";
519
278
  import { createHash as createHash2 } from "crypto";
520
279
  import Database from "better-sqlite3";
521
280
  var TieredStorage = class {
@@ -530,10 +289,10 @@ var TieredStorage = class {
530
289
  */
531
290
  async initialize() {
532
291
  const trieDir = getTrieDirectory(this.workDir);
533
- await mkdir2(join3(trieDir, "hot"), { recursive: true });
534
- await mkdir2(join3(trieDir, "warm"), { recursive: true });
535
- await mkdir2(join3(trieDir, "cold"), { recursive: true });
536
- const dbPath = join3(trieDir, "warm", "decisions.db");
292
+ await mkdir2(join2(trieDir, "hot"), { recursive: true });
293
+ await mkdir2(join2(trieDir, "warm"), { recursive: true });
294
+ await mkdir2(join2(trieDir, "cold"), { recursive: true });
295
+ const dbPath = join2(trieDir, "warm", "decisions.db");
537
296
  this.warmDb = new Database(dbPath);
538
297
  this.warmDb.exec(`
539
298
  CREATE TABLE IF NOT EXISTS decisions (
@@ -815,8 +574,8 @@ var TieredStorage = class {
815
574
  const cutoffDate = /* @__PURE__ */ new Date();
816
575
  cutoffDate.setDate(cutoffDate.getDate() - olderThanDays);
817
576
  const cutoff = cutoffDate.toISOString();
818
- const coldDir = join3(getTrieDirectory(this.workDir), "cold");
819
- const archivePath = join3(coldDir, `archive-${Date.now()}.json`);
577
+ const coldDir = join2(getTrieDirectory(this.workDir), "cold");
578
+ const archivePath = join2(coldDir, `archive-${Date.now()}.json`);
820
579
  const decisions = this.warmDb.prepare("SELECT * FROM decisions WHERE timestamp < ? AND accessCount < 3").all(cutoff);
821
580
  const facts = this.warmDb.prepare("SELECT * FROM facts WHERE timestamp < ? AND accessCount < 3").all(cutoff);
822
581
  const blockers = this.warmDb.prepare("SELECT * FROM blockers WHERE timestamp < ? AND resolvedAt IS NOT NULL").all(cutoff);
@@ -1031,392 +790,6 @@ var GotchaPredictor = class {
1031
790
  }
1032
791
  };
1033
792
 
1034
- // src/context/graph.ts
1035
- import crypto from "crypto";
1036
- import path3 from "path";
1037
-
1038
- // src/context/store.ts
1039
- import Database2 from "better-sqlite3";
1040
- import fs2 from "fs";
1041
- import path2 from "path";
1042
- var ContextStore = class {
1043
- db;
1044
- dbFilePath;
1045
- constructor(projectPath, dbFilePath) {
1046
- this.dbFilePath = dbFilePath ?? path2.join(getTrieDirectory(projectPath), "context.db");
1047
- this.ensureDirectory();
1048
- this.db = new Database2(this.dbFilePath);
1049
- this.configure();
1050
- this.prepareSchema();
1051
- }
1052
- get databasePath() {
1053
- return this.dbFilePath;
1054
- }
1055
- addNode(node) {
1056
- const stmt = this.db.prepare(
1057
- `INSERT INTO nodes (id, type, data, created_at, updated_at)
1058
- VALUES (@id, @type, @data, @created_at, @updated_at)`
1059
- );
1060
- stmt.run({
1061
- id: node.id,
1062
- type: node.type,
1063
- data: JSON.stringify(node.data),
1064
- created_at: node.created_at,
1065
- updated_at: node.updated_at
1066
- });
1067
- return node;
1068
- }
1069
- upsertNode(node) {
1070
- const stmt = this.db.prepare(
1071
- `INSERT INTO nodes (id, type, data, created_at, updated_at)
1072
- VALUES (@id, @type, @data, @created_at, @updated_at)
1073
- ON CONFLICT(id) DO UPDATE SET
1074
- type=excluded.type,
1075
- data=excluded.data,
1076
- updated_at=excluded.updated_at`
1077
- );
1078
- stmt.run({
1079
- id: node.id,
1080
- type: node.type,
1081
- data: JSON.stringify(node.data),
1082
- created_at: node.created_at,
1083
- updated_at: node.updated_at
1084
- });
1085
- return node;
1086
- }
1087
- getNode(id) {
1088
- const row = this.db.prepare("SELECT * FROM nodes WHERE id = ?").get(id);
1089
- return row ? this.mapNodeRow(row) : null;
1090
- }
1091
- getNodeByType(type, id) {
1092
- const row = this.db.prepare("SELECT * FROM nodes WHERE id = ? AND type = ?").get(id, type);
1093
- return row ? this.mapNodeRow(row) : null;
1094
- }
1095
- updateNode(id, updates, updatedAt) {
1096
- const existing = this.getNode(id);
1097
- if (!existing) {
1098
- return null;
1099
- }
1100
- const merged = {
1101
- ...existing,
1102
- data: { ...existing.data, ...updates },
1103
- updated_at: updatedAt
1104
- };
1105
- this.db.prepare(
1106
- `UPDATE nodes SET data = @data, updated_at = @updated_at
1107
- WHERE id = @id`
1108
- ).run({
1109
- id,
1110
- data: JSON.stringify(merged.data),
1111
- updated_at: merged.updated_at
1112
- });
1113
- return merged;
1114
- }
1115
- deleteNode(id) {
1116
- const deleteEdges = this.db.prepare("DELETE FROM edges WHERE from_id = ? OR to_id = ?");
1117
- const deleteNodeStmt = this.db.prepare("DELETE FROM nodes WHERE id = ?");
1118
- const transaction = this.db.transaction((nodeId) => {
1119
- deleteEdges.run(nodeId, nodeId);
1120
- deleteNodeStmt.run(nodeId);
1121
- });
1122
- transaction(id);
1123
- }
1124
- listNodes() {
1125
- const rows = this.db.prepare("SELECT * FROM nodes").all();
1126
- return rows.map((row) => this.mapNodeRow(row));
1127
- }
1128
- findNodesByType(type) {
1129
- const rows = this.db.prepare("SELECT * FROM nodes WHERE type = ?").all(type);
1130
- return rows.map((row) => this.mapNodeRow(row));
1131
- }
1132
- addEdge(edge) {
1133
- const stmt = this.db.prepare(
1134
- `INSERT INTO edges (id, from_id, to_id, type, weight, metadata, created_at)
1135
- VALUES (@id, @from_id, @to_id, @type, @weight, @metadata, @created_at)`
1136
- );
1137
- stmt.run({
1138
- id: edge.id,
1139
- from_id: edge.from_id,
1140
- to_id: edge.to_id,
1141
- type: edge.type,
1142
- weight: edge.weight,
1143
- metadata: JSON.stringify(edge.metadata ?? {}),
1144
- created_at: edge.created_at
1145
- });
1146
- return edge;
1147
- }
1148
- upsertEdge(edge) {
1149
- const stmt = this.db.prepare(
1150
- `INSERT INTO edges (id, from_id, to_id, type, weight, metadata, created_at)
1151
- VALUES (@id, @from_id, @to_id, @type, @weight, @metadata, @created_at)
1152
- ON CONFLICT(id) DO UPDATE SET
1153
- from_id=excluded.from_id,
1154
- to_id=excluded.to_id,
1155
- type=excluded.type,
1156
- weight=excluded.weight,
1157
- metadata=excluded.metadata`
1158
- );
1159
- stmt.run({
1160
- id: edge.id,
1161
- from_id: edge.from_id,
1162
- to_id: edge.to_id,
1163
- type: edge.type,
1164
- weight: edge.weight,
1165
- metadata: JSON.stringify(edge.metadata ?? {}),
1166
- created_at: edge.created_at
1167
- });
1168
- return edge;
1169
- }
1170
- getEdge(id) {
1171
- const row = this.db.prepare("SELECT * FROM edges WHERE id = ?").get(id);
1172
- return row ? this.mapEdgeRow(row) : null;
1173
- }
1174
- getEdges(nodeId, direction = "both") {
1175
- let rows;
1176
- if (direction === "in") {
1177
- rows = this.db.prepare("SELECT * FROM edges WHERE to_id = ?").all(nodeId);
1178
- } else if (direction === "out") {
1179
- rows = this.db.prepare("SELECT * FROM edges WHERE from_id = ?").all(nodeId);
1180
- } else {
1181
- rows = this.db.prepare("SELECT * FROM edges WHERE from_id = ? OR to_id = ?").all(nodeId, nodeId);
1182
- }
1183
- return rows.map((row) => this.mapEdgeRow(row));
1184
- }
1185
- listEdges() {
1186
- const rows = this.db.prepare("SELECT * FROM edges").all();
1187
- return rows.map((row) => this.mapEdgeRow(row));
1188
- }
1189
- deleteEdge(id) {
1190
- this.db.prepare("DELETE FROM edges WHERE id = ?").run(id);
1191
- }
1192
- close() {
1193
- this.db.close();
1194
- }
1195
- ensureDirectory() {
1196
- fs2.mkdirSync(path2.dirname(this.dbFilePath), { recursive: true });
1197
- }
1198
- configure() {
1199
- this.db.pragma("journal_mode = WAL");
1200
- this.db.pragma("busy_timeout = 5000");
1201
- this.db.pragma("synchronous = NORMAL");
1202
- }
1203
- prepareSchema() {
1204
- this.db.exec(`
1205
- CREATE TABLE IF NOT EXISTS nodes (
1206
- id TEXT PRIMARY KEY,
1207
- type TEXT NOT NULL,
1208
- data TEXT NOT NULL,
1209
- created_at TEXT NOT NULL,
1210
- updated_at TEXT NOT NULL
1211
- );
1212
-
1213
- CREATE TABLE IF NOT EXISTS edges (
1214
- id TEXT PRIMARY KEY,
1215
- from_id TEXT NOT NULL,
1216
- to_id TEXT NOT NULL,
1217
- type TEXT NOT NULL,
1218
- weight REAL NOT NULL DEFAULT 1,
1219
- metadata TEXT DEFAULT '{}',
1220
- created_at TEXT NOT NULL
1221
- );
1222
-
1223
- CREATE INDEX IF NOT EXISTS idx_nodes_type ON nodes(type);
1224
- CREATE INDEX IF NOT EXISTS idx_edges_from ON edges(from_id);
1225
- CREATE INDEX IF NOT EXISTS idx_edges_to ON edges(to_id);
1226
- CREATE INDEX IF NOT EXISTS idx_edges_type ON edges(type);
1227
- `);
1228
- }
1229
- mapNodeRow(row) {
1230
- return {
1231
- id: row.id,
1232
- type: row.type,
1233
- data: JSON.parse(row.data),
1234
- created_at: row.created_at,
1235
- updated_at: row.updated_at
1236
- };
1237
- }
1238
- mapEdgeRow(row) {
1239
- return {
1240
- id: row.id,
1241
- from_id: row.from_id,
1242
- to_id: row.to_id,
1243
- type: row.type,
1244
- weight: row.weight,
1245
- created_at: row.created_at,
1246
- metadata: row.metadata ? JSON.parse(row.metadata) : {}
1247
- };
1248
- }
1249
- };
1250
-
1251
- // src/context/graph.ts
1252
- var ContextGraph = class {
1253
- store;
1254
- projectPath;
1255
- constructor(projectPath, dbPath, store) {
1256
- this.projectPath = projectPath;
1257
- this.store = store ?? new ContextStore(projectPath, dbPath);
1258
- }
1259
- get projectRoot() {
1260
- return this.projectPath;
1261
- }
1262
- async addNode(type, data) {
1263
- const now = (/* @__PURE__ */ new Date()).toISOString();
1264
- const id = this.generateNodeId(type, data);
1265
- const node = {
1266
- id,
1267
- type,
1268
- data,
1269
- created_at: now,
1270
- updated_at: now
1271
- };
1272
- this.store.addNode(node);
1273
- return node;
1274
- }
1275
- async getNode(type, id) {
1276
- return this.store.getNodeByType(type, id);
1277
- }
1278
- async updateNode(type, id, updates) {
1279
- const updated = this.store.updateNode(id, updates, (/* @__PURE__ */ new Date()).toISOString());
1280
- if (updated && updated.type !== type) {
1281
- throw new Error(`Type mismatch for node ${id}: expected ${type} but found ${updated.type}`);
1282
- }
1283
- }
1284
- async deleteNode(_type, id) {
1285
- this.store.deleteNode(id);
1286
- }
1287
- async addEdge(fromId, toId, type, metadata = {}, weight = 1) {
1288
- const edge = {
1289
- id: crypto.randomUUID(),
1290
- from_id: fromId,
1291
- to_id: toId,
1292
- type,
1293
- weight,
1294
- metadata,
1295
- created_at: (/* @__PURE__ */ new Date()).toISOString()
1296
- };
1297
- this.store.addEdge(edge);
1298
- return edge;
1299
- }
1300
- async getEdges(nodeId, direction = "both") {
1301
- return this.store.getEdges(nodeId, direction);
1302
- }
1303
- async getIncidentsForFile(filePath) {
1304
- const fileNode = this.findFileNode(filePath);
1305
- if (!fileNode) return [];
1306
- const incidents = /* @__PURE__ */ new Map();
1307
- const affectEdges = this.store.getEdges(fileNode.id, "in").filter((edge) => edge.type === "affects");
1308
- for (const edge of affectEdges) {
1309
- const changeId = edge.from_id;
1310
- const leadEdges = this.store.getEdges(changeId, "out").filter((e) => e.type === "leadTo");
1311
- const causedByEdges = this.store.getEdges(changeId, "in").filter((e) => e.type === "causedBy");
1312
- for (const le of leadEdges) {
1313
- const incident = this.store.getNodeByType("incident", le.to_id);
1314
- if (incident) incidents.set(incident.id, incident);
1315
- }
1316
- for (const ce of causedByEdges) {
1317
- const incident = this.store.getNodeByType("incident", ce.from_id);
1318
- if (incident) incidents.set(incident.id, incident);
1319
- }
1320
- }
1321
- return Array.from(incidents.values());
1322
- }
1323
- async getPatternsForFile(filePath) {
1324
- const normalized = this.normalizePath(filePath);
1325
- const nodes = this.store.findNodesByType("pattern");
1326
- return nodes.filter(
1327
- (node) => node.data.appliesTo.some((pattern) => normalized.includes(pattern) || filePath.includes(pattern))
1328
- );
1329
- }
1330
- async getRecentChanges(limit) {
1331
- const nodes = this.store.findNodesByType("change");
1332
- return nodes.sort((a, b) => new Date(b.data.timestamp).getTime() - new Date(a.data.timestamp).getTime()).slice(0, limit);
1333
- }
1334
- async calculateFileRisk(filePath) {
1335
- const fileNode = this.findFileNode(filePath);
1336
- if (!fileNode) return "low";
1337
- const incidentScore = Math.min(fileNode.data.incidentCount * 2, 6);
1338
- const changeScore = Math.min(fileNode.data.changeCount, 4);
1339
- const baseScore = this.riskLevelToScore(fileNode.data.riskLevel);
1340
- const total = baseScore + incidentScore + changeScore;
1341
- if (total >= 10) return "critical";
1342
- if (total >= 7) return "high";
1343
- if (total >= 4) return "medium";
1344
- return "low";
1345
- }
1346
- async listNodes() {
1347
- return this.store.listNodes();
1348
- }
1349
- async listEdges() {
1350
- return this.store.listEdges();
1351
- }
1352
- async deleteEdge(id) {
1353
- this.store.deleteEdge(id);
1354
- }
1355
- async getSnapshot() {
1356
- return {
1357
- nodes: this.store.listNodes(),
1358
- edges: this.store.listEdges(),
1359
- exported_at: (/* @__PURE__ */ new Date()).toISOString()
1360
- };
1361
- }
1362
- async applySnapshot(snapshot) {
1363
- for (const node of snapshot.nodes) {
1364
- const existing = this.store.getNode(node.id);
1365
- if (!existing || this.isNewer(node.updated_at, existing.updated_at)) {
1366
- this.store.upsertNode(node);
1367
- }
1368
- }
1369
- for (const edge of snapshot.edges) {
1370
- const existing = this.store.getEdge(edge.id);
1371
- if (!existing) {
1372
- this.store.upsertEdge(edge);
1373
- }
1374
- }
1375
- }
1376
- generateNodeId(type, data) {
1377
- if (type === "file") {
1378
- const fileData = data;
1379
- return this.normalizePath(fileData.path);
1380
- }
1381
- if (type === "change") {
1382
- const changeData = data;
1383
- if (changeData.commitHash) {
1384
- return changeData.commitHash;
1385
- }
1386
- }
1387
- if (type === "linear-ticket") {
1388
- const ticketData = data;
1389
- return `linear:${ticketData.ticketId}`;
1390
- }
1391
- return crypto.randomUUID();
1392
- }
1393
- findFileNode(filePath) {
1394
- const normalized = this.normalizePath(filePath);
1395
- const nodes = this.store.findNodesByType("file");
1396
- return nodes.find(
1397
- (node) => node.id === normalized || this.normalizePath(node.data.path) === normalized || node.data.path === filePath
1398
- ) ?? null;
1399
- }
1400
- normalizePath(filePath) {
1401
- return path3.resolve(this.projectPath, filePath);
1402
- }
1403
- riskLevelToScore(level) {
1404
- switch (level) {
1405
- case "critical":
1406
- return 6;
1407
- case "high":
1408
- return 4;
1409
- case "medium":
1410
- return 2;
1411
- default:
1412
- return 0;
1413
- }
1414
- }
1415
- isNewer(incoming, existing) {
1416
- return new Date(incoming).getTime() >= new Date(existing).getTime();
1417
- }
1418
- };
1419
-
1420
793
  export {
1421
794
  recordToGlobalMemory,
1422
795
  findCrossProjectPatterns,
@@ -1424,14 +797,8 @@ export {
1424
797
  getGlobalMemoryStats,
1425
798
  updateGlobalMemoryMd,
1426
799
  searchGlobalPatterns,
1427
- isAIAvailable,
1428
- getKeyFromKeychain,
1429
- setAPIKey,
1430
- runAIAnalysis,
1431
- runAIWithTools,
1432
800
  TieredStorage,
1433
801
  getStorage,
1434
- GotchaPredictor,
1435
- ContextGraph
802
+ GotchaPredictor
1436
803
  };
1437
- //# sourceMappingURL=chunk-6QR6QZIX.js.map
804
+ //# sourceMappingURL=chunk-D3EXBJE2.js.map