gnosys 4.0.0

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 (188) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1387 -0
  3. package/dist/cli.d.ts +7 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +3753 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/index.d.ts +8 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +2267 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/lib/archive.d.ts +95 -0
  12. package/dist/lib/archive.d.ts.map +1 -0
  13. package/dist/lib/archive.js +311 -0
  14. package/dist/lib/archive.js.map +1 -0
  15. package/dist/lib/ask.d.ts +77 -0
  16. package/dist/lib/ask.d.ts.map +1 -0
  17. package/dist/lib/ask.js +316 -0
  18. package/dist/lib/ask.js.map +1 -0
  19. package/dist/lib/audit.d.ts +47 -0
  20. package/dist/lib/audit.d.ts.map +1 -0
  21. package/dist/lib/audit.js +136 -0
  22. package/dist/lib/audit.js.map +1 -0
  23. package/dist/lib/bootstrap.d.ts +56 -0
  24. package/dist/lib/bootstrap.d.ts.map +1 -0
  25. package/dist/lib/bootstrap.js +163 -0
  26. package/dist/lib/bootstrap.js.map +1 -0
  27. package/dist/lib/config.d.ts +239 -0
  28. package/dist/lib/config.d.ts.map +1 -0
  29. package/dist/lib/config.js +371 -0
  30. package/dist/lib/config.js.map +1 -0
  31. package/dist/lib/dashboard.d.ts +81 -0
  32. package/dist/lib/dashboard.d.ts.map +1 -0
  33. package/dist/lib/dashboard.js +314 -0
  34. package/dist/lib/dashboard.js.map +1 -0
  35. package/dist/lib/db.d.ts +182 -0
  36. package/dist/lib/db.d.ts.map +1 -0
  37. package/dist/lib/db.js +620 -0
  38. package/dist/lib/db.js.map +1 -0
  39. package/dist/lib/dbSearch.d.ts +65 -0
  40. package/dist/lib/dbSearch.d.ts.map +1 -0
  41. package/dist/lib/dbSearch.js +239 -0
  42. package/dist/lib/dbSearch.js.map +1 -0
  43. package/dist/lib/dbWrite.d.ts +56 -0
  44. package/dist/lib/dbWrite.d.ts.map +1 -0
  45. package/dist/lib/dbWrite.js +171 -0
  46. package/dist/lib/dbWrite.js.map +1 -0
  47. package/dist/lib/dream.d.ts +170 -0
  48. package/dist/lib/dream.d.ts.map +1 -0
  49. package/dist/lib/dream.js +706 -0
  50. package/dist/lib/dream.js.map +1 -0
  51. package/dist/lib/embeddings.d.ts +84 -0
  52. package/dist/lib/embeddings.d.ts.map +1 -0
  53. package/dist/lib/embeddings.js +226 -0
  54. package/dist/lib/embeddings.js.map +1 -0
  55. package/dist/lib/export.d.ts +92 -0
  56. package/dist/lib/export.d.ts.map +1 -0
  57. package/dist/lib/export.js +362 -0
  58. package/dist/lib/export.js.map +1 -0
  59. package/dist/lib/federated.d.ts +113 -0
  60. package/dist/lib/federated.d.ts.map +1 -0
  61. package/dist/lib/federated.js +346 -0
  62. package/dist/lib/federated.js.map +1 -0
  63. package/dist/lib/graph.d.ts +50 -0
  64. package/dist/lib/graph.d.ts.map +1 -0
  65. package/dist/lib/graph.js +118 -0
  66. package/dist/lib/graph.js.map +1 -0
  67. package/dist/lib/history.d.ts +39 -0
  68. package/dist/lib/history.d.ts.map +1 -0
  69. package/dist/lib/history.js +112 -0
  70. package/dist/lib/history.js.map +1 -0
  71. package/dist/lib/hybridSearch.d.ts +80 -0
  72. package/dist/lib/hybridSearch.d.ts.map +1 -0
  73. package/dist/lib/hybridSearch.js +296 -0
  74. package/dist/lib/hybridSearch.js.map +1 -0
  75. package/dist/lib/import.d.ts +52 -0
  76. package/dist/lib/import.d.ts.map +1 -0
  77. package/dist/lib/import.js +365 -0
  78. package/dist/lib/import.js.map +1 -0
  79. package/dist/lib/ingest.d.ts +51 -0
  80. package/dist/lib/ingest.d.ts.map +1 -0
  81. package/dist/lib/ingest.js +144 -0
  82. package/dist/lib/ingest.js.map +1 -0
  83. package/dist/lib/lensing.d.ts +35 -0
  84. package/dist/lib/lensing.d.ts.map +1 -0
  85. package/dist/lib/lensing.js +85 -0
  86. package/dist/lib/lensing.js.map +1 -0
  87. package/dist/lib/llm.d.ts +84 -0
  88. package/dist/lib/llm.d.ts.map +1 -0
  89. package/dist/lib/llm.js +386 -0
  90. package/dist/lib/llm.js.map +1 -0
  91. package/dist/lib/lock.d.ts +28 -0
  92. package/dist/lib/lock.d.ts.map +1 -0
  93. package/dist/lib/lock.js +145 -0
  94. package/dist/lib/lock.js.map +1 -0
  95. package/dist/lib/maintenance.d.ts +124 -0
  96. package/dist/lib/maintenance.d.ts.map +1 -0
  97. package/dist/lib/maintenance.js +587 -0
  98. package/dist/lib/maintenance.js.map +1 -0
  99. package/dist/lib/migrate.d.ts +19 -0
  100. package/dist/lib/migrate.d.ts.map +1 -0
  101. package/dist/lib/migrate.js +260 -0
  102. package/dist/lib/migrate.js.map +1 -0
  103. package/dist/lib/preferences.d.ts +49 -0
  104. package/dist/lib/preferences.d.ts.map +1 -0
  105. package/dist/lib/preferences.js +149 -0
  106. package/dist/lib/preferences.js.map +1 -0
  107. package/dist/lib/projectIdentity.d.ts +66 -0
  108. package/dist/lib/projectIdentity.d.ts.map +1 -0
  109. package/dist/lib/projectIdentity.js +148 -0
  110. package/dist/lib/projectIdentity.js.map +1 -0
  111. package/dist/lib/recall.d.ts +82 -0
  112. package/dist/lib/recall.d.ts.map +1 -0
  113. package/dist/lib/recall.js +289 -0
  114. package/dist/lib/recall.js.map +1 -0
  115. package/dist/lib/resolver.d.ts +116 -0
  116. package/dist/lib/resolver.d.ts.map +1 -0
  117. package/dist/lib/resolver.js +372 -0
  118. package/dist/lib/resolver.js.map +1 -0
  119. package/dist/lib/retry.d.ts +24 -0
  120. package/dist/lib/retry.d.ts.map +1 -0
  121. package/dist/lib/retry.js +60 -0
  122. package/dist/lib/retry.js.map +1 -0
  123. package/dist/lib/rulesGen.d.ts +51 -0
  124. package/dist/lib/rulesGen.d.ts.map +1 -0
  125. package/dist/lib/rulesGen.js +167 -0
  126. package/dist/lib/rulesGen.js.map +1 -0
  127. package/dist/lib/search.d.ts +51 -0
  128. package/dist/lib/search.d.ts.map +1 -0
  129. package/dist/lib/search.js +190 -0
  130. package/dist/lib/search.js.map +1 -0
  131. package/dist/lib/staticSearch.d.ts +70 -0
  132. package/dist/lib/staticSearch.d.ts.map +1 -0
  133. package/dist/lib/staticSearch.js +162 -0
  134. package/dist/lib/staticSearch.js.map +1 -0
  135. package/dist/lib/store.d.ts +79 -0
  136. package/dist/lib/store.d.ts.map +1 -0
  137. package/dist/lib/store.js +227 -0
  138. package/dist/lib/store.js.map +1 -0
  139. package/dist/lib/structuredIngest.d.ts +37 -0
  140. package/dist/lib/structuredIngest.d.ts.map +1 -0
  141. package/dist/lib/structuredIngest.js +208 -0
  142. package/dist/lib/structuredIngest.js.map +1 -0
  143. package/dist/lib/tags.d.ts +26 -0
  144. package/dist/lib/tags.d.ts.map +1 -0
  145. package/dist/lib/tags.js +109 -0
  146. package/dist/lib/tags.js.map +1 -0
  147. package/dist/lib/timeline.d.ts +34 -0
  148. package/dist/lib/timeline.d.ts.map +1 -0
  149. package/dist/lib/timeline.js +116 -0
  150. package/dist/lib/timeline.js.map +1 -0
  151. package/dist/lib/trace.d.ts +42 -0
  152. package/dist/lib/trace.d.ts.map +1 -0
  153. package/dist/lib/trace.js +338 -0
  154. package/dist/lib/trace.js.map +1 -0
  155. package/dist/lib/webIndex.d.ts +28 -0
  156. package/dist/lib/webIndex.d.ts.map +1 -0
  157. package/dist/lib/webIndex.js +208 -0
  158. package/dist/lib/webIndex.js.map +1 -0
  159. package/dist/lib/webIngest.d.ts +51 -0
  160. package/dist/lib/webIngest.d.ts.map +1 -0
  161. package/dist/lib/webIngest.js +533 -0
  162. package/dist/lib/webIngest.js.map +1 -0
  163. package/dist/lib/wikilinks.d.ts +63 -0
  164. package/dist/lib/wikilinks.d.ts.map +1 -0
  165. package/dist/lib/wikilinks.js +146 -0
  166. package/dist/lib/wikilinks.js.map +1 -0
  167. package/dist/sandbox/client.d.ts +82 -0
  168. package/dist/sandbox/client.d.ts.map +1 -0
  169. package/dist/sandbox/client.js +128 -0
  170. package/dist/sandbox/client.js.map +1 -0
  171. package/dist/sandbox/helper-template.d.ts +14 -0
  172. package/dist/sandbox/helper-template.d.ts.map +1 -0
  173. package/dist/sandbox/helper-template.js +285 -0
  174. package/dist/sandbox/helper-template.js.map +1 -0
  175. package/dist/sandbox/index.d.ts +10 -0
  176. package/dist/sandbox/index.d.ts.map +1 -0
  177. package/dist/sandbox/index.js +10 -0
  178. package/dist/sandbox/index.js.map +1 -0
  179. package/dist/sandbox/manager.d.ts +40 -0
  180. package/dist/sandbox/manager.d.ts.map +1 -0
  181. package/dist/sandbox/manager.js +220 -0
  182. package/dist/sandbox/manager.js.map +1 -0
  183. package/dist/sandbox/server.d.ts +44 -0
  184. package/dist/sandbox/server.d.ts.map +1 -0
  185. package/dist/sandbox/server.js +661 -0
  186. package/dist/sandbox/server.js.map +1 -0
  187. package/package.json +103 -0
  188. package/prompts/synthesize.md +21 -0
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Gnosys Tag Registry — Categorized controlled vocabulary for tags.
3
+ * Stored in .config/tags.json. The ingestion LLM must use existing tags
4
+ * but can propose new ones for approval.
5
+ */
6
+ import fs from "fs/promises";
7
+ import path from "path";
8
+ const DEFAULT_REGISTRY = {
9
+ domain: [
10
+ "auth",
11
+ "database",
12
+ "frontend",
13
+ "backend",
14
+ "deployment",
15
+ "api",
16
+ "cli",
17
+ "mcp",
18
+ "wiki",
19
+ "obsidian",
20
+ "architecture",
21
+ "retrieval",
22
+ "search",
23
+ "ingestion",
24
+ "memory",
25
+ "lensing",
26
+ "decay",
27
+ "reinforcement",
28
+ "contradiction",
29
+ "tags",
30
+ "git",
31
+ "typescript",
32
+ "tooling",
33
+ "roadmap",
34
+ "scope",
35
+ ],
36
+ type: [
37
+ "decision",
38
+ "convention",
39
+ "architecture",
40
+ "concept",
41
+ "requirement",
42
+ "landscape",
43
+ "open-question",
44
+ ],
45
+ concern: [
46
+ "security",
47
+ "performance",
48
+ "scalability",
49
+ "dx",
50
+ "adoption",
51
+ "community",
52
+ "portability",
53
+ ],
54
+ status_tag: ["core", "experimental", "deprecated", "phased"],
55
+ };
56
+ export class GnosysTagRegistry {
57
+ registryPath;
58
+ registry;
59
+ constructor(storePath) {
60
+ this.registryPath = path.join(storePath, ".config", "tags.json");
61
+ this.registry = { ...DEFAULT_REGISTRY };
62
+ }
63
+ async load() {
64
+ try {
65
+ const raw = await fs.readFile(this.registryPath, "utf-8");
66
+ this.registry = JSON.parse(raw);
67
+ }
68
+ catch {
69
+ // File doesn't exist yet — use defaults and create it
70
+ await this.save();
71
+ }
72
+ return this.registry;
73
+ }
74
+ async save() {
75
+ const dir = path.dirname(this.registryPath);
76
+ await fs.mkdir(dir, { recursive: true });
77
+ await fs.writeFile(this.registryPath, JSON.stringify(this.registry, null, 2), "utf-8");
78
+ }
79
+ getRegistry() {
80
+ return this.registry;
81
+ }
82
+ getAllTags() {
83
+ return [...new Set(Object.values(this.registry).flat())].sort();
84
+ }
85
+ getTagsByCategory(category) {
86
+ return this.registry[category] || [];
87
+ }
88
+ hasTag(tag) {
89
+ return Object.values(this.registry).some((tags) => tags.includes(tag));
90
+ }
91
+ findTagCategory(tag) {
92
+ for (const [category, tags] of Object.entries(this.registry)) {
93
+ if (tags.includes(tag))
94
+ return category;
95
+ }
96
+ return null;
97
+ }
98
+ async addTag(category, tag) {
99
+ if (!this.registry[category]) {
100
+ this.registry[category] = [];
101
+ }
102
+ if (this.registry[category].includes(tag))
103
+ return false;
104
+ this.registry[category].push(tag);
105
+ await this.save();
106
+ return true;
107
+ }
108
+ }
109
+ //# sourceMappingURL=tags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tags.js","sourceRoot":"","sources":["../../src/lib/tags.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Gnosys Timeline — Temporal views and statistics for memory stores.
3
+ *
4
+ * Group memories by time period to see knowledge evolution.
5
+ * Compute summary statistics across the store.
6
+ */
7
+ import { Memory } from "./store.js";
8
+ export type TimePeriod = "day" | "week" | "month" | "year";
9
+ export interface TimelineEntry {
10
+ period: string;
11
+ created: number;
12
+ modified: number;
13
+ titles: string[];
14
+ }
15
+ export interface MemoryStats {
16
+ totalCount: number;
17
+ byCategory: Record<string, number>;
18
+ byStatus: Record<string, number>;
19
+ byAuthor: Record<string, number>;
20
+ byAuthority: Record<string, number>;
21
+ averageConfidence: number;
22
+ oldestCreated: string | null;
23
+ newestCreated: string | null;
24
+ lastModified: string | null;
25
+ }
26
+ /**
27
+ * Group memories by time period based on their created/modified dates.
28
+ */
29
+ export declare function groupByPeriod(memories: Memory[], period: TimePeriod): TimelineEntry[];
30
+ /**
31
+ * Compute summary statistics across all memories.
32
+ */
33
+ export declare function computeStats(memories: Memory[]): MemoryStats;
34
+ //# sourceMappingURL=timeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../../src/lib/timeline.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEpC,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3D,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,UAAU,GAAG,aAAa,EAAE,CAkCrF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,WAAW,CAmC5D"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Gnosys Timeline — Temporal views and statistics for memory stores.
3
+ *
4
+ * Group memories by time period to see knowledge evolution.
5
+ * Compute summary statistics across the store.
6
+ */
7
+ /**
8
+ * Group memories by time period based on their created/modified dates.
9
+ */
10
+ export function groupByPeriod(memories, period) {
11
+ const createdMap = new Map();
12
+ const modifiedMap = new Map();
13
+ for (const m of memories) {
14
+ const createdKey = toPeriodKey(m.frontmatter.created, period);
15
+ if (createdKey) {
16
+ const entry = createdMap.get(createdKey) || { count: 0, titles: [] };
17
+ entry.count++;
18
+ entry.titles.push(m.frontmatter.title);
19
+ createdMap.set(createdKey, entry);
20
+ }
21
+ const modifiedKey = toPeriodKey(m.frontmatter.modified, period);
22
+ if (modifiedKey && modifiedKey !== createdKey) {
23
+ modifiedMap.set(modifiedKey, (modifiedMap.get(modifiedKey) || 0) + 1);
24
+ }
25
+ }
26
+ // Merge all period keys
27
+ const allKeys = new Set([...createdMap.keys(), ...modifiedMap.keys()]);
28
+ const entries = [];
29
+ for (const key of allKeys) {
30
+ const created = createdMap.get(key);
31
+ entries.push({
32
+ period: key,
33
+ created: created?.count || 0,
34
+ modified: modifiedMap.get(key) || 0,
35
+ titles: created?.titles || [],
36
+ });
37
+ }
38
+ return entries.sort((a, b) => a.period.localeCompare(b.period));
39
+ }
40
+ /**
41
+ * Compute summary statistics across all memories.
42
+ */
43
+ export function computeStats(memories) {
44
+ const byCategory = {};
45
+ const byStatus = {};
46
+ const byAuthor = {};
47
+ const byAuthority = {};
48
+ let totalConfidence = 0;
49
+ let oldest = null;
50
+ let newest = null;
51
+ let lastMod = null;
52
+ for (const m of memories) {
53
+ const fm = m.frontmatter;
54
+ byCategory[fm.category] = (byCategory[fm.category] || 0) + 1;
55
+ byStatus[fm.status] = (byStatus[fm.status] || 0) + 1;
56
+ byAuthor[fm.author] = (byAuthor[fm.author] || 0) + 1;
57
+ byAuthority[fm.authority] = (byAuthority[fm.authority] || 0) + 1;
58
+ totalConfidence += fm.confidence;
59
+ if (!oldest || fm.created < oldest)
60
+ oldest = fm.created;
61
+ if (!newest || fm.created > newest)
62
+ newest = fm.created;
63
+ if (!lastMod || fm.modified > lastMod)
64
+ lastMod = fm.modified;
65
+ }
66
+ return {
67
+ totalCount: memories.length,
68
+ byCategory,
69
+ byStatus,
70
+ byAuthor,
71
+ byAuthority,
72
+ averageConfidence: memories.length > 0 ? Math.round((totalConfidence / memories.length) * 100) / 100 : 0,
73
+ oldestCreated: oldest,
74
+ newestCreated: newest,
75
+ lastModified: lastMod,
76
+ };
77
+ }
78
+ /**
79
+ * Convert an ISO date string to a period key.
80
+ */
81
+ function toPeriodKey(dateStr, period) {
82
+ if (!dateStr)
83
+ return null;
84
+ // Parse the date string (YYYY-MM-DD format)
85
+ const parts = dateStr.split("-");
86
+ if (parts.length < 3)
87
+ return null;
88
+ const year = parseInt(parts[0]);
89
+ const month = parseInt(parts[1]);
90
+ const day = parseInt(parts[2]);
91
+ switch (period) {
92
+ case "day":
93
+ return dateStr; // Already YYYY-MM-DD
94
+ case "week": {
95
+ const d = new Date(year, month - 1, day);
96
+ const weekNum = getISOWeek(d);
97
+ return `${year}-W${String(weekNum).padStart(2, "0")}`;
98
+ }
99
+ case "month":
100
+ return `${year}-${String(month).padStart(2, "0")}`;
101
+ case "year":
102
+ return `${year}`;
103
+ }
104
+ }
105
+ /**
106
+ * Get ISO week number for a date.
107
+ */
108
+ function getISOWeek(d) {
109
+ const date = new Date(d.getTime());
110
+ date.setHours(0, 0, 0, 0);
111
+ date.setDate(date.getDate() + 3 - ((date.getDay() + 6) % 7));
112
+ const week1 = new Date(date.getFullYear(), 0, 4);
113
+ return (1 +
114
+ Math.round(((date.getTime() - week1.getTime()) / 86400000 - 3 + ((week1.getDay() + 6) % 7)) / 7));
115
+ }
116
+ //# sourceMappingURL=timeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline.js","sourceRoot":"","sources":["../../src/lib/timeline.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAyBH;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,QAAkB,EAAE,MAAkB;IAClE,MAAM,UAAU,GAAG,IAAI,GAAG,EAA+C,CAAC;IAC1E,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE9C,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC9D,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;YACrE,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACvC,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QACpC,CAAC;QAED,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAChE,IAAI,WAAW,IAAI,WAAW,KAAK,UAAU,EAAE,CAAC;YAC9C,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IAED,wBAAwB;IACxB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,IAAI,EAAE,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACvE,MAAM,OAAO,GAAoB,EAAE,CAAC;IAEpC,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC;YACX,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;YAC5B,QAAQ,EAAE,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;YACnC,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,EAAE;SAC9B,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAClE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,QAAkB;IAC7C,MAAM,UAAU,GAA2B,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,MAAM,WAAW,GAA2B,EAAE,CAAC;IAC/C,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,IAAI,MAAM,GAAkB,IAAI,CAAC;IACjC,IAAI,MAAM,GAAkB,IAAI,CAAC;IACjC,IAAI,OAAO,GAAkB,IAAI,CAAC;IAElC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,CAAC;QAEzB,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC7D,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACrD,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACrD,WAAW,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACjE,eAAe,IAAI,EAAE,CAAC,UAAU,CAAC;QAEjC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,OAAO,GAAG,MAAM;YAAE,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC;QACxD,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,OAAO,GAAG,MAAM;YAAE,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC;QACxD,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,QAAQ,GAAG,OAAO;YAAE,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC;IAC/D,CAAC;IAED,OAAO;QACL,UAAU,EAAE,QAAQ,CAAC,MAAM;QAC3B,UAAU;QACV,QAAQ;QACR,QAAQ;QACR,WAAW;QACX,iBAAiB,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACxG,aAAa,EAAE,MAAM;QACrB,aAAa,EAAE,MAAM;QACrB,YAAY,EAAE,OAAO;KACtB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,OAAkC,EAAE,MAAkB;IACzE,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE1B,4CAA4C;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAElC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACjC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAE/B,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,KAAK;YACR,OAAO,OAAO,CAAC,CAAC,qBAAqB;QACvC,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;YACzC,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAC9B,OAAO,GAAG,IAAI,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;QACxD,CAAC;QACD,KAAK,OAAO;YACV,OAAO,GAAG,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;QACrD,KAAK,MAAM;YACT,OAAO,GAAG,IAAI,EAAE,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,CAAO;IACzB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IACnC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACjD,OAAO,CACL,CAAC;QACD,IAAI,CAAC,KAAK,CACR,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,GAAG,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CACrF,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Gnosys Process Tracing — Phase 10
3
+ *
4
+ * Builds call chains from TypeScript/JavaScript source files and stores them
5
+ * as procedural "how" memories with relationship chaining:
6
+ * - follows_from: sequential call order
7
+ * - requires: dependency / import relationships
8
+ * - leads_to: what this function calls
9
+ *
10
+ * No external dependencies beyond Node built-ins and the Gnosys DB.
11
+ */
12
+ import { GnosysDB } from "./db.js";
13
+ export interface TraceNode {
14
+ name: string;
15
+ file: string;
16
+ kind: "function" | "class" | "method" | "export";
17
+ line: number;
18
+ calls: string[];
19
+ calledBy: string[];
20
+ imports: string[];
21
+ }
22
+ export interface TraceGraph {
23
+ nodes: Map<string, TraceNode>;
24
+ files: string[];
25
+ rootDir: string;
26
+ }
27
+ export interface TraceResult {
28
+ memoriesCreated: number;
29
+ relationshipsCreated: number;
30
+ functionsFound: number;
31
+ filesScanned: number;
32
+ memoryIds: string[];
33
+ }
34
+ /**
35
+ * Trace a codebase directory: discover source files, parse function declarations
36
+ * and call relationships, then store as procedural "how" memories in the DB.
37
+ */
38
+ export declare function traceCodebase(db: GnosysDB, rootDir: string, opts?: {
39
+ projectId?: string;
40
+ maxFiles?: number;
41
+ }): TraceResult;
42
+ //# sourceMappingURL=trace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../src/lib/trace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,QAAQ,EAAY,MAAM,SAAS,CAAC;AAI7C,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC9B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAwLD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,EAAE,EAAE,QAAQ,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,GAAE;IACJ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACd,GACL,WAAW,CAkKb"}
@@ -0,0 +1,338 @@
1
+ /**
2
+ * Gnosys Process Tracing — Phase 10
3
+ *
4
+ * Builds call chains from TypeScript/JavaScript source files and stores them
5
+ * as procedural "how" memories with relationship chaining:
6
+ * - follows_from: sequential call order
7
+ * - requires: dependency / import relationships
8
+ * - leads_to: what this function calls
9
+ *
10
+ * No external dependencies beyond Node built-ins and the Gnosys DB.
11
+ */
12
+ import fs from "fs";
13
+ import path from "path";
14
+ // ─── Source Parsing (Regex-based, no TS compiler dependency) ─────────
15
+ /**
16
+ * Extract function declarations, class methods, exports, and call sites
17
+ * from a TypeScript/JavaScript source file using regex patterns.
18
+ *
19
+ * This is intentionally lightweight — no AST parsing dependency needed.
20
+ */
21
+ function parseSourceFile(filePath, rootDir) {
22
+ const content = fs.readFileSync(filePath, "utf-8");
23
+ const lines = content.split("\n");
24
+ const relPath = path.relative(rootDir, filePath);
25
+ const nodes = [];
26
+ // Track imports for the file
27
+ const fileImports = [];
28
+ const importRegex = /import\s+(?:{[^}]*}|\*\s+as\s+\w+|\w+)\s+from\s+["']([^"']+)["']/g;
29
+ let importMatch;
30
+ while ((importMatch = importRegex.exec(content))) {
31
+ fileImports.push(importMatch[1]);
32
+ }
33
+ // Pattern: function declarations (named functions, arrow functions assigned to const/let/var)
34
+ const funcPatterns = [
35
+ // export function foo(...) or function foo(...)
36
+ /(?:export\s+)?(?:async\s+)?function\s+(\w+)\s*\(/g,
37
+ // const foo = (...) => or const foo = function(...)
38
+ /(?:export\s+)?(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?(?:\([^)]*\)\s*=>|function\s*\()/g,
39
+ // class methods: foo(...) { or async foo(...) {
40
+ /^\s+(?:async\s+)?(\w+)\s*\([^)]*\)\s*(?::\s*[^{]+)?\s*\{/gm,
41
+ ];
42
+ // Pattern: class declarations
43
+ const classRegex = /(?:export\s+)?class\s+(\w+)(?:\s+(?:extends|implements)\s+\w+)?\s*\{/g;
44
+ // Extract function call sites: identifier followed by (
45
+ const callRegex = /\b(\w+)\s*\(/g;
46
+ // Common built-ins to exclude from call detection
47
+ const builtins = new Set([
48
+ "if", "for", "while", "switch", "catch", "return", "throw", "new", "typeof",
49
+ "instanceof", "delete", "void", "yield", "await", "import", "export",
50
+ "require", "console", "process", "JSON", "Object", "Array", "String",
51
+ "Number", "Boolean", "Map", "Set", "Promise", "Error", "Math", "Date",
52
+ "parseInt", "parseFloat", "setTimeout", "setInterval", "clearTimeout",
53
+ "clearInterval", "Buffer", "Symbol", "RegExp", "Proxy", "Reflect",
54
+ "describe", "it", "expect", "test", "beforeEach", "afterEach",
55
+ ]);
56
+ // First pass: find all function/class/method declarations
57
+ const declaredNames = new Set();
58
+ for (const pattern of funcPatterns) {
59
+ pattern.lastIndex = 0;
60
+ let match;
61
+ while ((match = pattern.exec(content))) {
62
+ const name = match[1];
63
+ if (builtins.has(name) || declaredNames.has(name))
64
+ continue;
65
+ declaredNames.add(name);
66
+ // Find line number
67
+ const lineNum = content.slice(0, match.index).split("\n").length;
68
+ nodes.push({
69
+ name,
70
+ file: relPath,
71
+ kind: "function",
72
+ line: lineNum,
73
+ calls: [],
74
+ calledBy: [],
75
+ imports: fileImports,
76
+ });
77
+ }
78
+ }
79
+ // Extract classes
80
+ {
81
+ classRegex.lastIndex = 0;
82
+ let match;
83
+ while ((match = classRegex.exec(content))) {
84
+ const name = match[1];
85
+ if (declaredNames.has(name))
86
+ continue;
87
+ declaredNames.add(name);
88
+ const lineNum = content.slice(0, match.index).split("\n").length;
89
+ nodes.push({
90
+ name,
91
+ file: relPath,
92
+ kind: "class",
93
+ line: lineNum,
94
+ calls: [],
95
+ calledBy: [],
96
+ imports: fileImports,
97
+ });
98
+ }
99
+ }
100
+ // Second pass: for each declared function, find what it calls
101
+ // This is an approximation — we scan the function body for call sites
102
+ for (const node of nodes) {
103
+ // Find the function body (from declaration to next top-level declaration or EOF)
104
+ const startLine = node.line - 1;
105
+ let endLine = lines.length;
106
+ // Simple heuristic: scan forward until we find the closing brace at the same indent level
107
+ let braceDepth = 0;
108
+ let foundOpen = false;
109
+ for (let i = startLine; i < lines.length; i++) {
110
+ for (const ch of lines[i]) {
111
+ if (ch === "{") {
112
+ braceDepth++;
113
+ foundOpen = true;
114
+ }
115
+ if (ch === "}") {
116
+ braceDepth--;
117
+ }
118
+ }
119
+ if (foundOpen && braceDepth <= 0) {
120
+ endLine = i + 1;
121
+ break;
122
+ }
123
+ }
124
+ const body = lines.slice(startLine, endLine).join("\n");
125
+ callRegex.lastIndex = 0;
126
+ let callMatch;
127
+ const callSet = new Set();
128
+ while ((callMatch = callRegex.exec(body))) {
129
+ const callee = callMatch[1];
130
+ if (callee !== node.name && !builtins.has(callee) && declaredNames.has(callee)) {
131
+ callSet.add(callee);
132
+ }
133
+ }
134
+ node.calls = [...callSet];
135
+ }
136
+ // Back-fill calledBy
137
+ const nodeMap = new Map(nodes.map((n) => [n.name, n]));
138
+ for (const node of nodes) {
139
+ for (const callee of node.calls) {
140
+ const target = nodeMap.get(callee);
141
+ if (target) {
142
+ target.calledBy.push(node.name);
143
+ }
144
+ }
145
+ }
146
+ return nodes;
147
+ }
148
+ // ─── File Discovery ─────────────────────────────────────────────────────
149
+ function discoverSourceFiles(rootDir) {
150
+ const files = [];
151
+ const extensions = new Set([".ts", ".js", ".tsx", ".jsx"]);
152
+ const ignoreDirs = new Set(["node_modules", "dist", "build", ".git", "coverage", ".gnosys"]);
153
+ function walk(dir) {
154
+ let entries;
155
+ try {
156
+ entries = fs.readdirSync(dir, { withFileTypes: true });
157
+ }
158
+ catch {
159
+ return; // Permission denied or other error
160
+ }
161
+ for (const entry of entries) {
162
+ if (entry.name.startsWith(".") && entry.isDirectory())
163
+ continue;
164
+ if (ignoreDirs.has(entry.name) && entry.isDirectory())
165
+ continue;
166
+ const fullPath = path.join(dir, entry.name);
167
+ if (entry.isDirectory()) {
168
+ walk(fullPath);
169
+ }
170
+ else if (entry.isFile() && extensions.has(path.extname(entry.name))) {
171
+ // Skip test files and declaration files
172
+ if (entry.name.endsWith(".test.ts") || entry.name.endsWith(".test.js"))
173
+ continue;
174
+ if (entry.name.endsWith(".d.ts"))
175
+ continue;
176
+ files.push(fullPath);
177
+ }
178
+ }
179
+ }
180
+ walk(rootDir);
181
+ return files;
182
+ }
183
+ // ─── Trace Codebase ─────────────────────────────────────────────────────
184
+ /**
185
+ * Trace a codebase directory: discover source files, parse function declarations
186
+ * and call relationships, then store as procedural "how" memories in the DB.
187
+ */
188
+ export function traceCodebase(db, rootDir, opts = {}) {
189
+ const absRoot = path.resolve(rootDir);
190
+ const sourceFiles = discoverSourceFiles(absRoot);
191
+ const filesToScan = opts.maxFiles
192
+ ? sourceFiles.slice(0, opts.maxFiles)
193
+ : sourceFiles;
194
+ // Parse all files
195
+ const allNodes = [];
196
+ for (const file of filesToScan) {
197
+ try {
198
+ const nodes = parseSourceFile(file, absRoot);
199
+ allNodes.push(...nodes);
200
+ }
201
+ catch {
202
+ // Skip unparseable files
203
+ }
204
+ }
205
+ if (allNodes.length === 0) {
206
+ return {
207
+ memoriesCreated: 0,
208
+ relationshipsCreated: 0,
209
+ functionsFound: 0,
210
+ filesScanned: filesToScan.length,
211
+ memoryIds: [],
212
+ };
213
+ }
214
+ // Build a global name→node map (deduplicate by file:name)
215
+ const globalMap = new Map();
216
+ for (const node of allNodes) {
217
+ const key = `${node.file}:${node.name}`;
218
+ globalMap.set(key, node);
219
+ }
220
+ // Cross-file: resolve calls to any declared function across files
221
+ const nameToKeys = new Map();
222
+ for (const [key, node] of globalMap) {
223
+ if (!nameToKeys.has(node.name))
224
+ nameToKeys.set(node.name, []);
225
+ nameToKeys.get(node.name).push(key);
226
+ }
227
+ const now = new Date().toISOString();
228
+ const memoryIds = [];
229
+ let relationshipsCreated = 0;
230
+ // Create a procedural memory for each function/class
231
+ const keyToMemId = new Map();
232
+ for (const [key, node] of globalMap) {
233
+ const memId = `mem-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
234
+ keyToMemId.set(key, memId);
235
+ const content = [
236
+ `## ${node.kind}: ${node.name}`,
237
+ "",
238
+ `**File:** \`${node.file}\` (line ${node.line})`,
239
+ "",
240
+ node.calls.length > 0
241
+ ? `**Calls:** ${node.calls.map((c) => `\`${c}\``).join(", ")}`
242
+ : "**Calls:** (none)",
243
+ node.calledBy.length > 0
244
+ ? `**Called by:** ${node.calledBy.map((c) => `\`${c}\``).join(", ")}`
245
+ : "**Called by:** (none)",
246
+ node.imports.length > 0
247
+ ? `\n**Imports:** ${node.imports.map((i) => `\`${i}\``).join(", ")}`
248
+ : "",
249
+ ].filter(Boolean).join("\n");
250
+ db.insertMemory({
251
+ id: memId,
252
+ title: `How: ${node.name} (${node.file})`,
253
+ category: "how",
254
+ content,
255
+ summary: null,
256
+ tags: JSON.stringify(["procedural", node.kind, path.basename(node.file, path.extname(node.file))]),
257
+ relevance: `how procedural ${node.name} ${node.file} ${node.kind}`,
258
+ author: "ai",
259
+ authority: "observed",
260
+ confidence: 0.85,
261
+ reinforcement_count: 0,
262
+ content_hash: "",
263
+ status: "active",
264
+ tier: "active",
265
+ supersedes: null,
266
+ superseded_by: null,
267
+ last_reinforced: null,
268
+ created: now,
269
+ modified: now,
270
+ embedding: null,
271
+ source_path: node.file,
272
+ project_id: opts.projectId || null,
273
+ scope: "project",
274
+ });
275
+ memoryIds.push(memId);
276
+ }
277
+ // Create relationships: leads_to, follows_from, requires
278
+ for (const [key, node] of globalMap) {
279
+ const sourceMemId = keyToMemId.get(key);
280
+ for (const callee of node.calls) {
281
+ // Find target memory IDs for this callee name
282
+ const targetKeys = nameToKeys.get(callee) || [];
283
+ for (const targetKey of targetKeys) {
284
+ const targetMemId = keyToMemId.get(targetKey);
285
+ if (!targetMemId || targetMemId === sourceMemId)
286
+ continue;
287
+ // leads_to: this function leads to the callee
288
+ db.insertRelationship({
289
+ source_id: sourceMemId,
290
+ target_id: targetMemId,
291
+ rel_type: "leads_to",
292
+ label: `${node.name} calls ${callee}`,
293
+ confidence: 0.9,
294
+ created: now,
295
+ });
296
+ relationshipsCreated++;
297
+ // follows_from: the callee follows from this function
298
+ db.insertRelationship({
299
+ source_id: targetMemId,
300
+ target_id: sourceMemId,
301
+ rel_type: "follows_from",
302
+ label: `${callee} is called by ${node.name}`,
303
+ confidence: 0.9,
304
+ created: now,
305
+ });
306
+ relationshipsCreated++;
307
+ }
308
+ }
309
+ // requires: import relationships (module-level)
310
+ for (const imp of node.imports) {
311
+ // Find any nodes from the imported module
312
+ for (const [targetKey, targetNode] of globalMap) {
313
+ if (targetNode.file.includes(imp.replace(/^\.\//, "").replace(/\.\w+$/, ""))) {
314
+ const targetMemId = keyToMemId.get(targetKey);
315
+ if (!targetMemId || targetMemId === sourceMemId)
316
+ continue;
317
+ db.insertRelationship({
318
+ source_id: sourceMemId,
319
+ target_id: targetMemId,
320
+ rel_type: "requires",
321
+ label: `${node.file} imports from ${targetNode.file}`,
322
+ confidence: 0.7,
323
+ created: now,
324
+ });
325
+ relationshipsCreated++;
326
+ }
327
+ }
328
+ }
329
+ }
330
+ return {
331
+ memoriesCreated: memoryIds.length,
332
+ relationshipsCreated,
333
+ functionsFound: allNodes.length,
334
+ filesScanned: filesToScan.length,
335
+ memoryIds,
336
+ };
337
+ }
338
+ //# sourceMappingURL=trace.js.map