@praneeth_54/agentdoctor 1.0.0 → 1.1.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 (208) hide show
  1. package/CHANGELOG.md +34 -5
  2. package/README.md +15 -12
  3. package/dist/cli/commands/brain-mcp.d.ts +9 -0
  4. package/dist/cli/commands/brain-mcp.js +38 -0
  5. package/dist/cli/program.js +13 -0
  6. package/dist/constants.d.ts +1 -1
  7. package/dist/constants.js +1 -1
  8. package/dist/core/understanding/architecture/index.d.ts +4 -0
  9. package/dist/core/understanding/architecture/index.js +3 -0
  10. package/dist/core/understanding/architecture/infer.d.ts +6 -0
  11. package/dist/core/understanding/architecture/infer.js +39 -0
  12. package/dist/core/understanding/architecture/models.d.ts +23 -0
  13. package/dist/core/understanding/architecture/models.js +127 -0
  14. package/dist/core/understanding/architecture/patterns/distribution.d.ts +2 -0
  15. package/dist/core/understanding/architecture/patterns/distribution.js +115 -0
  16. package/dist/core/understanding/architecture/patterns/index.d.ts +2 -0
  17. package/dist/core/understanding/architecture/patterns/index.js +8 -0
  18. package/dist/core/understanding/architecture/patterns/layered.d.ts +2 -0
  19. package/dist/core/understanding/architecture/patterns/layered.js +279 -0
  20. package/dist/core/understanding/architecture/patterns/structural.d.ts +2 -0
  21. package/dist/core/understanding/architecture/patterns/structural.js +197 -0
  22. package/dist/core/understanding/architecture/rules.d.ts +4 -0
  23. package/dist/core/understanding/architecture/rules.js +6 -0
  24. package/dist/core/understanding/architecture/types.d.ts +52 -0
  25. package/dist/core/understanding/architecture/types.js +1 -0
  26. package/dist/core/understanding/brain/build.d.ts +13 -0
  27. package/dist/core/understanding/brain/build.js +158 -0
  28. package/dist/core/understanding/brain/claims/index.d.ts +3 -0
  29. package/dist/core/understanding/brain/claims/index.js +2 -0
  30. package/dist/core/understanding/brain/claims/lifecycle.d.ts +16 -0
  31. package/dist/core/understanding/brain/claims/lifecycle.js +78 -0
  32. package/dist/core/understanding/brain/claims/types.d.ts +32 -0
  33. package/dist/core/understanding/brain/claims/types.js +25 -0
  34. package/dist/core/understanding/brain/components/index.d.ts +17 -0
  35. package/dist/core/understanding/brain/components/index.js +97 -0
  36. package/dist/core/understanding/brain/components/types.d.ts +16 -0
  37. package/dist/core/understanding/brain/components/types.js +8 -0
  38. package/dist/core/understanding/brain/confidence.d.ts +19 -0
  39. package/dist/core/understanding/brain/confidence.js +39 -0
  40. package/dist/core/understanding/brain/contract.d.ts +17 -0
  41. package/dist/core/understanding/brain/contract.js +100 -0
  42. package/dist/core/understanding/brain/contradictions/index.d.ts +12 -0
  43. package/dist/core/understanding/brain/contradictions/index.js +57 -0
  44. package/dist/core/understanding/brain/contradictions/types.d.ts +12 -0
  45. package/dist/core/understanding/brain/contradictions/types.js +8 -0
  46. package/dist/core/understanding/brain/delta.d.ts +25 -0
  47. package/dist/core/understanding/brain/delta.js +116 -0
  48. package/dist/core/understanding/brain/evidence/index.d.ts +3 -0
  49. package/dist/core/understanding/brain/evidence/index.js +2 -0
  50. package/dist/core/understanding/brain/evidence/redact.d.ts +4 -0
  51. package/dist/core/understanding/brain/evidence/redact.js +36 -0
  52. package/dist/core/understanding/brain/evidence/types.d.ts +34 -0
  53. package/dist/core/understanding/brain/evidence/types.js +35 -0
  54. package/dist/core/understanding/brain/explain.d.ts +17 -0
  55. package/dist/core/understanding/brain/explain.js +33 -0
  56. package/dist/core/understanding/brain/index.d.ts +28 -0
  57. package/dist/core/understanding/brain/index.js +16 -0
  58. package/dist/core/understanding/brain/migrate.d.ts +21 -0
  59. package/dist/core/understanding/brain/migrate.js +47 -0
  60. package/dist/core/understanding/brain/query.d.ts +60 -0
  61. package/dist/core/understanding/brain/query.js +92 -0
  62. package/dist/core/understanding/brain/security.d.ts +3 -0
  63. package/dist/core/understanding/brain/security.js +43 -0
  64. package/dist/core/understanding/brain/storage/index.d.ts +2 -0
  65. package/dist/core/understanding/brain/storage/index.js +1 -0
  66. package/dist/core/understanding/brain/storage/store.d.ts +53 -0
  67. package/dist/core/understanding/brain/storage/store.js +305 -0
  68. package/dist/core/understanding/brain/trace.d.ts +24 -0
  69. package/dist/core/understanding/brain/trace.js +207 -0
  70. package/dist/core/understanding/brain/types.d.ts +32 -0
  71. package/dist/core/understanding/brain/types.js +8 -0
  72. package/dist/core/understanding/brain/version.d.ts +13 -0
  73. package/dist/core/understanding/brain/version.js +7 -0
  74. package/dist/core/understanding/delta/compare.d.ts +26 -0
  75. package/dist/core/understanding/delta/compare.js +74 -0
  76. package/dist/core/understanding/delta/index.d.ts +2 -0
  77. package/dist/core/understanding/delta/index.js +1 -0
  78. package/dist/core/understanding/dependencies/discover.d.ts +7 -0
  79. package/dist/core/understanding/dependencies/discover.js +550 -0
  80. package/dist/core/understanding/dependencies/extract.d.ts +10 -0
  81. package/dist/core/understanding/dependencies/extract.js +189 -0
  82. package/dist/core/understanding/dependencies/index.d.ts +4 -0
  83. package/dist/core/understanding/dependencies/index.js +3 -0
  84. package/dist/core/understanding/dependencies/models.d.ts +12 -0
  85. package/dist/core/understanding/dependencies/models.js +125 -0
  86. package/dist/core/understanding/dependencies/types.d.ts +27 -0
  87. package/dist/core/understanding/dependencies/types.js +1 -0
  88. package/dist/core/understanding/domain/discover.d.ts +14 -0
  89. package/dist/core/understanding/domain/discover.js +90 -0
  90. package/dist/core/understanding/domain/index.d.ts +2 -0
  91. package/dist/core/understanding/domain/index.js +1 -0
  92. package/dist/core/understanding/entrypoints/discover.d.ts +6 -0
  93. package/dist/core/understanding/entrypoints/discover.js +62 -0
  94. package/dist/core/understanding/entrypoints/extract.d.ts +19 -0
  95. package/dist/core/understanding/entrypoints/extract.js +43 -0
  96. package/dist/core/understanding/entrypoints/index.d.ts +4 -0
  97. package/dist/core/understanding/entrypoints/index.js +3 -0
  98. package/dist/core/understanding/entrypoints/models.d.ts +26 -0
  99. package/dist/core/understanding/entrypoints/models.js +216 -0
  100. package/dist/core/understanding/entrypoints/types.d.ts +20 -0
  101. package/dist/core/understanding/entrypoints/types.js +1 -0
  102. package/dist/core/understanding/index.d.ts +32 -0
  103. package/dist/core/understanding/index.js +18 -0
  104. package/dist/core/understanding/mind/build.d.ts +16 -0
  105. package/dist/core/understanding/mind/build.js +134 -0
  106. package/dist/core/understanding/mind/index.d.ts +6 -0
  107. package/dist/core/understanding/mind/index.js +3 -0
  108. package/dist/core/understanding/mind/query.d.ts +33 -0
  109. package/dist/core/understanding/mind/query.js +39 -0
  110. package/dist/core/understanding/mind/types.d.ts +24 -0
  111. package/dist/core/understanding/mind/types.js +7 -0
  112. package/dist/core/understanding/model/builder.d.ts +9 -0
  113. package/dist/core/understanding/model/builder.js +209 -0
  114. package/dist/core/understanding/model/ids.d.ts +7 -0
  115. package/dist/core/understanding/model/ids.js +48 -0
  116. package/dist/core/understanding/model/index.d.ts +7 -0
  117. package/dist/core/understanding/model/index.js +6 -0
  118. package/dist/core/understanding/model/schema.d.ts +12 -0
  119. package/dist/core/understanding/model/schema.js +33 -0
  120. package/dist/core/understanding/model/serializer.d.ts +9 -0
  121. package/dist/core/understanding/model/serializer.js +46 -0
  122. package/dist/core/understanding/model/types.d.ts +110 -0
  123. package/dist/core/understanding/model/types.js +1 -0
  124. package/dist/core/understanding/model/validator.d.ts +5 -0
  125. package/dist/core/understanding/model/validator.js +126 -0
  126. package/dist/core/understanding/model/version.d.ts +9 -0
  127. package/dist/core/understanding/model/version.js +7 -0
  128. package/dist/core/understanding/ownership/discover.d.ts +12 -0
  129. package/dist/core/understanding/ownership/discover.js +242 -0
  130. package/dist/core/understanding/ownership/index.d.ts +2 -0
  131. package/dist/core/understanding/ownership/index.js +1 -0
  132. package/dist/core/understanding/ownership/types.d.ts +23 -0
  133. package/dist/core/understanding/ownership/types.js +1 -0
  134. package/dist/core/understanding/query/engine.d.ts +24 -0
  135. package/dist/core/understanding/query/engine.js +35 -0
  136. package/dist/core/understanding/query/errors.d.ts +13 -0
  137. package/dist/core/understanding/query/errors.js +26 -0
  138. package/dist/core/understanding/query/executor.d.ts +8 -0
  139. package/dist/core/understanding/query/executor.js +34 -0
  140. package/dist/core/understanding/query/index.d.ts +7 -0
  141. package/dist/core/understanding/query/index.js +5 -0
  142. package/dist/core/understanding/query/models.d.ts +102 -0
  143. package/dist/core/understanding/query/models.js +1 -0
  144. package/dist/core/understanding/query/query.d.ts +68 -0
  145. package/dist/core/understanding/query/query.js +145 -0
  146. package/dist/core/understanding/query/registry.d.ts +8 -0
  147. package/dist/core/understanding/query/registry.js +340 -0
  148. package/dist/core/understanding/query/types.d.ts +63 -0
  149. package/dist/core/understanding/query/types.js +1 -0
  150. package/dist/core/understanding/relationships/discover.d.ts +11 -0
  151. package/dist/core/understanding/relationships/discover.js +517 -0
  152. package/dist/core/understanding/relationships/extract.d.ts +14 -0
  153. package/dist/core/understanding/relationships/extract.js +165 -0
  154. package/dist/core/understanding/relationships/index.d.ts +4 -0
  155. package/dist/core/understanding/relationships/index.js +3 -0
  156. package/dist/core/understanding/relationships/models.d.ts +21 -0
  157. package/dist/core/understanding/relationships/models.js +185 -0
  158. package/dist/core/understanding/relationships/types.d.ts +42 -0
  159. package/dist/core/understanding/relationships/types.js +1 -0
  160. package/dist/core/understanding/risks/discover.d.ts +8 -0
  161. package/dist/core/understanding/risks/discover.js +155 -0
  162. package/dist/core/understanding/risks/index.d.ts +2 -0
  163. package/dist/core/understanding/risks/index.js +1 -0
  164. package/dist/core/understanding/risks/types.d.ts +26 -0
  165. package/dist/core/understanding/risks/types.js +1 -0
  166. package/dist/core/understanding/shared/domain-lexicon.d.ts +9 -0
  167. package/dist/core/understanding/shared/domain-lexicon.js +107 -0
  168. package/dist/core/understanding/shared/index.d.ts +2 -0
  169. package/dist/core/understanding/shared/index.js +2 -0
  170. package/dist/core/understanding/shared/tokens.d.ts +7 -0
  171. package/dist/core/understanding/shared/tokens.js +141 -0
  172. package/dist/core/understanding/snapshot/identity.d.ts +24 -0
  173. package/dist/core/understanding/snapshot/identity.js +79 -0
  174. package/dist/core/understanding/snapshot/index.d.ts +2 -0
  175. package/dist/core/understanding/snapshot/index.js +1 -0
  176. package/dist/core/understanding/types/index.d.ts +22 -0
  177. package/dist/core/understanding/types/index.js +1 -0
  178. package/dist/core/understanding/understand/formatter.d.ts +10 -0
  179. package/dist/core/understanding/understand/formatter.js +115 -0
  180. package/dist/core/understanding/understand/index.d.ts +4 -0
  181. package/dist/core/understanding/understand/index.js +3 -0
  182. package/dist/core/understanding/understand/service.d.ts +17 -0
  183. package/dist/core/understanding/understand/service.js +76 -0
  184. package/dist/core/understanding/understand/summary.d.ts +14 -0
  185. package/dist/core/understanding/understand/summary.js +39 -0
  186. package/dist/core/understanding/understand/types.d.ts +31 -0
  187. package/dist/core/understanding/understand/types.js +1 -0
  188. package/dist/mcp/brain/compile.d.ts +9 -0
  189. package/dist/mcp/brain/compile.js +42 -0
  190. package/dist/mcp/brain/errors.d.ts +12 -0
  191. package/dist/mcp/brain/errors.js +23 -0
  192. package/dist/mcp/brain/index.d.ts +11 -0
  193. package/dist/mcp/brain/index.js +8 -0
  194. package/dist/mcp/brain/provenance.d.ts +29 -0
  195. package/dist/mcp/brain/provenance.js +59 -0
  196. package/dist/mcp/brain/schemas.d.ts +13 -0
  197. package/dist/mcp/brain/schemas.js +105 -0
  198. package/dist/mcp/brain/security/root.d.ts +6 -0
  199. package/dist/mcp/brain/security/root.js +66 -0
  200. package/dist/mcp/brain/server.d.ts +12 -0
  201. package/dist/mcp/brain/server.js +46 -0
  202. package/dist/mcp/brain/session.d.ts +33 -0
  203. package/dist/mcp/brain/session.js +117 -0
  204. package/dist/mcp/brain/tools/handlers.d.ts +13 -0
  205. package/dist/mcp/brain/tools/handlers.js +483 -0
  206. package/dist/mcp/brain/tools/registry.d.ts +9 -0
  207. package/dist/mcp/brain/tools/registry.js +191 -0
  208. package/package.json +5 -1
@@ -0,0 +1,242 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { discoverFiles } from "../../../discovery/files.js";
4
+ import { readTextFile } from "../../../utils/fs.js";
5
+ const MAX_BYTES = 512 * 1024;
6
+ const CODEOWNERS_CANDIDATES = [
7
+ "CODEOWNERS",
8
+ ".github/CODEOWNERS",
9
+ "docs/CODEOWNERS",
10
+ ".gitlab/CODEOWNERS",
11
+ ];
12
+ export function scoreOwnershipConfidence(source) {
13
+ switch (source) {
14
+ case "codeowners":
15
+ return 0.95;
16
+ case "maintainers-file":
17
+ return 0.85;
18
+ case "package-maintainers":
19
+ return 0.75;
20
+ default:
21
+ return 0;
22
+ }
23
+ }
24
+ /** Match a repo-relative path against a CODEOWNERS pattern (subset of GitHub rules). */
25
+ export function matchCodeownersPattern(filePath, pattern) {
26
+ const normalizedFile = filePath.replace(/\\/g, "/").replace(/^\/+/, "");
27
+ let normalizedPattern = pattern.replace(/\\/g, "/").trim();
28
+ if (normalizedPattern.length === 0) {
29
+ return false;
30
+ }
31
+ const anchored = normalizedPattern.startsWith("/");
32
+ if (anchored) {
33
+ normalizedPattern = normalizedPattern.slice(1);
34
+ }
35
+ const dirOnly = normalizedPattern.endsWith("/");
36
+ if (dirOnly) {
37
+ normalizedPattern = normalizedPattern.slice(0, -1);
38
+ }
39
+ const escaped = normalizedPattern
40
+ .replace(/[.+^${}()|[\]\\]/g, "\\$&")
41
+ .replace(/\*\*/g, "{{GLOBSTAR}}")
42
+ .replace(/\*/g, "[^/]*")
43
+ .replace(/\?/g, "[^/]")
44
+ .replace(/{{GLOBSTAR}}/g, ".*");
45
+ const prefix = anchored ? "^" : "(^|/)";
46
+ const suffix = dirOnly ? "(/.*)?$" : "$";
47
+ const regex = new RegExp(`${prefix}${escaped}${suffix}`);
48
+ return regex.test(normalizedFile);
49
+ }
50
+ function parseCodeowners(content, sourcePath) {
51
+ const matches = [];
52
+ for (const rawLine of content.split(/\r?\n/)) {
53
+ const line = rawLine.trim();
54
+ if (line.length === 0 || line.startsWith("#")) {
55
+ continue;
56
+ }
57
+ const parts = line.split(/\s+/).filter((part) => part.length > 0);
58
+ if (parts.length < 2) {
59
+ continue;
60
+ }
61
+ const pattern = parts[0];
62
+ if (!pattern) {
63
+ continue;
64
+ }
65
+ const owners = parts.slice(1).filter((part) => !part.startsWith("#"));
66
+ if (owners.length === 0) {
67
+ continue;
68
+ }
69
+ matches.push({
70
+ path: pattern,
71
+ owners,
72
+ confidence: scoreOwnershipConfidence("codeowners"),
73
+ evidence: [`${sourcePath}:${pattern}`],
74
+ source: "codeowners",
75
+ });
76
+ }
77
+ return matches;
78
+ }
79
+ function parseMaintainersFile(content, sourcePath) {
80
+ const owners = [];
81
+ for (const rawLine of content.split(/\r?\n/)) {
82
+ const line = rawLine.trim();
83
+ if (line.length === 0 || line.startsWith("#")) {
84
+ continue;
85
+ }
86
+ // Common formats: "@handle", "Name <email>", plain email/name
87
+ owners.push(line.replace(/,\s*$/, ""));
88
+ }
89
+ if (owners.length === 0) {
90
+ return [];
91
+ }
92
+ return [
93
+ {
94
+ path: "*",
95
+ owners,
96
+ confidence: scoreOwnershipConfidence("maintainers-file"),
97
+ evidence: [sourcePath],
98
+ source: "maintainers-file",
99
+ },
100
+ ];
101
+ }
102
+ function ownersFromPackageJson(data, packageRelativePath) {
103
+ if (!data || typeof data !== "object") {
104
+ return null;
105
+ }
106
+ const record = data;
107
+ const owners = [];
108
+ const pushAuthor = (value) => {
109
+ if (typeof value === "string" && value.trim().length > 0) {
110
+ owners.push(value.trim());
111
+ return;
112
+ }
113
+ if (value && typeof value === "object") {
114
+ const author = value;
115
+ const name = typeof author.name === "string" ? author.name.trim() : "";
116
+ const email = typeof author.email === "string" ? author.email.trim() : "";
117
+ if (name && email) {
118
+ owners.push(`${name} <${email}>`);
119
+ }
120
+ else if (name) {
121
+ owners.push(name);
122
+ }
123
+ else if (email) {
124
+ owners.push(email);
125
+ }
126
+ }
127
+ };
128
+ pushAuthor(record.author);
129
+ if (Array.isArray(record.maintainers)) {
130
+ for (const item of record.maintainers) {
131
+ pushAuthor(item);
132
+ }
133
+ }
134
+ const unique = [...new Set(owners)];
135
+ if (unique.length === 0) {
136
+ return null;
137
+ }
138
+ const dir = path.posix.dirname(packageRelativePath.replace(/\\/g, "/"));
139
+ const covered = dir === "." ? "*" : `${dir}/**`;
140
+ return {
141
+ path: covered,
142
+ owners: unique,
143
+ confidence: scoreOwnershipConfidence("package-maintainers"),
144
+ evidence: [packageRelativePath],
145
+ source: "package-maintainers",
146
+ };
147
+ }
148
+ /**
149
+ * Discover ownership from explicit repository evidence only.
150
+ * Sources: CODEOWNERS, MAINTAINERS, package.json author/maintainers.
151
+ * No git-blame guessing.
152
+ */
153
+ export async function discoverOwnership(options = {}) {
154
+ const started = performance.now();
155
+ const cwd = options.cwd ?? process.cwd();
156
+ const minConfidence = options.minConfidence ?? 0.5;
157
+ const ownerships = [];
158
+ const unknowns = [];
159
+ let filesConsidered = 0;
160
+ for (const candidate of CODEOWNERS_CANDIDATES) {
161
+ const absolute = path.join(cwd, candidate);
162
+ const text = await readTextFile(absolute, MAX_BYTES);
163
+ if (text === null) {
164
+ continue;
165
+ }
166
+ filesConsidered += 1;
167
+ ownerships.push(...parseCodeowners(text, candidate));
168
+ }
169
+ for (const candidate of ["MAINTAINERS", "OWNERS", "docs/MAINTAINERS"]) {
170
+ const text = await readTextFile(path.join(cwd, candidate), MAX_BYTES);
171
+ if (text === null) {
172
+ continue;
173
+ }
174
+ filesConsidered += 1;
175
+ ownerships.push(...parseMaintainersFile(text, candidate));
176
+ }
177
+ const relativePaths = options.relativePaths ??
178
+ (await discoverFiles({ root: cwd })).files.map((file) => file.relativePath);
179
+ const packageJsonPaths = relativePaths.filter((relative) => {
180
+ const normalized = relative.replace(/\\/g, "/");
181
+ return normalized === "package.json" || normalized.endsWith("/package.json");
182
+ });
183
+ for (const packageRelative of packageJsonPaths) {
184
+ filesConsidered += 1;
185
+ try {
186
+ const raw = await fs.readFile(path.join(cwd, packageRelative), "utf8");
187
+ if (Buffer.byteLength(raw, "utf8") > MAX_BYTES) {
188
+ continue;
189
+ }
190
+ const parsed = JSON.parse(raw);
191
+ const match = ownersFromPackageJson(parsed, packageRelative.replace(/\\/g, "/"));
192
+ if (match) {
193
+ ownerships.push(match);
194
+ }
195
+ }
196
+ catch {
197
+ // Malformed package.json is not ownership evidence.
198
+ }
199
+ }
200
+ const filtered = ownerships
201
+ .filter((item) => item.confidence >= minConfidence && item.owners.length > 0)
202
+ .sort((a, b) => b.confidence - a.confidence ||
203
+ a.source.localeCompare(b.source) ||
204
+ a.path.localeCompare(b.path));
205
+ if (filtered.length === 0) {
206
+ unknowns.push("No explicit ownership evidence found (CODEOWNERS / MAINTAINERS / package.json)");
207
+ }
208
+ return {
209
+ ownerships: filtered,
210
+ timingMs: Math.max(0, Math.round(performance.now() - started)),
211
+ filesConsidered,
212
+ unknowns,
213
+ };
214
+ }
215
+ /** Resolve owners for a path using last-matching CODEOWNERS rule semantics when possible. */
216
+ export function ownersForPath(filePath, ownerships) {
217
+ const normalized = filePath.replace(/\\/g, "/").replace(/^\/+/, "");
218
+ let lastCodeowners = null;
219
+ let packageMatch = null;
220
+ let maintainersMatch = null;
221
+ for (const ownership of ownerships) {
222
+ if (ownership.source === "codeowners") {
223
+ if (matchCodeownersPattern(normalized, ownership.path)) {
224
+ lastCodeowners = ownership;
225
+ }
226
+ continue;
227
+ }
228
+ if (ownership.source === "package-maintainers") {
229
+ if (ownership.path === "*" || matchCodeownersPattern(normalized, ownership.path)) {
230
+ // Prefer the most specific package path (longest prefix).
231
+ if (!packageMatch || ownership.path.length > packageMatch.path.length) {
232
+ packageMatch = ownership;
233
+ }
234
+ }
235
+ continue;
236
+ }
237
+ if (ownership.source === "maintainers-file" && ownership.path === "*") {
238
+ maintainersMatch = ownership;
239
+ }
240
+ }
241
+ return lastCodeowners ?? packageMatch ?? maintainersMatch;
242
+ }
@@ -0,0 +1,2 @@
1
+ export { discoverOwnership, ownersForPath, matchCodeownersPattern, scoreOwnershipConfidence, } from "./discover.js";
2
+ export type { OwnershipDiscoveryOptions, OwnershipDiscoveryResult, OwnershipMatch, OwnershipSource, } from "./types.js";
@@ -0,0 +1 @@
1
+ export { discoverOwnership, ownersForPath, matchCodeownersPattern, scoreOwnershipConfidence, } from "./discover.js";
@@ -0,0 +1,23 @@
1
+ export type OwnershipSource = "codeowners" | "package-maintainers" | "maintainers-file";
2
+ export interface OwnershipMatch {
3
+ /** Repository-relative path or glob covered by this ownership claim. */
4
+ path: string;
5
+ /** Owner handles / emails / team refs as written in evidence. */
6
+ owners: readonly string[];
7
+ confidence: number;
8
+ evidence: readonly string[];
9
+ source: OwnershipSource;
10
+ }
11
+ export interface OwnershipDiscoveryResult {
12
+ ownerships: OwnershipMatch[];
13
+ timingMs: number;
14
+ filesConsidered: number;
15
+ /** Explicit unknowns — never invent owners. */
16
+ unknowns: string[];
17
+ }
18
+ export interface OwnershipDiscoveryOptions {
19
+ cwd?: string;
20
+ /** Optional file list (repo-relative). When omitted, discovery walks the tree. */
21
+ relativePaths?: readonly string[];
22
+ minConfidence?: number;
23
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ import type { ProjectModel } from "../model/types.js";
2
+ import type { QueryResultMap } from "./models.js";
3
+ import { Queries } from "./query.js";
4
+ import type { Query, QueryResponse } from "./types.js";
5
+ /**
6
+ * Runtime query facade over an immutable ProjectModel.
7
+ * This is the only supported read interface for future Explain/Trace/Understand/Verify/Search layers.
8
+ */
9
+ export declare class QueryEngine {
10
+ private readonly model;
11
+ constructor(model: ProjectModel);
12
+ /** Execute any supported query against the bound ProjectModel. */
13
+ execute<T extends Query>(query: T): QueryResponse<QueryResultMap[T["type"]]>;
14
+ /** Validate a raw query object without executing it. */
15
+ validate(query: unknown): Query;
16
+ supportedQueries(): readonly string[];
17
+ getModelIdentity(): {
18
+ projectName: string;
19
+ modelId: string;
20
+ schemaVersion: string;
21
+ };
22
+ }
23
+ export declare function createQueryEngine(model: ProjectModel): QueryEngine;
24
+ export { Queries };
@@ -0,0 +1,35 @@
1
+ import { executeQuery } from "./executor.js";
2
+ import { Queries, validateQuery } from "./query.js";
3
+ import { listSupportedQueryTypes } from "./registry.js";
4
+ /**
5
+ * Runtime query facade over an immutable ProjectModel.
6
+ * This is the only supported read interface for future Explain/Trace/Understand/Verify/Search layers.
7
+ */
8
+ export class QueryEngine {
9
+ model;
10
+ constructor(model) {
11
+ this.model = model;
12
+ }
13
+ /** Execute any supported query against the bound ProjectModel. */
14
+ execute(query) {
15
+ return executeQuery(this.model, query);
16
+ }
17
+ /** Validate a raw query object without executing it. */
18
+ validate(query) {
19
+ return validateQuery(query);
20
+ }
21
+ supportedQueries() {
22
+ return listSupportedQueryTypes();
23
+ }
24
+ getModelIdentity() {
25
+ return {
26
+ projectName: this.model.metadata.project.name,
27
+ modelId: this.model.metadata.id,
28
+ schemaVersion: this.model.metadata.schemaVersion,
29
+ };
30
+ }
31
+ }
32
+ export function createQueryEngine(model) {
33
+ return new QueryEngine(model);
34
+ }
35
+ export { Queries };
@@ -0,0 +1,13 @@
1
+ export declare class QueryError extends Error {
2
+ readonly code: string;
3
+ constructor(code: string, message: string);
4
+ }
5
+ export declare class QueryValidationError extends QueryError {
6
+ constructor(message: string);
7
+ }
8
+ export declare class QueryNotFoundError extends QueryError {
9
+ constructor(message: string);
10
+ }
11
+ export declare class QueryUnsupportedError extends QueryError {
12
+ constructor(message: string);
13
+ }
@@ -0,0 +1,26 @@
1
+ export class QueryError extends Error {
2
+ code;
3
+ constructor(code, message) {
4
+ super(message);
5
+ this.name = "QueryError";
6
+ this.code = code;
7
+ }
8
+ }
9
+ export class QueryValidationError extends QueryError {
10
+ constructor(message) {
11
+ super("QUERY_VALIDATION", message);
12
+ this.name = "QueryValidationError";
13
+ }
14
+ }
15
+ export class QueryNotFoundError extends QueryError {
16
+ constructor(message) {
17
+ super("QUERY_NOT_FOUND", message);
18
+ this.name = "QueryNotFoundError";
19
+ }
20
+ }
21
+ export class QueryUnsupportedError extends QueryError {
22
+ constructor(message) {
23
+ super("QUERY_UNSUPPORTED", message);
24
+ this.name = "QueryUnsupportedError";
25
+ }
26
+ }
@@ -0,0 +1,8 @@
1
+ import type { ProjectModel } from "../model/types.js";
2
+ import type { QueryResultMap } from "./models.js";
3
+ import type { Query, QueryResponse } from "./types.js";
4
+ /**
5
+ * Execute a validated query against an immutable ProjectModel.
6
+ * Pure: no I/O, no compiler passes, no model mutation.
7
+ */
8
+ export declare function executeQuery<T extends Query>(model: ProjectModel, rawQuery: T): QueryResponse<QueryResultMap[T["type"]]>;
@@ -0,0 +1,34 @@
1
+ import { QueryUnsupportedError } from "./errors.js";
2
+ import { getQueryHandler } from "./registry.js";
3
+ import { validateQuery } from "./query.js";
4
+ function buildMetadata(model, queryType) {
5
+ return {
6
+ queryType,
7
+ projectName: model.metadata.project.name,
8
+ modelId: model.metadata.id,
9
+ schemaVersion: model.metadata.schemaVersion,
10
+ compilerVersion: model.compilerMetadata.compilerVersion,
11
+ modelGeneratedAt: model.compilerMetadata.generatedAt,
12
+ };
13
+ }
14
+ /**
15
+ * Execute a validated query against an immutable ProjectModel.
16
+ * Pure: no I/O, no compiler passes, no model mutation.
17
+ */
18
+ export function executeQuery(model, rawQuery) {
19
+ const started = performance.now();
20
+ const query = validateQuery(rawQuery);
21
+ const handler = getQueryHandler(query.type);
22
+ if (!handler) {
23
+ throw new QueryUnsupportedError(`no handler registered for ${query.type}`);
24
+ }
25
+ const output = handler(query, { model });
26
+ const executionTimeMs = Math.max(0, Math.round(performance.now() - started));
27
+ return {
28
+ result: output.result,
29
+ evidence: Object.freeze([...output.evidence]),
30
+ confidence: output.confidence,
31
+ metadata: buildMetadata(model, query.type),
32
+ executionTimeMs,
33
+ };
34
+ }
@@ -0,0 +1,7 @@
1
+ export { QueryEngine, createQueryEngine, Queries } from "./engine.js";
2
+ export { executeQuery } from "./executor.js";
3
+ export { validateQuery } from "./query.js";
4
+ export { listSupportedQueryTypes } from "./registry.js";
5
+ export { QueryError, QueryValidationError, QueryNotFoundError, QueryUnsupportedError, } from "./errors.js";
6
+ export type { Query, QueryType, QueryResponse, QueryMetadata } from "./types.js";
7
+ export type { RepositorySummaryResult, ListDomainsResult, FindDomainResult, FindComponentResult, FindEvidenceResult, StatisticsResult, QueryResultMap, } from "./models.js";
@@ -0,0 +1,5 @@
1
+ export { QueryEngine, createQueryEngine, Queries } from "./engine.js";
2
+ export { executeQuery } from "./executor.js";
3
+ export { validateQuery } from "./query.js";
4
+ export { listSupportedQueryTypes } from "./registry.js";
5
+ export { QueryError, QueryValidationError, QueryNotFoundError, QueryUnsupportedError, } from "./errors.js";
@@ -0,0 +1,102 @@
1
+ import type { ProjectArchitecture, ProjectDependency, ProjectDomain, ProjectEntrypoint, ProjectModel, ProjectRelationship, ProjectStatistics, ProjectSummary } from "../model/types.js";
2
+ export interface RepositorySummaryResult {
3
+ projectName: string;
4
+ schemaVersion: string;
5
+ compilerVersion: string;
6
+ generatedAt: string;
7
+ topDomains: readonly string[];
8
+ topArchitectures: readonly string[];
9
+ frameworks: readonly string[];
10
+ statistics: ProjectStatistics;
11
+ }
12
+ export interface ListDomainsResult {
13
+ domains: readonly ProjectDomain[];
14
+ count: number;
15
+ }
16
+ export interface ListEntrypointsResult {
17
+ entrypoints: readonly ProjectEntrypoint[];
18
+ count: number;
19
+ }
20
+ export interface ListArchitecturesResult {
21
+ architectures: readonly ProjectArchitecture[];
22
+ count: number;
23
+ }
24
+ export interface ListRelationshipsResult {
25
+ relationships: readonly ProjectRelationship[];
26
+ count: number;
27
+ }
28
+ export interface ListDependenciesResult {
29
+ dependencies: readonly ProjectDependency[];
30
+ count: number;
31
+ }
32
+ export interface FindDomainResult {
33
+ domain: ProjectDomain;
34
+ entrypoints: readonly ProjectEntrypoint[];
35
+ relationships: readonly ProjectRelationship[];
36
+ dependencies: readonly ProjectDependency[];
37
+ architectures: readonly ProjectArchitecture[];
38
+ }
39
+ export interface FindEntrypointResult {
40
+ entrypoint: ProjectEntrypoint;
41
+ }
42
+ export interface FindArchitectureResult {
43
+ architecture: ProjectArchitecture;
44
+ }
45
+ export interface FindComponentResult {
46
+ name: string;
47
+ asRelationshipSource: readonly ProjectRelationship[];
48
+ asRelationshipTarget: readonly ProjectRelationship[];
49
+ asDependencyEndpoint: readonly ProjectDependency[];
50
+ matchingEntrypoints: readonly ProjectEntrypoint[];
51
+ matchingDomains: readonly ProjectDomain[];
52
+ }
53
+ export interface FindRelationshipResult {
54
+ relationship: ProjectRelationship;
55
+ }
56
+ export interface FindDependencyResult {
57
+ dependency: ProjectDependency;
58
+ }
59
+ export interface EvidenceHit {
60
+ collection: "domains" | "entrypoints" | "dependencies" | "relationships" | "architectures" | "metadata";
61
+ id: string;
62
+ label: string;
63
+ evidence: readonly string[];
64
+ }
65
+ export interface FindEvidenceResult {
66
+ needle: string;
67
+ hits: readonly EvidenceHit[];
68
+ count: number;
69
+ }
70
+ export interface StatisticsResult {
71
+ summary: ProjectSummary;
72
+ model: {
73
+ projectName: string;
74
+ schemaVersion: string;
75
+ compilerVersion: string;
76
+ generatedAt: string;
77
+ };
78
+ }
79
+ export type QueryResultMap = {
80
+ RepositorySummary: RepositorySummaryResult;
81
+ ListDomains: ListDomainsResult;
82
+ ListEntrypoints: ListEntrypointsResult;
83
+ ListArchitectures: ListArchitecturesResult;
84
+ ListRelationships: ListRelationshipsResult;
85
+ ListDependencies: ListDependenciesResult;
86
+ FindDomain: FindDomainResult;
87
+ FindEntrypoint: FindEntrypointResult;
88
+ FindArchitecture: FindArchitectureResult;
89
+ FindComponent: FindComponentResult;
90
+ FindRelationship: FindRelationshipResult;
91
+ FindDependency: FindDependencyResult;
92
+ FindEvidence: FindEvidenceResult;
93
+ Statistics: StatisticsResult;
94
+ };
95
+ export interface QueryHandlerContext {
96
+ model: ProjectModel;
97
+ }
98
+ export interface QueryHandlerOutput<T> {
99
+ result: T;
100
+ evidence: string[];
101
+ confidence: number;
102
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,68 @@
1
+ import type { Query } from "./types.js";
2
+ /**
3
+ * Validate and normalize a raw query object into a typed Query.
4
+ */
5
+ export declare function validateQuery(input: unknown): Query;
6
+ /** Typed query constructors (internal ergonomics). */
7
+ export declare const Queries: {
8
+ readonly repositorySummary: () => {
9
+ type: "RepositorySummary";
10
+ };
11
+ readonly listDomains: () => {
12
+ type: "ListDomains";
13
+ };
14
+ readonly listEntrypoints: () => {
15
+ type: "ListEntrypoints";
16
+ };
17
+ readonly listArchitectures: () => {
18
+ type: "ListArchitectures";
19
+ };
20
+ readonly listRelationships: () => {
21
+ type: "ListRelationships";
22
+ };
23
+ readonly listDependencies: () => {
24
+ type: "ListDependencies";
25
+ };
26
+ readonly findDomain: (name: string) => {
27
+ type: "FindDomain";
28
+ name: string;
29
+ };
30
+ readonly findEntrypoint: (options: {
31
+ file?: string;
32
+ framework?: string;
33
+ id?: string;
34
+ }) => {
35
+ type: "FindEntrypoint";
36
+ };
37
+ readonly findArchitecture: (pattern: string) => {
38
+ type: "FindArchitecture";
39
+ pattern: string;
40
+ };
41
+ readonly findComponent: (name: string) => {
42
+ type: "FindComponent";
43
+ name: string;
44
+ };
45
+ readonly findRelationship: (options: {
46
+ source?: string;
47
+ target?: string;
48
+ relationship?: string;
49
+ id?: string;
50
+ }) => {
51
+ type: "FindRelationship";
52
+ };
53
+ readonly findDependency: (options: {
54
+ from?: string;
55
+ to?: string;
56
+ dependencyType?: string;
57
+ id?: string;
58
+ }) => {
59
+ type: "FindDependency";
60
+ };
61
+ readonly findEvidence: (needle: string) => {
62
+ type: "FindEvidence";
63
+ needle: string;
64
+ };
65
+ readonly statistics: () => {
66
+ type: "Statistics";
67
+ };
68
+ };