pi-harness-runtime 1.1.440 → 1.1.441

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 (349) hide show
  1. package/harness/e2e/auto-test-loop.ts +2 -0
  2. package/harness/e2e/browser-scrapers/base-browser-scraper.ts +2 -0
  3. package/harness/e2e/browser-scrapers/chrome-profile-manager.ts +2 -0
  4. package/harness/e2e/browser-scrapers/codex-browser-scraper.ts +2 -0
  5. package/harness/e2e/tools-detector.ts +2 -0
  6. package/harness/key-loader.ts +2 -0
  7. package/harness/langchain/checkpointer.ts +2 -0
  8. package/harness/langchain/cron-cli.ts +2 -0
  9. package/harness/langchain/graph.ts +2 -0
  10. package/harness/notification-center.ts +2 -0
  11. package/harness/secret-provider.ts +2 -0
  12. package/index.ts +2 -0
  13. package/package.json +7 -1
  14. package/packages/a2a-adapter/package.json +1 -1
  15. package/packages/agent-policy/dist/extension.d.ts.map +1 -1
  16. package/packages/agent-policy/dist/extension.js +2 -0
  17. package/packages/agent-policy/dist/extension.js.map +1 -1
  18. package/packages/agent-policy/package.json +1 -1
  19. package/packages/agent-policy/src/extension.ts +2 -0
  20. package/packages/architecture-generator/package.json +1 -1
  21. package/packages/auth/dist/minimax-browser-auth.d.ts.map +1 -1
  22. package/packages/auth/dist/minimax-browser-auth.js +23 -1
  23. package/packages/auth/dist/minimax-browser-auth.js.map +1 -1
  24. package/packages/auth/package.json +1 -1
  25. package/packages/auth/src/minimax-browser-auth.ts +30 -5
  26. package/packages/autonomous-refactor/package.json +1 -1
  27. package/packages/autonomous-runtime/dist/inbox.d.ts.map +1 -1
  28. package/packages/autonomous-runtime/dist/inbox.js +2 -0
  29. package/packages/autonomous-runtime/dist/inbox.js.map +1 -1
  30. package/packages/autonomous-runtime/package.json +1 -1
  31. package/packages/autonomous-runtime/src/inbox.ts +2 -0
  32. package/packages/cache-strategy/package.json +1 -1
  33. package/packages/capability-registry/package.json +1 -1
  34. package/packages/checkpoint/package.json +1 -1
  35. package/packages/cli-plugin-sdk/package.json +1 -1
  36. package/packages/clipboard/dist/src/clipboard.d.ts.map +1 -1
  37. package/packages/clipboard/dist/src/clipboard.js +2 -0
  38. package/packages/clipboard/dist/src/clipboard.js.map +1 -1
  39. package/packages/clipboard/dist/src/copy-sync.d.ts.map +1 -1
  40. package/packages/clipboard/dist/src/copy-sync.js +2 -0
  41. package/packages/clipboard/dist/src/copy-sync.js.map +1 -1
  42. package/packages/clipboard/dist/src/gist-relay.d.ts.map +1 -1
  43. package/packages/clipboard/dist/src/gist-relay.js +2 -0
  44. package/packages/clipboard/dist/src/gist-relay.js.map +1 -1
  45. package/packages/clipboard/package.json +1 -1
  46. package/packages/clipboard/src/clipboard.ts +2 -0
  47. package/packages/clipboard/src/copy-sync.ts +2 -0
  48. package/packages/clipboard/src/gist-relay.ts +2 -0
  49. package/packages/clipboard-plugin/package.json +1 -1
  50. package/packages/code-generation/package.json +1 -1
  51. package/packages/code-review/package.json +1 -1
  52. package/packages/codex-adapter/package.json +1 -1
  53. package/packages/codex-watcher/package.json +1 -1
  54. package/packages/config-capture/package.json +1 -1
  55. package/packages/connection-runtime/package.json +1 -1
  56. package/packages/context-compiler/package.json +1 -1
  57. package/packages/context-discovery/package.json +1 -1
  58. package/packages/context-manager/package.json +1 -1
  59. package/packages/contracts/dist/delegation-store.js +1 -4
  60. package/packages/contracts/dist/workspace-env.js +28 -1
  61. package/packages/contracts/package.json +1 -1
  62. package/packages/contracts/src/delegation-store.ts +9 -4
  63. package/packages/contracts/src/workspace-env.ts +29 -4
  64. package/packages/cookie-sanitizer/package.json +1 -1
  65. package/packages/cost-optimizer/package.json +1 -1
  66. package/packages/dependency-analyzer/package.json +1 -1
  67. package/packages/django-plugin/package.json +1 -1
  68. package/packages/doc-generator/package.json +1 -1
  69. package/packages/durable-review/package.json +1 -1
  70. package/packages/e2e-tester/package.json +1 -1
  71. package/packages/evaluation-engine/package.json +1 -1
  72. package/packages/evaluation-runner/package.json +1 -1
  73. package/packages/event-bus/package.json +1 -1
  74. package/packages/event-sink/package.json +1 -1
  75. package/packages/event-store/dist/src/store.d.ts.map +1 -1
  76. package/packages/event-store/dist/src/store.js +2 -0
  77. package/packages/event-store/dist/src/store.js.map +1 -1
  78. package/packages/event-store/package.json +1 -1
  79. package/packages/event-store/src/store.ts +3 -0
  80. package/packages/experience-replay/package.json +1 -1
  81. package/packages/feedback-collector/package.json +1 -1
  82. package/packages/file-copy-helper/package.json +1 -1
  83. package/packages/framework-detector/package.json +1 -1
  84. package/packages/framework-plugin-sdk/package.json +1 -1
  85. package/packages/frappe-plugin/package.json +1 -1
  86. package/packages/generic-web-plugin/dist/analyzer.d.ts.map +1 -1
  87. package/packages/generic-web-plugin/dist/analyzer.js +2 -0
  88. package/packages/generic-web-plugin/dist/analyzer.js.map +1 -1
  89. package/packages/generic-web-plugin/package.json +1 -1
  90. package/packages/generic-web-plugin/src/analyzer.ts +3 -0
  91. package/packages/health-monitor/package.json +1 -1
  92. package/packages/intent-analyzer/package.json +1 -1
  93. package/packages/jev-judge/package.json +1 -1
  94. package/packages/knowledge-graph/package.json +1 -1
  95. package/packages/knowledge-retrieval/dist/mcp-client.d.ts.map +1 -1
  96. package/packages/knowledge-retrieval/dist/mcp-client.js +0 -1
  97. package/packages/knowledge-retrieval/dist/mcp-client.js.map +1 -1
  98. package/packages/knowledge-retrieval/package.json +1 -4
  99. package/packages/knowledge-retrieval/src/mcp-client.ts +0 -1
  100. package/packages/laravel-plugin/package.json +1 -1
  101. package/packages/learning-engine/package.json +1 -1
  102. package/packages/logging/package.json +1 -1
  103. package/packages/mcp-adapter/dist/server.d.ts.map +1 -1
  104. package/packages/mcp-adapter/dist/server.js +2 -0
  105. package/packages/mcp-adapter/dist/server.js.map +1 -1
  106. package/packages/mcp-adapter/package.json +1 -1
  107. package/packages/mcp-adapter/src/server.ts +3 -0
  108. package/packages/memory-engine/package.json +1 -1
  109. package/packages/milestone-manager/package.json +1 -1
  110. package/packages/model-registry/package.json +1 -1
  111. package/packages/nextjs-plugin/package.json +1 -1
  112. package/packages/notification/package.json +1 -1
  113. package/packages/observability/package.json +1 -1
  114. package/packages/okf-indexer/package.json +1 -1
  115. package/packages/paperclip-integration/dist/index.d.ts.map +1 -1
  116. package/packages/paperclip-integration/dist/index.js +2 -0
  117. package/packages/paperclip-integration/dist/index.js.map +1 -1
  118. package/packages/paperclip-integration/package.json +1 -1
  119. package/packages/paperclip-integration/src/index.ts +2 -0
  120. package/packages/performance-optimizer/package.json +1 -1
  121. package/packages/permission-mode/package.json +1 -1
  122. package/packages/privilege-broker/dist/audit.d.ts.map +1 -1
  123. package/packages/privilege-broker/dist/audit.js +2 -0
  124. package/packages/privilege-broker/dist/audit.js.map +1 -1
  125. package/packages/privilege-broker/package.json +1 -1
  126. package/packages/privilege-broker/src/audit.ts +2 -0
  127. package/packages/project-analyzer/package.json +1 -1
  128. package/packages/project-bootstrap/package.json +1 -1
  129. package/packages/projection-engine/package.json +1 -1
  130. package/packages/prompt-compiler/dist/compiler.d.ts.map +1 -1
  131. package/packages/prompt-compiler/dist/compiler.js +2 -0
  132. package/packages/prompt-compiler/dist/compiler.js.map +1 -1
  133. package/packages/prompt-compiler/package.json +1 -1
  134. package/packages/prompt-compiler/src/compiler.ts +2 -0
  135. package/packages/prompt-versioning/package.json +1 -1
  136. package/packages/provider-adapter-sdk/package.json +1 -1
  137. package/packages/provider-router/package.json +1 -1
  138. package/packages/provider-selector/package.json +1 -1
  139. package/packages/providers/package.json +1 -1
  140. package/packages/qdrant-skills/package.json +1 -1
  141. package/packages/quota-manager/package.json +1 -1
  142. package/packages/rate-limiter/package.json +1 -1
  143. package/packages/react-vite-plugin/package.json +1 -1
  144. package/packages/relay/package.json +1 -1
  145. package/packages/release-manager/package.json +1 -1
  146. package/packages/requirement-compiler/package.json +1 -1
  147. package/packages/runtime/package.json +1 -1
  148. package/packages/scheduler/package.json +1 -1
  149. package/packages/scheduler-adapter/package.json +1 -1
  150. package/packages/session/package.json +1 -1
  151. package/packages/session-api/package.json +1 -1
  152. package/packages/session-export/package.json +1 -1
  153. package/packages/shared-context/package.json +1 -1
  154. package/packages/skill-mcp-client/dist/client.d.ts.map +1 -1
  155. package/packages/skill-mcp-client/dist/client.js +0 -1
  156. package/packages/skill-mcp-client/dist/client.js.map +1 -1
  157. package/packages/skill-mcp-client/package.json +1 -4
  158. package/packages/skill-mcp-client/src/client.ts +0 -1
  159. package/packages/skill-registry/package.json +1 -1
  160. package/packages/skills/dist/parser.d.ts.map +1 -1
  161. package/packages/skills/dist/parser.js +2 -0
  162. package/packages/skills/dist/parser.js.map +1 -1
  163. package/packages/skills/dist/skill-versioning.d.ts.map +1 -1
  164. package/packages/skills/dist/skill-versioning.js +2 -0
  165. package/packages/skills/dist/skill-versioning.js.map +1 -1
  166. package/packages/skills/package.json +1 -1
  167. package/packages/skills/src/parser.ts +3 -0
  168. package/packages/skills/src/skill-versioning.ts +2 -0
  169. package/packages/sprint-planner/package.json +1 -1
  170. package/packages/subscription-engine/package.json +1 -1
  171. package/packages/task-compiler/package.json +1 -1
  172. package/packages/tencentdb-memory/package.json +1 -1
  173. package/packages/tencentdb-sync/package.json +1 -1
  174. package/packages/test-data-generator/package.json +1 -1
  175. package/packages/test-generator/package.json +1 -1
  176. package/packages/todo-bd-sync/package.json +1 -1
  177. package/packages/token-estimation/package.json +1 -1
  178. package/packages/token-optimizer/package.json +1 -1
  179. package/packages/tooling-preference/package.json +1 -1
  180. package/packages/trajectory/package.json +1 -1
  181. package/packages/tui/package.json +1 -1
  182. package/packages/two-phase-review/package.json +1 -1
  183. package/packages/types/package.json +1 -1
  184. package/packages/voice-api/package.json +1 -1
  185. package/packages/webmcp-tester/dist/index.js +0 -2
  186. package/packages/webmcp-tester/package.json +1 -1
  187. package/packages/webmcp-tester/src/index.ts +0 -3
  188. package/packages/wiki/package.json +1 -1
  189. package/packages/workflow-events/package.json +1 -1
  190. package/packages/workspace-scanner/package.json +1 -1
  191. package/packages/worktree/package.json +1 -1
  192. package/packages/write-review/dist/trigger.d.ts.map +1 -1
  193. package/packages/write-review/dist/trigger.js +1 -2
  194. package/packages/write-review/dist/trigger.js.map +1 -1
  195. package/packages/write-review/package.json +1 -1
  196. package/packages/write-review/src/trigger.ts +1 -2
  197. package/scripts/lib/runtime-imports.ts +189 -3
  198. package/scripts/telegram-webhook-server.ts +2 -0
  199. package/scripts/verify-package-contents.ts +148 -1
  200. package/harness/e2e/tools-detector.test.ts +0 -155
  201. package/harness/glm-quota-countdown.test.ts +0 -323
  202. package/harness/langchain/agents.test.ts +0 -39
  203. package/harness/langchain/checkpointer.test.ts +0 -243
  204. package/harness/langchain/daemon.test.ts +0 -459
  205. package/harness/langchain/model-router.test.ts +0 -191
  206. package/harness/langchain/ping-pong-middleware.test.ts +0 -69
  207. package/harness/langchain/scoreboard.test.ts +0 -267
  208. package/harness/langchain/status-line.test.ts +0 -106
  209. package/harness/langchain/surge.test.ts +0 -467
  210. package/harness/langchain/widget.test.ts +0 -251
  211. package/harness/skill-sync.test.ts +0 -57
  212. package/harness/ssh-detach-interceptor.test.ts +0 -263
  213. package/harness/ssh-hang-recovery.test.ts +0 -86
  214. package/packages/a2a-adapter/test/a2a.test.ts +0 -151
  215. package/packages/agent-policy/test/interlock.test.ts +0 -101
  216. package/packages/agent-policy/test/policy-retention.test.ts +0 -380
  217. package/packages/agent-policy/test/policy.test.ts +0 -387
  218. package/packages/auth/test/auth.test.ts +0 -238
  219. package/packages/autonomous-refactor/test/refactor.test.ts +0 -202
  220. package/packages/autonomous-runtime/test/types.test.ts +0 -95
  221. package/packages/cache-strategy/test/cache.test.ts +0 -137
  222. package/packages/capability-registry/test/registry.test.ts +0 -204
  223. package/packages/checkpoint/test/engine.test.ts +0 -265
  224. package/packages/cli-plugin-sdk/test/cli.test.ts +0 -45
  225. package/packages/code-generation/test/generator.test.ts +0 -238
  226. package/packages/code-review/test/engine.test.ts +0 -302
  227. package/packages/codex-adapter/test/provider.test.ts +0 -142
  228. package/packages/codex-watcher/test/watch.test.ts +0 -453
  229. package/packages/context-compiler/test/context-compiler.test.ts +0 -746
  230. package/packages/context-manager/test/context.test.ts +0 -198
  231. package/packages/contracts/test/delegation.test.ts +0 -350
  232. package/packages/contracts/test/workspace-env.test.ts +0 -802
  233. package/packages/cookie-sanitizer/test/infer.test.ts +0 -110
  234. package/packages/cookie-sanitizer/test/normalize.test.ts +0 -113
  235. package/packages/cookie-sanitizer/test/parse.test.ts +0 -204
  236. package/packages/cookie-sanitizer/test/sync.test.ts +0 -237
  237. package/packages/cookie-sanitizer/test/watcher.test.ts +0 -27
  238. package/packages/cost-optimizer/test/cost-optimizer.test.ts +0 -438
  239. package/packages/dependency-analyzer/test/analyzer.test.ts +0 -49
  240. package/packages/django-plugin/test/analyzer.test.ts +0 -195
  241. package/packages/doc-generator/test/docs.test.ts +0 -168
  242. package/packages/durable-review/test/acceptance.test.ts +0 -357
  243. package/packages/durable-review/test/smoke.test.ts +0 -107
  244. package/packages/evaluation-engine/test/engine.test.ts +0 -277
  245. package/packages/evaluation-runner/test/runner.test.ts +0 -168
  246. package/packages/event-bus/test/bus.test.ts +0 -100
  247. package/packages/event-store/test/store.test.ts +0 -115
  248. package/packages/experience-replay/test/replay.test.ts +0 -267
  249. package/packages/feedback-collector/test/collector.test.ts +0 -142
  250. package/packages/framework-detector/test/detector.test.ts +0 -75
  251. package/packages/framework-plugin-sdk/test/manager.test.ts +0 -320
  252. package/packages/frappe-plugin/test/analyzer.test.ts +0 -250
  253. package/packages/generic-web-plugin/test/analyzer.test.ts +0 -134
  254. package/packages/health-monitor/test/health.test.ts +0 -231
  255. package/packages/intent-analyzer/test/analyzer.test.ts +0 -72
  256. package/packages/intent-analyzer/test/ping-pong.test.ts +0 -96
  257. package/packages/jev-judge/tests/auto-continue-context.test.ts +0 -280
  258. package/packages/jev-judge/tests/continuation-controller.test.ts +0 -1396
  259. package/packages/jev-judge/tests/jev-provider-chain.test.ts +0 -536
  260. package/packages/jev-judge/tests/outcome-application.test.ts +0 -132
  261. package/packages/jev-judge/tests/question-risk.test.ts +0 -129
  262. package/packages/jev-judge/tests/typesafe-provider.test.ts +0 -640
  263. package/packages/jev-judge/tests/validation-ledger.test.ts +0 -181
  264. package/packages/jev-judge/tests/validation-plan.test.ts +0 -170
  265. package/packages/jev-judge/tests/validation-tie-breaker.test.ts +0 -88
  266. package/packages/laravel-plugin/test/analyzer.test.ts +0 -220
  267. package/packages/learning-engine/test/engine.test.ts +0 -331
  268. package/packages/logging/test/buffer.test.ts +0 -44
  269. package/packages/logging/test/classification.test.ts +0 -137
  270. package/packages/logging/test/config.test.ts +0 -97
  271. package/packages/logging/test/fanout.test.ts +0 -186
  272. package/packages/logging/test/identity-transport.test.ts +0 -197
  273. package/packages/logging/test/incidents.test.ts +0 -404
  274. package/packages/logging/test/ingest-schema.test.ts +0 -184
  275. package/packages/logging/test/integration.test.ts +0 -140
  276. package/packages/logging/test/log-http.test.ts +0 -246
  277. package/packages/logging/test/redact.test.ts +0 -109
  278. package/packages/logging/test/sampler.test.ts +0 -57
  279. package/packages/logging/test/server.test.ts +0 -444
  280. package/packages/logging/test/shipper.test.ts +0 -152
  281. package/packages/logging/test/spool.test.ts +0 -96
  282. package/packages/mcp-adapter/test/server.test.ts +0 -91
  283. package/packages/memory-engine/test/engine.test.ts +0 -456
  284. package/packages/model-registry/test/registry.test.ts +0 -342
  285. package/packages/nextjs-plugin/test/analyzer.test.ts +0 -149
  286. package/packages/notification/test/approval-payload.test.ts +0 -269
  287. package/packages/notification/test/detail-format.test.ts +0 -106
  288. package/packages/notification/test/notification.test.ts +0 -375
  289. package/packages/notification/test/pending-question-lifecycle.test.ts +0 -195
  290. package/packages/notification/test/pending-question.test.ts +0 -331
  291. package/packages/notification/test/tooling-proposal-payload.test.ts +0 -212
  292. package/packages/observability/test/observability.test.ts +0 -1350
  293. package/packages/performance-optimizer/test/optimizer.test.ts +0 -267
  294. package/packages/project-analyzer/test/index.test.ts +0 -1719
  295. package/packages/prompt-compiler/test/prompt-compiler.test.ts +0 -813
  296. package/packages/prompt-versioning/test/versioning.test.ts +0 -112
  297. package/packages/provider-adapter-sdk/test/sdk.test.ts +0 -220
  298. package/packages/provider-router/test/provider-router.test.ts +0 -405
  299. package/packages/provider-selector/test/selector.test.ts +0 -192
  300. package/packages/providers/test/providers.test.ts +0 -225
  301. package/packages/qdrant-skills/test/collection-info.test.ts +0 -165
  302. package/packages/qdrant-skills/test/embedder-batch.test.ts +0 -184
  303. package/packages/qdrant-skills/test/embedder.test.ts +0 -97
  304. package/packages/quota-manager/test/quota.test.ts +0 -432
  305. package/packages/rate-limiter/test/limiter.test.ts +0 -128
  306. package/packages/react-vite-plugin/test/analyzer.test.ts +0 -139
  307. package/packages/relay/test/client.test.ts +0 -446
  308. package/packages/relay/test/relay-e2e.test.ts +0 -299
  309. package/packages/relay/test/relay-endpoint.test.ts +0 -278
  310. package/packages/release-manager/test/release.test.ts +0 -215
  311. package/packages/requirement-compiler/test/requirement-compiler.test.ts +0 -743
  312. package/packages/runtime/test/runtime-api.test.ts +0 -169
  313. package/packages/runtime/test/runtime.test.ts +0 -297
  314. package/packages/scheduler/test/scheduler.test.ts +0 -125
  315. package/packages/session/test/manager.test.ts +0 -233
  316. package/packages/shared-context/test/shared-context.test.ts +0 -114
  317. package/packages/skill-registry/test/registry.test.ts +0 -508
  318. package/packages/skills/test/init-skills.test.ts +0 -114
  319. package/packages/skills/test/remote-skills.test.ts +0 -360
  320. package/packages/skills/test/remote-source.test.ts +0 -248
  321. package/packages/skills/test/sanitize.test.ts +0 -250
  322. package/packages/skills/test/vector-indexing.test.ts +0 -205
  323. package/packages/skills/test/vector-schema.test.ts +0 -180
  324. package/packages/skills/test/vector-threshold.test.ts +0 -108
  325. package/packages/sprint-planner/test/planner.test.ts +0 -187
  326. package/packages/task-compiler/test/task-compiler.test.ts +0 -628
  327. package/packages/test-data-generator/test/generator.test.ts +0 -265
  328. package/packages/test-generator/test/generator.test.ts +0 -156
  329. package/packages/token-estimation/test/token-estimation.test.ts +0 -207
  330. package/packages/token-optimizer/test/optimizer.test.ts +0 -141
  331. package/packages/tooling-preference/tests/changed-files.test.ts +0 -124
  332. package/packages/tooling-preference/tests/detect.test.ts +0 -188
  333. package/packages/tooling-preference/tests/proposal.test.ts +0 -107
  334. package/packages/tooling-preference/tests/quality-check.test.ts +0 -272
  335. package/packages/tooling-preference/tests/registry.test.ts +0 -51
  336. package/packages/tooling-preference/tests/store.test.ts +0 -99
  337. package/packages/trajectory/test/store.test.ts +0 -250
  338. package/packages/tui/test/harness-footer.test.ts +0 -559
  339. package/packages/tui/test/harness-header.test.ts +0 -590
  340. package/packages/two-phase-review/test/classify.test.ts +0 -102
  341. package/packages/two-phase-review/test/helpers.ts +0 -72
  342. package/packages/two-phase-review/test/rules.test.ts +0 -150
  343. package/packages/two-phase-review/test/runtime.test.ts +0 -362
  344. package/packages/two-phase-review/test/scope.test.ts +0 -186
  345. package/packages/two-phase-review/test/signals.test.ts +0 -183
  346. package/packages/two-phase-review/test/state.test.ts +0 -201
  347. package/packages/wiki/test/basic.test.ts +0 -242
  348. package/packages/workspace-scanner/test/scanner.test.ts +0 -43
  349. package/packages/worktree/test/worktree.test.ts +0 -163
@@ -1,186 +0,0 @@
1
- /**
2
- * The review scope.
3
- *
4
- * The scope is the diff of the task, never the whole repository. A workspace
5
- * without Git has no honest scope, so nothing is reviewed.
6
- */
7
-
8
- import { describe, it, expect } from "bun:test";
9
- import { execFileSync } from "node:child_process";
10
- import { mkdirSync, writeFileSync } from "node:fs";
11
- import { join } from "node:path";
12
- import {
13
- chunkScope,
14
- collectScope,
15
- countModules,
16
- currentRevision,
17
- isGitRepository,
18
- isReviewablePath,
19
- moduleKey,
20
- parseNumstat,
21
- shouldChunkScope,
22
- } from "../src/scope.js";
23
- import { withPlainTempDir, withTempDir } from "./helpers.js";
24
-
25
- function git(root: string, ...args: string[]): void {
26
- // The ambient Git configuration must not decide whether the fixture works:
27
- // a global identity, a signing key or a hook would break the commit.
28
- try {
29
- execFileSync(
30
- "git",
31
- [
32
- "-c",
33
- "user.email=test@example.com",
34
- "-c",
35
- "user.name=Test",
36
- "-c",
37
- "commit.gpgsign=false",
38
- "-c",
39
- "core.hooksPath=/dev/null",
40
- ...args,
41
- ],
42
- { cwd: root, stdio: "pipe" },
43
- );
44
- } catch (error) {
45
- const detail = error as { stderr?: Buffer; status?: number; signal?: string; message?: string };
46
- const stderr = detail.stderr?.toString() ?? "";
47
- throw new Error(
48
- `git ${args.join(" ")} failed in ${root}: status=${detail.status} signal=${detail.signal} message=${detail.message} stderr=${stderr}`,
49
- );
50
- }
51
- }
52
-
53
- /** A fresh Git repository with one commit. */
54
- function withRepository(body: (root: string) => void): void {
55
- withTempDir("scope", (root) => {
56
- git(root, "init", "-q");
57
- body(root);
58
- });
59
- }
60
-
61
- describe("isReviewablePath", () => {
62
- it("keeps the source files", () => {
63
- expect(isReviewablePath("packages/notification/src/index.ts")).toBe(true);
64
- expect(isReviewablePath("index.ts")).toBe(true);
65
- });
66
-
67
- it("drops the build output", () => {
68
- expect(isReviewablePath("dist/index.js")).toBe(false);
69
- expect(isReviewablePath("node_modules/x/index.js")).toBe(false);
70
- expect(isReviewablePath("coverage/lcov.info")).toBe(false);
71
- });
72
-
73
- it("drops the build output of a nested module", () => {
74
- expect(isReviewablePath("packages/foo/dist/index.js")).toBe(false);
75
- expect(isReviewablePath("apps/x/coverage/lcov.info")).toBe(false);
76
- expect(isReviewablePath("services/x/vendor/lib.js")).toBe(false);
77
- expect(isReviewablePath("packages/foo/node_modules/x/index.js")).toBe(false);
78
- });
79
- });
80
-
81
- describe("moduleKey", () => {
82
- it("names the module of a file", () => {
83
- expect(moduleKey("packages/notification/src/index.ts")).toBe("packages/notification");
84
- expect(moduleKey("harness/wiki-integration.ts")).toBe("harness");
85
- expect(moduleKey("index.ts")).toBe("root");
86
- });
87
- });
88
-
89
- describe("collectScope", () => {
90
- it("reads the diff since the start revision", () => {
91
- withRepository((root) => {
92
- mkdirSync(join(root, "packages", "notification"), { recursive: true });
93
- writeFileSync(join(root, "packages", "notification", "index.ts"), "export const a = 1;\n");
94
- git(root, "add", "-A");
95
- git(root, "commit", "-qm", "base");
96
- const start = currentRevision(root);
97
- expect(start).toBeTruthy();
98
-
99
- writeFileSync(join(root, "packages", "notification", "index.ts"), "export const a = 2;\n");
100
- writeFileSync(join(root, "packages", "notification", "new.ts"), "export const b = 1;\n");
101
-
102
- const scope = collectScope(root, start);
103
- expect(scope.detected).toBe(true);
104
- expect(scope.files).toContain("packages/notification/index.ts");
105
- expect(scope.files).toContain("packages/notification/new.ts");
106
- expect(scope.metrics.files).toBe(2);
107
- expect(scope.metrics.modules).toBe(1);
108
- });
109
- });
110
-
111
- it("ignores the build output", () => {
112
- withRepository((root) => {
113
- mkdirSync(join(root, "dist"), { recursive: true });
114
- writeFileSync(join(root, "dist", "index.js"), "built\n");
115
- git(root, "add", "-A");
116
- git(root, "commit", "-qm", "base");
117
- const start = currentRevision(root);
118
- writeFileSync(join(root, "dist", "index.js"), "built again\n");
119
-
120
- const scope = collectScope(root, start);
121
- expect(scope.files).not.toContain("dist/index.js");
122
- });
123
- });
124
-
125
- it("reports no scope without Git", () => {
126
- withPlainTempDir("plain", (plain) => {
127
- expect(isGitRepository(plain)).toBe(false);
128
- const scope = collectScope(plain, null);
129
- expect(scope.detected).toBe(false);
130
- expect(scope.files).toEqual([]);
131
- });
132
- });
133
-
134
- it("reports no scope when the start revision is gone", () => {
135
- withRepository((root) => {
136
- // A missing baseline would silently reduce the scope to the last
137
- // commit, so the scope is empty instead of incomplete.
138
- const scope = collectScope(root, "0000000000000000000000000000000000000000");
139
- expect(scope.detected).toBe(false);
140
- expect(scope.files).toEqual([]);
141
- expect(scope.reason).toMatch(/does not exist/);
142
- });
143
- });
144
- });
145
-
146
- describe("parseNumstat", () => {
147
- it("adds the changed lines", () => {
148
- expect(parseNumstat("3\t1\tindex.ts\n0\t0\tother.ts\n")).toBe(4);
149
- });
150
- });
151
-
152
- describe("chunkScope", () => {
153
- it("splits the scope by module", () => {
154
- const chunks = chunkScope([
155
- "packages/notification/src/a.ts",
156
- "packages/notification/src/b.ts",
157
- "packages/jev-judge/src/c.ts",
158
- ]);
159
- expect(chunks).toHaveLength(2);
160
- expect(chunks[0]?.id).toBe("chunk-1");
161
- expect(chunks.map((chunk) => chunk.files.length)).toEqual([2, 1]);
162
- });
163
-
164
- it("splits a big module into several chunks", () => {
165
- const files = Array.from({ length: 7 }, (_, index) => `packages/x/src/file-${index}.ts`);
166
- const chunks = chunkScope(files, { maxFilesPerChunk: 3 });
167
- expect(chunks).toHaveLength(3);
168
- expect(chunks[2]?.files).toHaveLength(1);
169
- });
170
-
171
- it("returns nothing for an empty scope", () => {
172
- expect(chunkScope([])).toEqual([]);
173
- });
174
- });
175
-
176
- describe("countModules and shouldChunkScope", () => {
177
- it("counts the modules", () => {
178
- expect(countModules(["packages/a/x.ts", "packages/b/y.ts", "packages/a/z.ts"])).toBe(2);
179
- });
180
-
181
- it("measures the scope instead of assuming it", () => {
182
- expect(shouldChunkScope({ files: 3, modules: 1, changedLines: 100 })).toBe(false);
183
- expect(shouldChunkScope({ files: 20, modules: 1, changedLines: 100 })).toBe(true);
184
- expect(shouldChunkScope({ files: 3, modules: 5, changedLines: 100 })).toBe(true);
185
- });
186
- });
@@ -1,183 +0,0 @@
1
- /**
2
- * Review signals.
3
- *
4
- * A signal is only raised for a comprehensive review. An ordinary task-level
5
- * check (a type error of the file that is edited right now) stays actionable
6
- * and must not be deferred.
7
- */
8
-
9
- import { describe, it, expect } from "bun:test";
10
- import {
11
- detectReviewInvocation,
12
- dispatchAgentName,
13
- explicitReviewRequest,
14
- extractFiles,
15
- isComprehensiveReviewTool,
16
- isReviewCommand,
17
- mergeSignals,
18
- summarizeSignals,
19
- } from "../src/signals.js";
20
- import type { ReviewSignal } from "../src/types.js";
21
-
22
- describe("isComprehensiveReviewTool", () => {
23
- it("knows the review tools", () => {
24
- expect(isComprehensiveReviewTool("code-reviewer")).toBe(true);
25
- expect(isComprehensiveReviewTool("code_reviewer")).toBe(true);
26
- expect(isComprehensiveReviewTool("differential-review")).toBe(true);
27
- expect(isComprehensiveReviewTool("semgrep")).toBe(true);
28
- expect(isComprehensiveReviewTool("codeql")).toBe(true);
29
- });
30
-
31
- it("matches a namespaced tool by its bare name", () => {
32
- expect(isComprehensiveReviewTool("mcp__pi__code-review")).toBe(true);
33
- });
34
-
35
- it("does not match a tool that only mentions a review", () => {
36
- expect(isComprehensiveReviewTool("read_audit_log")).toBe(false);
37
- expect(isComprehensiveReviewTool("review_status")).toBe(false);
38
- expect(isComprehensiveReviewTool("semgrep_scan")).toBe(false);
39
- });
40
-
41
- it("leaves the task-level checks alone", () => {
42
- expect(isComprehensiveReviewTool("lens_diagnostics")).toBe(false);
43
- expect(isComprehensiveReviewTool("bash")).toBe(false);
44
- expect(isComprehensiveReviewTool("edit")).toBe(false);
45
- expect(isComprehensiveReviewTool("todo")).toBe(false);
46
- expect(isComprehensiveReviewTool("read")).toBe(false);
47
- });
48
-
49
- it("accepts extra patterns from the deployment", () => {
50
- expect(isComprehensiveReviewTool("house_review", ["house_review"])).toBe(true);
51
- });
52
- });
53
-
54
- describe("isReviewCommand", () => {
55
- it("knows a review runner", () => {
56
- expect(isReviewCommand("bun run code-review")).toBe(true);
57
- expect(isReviewCommand("semgrep scan --config auto")).toBe(true);
58
- expect(isReviewCommand("npx differential-review")).toBe(true);
59
- expect(isReviewCommand("bun test && code-review")).toBe(true);
60
- });
61
-
62
- it("ignores an ordinary command", () => {
63
- expect(isReviewCommand("bun test")).toBe(false);
64
- expect(isReviewCommand("npx biome check index.ts")).toBe(false);
65
- });
66
-
67
- it("ignores a runner that is only mentioned", () => {
68
- expect(isReviewCommand("echo code-review")).toBe(false);
69
- expect(isReviewCommand("grep security-review README.md")).toBe(false);
70
- expect(isReviewCommand("# semgrep scan")).toBe(false);
71
- expect(isReviewCommand("cat notes.md | grep semgrep")).toBe(false);
72
- });
73
- });
74
-
75
- describe("dispatchAgentName", () => {
76
- it("reads the agent of a dispatch tool", () => {
77
- expect(dispatchAgentName("subagent", { agent: "code-reviewer" })).toBe("code-reviewer");
78
- expect(dispatchAgentName("subagent", { agent: "researcher" })).toBe("researcher");
79
- expect(dispatchAgentName("bash", { command: "ls" })).toBe("");
80
- });
81
- });
82
-
83
- describe("detectReviewInvocation", () => {
84
- it("recognizes a review tool", () => {
85
- const invocation = detectReviewInvocation("code-reviewer", { files: ["index.ts"] });
86
- expect(invocation?.source).toBe("code-reviewer");
87
- expect(invocation?.files).toEqual(["index.ts"]);
88
- });
89
-
90
- it("recognizes a reviewer that was dispatched as an agent", () => {
91
- const invocation = detectReviewInvocation("subagent", { agent: "code-reviewer" });
92
- expect(invocation?.source).toBe("code-reviewer");
93
- });
94
-
95
- it("recognizes a review runner in the shell", () => {
96
- const invocation = detectReviewInvocation("bash", {
97
- command: "bun run code-review --scope packages/notification",
98
- });
99
- expect(invocation?.source).toBe("bash");
100
- expect(invocation?.reason).toContain("code-review");
101
- });
102
-
103
- it("does not raise a signal for a task-level check", () => {
104
- expect(detectReviewInvocation("lens_diagnostics", { paths: ["index.ts"] })).toBeNull();
105
- expect(detectReviewInvocation("bash", { command: "npx tsc --noEmit" })).toBeNull();
106
- expect(detectReviewInvocation("edit", { path: "index.ts" })).toBeNull();
107
- });
108
- });
109
-
110
- describe("extractFiles", () => {
111
- it("reads the files of a tool input", () => {
112
- expect(extractFiles("code-reviewer", { files: ["a.ts", "b.ts"] })).toEqual(["a.ts", "b.ts"]);
113
- });
114
-
115
- it("reads the files of a shell command", () => {
116
- const files = extractFiles("bash", { command: "eslint packages/notification/index.ts" });
117
- expect(files).toContain("packages/notification/index.ts");
118
- });
119
- });
120
-
121
- describe("explicitReviewRequest", () => {
122
- it("sees an explicit request of the user", () => {
123
- expect(explicitReviewRequest("please review the whole diff now")).toBe(true);
124
- expect(explicitReviewRequest("run an audit of the repository")).toBe(true);
125
- expect(explicitReviewRequest("review the task diff")).toBe(true);
126
- });
127
-
128
- it("sees no request in an ordinary message", () => {
129
- expect(explicitReviewRequest("fix the failing test")).toBe(false);
130
- expect(explicitReviewRequest("")).toBe(false);
131
- expect(explicitReviewRequest("the review notes mention a stale cache")).toBe(false);
132
- });
133
-
134
- it("respects a negation", () => {
135
- expect(explicitReviewRequest("do not review yet, continue the implementation")).toBe(false);
136
- expect(explicitReviewRequest("no review for now")).toBe(false);
137
- expect(explicitReviewRequest("skip the audit")).toBe(false);
138
- });
139
-
140
- it("reads every sentence on its own", () => {
141
- expect(explicitReviewRequest("Do not review yet. Please review the diff afterwards.")).toBe(
142
- true,
143
- );
144
- });
145
- });
146
-
147
- describe("mergeSignals", () => {
148
- const signal: ReviewSignal = {
149
- source: "code-reviewer",
150
- files: ["index.ts"],
151
- reason: "a comprehensive review was requested",
152
- at: "2026-10-25T00:00:00.000Z",
153
- };
154
-
155
- it("records a signal once", () => {
156
- const once = mergeSignals([], signal);
157
- const twice = mergeSignals(once, signal);
158
- expect(twice).toHaveLength(1);
159
- });
160
-
161
- it("keeps a different signal", () => {
162
- const merged = mergeSignals(mergeSignals([], signal), {
163
- ...signal,
164
- source: "semgrep",
165
- });
166
- expect(merged).toHaveLength(2);
167
- });
168
-
169
- it("summarizes the signals into one scope", () => {
170
- const merged = mergeSignals(mergeSignals([], signal), {
171
- source: "semgrep",
172
- files: ["other.ts"],
173
- reason: "a second source",
174
- at: "2026-10-25T00:01:00.000Z",
175
- });
176
- const summary = summarizeSignals(merged);
177
- expect(summary.sources).toEqual(["code-reviewer", "semgrep"]);
178
- expect(summary.files).toEqual(["index.ts", "other.ts"]);
179
- expect(summary.reason).toContain("a second source");
180
- });
181
- });
182
-
183
- // touched
@@ -1,201 +0,0 @@
1
- /**
2
- * The persisted state.
3
- *
4
- * The phase, the start revision, the scope, the finished chunks and the open
5
- * findings survive a restart, so the workflow can be resumed after a
6
- * compaction or a reset.
7
- */
8
-
9
- import { describe, it, expect } from "bun:test";
10
- import { readdirSync, writeFileSync } from "node:fs";
11
- import {
12
- TwoPhaseStateStore,
13
- allChunksDone,
14
- createState,
15
- hasQueuedReview,
16
- markChunkDone,
17
- markComplete,
18
- moveToPhase,
19
- normalizeState,
20
- recordFinding,
21
- recordSignal,
22
- safeFileName,
23
- startReview,
24
- transitionToReviewFixes,
25
- transitionToReviewPending,
26
- } from "../src/state.js";
27
- import type { ReviewChunk, ReviewSignal } from "../src/types.js";
28
- import { withTempDir } from "./helpers.js";
29
-
30
- /** A review chunk of the given id. */
31
- function chunk(id: string): ReviewChunk {
32
- return { id, label: `${id} (1 file)`, files: [`${id}.ts`], status: "pending" };
33
- }
34
-
35
- const signal: ReviewSignal = {
36
- source: "code-reviewer",
37
- files: ["index.ts"],
38
- reason: "a comprehensive review was requested with code-reviewer",
39
- at: "2026-10-25T00:00:00.000Z",
40
- };
41
-
42
- describe("createState", () => {
43
- it("starts in the implementation phase", () => {
44
- const state = createState("task-1", "abc123");
45
- expect(state.phase).toBe("implementation");
46
- expect(state.startRevision).toBe("abc123");
47
- expect(state.signals).toEqual([]);
48
- });
49
- });
50
-
51
- describe("signals", () => {
52
- it("records a signal once", () => {
53
- const once = recordSignal(createState("t"), signal);
54
- const twice = recordSignal(once, signal);
55
- expect(twice.signals).toHaveLength(1);
56
- expect(hasQueuedReview(twice)).toBe(true);
57
- });
58
-
59
- it("keeps the phase while a signal is recorded", () => {
60
- const state = recordSignal(createState("t"), signal);
61
- expect(state.phase).toBe("implementation");
62
- });
63
- });
64
-
65
- describe("phases", () => {
66
- it("moves forward only", () => {
67
- const state = createState("t");
68
- expect(moveToPhase(state, "review_pending").phase).toBe("review_pending");
69
- expect(moveToPhase(state, "implementation").phase).toBe("implementation");
70
- const review = moveToPhase(state, "review");
71
- expect(moveToPhase(review, "implementation").phase).toBe("review");
72
- });
73
-
74
- it("does not move back from the review into the implementation", () => {
75
- const review = startReview(createState("t"), []);
76
- expect(moveToPhase(review, "implementation").phase).toBe("review");
77
- });
78
-
79
- it("enters the review with the scope and the chunks", () => {
80
- const pending = transitionToReviewPending(createState("t"), ["a.ts", "b.ts"]);
81
- expect(pending.phase).toBe("review_pending");
82
- expect(pending.scopeFiles).toEqual(["a.ts", "b.ts"]);
83
-
84
- const review = startReview(pending, [
85
- { id: "chunk-1", label: "packages/x (1 file)", files: ["a.ts"], status: "pending" },
86
- ]);
87
- expect(review.phase).toBe("review");
88
- expect(review.chunks).toHaveLength(1);
89
- });
90
-
91
- it("marks the chunks as done", () => {
92
- const review = startReview(createState("t"), [
93
- { id: "chunk-1", label: "a", files: ["a.ts"], status: "pending" },
94
- { id: "chunk-2", label: "b", files: ["b.ts"], status: "pending" },
95
- ]);
96
- const one = markChunkDone(review, "chunk-1");
97
- expect(allChunksDone(one)).toBe(false);
98
- const both = markChunkDone(one, "chunk-2");
99
- expect(allChunksDone(both)).toBe(true);
100
- });
101
-
102
- it("enters the fixes only when the review is finished", () => {
103
- const review = startReview(createState("t"), [chunk("chunk-1")]);
104
- expect(transitionToReviewFixes(review).phase).toBe("review");
105
-
106
- const withFinding = recordFinding(review, {
107
- id: "finding-1",
108
- severity: "medium",
109
- summary: "the callback is not idempotent",
110
- at: "2026-10-25T00:00:00.000Z",
111
- });
112
- // The review has not run over every chunk yet.
113
- expect(transitionToReviewFixes(withFinding).phase).toBe("review");
114
-
115
- const reviewed = markChunkDone(withFinding, "chunk-1");
116
- expect(transitionToReviewFixes(reviewed).phase).toBe("review_fixes");
117
- expect(withFinding.findings).toHaveLength(1);
118
- });
119
-
120
- it("marks the task complete only when the review ran", () => {
121
- // The implementation alone never completes the task.
122
- expect(markComplete(createState("t")).phase).toBe("implementation");
123
-
124
- const review = startReview(createState("t"), [chunk("chunk-1")]);
125
- expect(markComplete(review).phase).toBe("review");
126
-
127
- const reviewed = markChunkDone(review, "chunk-1");
128
- expect(markComplete(reviewed).phase).toBe("complete");
129
- });
130
-
131
- it("never moves the phase backwards", () => {
132
- const review = startReview(createState("t"), [chunk("chunk-1")]);
133
- const done = markComplete(markChunkDone(review, "chunk-1"));
134
- expect(done.phase).toBe("complete");
135
- // A late transition cannot undo the completion.
136
- expect(transitionToReviewFixes(done).phase).toBe("complete");
137
- expect(moveToPhase(done, "review").phase).toBe("complete");
138
- });
139
- });
140
-
141
- describe("TwoPhaseStateStore", () => {
142
- it("writes and reads the state of a task", () => {
143
- withTempDir("state", (dir) => {
144
- const store = new TwoPhaseStateStore(dir);
145
- const state = recordSignal(createState("task-1", "rev1"), signal);
146
- store.write(state);
147
-
148
- const read = store.read("task-1");
149
- expect(read?.phase).toBe("implementation");
150
- expect(read?.signals).toHaveLength(1);
151
- expect(read?.startRevision).toBe("rev1");
152
- });
153
- });
154
-
155
- it("returns nothing for an unknown task", () => {
156
- withTempDir("state", (dir) => {
157
- const store = new TwoPhaseStateStore(dir);
158
- expect(store.read("unknown")).toBeNull();
159
- });
160
- });
161
-
162
- it("reports a corrupt state instead of losing it", () => {
163
- withTempDir("state", (dir) => {
164
- const store = new TwoPhaseStateStore(dir);
165
- store.write(createState("task-1", "rev1"));
166
- writeFileSync(store.path("task-1"), "{not json", "utf8");
167
-
168
- // A corrupt state must not look like a fresh task: that would lose
169
- // the revision the task started at and the progress of the review.
170
- expect(() => store.read("task-1")).toThrow(/not valid JSON/);
171
- });
172
- });
173
-
174
- it("leaves no temporary file behind", () => {
175
- withTempDir("state", (dir) => {
176
- const store = new TwoPhaseStateStore(dir);
177
- store.write(createState("task-1"));
178
- store.write(createState("task-1"));
179
- expect(readdirSync(dir).filter((entry) => entry.endsWith(".tmp"))).toEqual([]);
180
- });
181
- });
182
-
183
- it("keeps the tasks apart", () => {
184
- withTempDir("state", (dir) => {
185
- const store = new TwoPhaseStateStore(dir);
186
- store.write(recordSignal(createState("task-a"), signal));
187
- store.write(createState("task-b"));
188
- expect(store.read("task-a")?.signals).toHaveLength(1);
189
- expect(store.read("task-b")?.signals).toHaveLength(0);
190
- });
191
- });
192
-
193
- it("repairs a broken state", () => {
194
- expect(normalizeState({ phase: "nonsense" }, "task-1").phase).toBe("implementation");
195
- expect(normalizeState(null, "task-1").taskId).toBe("task-1");
196
- });
197
-
198
- it("uses a safe file name", () => {
199
- expect(safeFileName("session/with spaces")).toBe("session_with_spaces");
200
- });
201
- });