@monoes/monograph 1.4.0 → 1.4.1

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 (228) hide show
  1. package/dist/src/analysis/benchmark.js.map +1 -1
  2. package/dist/src/analysis/changed-files.d.ts.map +1 -1
  3. package/dist/src/analysis/changed-files.js +11 -2
  4. package/dist/src/analysis/changed-files.js.map +1 -1
  5. package/dist/src/analysis/changed-workspaces.d.ts.map +1 -1
  6. package/dist/src/analysis/changed-workspaces.js +11 -3
  7. package/dist/src/analysis/changed-workspaces.js.map +1 -1
  8. package/dist/src/analysis/churn.d.ts +1 -1
  9. package/dist/src/analysis/churn.d.ts.map +1 -1
  10. package/dist/src/analysis/churn.js +56 -10
  11. package/dist/src/analysis/churn.js.map +1 -1
  12. package/dist/src/analysis/feature-flags.d.ts.map +1 -1
  13. package/dist/src/analysis/feature-flags.js +11 -5
  14. package/dist/src/analysis/feature-flags.js.map +1 -1
  15. package/dist/src/analysis/progress.d.ts.map +1 -1
  16. package/dist/src/analysis/project-state.d.ts.map +1 -1
  17. package/dist/src/analysis/shape-extractor.js.map +1 -1
  18. package/dist/src/analysis/suppression-context.d.ts.map +1 -1
  19. package/dist/src/analysis/surprise-scorer.js.map +1 -1
  20. package/dist/src/analysis/targets.d.ts.map +1 -1
  21. package/dist/src/analysis/worker-pool.d.ts.map +1 -1
  22. package/dist/src/analysis/worker-pool.js.map +1 -1
  23. package/dist/src/analyze/unused-deps.js.map +1 -1
  24. package/dist/src/analyze/unused-exports.js.map +1 -1
  25. package/dist/src/analyze/unused-files.js.map +1 -1
  26. package/dist/src/cache/augment-cache.js.map +1 -1
  27. package/dist/src/cache/extraction-cache.d.ts +21 -0
  28. package/dist/src/cache/extraction-cache.d.ts.map +1 -1
  29. package/dist/src/cache/extraction-cache.js +62 -6
  30. package/dist/src/cache/extraction-cache.js.map +1 -1
  31. package/dist/src/check/index.js.map +1 -1
  32. package/dist/src/cli/check-update.js.map +1 -1
  33. package/dist/src/cli/doctor.d.ts.map +1 -1
  34. package/dist/src/cli/doctor.js +6 -10
  35. package/dist/src/cli/doctor.js.map +1 -1
  36. package/dist/src/config/boundary-config.js.map +1 -1
  37. package/dist/src/config/config-parsing.d.ts +1 -1
  38. package/dist/src/config/config-parsing.d.ts.map +1 -1
  39. package/dist/src/config/migration-types.d.ts +2 -2
  40. package/dist/src/config/migration-types.d.ts.map +1 -1
  41. package/dist/src/config/migration-types.js.map +1 -1
  42. package/dist/src/config/used-class-members.js.map +1 -1
  43. package/dist/src/config/workspace.js.map +1 -1
  44. package/dist/src/coverage/upload-source-maps.js.map +1 -1
  45. package/dist/src/duplicates/detect/filtering.d.ts.map +1 -1
  46. package/dist/src/duplicates/shingle-filter.js.map +1 -1
  47. package/dist/src/error/fallow-error.d.ts.map +1 -1
  48. package/dist/src/error/fallow-error.js.map +1 -1
  49. package/dist/src/error.d.ts.map +1 -1
  50. package/dist/src/error.js.map +1 -1
  51. package/dist/src/export/analysis-json.js.map +1 -1
  52. package/dist/src/export/badge.js.map +1 -1
  53. package/dist/src/export/dot.js.map +1 -1
  54. package/dist/src/export/sarif.js.map +1 -1
  55. package/dist/src/fix/orchestrator.js.map +1 -1
  56. package/dist/src/graph/cycle-detection.js.map +1 -1
  57. package/dist/src/graph/dead-code.d.ts +7 -2
  58. package/dist/src/graph/dead-code.d.ts.map +1 -1
  59. package/dist/src/graph/dead-code.js +19 -16
  60. package/dist/src/graph/dead-code.js.map +1 -1
  61. package/dist/src/graph/dfs.js.map +1 -1
  62. package/dist/src/graph/edge-filter.js.map +1 -1
  63. package/dist/src/graph/hotspots.js.map +1 -1
  64. package/dist/src/graph/import-chain.js.map +1 -1
  65. package/dist/src/graph/merge.js.map +1 -1
  66. package/dist/src/graph/node-search.js.map +1 -1
  67. package/dist/src/graph/node-types.d.ts.map +1 -1
  68. package/dist/src/graph/pagerank.d.ts.map +1 -1
  69. package/dist/src/graph/pagerank.js +10 -1
  70. package/dist/src/graph/pagerank.js.map +1 -1
  71. package/dist/src/graph/regex-search.js.map +1 -1
  72. package/dist/src/graph/regression.d.ts.map +1 -1
  73. package/dist/src/graph/resolve/discover-types.js.map +1 -1
  74. package/dist/src/graph/resolve/types.d.ts +3 -3
  75. package/dist/src/graph/resolve/types.d.ts.map +1 -1
  76. package/dist/src/groups/group-search.d.ts.map +1 -1
  77. package/dist/src/groups/group-search.js +9 -18
  78. package/dist/src/groups/group-search.js.map +1 -1
  79. package/dist/src/health/complexity-findings.js.map +1 -1
  80. package/dist/src/health/grouping.js.map +1 -1
  81. package/dist/src/health/health-report-types.js.map +1 -1
  82. package/dist/src/health/health-report.js.map +1 -1
  83. package/dist/src/health/targets.js.map +1 -1
  84. package/dist/src/ingest/transcribe.js.map +1 -1
  85. package/dist/src/ingest/url-ingest.js.map +1 -1
  86. package/dist/src/license/manager.d.ts.map +1 -1
  87. package/dist/src/license/manager.js.map +1 -1
  88. package/dist/src/lsp/diagnostics-push.js.map +1 -1
  89. package/dist/src/mcp-tools/impact.d.ts.map +1 -1
  90. package/dist/src/mcp-tools/impact.js +7 -1
  91. package/dist/src/mcp-tools/impact.js.map +1 -1
  92. package/dist/src/mcp-tools/list-repos.d.ts +1 -1
  93. package/dist/src/mcp-tools/list-repos.d.ts.map +1 -1
  94. package/dist/src/mcp-tools/query.d.ts +1 -1
  95. package/dist/src/mcp-tools/query.d.ts.map +1 -1
  96. package/dist/src/parsers/c.js.map +1 -1
  97. package/dist/src/parsers/cpp.js.map +1 -1
  98. package/dist/src/parsers/csharp.js.map +1 -1
  99. package/dist/src/parsers/dart.js.map +1 -1
  100. package/dist/src/parsers/go.js.map +1 -1
  101. package/dist/src/parsers/java.js.map +1 -1
  102. package/dist/src/parsers/kotlin.js.map +1 -1
  103. package/dist/src/parsers/loader.js.map +1 -1
  104. package/dist/src/parsers/php.js.map +1 -1
  105. package/dist/src/parsers/python.js.map +1 -1
  106. package/dist/src/parsers/ruby.js.map +1 -1
  107. package/dist/src/parsers/rust.js.map +1 -1
  108. package/dist/src/parsers/swift.js.map +1 -1
  109. package/dist/src/parsers/typescript.js.map +1 -1
  110. package/dist/src/parsers/vue.js.map +1 -1
  111. package/dist/src/pipeline/effort.js.map +1 -1
  112. package/dist/src/pipeline/orchestrator.d.ts.map +1 -1
  113. package/dist/src/pipeline/orchestrator.js +48 -24
  114. package/dist/src/pipeline/orchestrator.js.map +1 -1
  115. package/dist/src/pipeline/phases/bridge-adapters/electron-ipc.d.ts +11 -0
  116. package/dist/src/pipeline/phases/bridge-adapters/electron-ipc.d.ts.map +1 -0
  117. package/dist/src/pipeline/phases/bridge-adapters/electron-ipc.js +96 -0
  118. package/dist/src/pipeline/phases/bridge-adapters/electron-ipc.js.map +1 -0
  119. package/dist/src/pipeline/phases/bridge-adapters/registry.d.ts +3 -0
  120. package/dist/src/pipeline/phases/bridge-adapters/registry.d.ts.map +1 -0
  121. package/dist/src/pipeline/phases/bridge-adapters/registry.js +13 -0
  122. package/dist/src/pipeline/phases/bridge-adapters/registry.js.map +1 -0
  123. package/dist/src/pipeline/phases/bridge-adapters/tauri.d.ts +10 -0
  124. package/dist/src/pipeline/phases/bridge-adapters/tauri.d.ts.map +1 -0
  125. package/dist/src/pipeline/phases/bridge-adapters/tauri.js +104 -0
  126. package/dist/src/pipeline/phases/bridge-adapters/tauri.js.map +1 -0
  127. package/dist/src/pipeline/phases/bridge-adapters/types.d.ts +30 -0
  128. package/dist/src/pipeline/phases/bridge-adapters/types.d.ts.map +1 -0
  129. package/dist/src/pipeline/phases/bridge-adapters/types.js +2 -0
  130. package/dist/src/pipeline/phases/bridge-adapters/types.js.map +1 -0
  131. package/dist/src/pipeline/phases/bridge-adapters/wails.d.ts +10 -0
  132. package/dist/src/pipeline/phases/bridge-adapters/wails.d.ts.map +1 -0
  133. package/dist/src/pipeline/phases/bridge-adapters/wails.js +27 -0
  134. package/dist/src/pipeline/phases/bridge-adapters/wails.js.map +1 -0
  135. package/dist/src/pipeline/phases/bridge-resolver.d.ts +23 -0
  136. package/dist/src/pipeline/phases/bridge-resolver.d.ts.map +1 -0
  137. package/dist/src/pipeline/phases/bridge-resolver.js +70 -0
  138. package/dist/src/pipeline/phases/bridge-resolver.js.map +1 -0
  139. package/dist/src/pipeline/phases/cross-file.d.ts.map +1 -1
  140. package/dist/src/pipeline/phases/cross-file.js +70 -27
  141. package/dist/src/pipeline/phases/cross-file.js.map +1 -1
  142. package/dist/src/pipeline/phases/leiden.js.map +1 -1
  143. package/dist/src/pipeline/phases/parse.d.ts.map +1 -1
  144. package/dist/src/pipeline/phases/parse.js +58 -17
  145. package/dist/src/pipeline/phases/parse.js.map +1 -1
  146. package/dist/src/pipeline/phases/scan.d.ts.map +1 -1
  147. package/dist/src/pipeline/phases/scan.js +12 -5
  148. package/dist/src/pipeline/phases/scan.js.map +1 -1
  149. package/dist/src/pipeline/phases/scope-resolution.d.ts +13 -0
  150. package/dist/src/pipeline/phases/scope-resolution.d.ts.map +1 -1
  151. package/dist/src/pipeline/phases/scope-resolution.js +18 -4
  152. package/dist/src/pipeline/phases/scope-resolution.js.map +1 -1
  153. package/dist/src/pipeline/progress.d.ts.map +1 -1
  154. package/dist/src/pipeline/runner.d.ts.map +1 -1
  155. package/dist/src/pipeline/runner.js.map +1 -1
  156. package/dist/src/pipeline/types.d.ts +2 -0
  157. package/dist/src/pipeline/types.d.ts.map +1 -1
  158. package/dist/src/pipeline/types.js +1 -0
  159. package/dist/src/pipeline/types.js.map +1 -1
  160. package/dist/src/regression/baseline.js.map +1 -1
  161. package/dist/src/regression/outcome.js.map +1 -1
  162. package/dist/src/report/badge-svg.js.map +1 -1
  163. package/dist/src/report/duplication-grouping.js.map +1 -1
  164. package/dist/src/report/human-check.js.map +1 -1
  165. package/dist/src/report/human-dupes.js.map +1 -1
  166. package/dist/src/report/human-health.js.map +1 -1
  167. package/dist/src/report/json-builders.js.map +1 -1
  168. package/dist/src/report/number-format.js.map +1 -1
  169. package/dist/src/reporting/graph-report.js.map +1 -1
  170. package/dist/src/scope-resolution/evidence-weights.d.ts.map +1 -1
  171. package/dist/src/search/hybrid-query.js.map +1 -1
  172. package/dist/src/security/safe-fetch.js.map +1 -1
  173. package/dist/src/storage/db.d.ts +13 -1
  174. package/dist/src/storage/db.d.ts.map +1 -1
  175. package/dist/src/storage/db.js +17 -1
  176. package/dist/src/storage/db.js.map +1 -1
  177. package/dist/src/storage/edge-store.d.ts +6 -0
  178. package/dist/src/storage/edge-store.d.ts.map +1 -1
  179. package/dist/src/storage/edge-store.js +8 -1
  180. package/dist/src/storage/edge-store.js.map +1 -1
  181. package/dist/src/storage/fts-store.d.ts.map +1 -1
  182. package/dist/src/storage/fts-store.js +31 -9
  183. package/dist/src/storage/fts-store.js.map +1 -1
  184. package/dist/src/storage/node-store.js.map +1 -1
  185. package/dist/src/storage/unlinked-refs.js.map +1 -1
  186. package/dist/src/types.d.ts +2 -2
  187. package/dist/src/types.d.ts.map +1 -1
  188. package/dist/src/types.js.map +1 -1
  189. package/dist/src/watch/watcher.d.ts.map +1 -1
  190. package/dist/src/watch/watcher.js +12 -2
  191. package/dist/src/watch/watcher.js.map +1 -1
  192. package/dist/src/web/analyze-api.js.map +1 -1
  193. package/dist/src/web/api.js.map +1 -1
  194. package/dist/src/wiki/providers.js.map +1 -1
  195. package/dist/tsconfig.tsbuildinfo +1 -1
  196. package/package.json +5 -2
  197. package/src/__tests__/graph/dead-code.test.ts +27 -7
  198. package/src/__tests__/pipeline/phases/bridge-adapters/electron-ipc.test.ts +87 -0
  199. package/src/__tests__/pipeline/phases/bridge-adapters/tauri.test.ts +116 -0
  200. package/src/__tests__/pipeline/phases/bridge-adapters/wails.test.ts +81 -0
  201. package/src/__tests__/pipeline/phases/bridge-resolver.test.ts +110 -0
  202. package/src/analysis/changed-files.ts +14 -2
  203. package/src/analysis/changed-workspaces.ts +13 -4
  204. package/src/analysis/churn.ts +57 -10
  205. package/src/analysis/feature-flags.ts +10 -5
  206. package/src/cache/extraction-cache.ts +59 -6
  207. package/src/cli/doctor.ts +6 -10
  208. package/src/graph/dead-code.ts +19 -16
  209. package/src/graph/pagerank.ts +10 -1
  210. package/src/groups/group-search.ts +9 -27
  211. package/src/mcp-tools/impact.ts +7 -1
  212. package/src/pipeline/orchestrator.ts +50 -26
  213. package/src/pipeline/phases/bridge-adapters/electron-ipc.ts +91 -0
  214. package/src/pipeline/phases/bridge-adapters/registry.ts +14 -0
  215. package/src/pipeline/phases/bridge-adapters/tauri.ts +103 -0
  216. package/src/pipeline/phases/bridge-adapters/types.ts +31 -0
  217. package/src/pipeline/phases/bridge-adapters/wails.ts +33 -0
  218. package/src/pipeline/phases/bridge-resolver.ts +77 -0
  219. package/src/pipeline/phases/cross-file.ts +75 -27
  220. package/src/pipeline/phases/parse.ts +60 -17
  221. package/src/pipeline/phases/scan.ts +11 -5
  222. package/src/pipeline/phases/scope-resolution.ts +19 -4
  223. package/src/pipeline/types.ts +3 -0
  224. package/src/storage/db.ts +27 -1
  225. package/src/storage/edge-store.ts +8 -1
  226. package/src/storage/fts-store.ts +31 -9
  227. package/src/watch/watcher.ts +11 -2
  228. package/tsconfig.json +2 -1
@@ -73,10 +73,17 @@ export function getEdgesForTarget(db: Database.Database, targetId: string): Mono
73
73
  return rows.map(rowToEdge);
74
74
  }
75
75
 
76
+ /**
77
+ * Delete every edge that touches a node belonging to `filePath`, on either end.
78
+ * Must be called BEFORE the corresponding nodes are deleted (the subselects need
79
+ * the file's nodes to still exist to identify which edges to remove) — e.g.
80
+ * `deleteEdgesForFile` then `deleteNodesForFile`, never the reverse.
81
+ */
76
82
  export function deleteEdgesForFile(db: Database.Database, filePath: string): void {
77
83
  db.prepare(`
78
84
  DELETE FROM edges WHERE source_id IN (SELECT id FROM nodes WHERE file_path = ?)
79
- `).run(filePath);
85
+ OR target_id IN (SELECT id FROM nodes WHERE file_path = ?)
86
+ `).run(filePath, filePath);
80
87
  }
81
88
 
82
89
  export function countEdges(db: Database.Database): number {
@@ -13,6 +13,20 @@ export interface FtsResult {
13
13
  endLine: number | null;
14
14
  }
15
15
 
16
+ /**
17
+ * Quote a single FTS5 search term as a string literal when it contains characters
18
+ * that would otherwise be parsed as FTS5 syntax (quotes, parens, boolean keywords
19
+ * like AND/OR/NOT, colons, hyphens, etc). Wrapping in double-quotes forces FTS5 to
20
+ * treat the term as a literal string; any literal `"` inside the term is escaped by
21
+ * doubling it, per FTS5's own string-literal quoting rules.
22
+ */
23
+ function quoteFtsTerm(term: string): string {
24
+ // Bare alphanumeric/underscore terms need no quoting and are the common case.
25
+ if (/^[A-Za-z0-9_]+$/.test(term)) return term;
26
+ const escaped = term.replace(/"/g, '""');
27
+ return `"${escaped}"`;
28
+ }
29
+
16
30
  export function ftsSearch(
17
31
  db: Database.Database,
18
32
  query: string,
@@ -24,8 +38,13 @@ export function ftsSearch(
24
38
  const safeQuery = query.replace(/[*]/g, ' ').trim();
25
39
  if (!safeQuery) return [];
26
40
 
27
- // Trigram handles substring matching natively — no need to append * to each term
28
- const ftsQuery = safeQuery.split(/\s+/).join(' ');
41
+ // Trigram handles substring matching natively — no need to append * to each term.
42
+ // Quote each term individually so characters like `"`, `(`, `)`, or bare boolean
43
+ // keywords (AND/OR/NOT) don't get parsed as FTS5 query syntax.
44
+ const ftsQuery = safeQuery
45
+ .split(/\s+/)
46
+ .map(quoteFtsTerm)
47
+ .join(' ');
29
48
 
30
49
  let matchSql = `
31
50
  SELECT n.id, n.name, n.norm_label, n.file_path, n.label,
@@ -52,16 +71,19 @@ export function ftsSearch(
52
71
  // FTS MATCH can throw on malformed queries; fall through to LIKE path
53
72
  }
54
73
 
55
- // For short queries (≤2 chars) trigram requires at least 3 characters to fire, so
56
- // supplement with a LIKE fallback to catch single/double-character matches.
57
- if (safeQuery.length <= 2) {
58
- const escapedQuery = safeQuery.replace(/%/g, '\\%').replace(/_/g, '\\_');
74
+ // Run the LIKE fallback whenever MATCH threw (malformed/boolean-keyword query) or
75
+ // returned zero rows not just for short (≤2 char) queries. Short queries need it
76
+ // because trigram requires ≥3 characters to fire; longer queries need it whenever
77
+ // MATCH couldn't handle the syntax, so a query-syntax failure doesn't silently read
78
+ // as "no results".
79
+ if (safeQuery.length <= 2 || matchRows.length === 0) {
80
+ const escapedQuery = safeQuery.replace(/\\/g, '\\\\').replace(/%/g, '\\%').replace(/_/g, '\\_');
59
81
  const likePattern = `%${escapedQuery}%`;
60
82
  let likeSql = `
61
83
  SELECT n.id, n.name, n.norm_label, n.file_path, n.label,
62
84
  n.start_line, n.end_line, 0 AS rank
63
85
  FROM nodes n
64
- WHERE (n.name LIKE ? OR n.norm_label LIKE ? OR n.file_path LIKE ?)
86
+ WHERE (n.name LIKE ? ESCAPE '\\' OR n.norm_label LIKE ? ESCAPE '\\' OR n.file_path LIKE ? ESCAPE '\\')
65
87
  `;
66
88
  const likeParams: unknown[] = [likePattern, likePattern, likePattern];
67
89
  if (label) {
@@ -186,13 +208,13 @@ export function hybridSearch(
186
208
  // ── Strategy 2: LIKE fallback ──────────────────────────────────────────────
187
209
  // Always run for short queries (≤3 chars) or when FTS returned nothing.
188
210
  if (safeQuery.length <= 3 || ftsRows.length === 0) {
189
- const escapedSafeQuery = safeQuery.replace(/%/g, '\\%').replace(/_/g, '\\_');
211
+ const escapedSafeQuery = safeQuery.replace(/\\/g, '\\\\').replace(/%/g, '\\%').replace(/_/g, '\\_');
190
212
  const likePattern = `%${escapedSafeQuery}%`;
191
213
  let likeSql = `
192
214
  SELECT n.id, n.name, n.norm_label, n.file_path, n.label,
193
215
  n.start_line, n.end_line
194
216
  FROM nodes n
195
- WHERE (n.name LIKE ? OR n.norm_label LIKE ?)
217
+ WHERE (n.name LIKE ? ESCAPE '\\' OR n.norm_label LIKE ? ESCAPE '\\')
196
218
  `;
197
219
  const likeParams: unknown[] = [likePattern, likePattern];
198
220
  if (label) {
@@ -34,8 +34,17 @@ export async function watchAsync(
34
34
  do {
35
35
  rerun = false;
36
36
  opts.onProgress?.({ phase: 'watch', message: `Changed: ${files.slice(0, 3).join(', ')}` });
37
- await buildAsync(repoPath, { onProgress: opts.onProgress, force: opts.force, codeOnly: opts.codeOnly, llmMaxSections: opts.llmMaxSections ?? 0 });
38
- opts.onProgress?.({ phase: 'watch', message: 'Graph rebuilt.' });
37
+ try {
38
+ await buildAsync(repoPath, { onProgress: opts.onProgress, force: opts.force, codeOnly: opts.codeOnly, llmMaxSections: opts.llmMaxSections ?? 0 });
39
+ opts.onProgress?.({ phase: 'watch', message: 'Graph rebuilt.' });
40
+ } catch (err) {
41
+ // A rebuild failure (locked DB past busy_timeout, disk full, transient
42
+ // I/O error) must not crash the watch process — log it, notify listeners,
43
+ // and keep watching for the next change instead of letting an unhandled
44
+ // rejection escape this listener.
45
+ watcher.emit('monograph:error', err);
46
+ opts.onProgress?.({ phase: 'watch', message: `Rebuild failed: ${err instanceof Error ? err.message : String(err)}` });
47
+ }
39
48
  } while (rerun);
40
49
  } finally {
41
50
  building = false;
package/tsconfig.json CHANGED
@@ -3,7 +3,8 @@
3
3
  "compilerOptions": {
4
4
  "outDir": "dist",
5
5
  "rootDir": ".",
6
- "composite": true
6
+ "composite": true,
7
+ "types": ["node", "better-sqlite3", "express", "micromatch"]
7
8
  },
8
9
  "include": ["src/**/*.ts"],
9
10
  "exclude": ["node_modules", "dist", "__tests__", "src/**/__tests__/**", "src/**/*.test.ts", "src/**/*.spec.ts"]