@unerr-ai/unerr 0.0.1 → 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 (556) hide show
  1. package/README.md +215 -35
  2. package/dist/__tests__/architecture-guard.test.js +122 -0
  3. package/dist/__tests__/arg-validator.test.js +205 -0
  4. package/dist/__tests__/ast-extractor.test.js +203 -0
  5. package/dist/__tests__/auto-bootstrap.test.js +280 -0
  6. package/dist/__tests__/background-indexer.test.js +228 -0
  7. package/dist/__tests__/blast-radius-engine.test.js +200 -0
  8. package/dist/__tests__/bridge-isolation.test.js +37 -0
  9. package/dist/__tests__/budget-enforcer.test.js +53 -0
  10. package/dist/__tests__/cfg-test-detection-perf.test.js +82 -0
  11. package/dist/__tests__/change-narrative.test.js +190 -0
  12. package/dist/__tests__/check-commit.test.js +258 -0
  13. package/dist/__tests__/checksum.test.js +34 -0
  14. package/dist/__tests__/commit-watcher.test.js +154 -0
  15. package/dist/__tests__/community-detection.test.js +179 -0
  16. package/dist/__tests__/community-tools.test.js +299 -0
  17. package/dist/__tests__/components.test.js +449 -0
  18. package/dist/__tests__/compression-log.test.js +174 -0
  19. package/dist/__tests__/compression-quality-monitor.test.js +40 -0
  20. package/dist/__tests__/config-healer.test.js +165 -0
  21. package/dist/__tests__/context-ledger.test.js +58 -0
  22. package/dist/__tests__/convention-detector.test.js +99 -0
  23. package/dist/__tests__/convention-learner.test.js +86 -0
  24. package/dist/__tests__/correction-detector.test.js +330 -0
  25. package/dist/__tests__/daemon-autostart-install.test.js +283 -0
  26. package/dist/__tests__/daemon-bridge.test.js +222 -0
  27. package/dist/__tests__/daemon-dashboard.test.js +202 -0
  28. package/dist/__tests__/daemon-registry.test.js +240 -0
  29. package/dist/__tests__/daemon-supervisor.test.js +318 -0
  30. package/dist/__tests__/daemon-version-check.test.js +275 -0
  31. package/dist/__tests__/decision-point-detector.test.js +98 -0
  32. package/dist/__tests__/deep-link.test.js +143 -0
  33. package/dist/__tests__/disallowed-tools.test.js +115 -0
  34. package/dist/__tests__/drift-tracker.test.js +582 -0
  35. package/dist/__tests__/durability-scorer.test.js +152 -0
  36. package/dist/__tests__/efficiency-tracker.test.js +65 -0
  37. package/dist/__tests__/enrich.test.js +144 -0
  38. package/dist/__tests__/entity-rewind.test.js +248 -0
  39. package/dist/__tests__/ephemeral.test.js +111 -0
  40. package/dist/__tests__/exploration-cost.test.js +93 -0
  41. package/dist/__tests__/fact-generator.test.js +197 -0
  42. package/dist/__tests__/file-l0-graph.test.js +244 -0
  43. package/dist/__tests__/file-logger.test.js +82 -0
  44. package/dist/__tests__/file-outline.test.js +141 -0
  45. package/dist/__tests__/file-read-protocol.test.js +188 -0
  46. package/dist/__tests__/format-encoder.test.js +233 -0
  47. package/dist/__tests__/git-attribution.test.js +259 -0
  48. package/dist/__tests__/graph-temporal-joiner.test.js +219 -0
  49. package/dist/__tests__/health-grade-enhanced.test.js +138 -0
  50. package/dist/__tests__/health-map-data.test.js +173 -0
  51. package/dist/__tests__/helpers/mcp-harness.js +45 -0
  52. package/dist/__tests__/helpers/mcp-harness.test.js +68 -0
  53. package/dist/__tests__/hook-dedup.test.js +112 -0
  54. package/dist/__tests__/hook-runner.test.js +253 -0
  55. package/dist/__tests__/indexer-cfg.test.js +185 -0
  56. package/dist/__tests__/indexer-cross-file.test.js +172 -0
  57. package/dist/__tests__/indexer-extraction.test.js +245 -0
  58. package/dist/__tests__/indexer-incremental.test.js +232 -0
  59. package/dist/__tests__/indexer-language-expansion.test.js +165 -0
  60. package/dist/__tests__/init-push.test.js +131 -0
  61. package/dist/__tests__/instruction-writer.test.js +179 -0
  62. package/dist/__tests__/intelligence-integration.test.js +217 -0
  63. package/dist/__tests__/intent-correlator.test.js +175 -0
  64. package/dist/__tests__/intent-detector.test.js +235 -0
  65. package/dist/__tests__/intent-encoder.test.js +167 -0
  66. package/dist/__tests__/java-build-tool-detection.test.js +174 -0
  67. package/dist/__tests__/layer3-sprint-q.test.js +160 -0
  68. package/dist/__tests__/layer3-sprint-r.test.js +91 -0
  69. package/dist/__tests__/layer3-sprint-s.test.js +183 -0
  70. package/dist/__tests__/layer3-sprint-t.test.js +201 -0
  71. package/dist/__tests__/layer3-sprint-u.test.js +174 -0
  72. package/dist/__tests__/layer4-sprint-ba2.test.js +354 -0
  73. package/dist/__tests__/layer4-sprint-ba4.test.js +84 -0
  74. package/dist/__tests__/layer4-sprint-vs.test.js +105 -0
  75. package/dist/__tests__/ledger-chains.test.js +162 -0
  76. package/dist/__tests__/lifecycle-machine.test.js +226 -0
  77. package/dist/__tests__/local-chat-provider.test.js +170 -0
  78. package/dist/__tests__/local-convention-detector.test.js +308 -0
  79. package/dist/__tests__/local-embeddings.test.js +422 -0
  80. package/dist/__tests__/local-graph.test.js +540 -0
  81. package/dist/__tests__/local-indexer.test.js +228 -0
  82. package/dist/__tests__/local-intelligence-l3.test.js +332 -0
  83. package/dist/__tests__/local-llm.test.js +253 -0
  84. package/dist/__tests__/local-mode-offline.test.js +187 -0
  85. package/dist/__tests__/local-mode-stats.test.js +273 -0
  86. package/dist/__tests__/local-mode-tui.test.js +343 -0
  87. package/dist/__tests__/local-parse.test.js +199 -0
  88. package/dist/__tests__/log-tailer.test.js +208 -0
  89. package/dist/__tests__/loop-breaker.test.js +276 -0
  90. package/dist/__tests__/loop-miner.test.js +226 -0
  91. package/dist/__tests__/mcp-config.test.js +126 -0
  92. package/dist/__tests__/mcp-content-json.test.js +10 -0
  93. package/dist/__tests__/mcp-envelope.test.js +124 -0
  94. package/dist/__tests__/metrics-store.test.js +223 -0
  95. package/dist/__tests__/native-watcher.test.js +191 -0
  96. package/dist/__tests__/navigation-hooks-agent-aware.test.js +145 -0
  97. package/dist/__tests__/negative-knowledge.test.js +116 -0
  98. package/dist/__tests__/network-boundary.test.js +190 -0
  99. package/dist/__tests__/network-firewall.test.js +112 -0
  100. package/dist/__tests__/nudge-invariants.test.js +160 -0
  101. package/dist/__tests__/nudge-v2.test.js +225 -0
  102. package/dist/__tests__/offline-rewind.test.js +251 -0
  103. package/dist/__tests__/open-threads.test.js +89 -0
  104. package/dist/__tests__/output-compressor.test.js +93 -0
  105. package/dist/__tests__/pending-violations.test.js +112 -0
  106. package/dist/__tests__/persistence-effectiveness.test.js +143 -0
  107. package/dist/__tests__/provider-factory.test.js +42 -0
  108. package/dist/__tests__/providers.test.js +24 -0
  109. package/dist/__tests__/proxy.test.js +314 -0
  110. package/dist/__tests__/query-router.test.js +1018 -0
  111. package/dist/__tests__/reasoning-quality-route.test.js +138 -0
  112. package/dist/__tests__/redactor.test.js +120 -0
  113. package/dist/__tests__/resource-monitor.test.js +57 -0
  114. package/dist/__tests__/response-envelope.test.js +100 -0
  115. package/dist/__tests__/risk-classifier.test.js +101 -0
  116. package/dist/__tests__/risk-signal-scope.test.js +75 -0
  117. package/dist/__tests__/rule-evaluator.test.js +280 -0
  118. package/dist/__tests__/scip-decoder.test.js +49 -0
  119. package/dist/__tests__/scip-downloader.test.js +201 -0
  120. package/dist/__tests__/scip-merger.test.js +103 -0
  121. package/dist/__tests__/search-index.test.js +422 -0
  122. package/dist/__tests__/semantic-enrichment.test.js +360 -0
  123. package/dist/__tests__/session-brief-builder.test.js +187 -0
  124. package/dist/__tests__/session-context.test.js +221 -0
  125. package/dist/__tests__/session-continuity.test.js +144 -0
  126. package/dist/__tests__/session-dedup.test.js +74 -0
  127. package/dist/__tests__/session-event-wiring.test.js +206 -0
  128. package/dist/__tests__/session-events.test.js +149 -0
  129. package/dist/__tests__/session-legend.test.js +20 -0
  130. package/dist/__tests__/session-persistence.test.js +131 -0
  131. package/dist/__tests__/session-resume-block.test.js +107 -0
  132. package/dist/__tests__/session-resume.test.js +97 -0
  133. package/dist/__tests__/session-summary-writer.test.js +134 -0
  134. package/dist/__tests__/shadow-ledger.test.js +203 -0
  135. package/dist/__tests__/shell-classifier.test.js +151 -0
  136. package/dist/__tests__/shell-compression-floor.test.js +189 -0
  137. package/dist/__tests__/shell-compression-v2.test.js +339 -0
  138. package/dist/__tests__/shell-compressor.test.js +35 -0
  139. package/dist/__tests__/shell-hooks.test.js +128 -0
  140. package/dist/__tests__/shell-strategies.test.js +644 -0
  141. package/dist/__tests__/shell-tee.test.js +133 -0
  142. package/dist/__tests__/signal-dedup.test.js +158 -0
  143. package/dist/__tests__/signal-reinforcer.test.js +77 -0
  144. package/dist/__tests__/signal-scorer.test.js +251 -0
  145. package/dist/__tests__/signal-show-store.test.js +108 -0
  146. package/dist/__tests__/smart-truncate.test.js +215 -0
  147. package/dist/__tests__/snapshot-v2.test.js +113 -0
  148. package/dist/__tests__/sprint-l1-local-mode.test.js +130 -0
  149. package/dist/__tests__/sprint-l10-boot.test.js +220 -0
  150. package/dist/__tests__/sprint-l9-offline-commands.test.js +189 -0
  151. package/dist/__tests__/sprint-q-persistent-context.test.js +198 -0
  152. package/dist/__tests__/sprint-s1-wiring.test.js +215 -0
  153. package/dist/__tests__/sprint-s2-wiring.test.js +256 -0
  154. package/dist/__tests__/sprint-s3-wiring.test.js +195 -0
  155. package/dist/__tests__/sprint-s4-wiring.test.js +213 -0
  156. package/dist/__tests__/sprint-s6-hooks.test.js +222 -0
  157. package/dist/__tests__/sprint-s7-persistent.test.js +263 -0
  158. package/dist/__tests__/sprint-s8-value.test.js +167 -0
  159. package/dist/__tests__/sprint-s9-behavioral.test.js +179 -0
  160. package/dist/__tests__/sprint3-intelligence.test.js +297 -0
  161. package/dist/__tests__/sprint5-mcp-server.test.js +136 -0
  162. package/dist/__tests__/startup-display.test.js +302 -0
  163. package/dist/__tests__/startup-log-file.test.js +97 -0
  164. package/dist/__tests__/stash-manager.test.js +229 -0
  165. package/dist/__tests__/state-detector.test.js +92 -0
  166. package/dist/__tests__/status-dashboard.test.js +142 -0
  167. package/dist/__tests__/temporal-facts.test.js +292 -0
  168. package/dist/__tests__/temporal-routes.test.js +142 -0
  169. package/dist/__tests__/test-detector.test.js +174 -0
  170. package/dist/__tests__/theme.test.js +72 -0
  171. package/dist/__tests__/timeline-agents.test.js +122 -0
  172. package/dist/__tests__/timeline-bootstrap.test.js +176 -0
  173. package/dist/__tests__/timeline-filters.test.js +193 -0
  174. package/dist/__tests__/timeline-markers.test.js +151 -0
  175. package/dist/__tests__/timeline-routes.test.js +156 -0
  176. package/dist/__tests__/timeline-store.test.js +171 -0
  177. package/dist/__tests__/token-counter.test.js +86 -0
  178. package/dist/__tests__/token-estimator.test.js +96 -0
  179. package/dist/__tests__/token-flow-api.test.js +239 -0
  180. package/dist/__tests__/token-flow-instrumentation.test.js +437 -0
  181. package/dist/__tests__/token-flow-persistence.test.js +356 -0
  182. package/dist/__tests__/token-flow-routes.test.js +199 -0
  183. package/dist/__tests__/token-flow.test.js +695 -0
  184. package/dist/__tests__/tool-clusters.test.js +177 -0
  185. package/dist/__tests__/transport-mux.test.js +283 -0
  186. package/dist/__tests__/turn-segmenter.test.js +166 -0
  187. package/dist/__tests__/uninstall.test.js +141 -0
  188. package/dist/__tests__/warm-start-policy.test.js +271 -0
  189. package/dist/__tests__/wire-cap-nudge.test.js +77 -0
  190. package/dist/__tests__/worker-pool.test.js +101 -0
  191. package/dist/behaviors/agent-llm-bridge.js +166 -0
  192. package/dist/behaviors/architecture-guard.js +256 -0
  193. package/dist/behaviors/auto-doc.js +247 -0
  194. package/dist/behaviors/cascade-guard.js +289 -0
  195. package/dist/behaviors/change-narrative.js +270 -0
  196. package/dist/behaviors/convention-drift.js +290 -0
  197. package/dist/behaviors/framework.js +235 -0
  198. package/dist/behaviors/guard-formatter.js +44 -0
  199. package/dist/behaviors/incomplete-work.js +270 -0
  200. package/dist/behaviors/loop-breaker.js +300 -0
  201. package/dist/behaviors/session-continuity.js +208 -0
  202. package/dist/cli.js +6446 -2227
  203. package/dist/commands/branches.js +97 -0
  204. package/dist/commands/check-commit.js +225 -0
  205. package/dist/commands/compress-output.js +64 -0
  206. package/dist/commands/config-verify.js +243 -0
  207. package/dist/commands/daemon.js +905 -0
  208. package/dist/commands/dashboard.js +52 -0
  209. package/dist/commands/debug.js +200 -0
  210. package/dist/commands/enrich.js +184 -0
  211. package/dist/commands/exec.js +233 -0
  212. package/dist/commands/gain.js +156 -0
  213. package/dist/commands/hook.js +88 -0
  214. package/dist/commands/index.js +88 -0
  215. package/dist/commands/init.js +74 -0
  216. package/dist/commands/install.js +505 -0
  217. package/dist/commands/learn.js +116 -0
  218. package/dist/commands/manifest.js +193 -0
  219. package/dist/commands/rewind.js +103 -0
  220. package/dist/commands/serve.js +19 -0
  221. package/dist/commands/setup-wizard.js +414 -0
  222. package/dist/commands/skills.js +64 -0
  223. package/dist/commands/stats.js +20 -0
  224. package/dist/commands/status.js +654 -0
  225. package/dist/commands/timeline.js +139 -0
  226. package/dist/commands/uninstall.js +230 -0
  227. package/dist/components/App.js +109 -0
  228. package/dist/components/Banner.js +12 -0
  229. package/dist/components/ConfirmPrompt.js +25 -0
  230. package/dist/components/DriftSummary.js +23 -0
  231. package/dist/components/GradeBadge.js +15 -0
  232. package/dist/components/HealthCard.js +18 -0
  233. package/dist/components/InkSpinner.js +22 -0
  234. package/dist/components/InputBox.js +17 -0
  235. package/dist/components/KeyValue.js +13 -0
  236. package/dist/components/MessageList.js +14 -0
  237. package/dist/components/ProgressBar.js +26 -0
  238. package/dist/components/Section.js +16 -0
  239. package/dist/components/SessionSummaryCard.js +73 -0
  240. package/dist/components/StartupDisplay.js +24 -0
  241. package/dist/components/StatusDashboard.js +57 -0
  242. package/dist/components/StatusLine.js +8 -0
  243. package/dist/components/StepLine.js +22 -0
  244. package/dist/components/Theme.js +20 -0
  245. package/dist/components/ToolProgress.js +8 -0
  246. package/dist/components/ViolationList.js +21 -0
  247. package/dist/components/render.js +13 -0
  248. package/dist/config/agent-registry.js +237 -0
  249. package/dist/config/claude-settings-hooks.js +304 -0
  250. package/dist/config/hook-installer.js +65 -0
  251. package/dist/config/instruction-writer.js +388 -0
  252. package/dist/config/mcp-config-writer.js +266 -0
  253. package/dist/config/settings.js +174 -0
  254. package/dist/config/tool-detector.js +42 -0
  255. package/dist/config/value-surfacing.js +119 -0
  256. package/dist/core/context-assembly.js +108 -0
  257. package/dist/core/conversation.js +33 -0
  258. package/dist/core/local-chat-provider.js +475 -0
  259. package/dist/core/provider-factory.js +55 -0
  260. package/dist/core/providers.js +90 -0
  261. package/dist/core/query-engine.js +174 -0
  262. package/dist/daemon/api.js +312 -0
  263. package/dist/daemon/autostart.js +119 -0
  264. package/dist/daemon/bootstrap.js +39 -0
  265. package/dist/daemon/client.js +164 -0
  266. package/dist/daemon/detect-ci.js +81 -0
  267. package/dist/daemon/platform-linux.js +146 -0
  268. package/dist/daemon/platform-macos.js +134 -0
  269. package/dist/daemon/platform-windows.js +116 -0
  270. package/dist/daemon/process-manager.js +299 -0
  271. package/dist/daemon/protocol.js +23 -0
  272. package/dist/daemon/registry.js +270 -0
  273. package/dist/daemon/settings-schema.js +72 -0
  274. package/dist/daemon/system-health.js +134 -0
  275. package/dist/daemon/version-checker.js +262 -0
  276. package/dist/daemon/warm-start.js +223 -0
  277. package/dist/entrypoints/cli.js +1043 -0
  278. package/dist/entrypoints/daemon.js +380 -0
  279. package/dist/entrypoints/repl.js +147 -0
  280. package/dist/hooks/adapters/claude-code.js +90 -0
  281. package/dist/hooks/adapters/cline.js +100 -0
  282. package/dist/hooks/adapters/cursor.js +98 -0
  283. package/dist/hooks/hook-dedup.js +79 -0
  284. package/dist/hooks/hook-runner.js +113 -0
  285. package/dist/hooks/navigation-hooks.js +175 -0
  286. package/dist/hooks/prompt-hooks.js +63 -0
  287. package/dist/hooks/shell-hooks.js +47 -0
  288. package/dist/ignore.js +111 -0
  289. package/dist/intelligence/approach-suggester.js +61 -0
  290. package/dist/intelligence/ast-extractor.js +2615 -0
  291. package/dist/intelligence/ast-worker.js +34 -0
  292. package/dist/intelligence/background-indexer.js +121 -0
  293. package/dist/intelligence/blast-radius.js +200 -0
  294. package/dist/intelligence/community-detection.js +691 -0
  295. package/dist/intelligence/community-detector.js +184 -0
  296. package/dist/intelligence/computation-scheduler.js +75 -0
  297. package/dist/intelligence/confidence-propagation.js +47 -0
  298. package/dist/intelligence/convention-detector.js +242 -0
  299. package/dist/intelligence/convention-learner.js +205 -0
  300. package/dist/intelligence/convention-matcher.js +205 -0
  301. package/dist/intelligence/cozo-schema.js +376 -0
  302. package/dist/intelligence/decision-point-detector.js +90 -0
  303. package/dist/intelligence/deep-dive-tools.js +586 -0
  304. package/dist/intelligence/durability-scorer.js +84 -0
  305. package/dist/intelligence/exploration-cost.js +204 -0
  306. package/dist/intelligence/exploration-pattern-tracker.js +61 -0
  307. package/dist/intelligence/fact-generator.js +322 -0
  308. package/dist/intelligence/facts-schema.js +90 -0
  309. package/dist/intelligence/file-intelligence.js +59 -0
  310. package/dist/intelligence/graph-holder.js +220 -0
  311. package/dist/intelligence/graph-temporal-joiner.js +238 -0
  312. package/dist/intelligence/health-grade.js +423 -0
  313. package/dist/intelligence/health-grader.js +200 -0
  314. package/dist/intelligence/health-map-data.js +259 -0
  315. package/dist/intelligence/import-symbols.js +136 -0
  316. package/dist/intelligence/incremental-indexer.js +658 -0
  317. package/dist/intelligence/indexer/centrality.js +62 -0
  318. package/dist/intelligence/indexer/cfg-context.js +95 -0
  319. package/dist/intelligence/indexer/confidence.js +34 -0
  320. package/dist/intelligence/indexer/cross-file-resolver.js +104 -0
  321. package/dist/intelligence/indexer/edge-repair.js +89 -0
  322. package/dist/intelligence/indexer/entity-key.js +17 -0
  323. package/dist/intelligence/indexer/export-map.js +132 -0
  324. package/dist/intelligence/indexer/git-cochange.js +128 -0
  325. package/dist/intelligence/indexer/graph-patch.js +147 -0
  326. package/dist/intelligence/indexer/incremental.js +78 -0
  327. package/dist/intelligence/indexer/ingest.js +160 -0
  328. package/dist/intelligence/indexer/language-detect.js +226 -0
  329. package/dist/intelligence/indexer/metadata.js +63 -0
  330. package/dist/intelligence/indexer/mutation-tracker.js +79 -0
  331. package/dist/intelligence/indexer/orchestrator.js +155 -0
  332. package/dist/intelligence/indexer/plugin-interface.js +31 -0
  333. package/dist/intelligence/indexer/plugins/csharp.js +440 -0
  334. package/dist/intelligence/indexer/plugins/go.js +335 -0
  335. package/dist/intelligence/indexer/plugins/java.js +370 -0
  336. package/dist/intelligence/indexer/plugins/python.js +358 -0
  337. package/dist/intelligence/indexer/plugins/regex-fallback.js +82 -0
  338. package/dist/intelligence/indexer/plugins/ruby.js +290 -0
  339. package/dist/intelligence/indexer/plugins/rust.js +484 -0
  340. package/dist/intelligence/indexer/plugins/tier2-generic.js +310 -0
  341. package/dist/intelligence/indexer/plugins/typescript.js +456 -0
  342. package/dist/intelligence/indexer/resource-monitor.js +93 -0
  343. package/dist/intelligence/indexer/scip/decoder.js +253 -0
  344. package/dist/intelligence/indexer/scip/detector.js +232 -0
  345. package/dist/intelligence/indexer/scip/downloader.js +427 -0
  346. package/dist/intelligence/indexer/scip/fallback.js +34 -0
  347. package/dist/intelligence/indexer/scip/merger.js +109 -0
  348. package/dist/intelligence/indexer/scip/orchestrator.js +433 -0
  349. package/dist/intelligence/indexer/scip/runner.js +98 -0
  350. package/dist/intelligence/indexer/snapshot.js +66 -0
  351. package/dist/intelligence/indexer/test-detector.js +196 -0
  352. package/dist/intelligence/indexer/watch-integration.js +61 -0
  353. package/dist/intelligence/indexer/worker.js +85 -0
  354. package/dist/intelligence/local-convention-detector.js +437 -0
  355. package/dist/intelligence/local-embeddings.js +190 -0
  356. package/dist/intelligence/local-graph.js +1946 -0
  357. package/dist/intelligence/local-indexer.js +1575 -0
  358. package/dist/intelligence/local-llm.js +163 -0
  359. package/dist/intelligence/local-rule-generator.js +154 -0
  360. package/dist/intelligence/local-snapshot.js +213 -0
  361. package/dist/intelligence/negative-knowledge.js +103 -0
  362. package/dist/intelligence/persistent-db.js +85 -0
  363. package/dist/intelligence/query-router.js +2556 -0
  364. package/dist/intelligence/risk-classifier.js +116 -0
  365. package/dist/intelligence/rule-evaluator.js +380 -0
  366. package/dist/intelligence/rule-generator.js +49 -0
  367. package/dist/intelligence/search-index.js +173 -0
  368. package/dist/intelligence/semantic/docstring-extractor.js +67 -0
  369. package/dist/intelligence/semantic/embedding-store.js +52 -0
  370. package/dist/intelligence/semantic/enrichment-orchestrator.js +48 -0
  371. package/dist/intelligence/semantic/git-message-miner.js +114 -0
  372. package/dist/intelligence/semantic/identifier-tokenizer.js +51 -0
  373. package/dist/intelligence/semantic/node2vec-embeddings.js +71 -0
  374. package/dist/intelligence/semantic/node2vec-walks.js +103 -0
  375. package/dist/intelligence/semantic/path-domain-inference.js +112 -0
  376. package/dist/intelligence/semantic/similarity-engine.js +60 -0
  377. package/dist/intelligence/semantic/tfidf-vectors.js +88 -0
  378. package/dist/intelligence/session-brief-builder.js +159 -0
  379. package/dist/intelligence/session-context.js +221 -0
  380. package/dist/intelligence/session-health-monitor.js +211 -0
  381. package/dist/intelligence/session-narrative.js +197 -0
  382. package/dist/intelligence/session-pattern-analyzer.js +218 -0
  383. package/dist/intelligence/signal-scorer.js +390 -0
  384. package/dist/intelligence/signal-show-store.js +182 -0
  385. package/dist/intelligence/smart-truncate.js +158 -0
  386. package/dist/intelligence/subgraph-cache.js +88 -0
  387. package/dist/intelligence/temporal-facts.js +494 -0
  388. package/dist/intelligence/token-estimator.js +100 -0
  389. package/dist/intelligence/tool-injector.js +87 -0
  390. package/dist/intelligence/tree-sitter-loader.js +71 -0
  391. package/dist/intelligence/worker-pool.js +116 -0
  392. package/dist/proxy/arg-validator.js +79 -0
  393. package/dist/proxy/auto-bootstrap.js +167 -0
  394. package/dist/proxy/bridge.js +147 -0
  395. package/dist/proxy/budget-enforcer.js +70 -0
  396. package/dist/proxy/compression-quality-monitor.js +160 -0
  397. package/dist/proxy/compression-stats.js +51 -0
  398. package/dist/proxy/context-rot-detector.js +137 -0
  399. package/dist/proxy/drift-detector.js +139 -0
  400. package/dist/proxy/efficiency-tracker.js +79 -0
  401. package/dist/proxy/fact-ranking.js +154 -0
  402. package/dist/proxy/format-encoder.js +266 -0
  403. package/dist/proxy/http-transport.js +90 -0
  404. package/dist/proxy/lifecycle-actor.js +55 -0
  405. package/dist/proxy/lifecycle-machine.js +187 -0
  406. package/dist/proxy/log-tailer.js +265 -0
  407. package/dist/proxy/model-pricing.js +98 -0
  408. package/dist/proxy/network-firewall.js +141 -0
  409. package/dist/proxy/nudge-state.js +93 -0
  410. package/dist/proxy/output-compressor.js +185 -0
  411. package/dist/proxy/pid-lock.js +291 -0
  412. package/dist/proxy/proxy-context.js +11 -0
  413. package/dist/proxy/proxy.js +2633 -0
  414. package/dist/proxy/response-enrichment.js +32 -0
  415. package/dist/proxy/response-envelope.js +313 -0
  416. package/dist/proxy/session-dedup.js +82 -0
  417. package/dist/proxy/session-legend.js +30 -0
  418. package/dist/proxy/session-persistence.js +210 -0
  419. package/dist/proxy/session-resume.js +94 -0
  420. package/dist/proxy/session-stats.js +513 -0
  421. package/dist/proxy/shell-classifier.js +1346 -0
  422. package/dist/proxy/shell-compression-log.js +93 -0
  423. package/dist/proxy/shell-compressor.js +390 -0
  424. package/dist/proxy/shell-graph-boost.js +202 -0
  425. package/dist/proxy/shell-monitor-map.js +18 -0
  426. package/dist/proxy/shell-stats.js +54 -0
  427. package/dist/proxy/shell-strategies/cloud.js +215 -0
  428. package/dist/proxy/shell-strategies/diff.js +159 -0
  429. package/dist/proxy/shell-strategies/error-diagnostic.js +796 -0
  430. package/dist/proxy/shell-strategies/filter-dsl.js +358 -0
  431. package/dist/proxy/shell-strategies/git-status.js +177 -0
  432. package/dist/proxy/shell-strategies/key-value.js +193 -0
  433. package/dist/proxy/shell-strategies/log-text.js +154 -0
  434. package/dist/proxy/shell-strategies/omni.js +188 -0
  435. package/dist/proxy/shell-strategies/progress.js +55 -0
  436. package/dist/proxy/shell-strategies/redact.js +76 -0
  437. package/dist/proxy/shell-strategies/structured.js +241 -0
  438. package/dist/proxy/shell-strategies/tabular.js +243 -0
  439. package/dist/proxy/shell-strategies/test-results-types.js +13 -0
  440. package/dist/proxy/shell-strategies/test-results.js +784 -0
  441. package/dist/proxy/shell-strategies/tree-paths.js +144 -0
  442. package/dist/proxy/shell-strategies/yaml.js +182 -0
  443. package/dist/proxy/shell-tee.js +111 -0
  444. package/dist/proxy/signal-dedup.js +171 -0
  445. package/dist/proxy/startup-renderer.js +158 -0
  446. package/dist/proxy/task-token-display.js +38 -0
  447. package/dist/proxy/token-counter.js +61 -0
  448. package/dist/proxy/tool-clusters.js +273 -0
  449. package/dist/proxy/tool-definitions.js +525 -0
  450. package/dist/proxy/transport-mux.js +229 -0
  451. package/dist/proxy/wire-cap.js +268 -0
  452. package/dist/schemas/api/skills.js +19 -0
  453. package/dist/schemas/common/errors.js +7 -0
  454. package/dist/schemas/common/headers.js +5 -0
  455. package/dist/schemas/entities/edge.js +25 -0
  456. package/dist/schemas/entities/entity.js +22 -0
  457. package/dist/schemas/entities/rule.js +18 -0
  458. package/dist/schemas/index.js +14 -0
  459. package/dist/server/event-bus.js +59 -0
  460. package/dist/server/http.js +156 -0
  461. package/dist/server/middleware.js +70 -0
  462. package/dist/server/routes/drift.js +97 -0
  463. package/dist/server/routes/intelligence.js +1217 -0
  464. package/dist/server/routes/reasoning-quality.js +444 -0
  465. package/dist/server/routes/session.js +86 -0
  466. package/dist/server/routes/stream.js +120 -0
  467. package/dist/server/routes/system.js +73 -0
  468. package/dist/server/routes/temporal.js +170 -0
  469. package/dist/server/routes/timeline.js +232 -0
  470. package/dist/server/routes/token-flow.js +403 -0
  471. package/dist/skills/effectiveness-tracker.js +93 -0
  472. package/dist/skills/local-pack.js +380 -0
  473. package/dist/skills/resolver.js +495 -0
  474. package/dist/state-detector.js +83 -0
  475. package/dist/timeline/intent-detector.js +263 -0
  476. package/dist/timeline/loop-miner.js +140 -0
  477. package/dist/timeline/open-threads.js +49 -0
  478. package/dist/timeline/signal-reinforcer.js +62 -0
  479. package/dist/timeline/timeline-bootstrap.js +151 -0
  480. package/dist/timeline/timeline-store.js +618 -0
  481. package/dist/tools/coding/bash.js +49 -0
  482. package/dist/tools/coding/file-edit.js +72 -0
  483. package/dist/tools/coding/file-outline.js +227 -0
  484. package/dist/tools/coding/file-read-protocol.js +425 -0
  485. package/dist/tools/coding/file-read.js +35 -0
  486. package/dist/tools/coding/file-write.js +43 -0
  487. package/dist/tools/coding/glob-tool.js +109 -0
  488. package/dist/tools/coding/grep.js +162 -0
  489. package/dist/tools/coding/index.js +27 -0
  490. package/dist/tools/intelligence/index.js +269 -0
  491. package/dist/tools/intelligence/record-fact.js +48 -0
  492. package/dist/tools/intelligence/timeline-markers.js +130 -0
  493. package/dist/tools/registry.js +47 -0
  494. package/dist/tools/types.js +8 -0
  495. package/dist/tracking/auto-snapshot-triggers.js +246 -0
  496. package/dist/tracking/branch-context.js +115 -0
  497. package/dist/tracking/branch-snapshot.js +217 -0
  498. package/dist/tracking/causal-bridge.js +317 -0
  499. package/dist/tracking/circuit-breaker.js +147 -0
  500. package/dist/tracking/commit-watcher.js +114 -0
  501. package/dist/tracking/context-ledger.js +119 -0
  502. package/dist/tracking/correction-detector.js +324 -0
  503. package/dist/tracking/drift-tracker.js +874 -0
  504. package/dist/tracking/durability-tracker.js +94 -0
  505. package/dist/tracking/entity-rewind.js +200 -0
  506. package/dist/tracking/file-hash-state.js +114 -0
  507. package/dist/tracking/git-attribution.js +132 -0
  508. package/dist/tracking/git-trailers.js +171 -0
  509. package/dist/tracking/intelligence-counter.js +46 -0
  510. package/dist/tracking/intent-correlator.js +202 -0
  511. package/dist/tracking/intent-encoder.js +52 -0
  512. package/dist/tracking/intent-token-tracker.js +159 -0
  513. package/dist/tracking/ledger-archiver.js +94 -0
  514. package/dist/tracking/ledger-chains.js +245 -0
  515. package/dist/tracking/metrics-store.js +361 -0
  516. package/dist/tracking/native-watcher.js +131 -0
  517. package/dist/tracking/offline-rewind.js +295 -0
  518. package/dist/tracking/pending-violations.js +74 -0
  519. package/dist/tracking/persistence-effectiveness.js +167 -0
  520. package/dist/tracking/prompt-durability.js +202 -0
  521. package/dist/tracking/quality-signals.js +213 -0
  522. package/dist/tracking/redactor.js +73 -0
  523. package/dist/tracking/rewind-engine.js +161 -0
  524. package/dist/tracking/session-history.js +128 -0
  525. package/dist/tracking/session-receipt.js +88 -0
  526. package/dist/tracking/session-summary-writer.js +157 -0
  527. package/dist/tracking/shadow-ledger.js +321 -0
  528. package/dist/tracking/stash-manager.js +258 -0
  529. package/dist/tracking/timeline-fork.js +213 -0
  530. package/dist/tracking/timeline.js +69 -0
  531. package/dist/tracking/token-flow.js +276 -0
  532. package/dist/tracking/turn-segmenter.js +122 -0
  533. package/dist/tracking/weekly-accumulator.js +179 -0
  534. package/dist/tracking/working-snapshots.js +188 -0
  535. package/dist/tracking/workspace-manifest.js +176 -0
  536. package/dist/transport/http.js +102 -0
  537. package/dist/ui/assets/index-7gl3mIuY.css +1 -0
  538. package/dist/ui/assets/index-BsMTQdhX.js +10 -0
  539. package/dist/ui/index.html +2 -2
  540. package/dist/utils/counterfactual.js +65 -0
  541. package/dist/utils/deep-link.js +34 -0
  542. package/dist/utils/detect.js +193 -0
  543. package/dist/utils/exec.js +73 -0
  544. package/dist/utils/file-logger.js +87 -0
  545. package/dist/utils/format-error.js +29 -0
  546. package/dist/utils/git.js +181 -0
  547. package/dist/utils/log.js +57 -0
  548. package/dist/utils/logger.js +35 -0
  549. package/dist/utils/mcp-content-json.js +8 -0
  550. package/dist/utils/session-logger.js +154 -0
  551. package/dist/utils/startup-log.js +512 -0
  552. package/dist/utils/ui.js +56 -0
  553. package/package.json +5 -3
  554. package/scripts/postinstall.mjs +299 -0
  555. package/dist/ui/assets/index-BISLlJyc.js +0 -10
  556. package/dist/ui/assets/index-BUChTv4H.css +0 -1
@@ -0,0 +1,414 @@
1
+ /**
2
+ * Setup Wizard — first-run project initialization.
3
+ *
4
+ * Generates a repo ID, writes .unerr/config.json, installs skills.
5
+ * All output goes to stderr (stdout is MCP-sacred).
6
+ *
7
+ * LLM configuration is disabled — unerr operates as an MCP proxy where
8
+ * the calling agent (Claude Code, Cursor, etc.) provides the LLM.
9
+ * The configure* functions are retained for future re-enablement.
10
+ */
11
+ import { createHash } from "node:crypto";
12
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
13
+ import { join } from "node:path";
14
+ import * as clack from "@clack/prompts";
15
+ import { getRemoteUrl } from "../utils/git.js";
16
+ /** @deprecated Use runSetup() directly. Kept for backward compat. */
17
+ export const promptLocalOrExit = runSetup;
18
+ /** @deprecated Use runSetup() directly. Kept for backward compat. */
19
+ export const enterLocalModeSetup = runSetup;
20
+ /**
21
+ * First-run project setup. Generates repo ID, writes config, installs skills.
22
+ */
23
+ export async function runSetup(cwd) {
24
+ const projectDir = cwd ?? process.cwd();
25
+ clack.intro("unerr");
26
+ clack.log.step("Project Setup");
27
+ // Generate repo ID from git remote or cwd
28
+ const repoId = await generateRepoId(projectDir);
29
+ // Write config files
30
+ const configDir = join(projectDir, ".unerr");
31
+ mkdirSync(configDir, { recursive: true });
32
+ const configPath = join(configDir, "config.json");
33
+ const settingsPath = join(configDir, "settings.json");
34
+ writeFileSync(configPath, `${JSON.stringify({ repoId }, null, 2)}\n`);
35
+ // Write/merge settings.json
36
+ let existingSettings = {};
37
+ if (existsSync(settingsPath)) {
38
+ try {
39
+ existingSettings = JSON.parse(require("node:fs").readFileSync(settingsPath, "utf-8"));
40
+ }
41
+ catch {
42
+ // Ignore parse errors
43
+ }
44
+ }
45
+ writeFileSync(settingsPath, `${JSON.stringify({ ...existingSettings }, null, 2)}\n`);
46
+ // Install skills from bundled pack
47
+ let skillCount = 0;
48
+ let detectedIde = "unknown";
49
+ try {
50
+ const { detectIde } = await import("../utils/detect.js");
51
+ const { resolveAndInstallSkills } = await import("../skills/resolver.js");
52
+ const ide = await detectIde(projectDir);
53
+ detectedIde = ide;
54
+ const result = await resolveAndInstallSkills({ ide, cwd: projectDir });
55
+ skillCount = result.installed.length;
56
+ if (skillCount > 0) {
57
+ clack.log.success(`🧠 ${skillCount} intelligence skills installed — your AI agent will now use graph tools before reading files`);
58
+ }
59
+ }
60
+ catch {
61
+ // Non-blocking — skills can self-heal on first boot
62
+ }
63
+ // Write MCP config for detected IDE only (project-level, never global)
64
+ // Users add other agents manually via: unerr install <agent>
65
+ let mcpConfigAction = "";
66
+ try {
67
+ const { writeMcpConfig } = await import("../config/mcp-config-writer.js");
68
+ const mcpResult = writeMcpConfig(projectDir, detectedIde);
69
+ if (mcpResult.action === "created") {
70
+ mcpConfigAction = `MCP config written → ${mcpResult.path}`;
71
+ clack.log.success(`🔌 MCP server registered for ${detectedIde} — AI agent will auto-connect to unerr intelligence`);
72
+ }
73
+ else if (mcpResult.action === "updated") {
74
+ mcpConfigAction = `MCP config updated → ${mcpResult.path}`;
75
+ clack.log.success(`🔌 MCP config updated for ${detectedIde} — unerr intelligence now wired in`);
76
+ }
77
+ }
78
+ catch {
79
+ // Non-blocking — MCP config can be written manually
80
+ }
81
+ // Summary
82
+ const summaryLines = [
83
+ `Mode: MCP intelligence proxy (${detectedIde} detected)`,
84
+ `Skills: ${skillCount} agent skills installed`,
85
+ ];
86
+ if (mcpConfigAction) {
87
+ summaryLines.push(`MCP: ${mcpConfigAction}`);
88
+ }
89
+ summaryLines.push("Config: .unerr/config.json");
90
+ summaryLines.push("");
91
+ summaryLines.push("Your AI agent now has: blast radius, community detection,");
92
+ summaryLines.push("convention enforcement, and <5ms graph queries.");
93
+ clack.note(summaryLines.join("\n"), "✅ Intelligence layer configured");
94
+ clack.outro("🚀 Starting intelligence engine...");
95
+ return { action: "setup", repoId };
96
+ }
97
+ // ── Internal Helpers ─────────────────────────────────────────
98
+ async function generateRepoId(cwd) {
99
+ let repoIdentifier = cwd;
100
+ const remote = await getRemoteUrl(cwd);
101
+ if (remote)
102
+ repoIdentifier = remote;
103
+ return createHash("sha256").update(repoIdentifier).digest("hex").slice(0, 12);
104
+ }
105
+ function formatSize(bytes) {
106
+ if (bytes >= 1e9)
107
+ return `${(bytes / 1e9).toFixed(1)}GB`;
108
+ if (bytes >= 1e6)
109
+ return `${(bytes / 1e6).toFixed(0)}MB`;
110
+ return `${bytes}B`;
111
+ }
112
+ async function fetchOllamaModels(baseUrl) {
113
+ try {
114
+ const response = await fetch(`${baseUrl}/api/tags`, {
115
+ signal: AbortSignal.timeout(3000),
116
+ });
117
+ if (!response.ok)
118
+ return [];
119
+ const body = (await response.json());
120
+ if (!body.models || !Array.isArray(body.models))
121
+ return [];
122
+ return body.models.map((m) => ({
123
+ name: m.name,
124
+ size: formatSize(m.size),
125
+ }));
126
+ }
127
+ catch {
128
+ return [];
129
+ }
130
+ }
131
+ /** @internal Retained for future LLM config re-enablement. */
132
+ export async function configureOllama() {
133
+ const defaultUrl = "http://localhost:11434";
134
+ const spinner = clack.spinner();
135
+ spinner.start("Checking for Ollama...");
136
+ let ollamaReachable = false;
137
+ let models = [];
138
+ try {
139
+ const response = await fetch(`${defaultUrl}/api/tags`, {
140
+ signal: AbortSignal.timeout(2000),
141
+ });
142
+ ollamaReachable = response.ok;
143
+ if (ollamaReachable) {
144
+ models = await fetchOllamaModels(defaultUrl);
145
+ }
146
+ }
147
+ catch {
148
+ ollamaReachable = false;
149
+ }
150
+ if (ollamaReachable && models.length > 0) {
151
+ spinner.stop("Ollama detected at localhost:11434");
152
+ const embeddingModel = await clack.select({
153
+ message: "Select embedding model",
154
+ options: models.map((m) => ({
155
+ value: m.name,
156
+ label: m.name,
157
+ hint: m.size,
158
+ })),
159
+ });
160
+ if (clack.isCancel(embeddingModel)) {
161
+ clack.cancel("Setup cancelled.");
162
+ return null;
163
+ }
164
+ const chatModel = await clack.select({
165
+ message: "Select chat model (for 'unerr chat' and enrichment)",
166
+ options: models.map((m) => ({
167
+ value: m.name,
168
+ label: m.name,
169
+ hint: m.size,
170
+ })),
171
+ });
172
+ if (clack.isCancel(chatModel)) {
173
+ clack.cancel("Setup cancelled.");
174
+ return null;
175
+ }
176
+ return {
177
+ provider: "ollama",
178
+ baseUrl: defaultUrl,
179
+ embeddingModel: embeddingModel,
180
+ chatModel: chatModel,
181
+ };
182
+ }
183
+ if (ollamaReachable) {
184
+ spinner.stop("Ollama detected but no models found");
185
+ clack.log.warn("No models installed. Run: ollama pull nomic-embed-text && ollama pull llama3");
186
+ }
187
+ else {
188
+ spinner.stop("Ollama not running");
189
+ clack.log.warn("Install from ollama.com and start it, or enter a custom URL.");
190
+ }
191
+ const baseUrl = await clack.text({
192
+ message: "Ollama URL",
193
+ defaultValue: defaultUrl,
194
+ placeholder: defaultUrl,
195
+ });
196
+ if (clack.isCancel(baseUrl)) {
197
+ clack.cancel("Setup cancelled.");
198
+ return null;
199
+ }
200
+ return {
201
+ provider: "ollama",
202
+ baseUrl: baseUrl || defaultUrl,
203
+ embeddingModel: "nomic-embed-text",
204
+ chatModel: "llama3",
205
+ };
206
+ }
207
+ /** @internal Retained for future LLM config re-enablement. */
208
+ export async function configureOpenAICompatible() {
209
+ const splitChoice = await clack.select({
210
+ message: "Same provider for embedding and inference?",
211
+ options: [
212
+ {
213
+ value: "same",
214
+ label: "Yes — same base URL for both",
215
+ hint: "Single provider, different models",
216
+ },
217
+ {
218
+ value: "split",
219
+ label: "No — different URLs/providers",
220
+ hint: "E.g., Ollama embedding + Fireworks inference",
221
+ },
222
+ ],
223
+ });
224
+ if (clack.isCancel(splitChoice)) {
225
+ clack.cancel("Setup cancelled.");
226
+ return null;
227
+ }
228
+ if (splitChoice === "split") {
229
+ return configureSplitEndpoints();
230
+ }
231
+ const baseUrl = await clack.text({
232
+ message: "API base URL",
233
+ placeholder: "http://localhost:1234/v1",
234
+ });
235
+ if (clack.isCancel(baseUrl)) {
236
+ clack.cancel("Setup cancelled.");
237
+ return null;
238
+ }
239
+ const apiKey = await clack.password({
240
+ message: "API key (leave empty if none)",
241
+ });
242
+ if (clack.isCancel(apiKey)) {
243
+ clack.cancel("Setup cancelled.");
244
+ return null;
245
+ }
246
+ const embeddingModel = await clack.text({
247
+ message: "Embedding model name",
248
+ placeholder: "nomic-embed-text",
249
+ defaultValue: "nomic-embed-text",
250
+ });
251
+ if (clack.isCancel(embeddingModel)) {
252
+ clack.cancel("Setup cancelled.");
253
+ return null;
254
+ }
255
+ const chatModel = await clack.text({
256
+ message: "Chat/inference model name",
257
+ placeholder: "llama3",
258
+ defaultValue: "llama3",
259
+ });
260
+ if (clack.isCancel(chatModel)) {
261
+ clack.cancel("Setup cancelled.");
262
+ return null;
263
+ }
264
+ return {
265
+ provider: "openai-compatible",
266
+ baseUrl: baseUrl,
267
+ ...(apiKey ? { apiKey: apiKey } : {}),
268
+ embeddingModel: embeddingModel,
269
+ chatModel: chatModel,
270
+ };
271
+ }
272
+ async function configureSplitEndpoints() {
273
+ clack.log.step("Embedding endpoint");
274
+ const embBaseUrl = await clack.text({
275
+ message: "Embedding API base URL",
276
+ placeholder: "http://localhost:11434",
277
+ });
278
+ if (clack.isCancel(embBaseUrl)) {
279
+ clack.cancel("Setup cancelled.");
280
+ return null;
281
+ }
282
+ const embApiKey = await clack.password({
283
+ message: "Embedding API key (leave empty if none)",
284
+ });
285
+ if (clack.isCancel(embApiKey)) {
286
+ clack.cancel("Setup cancelled.");
287
+ return null;
288
+ }
289
+ const embModel = await clack.text({
290
+ message: "Embedding model name",
291
+ placeholder: "nomic-embed-text",
292
+ defaultValue: "nomic-embed-text",
293
+ });
294
+ if (clack.isCancel(embModel)) {
295
+ clack.cancel("Setup cancelled.");
296
+ return null;
297
+ }
298
+ clack.log.step("Inference (chat) endpoint");
299
+ const infProvider = await clack.select({
300
+ message: "Inference provider type",
301
+ options: [
302
+ {
303
+ value: "openai-compatible",
304
+ label: "OpenAI-compatible",
305
+ hint: "Fireworks, Together, vLLM, etc.",
306
+ },
307
+ {
308
+ value: "anthropic-direct",
309
+ label: "Anthropic",
310
+ hint: "Claude API",
311
+ },
312
+ { value: "ollama", label: "Ollama", hint: "Local Ollama" },
313
+ ],
314
+ });
315
+ if (clack.isCancel(infProvider)) {
316
+ clack.cancel("Setup cancelled.");
317
+ return null;
318
+ }
319
+ const infBaseUrl = await clack.text({
320
+ message: "Inference API base URL",
321
+ placeholder: infProvider === "anthropic-direct"
322
+ ? "https://api.anthropic.com"
323
+ : infProvider === "ollama"
324
+ ? "http://localhost:11434"
325
+ : "https://api.fireworks.ai/inference/v1",
326
+ });
327
+ if (clack.isCancel(infBaseUrl)) {
328
+ clack.cancel("Setup cancelled.");
329
+ return null;
330
+ }
331
+ const infApiKey = await clack.password({
332
+ message: "Inference API key (leave empty if none)",
333
+ });
334
+ if (clack.isCancel(infApiKey)) {
335
+ clack.cancel("Setup cancelled.");
336
+ return null;
337
+ }
338
+ const infModel = await clack.text({
339
+ message: "Chat/inference model name",
340
+ placeholder: "llama3",
341
+ defaultValue: "llama3",
342
+ });
343
+ if (clack.isCancel(infModel)) {
344
+ clack.cancel("Setup cancelled.");
345
+ return null;
346
+ }
347
+ return {
348
+ provider: "openai-compatible",
349
+ embedding: {
350
+ provider: "openai-compatible",
351
+ baseUrl: embBaseUrl,
352
+ model: embModel,
353
+ ...(embApiKey ? { apiKey: embApiKey } : {}),
354
+ },
355
+ inference: {
356
+ provider: infProvider,
357
+ baseUrl: infBaseUrl,
358
+ model: infModel,
359
+ ...(infApiKey ? { apiKey: infApiKey } : {}),
360
+ },
361
+ };
362
+ }
363
+ /** @internal Retained for future LLM config re-enablement. */
364
+ export async function configureOpenAI() {
365
+ const apiKey = await clack.password({
366
+ message: "OpenAI API key",
367
+ });
368
+ if (clack.isCancel(apiKey)) {
369
+ clack.cancel("Setup cancelled.");
370
+ return null;
371
+ }
372
+ const embeddingModel = await clack.select({
373
+ message: "Embedding model",
374
+ options: [
375
+ {
376
+ value: "text-embedding-3-small",
377
+ label: "text-embedding-3-small",
378
+ hint: "Fast, cheap",
379
+ },
380
+ {
381
+ value: "text-embedding-3-large",
382
+ label: "text-embedding-3-large",
383
+ hint: "Best quality",
384
+ },
385
+ ],
386
+ });
387
+ if (clack.isCancel(embeddingModel)) {
388
+ clack.cancel("Setup cancelled.");
389
+ return null;
390
+ }
391
+ return {
392
+ provider: "openai-compatible",
393
+ baseUrl: "https://api.openai.com/v1",
394
+ apiKey: apiKey,
395
+ embeddingModel: embeddingModel,
396
+ chatModel: "gpt-4o",
397
+ };
398
+ }
399
+ /** @internal Retained for future LLM config re-enablement. */
400
+ export async function configureAnthropic() {
401
+ const apiKey = await clack.password({
402
+ message: "Anthropic API key",
403
+ });
404
+ if (clack.isCancel(apiKey)) {
405
+ clack.cancel("Setup cancelled.");
406
+ return null;
407
+ }
408
+ clack.log.info("Note: Anthropic has no embedding API. Semantic search will use text matching.");
409
+ return {
410
+ provider: "anthropic-direct",
411
+ apiKey: apiKey,
412
+ chatModel: "claude-sonnet-4-20250514",
413
+ };
414
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * unerr skills — Skill download & installation.
3
+ *
4
+ * Installs skills from bundled and local directories into IDE-specific locations.
5
+ *
6
+ * Skill destinations:
7
+ * - Claude Code: .claude/skills/{name}.md (project-level)
8
+ * - Cursor: .cursor/rules/{name}.mdc (as always-on rules)
9
+ * - VS Code: .github/copilot/{name}.md
10
+ * - Windsurf: embedded in .windsurfrules
11
+ * - Zed: .zed/rules/{name}.md
12
+ *
13
+ * Usage:
14
+ * unerr skills install — Install recommended skills for detected IDE
15
+ * unerr skills list — List installed skills
16
+ */
17
+ import { blank, detail, info, pc, section, success } from "../utils/ui.js";
18
+ // ── CLI Command ─────────────────────────────────────────────────────
19
+ export function registerSkillsCommand(program) {
20
+ const skillsCmd = program
21
+ .command("skills")
22
+ .description("Manage unerr skills for your coding agent");
23
+ skillsCmd
24
+ .command("install")
25
+ .description("Download and install recommended skills")
26
+ .option("--ide <ide>", "IDE type (auto-detected if not specified)")
27
+ .action(async (opts) => {
28
+ const { detectIde } = await import("../utils/detect.js");
29
+ const { resolveAndInstallSkills } = await import("../skills/resolver.js");
30
+ const cwd = process.cwd();
31
+ const ide = opts.ide ?? (await detectIde(cwd));
32
+ section("Installing skills (bundled + local)...");
33
+ const result = await resolveAndInstallSkills({
34
+ ide,
35
+ cwd,
36
+ });
37
+ if (result.installed.length > 0) {
38
+ success(`Installed ${result.installed.length} skill${result.installed.length === 1 ? "" : "s"} (source: ${result.source}): ${result.installed.map((n) => pc.bold(n)).join(", ")}`);
39
+ }
40
+ else {
41
+ detail("No skills available.");
42
+ }
43
+ });
44
+ skillsCmd
45
+ .command("list")
46
+ .description("List installed skills")
47
+ .action(async () => {
48
+ const { detectIde } = await import("../utils/detect.js");
49
+ const { listInstalledSkills } = await import("../skills/resolver.js");
50
+ const cwd = process.cwd();
51
+ const ide = await detectIde(cwd);
52
+ const skills = listInstalledSkills(ide, cwd);
53
+ if (skills.length === 0) {
54
+ info("No unerr skills installed.");
55
+ info(`Run ${pc.cyan("unerr skills install")} to get started.`);
56
+ return;
57
+ }
58
+ section(`Installed skills (${skills.length}):`);
59
+ for (const skill of skills) {
60
+ info(` ${pc.bold(skill.name)} ${pc.dim(skill.path)}`);
61
+ }
62
+ blank();
63
+ });
64
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * unerr stats — Show weekly and all-time savings with mechanism breakdown.
3
+ *
4
+ * S8.8 + Layer 10 TF-C.6: Reads ~/.unerr/stats.json and displays formatted
5
+ * report including per-mechanism token attribution.
6
+ */
7
+ import { formatStatsReport, loadStats, } from "../tracking/weekly-accumulator.js";
8
+ export function registerStatsCommand(program) {
9
+ program
10
+ .command("stats")
11
+ .description("Show weekly and all-time token savings with mechanism breakdown")
12
+ .action(() => {
13
+ const stats = loadStats();
14
+ if (stats.allTime.totalSessions === 0) {
15
+ process.stderr.write("\n No sessions recorded yet. Start using unerr to see stats.\n\n");
16
+ return;
17
+ }
18
+ process.stderr.write(formatStatsReport(stats));
19
+ });
20
+ }