@unerr-ai/unerr 0.1.0 → 0.1.2

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 +996 -710
  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 +312 -0
  553. package/dist/ui/assets/index-B-0HTtUR.js +0 -10
@@ -0,0 +1,784 @@
1
+ /**
2
+ * Strategy T8 — framework-aware test result compression.
3
+ * Extracts summary + failure blocks; drops all passing test lines.
4
+ */
5
+ function detectTestFramework(command, lines) {
6
+ if (command) {
7
+ const cmd = command.toLowerCase();
8
+ if (cmd.includes("vitest"))
9
+ return "vitest";
10
+ if (cmd.includes("jest"))
11
+ return "jest";
12
+ if (cmd.includes("pytest") || cmd.includes("python -m pytest"))
13
+ return "pytest";
14
+ if (cmd.includes("cargo test"))
15
+ return "cargo_test";
16
+ if (cmd.includes("go test"))
17
+ return "go_test";
18
+ if (cmd.includes("playwright"))
19
+ return "playwright";
20
+ }
21
+ const sample = lines.slice(0, 50).join("\n");
22
+ // Playwright: "[chromium]" or "[firefox]" or "[webkit]" with ›
23
+ if (/\[(chromium|firefox|webkit)\]\s+›/.test(sample))
24
+ return "playwright";
25
+ if (/✓ .+\d+ms/m.test(sample) || /Test Files\s+\d+/m.test(sample))
26
+ return "vitest";
27
+ if (/^PASS\s+\S+\.(test|spec)\.(ts|js|tsx|jsx)/m.test(sample))
28
+ return "jest";
29
+ if (/^={3,}\s*(test session starts|FAILURES)/m.test(sample))
30
+ return "pytest";
31
+ if (/^test .+ \.\.\. ok$/m.test(sample))
32
+ return "cargo_test";
33
+ if (/^--- (PASS|FAIL): /m.test(sample))
34
+ return "go_test";
35
+ if (/^\d+ examples?, \d+ failures?/m.test(sample) ||
36
+ /^Finished in .+\n\d+ examples?/m.test(sample))
37
+ return "rspec";
38
+ if (/^PHPUnit|^Tests: \d+, Assertions: \d+/m.test(sample))
39
+ return "phpunit";
40
+ if (/^(Passed|Failed)!\s+-\s+(Passed|Failed):/m.test(sample) ||
41
+ /^Total tests: \d+/m.test(sample))
42
+ return "dotnet_test";
43
+ if (/^\d+ tests?, \d+ failures?$/m.test(sample) &&
44
+ /^Finished in /m.test(sample))
45
+ return "elixir_test";
46
+ return "generic";
47
+ }
48
+ const NOISE_RE = /^\[(unerr|warn)\]|^fatal: /;
49
+ function filterNoise(lines) {
50
+ return lines.filter((l) => !NOISE_RE.test(l));
51
+ }
52
+ function parseVitest(lines) {
53
+ const clean = filterNoise(lines);
54
+ const failures = [];
55
+ let passed = 0;
56
+ let failed = 0;
57
+ let skipped = 0;
58
+ let duration = "";
59
+ const summaryLines = [];
60
+ let currentFail = null;
61
+ let inFailSection = false;
62
+ for (const line of clean) {
63
+ if (/^\s*(Test Files|Tests)\s+/.test(line)) {
64
+ summaryLines.push(line.trim());
65
+ const mp = line.match(/(\d+)\s+passed/);
66
+ if (mp)
67
+ passed = Number.parseInt(mp[1], 10);
68
+ const mf = line.match(/(\d+)\s+failed/);
69
+ if (mf)
70
+ failed = Number.parseInt(mf[1], 10);
71
+ const ms = line.match(/(\d+)\s+skipped/);
72
+ if (ms)
73
+ skipped = Number.parseInt(ms[1], 10);
74
+ continue;
75
+ }
76
+ if (/^\s+Duration\s+/.test(line)) {
77
+ duration = line.trim();
78
+ summaryLines.push(duration);
79
+ continue;
80
+ }
81
+ if (/^⎯{3,}/.test(line)) {
82
+ if (currentFail) {
83
+ failures.push(currentFail);
84
+ currentFail = null;
85
+ }
86
+ inFailSection = !inFailSection;
87
+ continue;
88
+ }
89
+ if (/^\s*FAIL\s+/.test(line)) {
90
+ if (currentFail)
91
+ failures.push(currentFail);
92
+ currentFail = { header: line.trim(), lines: [] };
93
+ continue;
94
+ }
95
+ if (currentFail) {
96
+ currentFail.lines.push(line);
97
+ continue;
98
+ }
99
+ // Skip pass lines (✓) — don't store
100
+ if (/^\s*✓\s/.test(line))
101
+ continue;
102
+ // Skip RUN header
103
+ if (/^\s*RUN\s+v/.test(line))
104
+ continue;
105
+ }
106
+ if (currentFail)
107
+ failures.push(currentFail);
108
+ return {
109
+ framework: "vitest",
110
+ passed,
111
+ failed,
112
+ skipped,
113
+ duration,
114
+ failures,
115
+ summaryLines,
116
+ };
117
+ }
118
+ function parseJest(lines) {
119
+ const clean = filterNoise(lines);
120
+ const failures = [];
121
+ let passed = 0;
122
+ let failed = 0;
123
+ let skipped = 0;
124
+ let duration = "";
125
+ const summaryLines = [];
126
+ let currentFail = null;
127
+ for (const line of clean) {
128
+ if (/^Tests?:\s+/.test(line.trim())) {
129
+ summaryLines.push(line.trim());
130
+ const mp = line.match(/(\d+)\s+passed/);
131
+ if (mp)
132
+ passed = Number.parseInt(mp[1], 10);
133
+ const mf = line.match(/(\d+)\s+failed/);
134
+ if (mf)
135
+ failed = Number.parseInt(mf[1], 10);
136
+ const ms = line.match(/(\d+)\s+skipped/);
137
+ if (ms)
138
+ skipped = Number.parseInt(ms[1], 10);
139
+ continue;
140
+ }
141
+ if (/^Time:\s+/.test(line.trim())) {
142
+ duration = line.trim();
143
+ summaryLines.push(duration);
144
+ continue;
145
+ }
146
+ if (/^Test Suites?:\s+/.test(line.trim())) {
147
+ summaryLines.push(line.trim());
148
+ continue;
149
+ }
150
+ if (/^\s*●\s/.test(line) || /^\s*FAIL\s+/.test(line)) {
151
+ if (currentFail)
152
+ failures.push(currentFail);
153
+ currentFail = { header: line.trim(), lines: [] };
154
+ continue;
155
+ }
156
+ if (currentFail) {
157
+ if (line.trim() === "" && currentFail.lines.length > 3) {
158
+ failures.push(currentFail);
159
+ currentFail = null;
160
+ continue;
161
+ }
162
+ currentFail.lines.push(line);
163
+ continue;
164
+ }
165
+ // Skip pass lines
166
+ if (/^\s*(PASS|✓|✓)\s/.test(line))
167
+ continue;
168
+ }
169
+ if (currentFail)
170
+ failures.push(currentFail);
171
+ return {
172
+ framework: "jest",
173
+ passed,
174
+ failed,
175
+ skipped,
176
+ duration,
177
+ failures,
178
+ summaryLines,
179
+ };
180
+ }
181
+ function parsePytest(lines) {
182
+ const failures = [];
183
+ let passed = 0;
184
+ let failed = 0;
185
+ let skipped = 0;
186
+ let duration = "";
187
+ const summaryLines = [];
188
+ let currentFail = null;
189
+ let inFailures = false;
190
+ for (const line of lines) {
191
+ // Final summary: "= N passed, M failed in Xs ="
192
+ const summaryMatch = line.match(/^=+\s*(\d+)\s+passed(?:,\s+(\d+)\s+failed)?(?:,\s+(\d+)\s+skipped)?\s+in\s+(.+?)\s*=+$/);
193
+ if (summaryMatch) {
194
+ passed = Number.parseInt(summaryMatch[1], 10);
195
+ if (summaryMatch[2])
196
+ failed = Number.parseInt(summaryMatch[2], 10);
197
+ if (summaryMatch[3])
198
+ skipped = Number.parseInt(summaryMatch[3], 10);
199
+ duration = summaryMatch[4];
200
+ summaryLines.push(line.trim());
201
+ continue;
202
+ }
203
+ // Short test summary info section header
204
+ if (/^=+\s*short test summary info\s*=+$/i.test(line)) {
205
+ summaryLines.push(line.trim());
206
+ continue;
207
+ }
208
+ // FAILURES section header
209
+ if (/^=+\s*FAILURES\s*=+$/.test(line)) {
210
+ inFailures = true;
211
+ continue;
212
+ }
213
+ // Individual failure header: "___ test_name ___"
214
+ if (/^_{3,}\s+(.+)\s+_{3,}$/.test(line)) {
215
+ if (currentFail)
216
+ failures.push(currentFail);
217
+ const name = line.replace(/^_{3,}\s+/, "").replace(/\s+_{3,}$/, "");
218
+ currentFail = { header: name, lines: [] };
219
+ continue;
220
+ }
221
+ if (currentFail) {
222
+ currentFail.lines.push(line);
223
+ continue;
224
+ }
225
+ // FAILED summary line
226
+ if (/^FAILED\s/.test(line)) {
227
+ summaryLines.push(line.trim());
228
+ }
229
+ }
230
+ if (currentFail)
231
+ failures.push(currentFail);
232
+ return {
233
+ framework: "pytest",
234
+ passed,
235
+ failed,
236
+ skipped,
237
+ duration,
238
+ failures,
239
+ summaryLines,
240
+ };
241
+ }
242
+ function parseCargoTest(lines) {
243
+ const failures = [];
244
+ let passed = 0;
245
+ let failed = 0;
246
+ let skipped = 0;
247
+ let duration = "";
248
+ const summaryLines = [];
249
+ let currentFail = null;
250
+ let inFailures = false;
251
+ for (const line of lines) {
252
+ // Summary: "test result: ok. N passed; M failed; K ignored; ... finished in Xs"
253
+ const summaryMatch = line.match(/^test result: \w+\. (\d+) passed; (\d+) failed; (\d+) ignored;.+?finished in (.+)$/);
254
+ if (summaryMatch) {
255
+ passed = Number.parseInt(summaryMatch[1], 10);
256
+ failed = Number.parseInt(summaryMatch[2], 10);
257
+ skipped = Number.parseInt(summaryMatch[3], 10);
258
+ duration = summaryMatch[4];
259
+ summaryLines.push(line.trim());
260
+ continue;
261
+ }
262
+ // "failures:" section marker
263
+ if (/^failures:$/.test(line.trim())) {
264
+ inFailures = true;
265
+ continue;
266
+ }
267
+ // Failure stdout header: "---- test_name stdout ----"
268
+ if (/^---- (.+) stdout ----$/.test(line)) {
269
+ if (currentFail)
270
+ failures.push(currentFail);
271
+ const name = line.replace(/^---- /, "").replace(/ stdout ----$/, "");
272
+ currentFail = { header: name, lines: [] };
273
+ continue;
274
+ }
275
+ if (currentFail) {
276
+ // End of failure block
277
+ if (/^---- .+ stdout ----$/.test(line) ||
278
+ /^failures:$/.test(line.trim())) {
279
+ failures.push(currentFail);
280
+ currentFail = null;
281
+ }
282
+ else {
283
+ currentFail.lines.push(line);
284
+ }
285
+ continue;
286
+ }
287
+ // Skip passing "test ... ok" lines
288
+ if (/^test .+ \.\.\. ok$/.test(line))
289
+ continue;
290
+ }
291
+ if (currentFail)
292
+ failures.push(currentFail);
293
+ return {
294
+ framework: "cargo_test",
295
+ passed,
296
+ failed,
297
+ skipped,
298
+ duration,
299
+ failures,
300
+ summaryLines,
301
+ };
302
+ }
303
+ function parseGoTest(lines) {
304
+ const failures = [];
305
+ let passed = 0;
306
+ let failed = 0;
307
+ let skipped = 0;
308
+ let duration = "";
309
+ const summaryLines = [];
310
+ let currentFail = null;
311
+ for (const line of lines) {
312
+ // "--- PASS: TestName (0.00s)"
313
+ if (/^--- PASS: /.test(line)) {
314
+ passed++;
315
+ continue;
316
+ }
317
+ // "--- FAIL: TestName (0.01s)"
318
+ const failMatch = /^--- FAIL: (.+?) \((.+?)\)$/.exec(line);
319
+ if (failMatch) {
320
+ if (currentFail)
321
+ failures.push(currentFail);
322
+ failed++;
323
+ currentFail = { header: `FAIL: ${failMatch[1]}`, lines: [] };
324
+ continue;
325
+ }
326
+ // "--- SKIP: TestName (0.00s)"
327
+ if (/^--- SKIP: /.test(line)) {
328
+ skipped++;
329
+ continue;
330
+ }
331
+ // Package summary: "ok \tpackage\t0.012s" or "FAIL\tpackage\t0.045s"
332
+ const pkgMatch = /^(ok|FAIL)\s+(\S+)\s+(.+)$/.exec(line);
333
+ if (pkgMatch) {
334
+ summaryLines.push(line.trim());
335
+ if (!duration)
336
+ duration = pkgMatch[3];
337
+ continue;
338
+ }
339
+ // Indented test output (failure details)
340
+ if (currentFail && /^\s{4,}/.test(line)) {
341
+ currentFail.lines.push(line);
342
+ continue;
343
+ }
344
+ // End of fail block on non-indented line
345
+ if (currentFail && !/^\s{4,}/.test(line)) {
346
+ failures.push(currentFail);
347
+ currentFail = null;
348
+ }
349
+ }
350
+ if (currentFail)
351
+ failures.push(currentFail);
352
+ return {
353
+ framework: "go_test",
354
+ passed,
355
+ failed,
356
+ skipped,
357
+ duration,
358
+ failures,
359
+ summaryLines,
360
+ };
361
+ }
362
+ function parseRspec(lines) {
363
+ const failures = [];
364
+ let passed = 0;
365
+ let failed = 0;
366
+ let skipped = 0;
367
+ let duration = "";
368
+ const summaryLines = [];
369
+ let currentFail = null;
370
+ for (const line of lines) {
371
+ // Summary: "15 examples, 2 failures, 1 pending"
372
+ const summaryMatch = line.match(/^(\d+) examples?, (\d+) failures?(?:,\s+(\d+) pending)?/);
373
+ if (summaryMatch) {
374
+ const total = Number.parseInt(summaryMatch[1], 10);
375
+ failed = Number.parseInt(summaryMatch[2], 10);
376
+ if (summaryMatch[3])
377
+ skipped = Number.parseInt(summaryMatch[3], 10);
378
+ passed = total - failed - skipped;
379
+ summaryLines.push(line.trim());
380
+ continue;
381
+ }
382
+ // Duration: "Finished in 1.23 seconds"
383
+ const durMatch = line.match(/^Finished in (.+)$/);
384
+ if (durMatch) {
385
+ duration = durMatch[1];
386
+ summaryLines.push(line.trim());
387
+ continue;
388
+ }
389
+ // Failure: " 1) ClassName should do something"
390
+ const failMatch = /^\s+\d+\)\s+(.+)$/.exec(line);
391
+ if (failMatch) {
392
+ if (currentFail)
393
+ failures.push(currentFail);
394
+ currentFail = { header: failMatch[1], lines: [] };
395
+ continue;
396
+ }
397
+ if (currentFail) {
398
+ if (line.trim() === "" && currentFail.lines.length > 2) {
399
+ failures.push(currentFail);
400
+ currentFail = null;
401
+ }
402
+ else {
403
+ currentFail.lines.push(line);
404
+ }
405
+ }
406
+ }
407
+ if (currentFail)
408
+ failures.push(currentFail);
409
+ return {
410
+ framework: "rspec",
411
+ passed,
412
+ failed,
413
+ skipped,
414
+ duration,
415
+ failures,
416
+ summaryLines,
417
+ };
418
+ }
419
+ function parsePhpunit(lines) {
420
+ const failures = [];
421
+ let passed = 0;
422
+ let failed = 0;
423
+ let skipped = 0;
424
+ let duration = "";
425
+ const summaryLines = [];
426
+ let currentFail = null;
427
+ for (const line of lines) {
428
+ // "Tests: 50, Assertions: 120, Failures: 2, Errors: 1."
429
+ const summaryMatch = line.match(/^Tests: (\d+), Assertions: (\d+)/);
430
+ if (summaryMatch) {
431
+ const total = Number.parseInt(summaryMatch[1], 10);
432
+ const failMatch = line.match(/Failures: (\d+)/);
433
+ const errMatch = line.match(/Errors: (\d+)/);
434
+ const skipMatch = line.match(/Skipped: (\d+)/);
435
+ failed =
436
+ (failMatch ? Number.parseInt(failMatch[1], 10) : 0) +
437
+ (errMatch ? Number.parseInt(errMatch[1], 10) : 0);
438
+ skipped = skipMatch ? Number.parseInt(skipMatch[1], 10) : 0;
439
+ passed = total - failed - skipped;
440
+ summaryLines.push(line.trim());
441
+ continue;
442
+ }
443
+ // "Time: 00:01.234"
444
+ const durMatch = line.match(/^Time: (.+)$/);
445
+ if (durMatch) {
446
+ duration = durMatch[1];
447
+ summaryLines.push(line.trim());
448
+ continue;
449
+ }
450
+ // Failure header: "1) TestClass::testMethod"
451
+ const failHeader = /^\d+\)\s+(\S+::\S+)/.exec(line);
452
+ if (failHeader) {
453
+ if (currentFail)
454
+ failures.push(currentFail);
455
+ currentFail = { header: failHeader[1], lines: [] };
456
+ continue;
457
+ }
458
+ if (currentFail) {
459
+ if (line.trim() === "" && currentFail.lines.length > 2) {
460
+ failures.push(currentFail);
461
+ currentFail = null;
462
+ }
463
+ else {
464
+ currentFail.lines.push(line);
465
+ }
466
+ }
467
+ }
468
+ if (currentFail)
469
+ failures.push(currentFail);
470
+ return {
471
+ framework: "phpunit",
472
+ passed,
473
+ failed,
474
+ skipped,
475
+ duration,
476
+ failures,
477
+ summaryLines,
478
+ };
479
+ }
480
+ function parseDotnetTest(lines) {
481
+ const failures = [];
482
+ let passed = 0;
483
+ let failed = 0;
484
+ let skipped = 0;
485
+ let duration = "";
486
+ const summaryLines = [];
487
+ let currentFail = null;
488
+ for (const line of lines) {
489
+ // "Total tests: 50 Passed: 48 Failed: 2 Skipped: 0"
490
+ const totalMatch = line.match(/Total tests: (\d+)/);
491
+ if (totalMatch) {
492
+ summaryLines.push(line.trim());
493
+ const pm = line.match(/Passed:\s*(\d+)/);
494
+ const fm = line.match(/Failed:\s*(\d+)/);
495
+ const sm = line.match(/Skipped:\s*(\d+)/);
496
+ if (pm)
497
+ passed = Number.parseInt(pm[1], 10);
498
+ if (fm)
499
+ failed = Number.parseInt(fm[1], 10);
500
+ if (sm)
501
+ skipped = Number.parseInt(sm[1], 10);
502
+ continue;
503
+ }
504
+ // Duration
505
+ const durMatch = line.match(/Duration: (.+)$/);
506
+ if (durMatch) {
507
+ duration = durMatch[1];
508
+ summaryLines.push(line.trim());
509
+ continue;
510
+ }
511
+ // "Failed TestName"
512
+ if (/^\s*Failed\s+\S/.test(line)) {
513
+ if (currentFail)
514
+ failures.push(currentFail);
515
+ currentFail = { header: line.trim(), lines: [] };
516
+ continue;
517
+ }
518
+ if (currentFail) {
519
+ if (/^\s*Failed\s+\S/.test(line) ||
520
+ (line.trim() === "" && currentFail.lines.length > 2)) {
521
+ failures.push(currentFail);
522
+ currentFail = null;
523
+ }
524
+ else {
525
+ currentFail.lines.push(line);
526
+ }
527
+ }
528
+ }
529
+ if (currentFail)
530
+ failures.push(currentFail);
531
+ return {
532
+ framework: "dotnet_test",
533
+ passed,
534
+ failed,
535
+ skipped,
536
+ duration,
537
+ failures,
538
+ summaryLines,
539
+ };
540
+ }
541
+ function parseElixirTest(lines) {
542
+ const failures = [];
543
+ let passed = 0;
544
+ let failed = 0;
545
+ const skipped = 0;
546
+ let duration = "";
547
+ const summaryLines = [];
548
+ let currentFail = null;
549
+ for (const line of lines) {
550
+ // "5 tests, 1 failure"
551
+ const summaryMatch = line.match(/^(\d+) tests?, (\d+) failures?/);
552
+ if (summaryMatch) {
553
+ const total = Number.parseInt(summaryMatch[1], 10);
554
+ failed = Number.parseInt(summaryMatch[2], 10);
555
+ passed = total - failed;
556
+ summaryLines.push(line.trim());
557
+ continue;
558
+ }
559
+ const durMatch = line.match(/^Finished in (.+)$/);
560
+ if (durMatch) {
561
+ duration = durMatch[1];
562
+ summaryLines.push(line.trim());
563
+ continue;
564
+ }
565
+ // Failure: " 1) test description (Module)"
566
+ const failMatch = /^\s+\d+\)\s+test (.+)/.exec(line);
567
+ if (failMatch) {
568
+ if (currentFail)
569
+ failures.push(currentFail);
570
+ currentFail = { header: failMatch[1], lines: [] };
571
+ continue;
572
+ }
573
+ if (currentFail) {
574
+ if (line.trim() === "" && currentFail.lines.length > 2) {
575
+ failures.push(currentFail);
576
+ currentFail = null;
577
+ }
578
+ else {
579
+ currentFail.lines.push(line);
580
+ }
581
+ }
582
+ }
583
+ if (currentFail)
584
+ failures.push(currentFail);
585
+ return {
586
+ framework: "elixir_test",
587
+ passed,
588
+ failed,
589
+ skipped,
590
+ duration,
591
+ failures,
592
+ summaryLines,
593
+ };
594
+ }
595
+ function parsePlaywright(lines) {
596
+ const PASS_RE = /^\s*[✓✔]\s+\d+\s+\[.+\]\s+›/;
597
+ const FAIL_RE = /^\s*[✘✗×]\s+\d+\s+\[.+\]\s+›/;
598
+ const SUMMARY_RE = /^\s*(\d+)\s+(passed|failed|skipped|flaky)/;
599
+ const failures = [];
600
+ let passed = 0;
601
+ let failed = 0;
602
+ let skipped = 0;
603
+ let duration = "";
604
+ const summaryLines = [];
605
+ let currentFail = null;
606
+ let i = 0;
607
+ while (i < lines.length) {
608
+ const line = lines[i];
609
+ // Summary lines at the end: " N passed (duration)"
610
+ const sumMatch = SUMMARY_RE.exec(line);
611
+ if (sumMatch) {
612
+ const count = Number.parseInt(sumMatch[1], 10);
613
+ const type = sumMatch[2];
614
+ if (type === "passed")
615
+ passed = count;
616
+ else if (type === "failed")
617
+ failed = count;
618
+ else if (type === "skipped")
619
+ skipped = count;
620
+ summaryLines.push(line.trim());
621
+ // Extract duration from passed line: "N passed (1.2s)"
622
+ const durMatch = /\(([^)]+)\)/.exec(line);
623
+ if (durMatch && type === "passed")
624
+ duration = durMatch[1];
625
+ i++;
626
+ continue;
627
+ }
628
+ // Failing test line
629
+ if (FAIL_RE.test(line)) {
630
+ if (currentFail)
631
+ failures.push(currentFail);
632
+ currentFail = { header: line.trim(), lines: [] };
633
+ i++;
634
+ // Collect failure details until next test line or end
635
+ while (i < lines.length) {
636
+ const nextLine = lines[i];
637
+ if (PASS_RE.test(nextLine) ||
638
+ FAIL_RE.test(nextLine) ||
639
+ SUMMARY_RE.test(nextLine))
640
+ break;
641
+ currentFail.lines.push(nextLine);
642
+ i++;
643
+ }
644
+ continue;
645
+ }
646
+ // Skip passing test lines
647
+ if (PASS_RE.test(line)) {
648
+ passed = Math.max(passed, 1); // ensure at least counted
649
+ i++;
650
+ continue;
651
+ }
652
+ i++;
653
+ }
654
+ if (currentFail)
655
+ failures.push(currentFail);
656
+ return {
657
+ framework: "playwright",
658
+ passed,
659
+ failed,
660
+ skipped,
661
+ duration,
662
+ failures,
663
+ summaryLines,
664
+ };
665
+ }
666
+ function emitCompressed(parsed) {
667
+ const parts = ["_shell_fmt:test_results"];
668
+ const counts = [];
669
+ if (parsed.passed > 0)
670
+ counts.push(`${parsed.passed} passed`);
671
+ if (parsed.failed > 0)
672
+ counts.push(`${parsed.failed} failed`);
673
+ if (parsed.skipped > 0)
674
+ counts.push(`${parsed.skipped} skipped`);
675
+ const countStr = counts.length > 0 ? counts.join(", ") : "0 tests";
676
+ const durStr = parsed.duration ? ` (${parsed.duration})` : "";
677
+ parts.push(`${parsed.framework}: ${countStr}${durStr}`);
678
+ for (const fail of parsed.failures.slice(0, 10)) {
679
+ parts.push("");
680
+ parts.push(fail.header);
681
+ const truncated = fail.lines.slice(0, 20);
682
+ parts.push(...truncated);
683
+ if (fail.lines.length > 20) {
684
+ parts.push(` … ${fail.lines.length - 20} more lines`);
685
+ }
686
+ }
687
+ if (parsed.failures.length > 10) {
688
+ parts.push(`\n… and ${parsed.failures.length - 10} more failures`);
689
+ }
690
+ if (parsed.summaryLines.length > 0 && parsed.failures.length > 0) {
691
+ parts.push("");
692
+ parts.push(...parsed.summaryLines);
693
+ }
694
+ return parts.join("\n");
695
+ }
696
+ /** Legacy fallback for unrecognized test output. */
697
+ function compressFallback(lines) {
698
+ const kept = [];
699
+ let passStreak = 0;
700
+ const isPassLine = (l) => /\b(passing|PASS|✓|ok\s+\d+)\b/i.test(l) && !/\bfail/i.test(l);
701
+ const isFailLine = (l) => /\b(FAIL|failing|AssertionError|Error:|✗|✕)\b/i.test(l);
702
+ for (const line of lines) {
703
+ if (isFailLine(line)) {
704
+ if (passStreak > 3) {
705
+ kept.push(`… (${passStreak} passing lines collapsed) …`);
706
+ }
707
+ passStreak = 0;
708
+ kept.push(line);
709
+ continue;
710
+ }
711
+ if (isPassLine(line)) {
712
+ passStreak++;
713
+ continue;
714
+ }
715
+ if (passStreak > 3) {
716
+ kept.push(`… (${passStreak} passing lines collapsed) …`);
717
+ passStreak = 0;
718
+ }
719
+ passStreak = 0;
720
+ kept.push(line);
721
+ }
722
+ if (passStreak > 3) {
723
+ kept.push(`… (${passStreak} passing lines collapsed) …`);
724
+ }
725
+ const summary = lines.find((l) => /\b(tests?\s+\d+|passed|failed|suites?)/i.test(l)) ?? "";
726
+ const body = kept.join("\n").trim();
727
+ return summary
728
+ ? `_shell_fmt:test_results\n_summary:${summary}\n${body}`
729
+ : `_shell_fmt:test_results\n${body}`;
730
+ }
731
+ export function compressTestResults(text, command, exitCode) {
732
+ const lines = text.replace(/\r\n/g, "\n").split("\n");
733
+ const framework = detectTestFramework(command, lines);
734
+ if (framework === "generic")
735
+ return compressFallback(lines);
736
+ let parsed;
737
+ try {
738
+ switch (framework) {
739
+ case "vitest":
740
+ case "jest":
741
+ parsed = framework === "vitest" ? parseVitest(lines) : parseJest(lines);
742
+ break;
743
+ case "pytest":
744
+ parsed = parsePytest(lines);
745
+ break;
746
+ case "cargo_test":
747
+ parsed = parseCargoTest(lines);
748
+ break;
749
+ case "go_test":
750
+ parsed = parseGoTest(lines);
751
+ break;
752
+ case "rspec":
753
+ parsed = parseRspec(lines);
754
+ break;
755
+ case "phpunit":
756
+ parsed = parsePhpunit(lines);
757
+ break;
758
+ case "dotnet_test":
759
+ parsed = parseDotnetTest(lines);
760
+ break;
761
+ case "elixir_test":
762
+ parsed = parseElixirTest(lines);
763
+ break;
764
+ case "playwright":
765
+ parsed = parsePlaywright(lines);
766
+ break;
767
+ }
768
+ }
769
+ catch {
770
+ return compressFallback(lines);
771
+ }
772
+ // If parser extracted nothing useful, fall back
773
+ if (parsed.passed === 0 &&
774
+ parsed.failed === 0 &&
775
+ parsed.summaryLines.length === 0) {
776
+ return compressFallback(lines);
777
+ }
778
+ // exitCode 0 with no failures — we can be more aggressive
779
+ if (exitCode === 0 && parsed.failures.length === 0 && parsed.passed > 0) {
780
+ const durStr = parsed.duration ? ` (${parsed.duration})` : "";
781
+ return `_shell_fmt:test_results\n${parsed.framework}: ${parsed.passed} passed${parsed.skipped > 0 ? `, ${parsed.skipped} skipped` : ""}${durStr}`;
782
+ }
783
+ return emitCompressed(parsed);
784
+ }