@unerr-ai/unerr 0.1.0 → 0.1.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 (553) hide show
  1. package/dist/__tests__/architecture-guard.test.js +122 -0
  2. package/dist/__tests__/arg-validator.test.js +205 -0
  3. package/dist/__tests__/ast-extractor.test.js +203 -0
  4. package/dist/__tests__/auto-bootstrap.test.js +280 -0
  5. package/dist/__tests__/background-indexer.test.js +228 -0
  6. package/dist/__tests__/blast-radius-engine.test.js +200 -0
  7. package/dist/__tests__/bridge-isolation.test.js +37 -0
  8. package/dist/__tests__/budget-enforcer.test.js +53 -0
  9. package/dist/__tests__/cfg-test-detection-perf.test.js +82 -0
  10. package/dist/__tests__/change-narrative.test.js +190 -0
  11. package/dist/__tests__/check-commit.test.js +258 -0
  12. package/dist/__tests__/checksum.test.js +34 -0
  13. package/dist/__tests__/commit-watcher.test.js +154 -0
  14. package/dist/__tests__/community-detection.test.js +179 -0
  15. package/dist/__tests__/community-tools.test.js +299 -0
  16. package/dist/__tests__/components.test.js +449 -0
  17. package/dist/__tests__/compression-log.test.js +174 -0
  18. package/dist/__tests__/compression-quality-monitor.test.js +40 -0
  19. package/dist/__tests__/config-healer.test.js +165 -0
  20. package/dist/__tests__/context-ledger.test.js +58 -0
  21. package/dist/__tests__/convention-detector.test.js +99 -0
  22. package/dist/__tests__/convention-learner.test.js +86 -0
  23. package/dist/__tests__/correction-detector.test.js +330 -0
  24. package/dist/__tests__/daemon-autostart-install.test.js +283 -0
  25. package/dist/__tests__/daemon-bridge.test.js +222 -0
  26. package/dist/__tests__/daemon-dashboard.test.js +202 -0
  27. package/dist/__tests__/daemon-registry.test.js +240 -0
  28. package/dist/__tests__/daemon-supervisor.test.js +318 -0
  29. package/dist/__tests__/daemon-version-check.test.js +275 -0
  30. package/dist/__tests__/decision-point-detector.test.js +98 -0
  31. package/dist/__tests__/deep-link.test.js +143 -0
  32. package/dist/__tests__/disallowed-tools.test.js +115 -0
  33. package/dist/__tests__/drift-tracker.test.js +582 -0
  34. package/dist/__tests__/durability-scorer.test.js +152 -0
  35. package/dist/__tests__/efficiency-tracker.test.js +65 -0
  36. package/dist/__tests__/enrich.test.js +144 -0
  37. package/dist/__tests__/entity-rewind.test.js +248 -0
  38. package/dist/__tests__/ephemeral.test.js +111 -0
  39. package/dist/__tests__/exploration-cost.test.js +93 -0
  40. package/dist/__tests__/fact-generator.test.js +197 -0
  41. package/dist/__tests__/file-l0-graph.test.js +244 -0
  42. package/dist/__tests__/file-logger.test.js +82 -0
  43. package/dist/__tests__/file-outline.test.js +141 -0
  44. package/dist/__tests__/file-read-protocol.test.js +188 -0
  45. package/dist/__tests__/format-encoder.test.js +233 -0
  46. package/dist/__tests__/git-attribution.test.js +259 -0
  47. package/dist/__tests__/graph-temporal-joiner.test.js +219 -0
  48. package/dist/__tests__/health-grade-enhanced.test.js +138 -0
  49. package/dist/__tests__/health-map-data.test.js +173 -0
  50. package/dist/__tests__/helpers/mcp-harness.js +45 -0
  51. package/dist/__tests__/helpers/mcp-harness.test.js +68 -0
  52. package/dist/__tests__/hook-dedup.test.js +112 -0
  53. package/dist/__tests__/hook-runner.test.js +253 -0
  54. package/dist/__tests__/indexer-cfg.test.js +185 -0
  55. package/dist/__tests__/indexer-cross-file.test.js +172 -0
  56. package/dist/__tests__/indexer-extraction.test.js +245 -0
  57. package/dist/__tests__/indexer-incremental.test.js +232 -0
  58. package/dist/__tests__/indexer-language-expansion.test.js +165 -0
  59. package/dist/__tests__/init-push.test.js +131 -0
  60. package/dist/__tests__/instruction-writer.test.js +179 -0
  61. package/dist/__tests__/intelligence-integration.test.js +217 -0
  62. package/dist/__tests__/intent-correlator.test.js +175 -0
  63. package/dist/__tests__/intent-detector.test.js +235 -0
  64. package/dist/__tests__/intent-encoder.test.js +167 -0
  65. package/dist/__tests__/java-build-tool-detection.test.js +174 -0
  66. package/dist/__tests__/layer3-sprint-q.test.js +160 -0
  67. package/dist/__tests__/layer3-sprint-r.test.js +91 -0
  68. package/dist/__tests__/layer3-sprint-s.test.js +183 -0
  69. package/dist/__tests__/layer3-sprint-t.test.js +201 -0
  70. package/dist/__tests__/layer3-sprint-u.test.js +174 -0
  71. package/dist/__tests__/layer4-sprint-ba2.test.js +354 -0
  72. package/dist/__tests__/layer4-sprint-ba4.test.js +84 -0
  73. package/dist/__tests__/layer4-sprint-vs.test.js +105 -0
  74. package/dist/__tests__/ledger-chains.test.js +162 -0
  75. package/dist/__tests__/lifecycle-machine.test.js +226 -0
  76. package/dist/__tests__/local-chat-provider.test.js +170 -0
  77. package/dist/__tests__/local-convention-detector.test.js +308 -0
  78. package/dist/__tests__/local-embeddings.test.js +422 -0
  79. package/dist/__tests__/local-graph.test.js +540 -0
  80. package/dist/__tests__/local-indexer.test.js +228 -0
  81. package/dist/__tests__/local-intelligence-l3.test.js +332 -0
  82. package/dist/__tests__/local-llm.test.js +253 -0
  83. package/dist/__tests__/local-mode-offline.test.js +187 -0
  84. package/dist/__tests__/local-mode-stats.test.js +273 -0
  85. package/dist/__tests__/local-mode-tui.test.js +343 -0
  86. package/dist/__tests__/local-parse.test.js +199 -0
  87. package/dist/__tests__/log-tailer.test.js +208 -0
  88. package/dist/__tests__/loop-breaker.test.js +276 -0
  89. package/dist/__tests__/loop-miner.test.js +226 -0
  90. package/dist/__tests__/mcp-config.test.js +126 -0
  91. package/dist/__tests__/mcp-content-json.test.js +10 -0
  92. package/dist/__tests__/mcp-envelope.test.js +124 -0
  93. package/dist/__tests__/metrics-store.test.js +223 -0
  94. package/dist/__tests__/native-watcher.test.js +191 -0
  95. package/dist/__tests__/navigation-hooks-agent-aware.test.js +145 -0
  96. package/dist/__tests__/negative-knowledge.test.js +116 -0
  97. package/dist/__tests__/network-boundary.test.js +190 -0
  98. package/dist/__tests__/network-firewall.test.js +112 -0
  99. package/dist/__tests__/nudge-invariants.test.js +160 -0
  100. package/dist/__tests__/nudge-v2.test.js +225 -0
  101. package/dist/__tests__/offline-rewind.test.js +251 -0
  102. package/dist/__tests__/open-threads.test.js +89 -0
  103. package/dist/__tests__/output-compressor.test.js +93 -0
  104. package/dist/__tests__/pending-violations.test.js +112 -0
  105. package/dist/__tests__/persistence-effectiveness.test.js +143 -0
  106. package/dist/__tests__/provider-factory.test.js +42 -0
  107. package/dist/__tests__/providers.test.js +24 -0
  108. package/dist/__tests__/proxy.test.js +314 -0
  109. package/dist/__tests__/query-router.test.js +1018 -0
  110. package/dist/__tests__/reasoning-quality-route.test.js +138 -0
  111. package/dist/__tests__/redactor.test.js +120 -0
  112. package/dist/__tests__/resource-monitor.test.js +57 -0
  113. package/dist/__tests__/response-envelope.test.js +100 -0
  114. package/dist/__tests__/risk-classifier.test.js +101 -0
  115. package/dist/__tests__/risk-signal-scope.test.js +75 -0
  116. package/dist/__tests__/rule-evaluator.test.js +280 -0
  117. package/dist/__tests__/scip-decoder.test.js +49 -0
  118. package/dist/__tests__/scip-downloader.test.js +201 -0
  119. package/dist/__tests__/scip-merger.test.js +103 -0
  120. package/dist/__tests__/search-index.test.js +422 -0
  121. package/dist/__tests__/semantic-enrichment.test.js +360 -0
  122. package/dist/__tests__/session-brief-builder.test.js +187 -0
  123. package/dist/__tests__/session-context.test.js +221 -0
  124. package/dist/__tests__/session-continuity.test.js +144 -0
  125. package/dist/__tests__/session-dedup.test.js +74 -0
  126. package/dist/__tests__/session-event-wiring.test.js +206 -0
  127. package/dist/__tests__/session-events.test.js +149 -0
  128. package/dist/__tests__/session-legend.test.js +20 -0
  129. package/dist/__tests__/session-persistence.test.js +131 -0
  130. package/dist/__tests__/session-resume-block.test.js +107 -0
  131. package/dist/__tests__/session-resume.test.js +97 -0
  132. package/dist/__tests__/session-summary-writer.test.js +134 -0
  133. package/dist/__tests__/shadow-ledger.test.js +203 -0
  134. package/dist/__tests__/shell-classifier.test.js +151 -0
  135. package/dist/__tests__/shell-compression-floor.test.js +189 -0
  136. package/dist/__tests__/shell-compression-v2.test.js +339 -0
  137. package/dist/__tests__/shell-compressor.test.js +35 -0
  138. package/dist/__tests__/shell-hooks.test.js +128 -0
  139. package/dist/__tests__/shell-strategies.test.js +644 -0
  140. package/dist/__tests__/shell-tee.test.js +133 -0
  141. package/dist/__tests__/signal-dedup.test.js +158 -0
  142. package/dist/__tests__/signal-reinforcer.test.js +77 -0
  143. package/dist/__tests__/signal-scorer.test.js +251 -0
  144. package/dist/__tests__/signal-show-store.test.js +108 -0
  145. package/dist/__tests__/smart-truncate.test.js +215 -0
  146. package/dist/__tests__/snapshot-v2.test.js +113 -0
  147. package/dist/__tests__/sprint-l1-local-mode.test.js +130 -0
  148. package/dist/__tests__/sprint-l10-boot.test.js +220 -0
  149. package/dist/__tests__/sprint-l9-offline-commands.test.js +189 -0
  150. package/dist/__tests__/sprint-q-persistent-context.test.js +198 -0
  151. package/dist/__tests__/sprint-s1-wiring.test.js +215 -0
  152. package/dist/__tests__/sprint-s2-wiring.test.js +256 -0
  153. package/dist/__tests__/sprint-s3-wiring.test.js +195 -0
  154. package/dist/__tests__/sprint-s4-wiring.test.js +213 -0
  155. package/dist/__tests__/sprint-s6-hooks.test.js +222 -0
  156. package/dist/__tests__/sprint-s7-persistent.test.js +263 -0
  157. package/dist/__tests__/sprint-s8-value.test.js +167 -0
  158. package/dist/__tests__/sprint-s9-behavioral.test.js +179 -0
  159. package/dist/__tests__/sprint3-intelligence.test.js +297 -0
  160. package/dist/__tests__/sprint5-mcp-server.test.js +136 -0
  161. package/dist/__tests__/startup-display.test.js +302 -0
  162. package/dist/__tests__/startup-log-file.test.js +97 -0
  163. package/dist/__tests__/stash-manager.test.js +229 -0
  164. package/dist/__tests__/state-detector.test.js +92 -0
  165. package/dist/__tests__/status-dashboard.test.js +142 -0
  166. package/dist/__tests__/temporal-facts.test.js +292 -0
  167. package/dist/__tests__/temporal-routes.test.js +142 -0
  168. package/dist/__tests__/test-detector.test.js +174 -0
  169. package/dist/__tests__/theme.test.js +72 -0
  170. package/dist/__tests__/timeline-agents.test.js +122 -0
  171. package/dist/__tests__/timeline-bootstrap.test.js +176 -0
  172. package/dist/__tests__/timeline-filters.test.js +193 -0
  173. package/dist/__tests__/timeline-markers.test.js +151 -0
  174. package/dist/__tests__/timeline-routes.test.js +156 -0
  175. package/dist/__tests__/timeline-store.test.js +171 -0
  176. package/dist/__tests__/token-counter.test.js +86 -0
  177. package/dist/__tests__/token-estimator.test.js +96 -0
  178. package/dist/__tests__/token-flow-api.test.js +239 -0
  179. package/dist/__tests__/token-flow-instrumentation.test.js +437 -0
  180. package/dist/__tests__/token-flow-persistence.test.js +356 -0
  181. package/dist/__tests__/token-flow-routes.test.js +199 -0
  182. package/dist/__tests__/token-flow.test.js +695 -0
  183. package/dist/__tests__/tool-clusters.test.js +177 -0
  184. package/dist/__tests__/transport-mux.test.js +283 -0
  185. package/dist/__tests__/turn-segmenter.test.js +166 -0
  186. package/dist/__tests__/uninstall.test.js +141 -0
  187. package/dist/__tests__/warm-start-policy.test.js +271 -0
  188. package/dist/__tests__/wire-cap-nudge.test.js +77 -0
  189. package/dist/__tests__/worker-pool.test.js +101 -0
  190. package/dist/behaviors/agent-llm-bridge.js +166 -0
  191. package/dist/behaviors/architecture-guard.js +256 -0
  192. package/dist/behaviors/auto-doc.js +247 -0
  193. package/dist/behaviors/cascade-guard.js +289 -0
  194. package/dist/behaviors/change-narrative.js +270 -0
  195. package/dist/behaviors/convention-drift.js +290 -0
  196. package/dist/behaviors/framework.js +235 -0
  197. package/dist/behaviors/guard-formatter.js +44 -0
  198. package/dist/behaviors/incomplete-work.js +270 -0
  199. package/dist/behaviors/loop-breaker.js +300 -0
  200. package/dist/behaviors/session-continuity.js +208 -0
  201. package/dist/cli.js +992 -706
  202. package/dist/commands/branches.js +97 -0
  203. package/dist/commands/check-commit.js +225 -0
  204. package/dist/commands/compress-output.js +64 -0
  205. package/dist/commands/config-verify.js +243 -0
  206. package/dist/commands/daemon.js +905 -0
  207. package/dist/commands/dashboard.js +52 -0
  208. package/dist/commands/debug.js +200 -0
  209. package/dist/commands/enrich.js +184 -0
  210. package/dist/commands/exec.js +233 -0
  211. package/dist/commands/gain.js +156 -0
  212. package/dist/commands/hook.js +88 -0
  213. package/dist/commands/index.js +88 -0
  214. package/dist/commands/init.js +74 -0
  215. package/dist/commands/install.js +505 -0
  216. package/dist/commands/learn.js +116 -0
  217. package/dist/commands/manifest.js +193 -0
  218. package/dist/commands/rewind.js +103 -0
  219. package/dist/commands/serve.js +19 -0
  220. package/dist/commands/setup-wizard.js +414 -0
  221. package/dist/commands/skills.js +64 -0
  222. package/dist/commands/stats.js +20 -0
  223. package/dist/commands/status.js +654 -0
  224. package/dist/commands/timeline.js +139 -0
  225. package/dist/commands/uninstall.js +230 -0
  226. package/dist/components/App.js +109 -0
  227. package/dist/components/Banner.js +12 -0
  228. package/dist/components/ConfirmPrompt.js +25 -0
  229. package/dist/components/DriftSummary.js +23 -0
  230. package/dist/components/GradeBadge.js +15 -0
  231. package/dist/components/HealthCard.js +18 -0
  232. package/dist/components/InkSpinner.js +22 -0
  233. package/dist/components/InputBox.js +17 -0
  234. package/dist/components/KeyValue.js +13 -0
  235. package/dist/components/MessageList.js +14 -0
  236. package/dist/components/ProgressBar.js +26 -0
  237. package/dist/components/Section.js +16 -0
  238. package/dist/components/SessionSummaryCard.js +73 -0
  239. package/dist/components/StartupDisplay.js +24 -0
  240. package/dist/components/StatusDashboard.js +57 -0
  241. package/dist/components/StatusLine.js +8 -0
  242. package/dist/components/StepLine.js +22 -0
  243. package/dist/components/Theme.js +20 -0
  244. package/dist/components/ToolProgress.js +8 -0
  245. package/dist/components/ViolationList.js +21 -0
  246. package/dist/components/render.js +13 -0
  247. package/dist/config/agent-registry.js +237 -0
  248. package/dist/config/claude-settings-hooks.js +304 -0
  249. package/dist/config/hook-installer.js +65 -0
  250. package/dist/config/instruction-writer.js +388 -0
  251. package/dist/config/mcp-config-writer.js +266 -0
  252. package/dist/config/settings.js +174 -0
  253. package/dist/config/tool-detector.js +42 -0
  254. package/dist/config/value-surfacing.js +119 -0
  255. package/dist/core/context-assembly.js +108 -0
  256. package/dist/core/conversation.js +33 -0
  257. package/dist/core/local-chat-provider.js +475 -0
  258. package/dist/core/provider-factory.js +55 -0
  259. package/dist/core/providers.js +90 -0
  260. package/dist/core/query-engine.js +174 -0
  261. package/dist/daemon/api.js +312 -0
  262. package/dist/daemon/autostart.js +119 -0
  263. package/dist/daemon/bootstrap.js +39 -0
  264. package/dist/daemon/client.js +164 -0
  265. package/dist/daemon/detect-ci.js +81 -0
  266. package/dist/daemon/platform-linux.js +146 -0
  267. package/dist/daemon/platform-macos.js +134 -0
  268. package/dist/daemon/platform-windows.js +116 -0
  269. package/dist/daemon/process-manager.js +299 -0
  270. package/dist/daemon/protocol.js +23 -0
  271. package/dist/daemon/registry.js +270 -0
  272. package/dist/daemon/settings-schema.js +72 -0
  273. package/dist/daemon/system-health.js +134 -0
  274. package/dist/daemon/version-checker.js +262 -0
  275. package/dist/daemon/warm-start.js +223 -0
  276. package/dist/entrypoints/cli.js +1043 -0
  277. package/dist/entrypoints/daemon.js +380 -0
  278. package/dist/entrypoints/repl.js +147 -0
  279. package/dist/hooks/adapters/claude-code.js +90 -0
  280. package/dist/hooks/adapters/cline.js +100 -0
  281. package/dist/hooks/adapters/cursor.js +98 -0
  282. package/dist/hooks/hook-dedup.js +79 -0
  283. package/dist/hooks/hook-runner.js +113 -0
  284. package/dist/hooks/navigation-hooks.js +175 -0
  285. package/dist/hooks/prompt-hooks.js +63 -0
  286. package/dist/hooks/shell-hooks.js +47 -0
  287. package/dist/ignore.js +111 -0
  288. package/dist/intelligence/approach-suggester.js +61 -0
  289. package/dist/intelligence/ast-extractor.js +2615 -0
  290. package/dist/intelligence/ast-worker.js +34 -0
  291. package/dist/intelligence/background-indexer.js +121 -0
  292. package/dist/intelligence/blast-radius.js +200 -0
  293. package/dist/intelligence/community-detection.js +691 -0
  294. package/dist/intelligence/community-detector.js +184 -0
  295. package/dist/intelligence/computation-scheduler.js +75 -0
  296. package/dist/intelligence/confidence-propagation.js +47 -0
  297. package/dist/intelligence/convention-detector.js +242 -0
  298. package/dist/intelligence/convention-learner.js +205 -0
  299. package/dist/intelligence/convention-matcher.js +205 -0
  300. package/dist/intelligence/cozo-schema.js +376 -0
  301. package/dist/intelligence/decision-point-detector.js +90 -0
  302. package/dist/intelligence/deep-dive-tools.js +586 -0
  303. package/dist/intelligence/durability-scorer.js +84 -0
  304. package/dist/intelligence/exploration-cost.js +204 -0
  305. package/dist/intelligence/exploration-pattern-tracker.js +61 -0
  306. package/dist/intelligence/fact-generator.js +322 -0
  307. package/dist/intelligence/facts-schema.js +90 -0
  308. package/dist/intelligence/file-intelligence.js +59 -0
  309. package/dist/intelligence/graph-holder.js +220 -0
  310. package/dist/intelligence/graph-temporal-joiner.js +238 -0
  311. package/dist/intelligence/health-grade.js +423 -0
  312. package/dist/intelligence/health-grader.js +200 -0
  313. package/dist/intelligence/health-map-data.js +259 -0
  314. package/dist/intelligence/import-symbols.js +136 -0
  315. package/dist/intelligence/incremental-indexer.js +658 -0
  316. package/dist/intelligence/indexer/centrality.js +62 -0
  317. package/dist/intelligence/indexer/cfg-context.js +95 -0
  318. package/dist/intelligence/indexer/confidence.js +34 -0
  319. package/dist/intelligence/indexer/cross-file-resolver.js +104 -0
  320. package/dist/intelligence/indexer/edge-repair.js +89 -0
  321. package/dist/intelligence/indexer/entity-key.js +17 -0
  322. package/dist/intelligence/indexer/export-map.js +132 -0
  323. package/dist/intelligence/indexer/git-cochange.js +128 -0
  324. package/dist/intelligence/indexer/graph-patch.js +147 -0
  325. package/dist/intelligence/indexer/incremental.js +78 -0
  326. package/dist/intelligence/indexer/ingest.js +160 -0
  327. package/dist/intelligence/indexer/language-detect.js +226 -0
  328. package/dist/intelligence/indexer/metadata.js +63 -0
  329. package/dist/intelligence/indexer/mutation-tracker.js +79 -0
  330. package/dist/intelligence/indexer/orchestrator.js +155 -0
  331. package/dist/intelligence/indexer/plugin-interface.js +31 -0
  332. package/dist/intelligence/indexer/plugins/csharp.js +440 -0
  333. package/dist/intelligence/indexer/plugins/go.js +335 -0
  334. package/dist/intelligence/indexer/plugins/java.js +370 -0
  335. package/dist/intelligence/indexer/plugins/python.js +358 -0
  336. package/dist/intelligence/indexer/plugins/regex-fallback.js +82 -0
  337. package/dist/intelligence/indexer/plugins/ruby.js +290 -0
  338. package/dist/intelligence/indexer/plugins/rust.js +484 -0
  339. package/dist/intelligence/indexer/plugins/tier2-generic.js +310 -0
  340. package/dist/intelligence/indexer/plugins/typescript.js +456 -0
  341. package/dist/intelligence/indexer/resource-monitor.js +93 -0
  342. package/dist/intelligence/indexer/scip/decoder.js +253 -0
  343. package/dist/intelligence/indexer/scip/detector.js +232 -0
  344. package/dist/intelligence/indexer/scip/downloader.js +427 -0
  345. package/dist/intelligence/indexer/scip/fallback.js +34 -0
  346. package/dist/intelligence/indexer/scip/merger.js +109 -0
  347. package/dist/intelligence/indexer/scip/orchestrator.js +433 -0
  348. package/dist/intelligence/indexer/scip/runner.js +98 -0
  349. package/dist/intelligence/indexer/snapshot.js +66 -0
  350. package/dist/intelligence/indexer/test-detector.js +196 -0
  351. package/dist/intelligence/indexer/watch-integration.js +61 -0
  352. package/dist/intelligence/indexer/worker.js +85 -0
  353. package/dist/intelligence/local-convention-detector.js +437 -0
  354. package/dist/intelligence/local-embeddings.js +190 -0
  355. package/dist/intelligence/local-graph.js +1946 -0
  356. package/dist/intelligence/local-indexer.js +1575 -0
  357. package/dist/intelligence/local-llm.js +163 -0
  358. package/dist/intelligence/local-rule-generator.js +154 -0
  359. package/dist/intelligence/local-snapshot.js +213 -0
  360. package/dist/intelligence/negative-knowledge.js +103 -0
  361. package/dist/intelligence/persistent-db.js +85 -0
  362. package/dist/intelligence/query-router.js +2556 -0
  363. package/dist/intelligence/risk-classifier.js +116 -0
  364. package/dist/intelligence/rule-evaluator.js +380 -0
  365. package/dist/intelligence/rule-generator.js +49 -0
  366. package/dist/intelligence/search-index.js +173 -0
  367. package/dist/intelligence/semantic/docstring-extractor.js +67 -0
  368. package/dist/intelligence/semantic/embedding-store.js +52 -0
  369. package/dist/intelligence/semantic/enrichment-orchestrator.js +48 -0
  370. package/dist/intelligence/semantic/git-message-miner.js +114 -0
  371. package/dist/intelligence/semantic/identifier-tokenizer.js +51 -0
  372. package/dist/intelligence/semantic/node2vec-embeddings.js +71 -0
  373. package/dist/intelligence/semantic/node2vec-walks.js +103 -0
  374. package/dist/intelligence/semantic/path-domain-inference.js +112 -0
  375. package/dist/intelligence/semantic/similarity-engine.js +60 -0
  376. package/dist/intelligence/semantic/tfidf-vectors.js +88 -0
  377. package/dist/intelligence/session-brief-builder.js +159 -0
  378. package/dist/intelligence/session-context.js +221 -0
  379. package/dist/intelligence/session-health-monitor.js +211 -0
  380. package/dist/intelligence/session-narrative.js +197 -0
  381. package/dist/intelligence/session-pattern-analyzer.js +218 -0
  382. package/dist/intelligence/signal-scorer.js +390 -0
  383. package/dist/intelligence/signal-show-store.js +182 -0
  384. package/dist/intelligence/smart-truncate.js +158 -0
  385. package/dist/intelligence/subgraph-cache.js +88 -0
  386. package/dist/intelligence/temporal-facts.js +494 -0
  387. package/dist/intelligence/token-estimator.js +100 -0
  388. package/dist/intelligence/tool-injector.js +87 -0
  389. package/dist/intelligence/tree-sitter-loader.js +71 -0
  390. package/dist/intelligence/worker-pool.js +116 -0
  391. package/dist/proxy/arg-validator.js +79 -0
  392. package/dist/proxy/auto-bootstrap.js +167 -0
  393. package/dist/proxy/bridge.js +147 -0
  394. package/dist/proxy/budget-enforcer.js +70 -0
  395. package/dist/proxy/compression-quality-monitor.js +160 -0
  396. package/dist/proxy/compression-stats.js +51 -0
  397. package/dist/proxy/context-rot-detector.js +137 -0
  398. package/dist/proxy/drift-detector.js +139 -0
  399. package/dist/proxy/efficiency-tracker.js +79 -0
  400. package/dist/proxy/fact-ranking.js +154 -0
  401. package/dist/proxy/format-encoder.js +266 -0
  402. package/dist/proxy/http-transport.js +90 -0
  403. package/dist/proxy/lifecycle-actor.js +55 -0
  404. package/dist/proxy/lifecycle-machine.js +187 -0
  405. package/dist/proxy/log-tailer.js +265 -0
  406. package/dist/proxy/model-pricing.js +98 -0
  407. package/dist/proxy/network-firewall.js +141 -0
  408. package/dist/proxy/nudge-state.js +93 -0
  409. package/dist/proxy/output-compressor.js +185 -0
  410. package/dist/proxy/pid-lock.js +291 -0
  411. package/dist/proxy/proxy-context.js +11 -0
  412. package/dist/proxy/proxy.js +2633 -0
  413. package/dist/proxy/response-enrichment.js +32 -0
  414. package/dist/proxy/response-envelope.js +313 -0
  415. package/dist/proxy/session-dedup.js +82 -0
  416. package/dist/proxy/session-legend.js +30 -0
  417. package/dist/proxy/session-persistence.js +210 -0
  418. package/dist/proxy/session-resume.js +94 -0
  419. package/dist/proxy/session-stats.js +513 -0
  420. package/dist/proxy/shell-classifier.js +1346 -0
  421. package/dist/proxy/shell-compression-log.js +93 -0
  422. package/dist/proxy/shell-compressor.js +390 -0
  423. package/dist/proxy/shell-graph-boost.js +202 -0
  424. package/dist/proxy/shell-monitor-map.js +18 -0
  425. package/dist/proxy/shell-stats.js +54 -0
  426. package/dist/proxy/shell-strategies/cloud.js +215 -0
  427. package/dist/proxy/shell-strategies/diff.js +159 -0
  428. package/dist/proxy/shell-strategies/error-diagnostic.js +796 -0
  429. package/dist/proxy/shell-strategies/filter-dsl.js +358 -0
  430. package/dist/proxy/shell-strategies/git-status.js +177 -0
  431. package/dist/proxy/shell-strategies/key-value.js +193 -0
  432. package/dist/proxy/shell-strategies/log-text.js +154 -0
  433. package/dist/proxy/shell-strategies/omni.js +188 -0
  434. package/dist/proxy/shell-strategies/progress.js +55 -0
  435. package/dist/proxy/shell-strategies/redact.js +76 -0
  436. package/dist/proxy/shell-strategies/structured.js +241 -0
  437. package/dist/proxy/shell-strategies/tabular.js +243 -0
  438. package/dist/proxy/shell-strategies/test-results-types.js +13 -0
  439. package/dist/proxy/shell-strategies/test-results.js +784 -0
  440. package/dist/proxy/shell-strategies/tree-paths.js +144 -0
  441. package/dist/proxy/shell-strategies/yaml.js +182 -0
  442. package/dist/proxy/shell-tee.js +111 -0
  443. package/dist/proxy/signal-dedup.js +171 -0
  444. package/dist/proxy/startup-renderer.js +158 -0
  445. package/dist/proxy/task-token-display.js +38 -0
  446. package/dist/proxy/token-counter.js +61 -0
  447. package/dist/proxy/tool-clusters.js +273 -0
  448. package/dist/proxy/tool-definitions.js +525 -0
  449. package/dist/proxy/transport-mux.js +229 -0
  450. package/dist/proxy/wire-cap.js +268 -0
  451. package/dist/schemas/api/skills.js +19 -0
  452. package/dist/schemas/common/errors.js +7 -0
  453. package/dist/schemas/common/headers.js +5 -0
  454. package/dist/schemas/entities/edge.js +25 -0
  455. package/dist/schemas/entities/entity.js +22 -0
  456. package/dist/schemas/entities/rule.js +18 -0
  457. package/dist/schemas/index.js +14 -0
  458. package/dist/server/event-bus.js +59 -0
  459. package/dist/server/http.js +156 -0
  460. package/dist/server/middleware.js +70 -0
  461. package/dist/server/routes/drift.js +97 -0
  462. package/dist/server/routes/intelligence.js +1217 -0
  463. package/dist/server/routes/reasoning-quality.js +444 -0
  464. package/dist/server/routes/session.js +86 -0
  465. package/dist/server/routes/stream.js +120 -0
  466. package/dist/server/routes/system.js +73 -0
  467. package/dist/server/routes/temporal.js +170 -0
  468. package/dist/server/routes/timeline.js +232 -0
  469. package/dist/server/routes/token-flow.js +403 -0
  470. package/dist/skills/effectiveness-tracker.js +93 -0
  471. package/dist/skills/local-pack.js +380 -0
  472. package/dist/skills/resolver.js +495 -0
  473. package/dist/state-detector.js +83 -0
  474. package/dist/timeline/intent-detector.js +263 -0
  475. package/dist/timeline/loop-miner.js +140 -0
  476. package/dist/timeline/open-threads.js +49 -0
  477. package/dist/timeline/signal-reinforcer.js +62 -0
  478. package/dist/timeline/timeline-bootstrap.js +151 -0
  479. package/dist/timeline/timeline-store.js +618 -0
  480. package/dist/tools/coding/bash.js +49 -0
  481. package/dist/tools/coding/file-edit.js +72 -0
  482. package/dist/tools/coding/file-outline.js +227 -0
  483. package/dist/tools/coding/file-read-protocol.js +425 -0
  484. package/dist/tools/coding/file-read.js +35 -0
  485. package/dist/tools/coding/file-write.js +43 -0
  486. package/dist/tools/coding/glob-tool.js +109 -0
  487. package/dist/tools/coding/grep.js +162 -0
  488. package/dist/tools/coding/index.js +27 -0
  489. package/dist/tools/intelligence/index.js +269 -0
  490. package/dist/tools/intelligence/record-fact.js +48 -0
  491. package/dist/tools/intelligence/timeline-markers.js +130 -0
  492. package/dist/tools/registry.js +47 -0
  493. package/dist/tools/types.js +8 -0
  494. package/dist/tracking/auto-snapshot-triggers.js +246 -0
  495. package/dist/tracking/branch-context.js +115 -0
  496. package/dist/tracking/branch-snapshot.js +217 -0
  497. package/dist/tracking/causal-bridge.js +317 -0
  498. package/dist/tracking/circuit-breaker.js +147 -0
  499. package/dist/tracking/commit-watcher.js +114 -0
  500. package/dist/tracking/context-ledger.js +119 -0
  501. package/dist/tracking/correction-detector.js +324 -0
  502. package/dist/tracking/drift-tracker.js +874 -0
  503. package/dist/tracking/durability-tracker.js +94 -0
  504. package/dist/tracking/entity-rewind.js +200 -0
  505. package/dist/tracking/file-hash-state.js +114 -0
  506. package/dist/tracking/git-attribution.js +132 -0
  507. package/dist/tracking/git-trailers.js +171 -0
  508. package/dist/tracking/intelligence-counter.js +46 -0
  509. package/dist/tracking/intent-correlator.js +202 -0
  510. package/dist/tracking/intent-encoder.js +52 -0
  511. package/dist/tracking/intent-token-tracker.js +159 -0
  512. package/dist/tracking/ledger-archiver.js +94 -0
  513. package/dist/tracking/ledger-chains.js +245 -0
  514. package/dist/tracking/metrics-store.js +361 -0
  515. package/dist/tracking/native-watcher.js +131 -0
  516. package/dist/tracking/offline-rewind.js +295 -0
  517. package/dist/tracking/pending-violations.js +74 -0
  518. package/dist/tracking/persistence-effectiveness.js +167 -0
  519. package/dist/tracking/prompt-durability.js +202 -0
  520. package/dist/tracking/quality-signals.js +213 -0
  521. package/dist/tracking/redactor.js +73 -0
  522. package/dist/tracking/rewind-engine.js +161 -0
  523. package/dist/tracking/session-history.js +128 -0
  524. package/dist/tracking/session-receipt.js +88 -0
  525. package/dist/tracking/session-summary-writer.js +157 -0
  526. package/dist/tracking/shadow-ledger.js +321 -0
  527. package/dist/tracking/stash-manager.js +258 -0
  528. package/dist/tracking/timeline-fork.js +213 -0
  529. package/dist/tracking/timeline.js +69 -0
  530. package/dist/tracking/token-flow.js +276 -0
  531. package/dist/tracking/turn-segmenter.js +122 -0
  532. package/dist/tracking/weekly-accumulator.js +179 -0
  533. package/dist/tracking/working-snapshots.js +188 -0
  534. package/dist/tracking/workspace-manifest.js +176 -0
  535. package/dist/transport/http.js +102 -0
  536. package/dist/ui/assets/index-BsMTQdhX.js +10 -0
  537. package/dist/ui/index.html +1 -1
  538. package/dist/utils/counterfactual.js +65 -0
  539. package/dist/utils/deep-link.js +34 -0
  540. package/dist/utils/detect.js +193 -0
  541. package/dist/utils/exec.js +73 -0
  542. package/dist/utils/file-logger.js +87 -0
  543. package/dist/utils/format-error.js +29 -0
  544. package/dist/utils/git.js +181 -0
  545. package/dist/utils/log.js +57 -0
  546. package/dist/utils/logger.js +35 -0
  547. package/dist/utils/mcp-content-json.js +8 -0
  548. package/dist/utils/session-logger.js +154 -0
  549. package/dist/utils/startup-log.js +512 -0
  550. package/dist/utils/ui.js +56 -0
  551. package/package.json +5 -3
  552. package/scripts/postinstall.mjs +299 -0
  553. package/dist/ui/assets/index-B-0HTtUR.js +0 -10
package/dist/cli.js CHANGED
@@ -2187,7 +2187,7 @@ var init_local_graph = __esm({
2187
2187
  { key: entityKey2 }
2188
2188
  );
2189
2189
  if (fileResult.rows.length === 0) return [];
2190
- const filePath = fileResult.rows[0][0];
2190
+ const filePath = fileResult.rows[0]?.[0];
2191
2191
  const siblingsResult = await this.query(
2192
2192
  `?[key, name, fp] := *edges{from_key: $fileKey, to_key: key, type: "contains"}, *entities{key, name, file_path: fp}, key != $entityKey`,
2193
2193
  { fileKey: `file:${filePath}`, entityKey: entityKey2 }
@@ -2222,11 +2222,11 @@ var init_local_graph = __esm({
2222
2222
  async getFileNeighbors(filePath) {
2223
2223
  const fileKey = `file:${filePath}`;
2224
2224
  const outResult = await this.query(
2225
- `?[to_key, type] := *edges{from_key: $fk, to_key, type}, to_key != $fk`,
2225
+ "?[to_key, type] := *edges{from_key: $fk, to_key, type}, to_key != $fk",
2226
2226
  { fk: fileKey }
2227
2227
  );
2228
2228
  const inResult = await this.query(
2229
- `?[from_key, type] := *edges{from_key, to_key: $fk, type}, from_key != $fk`,
2229
+ "?[from_key, type] := *edges{from_key, to_key: $fk, type}, from_key != $fk",
2230
2230
  { fk: fileKey }
2231
2231
  );
2232
2232
  const outbound = [];
@@ -2422,6 +2422,82 @@ var init_local_graph = __esm({
2422
2422
  scored.sort((a, b) => b.surprise_score - a.surprise_score);
2423
2423
  return scored.slice(0, topN);
2424
2424
  }
2425
+ /**
2426
+ * Get cross-boundary links for a specific pair of directory prefixes.
2427
+ *
2428
+ * Unlike getCrossBoundaryLinks (which fetches ALL cross-community edges and
2429
+ * post-filters), this runs a targeted Datalog query with starts_with so it
2430
+ * always finds relevant edges regardless of how many total cross-community
2431
+ * edges exist in the project. Used when both from_path and to_path are
2432
+ * provided to get_cross_boundary_links.
2433
+ *
2434
+ * NOTE: Entity community IDs are hierarchical (macroCid * 1000 + subId).
2435
+ * The `communities` table only stores macro IDs. This method avoids the
2436
+ * table join and resolves labels by looking up macroId = floor(id / 1000).
2437
+ */
2438
+ async getCrossPathLinks(fromPrefix, toPrefix, topN) {
2439
+ const fp = fromPrefix.endsWith("/") ? fromPrefix : `${fromPrefix}/`;
2440
+ const tp = toPrefix.endsWith("/") ? toPrefix : `${toPrefix}/`;
2441
+ const mkQuery = (a, b) => `?[fn, ff, fc, tn, tf, tc, et] :=
2442
+ *edges{from_key: fk, to_key: tk, type: et},
2443
+ *entities{key: fk, name: fn, file_path: ff, community: fc},
2444
+ *entities{key: tk, name: tn, file_path: tf, community: tc},
2445
+ starts_with(ff, $a), starts_with(tf, $b),
2446
+ fc >= 0, tc >= 0
2447
+ :limit $n`;
2448
+ const [fwdRes, revRes] = await Promise.all([
2449
+ this.query(mkQuery(fp, tp), { a: fp, b: tp, n: topN }).catch(() => ({
2450
+ rows: []
2451
+ })),
2452
+ this.query(mkQuery(tp, fp), { a: tp, b: fp, n: topN }).catch(() => ({
2453
+ rows: []
2454
+ }))
2455
+ ]);
2456
+ const macroIds = /* @__PURE__ */ new Set();
2457
+ for (const rows of [fwdRes.rows, revRes.rows]) {
2458
+ for (const row of rows) {
2459
+ macroIds.add(Math.floor(row[2] / 1e3));
2460
+ macroIds.add(Math.floor(row[5] / 1e3));
2461
+ }
2462
+ }
2463
+ const labelMap = /* @__PURE__ */ new Map();
2464
+ if (macroIds.size > 0) {
2465
+ const ids = [...macroIds];
2466
+ try {
2467
+ const labelRes = await this.query(
2468
+ `?[id, label] := *communities{id, label}, id in $ids`,
2469
+ { ids }
2470
+ );
2471
+ for (const row of labelRes.rows) {
2472
+ labelMap.set(row[0], row[1]);
2473
+ }
2474
+ } catch {
2475
+ }
2476
+ }
2477
+ const seen = /* @__PURE__ */ new Set();
2478
+ const results = [];
2479
+ for (const row of [...fwdRes.rows, ...revRes.rows]) {
2480
+ const fc = row[2];
2481
+ const tc = row[5];
2482
+ const key = `${row[0]}:${row[3]}:${row[6]}`;
2483
+ if (seen.has(key)) continue;
2484
+ seen.add(key);
2485
+ results.push({
2486
+ from_name: row[0],
2487
+ from_file: row[1],
2488
+ from_community: fc,
2489
+ from_community_label: labelMap.get(Math.floor(fc / 1e3)) ?? String(Math.floor(fc / 1e3)),
2490
+ to_name: row[3],
2491
+ to_file: row[4],
2492
+ to_community: tc,
2493
+ to_community_label: labelMap.get(Math.floor(tc / 1e3)) ?? String(Math.floor(tc / 1e3)),
2494
+ edge_type: row[6],
2495
+ surprise_score: 1
2496
+ // all edges here cross an explicit path boundary
2497
+ });
2498
+ }
2499
+ return results.slice(0, topN);
2500
+ }
2425
2501
  /**
2426
2502
  * Get critical nodes — highest degree entities excluding file-level hubs.
2427
2503
  * Degree ranking excluding kind=="file" and kind=="module".
@@ -5252,11 +5328,13 @@ import { execSync } from "child_process";
5252
5328
  import {
5253
5329
  existsSync as existsSync10,
5254
5330
  mkdirSync as mkdirSync5,
5331
+ readFileSync as readFileSync9,
5332
+ realpathSync,
5255
5333
  unlinkSync,
5256
5334
  writeFileSync as writeFileSync4
5257
5335
  } from "fs";
5258
5336
  import { homedir as homedir4 } from "os";
5259
- import { join as join10 } from "path";
5337
+ import { dirname as dirname5, join as join10, resolve as resolve2 } from "path";
5260
5338
  function plistDir() {
5261
5339
  return join10(homedir4(), "Library", "LaunchAgents");
5262
5340
  }
@@ -5266,15 +5344,41 @@ function plistPath() {
5266
5344
  function logPath() {
5267
5345
  return join10(homedir4(), ".unerr", "logs", "unerrd.boot.log");
5268
5346
  }
5269
- function resolveUnerrBin() {
5347
+ function resolveNodeBin() {
5348
+ try {
5349
+ return realpathSync(process.execPath);
5350
+ } catch {
5351
+ return process.execPath;
5352
+ }
5353
+ }
5354
+ function resolveCliEntry() {
5355
+ if (process.argv[1]) {
5356
+ const resolved = resolve2(process.argv[1]);
5357
+ if (existsSync10(resolved)) return resolved;
5358
+ }
5270
5359
  try {
5271
- return execSync("which unerr", { encoding: "utf-8" }).trim();
5360
+ const shimPath = execSync("which unerr", { encoding: "utf-8" }).trim();
5361
+ if (shimPath && existsSync10(shimPath)) {
5362
+ const shimContent = readFileSync9(shimPath, "utf-8");
5363
+ const jsMatch = /"\$basedir\/((?:\.\.\/)*[^"]+\.js)"/m.exec(shimContent);
5364
+ if (jsMatch?.[1]) {
5365
+ const basedir = dirname5(shimPath);
5366
+ const abs = resolve2(basedir, jsMatch[1]);
5367
+ if (existsSync10(abs)) return abs;
5368
+ }
5369
+ }
5272
5370
  } catch {
5273
- return join10(process.argv[1] || "unerr");
5274
5371
  }
5372
+ const fallbackBase = process.argv[1] ? dirname5(resolve2(process.argv[1])) : process.cwd();
5373
+ return join10(fallbackBase, "cli.js");
5374
+ }
5375
+ function xmlEscape(s) {
5376
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
5275
5377
  }
5276
- function generatePlist(bin) {
5378
+ function generatePlist(nodeBin, cliEntry) {
5277
5379
  const log24 = logPath();
5380
+ const nodeBinDir = dirname5(nodeBin);
5381
+ const e = xmlEscape;
5278
5382
  return `<?xml version="1.0" encoding="UTF-8"?>
5279
5383
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
5280
5384
  <plist version="1.0">
@@ -5283,11 +5387,17 @@ function generatePlist(bin) {
5283
5387
  <string>com.unerr.daemon</string>
5284
5388
  <key>ProgramArguments</key>
5285
5389
  <array>
5286
- <string>${bin}</string>
5390
+ <string>${e(nodeBin)}</string>
5391
+ <string>${e(cliEntry)}</string>
5287
5392
  <string>daemon</string>
5288
5393
  <string>start</string>
5289
5394
  <string>--foreground</string>
5290
5395
  </array>
5396
+ <key>EnvironmentVariables</key>
5397
+ <dict>
5398
+ <key>PATH</key>
5399
+ <string>${e(nodeBinDir)}:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
5400
+ </dict>
5291
5401
  <key>RunAtLoad</key>
5292
5402
  <true/>
5293
5403
  <key>KeepAlive</key>
@@ -5295,10 +5405,12 @@ function generatePlist(bin) {
5295
5405
  <key>SuccessfulExit</key>
5296
5406
  <false/>
5297
5407
  </dict>
5408
+ <key>ThrottleInterval</key>
5409
+ <integer>30</integer>
5298
5410
  <key>StandardOutPath</key>
5299
- <string>${log24}</string>
5411
+ <string>${e(log24)}</string>
5300
5412
  <key>StandardErrorPath</key>
5301
- <string>${log24}</string>
5413
+ <string>${e(log24)}</string>
5302
5414
  <key>ProcessType</key>
5303
5415
  <string>Background</string>
5304
5416
  <key>LowPriorityBackgroundIO</key>
@@ -5309,12 +5421,13 @@ function generatePlist(bin) {
5309
5421
  function installLaunchd() {
5310
5422
  const dir = plistDir();
5311
5423
  const path7 = plistPath();
5312
- const bin = resolveUnerrBin();
5424
+ const nodeBin = resolveNodeBin();
5425
+ const cliEntry = resolveCliEntry();
5313
5426
  try {
5314
5427
  mkdirSync5(dir, { recursive: true });
5315
5428
  const logDir = join10(homedir4(), ".unerr", "logs");
5316
5429
  mkdirSync5(logDir, { recursive: true });
5317
- const plist = generatePlist(bin);
5430
+ const plist = generatePlist(nodeBin, cliEntry);
5318
5431
  writeFileSync4(path7, plist, "utf-8");
5319
5432
  const uid = process.getuid?.() ?? execSync("id -u", { encoding: "utf-8" }).trim();
5320
5433
  try {
@@ -5395,24 +5508,46 @@ import {
5395
5508
  existsSync as existsSync11,
5396
5509
  mkdirSync as mkdirSync6,
5397
5510
  readFileSync as readFileSync10,
5511
+ realpathSync as realpathSync2,
5398
5512
  unlinkSync as unlinkSync2,
5399
5513
  writeFileSync as writeFileSync5
5400
5514
  } from "fs";
5401
5515
  import { homedir as homedir5 } from "os";
5402
- import { join as join11 } from "path";
5516
+ import { dirname as dirname6, join as join11, resolve as resolve3 } from "path";
5403
5517
  function unitDir() {
5404
5518
  return join11(homedir5(), ".config", "systemd", "user");
5405
5519
  }
5406
5520
  function unitPath() {
5407
5521
  return join11(unitDir(), UNIT_NAME);
5408
5522
  }
5409
- function resolveUnerrBin2() {
5523
+ function resolveNodeBin2() {
5410
5524
  try {
5411
- return execSync2("which unerr", { encoding: "utf-8" }).trim();
5525
+ return realpathSync2(process.execPath);
5412
5526
  } catch {
5413
- return join11(process.argv[1] || "unerr");
5527
+ return process.execPath;
5414
5528
  }
5415
5529
  }
5530
+ function resolveCliEntry2() {
5531
+ if (process.argv[1]) {
5532
+ const resolved = resolve3(process.argv[1]);
5533
+ if (existsSync11(resolved)) return resolved;
5534
+ }
5535
+ try {
5536
+ const shimPath = execSync2("which unerr", { encoding: "utf-8" }).trim();
5537
+ if (shimPath && existsSync11(shimPath)) {
5538
+ const shimContent = readFileSync10(shimPath, "utf-8");
5539
+ const jsMatch = /"\$basedir\/((?:\.\.\/)*[^"]+\.js)"/m.exec(shimContent);
5540
+ if (jsMatch?.[1]) {
5541
+ const basedir = dirname6(shimPath);
5542
+ const abs = resolve3(basedir, jsMatch[1]);
5543
+ if (existsSync11(abs)) return abs;
5544
+ }
5545
+ }
5546
+ } catch {
5547
+ }
5548
+ const fallbackBase = process.argv[1] ? dirname6(resolve3(process.argv[1])) : process.cwd();
5549
+ return join11(fallbackBase, "cli.js");
5550
+ }
5416
5551
  function isWSL() {
5417
5552
  try {
5418
5553
  const version = readFileSync10("/proc/version", "utf-8");
@@ -5421,18 +5556,25 @@ function isWSL() {
5421
5556
  return false;
5422
5557
  }
5423
5558
  }
5424
- function generateUnit(bin) {
5559
+ function systemdQuote(s) {
5560
+ if (/[\s"\\]/.test(s))
5561
+ return `"${s.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
5562
+ return s;
5563
+ }
5564
+ function generateUnit(nodeBin, cliEntry) {
5565
+ const nodeBinDir = dirname6(nodeBin);
5566
+ const home = homedir5();
5425
5567
  return `[Unit]
5426
5568
  Description=unerr daemon supervisor
5427
5569
  After=network.target
5428
5570
 
5429
5571
  [Service]
5430
5572
  Type=simple
5431
- ExecStart=${bin} daemon start --foreground
5573
+ ExecStart=${systemdQuote(nodeBin)} ${systemdQuote(cliEntry)} daemon start --foreground
5432
5574
  Restart=on-failure
5433
- RestartSec=5
5434
- Environment=HOME=${homedir5()}
5435
- Environment=PATH=${process.env.PATH || "/usr/local/bin:/usr/bin:/bin"}
5575
+ RestartSec=30
5576
+ Environment=HOME=${home}
5577
+ Environment=PATH=${nodeBinDir}:/usr/local/bin:/usr/bin:/bin
5436
5578
 
5437
5579
  [Install]
5438
5580
  WantedBy=default.target
@@ -5448,16 +5590,18 @@ function installSystemd() {
5448
5590
  };
5449
5591
  }
5450
5592
  try {
5451
- const bin = resolveUnerrBin2();
5593
+ const nodeBin = resolveNodeBin2();
5594
+ const cliEntry = resolveCliEntry2();
5452
5595
  const dir = unitDir();
5453
5596
  mkdirSync6(dir, { recursive: true });
5454
- writeFileSync5(path7, generateUnit(bin), "utf-8");
5597
+ writeFileSync5(path7, generateUnit(nodeBin, cliEntry), "utf-8");
5455
5598
  execSync2("systemctl --user daemon-reload", { stdio: "ignore" });
5456
5599
  execSync2("systemctl --user enable --now unerrd.service", {
5457
5600
  stdio: "ignore"
5458
5601
  });
5459
5602
  try {
5460
- execSync2("loginctl enable-linger $USER", { stdio: "ignore" });
5603
+ const username = process.env.USER || execSync2("whoami", { encoding: "utf-8" }).trim();
5604
+ execSync2(`loginctl enable-linger ${username}`, { stdio: "ignore" });
5461
5605
  } catch {
5462
5606
  }
5463
5607
  return { installed: true, path: path7 };
@@ -5533,9 +5677,16 @@ __export(platform_windows_exports, {
5533
5677
  uninstallWindows: () => uninstallWindows
5534
5678
  });
5535
5679
  import { execSync as execSync3 } from "child_process";
5536
- import { existsSync as existsSync12, mkdirSync as mkdirSync7, unlinkSync as unlinkSync3, writeFileSync as writeFileSync6 } from "fs";
5680
+ import {
5681
+ existsSync as existsSync12,
5682
+ mkdirSync as mkdirSync7,
5683
+ readFileSync as readFileSync11,
5684
+ realpathSync as realpathSync3,
5685
+ unlinkSync as unlinkSync3,
5686
+ writeFileSync as writeFileSync6
5687
+ } from "fs";
5537
5688
  import { homedir as homedir6 } from "os";
5538
- import { join as join12 } from "path";
5689
+ import { dirname as dirname7, join as join12, resolve as resolve4 } from "path";
5539
5690
  function startupDir() {
5540
5691
  return join12(
5541
5692
  process.env.APPDATA || join12(homedir6(), "AppData", "Roaming"),
@@ -5549,28 +5700,50 @@ function startupDir() {
5549
5700
  function startupCmdPath() {
5550
5701
  return join12(startupDir(), STARTUP_CMD_NAME);
5551
5702
  }
5552
- function resolveUnerrBin3() {
5703
+ function resolveNodeBin3() {
5704
+ try {
5705
+ return realpathSync3(process.execPath);
5706
+ } catch {
5707
+ return process.execPath;
5708
+ }
5709
+ }
5710
+ function resolveCliEntry3() {
5711
+ if (process.argv[1]) {
5712
+ const resolved = resolve4(process.argv[1]);
5713
+ if (existsSync12(resolved)) return resolved;
5714
+ }
5553
5715
  try {
5554
- return execSync3("where unerr", { encoding: "utf-8" }).trim().split("\n")[0].trim();
5716
+ const whereLine = execSync3("where unerr", { encoding: "utf-8" }).trim().split("\n")[0]?.trim();
5717
+ if (whereLine && existsSync12(whereLine)) {
5718
+ const shimContent = readFileSync11(whereLine, "utf-8");
5719
+ const jsMatch = /"%~dp0\\([^"]+\.js)"/m.exec(shimContent);
5720
+ if (jsMatch?.[1]) {
5721
+ const abs = resolve4(dirname7(whereLine), jsMatch[1]);
5722
+ if (existsSync12(abs)) return abs;
5723
+ }
5724
+ }
5555
5725
  } catch {
5556
- return process.argv[1] || "unerr";
5557
5726
  }
5727
+ const fallbackBase = process.argv[1] ? dirname7(resolve4(process.argv[1])) : process.cwd();
5728
+ return join12(fallbackBase, "cli.js");
5558
5729
  }
5559
5730
  function installWindows() {
5560
- const bin = resolveUnerrBin3();
5561
- const taskResult = installScheduledTask(bin);
5731
+ const nodeBin = resolveNodeBin3();
5732
+ const cliEntry = resolveCliEntry3();
5733
+ const taskResult = installScheduledTask(nodeBin, cliEntry);
5562
5734
  if (taskResult.installed) return taskResult;
5563
- return installStartupCmd(bin);
5735
+ return installStartupCmd(nodeBin, cliEntry);
5564
5736
  }
5565
- function installScheduledTask(bin) {
5566
- const cmd = `"${bin}" daemon start --foreground`;
5737
+ function installScheduledTask(nodeBin, cliEntry) {
5738
+ const innerCmd = `\\"${nodeBin}\\" \\"${cliEntry}\\" daemon start --foreground`;
5739
+ const trArg = `"${innerCmd}"`;
5567
5740
  try {
5568
5741
  try {
5569
5742
  execSync3(`schtasks /Delete /TN "${TASK_NAME}" /F`, { stdio: "ignore" });
5570
5743
  } catch {
5571
5744
  }
5572
5745
  execSync3(
5573
- `schtasks /Create /SC ONLOGON /TN "${TASK_NAME}" /TR ${cmd} /RI 5 /DU 0000:00 /F`,
5746
+ `schtasks /Create /SC ONLOGON /TN "${TASK_NAME}" /TR ${trArg} /RL LIMITED /F`,
5574
5747
  { stdio: "ignore" }
5575
5748
  );
5576
5749
  return { installed: true, path: `Scheduled Task: ${TASK_NAME}` };
@@ -5582,13 +5755,13 @@ function installScheduledTask(bin) {
5582
5755
  };
5583
5756
  }
5584
5757
  }
5585
- function installStartupCmd(bin) {
5758
+ function installStartupCmd(nodeBin, cliEntry) {
5586
5759
  const path7 = startupCmdPath();
5587
5760
  try {
5588
5761
  const dir = startupDir();
5589
5762
  mkdirSync7(dir, { recursive: true });
5590
5763
  const script = `@echo off\r
5591
- "${bin}" daemon start --foreground\r
5764
+ "${nodeBin}" "${cliEntry}" daemon start --foreground\r
5592
5765
  `;
5593
5766
  writeFileSync6(path7, script, "utf-8");
5594
5767
  return { installed: true, path: path7 };
@@ -5770,7 +5943,7 @@ function daemonSockPath() {
5770
5943
  return join14(globalDir(), "unerrd.sock");
5771
5944
  }
5772
5945
  function sendRequest(sockPath2, request, timeoutMs = 3e4) {
5773
- return new Promise((resolve6, reject) => {
5946
+ return new Promise((resolve9, reject) => {
5774
5947
  let buffer = "";
5775
5948
  let settled = false;
5776
5949
  const timer = setTimeout(() => {
@@ -5796,7 +5969,7 @@ function sendRequest(sockPath2, request, timeoutMs = 3e4) {
5796
5969
  clearTimeout(timer);
5797
5970
  socket.destroy();
5798
5971
  try {
5799
- resolve6(JSON.parse(line));
5972
+ resolve9(JSON.parse(line));
5800
5973
  } catch {
5801
5974
  reject(new Error(`Invalid JSON from unerrd: ${line.slice(0, 200)}`));
5802
5975
  }
@@ -5863,21 +6036,21 @@ async function getStatus(sockPath2) {
5863
6036
  return resp;
5864
6037
  }
5865
6038
  function probeDaemon(sockPath2) {
5866
- return new Promise((resolve6) => {
6039
+ return new Promise((resolve9) => {
5867
6040
  const socket = createConnection(sockPath2);
5868
6041
  const timer = setTimeout(() => {
5869
6042
  socket.destroy();
5870
- resolve6(false);
6043
+ resolve9(false);
5871
6044
  }, 1e3);
5872
6045
  timer.unref();
5873
6046
  socket.on("connect", () => {
5874
6047
  clearTimeout(timer);
5875
6048
  socket.destroy();
5876
- resolve6(true);
6049
+ resolve9(true);
5877
6050
  });
5878
6051
  socket.on("error", () => {
5879
6052
  clearTimeout(timer);
5880
- resolve6(false);
6053
+ resolve9(false);
5881
6054
  });
5882
6055
  });
5883
6056
  }
@@ -6062,8 +6235,8 @@ var init_process_manager = __esm({
6062
6235
  if (repo.sock && repo.status === "running") {
6063
6236
  return Promise.resolve(repo.sock);
6064
6237
  }
6065
- return new Promise((resolve6, reject) => {
6066
- repo.readyResolve = resolve6;
6238
+ return new Promise((resolve9, reject) => {
6239
+ repo.readyResolve = resolve9;
6067
6240
  repo.readyReject = reject;
6068
6241
  const timer = setTimeout(() => {
6069
6242
  repo.readyReject?.(
@@ -6130,9 +6303,9 @@ var init_process_manager = __esm({
6130
6303
  }
6131
6304
  // ── Internal: graceful shutdown ─────────────────────────────
6132
6305
  shutdownChild(repo) {
6133
- return new Promise((resolve6) => {
6306
+ return new Promise((resolve9) => {
6134
6307
  if (!repo.child) {
6135
- resolve6();
6308
+ resolve9();
6136
6309
  return;
6137
6310
  }
6138
6311
  const child = repo.child;
@@ -6140,12 +6313,12 @@ var init_process_manager = __esm({
6140
6313
  if (!child.killed) {
6141
6314
  child.kill("SIGKILL");
6142
6315
  }
6143
- resolve6();
6316
+ resolve9();
6144
6317
  }, 1e4);
6145
6318
  timer.unref();
6146
6319
  child.once("exit", () => {
6147
6320
  clearTimeout(timer);
6148
- resolve6();
6321
+ resolve9();
6149
6322
  });
6150
6323
  try {
6151
6324
  child.send({ type: "shutdown" });
@@ -6183,7 +6356,7 @@ import {
6183
6356
  statSync as statSync2,
6184
6357
  unlinkSync as unlinkSync5
6185
6358
  } from "fs";
6186
- import { dirname as dirname5 } from "path";
6359
+ import { dirname as dirname8 } from "path";
6187
6360
  function stripAnsi(s) {
6188
6361
  return s.replace(ANSI_RE, "");
6189
6362
  }
@@ -6206,7 +6379,7 @@ function rotate(filePath, keep) {
6206
6379
  }
6207
6380
  function installFileLogger(opts) {
6208
6381
  const { filePath, maxBytes = 5e6, keep = 5 } = opts;
6209
- mkdirSync9(dirname5(filePath), { recursive: true });
6382
+ mkdirSync9(dirname8(filePath), { recursive: true });
6210
6383
  let bytesWritten = 0;
6211
6384
  try {
6212
6385
  bytesWritten = statSync2(filePath).size;
@@ -6244,7 +6417,7 @@ var init_file_logger = __esm({
6244
6417
 
6245
6418
  // src/daemon/system-health.ts
6246
6419
  import { execSync as execSync4 } from "child_process";
6247
- import { existsSync as existsSync15, readFileSync as readFileSync11, readdirSync as readdirSync3 } from "fs";
6420
+ import { existsSync as existsSync15, readFileSync as readFileSync12, readdirSync as readdirSync3 } from "fs";
6248
6421
  import { cpus, loadavg, platform } from "os";
6249
6422
  function onBattery() {
6250
6423
  const now = Date.now();
@@ -6283,7 +6456,7 @@ function detectBatteryLinux() {
6283
6456
  if (name.startsWith("AC") || name.startsWith("ADP")) {
6284
6457
  const onlinePath = `${psDir}/${name}/online`;
6285
6458
  if (existsSync15(onlinePath)) {
6286
- const online = readFileSync11(onlinePath, "utf-8").trim();
6459
+ const online = readFileSync12(onlinePath, "utf-8").trim();
6287
6460
  if (online === "0") return true;
6288
6461
  if (online === "1") return false;
6289
6462
  }
@@ -6353,14 +6526,14 @@ __export(warm_start_exports, {
6353
6526
  scheduleWarmStart: () => scheduleWarmStart,
6354
6527
  selectCandidates: () => selectCandidates
6355
6528
  });
6356
- import { existsSync as existsSync16, mkdirSync as mkdirSync10, readFileSync as readFileSync12, writeFileSync as writeFileSync8 } from "fs";
6529
+ import { existsSync as existsSync16, mkdirSync as mkdirSync10, readFileSync as readFileSync13, writeFileSync as writeFileSync8 } from "fs";
6357
6530
  import { homedir as homedir8 } from "os";
6358
6531
  import { join as join15 } from "path";
6359
6532
  function loadWarmStartConfig() {
6360
6533
  const configPath = join15(homedir8(), ".unerr", "config.json");
6361
6534
  try {
6362
6535
  if (!existsSync16(configPath)) return { ...DEFAULT_CONFIG };
6363
- const raw = JSON.parse(readFileSync12(configPath, "utf-8"));
6536
+ const raw = JSON.parse(readFileSync13(configPath, "utf-8"));
6364
6537
  return {
6365
6538
  warmStartBudget: typeof raw.warmStartBudget === "number" ? raw.warmStartBudget : DEFAULT_CONFIG.warmStartBudget,
6366
6539
  warmStartIdleDays: typeof raw.warmStartIdleDays === "number" ? raw.warmStartIdleDays : DEFAULT_CONFIG.warmStartIdleDays,
@@ -6377,7 +6550,7 @@ function saveWarmStartConfig(partial) {
6377
6550
  let existing = {};
6378
6551
  try {
6379
6552
  if (existsSync16(configPath)) {
6380
- existing = JSON.parse(readFileSync12(configPath, "utf-8"));
6553
+ existing = JSON.parse(readFileSync13(configPath, "utf-8"));
6381
6554
  }
6382
6555
  } catch {
6383
6556
  }
@@ -6553,7 +6726,7 @@ __export(version_checker_exports, {
6553
6726
  startPeriodicCheck: () => startPeriodicCheck,
6554
6727
  writeVersionCache: () => writeVersionCache
6555
6728
  });
6556
- import { existsSync as existsSync17, mkdirSync as mkdirSync11, readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "fs";
6729
+ import { existsSync as existsSync17, mkdirSync as mkdirSync11, readFileSync as readFileSync14, writeFileSync as writeFileSync9 } from "fs";
6557
6730
  import { get as httpsGet } from "https";
6558
6731
  import { homedir as homedir9 } from "os";
6559
6732
  import { join as join16 } from "path";
@@ -6565,7 +6738,7 @@ function getInstalledVersion() {
6565
6738
  try {
6566
6739
  const pkgPath = join16(__dirname, "../../package.json");
6567
6740
  if (existsSync17(pkgPath)) {
6568
- const pkg = JSON.parse(readFileSync13(pkgPath, "utf-8"));
6741
+ const pkg = JSON.parse(readFileSync14(pkgPath, "utf-8"));
6569
6742
  cachedInstalledVersion = pkg.version;
6570
6743
  return pkg.version;
6571
6744
  }
@@ -6575,7 +6748,7 @@ function getInstalledVersion() {
6575
6748
  const binDir = join16(process.argv[1] || "", "..");
6576
6749
  const pkgPath = join16(binDir, "../package.json");
6577
6750
  if (existsSync17(pkgPath)) {
6578
- const pkg = JSON.parse(readFileSync13(pkgPath, "utf-8"));
6751
+ const pkg = JSON.parse(readFileSync14(pkgPath, "utf-8"));
6579
6752
  cachedInstalledVersion = pkg.version;
6580
6753
  return pkg.version;
6581
6754
  }
@@ -6596,7 +6769,7 @@ function readVersionCache() {
6596
6769
  const path7 = versionCachePath();
6597
6770
  if (!existsSync17(path7)) return defaults;
6598
6771
  const raw = JSON.parse(
6599
- readFileSync13(path7, "utf-8")
6772
+ readFileSync14(path7, "utf-8")
6600
6773
  );
6601
6774
  return {
6602
6775
  lastChecked: raw.lastChecked ?? defaults.lastChecked,
@@ -6620,7 +6793,7 @@ function parseSemVer(version) {
6620
6793
  if (parts.length < 3) return null;
6621
6794
  const major = Number.parseInt(parts[0], 10);
6622
6795
  const minor = Number.parseInt(parts[1], 10);
6623
- const patch = Number.parseInt(parts[2].split("-")[0], 10);
6796
+ const patch = Number.parseInt(parts[2]?.split("-")[0], 10);
6624
6797
  if (!Number.isFinite(major) || !Number.isFinite(minor) || !Number.isFinite(patch))
6625
6798
  return null;
6626
6799
  return { major, minor, patch };
@@ -6642,14 +6815,14 @@ function minorsBehind(latest, current) {
6642
6815
  return Math.max(0, l.minor - c.minor);
6643
6816
  }
6644
6817
  function fetchLatestVersion() {
6645
- return new Promise((resolve6) => {
6818
+ return new Promise((resolve9) => {
6646
6819
  const req = httpsGet(
6647
6820
  REGISTRY_URL,
6648
6821
  { headers: { Accept: "application/json" }, timeout: REQUEST_TIMEOUT_MS },
6649
6822
  (res) => {
6650
6823
  if (res.statusCode !== 200) {
6651
6824
  res.resume();
6652
- resolve6(null);
6825
+ resolve9(null);
6653
6826
  return;
6654
6827
  }
6655
6828
  let body = "";
@@ -6659,17 +6832,17 @@ function fetchLatestVersion() {
6659
6832
  res.on("end", () => {
6660
6833
  try {
6661
6834
  const data = JSON.parse(body);
6662
- resolve6(data.version ?? null);
6835
+ resolve9(data.version ?? null);
6663
6836
  } catch {
6664
- resolve6(null);
6837
+ resolve9(null);
6665
6838
  }
6666
6839
  });
6667
6840
  }
6668
6841
  );
6669
- req.on("error", () => resolve6(null));
6842
+ req.on("error", () => resolve9(null));
6670
6843
  req.on("timeout", () => {
6671
6844
  req.destroy();
6672
- resolve6(null);
6845
+ resolve9(null);
6673
6846
  });
6674
6847
  });
6675
6848
  }
@@ -6773,9 +6946,9 @@ var api_exports = {};
6773
6946
  __export(api_exports, {
6774
6947
  startDaemonApi: () => startDaemonApi
6775
6948
  });
6776
- import { existsSync as existsSync18, readFileSync as readFileSync14 } from "fs";
6949
+ import { existsSync as existsSync18, readFileSync as readFileSync15 } from "fs";
6777
6950
  import { request as httpRequest } from "http";
6778
- import { dirname as dirname6, join as join17 } from "path";
6951
+ import { dirname as dirname9, join as join17 } from "path";
6779
6952
  import { fileURLToPath } from "url";
6780
6953
  import { serve } from "@hono/node-server";
6781
6954
  import { serveStatic } from "@hono/node-server/serve-static";
@@ -6829,7 +7002,7 @@ function startDaemonApi(pm) {
6829
7002
  if (!existsSync18(serverJsonPath)) return null;
6830
7003
  try {
6831
7004
  const serverInfo = JSON.parse(
6832
- readFileSync14(serverJsonPath, "utf-8")
7005
+ readFileSync15(serverJsonPath, "utf-8")
6833
7006
  );
6834
7007
  const [sessionStats, tokenFlow] = await Promise.allSettled([
6835
7008
  fetchRepoApi(serverInfo.port, "/api/session/stats"),
@@ -6943,7 +7116,7 @@ function startDaemonApi(pm) {
6943
7116
  }
6944
7117
  let repoPort;
6945
7118
  try {
6946
- const info2 = JSON.parse(readFileSync14(serverJsonPath, "utf-8"));
7119
+ const info2 = JSON.parse(readFileSync15(serverJsonPath, "utf-8"));
6947
7120
  repoPort = info2.port;
6948
7121
  } catch {
6949
7122
  return c.json({ error: `Cannot read server.json for ${label}` }, 500);
@@ -6961,10 +7134,10 @@ function startDaemonApi(pm) {
6961
7134
  return c.json({ error: `Proxy error: ${err.message}` }, 502);
6962
7135
  }
6963
7136
  });
6964
- const distDir = join17(dirname6(fileURLToPath(import.meta.url)), "ui");
7137
+ const distDir = join17(dirname9(fileURLToPath(import.meta.url)), "ui");
6965
7138
  const spaIndex = join17(distDir, "index.html");
6966
7139
  if (existsSync18(spaIndex)) {
6967
- const spaHtml = readFileSync14(spaIndex, "utf-8");
7140
+ const spaHtml = readFileSync15(spaIndex, "utf-8");
6968
7141
  app.use("*", serveStatic({ root: distDir }));
6969
7142
  app.get("*", (c) => {
6970
7143
  if (c.req.path.startsWith("/api/")) return c.notFound();
@@ -7010,7 +7183,7 @@ function startDaemonApi(pm) {
7010
7183
  };
7011
7184
  }
7012
7185
  function fetchRepoApi(port, path7) {
7013
- return new Promise((resolve6, reject) => {
7186
+ return new Promise((resolve9, reject) => {
7014
7187
  const req = httpRequest(
7015
7188
  { hostname: "127.0.0.1", port, path: path7, method: "GET", timeout: 3e3 },
7016
7189
  (res) => {
@@ -7020,9 +7193,9 @@ function fetchRepoApi(port, path7) {
7020
7193
  });
7021
7194
  res.on("end", () => {
7022
7195
  try {
7023
- resolve6(JSON.parse(body));
7196
+ resolve9(JSON.parse(body));
7024
7197
  } catch {
7025
- resolve6(body);
7198
+ resolve9(body);
7026
7199
  }
7027
7200
  });
7028
7201
  }
@@ -7036,7 +7209,7 @@ function fetchRepoApi(port, path7) {
7036
7209
  });
7037
7210
  }
7038
7211
  function proxyToRepoHttp(port, path7, method) {
7039
- return new Promise((resolve6, reject) => {
7212
+ return new Promise((resolve9, reject) => {
7040
7213
  const req = httpRequest(
7041
7214
  { hostname: "127.0.0.1", port, path: path7, method, timeout: 1e4 },
7042
7215
  (res) => {
@@ -7046,9 +7219,9 @@ function proxyToRepoHttp(port, path7, method) {
7046
7219
  });
7047
7220
  res.on("end", () => {
7048
7221
  try {
7049
- resolve6(JSON.parse(body));
7222
+ resolve9(JSON.parse(body));
7050
7223
  } catch {
7051
- resolve6(body);
7224
+ resolve9(body);
7052
7225
  }
7053
7226
  });
7054
7227
  }
@@ -7078,7 +7251,7 @@ __export(daemon_exports, {
7078
7251
  import {
7079
7252
  existsSync as existsSync19,
7080
7253
  mkdirSync as mkdirSync12,
7081
- readFileSync as readFileSync15,
7254
+ readFileSync as readFileSync16,
7082
7255
  unlinkSync as unlinkSync6,
7083
7256
  writeFileSync as writeFileSync10
7084
7257
  } from "fs";
@@ -7101,7 +7274,7 @@ function isProcessAlive(pid) {
7101
7274
  function acquirePidLock() {
7102
7275
  const p = pidPath();
7103
7276
  try {
7104
- const raw = readFileSync15(p, "utf-8").trim();
7277
+ const raw = readFileSync16(p, "utf-8").trim();
7105
7278
  const existingPid = Number.parseInt(raw, 10);
7106
7279
  if (Number.isFinite(existingPid) && isProcessAlive(existingPid)) {
7107
7280
  return false;
@@ -7149,8 +7322,9 @@ function createUdsServer(pm) {
7149
7322
  let buffer = "";
7150
7323
  socket.on("data", (chunk) => {
7151
7324
  buffer += chunk.toString();
7152
- let newlineIdx;
7153
- while ((newlineIdx = buffer.indexOf("\n")) !== -1) {
7325
+ while (true) {
7326
+ const newlineIdx = buffer.indexOf("\n");
7327
+ if (newlineIdx === -1) break;
7154
7328
  const line = buffer.slice(0, newlineIdx).trim();
7155
7329
  buffer = buffer.slice(newlineIdx + 1);
7156
7330
  if (!line) continue;
@@ -7309,14 +7483,14 @@ async function startDaemon(opts) {
7309
7483
  }
7310
7484
  });
7311
7485
  });
7312
- await new Promise((resolve6, reject) => {
7486
+ await new Promise((resolve9, reject) => {
7313
7487
  server.on("error", (err) => {
7314
7488
  log.error(`UDS server error: ${err.message}`);
7315
7489
  releasePidLock();
7316
7490
  reject(err);
7317
7491
  });
7318
7492
  server.listen(sock, () => {
7319
- resolve6();
7493
+ resolve9();
7320
7494
  });
7321
7495
  });
7322
7496
  const reg = readRegistry();
@@ -7399,19 +7573,23 @@ __export(startup_log_exports, {
7399
7573
  import {
7400
7574
  appendFileSync as appendFileSync4,
7401
7575
  mkdirSync as mkdirSync13,
7402
- readFileSync as readFileSync16,
7576
+ readFileSync as readFileSync17,
7403
7577
  writeFileSync as writeFileSync11
7404
7578
  } from "fs";
7405
7579
  import { join as join19 } from "path";
7406
7580
  function stripAnsi2(s) {
7407
- return s.replace(/\x1b\[[0-9;?]*[A-Za-z~]/g, "").replace(/\x1b\][^\x07]*\x07/g, "");
7581
+ const ESC2 = "\x1B";
7582
+ const CSI = new RegExp(`${ESC2}\\[[0-9;?]*[A-Za-z~]`, "g");
7583
+ const OSC = new RegExp(`${ESC2}\\][^\\x07]*\\x07`, "g");
7584
+ return s.replace(CSI, "").replace(OSC, "");
7408
7585
  }
7409
7586
  function rotateIfNeeded(filePath, maxLines, keepLines) {
7410
7587
  try {
7411
- const content = readFileSync16(filePath, "utf-8");
7588
+ const content = readFileSync17(filePath, "utf-8");
7412
7589
  const lines = content.split("\n").filter(Boolean);
7413
7590
  if (lines.length > maxLines) {
7414
- writeFileSync11(filePath, lines.slice(-keepLines).join("\n") + "\n");
7591
+ writeFileSync11(filePath, `${lines.slice(-keepLines).join("\n")}
7592
+ `);
7415
7593
  }
7416
7594
  } catch {
7417
7595
  }
@@ -7432,7 +7610,8 @@ function writeToFile(level, message, meta) {
7432
7610
  ...meta
7433
7611
  };
7434
7612
  try {
7435
- appendFileSync4(_fileLogPath, JSON.stringify(entry) + "\n");
7613
+ appendFileSync4(_fileLogPath, `${JSON.stringify(entry)}
7614
+ `);
7436
7615
  if (++_fileLogCount % 200 === 0) rotateIfNeeded(_fileLogPath, 2e3, 1e3);
7437
7616
  } catch {
7438
7617
  }
@@ -7960,7 +8139,7 @@ __export(settings_exports, {
7960
8139
  resolveEmbeddingEndpoint: () => resolveEmbeddingEndpoint,
7961
8140
  resolveInferenceEndpoint: () => resolveInferenceEndpoint
7962
8141
  });
7963
- import { existsSync as existsSync22, readFileSync as readFileSync19 } from "fs";
8142
+ import { existsSync as existsSync22, readFileSync as readFileSync20 } from "fs";
7964
8143
  import { homedir as homedir11 } from "os";
7965
8144
  import { join as join22 } from "path";
7966
8145
  import { z } from "zod";
@@ -7985,7 +8164,7 @@ function resolveInferenceEndpoint(config) {
7985
8164
  function loadJsonFile(filePath) {
7986
8165
  if (!existsSync22(filePath)) return {};
7987
8166
  try {
7988
- return JSON.parse(readFileSync19(filePath, "utf-8"));
8167
+ return JSON.parse(readFileSync20(filePath, "utf-8"));
7989
8168
  } catch {
7990
8169
  return {};
7991
8170
  }
@@ -8611,9 +8790,9 @@ __export(metrics_store_exports, {
8611
8790
  closeMetricsStore: () => closeMetricsStore,
8612
8791
  openMetricsStore: () => openMetricsStore
8613
8792
  });
8614
- import Database from "better-sqlite3";
8615
8793
  import { mkdirSync as mkdirSync16 } from "fs";
8616
8794
  import { join as join25 } from "path";
8795
+ import Database from "better-sqlite3";
8617
8796
  function openMetricsStore(unerrDir) {
8618
8797
  let store = instances.get(unerrDir);
8619
8798
  if (!store) {
@@ -9278,7 +9457,7 @@ __export(shell_stats_exports, {
9278
9457
  readShellCompressionAggregate: () => readShellCompressionAggregate,
9279
9458
  recordShellCompressionEvent: () => recordShellCompressionEvent
9280
9459
  });
9281
- import { existsSync as existsSync25, mkdirSync as mkdirSync17, readFileSync as readFileSync21, writeFileSync as writeFileSync13 } from "fs";
9460
+ import { existsSync as existsSync25, mkdirSync as mkdirSync17, readFileSync as readFileSync22, writeFileSync as writeFileSync13 } from "fs";
9282
9461
  import { join as join27 } from "path";
9283
9462
  function estimateRoughTokens(s) {
9284
9463
  return Math.max(1, Math.ceil(s.length / 4));
@@ -9301,7 +9480,7 @@ function recordShellCompressionEvent(cwd, category, original, compressed) {
9301
9480
  agg = {
9302
9481
  ...agg,
9303
9482
  ...JSON.parse(
9304
- readFileSync21(path7, "utf-8")
9483
+ readFileSync22(path7, "utf-8")
9305
9484
  )
9306
9485
  };
9307
9486
  }
@@ -9321,7 +9500,7 @@ function readShellCompressionAggregate(cwd) {
9321
9500
  try {
9322
9501
  const path7 = join27(cwd, ".unerr", "state", "shell_compression_stats.json");
9323
9502
  if (!existsSync25(path7)) return null;
9324
- return JSON.parse(readFileSync21(path7, "utf-8"));
9503
+ return JSON.parse(readFileSync22(path7, "utf-8"));
9325
9504
  } catch {
9326
9505
  return null;
9327
9506
  }
@@ -9344,7 +9523,7 @@ __export(local_snapshot_exports, {
9344
9523
  import {
9345
9524
  existsSync as existsSync29,
9346
9525
  mkdirSync as mkdirSync20,
9347
- readFileSync as readFileSync27,
9526
+ readFileSync as readFileSync28,
9348
9527
  readdirSync as readdirSync6,
9349
9528
  statSync as statSync6,
9350
9529
  writeFileSync as writeFileSync16
@@ -9401,7 +9580,7 @@ async function loadLocalSnapshot(projectRoot, graphStore) {
9401
9580
  try {
9402
9581
  const { unpack } = await import("msgpackr");
9403
9582
  const { gunzipSync: gunzipSync3 } = await import("zlib");
9404
- const raw = readFileSync27(path7);
9583
+ const raw = readFileSync28(path7);
9405
9584
  const buffer = gunzipSync3(raw);
9406
9585
  const envelope = unpack(buffer);
9407
9586
  await graphStore.loadSnapshot(envelope);
@@ -9489,6 +9668,28 @@ var init_local_snapshot = __esm({
9489
9668
  }
9490
9669
  });
9491
9670
 
9671
+ // src/utils/format-error.ts
9672
+ function formatUnknownError(err) {
9673
+ if (err instanceof Error) return err.stack ?? err.message;
9674
+ if (typeof err === "object" && err !== null) {
9675
+ const obj = err;
9676
+ if (typeof obj.display === "string") return obj.display;
9677
+ if (typeof obj.message === "string") return obj.message;
9678
+ try {
9679
+ const serialized = JSON.stringify(err, Object.getOwnPropertyNames(err));
9680
+ if (serialized && serialized !== "{}") return serialized;
9681
+ } catch {
9682
+ }
9683
+ return Object.prototype.toString.call(err);
9684
+ }
9685
+ return String(err);
9686
+ }
9687
+ var init_format_error = __esm({
9688
+ "src/utils/format-error.ts"() {
9689
+ "use strict";
9690
+ }
9691
+ });
9692
+
9492
9693
  // src/intelligence/ast-extractor.ts
9493
9694
  var ast_extractor_exports = {};
9494
9695
  __export(ast_extractor_exports, {
@@ -11047,6 +11248,28 @@ function extractTSEdges(root, edges, entities) {
11047
11248
  }
11048
11249
  }
11049
11250
  }
11251
+ if (n.type === "call_expression") {
11252
+ const func = n.childForFieldName("function");
11253
+ if (func?.type === "import") {
11254
+ const awaitExpr = n.parent;
11255
+ const varDecl = awaitExpr?.type === "await_expression" ? awaitExpr.parent : null;
11256
+ if (varDecl?.type === "variable_declarator") {
11257
+ const pattern = varDecl.childForFieldName("name");
11258
+ if (pattern?.type === "object_pattern") {
11259
+ for (const prop of pattern.namedChildren) {
11260
+ if (prop.type === "shorthand_property_identifier_pattern") {
11261
+ importedNames.add(prop.text);
11262
+ } else if (prop.type === "pair_pattern") {
11263
+ const val = prop.childForFieldName("value");
11264
+ if (val?.type === "identifier") importedNames.add(val.text);
11265
+ }
11266
+ }
11267
+ } else if (pattern?.type === "identifier") {
11268
+ importedNames.add(pattern.text);
11269
+ }
11270
+ }
11271
+ }
11272
+ }
11050
11273
  });
11051
11274
  walkNodes(root, (n) => {
11052
11275
  if (n.type === "import_statement") {
@@ -11116,6 +11339,26 @@ function extractTSEdges(root, edges, entities) {
11116
11339
  if (n.type === "call_expression") {
11117
11340
  const func = n.childForFieldName("function");
11118
11341
  if (!func) return;
11342
+ if (func.type === "import") {
11343
+ const argsNode = n.childForFieldName("arguments");
11344
+ if (argsNode) {
11345
+ const strArg = argsNode.namedChildren.find(
11346
+ (c) => c.type === "string"
11347
+ );
11348
+ if (strArg) {
11349
+ const src = strArg.text.replace(/['"]/g, "");
11350
+ if (src) {
11351
+ edges.push({
11352
+ from_name: "__file__",
11353
+ to_name: "__dynamic_import__",
11354
+ type: "imports",
11355
+ import_source: src
11356
+ });
11357
+ }
11358
+ }
11359
+ }
11360
+ return;
11361
+ }
11119
11362
  let calledName = null;
11120
11363
  if (func.type === "identifier") {
11121
11364
  calledName = func.text;
@@ -11948,12 +12191,12 @@ var init_logger = __esm({
11948
12191
  });
11949
12192
 
11950
12193
  // src/intelligence/indexer/scip/decoder.ts
11951
- import { readFileSync as readFileSync28 } from "fs";
12194
+ import { readFileSync as readFileSync29 } from "fs";
11952
12195
  async function decodeScipOutput(filePath) {
11953
12196
  const start = performance.now();
11954
12197
  let buffer;
11955
12198
  try {
11956
- buffer = readFileSync28(filePath);
12199
+ buffer = readFileSync29(filePath);
11957
12200
  } catch {
11958
12201
  return emptyResult(start);
11959
12202
  }
@@ -11970,7 +12213,7 @@ async function decodeScipOutput(filePath) {
11970
12213
  offset = field.nextOffset;
11971
12214
  if (field.fieldNumber === 2 && field.wireType === 2) {
11972
12215
  const doc = parseDocument(field.data);
11973
- if (doc && doc.relativePath) {
12216
+ if (doc?.relativePath) {
11974
12217
  documents.push(doc);
11975
12218
  symbolCount += doc.symbols.length;
11976
12219
  definitionCount += doc.symbols.filter((s) => s.isDefinition).length;
@@ -12545,7 +12788,6 @@ async function detectScipBinary(language) {
12545
12788
  };
12546
12789
  }
12547
12790
  } catch {
12548
- continue;
12549
12791
  }
12550
12792
  }
12551
12793
  return {
@@ -12823,7 +13065,7 @@ var init_runner = __esm({
12823
13065
  import {
12824
13066
  existsSync as existsSync34,
12825
13067
  mkdirSync as mkdirSync23,
12826
- readFileSync as readFileSync29,
13068
+ readFileSync as readFileSync30,
12827
13069
  statSync as statSync7,
12828
13070
  writeFileSync as writeFileSync17
12829
13071
  } from "fs";
@@ -12876,7 +13118,7 @@ async function enrichWithScip(files, projectRoot, existingEdges, entities, optio
12876
13118
  if (language === "typescript") {
12877
13119
  if (!existsSync34(join37(projectRoot, "tsconfig.json")) && !existsSync34(join37(projectRoot, "jsconfig.json"))) {
12878
13120
  log6.info(
12879
- `SCIP skipping TypeScript: no tsconfig.json or jsconfig.json found in project root. Create one to enable SCIP indexing.`
13121
+ "SCIP skipping TypeScript: no tsconfig.json or jsconfig.json found in project root. Create one to enable SCIP indexing."
12880
13122
  );
12881
13123
  continue;
12882
13124
  }
@@ -12891,7 +13133,7 @@ async function enrichWithScip(files, projectRoot, existingEdges, entities, optio
12891
13133
  const compdbPath = resolveCompileCommandsJson(projectRoot);
12892
13134
  if (!compdbPath) {
12893
13135
  log6.info(
12894
- `SCIP skipping C/C++: no compile_commands.json found. Generate one with CMake (-DCMAKE_EXPORT_COMPILE_COMMANDS=ON), Bear, or your build system.`
13136
+ "SCIP skipping C/C++: no compile_commands.json found. Generate one with CMake (-DCMAKE_EXPORT_COMPILE_COMMANDS=ON), Bear, or your build system."
12895
13137
  );
12896
13138
  continue;
12897
13139
  }
@@ -12966,7 +13208,7 @@ function detectJavaBuildTools(projectRoot) {
12966
13208
  function getStoredBuildTool(projectRoot) {
12967
13209
  try {
12968
13210
  const configPath = join37(projectRoot, ".unerr", "config.json");
12969
- const config = JSON.parse(readFileSync29(configPath, "utf-8"));
13211
+ const config = JSON.parse(readFileSync30(configPath, "utf-8"));
12970
13212
  return config.javaBuildTool ?? null;
12971
13213
  } catch {
12972
13214
  return null;
@@ -12976,7 +13218,7 @@ function storeBuildTool(projectRoot, tool) {
12976
13218
  const configPath = join37(projectRoot, ".unerr", "config.json");
12977
13219
  let config = {};
12978
13220
  try {
12979
- config = JSON.parse(readFileSync29(configPath, "utf-8"));
13221
+ config = JSON.parse(readFileSync30(configPath, "utf-8"));
12980
13222
  } catch {
12981
13223
  }
12982
13224
  config.javaBuildTool = tool;
@@ -13102,13 +13344,13 @@ async function installScipDotnet() {
13102
13344
  const dotnetCheck = await exec("which", ["dotnet"]);
13103
13345
  if (dotnetCheck.exitCode !== 0) {
13104
13346
  log6.warn(
13105
- `SCIP skipping C#: dotnet CLI not found on PATH. Install the .NET SDK to enable SCIP indexing for C#.`
13347
+ "SCIP skipping C#: dotnet CLI not found on PATH. Install the .NET SDK to enable SCIP indexing for C#."
13106
13348
  );
13107
13349
  return false;
13108
13350
  }
13109
13351
  } catch {
13110
13352
  log6.warn(
13111
- `SCIP skipping C#: dotnet CLI not found on PATH. Install the .NET SDK to enable SCIP indexing for C#.`
13353
+ "SCIP skipping C#: dotnet CLI not found on PATH. Install the .NET SDK to enable SCIP indexing for C#."
13112
13354
  );
13113
13355
  return false;
13114
13356
  }
@@ -13192,34 +13434,12 @@ var init_orchestrator = __esm({
13192
13434
  }
13193
13435
  });
13194
13436
 
13195
- // src/utils/format-error.ts
13196
- function formatUnknownError(err) {
13197
- if (err instanceof Error) return err.stack ?? err.message;
13198
- if (typeof err === "object" && err !== null) {
13199
- const obj = err;
13200
- if (typeof obj.display === "string") return obj.display;
13201
- if (typeof obj.message === "string") return obj.message;
13202
- try {
13203
- const serialized = JSON.stringify(err, Object.getOwnPropertyNames(err));
13204
- if (serialized && serialized !== "{}") return serialized;
13205
- } catch {
13206
- }
13207
- return Object.prototype.toString.call(err);
13208
- }
13209
- return String(err);
13210
- }
13211
- var init_format_error = __esm({
13212
- "src/utils/format-error.ts"() {
13213
- "use strict";
13214
- }
13215
- });
13216
-
13217
13437
  // src/intelligence/local-convention-detector.ts
13218
13438
  var local_convention_detector_exports = {};
13219
13439
  __export(local_convention_detector_exports, {
13220
13440
  detectLocalConventions: () => detectLocalConventions
13221
13441
  });
13222
- import { dirname as dirname8 } from "path";
13442
+ import { dirname as dirname11 } from "path";
13223
13443
  async function detectLocalConventions(db) {
13224
13444
  const start = Date.now();
13225
13445
  const entities = await queryAllEntities(db);
@@ -13364,7 +13584,7 @@ function detectFileStructurePatterns(entities) {
13364
13584
  const conventions = [];
13365
13585
  const byDir = /* @__PURE__ */ new Map();
13366
13586
  for (const e of entities) {
13367
- const dir = dirname8(e.file_path);
13587
+ const dir = dirname11(e.file_path);
13368
13588
  const existing = byDir.get(dir);
13369
13589
  if (existing) {
13370
13590
  existing.push(e);
@@ -13394,8 +13614,8 @@ function detectFileStructurePatterns(entities) {
13394
13614
  (e) => e.file_path.endsWith("/index.ts") || e.file_path.endsWith("/index.js") || e.file_path === "index.ts" || e.file_path === "index.js"
13395
13615
  );
13396
13616
  if (indexFiles.length >= MIN_SAMPLE_SIZE) {
13397
- const dirsWithIndex = new Set(indexFiles.map((e) => dirname8(e.file_path)));
13398
- const totalDirs = new Set(entities.map((e) => dirname8(e.file_path))).size;
13617
+ const dirsWithIndex = new Set(indexFiles.map((e) => dirname11(e.file_path)));
13618
+ const totalDirs = new Set(entities.map((e) => dirname11(e.file_path))).size;
13399
13619
  if (totalDirs > 0) {
13400
13620
  const adherence = dirsWithIndex.size / totalDirs;
13401
13621
  if (adherence >= 0.3) {
@@ -13484,8 +13704,8 @@ function detectImportDirectionPatterns(entities, edges, communities) {
13484
13704
  const fromEntity = entities.find((e) => e.key === edge.from_key);
13485
13705
  const toEntity = entities.find((e) => e.key === edge.to_key);
13486
13706
  if (!fromEntity || !toEntity) continue;
13487
- const fromDir = dirname8(fromEntity.file_path);
13488
- const toDir = dirname8(toEntity.file_path);
13707
+ const fromDir = dirname11(fromEntity.file_path);
13708
+ const toDir = dirname11(toEntity.file_path);
13489
13709
  if (fromDir === toDir) continue;
13490
13710
  const fromStats = dirImports.get(fromDir) ?? { inbound: 0, outbound: 0 };
13491
13711
  fromStats.outbound++;
@@ -13512,8 +13732,8 @@ function detectImportDirectionPatterns(entities, edges, communities) {
13512
13732
  const fromEntity = entities.find((e) => e.key === edge.from_key);
13513
13733
  const toEntity = entities.find((e) => e.key === edge.to_key);
13514
13734
  if (!fromEntity || !toEntity) continue;
13515
- const fromDir = dirname8(fromEntity.file_path);
13516
- const toDir = dirname8(toEntity.file_path);
13735
+ const fromDir = dirname11(fromEntity.file_path);
13736
+ const toDir = dirname11(toEntity.file_path);
13517
13737
  if (fromDir === toDir) continue;
13518
13738
  const pairKey2 = `${fromDir}->${toDir}`;
13519
13739
  layerPairs.set(pairKey2, (layerPairs.get(pairKey2) ?? 0) + 1);
@@ -13738,7 +13958,7 @@ __export(local_indexer_exports, {
13738
13958
  runCommunityDetection: () => runCommunityDetection,
13739
13959
  runConventionDetection: () => runConventionDetection
13740
13960
  });
13741
- import { readFileSync as readFileSync30, readdirSync as readdirSync8, statSync as statSync8 } from "fs";
13961
+ import { readFileSync as readFileSync31, readdirSync as readdirSync8, statSync as statSync8 } from "fs";
13742
13962
  import { basename as basename3, extname as extname2, join as join38, relative as relative2 } from "path";
13743
13963
  function isExcludedPath(relPath) {
13744
13964
  for (const prefix of EXCLUDED_PATH_PREFIXES) {
@@ -13772,7 +13992,7 @@ async function indexLocalProject(projectRoot, graphStore, repoId, opts) {
13772
13992
  });
13773
13993
  let content;
13774
13994
  try {
13775
- content = readFileSync30(absPath, "utf-8");
13995
+ content = readFileSync31(absPath, "utf-8");
13776
13996
  } catch {
13777
13997
  filesProcessed++;
13778
13998
  continue;
@@ -13959,7 +14179,7 @@ async function reindexFile(projectRoot, filePath, graphStore, repoId) {
13959
14179
  await removeFileEntities(graphStore, relPath);
13960
14180
  let content;
13961
14181
  try {
13962
- content = readFileSync30(absPath, "utf-8");
14182
+ content = readFileSync31(absPath, "utf-8");
13963
14183
  } catch {
13964
14184
  return { entities: 0, edges: 0 };
13965
14185
  }
@@ -14153,7 +14373,7 @@ function resolveImportSourceToFile(importSource, sourceFile, projectFiles) {
14153
14373
  for (let i = Math.max(0, segments.length - 3); i < segments.length; i++) {
14154
14374
  const suffix = segments.slice(i).join("/");
14155
14375
  for (const fp of projectFiles) {
14156
- if (fp.endsWith(".go") && fp.includes(suffix + "/")) {
14376
+ if (fp.endsWith(".go") && fp.includes(`${suffix}/`)) {
14157
14377
  return fp;
14158
14378
  }
14159
14379
  const dir = fp.substring(0, fp.lastIndexOf("/"));
@@ -14184,9 +14404,7 @@ function resolveImportSourceToFile(importSource, sourceFile, projectFiles) {
14184
14404
  function resolveRelativeImport(importSource, sourceFile, projectFiles) {
14185
14405
  const sourceDir = sourceFile.substring(0, sourceFile.lastIndexOf("/"));
14186
14406
  const candidates = [];
14187
- const parts = (sourceDir + "/" + importSource.replace(/^\.\//, "")).split(
14188
- "/"
14189
- );
14407
+ const parts = `${sourceDir}/${importSource.replace(/^\.\//, "")}`.split("/");
14190
14408
  const resolved = [];
14191
14409
  for (const p of parts) {
14192
14410
  if (p === "..") resolved.pop();
@@ -14843,21 +15061,25 @@ function extractDocTokens(absPath, relPath) {
14843
15061
  }
14844
15062
  const ext = extname2(absPath).toLowerCase();
14845
15063
  try {
14846
- const content = readFileSync30(absPath, "utf-8").slice(0, DOC_READ_LIMIT);
15064
+ const content = readFileSync31(absPath, "utf-8").slice(0, DOC_READ_LIMIT);
14847
15065
  const pattern = DOC_TOKEN_PATTERNS[ext];
14848
15066
  if (pattern) {
14849
15067
  pattern.lastIndex = 0;
14850
15068
  let match;
14851
- while ((match = pattern.exec(content)) !== null) {
15069
+ match = pattern.exec(content);
15070
+ while (match !== null) {
14852
15071
  if (match[1]) for (const t of tokenize(match[1])) tokens.add(t);
14853
15072
  if (match[2]) for (const t of tokenize(match[2])) tokens.add(t);
15073
+ match = pattern.exec(content);
14854
15074
  }
14855
15075
  }
14856
15076
  if (ext === ".yaml" || ext === ".yml") {
14857
15077
  const yamlKeyRegex = /^([a-zA-Z_][\w-]*)\s*:/gm;
14858
15078
  let match;
14859
- while ((match = yamlKeyRegex.exec(content)) !== null) {
15079
+ match = yamlKeyRegex.exec(content);
15080
+ while (match !== null) {
14860
15081
  if (match[1]) for (const t of tokenize(match[1])) tokens.add(t);
15082
+ match = yamlKeyRegex.exec(content);
14861
15083
  }
14862
15084
  }
14863
15085
  } catch {
@@ -14910,12 +15132,12 @@ var INDEXABLE_EXTENSIONS, EXCLUDED_DIRS2, EXCLUDED_PATH_PREFIXES, MAX_FILE_SIZE,
14910
15132
  var init_local_indexer = __esm({
14911
15133
  "src/intelligence/local-indexer.ts"() {
14912
15134
  "use strict";
15135
+ init_format_error();
14913
15136
  init_ast_extractor();
14914
15137
  init_community_detection();
14915
15138
  init_git_cochange();
14916
15139
  init_orchestrator();
14917
15140
  init_test_detector();
14918
- init_format_error();
14919
15141
  init_local_convention_detector();
14920
15142
  init_local_rule_generator();
14921
15143
  init_local_snapshot();
@@ -15586,14 +15808,14 @@ __export(resolver_exports, {
15586
15808
  import {
15587
15809
  existsSync as existsSync39,
15588
15810
  mkdirSync as mkdirSync27,
15589
- readFileSync as readFileSync33,
15811
+ readFileSync as readFileSync34,
15590
15812
  readdirSync as readdirSync9,
15591
15813
  rmSync,
15592
15814
  unlinkSync as unlinkSync10,
15593
15815
  writeFileSync as writeFileSync21
15594
15816
  } from "fs";
15595
15817
  import { homedir as homedir15 } from "os";
15596
- import { dirname as dirname10, join as join43 } from "path";
15818
+ import { dirname as dirname13, join as join43 } from "path";
15597
15819
  function getSkillDir(ide, cwd) {
15598
15820
  switch (ide) {
15599
15821
  case "claude-code":
@@ -15826,11 +16048,9 @@ globs:
15826
16048
  ${globs.map((g) => ` - ${g}`).join("\n")}`;
15827
16049
  }
15828
16050
  if (triggerType === "manual") {
15829
- frontmatter += `
15830
- user_invocable: true`;
16051
+ frontmatter += "\nuser_invocable: true";
15831
16052
  }
15832
- frontmatter += `
15833
- ---`;
16053
+ frontmatter += "\n---";
15834
16054
  return `${frontmatter}
15835
16055
 
15836
16056
  ${skill.content}
@@ -15873,7 +16093,7 @@ function scanSkillDirectory(dir) {
15873
16093
  const files = readdirSync9(dir).filter((f) => f.endsWith(".md"));
15874
16094
  for (const file of files) {
15875
16095
  try {
15876
- const raw = readFileSync33(join43(dir, file), "utf-8");
16096
+ const raw = readFileSync34(join43(dir, file), "utf-8");
15877
16097
  const { meta, content } = parseFrontmatter(raw);
15878
16098
  const name = meta.name ?? file.replace(/\.md$/, "");
15879
16099
  skills.push({
@@ -15967,7 +16187,7 @@ function removeInstalledSkills(ide, cwd) {
15967
16187
  for (const skill of skills) {
15968
16188
  try {
15969
16189
  if (dirPerSkill) {
15970
- rmSync(dirname10(skill.path), { recursive: true, force: true });
16190
+ rmSync(dirname13(skill.path), { recursive: true, force: true });
15971
16191
  } else {
15972
16192
  unlinkSync10(skill.path);
15973
16193
  }
@@ -15989,7 +16209,7 @@ var correction_detector_exports = {};
15989
16209
  __export(correction_detector_exports, {
15990
16210
  detectCorrections: () => detectCorrections
15991
16211
  });
15992
- import { existsSync as existsSync41, readFileSync as readFileSync35 } from "fs";
16212
+ import { existsSync as existsSync41, readFileSync as readFileSync36 } from "fs";
15993
16213
  function detectCorrections(ledgerPath, options) {
15994
16214
  const MIN_CONFIDENCE = options?.min_confidence ?? 0.6;
15995
16215
  const CORRECTION_WINDOW = options?.correction_window_ms ?? 6e4;
@@ -16016,7 +16236,7 @@ function readLedgerEntries(ledgerPath, sinceDays) {
16016
16236
  const cutoff = Date.now() - sinceDays * 24 * 60 * 60 * 1e3;
16017
16237
  const entries = [];
16018
16238
  try {
16019
- const content = readFileSync35(ledgerPath, "utf-8");
16239
+ const content = readFileSync36(ledgerPath, "utf-8");
16020
16240
  const lines = content.split("\n");
16021
16241
  for (const line of lines) {
16022
16242
  if (line.trim().length === 0) continue;
@@ -16223,7 +16443,7 @@ import {
16223
16443
  appendFileSync as appendFileSync5,
16224
16444
  existsSync as existsSync44,
16225
16445
  mkdirSync as mkdirSync29,
16226
- readFileSync as readFileSync37,
16446
+ readFileSync as readFileSync38,
16227
16447
  writeFileSync as writeFileSync23
16228
16448
  } from "fs";
16229
16449
  import { join as join47 } from "path";
@@ -16364,7 +16584,7 @@ function readBranchCounter(unerrDir) {
16364
16584
  const contextPath = join47(unerrDir, "ledger", "branch_context.json");
16365
16585
  if (!existsSync44(contextPath)) return 1;
16366
16586
  try {
16367
- const data = JSON.parse(readFileSync37(contextPath, "utf-8"));
16587
+ const data = JSON.parse(readFileSync38(contextPath, "utf-8"));
16368
16588
  return data.timeline_branch ?? 1;
16369
16589
  } catch {
16370
16590
  return 1;
@@ -16379,7 +16599,7 @@ function incrementBranchCounter(unerrDir) {
16379
16599
  let data = {};
16380
16600
  if (existsSync44(contextPath)) {
16381
16601
  try {
16382
- data = JSON.parse(readFileSync37(contextPath, "utf-8"));
16602
+ data = JSON.parse(readFileSync38(contextPath, "utf-8"));
16383
16603
  } catch {
16384
16604
  }
16385
16605
  }
@@ -16400,7 +16620,7 @@ function markEntriesReverted(unerrDir, entryIds) {
16400
16620
  let existing = [];
16401
16621
  if (existsSync44(revertedPath)) {
16402
16622
  try {
16403
- existing = JSON.parse(readFileSync37(revertedPath, "utf-8"));
16623
+ existing = JSON.parse(readFileSync38(revertedPath, "utf-8"));
16404
16624
  } catch {
16405
16625
  }
16406
16626
  }
@@ -16631,7 +16851,7 @@ import {
16631
16851
  appendFileSync as appendFileSync6,
16632
16852
  existsSync as existsSync45,
16633
16853
  mkdirSync as mkdirSync30,
16634
- readFileSync as readFileSync38,
16854
+ readFileSync as readFileSync39,
16635
16855
  writeFileSync as writeFileSync24
16636
16856
  } from "fs";
16637
16857
  import { join as join48 } from "path";
@@ -16798,7 +17018,7 @@ var init_shadow_ledger = __esm({
16798
17018
  readAllEntries() {
16799
17019
  if (!existsSync45(this.filePath)) return [];
16800
17020
  try {
16801
- const content = readFileSync38(this.filePath, "utf-8");
17021
+ const content = readFileSync39(this.filePath, "utf-8");
16802
17022
  const lines = content.split("\n").filter((l) => l.trim().length > 0);
16803
17023
  return lines.map((line) => JSON.parse(line));
16804
17024
  } catch {
@@ -16837,7 +17057,7 @@ var init_shadow_ledger = __esm({
16837
17057
  recoverFile() {
16838
17058
  if (!existsSync45(this.filePath)) return;
16839
17059
  try {
16840
- const content = readFileSync38(this.filePath, "utf-8");
17060
+ const content = readFileSync39(this.filePath, "utf-8");
16841
17061
  const lines = content.split("\n");
16842
17062
  const validLines = [];
16843
17063
  for (const line of lines) {
@@ -16870,7 +17090,7 @@ var init_shadow_ledger = __esm({
16870
17090
  loadRecentEntries() {
16871
17091
  if (!existsSync45(this.filePath)) return;
16872
17092
  try {
16873
- const content = readFileSync38(this.filePath, "utf-8");
17093
+ const content = readFileSync39(this.filePath, "utf-8");
16874
17094
  const lines = content.split("\n").filter((l) => l.trim().length > 0);
16875
17095
  const start = Math.max(0, lines.length - MAX_BUFFER_SIZE);
16876
17096
  for (let i = start; i < lines.length; i++) {
@@ -16900,7 +17120,7 @@ var init_shadow_ledger = __esm({
16900
17120
  countEntries() {
16901
17121
  if (!existsSync45(this.filePath)) return 0;
16902
17122
  try {
16903
- const content = readFileSync38(this.filePath, "utf-8");
17123
+ const content = readFileSync39(this.filePath, "utf-8");
16904
17124
  return content.split("\n").filter((l) => l.trim().length > 0).length;
16905
17125
  } catch {
16906
17126
  return 0;
@@ -16925,7 +17145,7 @@ __export(timeline_fork_exports, {
16925
17145
  resetTimelineForks: () => resetTimelineForks,
16926
17146
  wasForkPoint: () => wasForkPoint
16927
17147
  });
16928
- import { existsSync as existsSync46, mkdirSync as mkdirSync31, readFileSync as readFileSync39, writeFileSync as writeFileSync25 } from "fs";
17148
+ import { existsSync as existsSync46, mkdirSync as mkdirSync31, readFileSync as readFileSync40, writeFileSync as writeFileSync25 } from "fs";
16929
17149
  import { join as join49 } from "path";
16930
17150
  function createTimelineFork(snapshotId, abandonedEntities, prompts, reason, unerrDir) {
16931
17151
  const state = unerrDir ? loadState(unerrDir) : { activeTimeline: inMemoryTimeline, forks: [] };
@@ -17066,7 +17286,7 @@ function loadState(unerrDir) {
17066
17286
  return { activeTimeline: 0, forks: [] };
17067
17287
  }
17068
17288
  try {
17069
- const raw = readFileSync39(path7, "utf-8");
17289
+ const raw = readFileSync40(path7, "utf-8");
17070
17290
  const parsed = JSON.parse(raw);
17071
17291
  return {
17072
17292
  activeTimeline: typeof parsed.activeTimeline === "number" ? parsed.activeTimeline : 0,
@@ -17142,9 +17362,9 @@ function createEmptyAllTime() {
17142
17362
  function loadStats() {
17143
17363
  const currentWeek = getWeekStart();
17144
17364
  try {
17145
- const { readFileSync: readFileSync67 } = __require("fs");
17365
+ const { readFileSync: readFileSync68 } = __require("fs");
17146
17366
  const raw = JSON.parse(
17147
- readFileSync67(getStatsPath(), "utf-8")
17367
+ readFileSync68(getStatsPath(), "utf-8")
17148
17368
  );
17149
17369
  if (raw.version !== 1) {
17150
17370
  return {
@@ -17271,7 +17491,7 @@ __export(branch_context_exports, {
17271
17491
  getHeadSha: () => getHeadSha2,
17272
17492
  startBranchPoller: () => startBranchPoller
17273
17493
  });
17274
- import { existsSync as existsSync47, readFileSync as readFileSync40 } from "fs";
17494
+ import { existsSync as existsSync47, readFileSync as readFileSync41 } from "fs";
17275
17495
  import { join as join51 } from "path";
17276
17496
  async function computeBranchContext(cwd) {
17277
17497
  const dir = cwd ?? process.cwd();
@@ -17338,7 +17558,7 @@ function getCurrentBranch2(cwd) {
17338
17558
  const headPath = join51(gitDir, "HEAD");
17339
17559
  if (!existsSync47(headPath)) return null;
17340
17560
  try {
17341
- const content = readFileSync40(headPath, "utf-8").trim();
17561
+ const content = readFileSync41(headPath, "utf-8").trim();
17342
17562
  if (content.startsWith("ref: refs/heads/")) {
17343
17563
  return content.slice("ref: refs/heads/".length);
17344
17564
  }
@@ -17861,9 +18081,9 @@ function getCumulativePath() {
17861
18081
  function loadCumulativeStats() {
17862
18082
  const currentWeek = getWeekStart2();
17863
18083
  try {
17864
- const { readFileSync: readFileSync67 } = __require("fs");
18084
+ const { readFileSync: readFileSync68 } = __require("fs");
17865
18085
  const raw = JSON.parse(
17866
- readFileSync67(getCumulativePath(), "utf-8")
18086
+ readFileSync68(getCumulativePath(), "utf-8")
17867
18087
  );
17868
18088
  if (raw.weekStart !== currentWeek) {
17869
18089
  return {
@@ -17924,9 +18144,9 @@ function createEmptyCumulativeLocal(weekStart) {
17924
18144
  function loadCumulativeLocalStats() {
17925
18145
  const currentWeek = getWeekStart2();
17926
18146
  try {
17927
- const { readFileSync: readFileSync67 } = __require("fs");
18147
+ const { readFileSync: readFileSync68 } = __require("fs");
17928
18148
  const raw = JSON.parse(
17929
- readFileSync67(getCumulativeLocalPath(), "utf-8")
18149
+ readFileSync68(getCumulativeLocalPath(), "utf-8")
17930
18150
  );
17931
18151
  if (raw.weekStartDate !== currentWeek) {
17932
18152
  return createEmptyCumulativeLocal(currentWeek);
@@ -18524,6 +18744,63 @@ var init_render = __esm({
18524
18744
  }
18525
18745
  });
18526
18746
 
18747
+ // src/proxy/arg-validator.ts
18748
+ function normalizeArgAliases(toolDef, args) {
18749
+ const props = toolDef.inputSchema.properties;
18750
+ for (const [canonical, aliases] of Object.entries(ALIAS_MAP)) {
18751
+ if (!(canonical in props)) continue;
18752
+ if (args[canonical] !== void 0 && args[canonical] !== null && args[canonical] !== "") {
18753
+ continue;
18754
+ }
18755
+ for (const alias of aliases) {
18756
+ const v = args[alias];
18757
+ if (typeof v === "string" && v.trim() !== "") {
18758
+ args[canonical] = v;
18759
+ break;
18760
+ }
18761
+ if (typeof v === "number" || typeof v === "boolean") {
18762
+ args[canonical] = v;
18763
+ break;
18764
+ }
18765
+ }
18766
+ }
18767
+ }
18768
+ function validateRequiredArgs(toolDef, args) {
18769
+ const required = toolDef.inputSchema.required ?? [];
18770
+ if (required.length === 0) return null;
18771
+ const missing = required.filter((field) => {
18772
+ const v = args[field];
18773
+ if (v === void 0 || v === null) return true;
18774
+ if (typeof v === "string" && v.trim() === "") return true;
18775
+ return false;
18776
+ });
18777
+ if (missing.length === 0) return null;
18778
+ const props = toolDef.inputSchema.properties;
18779
+ const details = missing.map((m) => {
18780
+ const desc = props[m]?.description?.trim();
18781
+ return desc ? `${m}: ${desc}` : `${m}: required`;
18782
+ }).join("; ");
18783
+ return {
18784
+ error: `${toolDef.name}: missing required parameter(s): ${missing.join(", ")}`,
18785
+ required: missing,
18786
+ details
18787
+ };
18788
+ }
18789
+ function aliasAndValidate(toolDef, args) {
18790
+ normalizeArgAliases(toolDef, args);
18791
+ return validateRequiredArgs(toolDef, args);
18792
+ }
18793
+ var ALIAS_MAP;
18794
+ var init_arg_validator = __esm({
18795
+ "src/proxy/arg-validator.ts"() {
18796
+ "use strict";
18797
+ ALIAS_MAP = {
18798
+ key: ["entity_name", "entity"],
18799
+ file_path: ["file", "path"]
18800
+ };
18801
+ }
18802
+ });
18803
+
18527
18804
  // src/proxy/pid-lock.ts
18528
18805
  var pid_lock_exports = {};
18529
18806
  __export(pid_lock_exports, {
@@ -18532,7 +18809,7 @@ __export(pid_lock_exports, {
18532
18809
  import {
18533
18810
  existsSync as existsSync51,
18534
18811
  mkdirSync as mkdirSync32,
18535
- readFileSync as readFileSync44,
18812
+ readFileSync as readFileSync45,
18536
18813
  unlinkSync as unlinkSync12,
18537
18814
  writeFileSync as writeFileSync27
18538
18815
  } from "fs";
@@ -18619,7 +18896,7 @@ var init_pid_lock = __esm({
18619
18896
  }
18620
18897
  if (existsSync51(this.pidPath)) {
18621
18898
  try {
18622
- const raw = readFileSync44(this.pidPath, "utf-8").trim();
18899
+ const raw = readFileSync45(this.pidPath, "utf-8").trim();
18623
18900
  const pidData = parsePidFile(raw);
18624
18901
  if (pidData && isProcessAlive2(pidData.pid)) {
18625
18902
  if (pidData.healthPort) {
@@ -18682,7 +18959,7 @@ var init_pid_lock = __esm({
18682
18959
  writeFileSync27(this.pidPath, JSON.stringify(data), "utf-8");
18683
18960
  }
18684
18961
  async startHealthServer() {
18685
- return new Promise((resolve6) => {
18962
+ return new Promise((resolve9) => {
18686
18963
  this.healthServer = createServer2((req, res) => {
18687
18964
  if (req.url === "/health" && req.method === "GET") {
18688
18965
  const uptimeS = Math.round(
@@ -18706,7 +18983,7 @@ var init_pid_lock = __esm({
18706
18983
  this.healthServer.listen(0, "127.0.0.1", () => {
18707
18984
  const addr = this.healthServer?.address();
18708
18985
  this.healthPort = typeof addr === "object" && addr ? addr.port : 0;
18709
- resolve6();
18986
+ resolve9();
18710
18987
  });
18711
18988
  this.healthServer.unref();
18712
18989
  });
@@ -18725,7 +19002,7 @@ var init_pid_lock = __esm({
18725
19002
  }
18726
19003
  try {
18727
19004
  if (existsSync51(this.pidPath)) {
18728
- const raw = readFileSync44(this.pidPath, "utf-8").trim();
19005
+ const raw = readFileSync45(this.pidPath, "utf-8").trim();
18729
19006
  const data = parsePidFile(raw);
18730
19007
  if (data && data.pid === process.pid) {
18731
19008
  unlinkSync12(this.pidPath);
@@ -18740,7 +19017,7 @@ var init_pid_lock = __esm({
18740
19017
  isLocked() {
18741
19018
  if (!existsSync51(this.pidPath)) return { locked: false };
18742
19019
  try {
18743
- const raw = readFileSync44(this.pidPath, "utf-8").trim();
19020
+ const raw = readFileSync45(this.pidPath, "utf-8").trim();
18744
19021
  const data = parsePidFile(raw);
18745
19022
  if (data && isProcessAlive2(data.pid)) {
18746
19023
  return { locked: true, pid: data.pid, healthPort: data.healthPort };
@@ -18757,7 +19034,7 @@ var init_pid_lock = __esm({
18757
19034
  async probe() {
18758
19035
  if (!existsSync51(this.pidPath)) return { alive: false };
18759
19036
  try {
18760
- const raw = readFileSync44(this.pidPath, "utf-8").trim();
19037
+ const raw = readFileSync45(this.pidPath, "utf-8").trim();
18761
19038
  const pidData = parsePidFile(raw);
18762
19039
  if (!pidData || !isProcessAlive2(pidData.pid)) return { alive: false };
18763
19040
  if (pidData.healthPort) {
@@ -18776,7 +19053,7 @@ var init_pid_lock = __esm({
18776
19053
  const pidPath2 = join55(stateDir, PID_FILENAME);
18777
19054
  if (!existsSync51(pidPath2)) return null;
18778
19055
  try {
18779
- const raw = readFileSync44(pidPath2, "utf-8").trim();
19056
+ const raw = readFileSync45(pidPath2, "utf-8").trim();
18780
19057
  const data = parsePidFile(raw);
18781
19058
  if (data && isProcessAlive2(data.pid)) return data;
18782
19059
  return null;
@@ -19005,7 +19282,7 @@ var init_deep_link = __esm({
19005
19282
  });
19006
19283
 
19007
19284
  // src/proxy/startup-renderer.ts
19008
- import { existsSync as existsSync52, readFileSync as readFileSync45, writeFileSync as writeFileSync28 } from "fs";
19285
+ import { existsSync as existsSync52, readFileSync as readFileSync46, writeFileSync as writeFileSync28 } from "fs";
19009
19286
  import { join as join56 } from "path";
19010
19287
  import React2 from "react";
19011
19288
  var StartupRenderer;
@@ -19120,7 +19397,7 @@ var init_startup_renderer = __esm({
19120
19397
  );
19121
19398
  if (!existsSync52(versionPath)) return true;
19122
19399
  try {
19123
- const data = JSON.parse(readFileSync45(versionPath, "utf-8"));
19400
+ const data = JSON.parse(readFileSync46(versionPath, "utf-8"));
19124
19401
  return !data.first_boot_shown;
19125
19402
  } catch {
19126
19403
  return true;
@@ -19132,7 +19409,7 @@ var init_startup_renderer = __esm({
19132
19409
  try {
19133
19410
  let data = {};
19134
19411
  if (existsSync52(versionPath)) {
19135
- data = JSON.parse(readFileSync45(versionPath, "utf-8"));
19412
+ data = JSON.parse(readFileSync46(versionPath, "utf-8"));
19136
19413
  }
19137
19414
  data.first_boot_shown = true;
19138
19415
  writeFileSync28(versionPath, JSON.stringify(data, null, 2));
@@ -19904,63 +20181,6 @@ var init_tool_definitions = __esm({
19904
20181
  }
19905
20182
  });
19906
20183
 
19907
- // src/proxy/arg-validator.ts
19908
- function normalizeArgAliases(toolDef, args) {
19909
- const props = toolDef.inputSchema.properties;
19910
- for (const [canonical, aliases] of Object.entries(ALIAS_MAP)) {
19911
- if (!(canonical in props)) continue;
19912
- if (args[canonical] !== void 0 && args[canonical] !== null && args[canonical] !== "") {
19913
- continue;
19914
- }
19915
- for (const alias of aliases) {
19916
- const v = args[alias];
19917
- if (typeof v === "string" && v.trim() !== "") {
19918
- args[canonical] = v;
19919
- break;
19920
- }
19921
- if (typeof v === "number" || typeof v === "boolean") {
19922
- args[canonical] = v;
19923
- break;
19924
- }
19925
- }
19926
- }
19927
- }
19928
- function validateRequiredArgs(toolDef, args) {
19929
- const required = toolDef.inputSchema.required ?? [];
19930
- if (required.length === 0) return null;
19931
- const missing = required.filter((field) => {
19932
- const v = args[field];
19933
- if (v === void 0 || v === null) return true;
19934
- if (typeof v === "string" && v.trim() === "") return true;
19935
- return false;
19936
- });
19937
- if (missing.length === 0) return null;
19938
- const props = toolDef.inputSchema.properties;
19939
- const details = missing.map((m) => {
19940
- const desc = props[m]?.description?.trim();
19941
- return desc ? `${m}: ${desc}` : `${m}: required`;
19942
- }).join("; ");
19943
- return {
19944
- error: `${toolDef.name}: missing required parameter(s): ${missing.join(", ")}`,
19945
- required: missing,
19946
- details
19947
- };
19948
- }
19949
- function aliasAndValidate(toolDef, args) {
19950
- normalizeArgAliases(toolDef, args);
19951
- return validateRequiredArgs(toolDef, args);
19952
- }
19953
- var ALIAS_MAP;
19954
- var init_arg_validator = __esm({
19955
- "src/proxy/arg-validator.ts"() {
19956
- "use strict";
19957
- ALIAS_MAP = {
19958
- key: ["entity_name", "entity"],
19959
- file_path: ["file", "path"]
19960
- };
19961
- }
19962
- });
19963
-
19964
20184
  // src/utils/mcp-content-json.ts
19965
20185
  function stringifyMcpToolJson(value) {
19966
20186
  return JSON.stringify(value);
@@ -20554,7 +20774,7 @@ var init_temporal_facts = __esm({
20554
20774
  const scopes = [filePath];
20555
20775
  const parts = filePath.split("/");
20556
20776
  for (let i = parts.length - 1; i > 0; i--) {
20557
- scopes.push(parts.slice(0, i).join("/") + "/");
20777
+ scopes.push(`${parts.slice(0, i).join("/")}/`);
20558
20778
  }
20559
20779
  scopes.push("project");
20560
20780
  return scopes;
@@ -20735,7 +20955,7 @@ var init_temporal_facts = __esm({
20735
20955
  filter_subject: subject
20736
20956
  }
20737
20957
  );
20738
- return result.rows.length > 0 ? result.rows[0][0] : null;
20958
+ return result.rows.length > 0 ? result.rows[0]?.[0] : null;
20739
20959
  }
20740
20960
  async getRawFact(factId) {
20741
20961
  const result = await this.db.run(
@@ -20999,7 +21219,7 @@ __export(fact_generator_exports, {
20999
21219
  generateFromSessionAnalysis: () => generateFromSessionAnalysis,
21000
21220
  runFactGenerationPipeline: () => runFactGenerationPipeline
21001
21221
  });
21002
- import { existsSync as existsSync54, readFileSync as readFileSync46, readdirSync as readdirSync11 } from "fs";
21222
+ import { existsSync as existsSync54, readFileSync as readFileSync47, readdirSync as readdirSync11 } from "fs";
21003
21223
  import { join as join58 } from "path";
21004
21224
  async function runFactGenerationPipeline(factStore, unerrDir) {
21005
21225
  const results = [];
@@ -21168,7 +21388,7 @@ function loadRecentSessions(unerrDir, limit) {
21168
21388
  const summaries = [];
21169
21389
  for (const file of files) {
21170
21390
  try {
21171
- const content = readFileSync46(join58(sessionsDir, file), "utf-8");
21391
+ const content = readFileSync47(join58(sessionsDir, file), "utf-8");
21172
21392
  const lines = content.trim().split("\n").filter(Boolean);
21173
21393
  const lastLine = lines[lines.length - 1];
21174
21394
  if (lastLine) {
@@ -22279,7 +22499,7 @@ function signalId(s) {
22279
22499
  return h.toString(16).padStart(8, "0");
22280
22500
  }
22281
22501
  function computeComposite(actionability, relevance, confidence) {
22282
- return Math.pow(actionability, 1.5) * relevance * confidence;
22502
+ return actionability ** 1.5 * relevance * confidence;
22283
22503
  }
22284
22504
  function createSignal(params) {
22285
22505
  return {
@@ -23655,7 +23875,7 @@ __export(import_symbols_exports, {
23655
23875
  parseImportSymbols: () => parseImportSymbols
23656
23876
  });
23657
23877
  import { promises as fs4 } from "fs";
23658
- import { isAbsolute, resolve as resolve3 } from "path";
23878
+ import { isAbsolute, resolve as resolve6 } from "path";
23659
23879
  function parseClause(clause) {
23660
23880
  const symbols = [];
23661
23881
  const trimmed = clause.trim();
@@ -23728,7 +23948,7 @@ function parseImportSymbols(source) {
23728
23948
  return out;
23729
23949
  }
23730
23950
  async function loadImportSymbols(projectRoot, filePath) {
23731
- const abs = isAbsolute(filePath) ? filePath : resolve3(projectRoot, filePath);
23951
+ const abs = isAbsolute(filePath) ? filePath : resolve6(projectRoot, filePath);
23732
23952
  try {
23733
23953
  const text2 = await fs4.readFile(abs, "utf8");
23734
23954
  return parseImportSymbols(text2);
@@ -23751,8 +23971,8 @@ __export(file_outline_exports, {
23751
23971
  buildFileOutline: () => buildFileOutline,
23752
23972
  fileOutlineTool: () => fileOutlineTool
23753
23973
  });
23754
- import { existsSync as existsSync55, readFileSync as readFileSync47 } from "fs";
23755
- import { relative as relative3, resolve as resolve4 } from "path";
23974
+ import { existsSync as existsSync55, readFileSync as readFileSync48 } from "fs";
23975
+ import { relative as relative3, resolve as resolve7 } from "path";
23756
23976
  function normRisk(rl) {
23757
23977
  const x2 = (rl ?? "low").toLowerCase();
23758
23978
  if (x2 === "critical") return "critical";
@@ -23790,12 +24010,12 @@ function detectExportedNames(lines, scanLimit) {
23790
24010
  const m = /^export\s+(?:default\s+)?(?:async\s+)?(?:function\*?\s+|const\s+|let\s+|var\s+|class\s+|interface\s+|type\s+|enum\s+)(\w+)/.exec(
23791
24011
  t
23792
24012
  );
23793
- if (m && m[1]) {
24013
+ if (m?.[1]) {
23794
24014
  exported.add(m[1]);
23795
24015
  continue;
23796
24016
  }
23797
24017
  const braceMatch = /^export\s*\{([^}]+)\}/.exec(t);
23798
- if (braceMatch && braceMatch[1]) {
24018
+ if (braceMatch?.[1]) {
23799
24019
  const names = braceMatch[1].split(",").map((n) => {
23800
24020
  const asMatch = /(\w+)\s+as\s+\w+/.exec(n.trim());
23801
24021
  return asMatch ? asMatch[1] : n.trim();
@@ -23808,12 +24028,12 @@ function detectExportedNames(lines, scanLimit) {
23808
24028
  return exported;
23809
24029
  }
23810
24030
  async function buildFileOutline(params) {
23811
- const abs = resolve4(params.cwd, params.filePathArg);
24031
+ const abs = resolve7(params.cwd, params.filePathArg);
23812
24032
  const rel = relative3(params.cwd, abs).replace(/\\/g, "/") || params.filePathArg;
23813
24033
  if (!existsSync55(abs)) {
23814
24034
  throw new Error(`File not found: ${abs}`);
23815
24035
  }
23816
- const raw = readFileSync47(abs);
24036
+ const raw = readFileSync48(abs);
23817
24037
  const sampleEnd = Math.min(raw.length, 8192);
23818
24038
  for (let i = 0; i < sampleEnd; i++) {
23819
24039
  if (raw[i] === 0) {
@@ -23970,8 +24190,8 @@ __export(file_read_protocol_exports, {
23970
24190
  runFileReadForRouter: () => runFileReadForRouter,
23971
24191
  runFileReadTool: () => runFileReadTool
23972
24192
  });
23973
- import { existsSync as existsSync56, readFileSync as readFileSync48 } from "fs";
23974
- import { relative as relative4, resolve as resolve5 } from "path";
24193
+ import { existsSync as existsSync56, readFileSync as readFileSync49 } from "fs";
24194
+ import { relative as relative4, resolve as resolve8 } from "path";
23975
24195
  function isGeneratedPath(rel) {
23976
24196
  return /(?:^|\/)node_modules\/|(?:^|\/)dist\/|\/\.next\/|\.generated\./.test(
23977
24197
  rel
@@ -24010,7 +24230,6 @@ function rankEntityMatches(entities, query) {
24010
24230
  score: 40 + specificity * 20,
24011
24231
  matchType: "substring"
24012
24232
  });
24013
- continue;
24014
24233
  }
24015
24234
  }
24016
24235
  return results.sort((a, b) => b.score - a.score);
@@ -24043,13 +24262,13 @@ async function runFileReadForRouter(args, ctx) {
24043
24262
  const budgetLines = Math.floor(
24044
24263
  tokenBudget * CHARS_PER_TOKEN4 / AVG_CHARS_PER_LINE
24045
24264
  );
24046
- const abs = resolve5(ctx.cwd, filePathArg);
24265
+ const abs = resolve8(ctx.cwd, filePathArg);
24047
24266
  const rel = relative4(ctx.cwd, abs).replace(/\\/g, "/") || filePathArg;
24048
24267
  const isOutOfProject = rel.startsWith("..");
24049
24268
  if (!existsSync56(abs)) {
24050
24269
  return { content: { error: `File not found: ${abs}` } };
24051
24270
  }
24052
- const raw = readFileSync48(abs);
24271
+ const raw = readFileSync49(abs);
24053
24272
  const sampleEnd = Math.min(raw.length, 8192);
24054
24273
  for (let i = 0; i < sampleEnd; i++) {
24055
24274
  if (raw[i] === 0) {
@@ -24118,8 +24337,9 @@ async function runFileReadForRouter(args, ctx) {
24118
24337
  ]).catch(() => []);
24119
24338
  if (entities.length > 0) {
24120
24339
  const ranked = rankEntityMatches(entities, entityName);
24121
- if (ranked.length > 0 && ranked[0].score >= 70) {
24122
- const match = ranked[0].entity;
24340
+ const topRanked = ranked[0];
24341
+ if (ranked.length > 0 && topRanked && topRanked.score >= 70) {
24342
+ const match = topRanked.entity;
24123
24343
  if (match.start_line >= 1 && match.start_line <= totalLines) {
24124
24344
  const start = Math.max(1, match.start_line - ENTITY_CONTEXT);
24125
24345
  const endLine = (match.end_line ?? 0) > match.start_line ? match.end_line : match.start_line + match.body.split("\n").length - 1;
@@ -24131,8 +24351,8 @@ async function runFileReadForRouter(args, ctx) {
24131
24351
  entityMatchInfo = {
24132
24352
  matched: true,
24133
24353
  name: match.name,
24134
- score: ranked[0].score,
24135
- matchType: ranked[0].matchType
24354
+ score: topRanked.score,
24355
+ matchType: topRanked.matchType
24136
24356
  };
24137
24357
  }
24138
24358
  } else if (ranked.length > 0) {
@@ -24158,8 +24378,9 @@ async function runFileReadForRouter(args, ctx) {
24158
24378
  body: lines.slice(e.line_start - 1, e.line_end).join("\n")
24159
24379
  }));
24160
24380
  const ranked = rankEntityMatches(astEntities, entityName);
24161
- if (ranked.length > 0 && ranked[0].score >= 70) {
24162
- const match = ranked[0].entity;
24381
+ const topAstRank = ranked[0];
24382
+ if (topAstRank && topAstRank.score >= 70 && topAstRank.entity) {
24383
+ const match = topAstRank.entity;
24163
24384
  if (match.start_line >= 1 && match.start_line <= totalLines) {
24164
24385
  const start = Math.max(1, match.start_line - ENTITY_CONTEXT);
24165
24386
  const endLine = match.start_line + match.body.split("\n").length - 1;
@@ -24170,8 +24391,8 @@ async function runFileReadForRouter(args, ctx) {
24170
24391
  entityMatchInfo = {
24171
24392
  matched: true,
24172
24393
  name: match.name,
24173
- score: ranked[0].score,
24174
- matchType: ranked[0].matchType
24394
+ score: topAstRank.score,
24395
+ matchType: topAstRank.matchType
24175
24396
  };
24176
24397
  }
24177
24398
  } else if (ranked.length > 0 && !entityMatchInfo) {
@@ -25827,7 +26048,7 @@ var init_query_router = __esm({
25827
26048
  const hiddenFile = topHidden[0];
25828
26049
  if (hiddenFile) {
25829
26050
  const otherFile = hiddenFile.file_a === filePath ? hiddenFile.file_b : hiddenFile.file_a;
25830
- context.co_changes = (context.co_changes ? context.co_changes + ". " : "") + `Hidden dependency: ${otherFile} (${hiddenFile.evidence})`;
26051
+ context.co_changes = `${context.co_changes ? `${context.co_changes}. ` : ""}Hidden dependency: ${otherFile} (${hiddenFile.evidence})`;
25831
26052
  hasContext = true;
25832
26053
  }
25833
26054
  }
@@ -26193,9 +26414,13 @@ var init_query_router = __esm({
26193
26414
  const filePathPattern = /(?:^|\s)([\w/.]+\.[a-z]{1,4})(?:\s|:|$)/gm;
26194
26415
  const seen = /* @__PURE__ */ new Set();
26195
26416
  let match;
26196
- while ((match = filePathPattern.exec(text2)) !== null) {
26417
+ match = filePathPattern.exec(text2);
26418
+ while (match !== null) {
26197
26419
  const filePath = match[1];
26198
- if (seen.has(filePath)) continue;
26420
+ if (seen.has(filePath)) {
26421
+ match = filePathPattern.exec(text2);
26422
+ continue;
26423
+ }
26199
26424
  seen.add(filePath);
26200
26425
  if (seen.size > 20) break;
26201
26426
  const entities = await this.localGraph.getEntitiesByFile(filePath);
@@ -26208,6 +26433,7 @@ var init_query_router = __esm({
26208
26433
  isChokepoint: br.is_chokepoint
26209
26434
  });
26210
26435
  }
26436
+ match = filePathPattern.exec(text2);
26211
26437
  }
26212
26438
  } catch (err) {
26213
26439
  process.stderr.write(
@@ -26241,13 +26467,13 @@ var init_query_router = __esm({
26241
26467
  const kindHint = args.kind ?? aliasKind;
26242
26468
  const key = await this.resolveKeyArg(rawArg, kindHint);
26243
26469
  const entity = await this.resolveEntityWithOverlay(key);
26244
- if (entity && entity.file_path && entity.start_line > 0) {
26470
+ if (entity?.file_path && entity.start_line > 0) {
26245
26471
  try {
26246
- const { readFileSync: readFileSync67 } = await import("fs");
26247
- const { resolve: resolve6 } = await import("path");
26472
+ const { readFileSync: readFileSync68 } = await import("fs");
26473
+ const { resolve: resolve9 } = await import("path");
26248
26474
  const cwd = this.projectRoot ?? process.cwd();
26249
- const abs = resolve6(cwd, entity.file_path);
26250
- const lines = readFileSync67(abs, "utf-8").split("\n");
26475
+ const abs = resolve9(cwd, entity.file_path);
26476
+ const lines = readFileSync68(abs, "utf-8").split("\n");
26251
26477
  const start = entity.start_line - 1;
26252
26478
  const end = entity.end_line ?? lines.length;
26253
26479
  const bodyLines = lines.slice(start, end);
@@ -26380,20 +26606,41 @@ var init_query_router = __esm({
26380
26606
  const topN = args.top_n ?? 20;
26381
26607
  const fromPath = args.from_path;
26382
26608
  const toPath = args.to_path;
26383
- const fetchN = fromPath || toPath ? Math.max(topN * 10, 200) : topN;
26609
+ if (fromPath && toPath) {
26610
+ const norm2 = (p) => p.replace(/\/+$/, "");
26611
+ const result2 = await this.localGraph.getCrossPathLinks(
26612
+ norm2(fromPath),
26613
+ norm2(toPath),
26614
+ topN
26615
+ );
26616
+ if (result2.length === 0) {
26617
+ return {
26618
+ links: [],
26619
+ _hint: "No edges found between these directory prefixes. call file_connections({file_path:'<file>'}) for import-level neighbors, or get_references({entity:'<name>', direction:'callees'}) for call-level dependencies."
26620
+ };
26621
+ }
26622
+ return result2;
26623
+ }
26624
+ const fetchN = fromPath ? Math.max(topN * 10, 200) : topN;
26384
26625
  const rows = await this.localGraph.getCrossBoundaryLinks(
26385
26626
  communityId,
26386
26627
  fetchN
26387
26628
  );
26388
- if (!fromPath && !toPath) return rows;
26629
+ if (!fromPath) return rows;
26389
26630
  const norm = (p) => p ? p.replace(/\/+$/, "") : "";
26390
26631
  const f = norm(fromPath);
26391
- const t = norm(toPath);
26392
26632
  const matches = (file, prefix) => !prefix || file === prefix || file.startsWith(prefix.endsWith("/") ? prefix : `${prefix}/`);
26393
26633
  const filtered = rows.filter(
26394
- (r) => matches(r.from_file, f) && matches(r.to_file, t) || matches(r.from_file, t) && matches(r.to_file, f)
26634
+ (r) => matches(r.from_file, f) || matches(r.to_file, f)
26395
26635
  );
26396
- return filtered.slice(0, topN);
26636
+ const result = filtered.slice(0, topN);
26637
+ if (result.length === 0) {
26638
+ return {
26639
+ links: [],
26640
+ _hint: "No cross-community edges found for this path filter. call file_connections({file_path:'<file>'}) for import-level neighbors, or get_references({entity:'<name>', direction:'callees'}) for call-level dependencies."
26641
+ };
26642
+ }
26643
+ return result;
26397
26644
  }
26398
26645
  case "get_critical_nodes": {
26399
26646
  const topN = args.top_n ?? 10;
@@ -27823,7 +28070,7 @@ __export(causal_bridge_exports, {
27823
28070
  assembleCausalChain: () => assembleCausalChain,
27824
28071
  computeDurability: () => computeDurability
27825
28072
  });
27826
- import { existsSync as existsSync57, readFileSync as readFileSync49 } from "fs";
28073
+ import { existsSync as existsSync57, readFileSync as readFileSync50 } from "fs";
27827
28074
  import { join as join59 } from "path";
27828
28075
  function computeAggregateDurability(interactions) {
27829
28076
  if (interactions.length === 0) return 1;
@@ -27983,7 +28230,7 @@ var init_causal_bridge = __esm({
27983
28230
  loadEntityLedgerEntries(entityKey2) {
27984
28231
  const ledgerPath = join59(this.unerrDir, "ledger", "shadow.jsonl");
27985
28232
  if (!existsSync57(ledgerPath)) return [];
27986
- const content = readFileSync49(ledgerPath, "utf-8");
28233
+ const content = readFileSync50(ledgerPath, "utf-8");
27987
28234
  const lines = content.split("\n").filter((l) => l.trim().length > 0);
27988
28235
  const entries = [];
27989
28236
  for (const line of lines) {
@@ -28469,7 +28716,7 @@ var context_ledger_exports = {};
28469
28716
  __export(context_ledger_exports, {
28470
28717
  createContextLedger: () => createContextLedger
28471
28718
  });
28472
- import { existsSync as existsSync58, mkdirSync as mkdirSync34, readFileSync as readFileSync50, writeFileSync as writeFileSync29 } from "fs";
28719
+ import { existsSync as existsSync58, mkdirSync as mkdirSync34, readFileSync as readFileSync51, writeFileSync as writeFileSync29 } from "fs";
28473
28720
  import { join as join60 } from "path";
28474
28721
  function createContextLedger(unerrDir) {
28475
28722
  const stateDir = join60(unerrDir, "state");
@@ -28492,7 +28739,7 @@ function createContextLedger(unerrDir) {
28492
28739
  return /* @__PURE__ */ new Map();
28493
28740
  }
28494
28741
  try {
28495
- const raw = readFileSync50(filePath, "utf-8");
28742
+ const raw = readFileSync51(filePath, "utf-8");
28496
28743
  const parsed = JSON.parse(raw);
28497
28744
  records = Array.isArray(parsed) ? parsed : [];
28498
28745
  } catch {
@@ -29401,7 +29648,7 @@ __export(intent_correlator_exports, {
29401
29648
  import {
29402
29649
  existsSync as existsSync59,
29403
29650
  mkdirSync as mkdirSync35,
29404
- readFileSync as readFileSync51,
29651
+ readFileSync as readFileSync52,
29405
29652
  renameSync as renameSync2,
29406
29653
  writeFileSync as writeFileSync30
29407
29654
  } from "fs";
@@ -29549,7 +29796,7 @@ var init_intent_correlator = __esm({
29549
29796
  load() {
29550
29797
  if (!existsSync59(this.pendingPath)) return;
29551
29798
  try {
29552
- const raw = readFileSync51(this.pendingPath, "utf-8");
29799
+ const raw = readFileSync52(this.pendingPath, "utf-8");
29553
29800
  const parsed = JSON.parse(raw);
29554
29801
  if (Array.isArray(parsed)) {
29555
29802
  this.pending = parsed;
@@ -29891,10 +30138,10 @@ var init_timeline_store = __esm({
29891
30138
  async setSessionAgent(sessionId, agentName, nowMs = Date.now()) {
29892
30139
  if (!agentName || agentName.length === 0) return;
29893
30140
  const existing = await this.db.run(
29894
- `?[first_seen] := *session_agents{session_id, first_seen}, session_id = $sid`,
30141
+ "?[first_seen] := *session_agents{session_id, first_seen}, session_id = $sid",
29895
30142
  { sid: sessionId }
29896
30143
  );
29897
- const firstSeen = existing.rows.length > 0 ? existing.rows[0][0] : nowMs;
30144
+ const firstSeen = existing.rows.length > 0 ? existing.rows[0]?.[0] : nowMs;
29898
30145
  await this.db.run(
29899
30146
  `?[session_id, agent_name, first_seen, last_seen] <-
29900
30147
  [[$sid, $name, $first, $last]]
@@ -29912,7 +30159,7 @@ var init_timeline_store = __esm({
29912
30159
  /** Lookup the agent name for one session id. Returns null when unknown. */
29913
30160
  async getSessionAgent(sessionId) {
29914
30161
  const result = await this.db.run(
29915
- `?[agent_name] := *session_agents{session_id, agent_name}, session_id = $sid`,
30162
+ "?[agent_name] := *session_agents{session_id, agent_name}, session_id = $sid",
29916
30163
  { sid: sessionId }
29917
30164
  );
29918
30165
  const row = result.rows[0];
@@ -30029,7 +30276,7 @@ var init_timeline_store = __esm({
30029
30276
  }
30030
30277
  async getSessionFiles(sessionId) {
30031
30278
  const result = await this.db.run(
30032
- `?[file_path] := *session_files{session_id: $session_id, file_path}`,
30279
+ "?[file_path] := *session_files{session_id: $session_id, file_path}",
30033
30280
  { session_id: sessionId }
30034
30281
  );
30035
30282
  return result.rows.map((r) => r[0]);
@@ -30047,7 +30294,7 @@ var init_timeline_store = __esm({
30047
30294
  }
30048
30295
  async listIntents(opts = {}) {
30049
30296
  const limit = Math.max(1, Math.min(opts.limit ?? 100, 500));
30050
- const filter = opts.status ? `, status = $status` : "";
30297
+ const filter = opts.status ? ", status = $status" : "";
30051
30298
  const query = `?[intent_id, title, started_at, last_active_at, file_set, file_set_hash, status, confidence, source] :=
30052
30299
  *intents{intent_id, title, started_at, last_active_at, file_set, file_set_hash, status, confidence, source}${filter}
30053
30300
  :order -last_active_at
@@ -30076,7 +30323,7 @@ var init_timeline_store = __esm({
30076
30323
  }
30077
30324
  async listIntentSessions(intentId) {
30078
30325
  const result = await this.db.run(
30079
- `?[session_id] := *intent_sessions{intent_id: $intent_id, session_id}`,
30326
+ "?[session_id] := *intent_sessions{intent_id: $intent_id, session_id}",
30080
30327
  { intent_id: intentId }
30081
30328
  );
30082
30329
  return result.rows.map((r) => r[0]);
@@ -30086,7 +30333,7 @@ var init_timeline_store = __esm({
30086
30333
  */
30087
30334
  async findIntentForSession(sessionId) {
30088
30335
  const result = await this.db.run(
30089
- `?[intent_id] := *intent_sessions{intent_id, session_id: $session_id}`,
30336
+ "?[intent_id] := *intent_sessions{intent_id, session_id: $session_id}",
30090
30337
  { session_id: sessionId }
30091
30338
  );
30092
30339
  const row = result.rows[0];
@@ -30439,7 +30686,10 @@ function stitchIntents(sessions, existingIntents, existingAttachments, opts = {}
30439
30686
  }
30440
30687
  function attachSession(intent, session) {
30441
30688
  for (const f of session.files) intent._filesSet.add(f);
30442
- intent.last_active_at = Math.max(intent.last_active_at, session.last_active_at);
30689
+ intent.last_active_at = Math.max(
30690
+ intent.last_active_at,
30691
+ session.last_active_at
30692
+ );
30443
30693
  intent.confidence = Math.min(1, intent.confidence + 0.05);
30444
30694
  intent.file_set = JSON.stringify([...intent._filesSet].sort());
30445
30695
  intent.file_set_hash = hashFileSet(intent._filesSet);
@@ -30525,7 +30775,12 @@ async function runIntentStitch(store, opts = {}) {
30525
30775
  existingAttachments.push({ intent_id: i.intent_id, session_id: sid });
30526
30776
  }
30527
30777
  }
30528
- const result = stitchIntents(summaries, existingIntents, existingAttachments, opts);
30778
+ const result = stitchIntents(
30779
+ summaries,
30780
+ existingIntents,
30781
+ existingAttachments,
30782
+ opts
30783
+ );
30529
30784
  let created = 0;
30530
30785
  const existingIds = new Set(existingIntents.map((i) => i.intent_id));
30531
30786
  for (const i of result.intents) {
@@ -30560,7 +30815,7 @@ __export(signal_reinforcer_exports, {
30560
30815
  import { randomUUID as randomUUID3 } from "crypto";
30561
30816
  async function reinforceSignal(store, identity, delta, source, opts = {}) {
30562
30817
  const now = opts.nowMs ?? Date.now();
30563
- let signal = await resolveSignal(store, identity);
30818
+ const signal = await resolveSignal(store, identity);
30564
30819
  if (!signal) {
30565
30820
  const created = {
30566
30821
  signal_id: "signal_id" in identity ? identity.signal_id : randomUUID3(),
@@ -30612,16 +30867,16 @@ var ledger_archiver_exports = {};
30612
30867
  __export(ledger_archiver_exports, {
30613
30868
  archiveShadowLedger: () => archiveShadowLedger
30614
30869
  });
30615
- import { gzipSync } from "zlib";
30616
30870
  import {
30617
30871
  appendFileSync as appendFileSync7,
30618
30872
  existsSync as existsSync61,
30619
30873
  mkdirSync as mkdirSync37,
30620
- readFileSync as readFileSync52,
30874
+ readFileSync as readFileSync53,
30621
30875
  renameSync as renameSync3,
30622
30876
  writeFileSync as writeFileSync31
30623
30877
  } from "fs";
30624
30878
  import { join as join63 } from "path";
30879
+ import { gzipSync } from "zlib";
30625
30880
  function archiveShadowLedger(unerrDir, opts = {}) {
30626
30881
  const ledgerDir = join63(unerrDir, "ledger");
30627
30882
  const filePath = join63(ledgerDir, "shadow.jsonl");
@@ -30632,13 +30887,13 @@ function archiveShadowLedger(unerrDir, opts = {}) {
30632
30887
  const retainMs = opts.retainMs ?? DEFAULT_RETAIN_MS;
30633
30888
  const now = opts.nowMs ?? Date.now();
30634
30889
  const cutoff = now - retainMs;
30635
- const raw = readFileSync52(filePath, "utf-8");
30890
+ const raw = readFileSync53(filePath, "utf-8");
30636
30891
  const initialBytes = Buffer.byteLength(raw);
30637
30892
  const lines = raw.split("\n").filter((l) => l.trim().length > 0);
30638
30893
  const keep = [];
30639
30894
  const archive = [];
30640
30895
  for (const line of lines) {
30641
- let entryTs = NaN;
30896
+ let entryTs = Number.NaN;
30642
30897
  try {
30643
30898
  const obj = JSON.parse(line);
30644
30899
  if (typeof obj.ts === "string") entryTs = Date.parse(obj.ts);
@@ -30669,7 +30924,7 @@ function archiveShadowLedger(unerrDir, opts = {}) {
30669
30924
  const tmpPath = `${filePath}.tmp-${Date.now()}-${Math.random().toString(36).slice(2)}`;
30670
30925
  const kept = `${keep.join("\n")}${keep.length > 0 ? "\n" : ""}`;
30671
30926
  writeFileSync31(tmpPath, kept, "utf-8");
30672
- const afterRaw = readFileSync52(filePath, "utf-8");
30927
+ const afterRaw = readFileSync53(filePath, "utf-8");
30673
30928
  const afterBytes = Buffer.byteLength(afterRaw);
30674
30929
  if (afterBytes > initialBytes) {
30675
30930
  const tail = afterRaw.slice(raw.length);
@@ -30815,7 +31070,12 @@ var init_session_narrative = __esm({
30815
31070
  const byArea = /* @__PURE__ */ new Map();
30816
31071
  for (const n of this.narratives) {
30817
31072
  const area = extractFeatureArea(n.file_path);
30818
- (byArea.get(area) ?? (byArea.set(area, []), byArea.get(area))).push(n);
31073
+ let list = byArea.get(area);
31074
+ if (!list) {
31075
+ list = [];
31076
+ byArea.set(area, list);
31077
+ }
31078
+ list.push(n);
30819
31079
  }
30820
31080
  const areaSummaries = [...byArea.entries()].map(([area, entries]) => {
30821
31081
  const whats = entries.map((e) => e.what).slice(0, 3);
@@ -31173,7 +31433,7 @@ import { randomBytes as randomBytes4 } from "crypto";
31173
31433
  import {
31174
31434
  existsSync as existsSync62,
31175
31435
  mkdirSync as mkdirSync38,
31176
- readFileSync as readFileSync53,
31436
+ readFileSync as readFileSync54,
31177
31437
  readdirSync as readdirSync12,
31178
31438
  rmSync as rmSync2,
31179
31439
  writeFileSync as writeFileSync32
@@ -31234,7 +31494,7 @@ var init_working_snapshots = __esm({
31234
31494
  const filePath = join64(this.snapshotDir, `${snapshotId}.json`);
31235
31495
  if (!existsSync62(filePath)) return null;
31236
31496
  try {
31237
- return JSON.parse(readFileSync53(filePath, "utf-8"));
31497
+ return JSON.parse(readFileSync54(filePath, "utf-8"));
31238
31498
  } catch {
31239
31499
  return null;
31240
31500
  }
@@ -31250,7 +31510,7 @@ var init_working_snapshots = __esm({
31250
31510
  const snapshots = [];
31251
31511
  for (const file of files) {
31252
31512
  try {
31253
- const raw = readFileSync53(join64(this.snapshotDir, file), "utf-8");
31513
+ const raw = readFileSync54(join64(this.snapshotDir, file), "utf-8");
31254
31514
  snapshots.push(JSON.parse(raw));
31255
31515
  } catch {
31256
31516
  }
@@ -31318,7 +31578,7 @@ var init_working_snapshots = __esm({
31318
31578
  const contextPath = join64(this.unerrDir, "branch_context.json");
31319
31579
  if (!existsSync62(contextPath)) return 0;
31320
31580
  try {
31321
- const ctx = JSON.parse(readFileSync53(contextPath, "utf-8"));
31581
+ const ctx = JSON.parse(readFileSync54(contextPath, "utf-8"));
31322
31582
  return ctx.timelineBranch ?? 0;
31323
31583
  } catch {
31324
31584
  return 0;
@@ -31332,7 +31592,7 @@ var init_working_snapshots = __esm({
31332
31592
  let ctx = {};
31333
31593
  if (existsSync62(contextPath)) {
31334
31594
  try {
31335
- ctx = JSON.parse(readFileSync53(contextPath, "utf-8"));
31595
+ ctx = JSON.parse(readFileSync54(contextPath, "utf-8"));
31336
31596
  } catch {
31337
31597
  ctx = {};
31338
31598
  }
@@ -31505,7 +31765,7 @@ var quality_signals_exports = {};
31505
31765
  __export(quality_signals_exports, {
31506
31766
  QualitySignalTracker: () => QualitySignalTracker
31507
31767
  });
31508
- import { existsSync as existsSync63, readFileSync as readFileSync54, writeFileSync as writeFileSync33 } from "fs";
31768
+ import { existsSync as existsSync63, readFileSync as readFileSync55, writeFileSync as writeFileSync33 } from "fs";
31509
31769
  import { join as join65 } from "path";
31510
31770
  function computeDurabilityFromAge(survivalMs) {
31511
31771
  if (survivalMs < FRAGILE_THRESHOLD_MS) {
@@ -31681,7 +31941,7 @@ var init_quality_signals = __esm({
31681
31941
  }
31682
31942
  try {
31683
31943
  return JSON.parse(
31684
- readFileSync54(this.signalsPath, "utf-8")
31944
+ readFileSync55(this.signalsPath, "utf-8")
31685
31945
  );
31686
31946
  } catch {
31687
31947
  return {
@@ -32265,8 +32525,8 @@ function extractPreviousSession(allEntries, currentSessionId) {
32265
32525
  return allEntries.filter((e) => e.session_id === lastSessionId);
32266
32526
  }
32267
32527
  function buildResumePayload(entries, maxItems) {
32268
- const firstTs = new Date(entries[0].ts).getTime();
32269
- const lastTs = new Date(entries[entries.length - 1].ts).getTime();
32528
+ const firstTs = new Date(entries[0]?.ts ?? 0).getTime();
32529
+ const lastTs = new Date(entries[entries.length - 1]?.ts ?? 0).getTime();
32270
32530
  const durationMs = lastTs - firstTs;
32271
32531
  const elapsedSinceMs = Date.now() - lastTs;
32272
32532
  const filesModified = /* @__PURE__ */ new Set();
@@ -32316,7 +32576,7 @@ function buildResumePayload(entries, maxItems) {
32316
32576
  summaryParts.push(`${filesModified.size} file(s) touched`);
32317
32577
  if (incompleteWork.length > 0)
32318
32578
  summaryParts.push(`${incompleteWork.length} incomplete item(s)`);
32319
- const suggestedNext = incompleteWork.length > 0 ? `Complete outstanding work on ${incompleteWork[0].entity} (${incompleteWork[0].status})` : "No outstanding items from last session \u2014 ready for new work.";
32579
+ const suggestedNext = incompleteWork.length > 0 ? `Complete outstanding work on ${incompleteWork[0]?.entity} (${incompleteWork[0]?.status})` : "No outstanding items from last session \u2014 ready for new work.";
32320
32580
  return {
32321
32581
  last_session: {
32322
32582
  when: formatElapsed(elapsedSinceMs),
@@ -32507,8 +32767,10 @@ function extractSignatures(content, entityName) {
32507
32767
  const results = [];
32508
32768
  for (const pattern of patterns) {
32509
32769
  let match;
32510
- while ((match = pattern.exec(content)) !== null) {
32770
+ match = pattern.exec(content);
32771
+ while (match !== null) {
32511
32772
  results.push(match[0]);
32773
+ match = pattern.exec(content);
32512
32774
  }
32513
32775
  if (results.length > 0) break;
32514
32776
  }
@@ -32698,7 +32960,7 @@ var incomplete_work_exports = {};
32698
32960
  __export(incomplete_work_exports, {
32699
32961
  IncompleteWorkDetector: () => IncompleteWorkDetector
32700
32962
  });
32701
- import { existsSync as existsSync64, mkdirSync as mkdirSync39, readFileSync as readFileSync55, writeFileSync as writeFileSync34 } from "fs";
32963
+ import { existsSync as existsSync64, mkdirSync as mkdirSync39, readFileSync as readFileSync56, writeFileSync as writeFileSync34 } from "fs";
32702
32964
  import { join as join66 } from "path";
32703
32965
  function severityRank(severity) {
32704
32966
  switch (severity) {
@@ -32916,7 +33178,7 @@ var init_incomplete_work = __esm({
32916
33178
  try {
32917
33179
  const filePath = join66(unerrDir, "state", PERSISTENCE_FILE);
32918
33180
  if (!existsSync64(filePath)) return [];
32919
- const data = JSON.parse(readFileSync55(filePath, "utf-8"));
33181
+ const data = JSON.parse(readFileSync56(filePath, "utf-8"));
32920
33182
  return data.items ?? [];
32921
33183
  } catch {
32922
33184
  return [];
@@ -32969,8 +33231,10 @@ function extractDefinedNames(content) {
32969
33231
  ];
32970
33232
  for (const pattern of patterns) {
32971
33233
  let match;
32972
- while ((match = pattern.exec(content)) !== null) {
33234
+ match = pattern.exec(content);
33235
+ while (match !== null) {
32973
33236
  if (match[1]) names.push(match[1]);
33237
+ match = pattern.exec(content);
32974
33238
  }
32975
33239
  }
32976
33240
  return [...new Set(names)];
@@ -32979,8 +33243,10 @@ function extractImportLines(content) {
32979
33243
  const imports = [];
32980
33244
  const pattern = /import\s+.*?from\s+['"]([^'"]+)['"]/g;
32981
33245
  let match;
32982
- while ((match = pattern.exec(content)) !== null) {
33246
+ match = pattern.exec(content);
33247
+ while (match !== null) {
32983
33248
  if (match[1]) imports.push(match[1]);
33249
+ match = pattern.exec(content);
32984
33250
  }
32985
33251
  return imports;
32986
33252
  }
@@ -33220,7 +33486,8 @@ function extractExportedSignatures(content) {
33220
33486
  const results = [];
33221
33487
  const pattern = /(?:export\s+)?(?:async\s+)?function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*(\([^)]*\))(?:\s*:\s*([^{]+?))?(?:\s*\{)/g;
33222
33488
  let match;
33223
- while ((match = pattern.exec(content)) !== null) {
33489
+ match = pattern.exec(content);
33490
+ while (match !== null) {
33224
33491
  const name = match[1];
33225
33492
  const params = match[2];
33226
33493
  const returnType = match[3]?.trim() ?? null;
@@ -33230,6 +33497,7 @@ function extractExportedSignatures(content) {
33230
33497
  startIndex: match.index,
33231
33498
  returnType
33232
33499
  });
33500
+ match = pattern.exec(content);
33233
33501
  }
33234
33502
  return results;
33235
33503
  }
@@ -33455,7 +33723,7 @@ function parseImports(content) {
33455
33723
  const isTypeOnly = !!importMatch[1];
33456
33724
  const specifier = importMatch[2];
33457
33725
  if (!specifier.startsWith(".")) continue;
33458
- const prevLine = i > 0 ? lines[i - 1].trim() : "";
33726
+ const prevLine = i > 0 ? lines[i - 1]?.trim() ?? "" : "";
33459
33727
  const hasOverride = OVERRIDE_PATTERN.test(prevLine) || OVERRIDE_PATTERN.test(line);
33460
33728
  results.push({
33461
33729
  raw: line,
@@ -33598,7 +33866,7 @@ var init_architecture_guard = __esm({
33598
33866
  },
33599
33867
  {
33600
33868
  pattern: "interface_bridge",
33601
- example: `Define shared types in a schemas/ module accessible to both communities`
33869
+ example: "Define shared types in a schemas/ module accessible to both communities"
33602
33870
  }
33603
33871
  );
33604
33872
  }
@@ -34690,7 +34958,7 @@ __export(git_trailers_exports, {
34690
34958
  parseTrailersFromMessage: () => parseTrailersFromMessage,
34691
34959
  uninstallPrepareCommitMsgHook: () => uninstallPrepareCommitMsgHook
34692
34960
  });
34693
- import { existsSync as existsSync66, readFileSync as readFileSync56, writeFileSync as writeFileSync35 } from "fs";
34961
+ import { existsSync as existsSync66, readFileSync as readFileSync57, writeFileSync as writeFileSync35 } from "fs";
34694
34962
  import { join as join67 } from "path";
34695
34963
  function getCommitTrailers(ledger, timelineBranch, branch) {
34696
34964
  const recent = ledger.getRecentEntries(1);
@@ -34719,7 +34987,7 @@ function installPrepareCommitMsgHook(projectRoot) {
34719
34987
  const marker = "# unerr-trailer-injection";
34720
34988
  if (existsSync66(hookPath)) {
34721
34989
  try {
34722
- const existing = readFileSync56(hookPath, "utf-8");
34990
+ const existing = readFileSync57(hookPath, "utf-8");
34723
34991
  if (existing.includes(marker)) {
34724
34992
  return true;
34725
34993
  }
@@ -34751,7 +35019,7 @@ function uninstallPrepareCommitMsgHook(projectRoot) {
34751
35019
  const hookPath = join67(projectRoot, ".git", "hooks", "prepare-commit-msg");
34752
35020
  if (!existsSync66(hookPath)) return true;
34753
35021
  try {
34754
- const content = readFileSync56(hookPath, "utf-8");
35022
+ const content = readFileSync57(hookPath, "utf-8");
34755
35023
  const marker = "# unerr-trailer-injection";
34756
35024
  if (!content.includes(marker)) return true;
34757
35025
  const lines = content.split("\n");
@@ -34890,12 +35158,12 @@ async function startHttpTransport(opts) {
34890
35158
  })
34891
35159
  );
34892
35160
  });
34893
- return new Promise((resolve6) => {
35161
+ return new Promise((resolve9) => {
34894
35162
  httpServer.listen(port, "127.0.0.1", () => {
34895
35163
  const addr = httpServer.address();
34896
35164
  const resolvedPort = typeof addr === "object" && addr ? addr.port : port;
34897
35165
  log24(`HTTP transport listening on http://127.0.0.1:${resolvedPort}/mcp`);
34898
- resolve6({
35166
+ resolve9({
34899
35167
  server: httpServer,
34900
35168
  port: resolvedPort,
34901
35169
  close: () => {
@@ -34918,7 +35186,7 @@ var init_http_transport = __esm({
34918
35186
  import {
34919
35187
  existsSync as existsSync67,
34920
35188
  mkdirSync as mkdirSync41,
34921
- readFileSync as readFileSync57,
35189
+ readFileSync as readFileSync58,
34922
35190
  readdirSync as readdirSync13,
34923
35191
  rmSync as rmSync3,
34924
35192
  statSync as statSync9,
@@ -34996,7 +35264,7 @@ var init_branch_snapshot = __esm({
34996
35264
  return null;
34997
35265
  }
34998
35266
  try {
34999
- const raw = readFileSync57(overlayPath, "utf-8");
35267
+ const raw = readFileSync58(overlayPath, "utf-8");
35000
35268
  const snapshot = JSON.parse(raw);
35001
35269
  for (const entity of snapshot.entities) {
35002
35270
  await localGraph.upsertDriftEntity(entity);
@@ -35038,7 +35306,7 @@ var init_branch_snapshot = __esm({
35038
35306
  const hashesPath = join68(this.branchDir, dirName, HASHES_FILE);
35039
35307
  if (!existsSync67(hashesPath)) return null;
35040
35308
  try {
35041
- const raw = readFileSync57(hashesPath, "utf-8");
35309
+ const raw = readFileSync58(hashesPath, "utf-8");
35042
35310
  return JSON.parse(raw);
35043
35311
  } catch {
35044
35312
  return null;
@@ -35087,7 +35355,7 @@ var init_branch_snapshot = __esm({
35087
35355
  const overlayPath = join68(this.branchDir, entry.name, OVERLAY_FILE);
35088
35356
  if (!existsSync67(overlayPath)) continue;
35089
35357
  try {
35090
- const raw = readFileSync57(overlayPath, "utf-8");
35358
+ const raw = readFileSync58(overlayPath, "utf-8");
35091
35359
  const snapshot = JSON.parse(raw);
35092
35360
  const accessPath = join68(this.branchDir, entry.name, ".last_access");
35093
35361
  let accessedAt;
@@ -35137,7 +35405,7 @@ import { createHash as createHash3 } from "crypto";
35137
35405
  import {
35138
35406
  existsSync as existsSync68,
35139
35407
  mkdirSync as mkdirSync42,
35140
- readFileSync as readFileSync58,
35408
+ readFileSync as readFileSync59,
35141
35409
  renameSync as renameSync4,
35142
35410
  writeFileSync as writeFileSync37
35143
35411
  } from "fs";
@@ -35232,7 +35500,7 @@ var init_file_hash_state = __esm({
35232
35500
  return { files: {} };
35233
35501
  }
35234
35502
  try {
35235
- const raw = readFileSync58(this.statePath, "utf-8");
35503
+ const raw = readFileSync59(this.statePath, "utf-8");
35236
35504
  return JSON.parse(raw);
35237
35505
  } catch {
35238
35506
  return { files: {} };
@@ -35246,7 +35514,7 @@ var init_file_hash_state = __esm({
35246
35514
  import {
35247
35515
  existsSync as existsSync69,
35248
35516
  mkdirSync as mkdirSync43,
35249
- readFileSync as readFileSync59,
35517
+ readFileSync as readFileSync60,
35250
35518
  readdirSync as readdirSync14,
35251
35519
  rmSync as rmSync4,
35252
35520
  statSync as statSync10,
@@ -35361,7 +35629,7 @@ var init_stash_manager = __esm({
35361
35629
  return 0;
35362
35630
  }
35363
35631
  try {
35364
- const raw = readFileSync59(overlayPath, "utf-8");
35632
+ const raw = readFileSync60(overlayPath, "utf-8");
35365
35633
  const snapshot = JSON.parse(raw);
35366
35634
  for (const entity of snapshot.entities) {
35367
35635
  await localGraph.upsertDriftEntity(entity);
@@ -35394,7 +35662,7 @@ var init_stash_manager = __esm({
35394
35662
  const hashesPath = join70(this.stashDir, latest.id, HASHES_FILE2);
35395
35663
  if (!existsSync69(hashesPath)) return null;
35396
35664
  try {
35397
- const raw = readFileSync59(hashesPath, "utf-8");
35665
+ const raw = readFileSync60(hashesPath, "utf-8");
35398
35666
  return JSON.parse(raw);
35399
35667
  } catch {
35400
35668
  return null;
@@ -35442,7 +35710,7 @@ var init_stash_manager = __esm({
35442
35710
  const stashPath = join70(this.gitDir, "refs", "stash");
35443
35711
  if (!existsSync69(stashPath)) return null;
35444
35712
  try {
35445
- return readFileSync59(stashPath, "utf-8").trim() || null;
35713
+ return readFileSync60(stashPath, "utf-8").trim() || null;
35446
35714
  } catch {
35447
35715
  return null;
35448
35716
  }
@@ -35454,7 +35722,7 @@ var init_stash_manager = __esm({
35454
35722
  const logPath2 = join70(this.gitDir, "logs", "refs", "stash");
35455
35723
  if (!existsSync69(logPath2)) return 0;
35456
35724
  try {
35457
- const content = readFileSync59(logPath2, "utf-8");
35725
+ const content = readFileSync60(logPath2, "utf-8");
35458
35726
  return content.split("\n").filter((line) => line.trim().length > 0).length;
35459
35727
  } catch {
35460
35728
  return 0;
@@ -35488,7 +35756,7 @@ __export(drift_tracker_exports, {
35488
35756
  import {
35489
35757
  existsSync as existsSync70,
35490
35758
  mkdirSync as mkdirSync44,
35491
- readFileSync as readFileSync60,
35759
+ readFileSync as readFileSync61,
35492
35760
  statSync as statSync11,
35493
35761
  writeFileSync as writeFileSync39
35494
35762
  } from "fs";
@@ -35749,7 +36017,7 @@ var init_drift_tracker = __esm({
35749
36017
  this.maybeEmitDrift(relPath, result);
35750
36018
  return result;
35751
36019
  }
35752
- const content = readFileSync60(absPath, "utf-8");
36020
+ const content = readFileSync61(absPath, "utf-8");
35753
36021
  const sha = contentSha256(content);
35754
36022
  const decision = this.fileHashManager.shouldProcess(relPath, sha, headSha);
35755
36023
  if (decision === "skip") {
@@ -36397,7 +36665,7 @@ var init_graph_holder = __esm({
36397
36665
  }
36398
36666
  runIncremental(changedFiles, changesAtStart, startMs) {
36399
36667
  _log8.info(`Incremental indexing ${changedFiles.length} files...`);
36400
- this.incrementalFactory(changedFiles).then((result) => {
36668
+ this.incrementalFactory?.(changedFiles).then((result) => {
36401
36669
  for (const fp of changedFiles) {
36402
36670
  this.changedFilePaths.delete(fp);
36403
36671
  }
@@ -36437,7 +36705,7 @@ var init_graph_holder = __esm({
36437
36705
  _log8.info(
36438
36706
  `Full reindex (${changesAtStart} file changes since last rebuild)...`
36439
36707
  );
36440
- this.rebuildFactory().then(({ graph: newGraph, result }) => {
36708
+ this.rebuildFactory?.().then(({ graph: newGraph, result }) => {
36441
36709
  const oldGraph = this.current;
36442
36710
  this.current = newGraph;
36443
36711
  for (const cb of this.swapCallbacks) {
@@ -36485,7 +36753,7 @@ var incremental_indexer_exports = {};
36485
36753
  __export(incremental_indexer_exports, {
36486
36754
  indexFilesIncremental: () => indexFilesIncremental
36487
36755
  });
36488
- import { existsSync as existsSync71, readFileSync as readFileSync61 } from "fs";
36756
+ import { existsSync as existsSync71, readFileSync as readFileSync62 } from "fs";
36489
36757
  import { join as join72, relative as relative5 } from "path";
36490
36758
  async function indexFilesIncremental(projectRoot, changedFiles, graphStore, repoId) {
36491
36759
  const startMs = Date.now();
@@ -36519,7 +36787,7 @@ async function indexFilesIncremental(projectRoot, changedFiles, graphStore, repo
36519
36787
  }
36520
36788
  let content;
36521
36789
  try {
36522
- content = readFileSync61(absPath, "utf-8");
36790
+ content = readFileSync62(absPath, "utf-8");
36523
36791
  } catch {
36524
36792
  continue;
36525
36793
  }
@@ -36713,7 +36981,7 @@ async function getFileEdgeKeysBatched(db, relPath, entities) {
36713
36981
  }
36714
36982
  try {
36715
36983
  const result = await db.run(
36716
- `?[from_key, to_key, type] := *edges{from_key: $key, to_key, type}`,
36984
+ "?[from_key, to_key, type] := *edges{from_key: $key, to_key, type}",
36717
36985
  { key: `file:${relPath}` }
36718
36986
  );
36719
36987
  for (const row of result.rows) {
@@ -36742,7 +37010,7 @@ async function deleteFileFromGraph(db, relPath) {
36742
37010
  }
36743
37011
  try {
36744
37012
  await db.write(
36745
- `?[file_path, entity_key] := *file_index{file_path: $fp, entity_key} :rm file_index { file_path, entity_key }`,
37013
+ "?[file_path, entity_key] := *file_index{file_path: $fp, entity_key} :rm file_index { file_path, entity_key }",
36746
37014
  { fp: relPath }
36747
37015
  );
36748
37016
  } catch {
@@ -36760,7 +37028,7 @@ async function removeEntitiesAndEdgesBatched(db, entityKeys) {
36760
37028
  for (const key of entityKeys) {
36761
37029
  try {
36762
37030
  const result = await db.write(
36763
- `?[from_key, to_key, type] := *edges{from_key: $key, to_key, type} :rm edges { from_key, to_key, type }`,
37031
+ "?[from_key, to_key, type] := *edges{from_key: $key, to_key, type} :rm edges { from_key, to_key, type }",
36764
37032
  { key }
36765
37033
  );
36766
37034
  edgesRemoved += result.rows?.length ?? 0;
@@ -36768,7 +37036,7 @@ async function removeEntitiesAndEdgesBatched(db, entityKeys) {
36768
37036
  }
36769
37037
  try {
36770
37038
  const result = await db.write(
36771
- `?[from_key, to_key, type] := *edges{from_key, to_key: $key, type} :rm edges { from_key, to_key, type }`,
37039
+ "?[from_key, to_key, type] := *edges{from_key, to_key: $key, type} :rm edges { from_key, to_key, type }",
36772
37040
  { key }
36773
37041
  );
36774
37042
  edgesRemoved += result.rows?.length ?? 0;
@@ -36784,7 +37052,7 @@ async function removeEntitiesAndEdgesBatched(db, entityKeys) {
36784
37052
  for (const key of entityKeys) {
36785
37053
  try {
36786
37054
  await db.write(
36787
- `?[file_path, entity_key] := *file_index{file_path, entity_key}, entity_key = $key :rm file_index { file_path, entity_key }`,
37055
+ "?[file_path, entity_key] := *file_index{file_path, entity_key}, entity_key = $key :rm file_index { file_path, entity_key }",
36788
37056
  { key }
36789
37057
  );
36790
37058
  } catch {
@@ -36797,14 +37065,14 @@ async function removeEdgesForKeysBatched(db, entityKeys) {
36797
37065
  for (const key of entityKeys) {
36798
37066
  try {
36799
37067
  await db.write(
36800
- `?[from_key, to_key, type] := *edges{from_key: $key, to_key, type} :rm edges { from_key, to_key, type }`,
37068
+ "?[from_key, to_key, type] := *edges{from_key: $key, to_key, type} :rm edges { from_key, to_key, type }",
36801
37069
  { key }
36802
37070
  );
36803
37071
  } catch {
36804
37072
  }
36805
37073
  try {
36806
37074
  await db.write(
36807
- `?[from_key, to_key, type] := *edges{from_key, to_key: $key, type} :rm edges { from_key, to_key, type }`,
37075
+ "?[from_key, to_key, type] := *edges{from_key, to_key: $key, type} :rm edges { from_key, to_key, type }",
36808
37076
  { key }
36809
37077
  );
36810
37078
  } catch {
@@ -36880,7 +37148,7 @@ async function removeEdgesBatched(db, edges) {
36880
37148
  for (const [fk, tk, type] of edges) {
36881
37149
  try {
36882
37150
  await db.write(
36883
- `?[from_key, to_key, type] <- [[$fk, $tk, $type]] :rm edges { from_key, to_key, type }`,
37151
+ "?[from_key, to_key, type] <- [[$fk, $tk, $type]] :rm edges { from_key, to_key, type }",
36884
37152
  { fk, tk, type }
36885
37153
  );
36886
37154
  } catch {
@@ -37015,7 +37283,7 @@ async function updateFanCountsBatched(db, affectedKeys) {
37015
37283
  const fo = fanOutMap.get(key) ?? 0;
37016
37284
  try {
37017
37285
  await db.write(
37018
- `?[key, fan_in, fan_out] <- [[$key, $fi, $fo]] :update entities { key => fan_in, fan_out }`,
37286
+ "?[key, fan_in, fan_out] <- [[$key, $fi, $fo]] :update entities { key => fan_in, fan_out }",
37019
37287
  { key, fi, fo }
37020
37288
  );
37021
37289
  } catch {
@@ -37255,13 +37523,7 @@ var init_background_indexer = __esm({
37255
37523
  this._result = null;
37256
37524
  this._error = null;
37257
37525
  this._completedAt = null;
37258
- this.runIndexing(
37259
- projectRoot,
37260
- graphStore,
37261
- repoId,
37262
- onComplete,
37263
- onError
37264
- );
37526
+ this.runIndexing(projectRoot, graphStore, repoId, onComplete, onError);
37265
37527
  }
37266
37528
  /** Whether indexing is currently in progress. */
37267
37529
  isIndexing() {
@@ -37531,7 +37793,7 @@ async function computeDriftImpact(db) {
37531
37793
  async function detectOrphanTestFiles(db) {
37532
37794
  try {
37533
37795
  const testFilesResult = await db.run(
37534
- `?[fp] := *entities{file_path: fp, is_test: t}, t = true`
37796
+ "?[fp] := *entities{file_path: fp, is_test: t}, t = true"
37535
37797
  );
37536
37798
  const allTestFiles = new Set(
37537
37799
  testFilesResult.rows.map((row) => row[0])
@@ -37703,7 +37965,7 @@ var workspace_manifest_exports = {};
37703
37965
  __export(workspace_manifest_exports, {
37704
37966
  WorkspaceManifest: () => WorkspaceManifest
37705
37967
  });
37706
- import { existsSync as existsSync72, mkdirSync as mkdirSync45, readFileSync as readFileSync62, writeFileSync as writeFileSync40 } from "fs";
37968
+ import { existsSync as existsSync72, mkdirSync as mkdirSync45, readFileSync as readFileSync63, writeFileSync as writeFileSync40 } from "fs";
37707
37969
  import { join as join73 } from "path";
37708
37970
  var WorkspaceManifest;
37709
37971
  var init_workspace_manifest = __esm({
@@ -37819,7 +38081,7 @@ var init_workspace_manifest = __esm({
37819
38081
  };
37820
38082
  }
37821
38083
  try {
37822
- const raw = readFileSync62(this.manifestPath, "utf-8");
38084
+ const raw = readFileSync63(this.manifestPath, "utf-8");
37823
38085
  const parsed = JSON.parse(raw);
37824
38086
  if (parsed.repoId !== this.repoId) {
37825
38087
  return {
@@ -38338,6 +38600,83 @@ var init_middleware = __esm({
38338
38600
  }
38339
38601
  });
38340
38602
 
38603
+ // src/server/routes/drift.ts
38604
+ import { existsSync as existsSync74, readFileSync as readFileSync64, readdirSync as readdirSync15 } from "fs";
38605
+ import { join as join75 } from "path";
38606
+ import { Hono as Hono2 } from "hono";
38607
+ function readFlags(path7) {
38608
+ try {
38609
+ if (!existsSync74(path7)) return null;
38610
+ return JSON.parse(readFileSync64(path7, "utf8"));
38611
+ } catch {
38612
+ return null;
38613
+ }
38614
+ }
38615
+ function listSessionFiles(stateDir) {
38616
+ try {
38617
+ if (!existsSync74(stateDir)) return [];
38618
+ return readdirSync15(stateDir).filter((f) => f.startsWith("nudge-") && f.endsWith(".flags")).map((f) => join75(stateDir, f));
38619
+ } catch {
38620
+ return [];
38621
+ }
38622
+ }
38623
+ function rowFor(file) {
38624
+ const flags = readFlags(file);
38625
+ if (!flags) return null;
38626
+ const id = file.split("/").pop()?.replace(/^nudge-/, "").replace(/\.flags$/, "");
38627
+ return {
38628
+ session_id: id ?? "",
38629
+ tier0_emitted: Boolean(flags.tier0_emitted),
38630
+ tier1_kinds: Array.isArray(flags.tier1_emitted_kinds) ? flags.tier1_emitted_kinds : [],
38631
+ drift_count: typeof flags.drift_count === "number" ? flags.drift_count : 0,
38632
+ tier2_emitted: Boolean(flags.tier2_emitted),
38633
+ last_unerr_tool_at: flags.last_unerr_tool_at ?? null
38634
+ };
38635
+ }
38636
+ function createDriftRoutes(deps) {
38637
+ const app = new Hono2();
38638
+ const stateDir = join75(deps.cwd, ".unerr", "state");
38639
+ app.get("/sessions", (c) => {
38640
+ const rows = [];
38641
+ for (const file of listSessionFiles(stateDir)) {
38642
+ const r = rowFor(file);
38643
+ if (r) rows.push(r);
38644
+ }
38645
+ const totalDrift = rows.reduce((s, r) => s + r.drift_count, 0);
38646
+ const corrected = rows.filter((r) => r.last_unerr_tool_at).length;
38647
+ return c.json({
38648
+ data: {
38649
+ sessions: rows,
38650
+ total_sessions: rows.length,
38651
+ total_drift_events: totalDrift,
38652
+ sessions_with_correction: corrected,
38653
+ correction_rate: rows.length > 0 ? corrected / rows.length : 0
38654
+ }
38655
+ });
38656
+ });
38657
+ app.get("/current", (c) => {
38658
+ const id = process.env.UNERR_SESSION_ID ?? `pid-${process.pid}`;
38659
+ const file = join75(stateDir, `nudge-${id}.flags`);
38660
+ const row = rowFor(file);
38661
+ return c.json({
38662
+ data: row ?? {
38663
+ session_id: id,
38664
+ tier0_emitted: false,
38665
+ tier1_kinds: [],
38666
+ drift_count: 0,
38667
+ tier2_emitted: false,
38668
+ last_unerr_tool_at: null
38669
+ }
38670
+ });
38671
+ });
38672
+ return app;
38673
+ }
38674
+ var init_drift = __esm({
38675
+ "src/server/routes/drift.ts"() {
38676
+ "use strict";
38677
+ }
38678
+ });
38679
+
38341
38680
  // src/intelligence/health-map-data.ts
38342
38681
  var health_map_data_exports = {};
38343
38682
  __export(health_map_data_exports, {
@@ -38569,7 +38908,7 @@ var init_health_map_data = __esm({
38569
38908
  });
38570
38909
 
38571
38910
  // src/server/routes/intelligence.ts
38572
- import { Hono as Hono2 } from "hono";
38911
+ import { Hono as Hono3 } from "hono";
38573
38912
  function slimCallerCallee(e) {
38574
38913
  return {
38575
38914
  key: e.key,
@@ -38597,7 +38936,7 @@ function parseLimit(raw, fallback, max) {
38597
38936
  return Math.min(n, max);
38598
38937
  }
38599
38938
  function createIntelligenceRoutes(deps) {
38600
- const app = new Hono2();
38939
+ const app = new Hono3();
38601
38940
  app.get("/search", async (c) => {
38602
38941
  const start = performance.now();
38603
38942
  const q = (c.req.query("q") ?? "").trim();
@@ -38899,7 +39238,7 @@ function createIntelligenceRoutes(deps) {
38899
39238
  const type = row[2];
38900
39239
  if (type === "contains") {
38901
39240
  if (!containsChildren.has(from)) containsChildren.set(from, /* @__PURE__ */ new Set());
38902
- containsChildren.get(from).add(to);
39241
+ containsChildren.get(from)?.add(to);
38903
39242
  childToParent.set(to, from);
38904
39243
  } else {
38905
39244
  relationshipEdges.push({ from, to, type });
@@ -39218,7 +39557,8 @@ function createIntelligenceRoutes(deps) {
39218
39557
  for (const [, ents] of fileEntityMap) {
39219
39558
  if (ents.length <= 1) {
39220
39559
  if (ents.length === 1) {
39221
- positions.entities[ents[0].id] = { x: 0, y: 0 };
39560
+ const ent0 = ents[0];
39561
+ if (ent0) positions.entities[ent0.id] = { x: 0, y: 0 };
39222
39562
  }
39223
39563
  continue;
39224
39564
  }
@@ -39852,7 +40192,7 @@ var init_session_history = __esm({
39852
40192
  });
39853
40193
 
39854
40194
  // src/server/routes/reasoning-quality.ts
39855
- import { Hono as Hono3 } from "hono";
40195
+ import { Hono as Hono4 } from "hono";
39856
40196
  function computeQualityMetrics(events) {
39857
40197
  if (events.length === 0) {
39858
40198
  return {
@@ -40048,7 +40388,7 @@ function computeQualityMetrics(events) {
40048
40388
  };
40049
40389
  }
40050
40390
  function createReasoningQualityRoutes(deps) {
40051
- const app = new Hono3();
40391
+ const app = new Hono4();
40052
40392
  app.get("/global", (c) => {
40053
40393
  const start = performance.now();
40054
40394
  const fromTs = c.req.query("from_ts");
@@ -40173,7 +40513,7 @@ function createReasoningQualityRoutes(deps) {
40173
40513
  memory_signals_fired: m.memory_signals_fired,
40174
40514
  memory_verdicts_total: m.memory_verdicts_total
40175
40515
  };
40176
- }).sort((a, b) => b.last_ts.localeCompare(a.last_ts));
40516
+ }).sort((a, b) => (b.last_ts ?? "").localeCompare(a.last_ts ?? ""));
40177
40517
  const paginated = allSessions.slice(offset, offset + limit);
40178
40518
  return c.json({
40179
40519
  data: paginated,
@@ -40249,14 +40589,14 @@ var init_reasoning_quality = __esm({
40249
40589
  });
40250
40590
 
40251
40591
  // src/server/routes/session.ts
40252
- import { Hono as Hono4 } from "hono";
40592
+ import { Hono as Hono5 } from "hono";
40253
40593
  function parseLimit2(raw, fallback, max) {
40254
40594
  const n = Number.parseInt(raw ?? "", 10);
40255
40595
  if (Number.isNaN(n) || n < 1) return fallback;
40256
40596
  return Math.min(n, max);
40257
40597
  }
40258
40598
  function createSessionRoutes(deps) {
40259
- const app = new Hono4();
40599
+ const app = new Hono5();
40260
40600
  app.get("/stats", async (c) => {
40261
40601
  const start = performance.now();
40262
40602
  const s = deps.stats;
@@ -40339,10 +40679,10 @@ var init_session = __esm({
40339
40679
  });
40340
40680
 
40341
40681
  // src/server/routes/stream.ts
40342
- import { Hono as Hono5 } from "hono";
40682
+ import { Hono as Hono6 } from "hono";
40343
40683
  import { streamSSE } from "hono/streaming";
40344
40684
  function createStreamRoutes(deps) {
40345
- const app = new Hono5();
40685
+ const app = new Hono6();
40346
40686
  app.get("/", (c) => {
40347
40687
  return streamSSE(c, async (stream) => {
40348
40688
  let id = 0;
@@ -40429,7 +40769,7 @@ function createStreamRoutes(deps) {
40429
40769
  }
40430
40770
  }, 3e4);
40431
40771
  while (!aborted) {
40432
- await new Promise((resolve6) => setTimeout(resolve6, 1e3));
40772
+ await new Promise((resolve9) => setTimeout(resolve9, 1e3));
40433
40773
  }
40434
40774
  clearInterval(pingInterval);
40435
40775
  clearInterval(statsInterval);
@@ -40447,9 +40787,9 @@ var init_stream = __esm({
40447
40787
  });
40448
40788
 
40449
40789
  // src/server/routes/system.ts
40450
- import { Hono as Hono6 } from "hono";
40790
+ import { Hono as Hono7 } from "hono";
40451
40791
  function createSystemRoutes(deps) {
40452
- const app = new Hono6();
40792
+ const app = new Hono7();
40453
40793
  app.get("/status", async (c) => {
40454
40794
  const start = performance.now();
40455
40795
  const uptime = Math.round((Date.now() - deps.startedAt) / 1e3);
@@ -40479,13 +40819,13 @@ function createSystemRoutes(deps) {
40479
40819
  });
40480
40820
  app.get("/config", async (c) => {
40481
40821
  const start = performance.now();
40482
- const { existsSync: existsSync80, readFileSync: readFileSync67 } = await import("fs");
40822
+ const { existsSync: existsSync80, readFileSync: readFileSync68 } = await import("fs");
40483
40823
  const { join: join81 } = await import("path");
40484
40824
  let config = {};
40485
40825
  const configPath = join81(deps.cwd, ".unerr", "config.json");
40486
40826
  if (existsSync80(configPath)) {
40487
40827
  try {
40488
- config = JSON.parse(readFileSync67(configPath, "utf-8"));
40828
+ config = JSON.parse(readFileSync68(configPath, "utf-8"));
40489
40829
  } catch {
40490
40830
  config = { error: "unreadable" };
40491
40831
  }
@@ -40519,83 +40859,6 @@ var init_system = __esm({
40519
40859
  }
40520
40860
  });
40521
40861
 
40522
- // src/server/routes/drift.ts
40523
- import { existsSync as existsSync74, readFileSync as readFileSync63, readdirSync as readdirSync15 } from "fs";
40524
- import { join as join75 } from "path";
40525
- import { Hono as Hono7 } from "hono";
40526
- function readFlags(path7) {
40527
- try {
40528
- if (!existsSync74(path7)) return null;
40529
- return JSON.parse(readFileSync63(path7, "utf8"));
40530
- } catch {
40531
- return null;
40532
- }
40533
- }
40534
- function listSessionFiles(stateDir) {
40535
- try {
40536
- if (!existsSync74(stateDir)) return [];
40537
- return readdirSync15(stateDir).filter((f) => f.startsWith("nudge-") && f.endsWith(".flags")).map((f) => join75(stateDir, f));
40538
- } catch {
40539
- return [];
40540
- }
40541
- }
40542
- function rowFor(file) {
40543
- const flags = readFlags(file);
40544
- if (!flags) return null;
40545
- const id = file.split("/").pop().replace(/^nudge-/, "").replace(/\.flags$/, "");
40546
- return {
40547
- session_id: id,
40548
- tier0_emitted: Boolean(flags.tier0_emitted),
40549
- tier1_kinds: Array.isArray(flags.tier1_emitted_kinds) ? flags.tier1_emitted_kinds : [],
40550
- drift_count: typeof flags.drift_count === "number" ? flags.drift_count : 0,
40551
- tier2_emitted: Boolean(flags.tier2_emitted),
40552
- last_unerr_tool_at: flags.last_unerr_tool_at ?? null
40553
- };
40554
- }
40555
- function createDriftRoutes(deps) {
40556
- const app = new Hono7();
40557
- const stateDir = join75(deps.cwd, ".unerr", "state");
40558
- app.get("/sessions", (c) => {
40559
- const rows = [];
40560
- for (const file of listSessionFiles(stateDir)) {
40561
- const r = rowFor(file);
40562
- if (r) rows.push(r);
40563
- }
40564
- const totalDrift = rows.reduce((s, r) => s + r.drift_count, 0);
40565
- const corrected = rows.filter((r) => r.last_unerr_tool_at).length;
40566
- return c.json({
40567
- data: {
40568
- sessions: rows,
40569
- total_sessions: rows.length,
40570
- total_drift_events: totalDrift,
40571
- sessions_with_correction: corrected,
40572
- correction_rate: rows.length > 0 ? corrected / rows.length : 0
40573
- }
40574
- });
40575
- });
40576
- app.get("/current", (c) => {
40577
- const id = process.env.UNERR_SESSION_ID ?? `pid-${process.pid}`;
40578
- const file = join75(stateDir, `nudge-${id}.flags`);
40579
- const row = rowFor(file);
40580
- return c.json({
40581
- data: row ?? {
40582
- session_id: id,
40583
- tier0_emitted: false,
40584
- tier1_kinds: [],
40585
- drift_count: 0,
40586
- tier2_emitted: false,
40587
- last_unerr_tool_at: null
40588
- }
40589
- });
40590
- });
40591
- return app;
40592
- }
40593
- var init_drift = __esm({
40594
- "src/server/routes/drift.ts"() {
40595
- "use strict";
40596
- }
40597
- });
40598
-
40599
40862
  // src/server/routes/temporal.ts
40600
40863
  import { Hono as Hono8 } from "hono";
40601
40864
  function createTemporalRoutes(deps) {
@@ -40861,7 +41124,7 @@ function detectLoops(entries, opts = {}) {
40861
41124
  return all.sort((a, b) => Date.parse(b.last_ts) - Date.parse(a.last_ts));
40862
41125
  }
40863
41126
  function maxTs(entries) {
40864
- let max = -Infinity;
41127
+ let max = Number.NEGATIVE_INFINITY;
40865
41128
  for (const e of entries) {
40866
41129
  const t = entryTsMs(e);
40867
41130
  if (Number.isFinite(t) && t > max) max = t;
@@ -40872,12 +41135,7 @@ var READ_TOOLS, EDIT_TOOLS8, DEFAULT_READ_WINDOW_MS, DEFAULT_QUERY_WINDOW_MS, DE
40872
41135
  var init_loop_miner = __esm({
40873
41136
  "src/timeline/loop-miner.ts"() {
40874
41137
  "use strict";
40875
- READ_TOOLS = /* @__PURE__ */ new Set([
40876
- "file_read",
40877
- "file_outline",
40878
- "get_file",
40879
- "Read"
40880
- ]);
41138
+ READ_TOOLS = /* @__PURE__ */ new Set(["file_read", "file_outline", "get_file", "Read"]);
40881
41139
  EDIT_TOOLS8 = /* @__PURE__ */ new Set([
40882
41140
  "Edit",
40883
41141
  "Write",
@@ -41135,9 +41393,9 @@ function createTimelineRoutes(deps) {
41135
41393
  var init_timeline = __esm({
41136
41394
  "src/server/routes/timeline.ts"() {
41137
41395
  "use strict";
41396
+ init_intent_detector();
41138
41397
  init_loop_miner();
41139
41398
  init_open_threads();
41140
- init_intent_detector();
41141
41399
  }
41142
41400
  });
41143
41401
 
@@ -41507,20 +41765,20 @@ var http_exports = {};
41507
41765
  __export(http_exports, {
41508
41766
  startDashboardServer: () => startDashboardServer
41509
41767
  });
41510
- import { existsSync as existsSync75, readFileSync as readFileSync64, unlinkSync as unlinkSync14, writeFileSync as writeFileSync41 } from "fs";
41768
+ import { existsSync as existsSync75, readFileSync as readFileSync65, unlinkSync as unlinkSync14, writeFileSync as writeFileSync41 } from "fs";
41511
41769
  import { createServer as createServer4 } from "net";
41512
- import { dirname as dirname11, join as join76 } from "path";
41770
+ import { dirname as dirname14, join as join76 } from "path";
41513
41771
  import { fileURLToPath as fileURLToPath3 } from "url";
41514
41772
  import { serve as serve2 } from "@hono/node-server";
41515
41773
  import { serveStatic as serveStatic2 } from "@hono/node-server/serve-static";
41516
41774
  import { Hono as Hono11 } from "hono";
41517
41775
  async function findAvailablePort() {
41518
41776
  for (let port = PORT_START; port <= PORT_END; port++) {
41519
- const available = await new Promise((resolve6) => {
41777
+ const available = await new Promise((resolve9) => {
41520
41778
  const server = createServer4();
41521
- server.once("error", () => resolve6(false));
41779
+ server.once("error", () => resolve9(false));
41522
41780
  server.once("listening", () => {
41523
- server.close(() => resolve6(true));
41781
+ server.close(() => resolve9(true));
41524
41782
  });
41525
41783
  server.listen(port, "127.0.0.1");
41526
41784
  });
@@ -41563,10 +41821,10 @@ async function startDashboardServer(opts) {
41563
41821
  );
41564
41822
  }
41565
41823
  if (!opts.apiOnly) {
41566
- const distDir = join76(dirname11(fileURLToPath3(import.meta.url)), "ui");
41824
+ const distDir = join76(dirname14(fileURLToPath3(import.meta.url)), "ui");
41567
41825
  const spaIndex = join76(distDir, "index.html");
41568
41826
  if (existsSync75(spaIndex)) {
41569
- const spaHtml = readFileSync64(spaIndex, "utf-8");
41827
+ const spaHtml = readFileSync65(spaIndex, "utf-8");
41570
41828
  app.use("*", serveStatic2({ root: distDir }));
41571
41829
  app.get("*", (c) => {
41572
41830
  const path7 = c.req.path;
@@ -41626,12 +41884,12 @@ var init_http = __esm({
41626
41884
  "src/server/http.ts"() {
41627
41885
  "use strict";
41628
41886
  init_middleware();
41887
+ init_drift();
41629
41888
  init_intelligence();
41630
41889
  init_reasoning_quality();
41631
41890
  init_session();
41632
41891
  init_stream();
41633
41892
  init_system();
41634
- init_drift();
41635
41893
  init_temporal();
41636
41894
  init_timeline();
41637
41895
  init_token_flow2();
@@ -41718,7 +41976,9 @@ function printSessionReceipt(input) {
41718
41976
  }
41719
41977
  }
41720
41978
  function stripAnsi3(s) {
41721
- return s.replace(/\x1b\[[0-9;?]*[A-Za-z~]/g, "");
41979
+ const ESC2 = "\x1B";
41980
+ const CSI = new RegExp(`${ESC2}\\[[0-9;?]*[A-Za-z~]`, "g");
41981
+ return s.replace(CSI, "");
41722
41982
  }
41723
41983
  var DIM2, BOLD2, RESET2, EMERALD2, CYAN2, VIOLET2, MUTED2;
41724
41984
  var init_session_receipt = __esm({
@@ -42024,7 +42284,7 @@ import {
42024
42284
  existsSync as existsSync76,
42025
42285
  writeFileSync as fsWriteFileSync,
42026
42286
  mkdirSync as mkdirSync46,
42027
- readFileSync as readFileSync65,
42287
+ readFileSync as readFileSync66,
42028
42288
  readdirSync as readdirSync16
42029
42289
  } from "fs";
42030
42290
  import { join as join77 } from "path";
@@ -42122,8 +42382,8 @@ async function handleRecallFactsProxy(args, unerrDir, effectiveness) {
42122
42382
  }
42123
42383
  const useRotation = rotationMode !== "none" && proxyShowStore !== null;
42124
42384
  const ranked = rankFactsWithRotation2(facts, {
42125
- getShowCount: useRotation ? (id) => proxyShowStore.getEffectiveShowCount(id) : void 0,
42126
- getLastShownMs: useRotation ? (id) => proxyShowStore.getLastShownMs(id) : void 0
42385
+ getShowCount: useRotation ? (id) => proxyShowStore?.getEffectiveShowCount(id) ?? 0 : void 0,
42386
+ getLastShownMs: useRotation ? (id) => proxyShowStore?.getLastShownMs(id) ?? 0 : void 0
42127
42387
  });
42128
42388
  const total = ranked.length;
42129
42389
  const sliced = applyDiversityQuota2(ranked, requestedLimit);
@@ -42178,14 +42438,15 @@ function migrateAgentPermissions(cwd) {
42178
42438
  try {
42179
42439
  const settingsPath = join77(cwd, ".claude", "settings.json");
42180
42440
  if (!existsSync76(settingsPath)) return;
42181
- const raw = readFileSync65(settingsPath, "utf-8");
42441
+ const raw = readFileSync66(settingsPath, "utf-8");
42182
42442
  const settings = JSON.parse(raw);
42183
42443
  const deny = settings?.permissions?.deny;
42184
42444
  if (!Array.isArray(deny)) return;
42185
42445
  const readIdx = deny.indexOf("Read");
42186
42446
  if (readIdx < 0) return;
42187
42447
  deny.splice(readIdx, 1);
42188
- fsWriteFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
42448
+ fsWriteFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}
42449
+ `);
42189
42450
  process.stderr.write(
42190
42451
  "[unerr] Migrated permissions: removed Read from deny list (required for Edit workflow)\n"
42191
42452
  );
@@ -42244,7 +42505,7 @@ async function startProxy(opts = {}) {
42244
42505
  const configPath = join77(process.cwd(), ".unerr", "config.json");
42245
42506
  if (existsSync76(configPath)) {
42246
42507
  try {
42247
- const config = JSON.parse(readFileSync65(configPath, "utf-8"));
42508
+ const config = JSON.parse(readFileSync66(configPath, "utf-8"));
42248
42509
  if (config.repoId) repoIds = [config.repoId];
42249
42510
  } catch {
42250
42511
  }
@@ -42812,9 +43073,7 @@ async function startProxy(opts = {}) {
42812
43073
  );
42813
43074
  router.setEffectivenessTracker(effectivenessTracker);
42814
43075
  shadowLedger.getTurnSegmenter().onTurnClose(() => {
42815
- effectivenessTracker.closeWindow(
42816
- router.sessionContext.getToolCallCount()
42817
- );
43076
+ effectivenessTracker.closeWindow(router.sessionContext.getToolCallCount());
42818
43077
  });
42819
43078
  const { WorkingSnapshotStore: WorkingSnapshotStore2 } = await Promise.resolve().then(() => (init_working_snapshots(), working_snapshots_exports));
42820
43079
  const workingSnapshotStore = new WorkingSnapshotStore2(unerrDirForLedger);
@@ -42884,9 +43143,7 @@ async function startProxy(opts = {}) {
42884
43143
  `
42885
43144
  );
42886
43145
  return {
42887
- content: [
42888
- { type: "text", text: JSON.stringify(validationFailure) }
42889
- ],
43146
+ content: [{ type: "text", text: JSON.stringify(validationFailure) }],
42890
43147
  isError: true
42891
43148
  };
42892
43149
  }
@@ -42954,23 +43211,24 @@ async function startProxy(opts = {}) {
42954
43211
  headShaVal = await getHeadSha3(process.cwd()) ?? "";
42955
43212
  } catch {
42956
43213
  }
42957
- return handleMarkerCall2(
42958
- name,
42959
- args,
42960
- {
42961
- ledger: shadowLedger,
42962
- store: timelineHandle.store,
42963
- branch: branchVal,
42964
- headSha: headShaVal
42965
- }
42966
- );
43214
+ return handleMarkerCall2(name, args, {
43215
+ ledger: shadowLedger,
43216
+ store: timelineHandle.store,
43217
+ branch: branchVal,
43218
+ headSha: headShaVal
43219
+ });
42967
43220
  }
42968
43221
  }
42969
43222
  if (name === "record_fact" || name === "recall_facts") {
42970
- const factResult = name === "record_fact" ? await handleRecordFactProxy(args, unerrDirForLedger, shadowLedger, {
42971
- tracker: effectivenessTracker,
42972
- turn: router.sessionContext.getToolCallCount()
42973
- }) : await handleRecallFactsProxy(args, unerrDirForLedger, {
43223
+ const factResult = name === "record_fact" ? await handleRecordFactProxy(
43224
+ args,
43225
+ unerrDirForLedger,
43226
+ shadowLedger,
43227
+ {
43228
+ tracker: effectivenessTracker,
43229
+ turn: router.sessionContext.getToolCallCount()
43230
+ }
43231
+ ) : await handleRecallFactsProxy(args, unerrDirForLedger, {
42974
43232
  tracker: effectivenessTracker,
42975
43233
  turn: router.sessionContext.getToolCallCount()
42976
43234
  });
@@ -43127,7 +43385,7 @@ async function startProxy(opts = {}) {
43127
43385
  const lastEntry = recentEntries[recentEntries.length - 1];
43128
43386
  if (lastEntry) {
43129
43387
  setImmediate(
43130
- () => narrativeCapture.captureEditNarrative(lastEntry).catch(() => {
43388
+ () => narrativeCapture?.captureEditNarrative(lastEntry).catch(() => {
43131
43389
  })
43132
43390
  );
43133
43391
  }
@@ -43137,11 +43395,11 @@ async function startProxy(opts = {}) {
43137
43395
  setImmediate(async () => {
43138
43396
  try {
43139
43397
  const { analyzeSessionPatterns: analyzeSessionPatterns2 } = await Promise.resolve().then(() => (init_session_pattern_analyzer(), session_pattern_analyzer_exports));
43140
- const entries = shadowLedger.getRecentEntries(20);
43398
+ const entries = shadowLedger?.getRecentEntries(20);
43141
43399
  await analyzeSessionPatterns2({
43142
43400
  ledgerEntries: entries,
43143
43401
  factStore: proxyFactStore2,
43144
- sessionId: shadowLedger.getSessionId()
43402
+ sessionId: shadowLedger?.getSessionId()
43145
43403
  });
43146
43404
  } catch {
43147
43405
  }
@@ -43808,7 +44066,7 @@ ${signalFooter2.trimEnd()}` : "";
43808
44066
  });
43809
44067
  for (const file of sourceFiles.slice(0, 500)) {
43810
44068
  try {
43811
- const content = readFileSync65(join77(process.cwd(), file), "utf-8");
44069
+ const content = readFileSync66(join77(process.cwd(), file), "utf-8");
43812
44070
  const entities = extractEntitiesFromSource2(file, content);
43813
44071
  parseIndex.addEntities(entities);
43814
44072
  } catch {
@@ -43978,7 +44236,7 @@ ${signalFooter2.trimEnd()}` : "";
43978
44236
  temporal: await (async () => {
43979
44237
  try {
43980
44238
  const { TemporalFactStore: TemporalFactStore2 } = await Promise.resolve().then(() => (init_temporal_facts(), temporal_facts_exports));
43981
- const { readdirSync: readdirSync18, readFileSync: readFileSync67 } = await import("fs");
44239
+ const { readdirSync: readdirSync18, readFileSync: readFileSync68 } = await import("fs");
43982
44240
  const factStore = await TemporalFactStore2.create(process.cwd());
43983
44241
  return {
43984
44242
  factStore,
@@ -43987,7 +44245,7 @@ ${signalFooter2.trimEnd()}` : "";
43987
44245
  const sessDir = join77(unerrDirForApi, "sessions");
43988
44246
  const files = readdirSync18(sessDir).filter((f) => f.endsWith(".jsonl")).sort().slice(-limit);
43989
44247
  return files.map((f) => {
43990
- const content = readFileSync67(join77(sessDir, f), "utf-8").trim().split("\n").pop();
44248
+ const content = readFileSync68(join77(sessDir, f), "utf-8").trim().split("\n").pop();
43991
44249
  return JSON.parse(content);
43992
44250
  });
43993
44251
  } catch {
@@ -44152,10 +44410,7 @@ ${signalFooter2.trimEnd()}` : "";
44152
44410
  const counterfactualStr = tokensWithout > 0 ? formatCounterfactual2(tokensWithout, tokensWithout - tokensSaved) : void 0;
44153
44411
  try {
44154
44412
  const React3 = __require("react");
44155
- const { SessionSummaryCard: SessionSummaryCard2 } = (
44156
- // biome-ignore lint/suspicious/noExplicitAny: dynamic require in non-critical shutdown path
44157
- (init_SessionSummaryCard(), __toCommonJS(SessionSummaryCard_exports))
44158
- );
44413
+ const { SessionSummaryCard: SessionSummaryCard2 } = (init_SessionSummaryCard(), __toCommonJS(SessionSummaryCard_exports));
44159
44414
  const { ThemeProvider: ThemeProvider2 } = (init_Theme(), __toCommonJS(Theme_exports));
44160
44415
  const { renderToStderr: renderToStderr2 } = (init_render(), __toCommonJS(render_exports));
44161
44416
  const el = React3.createElement(
@@ -44448,12 +44703,12 @@ var log21, proxyFactStore, proxyShowStore;
44448
44703
  var init_proxy = __esm({
44449
44704
  "src/proxy/proxy.ts"() {
44450
44705
  "use strict";
44706
+ init_arg_validator();
44451
44707
  init_pid_lock();
44452
44708
  init_session_stats();
44453
44709
  init_startup_renderer();
44454
44710
  init_tool_clusters();
44455
44711
  init_tool_definitions();
44456
- init_arg_validator();
44457
44712
  init_file_logger();
44458
44713
  init_format_error();
44459
44714
  init_mcp_content_json();
@@ -45014,7 +45269,7 @@ __export(bridge_exports, {
45014
45269
  });
45015
45270
  import { connect } from "net";
45016
45271
  function startUdsBridge(sockPath2) {
45017
- return new Promise((resolve6, reject) => {
45272
+ return new Promise((resolve9, reject) => {
45018
45273
  const socket = connect(sockPath2);
45019
45274
  let heartbeatTimer;
45020
45275
  let heartbeatTimeoutTimer;
@@ -45027,7 +45282,7 @@ function startUdsBridge(sockPath2) {
45027
45282
  if (heartbeatTimer) clearInterval(heartbeatTimer);
45028
45283
  if (heartbeatTimeoutTimer) clearTimeout(heartbeatTimeoutTimer);
45029
45284
  if (!socket.destroyed) socket.destroy();
45030
- resolve6({ reason });
45285
+ resolve9({ reason });
45031
45286
  }
45032
45287
  socket.on("connect", () => {
45033
45288
  log23.info(`Connected to proxy at ${sockPath2}`);
@@ -45077,7 +45332,8 @@ function startUdsBridge(sockPath2) {
45077
45332
  params: { ts: Date.now() }
45078
45333
  });
45079
45334
  try {
45080
- socket.write(ping + "\n");
45335
+ socket.write(`${ping}
45336
+ `);
45081
45337
  } catch {
45082
45338
  cleanup("daemon_dead");
45083
45339
  return;
@@ -45127,7 +45383,7 @@ var init_bridge = __esm({
45127
45383
  });
45128
45384
 
45129
45385
  // src/entrypoints/cli.ts
45130
- import { existsSync as existsSync79, readFileSync as readFileSync66 } from "fs";
45386
+ import { existsSync as existsSync79, readFileSync as readFileSync67 } from "fs";
45131
45387
  import { join as join80 } from "path";
45132
45388
  import { Command } from "commander";
45133
45389
 
@@ -45521,7 +45777,7 @@ init_config_verify();
45521
45777
 
45522
45778
  // src/commands/daemon.ts
45523
45779
  init_registry();
45524
- import { resolve as resolve2 } from "path";
45780
+ import { resolve as resolve5 } from "path";
45525
45781
 
45526
45782
  // src/daemon/settings-schema.ts
45527
45783
  init_protocol();
@@ -45604,9 +45860,7 @@ function registerDaemonCommand(program2) {
45604
45860
  const { existsSync: existsSync80, mkdirSync: mkdirSync49, writeFileSync: writeFileSync43 } = await import("fs");
45605
45861
  const { homedir: homedir16 } = await import("os");
45606
45862
  const { join: join81 } = await import("path");
45607
- write2(
45608
- "\x1B[38;2;139;92;246m\u25B8\x1B[0m Initializing unerr daemon...\n"
45609
- );
45863
+ write2("\x1B[38;2;139;92;246m\u25B8\x1B[0m Initializing unerr daemon...\n");
45610
45864
  const result = await installForCurrentPlatform2();
45611
45865
  if (result.installed) {
45612
45866
  const sentinel = join81(homedir16(), ".unerr", ".autostart-installed");
@@ -45718,8 +45972,8 @@ function registerDaemonCommand(program2) {
45718
45972
  const pidPath2 = join81(homedir16(), ".unerr", "unerrd.pid");
45719
45973
  let daemonPid = String(child.pid);
45720
45974
  try {
45721
- const { readFileSync: readFileSync67 } = await import("fs");
45722
- daemonPid = readFileSync67(pidPath2, "utf-8").trim();
45975
+ const { readFileSync: readFileSync68 } = await import("fs");
45976
+ daemonPid = readFileSync68(pidPath2, "utf-8").trim();
45723
45977
  } catch {
45724
45978
  }
45725
45979
  write2(
@@ -45744,19 +45998,19 @@ function registerDaemonCommand(program2) {
45744
45998
  return;
45745
45999
  }
45746
46000
  try {
45747
- await new Promise((resolve6, reject) => {
46001
+ await new Promise((resolve9, reject) => {
45748
46002
  const conn = createConnection3(sock, () => {
45749
46003
  conn.write(`${JSON.stringify({ cmd: "shutdown" })}
45750
46004
  `);
45751
46005
  });
45752
46006
  conn.on("data", () => {
45753
46007
  conn.destroy();
45754
- resolve6();
46008
+ resolve9();
45755
46009
  });
45756
46010
  conn.on("error", (err) => reject(err));
45757
46011
  setTimeout(() => {
45758
46012
  conn.destroy();
45759
- resolve6();
46013
+ resolve9();
45760
46014
  }, 3e3);
45761
46015
  });
45762
46016
  write2("\x1B[38;2;52;211;153m\u2713\x1B[0m unerrd stopped.\n");
@@ -45780,19 +46034,19 @@ function registerDaemonCommand(program2) {
45780
46034
  if (existsSync80(sock)) {
45781
46035
  write2("\x1B[38;2;139;92;246m\u25B8\x1B[0m Stopping unerrd...\n");
45782
46036
  try {
45783
- await new Promise((resolve6, reject) => {
46037
+ await new Promise((resolve9, reject) => {
45784
46038
  const conn = createConnection3(sock, () => {
45785
46039
  conn.write(`${JSON.stringify({ cmd: "shutdown" })}
45786
46040
  `);
45787
46041
  });
45788
46042
  conn.on("data", () => {
45789
46043
  conn.destroy();
45790
- resolve6();
46044
+ resolve9();
45791
46045
  });
45792
46046
  conn.on("error", (err) => reject(err));
45793
46047
  setTimeout(() => {
45794
46048
  conn.destroy();
45795
- resolve6();
46049
+ resolve9();
45796
46050
  }, 3e3);
45797
46051
  });
45798
46052
  stopped = true;
@@ -45818,14 +46072,10 @@ function registerDaemonCommand(program2) {
45818
46072
  `
45819
46073
  );
45820
46074
  } else {
45821
- write2(
45822
- "\x1B[38;2;52;211;153m\u2713\x1B[0m Boot registration removed.\n"
45823
- );
46075
+ write2("\x1B[38;2;52;211;153m\u2713\x1B[0m Boot registration removed.\n");
45824
46076
  }
45825
46077
  } catch {
45826
- write2(
45827
- "\x1B[38;2;251;191;36m\u26A0\x1B[0m No boot registration found.\n"
45828
- );
46078
+ write2("\x1B[38;2;251;191;36m\u26A0\x1B[0m No boot registration found.\n");
45829
46079
  }
45830
46080
  const pidFile = join81(home, "unerrd.pid");
45831
46081
  for (const f of [sock, pidFile]) {
@@ -45840,18 +46090,16 @@ function registerDaemonCommand(program2) {
45840
46090
  write2("\x1B[38;2;139;92;246m\u25B8\x1B[0m Purging ~/.unerr...\n");
45841
46091
  if (existsSync80(home)) {
45842
46092
  rmSync5(home, { recursive: true, force: true });
45843
- write2(
45844
- "\x1B[38;2;52;211;153m\u2713\x1B[0m ~/.unerr removed.\n"
45845
- );
46093
+ write2("\x1B[38;2;52;211;153m\u2713\x1B[0m ~/.unerr removed.\n");
45846
46094
  }
45847
46095
  }
45848
46096
  write2(
45849
- "\n\x1B[38;2;52;211;153m\u2713\x1B[0m Daemon teardown complete." + (opts.purge ? "" : " Registry and logs preserved in ~/.unerr (use --purge to remove).") + "\n"
46097
+ `
46098
+ \x1B[38;2;52;211;153m\u2713\x1B[0m Daemon teardown complete.${opts.purge ? "" : " Registry and logs preserved in ~/.unerr (use --purge to remove)."}
46099
+ `
45850
46100
  );
45851
46101
  if (!opts.purge) {
45852
- write2(
45853
- "\n To re-initialize: \x1B[1munerr daemon initialize\x1B[0m\n"
45854
- );
46102
+ write2("\n To re-initialize: \x1B[1munerr daemon initialize\x1B[0m\n");
45855
46103
  }
45856
46104
  });
45857
46105
  const addCmd = daemon.command("add [path]").description("Register a repo with unerrd").option(
@@ -45866,7 +46114,7 @@ function registerDaemonCommand(program2) {
45866
46114
  }
45867
46115
  addCmd.action(
45868
46116
  async (pathArg, opts) => {
45869
- const targetPath = resolve2(pathArg ?? ".");
46117
+ const targetPath = resolve5(pathArg ?? ".");
45870
46118
  const settingsRaw = {};
45871
46119
  for (const s of SETTINGS_SCHEMA) {
45872
46120
  const camelFlag = s.flag.replace(
@@ -45933,7 +46181,7 @@ function registerDaemonCommand(program2) {
45933
46181
  }
45934
46182
  );
45935
46183
  daemon.command("remove [path]").description("Unregister a repo from unerrd").action((pathArg) => {
45936
- const targetPath = resolve2(pathArg ?? ".");
46184
+ const targetPath = resolve5(pathArg ?? ".");
45937
46185
  const removed = removeRepo(targetPath);
45938
46186
  if (removed) {
45939
46187
  write2(`\x1B[38;2;52;211;153m\u2713\x1B[0m Removed ${targetPath}
@@ -45972,7 +46220,13 @@ function registerDaemonCommand(program2) {
45972
46220
  const { request } = await import("http");
45973
46221
  const body = await new Promise((resolveReq, rejectReq) => {
45974
46222
  const req = request(
45975
- { hostname: "127.0.0.1", port: 9847, path: "/api/repos", method: "GET", timeout: 2e3 },
46223
+ {
46224
+ hostname: "127.0.0.1",
46225
+ port: 9847,
46226
+ path: "/api/repos",
46227
+ method: "GET",
46228
+ timeout: 2e3
46229
+ },
45976
46230
  (res) => {
45977
46231
  let data = "";
45978
46232
  res.on("data", (chunk) => {
@@ -45991,7 +46245,13 @@ function registerDaemonCommand(program2) {
45991
46245
  const parsed = JSON.parse(body);
45992
46246
  liveStatus = /* @__PURE__ */ new Map();
45993
46247
  for (const r of parsed.repos) {
45994
- liveStatus.set(r.path, { status: r.status, pid: r.pid, connections: r.connections, idle: r.idle, memory: r.memory });
46248
+ liveStatus.set(r.path, {
46249
+ status: r.status,
46250
+ pid: r.pid,
46251
+ connections: r.connections,
46252
+ idle: r.idle,
46253
+ memory: r.memory
46254
+ });
45995
46255
  }
45996
46256
  }
45997
46257
  } catch {
@@ -46026,8 +46286,7 @@ function registerDaemonCommand(program2) {
46026
46286
  );
46027
46287
  }
46028
46288
  if (needsInput.length > 0) {
46029
- write2(` \x1B[38;2;251;191;36m\u26A0\x1B[0m Needs input:
46030
- `);
46289
+ write2(" \x1B[38;2;251;191;36m\u26A0\x1B[0m Needs input:\n");
46031
46290
  for (const ni of needsInput) {
46032
46291
  write2(
46033
46292
  ` ${ni.key}: auto-selected \x1B[1m${ni.auto}\x1B[0m (${ni.reason})
@@ -46046,7 +46305,7 @@ function registerDaemonCommand(program2) {
46046
46305
  }
46047
46306
  configCmd.action(
46048
46307
  (pathArg, opts) => {
46049
- const targetPath = resolve2(pathArg ?? ".");
46308
+ const targetPath = resolve5(pathArg ?? ".");
46050
46309
  const settingsRaw = {};
46051
46310
  for (const s of SETTINGS_SCHEMA) {
46052
46311
  const camelFlag = s.flag.replace(
@@ -46090,9 +46349,7 @@ function registerDaemonCommand(program2) {
46090
46349
  const needsInput = readNeedsInput(entry.path);
46091
46350
  if (needsInput.length > 0) {
46092
46351
  write2(
46093
- `
46094
- \x1B[38;2;251;191;36m\u26A0 Auto-detected picks (override with flags):\x1B[0m
46095
- `
46352
+ "\n \x1B[38;2;251;191;36m\u26A0 Auto-detected picks (override with flags):\x1B[0m\n"
46096
46353
  );
46097
46354
  for (const ni of needsInput) {
46098
46355
  write2(
@@ -46153,10 +46410,7 @@ function registerDaemonCommand(program2) {
46153
46410
  const autostartRepos = repos.filter(
46154
46411
  (r) => (r.settings?.autostart ?? "auto") !== "never"
46155
46412
  );
46156
- write2(`
46157
- \x1B[1munerr daemon autostart\x1B[0m
46158
-
46159
- `);
46413
+ write2("\n \x1B[1munerr daemon autostart\x1B[0m\n\n");
46160
46414
  write2(` Platform: ${status.platform}
46161
46415
  `);
46162
46416
  write2(
@@ -46269,11 +46523,11 @@ function registerDaemonCommand(program2) {
46269
46523
  stdio: ["ignore", "inherit", "inherit"]
46270
46524
  }
46271
46525
  );
46272
- await new Promise((resolve6) => {
46273
- child.on("close", () => resolve6());
46526
+ await new Promise((resolve9) => {
46527
+ child.on("close", () => resolve9());
46274
46528
  process.on("SIGINT", () => {
46275
46529
  child.kill("SIGTERM");
46276
- resolve6();
46530
+ resolve9();
46277
46531
  });
46278
46532
  });
46279
46533
  return;
@@ -46377,10 +46631,7 @@ ${tail}
46377
46631
  if (!anySet) {
46378
46632
  const { loadWarmStartConfig: loadWarmStartConfig2 } = await Promise.resolve().then(() => (init_warm_start(), warm_start_exports));
46379
46633
  const config = loadWarmStartConfig2();
46380
- write2(`
46381
- \x1B[1mGlobal daemon config\x1B[0m
46382
-
46383
- `);
46634
+ write2("\n \x1B[1mGlobal daemon config\x1B[0m\n\n");
46384
46635
  write2(` warmStartBudget: ${config.warmStartBudget}
46385
46636
  `);
46386
46637
  write2(` warmStartIdleDays: ${config.warmStartIdleDays}
@@ -46425,12 +46676,12 @@ ${tail}
46425
46676
  input: process.stdin,
46426
46677
  output: process.stderr
46427
46678
  });
46428
- const answer = await new Promise((resolve6) => {
46679
+ const answer = await new Promise((resolve9) => {
46429
46680
  rl.question(
46430
46681
  ` Update unerr ${info2.current} \u2192 ${info2.latest}? [y/N] `,
46431
46682
  (ans) => {
46432
46683
  rl.close();
46433
- resolve6(ans.trim().toLowerCase());
46684
+ resolve9(ans.trim().toLowerCase());
46434
46685
  }
46435
46686
  );
46436
46687
  });
@@ -46448,19 +46699,19 @@ ${tail}
46448
46699
  const sock = join81(globalDir2(), "unerrd.sock");
46449
46700
  const { existsSync: existsSync80 } = await import("fs");
46450
46701
  if (existsSync80(sock)) {
46451
- await new Promise((resolve6) => {
46702
+ await new Promise((resolve9) => {
46452
46703
  const conn = createConnection3(sock, () => {
46453
46704
  conn.write(`${JSON.stringify({ cmd: "shutdown" })}
46454
46705
  `);
46455
46706
  });
46456
46707
  conn.on("data", () => {
46457
46708
  conn.destroy();
46458
- resolve6();
46709
+ resolve9();
46459
46710
  });
46460
- conn.on("error", () => resolve6());
46711
+ conn.on("error", () => resolve9());
46461
46712
  setTimeout(() => {
46462
46713
  conn.destroy();
46463
- resolve6();
46714
+ resolve9();
46464
46715
  }, 5e3);
46465
46716
  });
46466
46717
  await new Promise((r) => setTimeout(r, 2e3));
@@ -46572,13 +46823,13 @@ function toKebab(s) {
46572
46823
  init_exec();
46573
46824
  init_git();
46574
46825
  init_startup_log();
46575
- import { existsSync as existsSync20, readFileSync as readFileSync17 } from "fs";
46826
+ import { existsSync as existsSync20, readFileSync as readFileSync18 } from "fs";
46576
46827
  import { join as join20 } from "path";
46577
46828
  function readServerJson(cwd) {
46578
46829
  const p = join20(cwd, ".unerr", "state", "server.json");
46579
46830
  if (!existsSync20(p)) return null;
46580
46831
  try {
46581
- const raw = readFileSync17(p, "utf-8");
46832
+ const raw = readFileSync18(p, "utf-8");
46582
46833
  return JSON.parse(raw);
46583
46834
  } catch {
46584
46835
  return null;
@@ -46617,7 +46868,7 @@ function registerDashboardCommand(program2) {
46617
46868
 
46618
46869
  // src/commands/debug.ts
46619
46870
  init_git();
46620
- import { existsSync as existsSync21, readFileSync as readFileSync18, readdirSync as readdirSync4, statSync as statSync3 } from "fs";
46871
+ import { existsSync as existsSync21, readFileSync as readFileSync19, readdirSync as readdirSync4, statSync as statSync3 } from "fs";
46621
46872
  import { arch, homedir as homedir10, platform as platform3, release } from "os";
46622
46873
  import { join as join21 } from "path";
46623
46874
  var UNERR_DIR = join21(homedir10(), ".unerr");
@@ -46635,7 +46886,7 @@ function registerDebugCommand(program2) {
46635
46886
  if (existsSync21(settingsPath)) {
46636
46887
  try {
46637
46888
  const settings = JSON.parse(
46638
- readFileSync18(settingsPath, "utf-8")
46889
+ readFileSync19(settingsPath, "utf-8")
46639
46890
  );
46640
46891
  for (const [key, value] of Object.entries(settings)) {
46641
46892
  if (key === "anthropicApiKey" && typeof value === "string") {
@@ -46663,7 +46914,7 @@ function registerDebugCommand(program2) {
46663
46914
  if (existsSync21(configPath)) {
46664
46915
  try {
46665
46916
  const config = JSON.parse(
46666
- readFileSync18(configPath, "utf-8")
46917
+ readFileSync19(configPath, "utf-8")
46667
46918
  );
46668
46919
  for (const [key, value] of Object.entries(config)) {
46669
46920
  sections.push(` ${key}: ${String(value)}`);
@@ -46680,7 +46931,7 @@ function registerDebugCommand(program2) {
46680
46931
  if (existsSync21(pidPath2)) {
46681
46932
  try {
46682
46933
  const pid = Number.parseInt(
46683
- readFileSync18(pidPath2, "utf-8").trim(),
46934
+ readFileSync19(pidPath2, "utf-8").trim(),
46684
46935
  10
46685
46936
  );
46686
46937
  let alive = false;
@@ -46751,7 +47002,7 @@ function registerDebugCommand(program2) {
46751
47002
  if (logFiles.length > 0 && logFiles[0]) {
46752
47003
  const logPath2 = join21(logsDir, logFiles[0]);
46753
47004
  try {
46754
- const content = readFileSync18(logPath2, "utf-8");
47005
+ const content = readFileSync19(logPath2, "utf-8");
46755
47006
  const lines = content.split("\n").filter(Boolean);
46756
47007
  const last20 = lines.slice(-20);
46757
47008
  for (const line of last20) {
@@ -47075,7 +47326,7 @@ function formatDriftNudge(hint) {
47075
47326
  }
47076
47327
 
47077
47328
  // src/proxy/nudge-state.ts
47078
- import { existsSync as existsSync24, mkdirSync as mkdirSync15, readFileSync as readFileSync20, writeFileSync as writeFileSync12 } from "fs";
47329
+ import { existsSync as existsSync24, mkdirSync as mkdirSync15, readFileSync as readFileSync21, writeFileSync as writeFileSync12 } from "fs";
47079
47330
  import { join as join24 } from "path";
47080
47331
  function defaultState() {
47081
47332
  return {
@@ -47093,7 +47344,7 @@ function readNudgeState(cwd) {
47093
47344
  try {
47094
47345
  const path7 = statePath(cwd);
47095
47346
  if (!existsSync24(path7)) return defaultState();
47096
- const raw = readFileSync20(path7, "utf8");
47347
+ const raw = readFileSync21(path7, "utf8");
47097
47348
  const parsed = JSON.parse(raw);
47098
47349
  return {
47099
47350
  tier0_emitted: Boolean(parsed.tier0_emitted),
@@ -47124,7 +47375,7 @@ function updateNudgeState(cwd, mutator) {
47124
47375
 
47125
47376
  // src/proxy/shell-compressor.ts
47126
47377
  init_token_flow();
47127
- import { readFileSync as readFileSync23 } from "fs";
47378
+ import { readFileSync as readFileSync24 } from "fs";
47128
47379
 
47129
47380
  // src/proxy/shell-classifier.ts
47130
47381
  var COMMAND_HINTS = {
@@ -48469,7 +48720,7 @@ async function tryLoadGraphForShellBoost(cwd) {
48469
48720
  if (cached && Date.now() - cached.loadedAt < BOOST_TTL_MS) {
48470
48721
  return cached.kind === "ok" ? cached.graph : null;
48471
48722
  }
48472
- const { existsSync: existsSync80, readFileSync: readFileSync67 } = await import("fs");
48723
+ const { existsSync: existsSync80, readFileSync: readFileSync68 } = await import("fs");
48473
48724
  const { join: join81 } = await import("path");
48474
48725
  const snapshotsDir = join81(cwd, ".unerr", "snapshots");
48475
48726
  let snapshotPath2 = join81(snapshotsDir, "graph.msgpack.gz");
@@ -48501,7 +48752,7 @@ async function tryLoadGraphForShellBoost(cwd) {
48501
48752
  let buffer;
48502
48753
  try {
48503
48754
  const { gunzipSync: gunzipSync3 } = await import("zlib");
48504
- const raw = readFileSync67(snapshotPath2);
48755
+ const raw = readFileSync68(snapshotPath2);
48505
48756
  try {
48506
48757
  buffer = gunzipSync3(raw);
48507
48758
  } catch {
@@ -48584,8 +48835,7 @@ function parseAwsEc2(raw) {
48584
48835
  );
48585
48836
  }
48586
48837
  }
48587
- if (count === 0) return `_shell_fmt:cloud[aws-ec2]
48588
- 0 instances`;
48838
+ if (count === 0) return "_shell_fmt:cloud[aws-ec2]\n0 instances";
48589
48839
  return `_shell_fmt:cloud[aws-ec2]
48590
48840
  ${fmtCount(count, "instance")}
48591
48841
  id state type ip az name
@@ -48970,7 +49220,7 @@ function compressEslintErrors(lines) {
48970
49220
  existing.count++;
48971
49221
  } else {
48972
49222
  ruleGroups.set(rule, {
48973
- message: message.trim(),
49223
+ message: message?.trim() ?? "",
48974
49224
  count: 1,
48975
49225
  firstFile: currentFile,
48976
49226
  firstLine: lineNum
@@ -49208,7 +49458,9 @@ function compressPythonErrors(lines) {
49208
49458
  const diagGroups = /* @__PURE__ */ new Map();
49209
49459
  let diagCount = 0;
49210
49460
  for (const line of lines) {
49211
- let code = "", message = "", filePath = "";
49461
+ let code = "";
49462
+ let message = "";
49463
+ let filePath = "";
49212
49464
  const mp = MYPY_RE.exec(line);
49213
49465
  if (mp) {
49214
49466
  filePath = mp[1] ?? "";
@@ -49297,7 +49549,8 @@ function compressPythonErrors(lines) {
49297
49549
  }
49298
49550
  const seen = /* @__PURE__ */ new Map();
49299
49551
  for (const tb of tracebacks) {
49300
- const fingerprint2 = tb.frames.join("\n") + "\n" + tb.error;
49552
+ const fingerprint2 = `${tb.frames.join("\n")}
49553
+ ${tb.error}`;
49301
49554
  const prev = seen.get(fingerprint2) ?? 0;
49302
49555
  seen.set(fingerprint2, prev + 1);
49303
49556
  if (prev === 0) {
@@ -49431,7 +49684,7 @@ function compressLineDiagnostics(lines) {
49431
49684
  continue;
49432
49685
  }
49433
49686
  const [, filePath, , , severity, message] = m;
49434
- const normMsg = message.trim().replace(/`[^`]+`/g, "`<id>`").replace(/'\S+'/, "'<id>'");
49687
+ const normMsg = message?.trim().replace(/`[^`]+`/g, "`<id>`").replace(/'\S+'/, "'<id>'");
49435
49688
  const key = `${severity ?? "warning"}:${normMsg}`;
49436
49689
  const existing = groups.get(key);
49437
49690
  if (existing) {
@@ -49439,7 +49692,7 @@ function compressLineDiagnostics(lines) {
49439
49692
  existing.files.add(filePath);
49440
49693
  } else {
49441
49694
  groups.set(key, {
49442
- message: message.trim(),
49695
+ message: message?.trim() ?? "",
49443
49696
  severity: severity ?? "warning",
49444
49697
  count: 1,
49445
49698
  files: /* @__PURE__ */ new Set([filePath]),
@@ -49564,7 +49817,7 @@ function compressErrorDiagnostic(raw, command) {
49564
49817
  }
49565
49818
 
49566
49819
  // src/proxy/shell-strategies/filter-dsl.ts
49567
- import { existsSync as existsSync26, readFileSync as readFileSync22 } from "fs";
49820
+ import { existsSync as existsSync26, readFileSync as readFileSync23 } from "fs";
49568
49821
  import { homedir as homedir12 } from "os";
49569
49822
  import { join as join28 } from "path";
49570
49823
  var cachedFilters = null;
@@ -49572,7 +49825,7 @@ var cacheKey = "";
49572
49825
  function readFile(path7) {
49573
49826
  try {
49574
49827
  if (!existsSync26(path7)) return null;
49575
- return readFileSync22(path7, "utf8");
49828
+ return readFileSync23(path7, "utf8");
49576
49829
  } catch {
49577
49830
  return null;
49578
49831
  }
@@ -49635,7 +49888,7 @@ function parseToml(src) {
49635
49888
  for (const rawLine of src.split("\n")) {
49636
49889
  const line = rawLine.replace(/#.*$/, "");
49637
49890
  if (depth > 0) {
49638
- buf += " " + line.trim();
49891
+ buf += ` ${line.trim()}`;
49639
49892
  } else if (line.includes("[") && !line.match(/^\s*\[[^=]*\]\s*$/)) {
49640
49893
  buf = line;
49641
49894
  } else {
@@ -49797,10 +50050,10 @@ ${sc.message}`,
49797
50050
  }
49798
50051
  let lines = text2.split("\n");
49799
50052
  if (filter.strip) {
49800
- lines = lines.filter((l) => !filter.strip.some((r) => r.test(l)));
50053
+ lines = lines.filter((l) => !filter.strip?.some((r) => r.test(l)));
49801
50054
  }
49802
50055
  if (filter.keep) {
49803
- lines = lines.filter((l) => filter.keep.some((r) => r.test(l)));
50056
+ lines = lines.filter((l) => filter.keep?.some((r) => r.test(l)));
49804
50057
  }
49805
50058
  if (filter.raw.truncate_lines_at) {
49806
50059
  const limit = filter.raw.truncate_lines_at;
@@ -49846,7 +50099,7 @@ function extOf(path7) {
49846
50099
  }
49847
50100
  function dirOf(path7) {
49848
50101
  const i = path7.lastIndexOf("/");
49849
- return i >= 0 ? path7.slice(0, i) + "/" : "./";
50102
+ return i >= 0 ? `${path7.slice(0, i)}/` : "./";
49850
50103
  }
49851
50104
  function topExt(byExt, k = 3) {
49852
50105
  const sorted = [...byExt.entries()].sort((a, b) => b[1] - a[1]);
@@ -49912,15 +50165,19 @@ function compressGitStatus(raw) {
49912
50165
  } else {
49913
50166
  buckets[currentBucket].files.push(stripped);
49914
50167
  }
49915
- continue;
49916
50168
  }
49917
50169
  }
49918
50170
  const totalFiles = buckets.staged.files.length + buckets.modified.files.length + buckets.untracked.files.length + buckets.unmerged.files.length;
49919
50171
  if (totalFiles === 0 && !branch) return null;
49920
- const out = [`_shell_fmt:git_status`];
50172
+ const out = ["_shell_fmt:git_status"];
49921
50173
  const branchLine = branch ? tracking ? `branch=${branch}; ${tracking}` : `branch=${branch}` : "";
49922
50174
  if (branchLine) out.push(branchLine);
49923
- const sectionOrder = ["staged", "modified", "untracked", "unmerged"];
50175
+ const sectionOrder = [
50176
+ "staged",
50177
+ "modified",
50178
+ "untracked",
50179
+ "unmerged"
50180
+ ];
49924
50181
  for (const bucket of sectionOrder) {
49925
50182
  const b = buckets[bucket];
49926
50183
  if (b.files.length === 0) continue;
@@ -49941,7 +50198,9 @@ function compressGitStatus(raw) {
49941
50198
  const ext = extOf(f);
49942
50199
  agg.byExt.set(ext, (agg.byExt.get(ext) ?? 0) + 1);
49943
50200
  }
49944
- const sortedDirs = [...byDir.entries()].sort((a, b2) => b2[1].total - a[1].total);
50201
+ const sortedDirs = [...byDir.entries()].sort(
50202
+ (a, b2) => b2[1].total - a[1].total
50203
+ );
49945
50204
  for (const [dir, agg] of sortedDirs.slice(0, 8)) {
49946
50205
  out.push(` ${dir} (${agg.total}: ${topExt(agg.byExt)})`);
49947
50206
  }
@@ -50038,8 +50297,8 @@ function compressColonFormat(lines) {
50038
50297
  continue;
50039
50298
  }
50040
50299
  const [, indent, key, value] = colonMatch;
50041
- const keyTrimmed = key.trim();
50042
- if (DROP_COLON_KEYS.has(keyTrimmed)) {
50300
+ const keyTrimmed = key?.trim();
50301
+ if (keyTrimmed && DROP_COLON_KEYS.has(keyTrimmed)) {
50043
50302
  i++;
50044
50303
  const childIndent2 = (indent?.length ?? 0) + 2;
50045
50304
  while (i < lines.length) {
@@ -50193,7 +50452,7 @@ ${label} \u2014 ${probe.line ?? "succeeded"} (${total} lines suppressed)`;
50193
50452
  patterns.set(normalized, { firstLine: line, count: 1 });
50194
50453
  }
50195
50454
  }
50196
- const parts = [`_shell_fmt:log_text`];
50455
+ const parts = ["_shell_fmt:log_text"];
50197
50456
  parts.push(`(${total} lines, ${patterns.size} unique patterns)`);
50198
50457
  if (errorLines.length > 0) {
50199
50458
  const errDedup = /* @__PURE__ */ new Map();
@@ -50367,7 +50626,7 @@ function compressOmni(raw) {
50367
50626
  const joined = truncated.join("\n");
50368
50627
  const capped = capChars(joined);
50369
50628
  const savedLines = originalCount - truncated.length;
50370
- const header = savedLines > 5 ? `_shell_fmt:omni (${originalCount}\u2192${truncated.length} lines)` : `_shell_fmt:omni`;
50629
+ const header = savedLines > 5 ? `_shell_fmt:omni (${originalCount}\u2192${truncated.length} lines)` : "_shell_fmt:omni";
50371
50630
  return `${header}
50372
50631
  ${capped}`;
50373
50632
  }
@@ -50548,9 +50807,9 @@ function compressRepeatedValueLines(lines, marker) {
50548
50807
  const out = [];
50549
50808
  let i = 0;
50550
50809
  while (i < lines.length) {
50551
- if (lines[i].includes(marker)) {
50810
+ if (lines[i]?.includes(marker)) {
50552
50811
  const runStart = i;
50553
- while (i < lines.length && lines[i].includes(marker)) i++;
50812
+ while (i < lines.length && lines[i]?.includes(marker)) i++;
50554
50813
  const runLen = i - runStart;
50555
50814
  if (runLen >= 3) {
50556
50815
  out.push(lines[runStart]);
@@ -50779,8 +51038,8 @@ function compressTabularInner(text2, command) {
50779
51038
  const profile = command ? matchColumnProfile(command) : null;
50780
51039
  const useLastColRest = command ? isLastColRestCommand(command) : false;
50781
51040
  if (useLastColRest && lines.length >= 2) {
50782
- const headerTokens = lines[0].trim().split(/\s+/).filter(Boolean);
50783
- if (headerTokens.length >= 2) {
51041
+ const headerTokens = lines[0]?.trim().split(/\s+/).filter(Boolean);
51042
+ if (headerTokens && headerTokens.length >= 2) {
50784
51043
  const numCols = headerTokens.length;
50785
51044
  const dataRows = lines.slice(1);
50786
51045
  let keepIndices;
@@ -50790,9 +51049,10 @@ function compressTabularInner(text2, command) {
50790
51049
  keepIndices = [];
50791
51050
  keepNames = [];
50792
51051
  for (let i = 0; i < headerTokens.length; i++) {
50793
- if (keepSet.has(headerTokens[i].toUpperCase())) {
51052
+ const tok = headerTokens[i];
51053
+ if (tok && keepSet.has(tok.toUpperCase())) {
50794
51054
  keepIndices.push(i);
50795
- keepNames.push(headerTokens[i]);
51055
+ keepNames.push(tok);
50796
51056
  }
50797
51057
  }
50798
51058
  if (keepIndices.length < 2) {
@@ -51075,7 +51335,6 @@ function parsePytest(lines) {
51075
51335
  }
51076
51336
  if (/^FAILED\s/.test(line)) {
51077
51337
  summaryLines.push(line.trim());
51078
- continue;
51079
51338
  }
51080
51339
  }
51081
51340
  if (currentFail) failures.push(currentFail);
@@ -51231,7 +51490,6 @@ function parseRspec(lines) {
51231
51490
  } else {
51232
51491
  currentFail.lines.push(line);
51233
51492
  }
51234
- continue;
51235
51493
  }
51236
51494
  }
51237
51495
  if (currentFail) failures.push(currentFail);
@@ -51668,7 +51926,7 @@ function compressTreePaths(raw, _maxDepth, command) {
51668
51926
  if (parentBucket) parentBucket.subdirs.add(dir);
51669
51927
  }
51670
51928
  const sortedDirs = [...buckets.keys()].sort();
51671
- const out = [`_shell_fmt:tree_paths`];
51929
+ const out = ["_shell_fmt:tree_paths"];
51672
51930
  out.push(
51673
51931
  `(${paths.length} paths across ${sortedDirs.length} dirs; rolled up)`
51674
51932
  );
@@ -51708,13 +51966,13 @@ var VALUE_MAX2 = 200;
51708
51966
  function detectIndentUnit(lines) {
51709
51967
  for (const line of lines) {
51710
51968
  const m = /^( +)\S/.exec(line);
51711
- if (m) return m[1].length;
51969
+ if (m) return m[1]?.length ?? 0;
51712
51970
  }
51713
51971
  return 2;
51714
51972
  }
51715
51973
  function indentOf(line) {
51716
51974
  const m = /^( *)/.exec(line);
51717
- return m ? m[1].length : 0;
51975
+ return m ? m[1]?.length ?? 0 : 0;
51718
51976
  }
51719
51977
  function compressYaml(raw, command) {
51720
51978
  void command;
@@ -51769,7 +52027,7 @@ function compressYaml(raw, command) {
51769
52027
  let preview = 0;
51770
52028
  let k = i + 1;
51771
52029
  while (k < j && preview < 3) {
51772
- if (lines[k].trim()) {
52030
+ if (lines[k]?.trim()) {
51773
52031
  kept.push(lines[k]);
51774
52032
  preview++;
51775
52033
  }
@@ -51870,12 +52128,12 @@ function teeShellOutput(cwd, command, raw, compressed) {
51870
52128
  const filename = `${ts}-${slug}.txt`;
51871
52129
  const filePath = join29(teeDir, filename);
51872
52130
  const header = [
51873
- `# unerr tee \u2014 full shell output`,
52131
+ "# unerr tee \u2014 full shell output",
51874
52132
  `# command: ${command}`,
51875
52133
  `# captured: ${new Date(ts).toISOString()}`,
51876
52134
  `# raw_bytes: ${raw.length} compressed_bytes: ${compressed.length} ratio: ${(ratio * 100).toFixed(1)}%`,
51877
- `# ---`,
51878
- ``
52135
+ "# ---",
52136
+ ""
51879
52137
  ].join("\n");
51880
52138
  const content = header + raw;
51881
52139
  try {
@@ -52286,7 +52544,7 @@ function recordShellTokenFlow(cwd, command, category, raw, compressed, strategy)
52286
52544
  const unerrDir = `${cwd}/.unerr`;
52287
52545
  if (!sessionId) {
52288
52546
  try {
52289
- sessionId = readFileSync23(
52547
+ sessionId = readFileSync24(
52290
52548
  `${unerrDir}/state/session.id`,
52291
52549
  "utf-8"
52292
52550
  ).trim();
@@ -52417,8 +52675,7 @@ async function runExecMain(argv) {
52417
52675
  `
52418
52676
  );
52419
52677
  process.stderr.write(
52420
- `[unerr:exec] \u2191 this error is from the command itself, not unerr
52421
- `
52678
+ "[unerr:exec] \u2191 this error is from the command itself, not unerr\n"
52422
52679
  );
52423
52680
  process.stdout.write(combined);
52424
52681
  if (combined.length > 0 && !combined.endsWith("\n"))
@@ -52485,7 +52742,7 @@ function registerExecCommand(program2) {
52485
52742
  }
52486
52743
 
52487
52744
  // src/commands/gain.ts
52488
- import { existsSync as existsSync27, readFileSync as readFileSync24 } from "fs";
52745
+ import { existsSync as existsSync27, readFileSync as readFileSync25 } from "fs";
52489
52746
  import { join as join30 } from "path";
52490
52747
  var PALETTE = {
52491
52748
  reset: "\x1B[0m",
@@ -52500,7 +52757,7 @@ var PALETTE = {
52500
52757
  function loadFlow(cwd) {
52501
52758
  const path7 = join30(cwd, ".unerr", "token-flow.jsonl");
52502
52759
  if (!existsSync27(path7)) return [];
52503
- const raw = readFileSync24(path7, "utf8");
52760
+ const raw = readFileSync25(path7, "utf8");
52504
52761
  const events = [];
52505
52762
  for (const line of raw.split("\n")) {
52506
52763
  if (!line.trim()) continue;
@@ -52624,18 +52881,18 @@ function registerDiscoverCommand(program2) {
52624
52881
  }
52625
52882
 
52626
52883
  // src/commands/hook.ts
52627
- import { readFileSync as readFileSync26 } from "fs";
52884
+ import { readFileSync as readFileSync27 } from "fs";
52628
52885
 
52629
52886
  // src/hooks/hook-dedup.ts
52630
- import { existsSync as existsSync28, mkdirSync as mkdirSync19, readFileSync as readFileSync25, writeFileSync as writeFileSync15 } from "fs";
52631
- import { dirname as dirname7, join as join31 } from "path";
52887
+ import { existsSync as existsSync28, mkdirSync as mkdirSync19, readFileSync as readFileSync26, writeFileSync as writeFileSync15 } from "fs";
52888
+ import { dirname as dirname10, join as join31 } from "path";
52632
52889
  var STATE_FILE = join31(".unerr", "state", "hook-recent.json");
52633
52890
  var DEFAULT_TTL_MS = 3e4;
52634
52891
  var PRUNE_FACTOR = 10;
52635
52892
  function readMap(file) {
52636
52893
  try {
52637
52894
  if (!existsSync28(file)) return {};
52638
- const raw = readFileSync25(file, "utf8");
52895
+ const raw = readFileSync26(file, "utf8");
52639
52896
  const obj = JSON.parse(raw);
52640
52897
  if (obj && typeof obj === "object") return obj;
52641
52898
  } catch {
@@ -52644,7 +52901,7 @@ function readMap(file) {
52644
52901
  }
52645
52902
  function writeMap(file, map) {
52646
52903
  try {
52647
- const dir = dirname7(file);
52904
+ const dir = dirname10(file);
52648
52905
  if (!existsSync28(dir)) mkdirSync19(dir, { recursive: true });
52649
52906
  writeFileSync15(file, JSON.stringify(map));
52650
52907
  } catch {
@@ -52779,7 +53036,7 @@ var clineAdapter = {
52779
53036
  if (result.type === "rewrite" && result.updatedInput) {
52780
53037
  return JSON.stringify({
52781
53038
  allow: true,
52782
- context: `Suggested rewrite: use unerr exec for this command.`
53039
+ context: "Suggested rewrite: use unerr exec for this command."
52783
53040
  });
52784
53041
  }
52785
53042
  return JSON.stringify({ allow: true });
@@ -52977,11 +53234,11 @@ Text grep matches comments, strings, and unrelated code. Graph tools are precise
52977
53234
  }
52978
53235
  if (looksLikeImportSearch) {
52979
53236
  return nudge(
52980
- `STOP: Use \`get_imports\` instead of Grep for import/dependency tracing. It returns structured import maps in <5ms \u2014 more reliable than grepping for import statements.`
53237
+ "STOP: Use `get_imports` instead of Grep for import/dependency tracing. It returns structured import maps in <5ms \u2014 more reliable than grepping for import statements."
52981
53238
  );
52982
53239
  }
52983
53240
  return nudge(
52984
- `REQUIRED: This project has unerr graph tools indexed. Use \`search_code\` for code entity searches (faster, more accurate than Grep). Use \`get_references\` for finding callers.`
53241
+ "REQUIRED: This project has unerr graph tools indexed. Use `search_code` for code entity searches (faster, more accurate than Grep). Use `get_references` for finding callers."
52985
53242
  );
52986
53243
  };
52987
53244
  var preGlobHandler = (normalized) => {
@@ -53020,13 +53277,13 @@ var preEditHandler = (normalized) => {
53020
53277
  );
53021
53278
  if (hasSignatureChange) {
53022
53279
  return nudge(
53023
- readPrereq + `You're editing a function/class signature in "${filePath}". This may break callers.
53280
+ `${readPrereq}You're editing a function/class signature in "${filePath}". This may break callers.
53024
53281
  - \`get_references\` on the entity you're modifying \u2014 all callers must be updated to match
53025
53282
  - \`get_test_coverage\` on the entity \u2014 verify which tests cover it`
53026
53283
  );
53027
53284
  }
53028
53285
  return nudge(
53029
- readPrereq + `Before editing "${filePath}":
53286
+ `${readPrereq}Before editing "${filePath}":
53030
53287
  - \`get_references\` on any entity you're changing \u2014 ensure callers won't break`
53031
53288
  );
53032
53289
  };
@@ -53038,11 +53295,11 @@ var postReadHandler = (normalized) => {
53038
53295
  const isClaudeCode = normalized.agentName === "claude-code";
53039
53296
  if (isClaudeCode) {
53040
53297
  return enrich(
53041
- `ur|hnt Edit needs built-in Read first; for understanding use \`file_read\` (auto-injects facts/drift).`
53298
+ "ur|hnt Edit needs built-in Read first; for understanding use `file_read` (auto-injects facts/drift)."
53042
53299
  );
53043
53300
  }
53044
53301
  return enrich(
53045
- `ur|hnt Prefer \`file_read\` over built-in Read \u2014 it auto-injects conventions, facts, drift.`
53302
+ "ur|hnt Prefer `file_read` over built-in Read \u2014 it auto-injects conventions, facts, drift."
53046
53303
  );
53047
53304
  };
53048
53305
  var postGrepHandler = (normalized) => {
@@ -53059,9 +53316,7 @@ var postGrepHandler = (normalized) => {
53059
53316
  );
53060
53317
  }
53061
53318
  return enrich(
53062
- `You just grepped for a pattern. For structured code navigation, unerr graph tools are faster and more accurate:
53063
- - \`search_code\` for entity-level search (functions, classes, types)
53064
- - \`get_references\` for reference tracing (no false positives)`
53319
+ "You just grepped for a pattern. For structured code navigation, unerr graph tools are faster and more accurate:\n- `search_code` for entity-level search (functions, classes, types)\n- `get_references` for reference tracing (no false positives)"
53065
53320
  );
53066
53321
  };
53067
53322
  var postGlobHandler = () => {
@@ -53174,7 +53429,7 @@ function runPreBashHook(stdinJson) {
53174
53429
  function safeHookAction(handler) {
53175
53430
  return () => {
53176
53431
  try {
53177
- const stdin = readFileSync26(0, "utf-8");
53432
+ const stdin = readFileSync27(0, "utf-8");
53178
53433
  process.stdout.write(handler(stdin));
53179
53434
  } catch (e) {
53180
53435
  process.stderr.write(`[unerr] hook error: ${e}
@@ -53370,14 +53625,14 @@ import {
53370
53625
  chmodSync as chmodSync4,
53371
53626
  existsSync as existsSync40,
53372
53627
  mkdirSync as mkdirSync28,
53373
- readFileSync as readFileSync34,
53628
+ readFileSync as readFileSync35,
53374
53629
  writeFileSync as writeFileSync22
53375
53630
  } from "fs";
53376
53631
  import { join as join44 } from "path";
53377
53632
 
53378
53633
  // src/config/claude-settings-hooks.ts
53379
53634
  import { execSync as execSync6 } from "child_process";
53380
- import { existsSync as existsSync37, mkdirSync as mkdirSync25, readFileSync as readFileSync31, writeFileSync as writeFileSync19 } from "fs";
53635
+ import { existsSync as existsSync37, mkdirSync as mkdirSync25, readFileSync as readFileSync32, writeFileSync as writeFileSync19 } from "fs";
53381
53636
  import { join as join41 } from "path";
53382
53637
  function resolveUnerrBinary() {
53383
53638
  const entryScript = process.argv[1];
@@ -53451,7 +53706,7 @@ function mergePreToolUseBashHook(cwd) {
53451
53706
  let settings = {};
53452
53707
  if (existsSync37(settingsPath)) {
53453
53708
  try {
53454
- settings = JSON.parse(readFileSync31(settingsPath, "utf-8"));
53709
+ settings = JSON.parse(readFileSync32(settingsPath, "utf-8"));
53455
53710
  } catch {
53456
53711
  settings = {};
53457
53712
  }
@@ -53516,7 +53771,7 @@ function addDisallowedTools(cwd) {
53516
53771
  let settings = {};
53517
53772
  if (existsSync37(settingsPath)) {
53518
53773
  try {
53519
- settings = JSON.parse(readFileSync31(settingsPath, "utf-8"));
53774
+ settings = JSON.parse(readFileSync32(settingsPath, "utf-8"));
53520
53775
  } catch {
53521
53776
  settings = {};
53522
53777
  }
@@ -53554,7 +53809,7 @@ function removeDisallowedTools(cwd) {
53554
53809
  const settingsPath = join41(cwd, ".claude", "settings.json");
53555
53810
  if (!existsSync37(settingsPath)) return false;
53556
53811
  try {
53557
- const settings = JSON.parse(readFileSync31(settingsPath, "utf-8"));
53812
+ const settings = JSON.parse(readFileSync32(settingsPath, "utf-8"));
53558
53813
  const permissions = settings.permissions;
53559
53814
  if (!permissions || !Array.isArray(permissions.deny)) return false;
53560
53815
  const before = permissions.deny.length;
@@ -53563,8 +53818,9 @@ function removeDisallowedTools(cwd) {
53563
53818
  );
53564
53819
  const removed = before - permissions.deny.length;
53565
53820
  if (removed === 0) return false;
53566
- if (permissions.deny.length === 0) delete permissions.deny;
53567
- if (Object.keys(permissions).length === 0) delete settings.permissions;
53821
+ if (permissions.deny.length === 0)
53822
+ permissions.deny = void 0;
53823
+ if (Object.keys(permissions).length === 0) settings.permissions = void 0;
53568
53824
  writeFileSync19(
53569
53825
  settingsPath,
53570
53826
  `${JSON.stringify(settings, null, 2)}
@@ -53580,7 +53836,7 @@ function removePreToolUseBashHook(cwd) {
53580
53836
  const settingsPath = join41(cwd, ".claude", "settings.json");
53581
53837
  if (!existsSync37(settingsPath)) return false;
53582
53838
  try {
53583
- const settings = JSON.parse(readFileSync31(settingsPath, "utf-8"));
53839
+ const settings = JSON.parse(readFileSync32(settingsPath, "utf-8"));
53584
53840
  const hooks = settings.hooks;
53585
53841
  if (!hooks) return false;
53586
53842
  let totalRemoved = 0;
@@ -53600,7 +53856,7 @@ function removePreToolUseBashHook(cwd) {
53600
53856
  if (hooks[eventType].length === 0) delete hooks[eventType];
53601
53857
  }
53602
53858
  if (totalRemoved === 0) return false;
53603
- if (Object.keys(hooks).length === 0) delete settings.hooks;
53859
+ if (Object.keys(hooks).length === 0) settings.hooks = void 0;
53604
53860
  writeFileSync19(
53605
53861
  settingsPath,
53606
53862
  `${JSON.stringify(settings, null, 2)}
@@ -53621,16 +53877,16 @@ init_agent_registry();
53621
53877
  import {
53622
53878
  existsSync as existsSync38,
53623
53879
  mkdirSync as mkdirSync26,
53624
- readFileSync as readFileSync32,
53880
+ readFileSync as readFileSync33,
53625
53881
  unlinkSync as unlinkSync9,
53626
53882
  writeFileSync as writeFileSync20
53627
53883
  } from "fs";
53628
- import { dirname as dirname9, join as join42 } from "path";
53884
+ import { dirname as dirname12, join as join42 } from "path";
53629
53885
  var SENTINEL_START = "<!-- unerr:start -->";
53630
53886
  var SENTINEL_END = "<!-- unerr:end -->";
53631
53887
  function getInstructionContent(ide) {
53632
53888
  const isClaudeCode = ide === "claude-code";
53633
- const readForEditRow = isClaudeCode ? `| Understand a file before editing | \`file_read\` with \`purpose:'explore'\` to understand, then built-in \`Read\` (offset/limit) on target lines before Edit | Reading entire file |` : `| Read a file before editing | \`file_read\` with \`entity\` param or offset/limit for targeted access | Reading entire file |`;
53889
+ const readForEditRow = isClaudeCode ? `| Understand a file before editing | \`file_read\` with \`purpose:'explore'\` to understand, then built-in \`Read\` (offset/limit) on target lines before Edit | Reading entire file |` : "| Read a file before editing | `file_read` with `entity` param or offset/limit for targeted access | Reading entire file |";
53634
53890
  const twoStepSection = isClaudeCode ? `
53635
53891
  ### IMPORTANT: Two-step Read Routing (Claude Code specific)
53636
53892
 
@@ -53646,9 +53902,7 @@ function getInstructionContent(ide) {
53646
53902
  When your next action is Edit, use built-in Read with offset/limit on the target lines. For everything else, use \`file_read\`.
53647
53903
 
53648
53904
  **Common failure mode:** Using \`file_read\` to understand a file, then attempting Edit without calling built-in Read first. The Edit tool WILL reject with "File has not been read yet". Always call built-in Read (with offset/limit) immediately before Edit.` : "";
53649
- const summaryEditNote = isClaudeCode ? `
53650
- NEVER use built-in Read/Grep/Glob for code navigation. EXCEPTION: built-in Read (with offset/limit) is REQUIRED immediately before Edit (file_read cannot substitute \u2014 Edit will fail without it).` : `
53651
- NEVER use built-in Read/Grep/Glob for code navigation \u2014 use unerr MCP tools instead.`;
53905
+ const summaryEditNote = isClaudeCode ? "\nNEVER use built-in Read/Grep/Glob for code navigation. EXCEPTION: built-in Read (with offset/limit) is REQUIRED immediately before Edit (file_read cannot substitute \u2014 Edit will fail without it)." : "\nNEVER use built-in Read/Grep/Glob for code navigation \u2014 use unerr MCP tools instead.";
53652
53906
  return `## REQUIRED: Use unerr Graph Intelligence Tools (22 MCP tools)
53653
53907
 
53654
53908
  This project has unerr MCP tools installed. You MUST use these instead of built-in Read/Grep/Glob for code navigation. unerr tools are graph-backed, return results in <5ms, and include project context that built-in tools miss.
@@ -53817,7 +54071,7 @@ function writeInstructionFile(cwd, ide) {
53817
54071
  return writeMdcInstructionFile(filePath);
53818
54072
  }
53819
54073
  if (agentDef.instructionFormat === "windsurf-rule") {
53820
- mkdirSync26(dirname9(filePath), { recursive: true });
54074
+ mkdirSync26(dirname12(filePath), { recursive: true });
53821
54075
  const content = getInstructionContent(ide);
53822
54076
  const truncatedContent = content.length > 5800 ? `${content.slice(0, 5800)}
53823
54077
 
@@ -53831,7 +54085,7 @@ ${truncatedContent}
53831
54085
  `;
53832
54086
  const existed = existsSync38(filePath);
53833
54087
  if (existed) {
53834
- const existing = readFileSync32(filePath, "utf-8");
54088
+ const existing = readFileSync33(filePath, "utf-8");
53835
54089
  if (existing === windsurfContent) {
53836
54090
  return { path: filePath, action: "skipped" };
53837
54091
  }
@@ -53840,7 +54094,7 @@ ${truncatedContent}
53840
54094
  return { path: filePath, action: existed ? "updated" : "created" };
53841
54095
  }
53842
54096
  if (agentDef.instructionFormat === "antigravity-rule") {
53843
- mkdirSync26(dirname9(filePath), { recursive: true });
54097
+ mkdirSync26(dirname12(filePath), { recursive: true });
53844
54098
  const content = getInstructionContent(ide);
53845
54099
  const antigravityContent = `---
53846
54100
  name: unerr-instructions
@@ -53852,7 +54106,7 @@ ${content}
53852
54106
  `;
53853
54107
  const existed = existsSync38(filePath);
53854
54108
  if (existed) {
53855
- const existing = readFileSync32(filePath, "utf-8");
54109
+ const existing = readFileSync33(filePath, "utf-8");
53856
54110
  if (existing === antigravityContent) {
53857
54111
  return { path: filePath, action: "skipped" };
53858
54112
  }
@@ -53867,13 +54121,13 @@ function mergeMarkdownSection(filePath, content) {
53867
54121
  ${content}
53868
54122
  ${SENTINEL_END}`;
53869
54123
  if (!existsSync38(filePath)) {
53870
- const dir = dirname9(filePath);
54124
+ const dir = dirname12(filePath);
53871
54125
  if (!existsSync38(dir)) mkdirSync26(dir, { recursive: true });
53872
54126
  writeFileSync20(filePath, `${wrappedContent}
53873
54127
  `);
53874
54128
  return { path: filePath, action: "created" };
53875
54129
  }
53876
- const existing = readFileSync32(filePath, "utf-8");
54130
+ const existing = readFileSync33(filePath, "utf-8");
53877
54131
  const startIdx = existing.indexOf(SENTINEL_START);
53878
54132
  const endIdx = existing.indexOf(SENTINEL_END);
53879
54133
  if (startIdx === -1 || endIdx === -1) {
@@ -53895,12 +54149,12 @@ function writeMdcInstructionFile(filePath) {
53895
54149
  const content = getMdcContent();
53896
54150
  const alreadyExists = existsSync38(filePath);
53897
54151
  if (alreadyExists) {
53898
- const existing = readFileSync32(filePath, "utf-8");
54152
+ const existing = readFileSync33(filePath, "utf-8");
53899
54153
  if (existing === content) {
53900
54154
  return { path: filePath, action: "skipped" };
53901
54155
  }
53902
54156
  }
53903
- const dir = dirname9(filePath);
54157
+ const dir = dirname12(filePath);
53904
54158
  if (!existsSync38(dir)) mkdirSync26(dir, { recursive: true });
53905
54159
  writeFileSync20(filePath, content);
53906
54160
  return {
@@ -53931,13 +54185,14 @@ function removeInstructionSection(cwd, ide) {
53931
54185
  }
53932
54186
  return false;
53933
54187
  }
53934
- const content = readFileSync32(filePath, "utf-8");
54188
+ const content = readFileSync33(filePath, "utf-8");
53935
54189
  const startIdx = content.indexOf(SENTINEL_START);
53936
54190
  const endIdx = content.indexOf(SENTINEL_END);
53937
54191
  if (startIdx === -1 || endIdx === -1) return false;
53938
54192
  const before = content.slice(0, startIdx);
53939
54193
  const after = content.slice(endIdx + SENTINEL_END.length);
53940
- const cleaned = (before + after).replace(/\n{3,}/g, "\n\n").trimEnd() + "\n";
54194
+ const cleaned = `${(before + after).replace(/\n{3,}/g, "\n\n").trimEnd()}
54195
+ `;
53941
54196
  const trimmed = cleaned.replace(/\s/g, "");
53942
54197
  if (trimmed.length === 0) {
53943
54198
  unlinkSync9(filePath);
@@ -54037,14 +54292,12 @@ function registerInstallCommand(program2) {
54037
54292
  }
54038
54293
  if (result.hookInstalled) {
54039
54294
  process.stderr.write(
54040
- ` \x1B[38;2;52;211;153m\u2713\x1B[0m PreToolUse hook installed (graph-first navigation)
54041
- `
54295
+ " \x1B[38;2;52;211;153m\u2713\x1B[0m PreToolUse hook installed (graph-first navigation)\n"
54042
54296
  );
54043
54297
  }
54044
54298
  if (result.gitignoreUpdated) {
54045
54299
  process.stderr.write(
54046
- ` \x1B[38;2;52;211;153m\u2713\x1B[0m .unerr added to .gitignore
54047
- `
54300
+ " \x1B[38;2;52;211;153m\u2713\x1B[0m .unerr added to .gitignore\n"
54048
54301
  );
54049
54302
  }
54050
54303
  if (result.instructionsInjected) {
@@ -54055,14 +54308,12 @@ function registerInstallCommand(program2) {
54055
54308
  }
54056
54309
  if (result.toolsDenied > 0) {
54057
54310
  process.stderr.write(
54058
- ` \x1B[38;2;52;211;153m\u2713\x1B[0m Built-in Read/Grep/Glob denied (use --no-force-tools to keep)
54059
- `
54311
+ " \x1B[38;2;52;211;153m\u2713\x1B[0m Built-in Read/Grep/Glob denied (use --no-force-tools to keep)\n"
54060
54312
  );
54061
54313
  }
54062
54314
  process.stderr.write("\n");
54063
54315
  process.stderr.write(
54064
- ` \x1B[38;2;161;161;170mRun \x1B[0munerr\x1B[38;2;161;161;170m to start the intelligence engine.\x1B[0m
54065
- `
54316
+ " \x1B[38;2;161;161;170mRun \x1B[0munerr\x1B[38;2;161;161;170m to start the intelligence engine.\x1B[0m\n"
54066
54317
  );
54067
54318
  process.stderr.write("\n");
54068
54319
  }
@@ -54111,6 +54362,17 @@ async function runInstall(cwd, ide, opts) {
54111
54362
  } catch {
54112
54363
  }
54113
54364
  }
54365
+ try {
54366
+ const { autoInstallIfNeeded: autoInstallIfNeeded2 } = await Promise.resolve().then(() => (init_autostart(), autostart_exports));
54367
+ const autostartResult = await autoInstallIfNeeded2();
54368
+ if (autostartResult?.installed) {
54369
+ process.stderr.write(
54370
+ `\x1B[38;2;52;211;153m\u2713\x1B[0m Daemon auto-start registered: ${autostartResult.path}
54371
+ `
54372
+ );
54373
+ }
54374
+ } catch {
54375
+ }
54114
54376
  let repoRegistered = false;
54115
54377
  try {
54116
54378
  const { daemonSockPath: daemonSockPath2, probeDaemon: probeDaemon2, ensureRepo: ensureRepo2 } = await Promise.resolve().then(() => (init_client(), client_exports));
@@ -54407,7 +54669,7 @@ function installCursorHooks(cwd) {
54407
54669
  if (existsSync40(hooksJsonPath)) {
54408
54670
  try {
54409
54671
  const existing = JSON.parse(
54410
- readFileSync34(hooksJsonPath, "utf-8")
54672
+ readFileSync35(hooksJsonPath, "utf-8")
54411
54673
  );
54412
54674
  if (existing.version && existing.hooks) {
54413
54675
  config = existing;
@@ -54481,7 +54743,7 @@ function ensureGitignore(cwd) {
54481
54743
  const gitignorePath = join44(cwd, ".gitignore");
54482
54744
  if (!existsSync40(gitignorePath)) return false;
54483
54745
  try {
54484
- const content = readFileSync34(gitignorePath, "utf-8");
54746
+ const content = readFileSync35(gitignorePath, "utf-8");
54485
54747
  const lines = content.split("\n");
54486
54748
  if (lines.some((l) => l.trim() === ".unerr" || l.trim() === ".unerr/")) {
54487
54749
  return false;
@@ -54582,8 +54844,8 @@ async function persistPatterns(patterns, _unerrDir) {
54582
54844
  );
54583
54845
  return;
54584
54846
  }
54585
- const { readFileSync: readFileSync67 } = await import("fs");
54586
- const config = JSON.parse(readFileSync67(configPath, "utf-8"));
54847
+ const { readFileSync: readFileSync68 } = await import("fs");
54848
+ const config = JSON.parse(readFileSync68(configPath, "utf-8"));
54587
54849
  if (!config.repoId || !config.orgId) {
54588
54850
  warn("Repo not configured \u2014 cannot persist to CozoDB.");
54589
54851
  return;
@@ -54601,7 +54863,7 @@ async function persistPatterns(patterns, _unerrDir) {
54601
54863
  const { CozoGraphStore: CozoGraphStore2 } = await Promise.resolve().then(() => (init_local_graph(), local_graph_exports));
54602
54864
  const store = await CozoGraphStore2.create(db);
54603
54865
  const { unpack } = await import("msgpackr");
54604
- const raw = readFileSync67(snapshotPath2);
54866
+ const raw = readFileSync68(snapshotPath2);
54605
54867
  const buffer = gunzipSync2(raw);
54606
54868
  const envelope = unpack(buffer);
54607
54869
  await store.loadSnapshot(envelope);
@@ -54618,7 +54880,7 @@ async function persistPatterns(patterns, _unerrDir) {
54618
54880
 
54619
54881
  // src/commands/manifest.ts
54620
54882
  init_exec();
54621
- import { existsSync as existsSync43, readFileSync as readFileSync36 } from "fs";
54883
+ import { existsSync as existsSync43, readFileSync as readFileSync37 } from "fs";
54622
54884
  import { join as join46 } from "path";
54623
54885
  async function findRepoRoot() {
54624
54886
  return gitQuery(["rev-parse", "--show-toplevel"]);
@@ -54627,7 +54889,7 @@ function loadManifest(repoRoot) {
54627
54889
  const manifestPath = join46(repoRoot, ".unerr", "manifest.json");
54628
54890
  if (!existsSync43(manifestPath)) return null;
54629
54891
  try {
54630
- const raw = readFileSync36(manifestPath, "utf-8");
54892
+ const raw = readFileSync37(manifestPath, "utf-8");
54631
54893
  return JSON.parse(raw);
54632
54894
  } catch {
54633
54895
  return null;
@@ -54950,7 +55212,7 @@ function registerStatsCommand(program2) {
54950
55212
 
54951
55213
  // src/commands/status.ts
54952
55214
  init_git();
54953
- import { existsSync as existsSync48, readFileSync as readFileSync41 } from "fs";
55215
+ import { existsSync as existsSync48, readFileSync as readFileSync42 } from "fs";
54954
55216
  import { join as join52 } from "path";
54955
55217
  import React from "react";
54956
55218
  function buildSuggestions(data) {
@@ -55001,7 +55263,7 @@ function registerStatusCommand(program2) {
55001
55263
  const configPath = join52(unerrDir, "config.json");
55002
55264
  if (existsSync48(configPath)) {
55003
55265
  try {
55004
- const config = JSON.parse(readFileSync41(configPath, "utf-8"));
55266
+ const config = JSON.parse(readFileSync42(configPath, "utf-8"));
55005
55267
  repoId = config.repoId ?? "";
55006
55268
  } catch {
55007
55269
  }
@@ -55032,7 +55294,7 @@ function registerStatusCommand(program2) {
55032
55294
  const pidPath2 = join52(unerrDir, "state", "proxy.pid");
55033
55295
  if (existsSync48(pidPath2)) {
55034
55296
  try {
55035
- const pidStr = readFileSync41(pidPath2, "utf-8").trim();
55297
+ const pidStr = readFileSync42(pidPath2, "utf-8").trim();
55036
55298
  const pid = Number.parseInt(pidStr, 10);
55037
55299
  process.kill(pid, 0);
55038
55300
  proxyStatus = `Running (PID ${pid})`;
@@ -55046,7 +55308,7 @@ function registerStatusCommand(program2) {
55046
55308
  if (repoId && existsSync48(join52(manifestsDir, `${repoId}.json`))) {
55047
55309
  try {
55048
55310
  const manifest = JSON.parse(
55049
- readFileSync41(join52(manifestsDir, `${repoId}.json`), "utf-8")
55311
+ readFileSync42(join52(manifestsDir, `${repoId}.json`), "utf-8")
55050
55312
  );
55051
55313
  const entityCount = manifest.entityCount ?? 0;
55052
55314
  const edgeCount = manifest.edgeCount ?? 0;
@@ -55068,7 +55330,7 @@ function registerStatusCommand(program2) {
55068
55330
  if (existsSync48(driftSummaryPath)) {
55069
55331
  try {
55070
55332
  const summary = JSON.parse(
55071
- readFileSync41(driftSummaryPath, "utf-8")
55333
+ readFileSync42(driftSummaryPath, "utf-8")
55072
55334
  );
55073
55335
  drift = {
55074
55336
  modified: summary.modified ?? 0,
@@ -55083,7 +55345,7 @@ function registerStatusCommand(program2) {
55083
55345
  const graphVersionPath = join52(unerrDir, "state", "graph_version.json");
55084
55346
  if (existsSync48(graphVersionPath)) {
55085
55347
  try {
55086
- const gv = JSON.parse(readFileSync41(graphVersionPath, "utf-8"));
55348
+ const gv = JSON.parse(readFileSync42(graphVersionPath, "utf-8"));
55087
55349
  healthGrade = gv.health_grade;
55088
55350
  healthScore = gv.health_score;
55089
55351
  } catch {
@@ -55102,7 +55364,7 @@ function registerStatusCommand(program2) {
55102
55364
  const { unpack } = await import("msgpackr");
55103
55365
  const { default: CozoDbConstructor } = await import("cozo-node");
55104
55366
  const { CozoGraphStore: CozoGraphStore2 } = await Promise.resolve().then(() => (init_local_graph(), local_graph_exports));
55105
- const raw = readFileSync41(snapshotPath2);
55367
+ const raw = readFileSync42(snapshotPath2);
55106
55368
  let buffer;
55107
55369
  try {
55108
55370
  buffer = gunzipSync3(raw);
@@ -55123,7 +55385,7 @@ function registerStatusCommand(program2) {
55123
55385
  const statsPath = join52(unerrDir, "state", "session_stats.json");
55124
55386
  if (existsSync48(statsPath) && proxyRunning) {
55125
55387
  try {
55126
- const liveStats = JSON.parse(readFileSync41(statsPath, "utf-8"));
55388
+ const liveStats = JSON.parse(readFileSync42(statsPath, "utf-8"));
55127
55389
  const localCalls = liveStats.toolCallsLocal ?? 0;
55128
55390
  if (localCalls > 0) {
55129
55391
  liveToolCalls = { local: localCalls };
@@ -55151,7 +55413,7 @@ function registerStatusCommand(program2) {
55151
55413
  "firewall_stats.json"
55152
55414
  );
55153
55415
  if (existsSync48(firewallStatsPath)) {
55154
- const fs6 = JSON.parse(readFileSync41(firewallStatsPath, "utf-8"));
55416
+ const fs6 = JSON.parse(readFileSync42(firewallStatsPath, "utf-8"));
55155
55417
  firewallBlocked = fs6.blocked ?? 0;
55156
55418
  }
55157
55419
  } catch {
@@ -55190,7 +55452,7 @@ function registerStatusCommand(program2) {
55190
55452
  const snapshotMetaPath = join52(unerrDir, "state", "snapshot_meta.json");
55191
55453
  if (existsSync48(snapshotMetaPath)) {
55192
55454
  try {
55193
- const meta = JSON.parse(readFileSync41(snapshotMetaPath, "utf-8"));
55455
+ const meta = JSON.parse(readFileSync42(snapshotMetaPath, "utf-8"));
55194
55456
  if (meta.indexedAt) {
55195
55457
  const ageMs = Date.now() - new Date(meta.indexedAt).getTime();
55196
55458
  const ageHours = Math.floor(ageMs / 36e5);
@@ -55208,7 +55470,7 @@ function registerStatusCommand(program2) {
55208
55470
  try {
55209
55471
  const corrPath = join52(unerrDir, "state", "corrections_count.json");
55210
55472
  if (existsSync48(corrPath)) {
55211
- const cc = JSON.parse(readFileSync41(corrPath, "utf-8"));
55473
+ const cc = JSON.parse(readFileSync42(corrPath, "utf-8"));
55212
55474
  corrections = cc.count;
55213
55475
  }
55214
55476
  } catch {
@@ -55218,7 +55480,7 @@ function registerStatusCommand(program2) {
55218
55480
  let ruleCount;
55219
55481
  try {
55220
55482
  if (existsSync48(graphVersionPath)) {
55221
- const gv = JSON.parse(readFileSync41(graphVersionPath, "utf-8"));
55483
+ const gv = JSON.parse(readFileSync42(graphVersionPath, "utf-8"));
55222
55484
  communityCount = gv.community_count;
55223
55485
  conventionCount = gv.convention_count;
55224
55486
  ruleCount = gv.rule_count;
@@ -55261,7 +55523,7 @@ function registerStatusCommand(program2) {
55261
55523
  try {
55262
55524
  const ledgerPath = join52(unerrDir, "ledger", "shadow.jsonl");
55263
55525
  if (existsSync48(ledgerPath)) {
55264
- const content = readFileSync41(ledgerPath, "utf-8");
55526
+ const content = readFileSync42(ledgerPath, "utf-8");
55265
55527
  ledgerEntryCount = content.split("\n").filter((l) => l.trim().length > 0).length;
55266
55528
  }
55267
55529
  } catch {
@@ -55301,7 +55563,7 @@ function registerStatusCommand(program2) {
55301
55563
  try {
55302
55564
  const statsPath2 = join52(unerrDir, "state", "session_stats.json");
55303
55565
  if (existsSync48(statsPath2)) {
55304
- const raw = JSON.parse(readFileSync41(statsPath2, "utf-8"));
55566
+ const raw = JSON.parse(readFileSync42(statsPath2, "utf-8"));
55305
55567
  const totalCalls = raw.toolCallsLocal ?? 0;
55306
55568
  if (totalCalls > 0) {
55307
55569
  const endTime = raw.updatedAt ? new Date(raw.updatedAt) : /* @__PURE__ */ new Date();
@@ -55337,7 +55599,7 @@ function registerStatusCommand(program2) {
55337
55599
  try {
55338
55600
  const sp = join52(cwd, ".claude", "settings.json");
55339
55601
  if (existsSync48(sp)) {
55340
- const raw = readFileSync41(sp, "utf8");
55602
+ const raw = readFileSync42(sp, "utf8");
55341
55603
  preBashHookConfigured = raw.includes("unerr hook pre-bash") || raw.includes('"unerr hook pre-bash"');
55342
55604
  }
55343
55605
  } catch {
@@ -55384,7 +55646,7 @@ function registerStatusCommand(program2) {
55384
55646
  const { readTokenFlowEvents: readTokenFlowEvents2, aggregateSession: aggSession } = await Promise.resolve().then(() => (init_token_flow(), token_flow_exports));
55385
55647
  const events = readTokenFlowEvents2(unerrDir);
55386
55648
  if (events.length > 0) {
55387
- const latestSessionId = events[events.length - 1].session_id;
55649
+ const latestSessionId = events[events.length - 1]?.session_id ?? "";
55388
55650
  const summary = aggSession(events, latestSessionId);
55389
55651
  if (summary.total_tokens_saved > 0) {
55390
55652
  tokenFlowData = {
@@ -55628,7 +55890,7 @@ function registerTimelineCommand(program2) {
55628
55890
 
55629
55891
  // src/commands/uninstall.ts
55630
55892
  init_agent_registry();
55631
- import { existsSync as existsSync50, readFileSync as readFileSync43, unlinkSync as unlinkSync11, writeFileSync as writeFileSync26 } from "fs";
55893
+ import { existsSync as existsSync50, readFileSync as readFileSync44, unlinkSync as unlinkSync11, writeFileSync as writeFileSync26 } from "fs";
55632
55894
  import { join as join54 } from "path";
55633
55895
  init_hook_installer();
55634
55896
  init_mcp_config_writer();
@@ -55803,7 +56065,7 @@ function removeCursorHooks(cwd) {
55803
56065
  const hooksPath = join54(cwd, ".cursor", "hooks.json");
55804
56066
  if (!existsSync50(hooksPath)) return false;
55805
56067
  try {
55806
- const config = JSON.parse(readFileSync43(hooksPath, "utf-8"));
56068
+ const config = JSON.parse(readFileSync44(hooksPath, "utf-8"));
55807
56069
  if (!Array.isArray(config.hooks)) return false;
55808
56070
  const before = config.hooks.length;
55809
56071
  config.hooks = config.hooks.filter(
@@ -56227,7 +56489,7 @@ async function detectProjectRoot(cwd) {
56227
56489
  let hasGit = false;
56228
56490
  const normalizedCwd = cwd.replace(/\\/g, "/");
56229
56491
  for (const ap of ANTI_SIGNAL_PATHS) {
56230
- if (normalizedCwd === ap || normalizedCwd === ap + "/") {
56492
+ if (normalizedCwd === ap || normalizedCwd === `${ap}/`) {
56231
56493
  return {
56232
56494
  isProject: false,
56233
56495
  hasGit: false,
@@ -56392,7 +56654,7 @@ function readLocalConfig(cwd) {
56392
56654
  const configPath = join80(cwd, ".unerr", "config.json");
56393
56655
  if (!existsSync79(configPath)) return null;
56394
56656
  try {
56395
- return JSON.parse(readFileSync66(configPath, "utf-8"));
56657
+ return JSON.parse(readFileSync67(configPath, "utf-8"));
56396
56658
  } catch {
56397
56659
  return null;
56398
56660
  }
@@ -56406,8 +56668,14 @@ async function resumeBoot(config) {
56406
56668
  `\x1B[38;2;248;113;113m\u2717\x1B[0m No code project detected in this directory.
56407
56669
  Found .unerr/config.json but the directory doesn't look like a project root.
56408
56670
  Detection score: ${detection.score} (need ${DETECTION_THRESHOLD})
56409
- ` + (antiSignals.length > 0 ? ` Negative signals: ${antiSignals.map((s) => s.replace("anti-", "")).join(", ")}
56410
- ` : "") + "\n unerr checks for: project files (package.json, Cargo.toml, go.mod, ...),\n VCS directories (.git, .hg), IDE configs, CI/CD files, lock files,\n and source code across 50+ languages.\n\n \u25B8 Run \x1B[1munerr\x1B[0m from a project root directory.\n"
56671
+ ${antiSignals.length > 0 ? ` Negative signals: ${antiSignals.map((s) => s.replace("anti-", "")).join(", ")}
56672
+ ` : ""}
56673
+ unerr checks for: project files (package.json, Cargo.toml, go.mod, ...),
56674
+ VCS directories (.git, .hg), IDE configs, CI/CD files, lock files,
56675
+ and source code across 50+ languages.
56676
+
56677
+ \u25B8 Run \x1B[1munerr\x1B[0m from a project root directory.
56678
+ `
56411
56679
  );
56412
56680
  process.exit(1);
56413
56681
  }
@@ -56442,14 +56710,25 @@ async function firstRunBoot() {
56442
56710
  `\x1B[38;2;248;113;113m\u2717\x1B[0m No code project detected in this directory.
56443
56711
  unerr needs a folder containing source code to index.
56444
56712
  Detection score: ${detection.score} (need ${DETECTION_THRESHOLD})
56445
- ` + (antiSignals.length > 0 ? ` Negative signals: ${antiSignals.map((s) => s.replace("anti-", "")).join(", ")}
56446
- ` : "") + "\n Checked for: project files (package.json, Cargo.toml, go.mod, pyproject.toml, ...),\n VCS directories (.git, .hg, .svn), IDE configs (.vscode, .idea),\n CI/CD files (.github, Jenkinsfile), lock files, and source code\n across 50+ languages in root + standard source directories.\n\n \u25B8 Run \x1B[1munerr\x1B[0m from a project root directory.\n"
56713
+ ${antiSignals.length > 0 ? ` Negative signals: ${antiSignals.map((s) => s.replace("anti-", "")).join(", ")}
56714
+ ` : ""}
56715
+ Checked for: project files (package.json, Cargo.toml, go.mod, pyproject.toml, ...),
56716
+ VCS directories (.git, .hg, .svn), IDE configs (.vscode, .idea),
56717
+ CI/CD files (.github, Jenkinsfile), lock files, and source code
56718
+ across 50+ languages in root + standard source directories.
56719
+
56720
+ \u25B8 Run \x1B[1munerr\x1B[0m from a project root directory.
56721
+ `
56447
56722
  );
56448
56723
  process.exit(1);
56449
56724
  }
56450
56725
  if (!detection.hasGit) {
56451
56726
  process.stderr.write(
56452
- "\x1B[38;2;251;191;36m\u26A0\x1B[0m Project detected (" + detection.reason + ") but no git repository found.\n unerr works best with git. Consider running \x1B[1mgit init\x1B[0m first.\n Continuing anyway...\n\n"
56727
+ `\x1B[38;2;251;191;36m\u26A0\x1B[0m Project detected (${detection.reason}) but no git repository found.
56728
+ unerr works best with git. Consider running \x1B[1mgit init\x1B[0m first.
56729
+ Continuing anyway...
56730
+
56731
+ `
56453
56732
  );
56454
56733
  }
56455
56734
  log24.info({
@@ -56588,7 +56867,14 @@ ${antiSignals.length > 0 ? ` Negative signals: ${antiSignals.map((s) => s.repla
56588
56867
  return bridgeAndExit(startUdsBridge2, repoSock);
56589
56868
  }
56590
56869
  }
56591
- const { daemonSockPath: daemonSockPath2, probeDaemon: probeDaemon2, ensureRepo: ensureRepo2, connectRepo: connectRepo2, disconnectRepo: disconnectRepo2, sendActivity: sendActivity2 } = await Promise.resolve().then(() => (init_client(), client_exports));
56870
+ const {
56871
+ daemonSockPath: daemonSockPath2,
56872
+ probeDaemon: probeDaemon2,
56873
+ ensureRepo: ensureRepo2,
56874
+ connectRepo: connectRepo2,
56875
+ disconnectRepo: disconnectRepo2,
56876
+ sendActivity: sendActivity2
56877
+ } = await Promise.resolve().then(() => (init_client(), client_exports));
56592
56878
  const { findRepo: findRepo2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
56593
56879
  const daemonSock = daemonSockPath2();
56594
56880
  const daemonRunning = await probeDaemon2(daemonSock);