pi-harness-runtime 1.1.439 → 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 (359) hide show
  1. package/harness/e2e/auto-test-loop.ts +8 -2
  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/index.ts +2 -1
  7. package/harness/key-loader.ts +2 -0
  8. package/harness/langchain/checkpointer.ts +2 -0
  9. package/harness/langchain/cron-cli.ts +2 -0
  10. package/harness/langchain/graph.ts +2 -0
  11. package/harness/master-planner.ts +1 -1
  12. package/harness/notification-center.ts +2 -0
  13. package/harness/output-limit-handler.ts +1 -1
  14. package/harness/project-detector/detector.ts +2 -4
  15. package/harness/secret-provider.ts +2 -0
  16. package/harness/task-graph.ts +460 -113
  17. package/index.ts +16 -7
  18. package/package.json +7 -1
  19. package/packages/a2a-adapter/package.json +1 -1
  20. package/packages/agent-policy/dist/extension.d.ts.map +1 -1
  21. package/packages/agent-policy/dist/extension.js +2 -0
  22. package/packages/agent-policy/dist/extension.js.map +1 -1
  23. package/packages/agent-policy/package.json +1 -1
  24. package/packages/agent-policy/src/extension.ts +2 -0
  25. package/packages/architecture-generator/package.json +1 -1
  26. package/packages/auth/dist/minimax-browser-auth.d.ts.map +1 -1
  27. package/packages/auth/dist/minimax-browser-auth.js +23 -1
  28. package/packages/auth/dist/minimax-browser-auth.js.map +1 -1
  29. package/packages/auth/package.json +1 -1
  30. package/packages/auth/src/minimax-browser-auth.ts +30 -5
  31. package/packages/autonomous-refactor/package.json +1 -1
  32. package/packages/autonomous-runtime/dist/inbox.d.ts.map +1 -1
  33. package/packages/autonomous-runtime/dist/inbox.js +2 -0
  34. package/packages/autonomous-runtime/dist/inbox.js.map +1 -1
  35. package/packages/autonomous-runtime/package.json +1 -1
  36. package/packages/autonomous-runtime/src/inbox.ts +2 -0
  37. package/packages/cache-strategy/package.json +1 -1
  38. package/packages/capability-registry/package.json +1 -1
  39. package/packages/checkpoint/package.json +1 -1
  40. package/packages/cli-plugin-sdk/package.json +1 -1
  41. package/packages/clipboard/dist/src/clipboard.d.ts.map +1 -1
  42. package/packages/clipboard/dist/src/clipboard.js +2 -0
  43. package/packages/clipboard/dist/src/clipboard.js.map +1 -1
  44. package/packages/clipboard/dist/src/copy-sync.d.ts.map +1 -1
  45. package/packages/clipboard/dist/src/copy-sync.js +2 -0
  46. package/packages/clipboard/dist/src/copy-sync.js.map +1 -1
  47. package/packages/clipboard/dist/src/gist-relay.d.ts.map +1 -1
  48. package/packages/clipboard/dist/src/gist-relay.js +2 -0
  49. package/packages/clipboard/dist/src/gist-relay.js.map +1 -1
  50. package/packages/clipboard/package.json +1 -1
  51. package/packages/clipboard/src/clipboard.ts +2 -0
  52. package/packages/clipboard/src/copy-sync.ts +2 -0
  53. package/packages/clipboard/src/gist-relay.ts +2 -0
  54. package/packages/clipboard-plugin/dist/types.d.ts +9 -2
  55. package/packages/clipboard-plugin/dist/types.d.ts.map +1 -1
  56. package/packages/clipboard-plugin/package.json +1 -1
  57. package/packages/clipboard-plugin/src/types.ts +9 -2
  58. package/packages/code-generation/package.json +1 -1
  59. package/packages/code-review/package.json +1 -1
  60. package/packages/codex-adapter/package.json +1 -1
  61. package/packages/codex-watcher/package.json +1 -1
  62. package/packages/config-capture/package.json +1 -1
  63. package/packages/connection-runtime/package.json +1 -1
  64. package/packages/context-compiler/package.json +1 -1
  65. package/packages/context-discovery/package.json +1 -1
  66. package/packages/context-manager/package.json +1 -1
  67. package/packages/contracts/dist/delegation-store.js +1 -4
  68. package/packages/contracts/dist/workspace-env.js +28 -1
  69. package/packages/contracts/package.json +1 -1
  70. package/packages/contracts/src/delegation-store.ts +9 -4
  71. package/packages/contracts/src/workspace-env.ts +29 -4
  72. package/packages/cookie-sanitizer/package.json +1 -1
  73. package/packages/cost-optimizer/package.json +1 -1
  74. package/packages/dependency-analyzer/package.json +1 -1
  75. package/packages/django-plugin/package.json +1 -1
  76. package/packages/doc-generator/package.json +1 -1
  77. package/packages/durable-review/package.json +1 -1
  78. package/packages/e2e-tester/package.json +1 -1
  79. package/packages/evaluation-engine/package.json +1 -1
  80. package/packages/evaluation-runner/package.json +1 -1
  81. package/packages/event-bus/package.json +1 -1
  82. package/packages/event-sink/package.json +1 -1
  83. package/packages/event-store/dist/src/store.d.ts.map +1 -1
  84. package/packages/event-store/dist/src/store.js +2 -0
  85. package/packages/event-store/dist/src/store.js.map +1 -1
  86. package/packages/event-store/package.json +1 -1
  87. package/packages/event-store/src/store.ts +3 -0
  88. package/packages/experience-replay/package.json +1 -1
  89. package/packages/feedback-collector/package.json +1 -1
  90. package/packages/file-copy-helper/package.json +1 -1
  91. package/packages/framework-detector/package.json +1 -1
  92. package/packages/framework-plugin-sdk/package.json +1 -1
  93. package/packages/frappe-plugin/package.json +1 -1
  94. package/packages/generic-web-plugin/dist/analyzer.d.ts.map +1 -1
  95. package/packages/generic-web-plugin/dist/analyzer.js +2 -0
  96. package/packages/generic-web-plugin/dist/analyzer.js.map +1 -1
  97. package/packages/generic-web-plugin/package.json +1 -1
  98. package/packages/generic-web-plugin/src/analyzer.ts +3 -0
  99. package/packages/health-monitor/package.json +1 -1
  100. package/packages/intent-analyzer/package.json +1 -1
  101. package/packages/jev-judge/package.json +1 -1
  102. package/packages/knowledge-graph/package.json +1 -1
  103. package/packages/knowledge-retrieval/dist/mcp-client.d.ts.map +1 -1
  104. package/packages/knowledge-retrieval/dist/mcp-client.js +0 -1
  105. package/packages/knowledge-retrieval/dist/mcp-client.js.map +1 -1
  106. package/packages/knowledge-retrieval/package.json +1 -4
  107. package/packages/knowledge-retrieval/src/mcp-client.ts +0 -1
  108. package/packages/laravel-plugin/package.json +1 -1
  109. package/packages/learning-engine/package.json +1 -1
  110. package/packages/logging/package.json +1 -1
  111. package/packages/mcp-adapter/dist/server.d.ts.map +1 -1
  112. package/packages/mcp-adapter/dist/server.js +2 -0
  113. package/packages/mcp-adapter/dist/server.js.map +1 -1
  114. package/packages/mcp-adapter/package.json +1 -1
  115. package/packages/mcp-adapter/src/server.ts +3 -0
  116. package/packages/memory-engine/package.json +1 -1
  117. package/packages/milestone-manager/package.json +1 -1
  118. package/packages/model-registry/package.json +1 -1
  119. package/packages/nextjs-plugin/package.json +1 -1
  120. package/packages/notification/package.json +1 -1
  121. package/packages/observability/package.json +1 -1
  122. package/packages/okf-indexer/package.json +1 -1
  123. package/packages/paperclip-integration/dist/index.d.ts.map +1 -1
  124. package/packages/paperclip-integration/dist/index.js +2 -0
  125. package/packages/paperclip-integration/dist/index.js.map +1 -1
  126. package/packages/paperclip-integration/package.json +1 -1
  127. package/packages/paperclip-integration/src/index.ts +2 -0
  128. package/packages/performance-optimizer/package.json +1 -1
  129. package/packages/permission-mode/package.json +1 -1
  130. package/packages/privilege-broker/dist/audit.d.ts.map +1 -1
  131. package/packages/privilege-broker/dist/audit.js +2 -0
  132. package/packages/privilege-broker/dist/audit.js.map +1 -1
  133. package/packages/privilege-broker/package.json +1 -1
  134. package/packages/privilege-broker/src/audit.ts +2 -0
  135. package/packages/project-analyzer/package.json +1 -1
  136. package/packages/project-bootstrap/package.json +1 -1
  137. package/packages/projection-engine/package.json +1 -1
  138. package/packages/prompt-compiler/dist/compiler.d.ts.map +1 -1
  139. package/packages/prompt-compiler/dist/compiler.js +2 -0
  140. package/packages/prompt-compiler/dist/compiler.js.map +1 -1
  141. package/packages/prompt-compiler/package.json +1 -1
  142. package/packages/prompt-compiler/src/compiler.ts +2 -0
  143. package/packages/prompt-versioning/package.json +1 -1
  144. package/packages/provider-adapter-sdk/package.json +1 -1
  145. package/packages/provider-router/package.json +1 -1
  146. package/packages/provider-selector/package.json +1 -1
  147. package/packages/providers/package.json +1 -1
  148. package/packages/qdrant-skills/package.json +1 -1
  149. package/packages/quota-manager/package.json +1 -1
  150. package/packages/rate-limiter/package.json +1 -1
  151. package/packages/react-vite-plugin/package.json +1 -1
  152. package/packages/relay/package.json +1 -1
  153. package/packages/release-manager/package.json +1 -1
  154. package/packages/requirement-compiler/package.json +1 -1
  155. package/packages/runtime/package.json +1 -1
  156. package/packages/scheduler/package.json +1 -1
  157. package/packages/scheduler-adapter/package.json +1 -1
  158. package/packages/session/package.json +1 -1
  159. package/packages/session-api/package.json +1 -1
  160. package/packages/session-export/package.json +1 -1
  161. package/packages/shared-context/package.json +1 -1
  162. package/packages/skill-mcp-client/dist/client.d.ts.map +1 -1
  163. package/packages/skill-mcp-client/dist/client.js +0 -1
  164. package/packages/skill-mcp-client/dist/client.js.map +1 -1
  165. package/packages/skill-mcp-client/package.json +1 -4
  166. package/packages/skill-mcp-client/src/client.ts +0 -1
  167. package/packages/skill-registry/package.json +1 -1
  168. package/packages/skills/dist/parser.d.ts.map +1 -1
  169. package/packages/skills/dist/parser.js +2 -0
  170. package/packages/skills/dist/parser.js.map +1 -1
  171. package/packages/skills/dist/skill-versioning.d.ts.map +1 -1
  172. package/packages/skills/dist/skill-versioning.js +2 -0
  173. package/packages/skills/dist/skill-versioning.js.map +1 -1
  174. package/packages/skills/package.json +1 -1
  175. package/packages/skills/src/parser.ts +3 -0
  176. package/packages/skills/src/skill-versioning.ts +2 -0
  177. package/packages/sprint-planner/package.json +1 -1
  178. package/packages/subscription-engine/package.json +1 -1
  179. package/packages/task-compiler/package.json +1 -1
  180. package/packages/tencentdb-memory/package.json +1 -1
  181. package/packages/tencentdb-sync/package.json +1 -1
  182. package/packages/test-data-generator/package.json +1 -1
  183. package/packages/test-generator/package.json +1 -1
  184. package/packages/todo-bd-sync/package.json +1 -1
  185. package/packages/token-estimation/package.json +1 -1
  186. package/packages/token-optimizer/package.json +1 -1
  187. package/packages/tooling-preference/package.json +1 -1
  188. package/packages/trajectory/package.json +1 -1
  189. package/packages/tui/package.json +1 -1
  190. package/packages/two-phase-review/package.json +1 -1
  191. package/packages/types/package.json +1 -1
  192. package/packages/voice-api/package.json +1 -1
  193. package/packages/webmcp-tester/dist/index.js +0 -2
  194. package/packages/webmcp-tester/package.json +1 -1
  195. package/packages/webmcp-tester/src/index.ts +0 -3
  196. package/packages/wiki/package.json +1 -1
  197. package/packages/workflow-events/package.json +1 -1
  198. package/packages/workspace-scanner/package.json +1 -1
  199. package/packages/worktree/package.json +1 -1
  200. package/packages/write-review/dist/trigger.d.ts.map +1 -1
  201. package/packages/write-review/dist/trigger.js +1 -2
  202. package/packages/write-review/dist/trigger.js.map +1 -1
  203. package/packages/write-review/package.json +1 -1
  204. package/packages/write-review/src/trigger.ts +1 -2
  205. package/scripts/lib/runtime-imports.ts +189 -3
  206. package/scripts/release-all.ts +5 -3
  207. package/scripts/telegram-webhook-server.ts +2 -0
  208. package/scripts/typecheck-packages.mjs +7 -4
  209. package/scripts/verify-package-contents.ts +161 -2
  210. package/harness/e2e/tools-detector.test.ts +0 -156
  211. package/harness/glm-quota-countdown.test.ts +0 -323
  212. package/harness/langchain/agents.test.ts +0 -39
  213. package/harness/langchain/checkpointer.test.ts +0 -243
  214. package/harness/langchain/daemon.test.ts +0 -459
  215. package/harness/langchain/model-router.test.ts +0 -191
  216. package/harness/langchain/ping-pong-middleware.test.ts +0 -69
  217. package/harness/langchain/scoreboard.test.ts +0 -245
  218. package/harness/langchain/status-line.test.ts +0 -106
  219. package/harness/langchain/surge.test.ts +0 -467
  220. package/harness/langchain/widget.test.ts +0 -251
  221. package/harness/skill-sync.test.ts +0 -57
  222. package/harness/ssh-detach-interceptor.test.ts +0 -263
  223. package/harness/ssh-hang-recovery.test.ts +0 -86
  224. package/packages/a2a-adapter/test/a2a.test.ts +0 -151
  225. package/packages/agent-policy/test/interlock.test.ts +0 -101
  226. package/packages/agent-policy/test/policy-retention.test.ts +0 -380
  227. package/packages/agent-policy/test/policy.test.ts +0 -387
  228. package/packages/auth/test/auth.test.ts +0 -238
  229. package/packages/autonomous-refactor/test/refactor.test.ts +0 -202
  230. package/packages/autonomous-runtime/test/types.test.ts +0 -95
  231. package/packages/cache-strategy/test/cache.test.ts +0 -137
  232. package/packages/capability-registry/test/registry.test.ts +0 -204
  233. package/packages/checkpoint/test/engine.test.ts +0 -265
  234. package/packages/cli-plugin-sdk/test/cli.test.ts +0 -45
  235. package/packages/code-generation/test/generator.test.ts +0 -238
  236. package/packages/code-review/test/engine.test.ts +0 -302
  237. package/packages/codex-adapter/test/provider.test.ts +0 -142
  238. package/packages/codex-watcher/test/watch.test.ts +0 -453
  239. package/packages/context-compiler/test/context-compiler.test.ts +0 -746
  240. package/packages/context-manager/test/context.test.ts +0 -198
  241. package/packages/contracts/test/delegation.test.ts +0 -350
  242. package/packages/contracts/test/workspace-env.test.ts +0 -802
  243. package/packages/cookie-sanitizer/test/infer.test.ts +0 -110
  244. package/packages/cookie-sanitizer/test/normalize.test.ts +0 -113
  245. package/packages/cookie-sanitizer/test/parse.test.ts +0 -204
  246. package/packages/cookie-sanitizer/test/sync.test.ts +0 -237
  247. package/packages/cookie-sanitizer/test/watcher.test.ts +0 -27
  248. package/packages/cost-optimizer/test/cost-optimizer.test.ts +0 -438
  249. package/packages/dependency-analyzer/test/analyzer.test.ts +0 -49
  250. package/packages/django-plugin/test/analyzer.test.ts +0 -195
  251. package/packages/doc-generator/test/docs.test.ts +0 -168
  252. package/packages/durable-review/test/acceptance.test.ts +0 -357
  253. package/packages/durable-review/test/smoke.test.ts +0 -107
  254. package/packages/evaluation-engine/test/engine.test.ts +0 -277
  255. package/packages/evaluation-runner/test/runner.test.ts +0 -168
  256. package/packages/event-bus/test/bus.test.ts +0 -100
  257. package/packages/event-store/test/store.test.ts +0 -115
  258. package/packages/experience-replay/test/replay.test.ts +0 -267
  259. package/packages/feedback-collector/test/collector.test.ts +0 -142
  260. package/packages/framework-detector/test/detector.test.ts +0 -75
  261. package/packages/framework-plugin-sdk/test/manager.test.ts +0 -320
  262. package/packages/frappe-plugin/test/analyzer.test.ts +0 -250
  263. package/packages/generic-web-plugin/test/analyzer.test.ts +0 -134
  264. package/packages/health-monitor/test/health.test.ts +0 -231
  265. package/packages/intent-analyzer/test/analyzer.test.ts +0 -72
  266. package/packages/intent-analyzer/test/ping-pong.test.ts +0 -96
  267. package/packages/jev-judge/tests/auto-continue-context.test.ts +0 -280
  268. package/packages/jev-judge/tests/continuation-controller.test.ts +0 -1396
  269. package/packages/jev-judge/tests/jev-provider-chain.test.ts +0 -536
  270. package/packages/jev-judge/tests/outcome-application.test.ts +0 -132
  271. package/packages/jev-judge/tests/question-risk.test.ts +0 -129
  272. package/packages/jev-judge/tests/typesafe-provider.test.ts +0 -640
  273. package/packages/jev-judge/tests/validation-ledger.test.ts +0 -181
  274. package/packages/jev-judge/tests/validation-plan.test.ts +0 -170
  275. package/packages/jev-judge/tests/validation-tie-breaker.test.ts +0 -88
  276. package/packages/laravel-plugin/test/analyzer.test.ts +0 -220
  277. package/packages/learning-engine/test/engine.test.ts +0 -331
  278. package/packages/logging/test/buffer.test.ts +0 -44
  279. package/packages/logging/test/classification.test.ts +0 -137
  280. package/packages/logging/test/config.test.ts +0 -97
  281. package/packages/logging/test/fanout.test.ts +0 -186
  282. package/packages/logging/test/identity-transport.test.ts +0 -197
  283. package/packages/logging/test/incidents.test.ts +0 -404
  284. package/packages/logging/test/ingest-schema.test.ts +0 -184
  285. package/packages/logging/test/integration.test.ts +0 -140
  286. package/packages/logging/test/log-http.test.ts +0 -246
  287. package/packages/logging/test/redact.test.ts +0 -109
  288. package/packages/logging/test/sampler.test.ts +0 -57
  289. package/packages/logging/test/server.test.ts +0 -444
  290. package/packages/logging/test/shipper.test.ts +0 -152
  291. package/packages/logging/test/spool.test.ts +0 -96
  292. package/packages/mcp-adapter/test/server.test.ts +0 -91
  293. package/packages/memory-engine/test/engine.test.ts +0 -456
  294. package/packages/model-registry/test/registry.test.ts +0 -342
  295. package/packages/nextjs-plugin/test/analyzer.test.ts +0 -149
  296. package/packages/notification/test/approval-payload.test.ts +0 -269
  297. package/packages/notification/test/detail-format.test.ts +0 -106
  298. package/packages/notification/test/notification.test.ts +0 -375
  299. package/packages/notification/test/pending-question-lifecycle.test.ts +0 -195
  300. package/packages/notification/test/pending-question.test.ts +0 -331
  301. package/packages/notification/test/tooling-proposal-payload.test.ts +0 -212
  302. package/packages/observability/test/observability.test.ts +0 -1350
  303. package/packages/performance-optimizer/test/optimizer.test.ts +0 -267
  304. package/packages/project-analyzer/test/index.test.ts +0 -1719
  305. package/packages/prompt-compiler/test/prompt-compiler.test.ts +0 -813
  306. package/packages/prompt-versioning/test/versioning.test.ts +0 -112
  307. package/packages/provider-adapter-sdk/test/sdk.test.ts +0 -220
  308. package/packages/provider-router/test/provider-router.test.ts +0 -405
  309. package/packages/provider-selector/test/selector.test.ts +0 -192
  310. package/packages/providers/test/providers.test.ts +0 -225
  311. package/packages/qdrant-skills/test/collection-info.test.ts +0 -165
  312. package/packages/qdrant-skills/test/embedder-batch.test.ts +0 -184
  313. package/packages/qdrant-skills/test/embedder.test.ts +0 -97
  314. package/packages/quota-manager/test/quota.test.ts +0 -432
  315. package/packages/rate-limiter/test/limiter.test.ts +0 -128
  316. package/packages/react-vite-plugin/test/analyzer.test.ts +0 -139
  317. package/packages/relay/test/client.test.ts +0 -446
  318. package/packages/relay/test/relay-e2e.test.ts +0 -299
  319. package/packages/relay/test/relay-endpoint.test.ts +0 -278
  320. package/packages/release-manager/test/release.test.ts +0 -215
  321. package/packages/requirement-compiler/test/requirement-compiler.test.ts +0 -743
  322. package/packages/runtime/test/runtime-api.test.ts +0 -169
  323. package/packages/runtime/test/runtime.test.ts +0 -297
  324. package/packages/scheduler/test/scheduler.test.ts +0 -125
  325. package/packages/session/test/manager.test.ts +0 -233
  326. package/packages/shared-context/test/shared-context.test.ts +0 -114
  327. package/packages/skill-registry/test/registry.test.ts +0 -508
  328. package/packages/skills/test/init-skills.test.ts +0 -114
  329. package/packages/skills/test/remote-skills.test.ts +0 -360
  330. package/packages/skills/test/remote-source.test.ts +0 -248
  331. package/packages/skills/test/sanitize.test.ts +0 -250
  332. package/packages/skills/test/vector-indexing.test.ts +0 -205
  333. package/packages/skills/test/vector-schema.test.ts +0 -180
  334. package/packages/skills/test/vector-threshold.test.ts +0 -108
  335. package/packages/sprint-planner/test/planner.test.ts +0 -187
  336. package/packages/task-compiler/test/task-compiler.test.ts +0 -628
  337. package/packages/test-data-generator/test/generator.test.ts +0 -265
  338. package/packages/test-generator/test/generator.test.ts +0 -156
  339. package/packages/token-estimation/test/token-estimation.test.ts +0 -207
  340. package/packages/token-optimizer/test/optimizer.test.ts +0 -141
  341. package/packages/tooling-preference/tests/changed-files.test.ts +0 -124
  342. package/packages/tooling-preference/tests/detect.test.ts +0 -188
  343. package/packages/tooling-preference/tests/proposal.test.ts +0 -107
  344. package/packages/tooling-preference/tests/quality-check.test.ts +0 -272
  345. package/packages/tooling-preference/tests/registry.test.ts +0 -51
  346. package/packages/tooling-preference/tests/store.test.ts +0 -99
  347. package/packages/trajectory/test/store.test.ts +0 -250
  348. package/packages/tui/test/harness-footer.test.ts +0 -559
  349. package/packages/tui/test/harness-header.test.ts +0 -590
  350. package/packages/two-phase-review/test/classify.test.ts +0 -102
  351. package/packages/two-phase-review/test/helpers.ts +0 -72
  352. package/packages/two-phase-review/test/rules.test.ts +0 -150
  353. package/packages/two-phase-review/test/runtime.test.ts +0 -362
  354. package/packages/two-phase-review/test/scope.test.ts +0 -186
  355. package/packages/two-phase-review/test/signals.test.ts +0 -183
  356. package/packages/two-phase-review/test/state.test.ts +0 -201
  357. package/packages/wiki/test/basic.test.ts +0 -242
  358. package/packages/workspace-scanner/test/scanner.test.ts +0 -43
  359. package/packages/worktree/test/worktree.test.ts +0 -163
@@ -30,14 +30,11 @@
30
30
  */
31
31
 
32
32
  import { spawn, ChildProcess } from "child_process";
33
- import { promisify } from "util";
34
33
  import { readFile, writeFile, mkdir } from "fs/promises";
35
34
  import { existsSync } from "fs";
36
35
  import { join, dirname } from "path";
37
36
  import { homedir } from "os";
38
37
 
39
- const exec = promisify(require("child_process").exec);
40
-
41
38
  // ---------------------------------------------------------------------------
42
39
  // Types
43
40
  // ---------------------------------------------------------------------------
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/wiki",
3
- "version": "1.1.439",
3
+ "version": "1.1.441",
4
4
  "description": "LLM Wiki integration for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/workflow-events",
3
- "version": "1.1.439",
3
+ "version": "1.1.441",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/workspace-scanner",
3
- "version": "1.1.439",
3
+ "version": "1.1.441",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/worktree",
3
- "version": "1.1.439",
3
+ "version": "1.1.441",
4
4
  "description": "pi-harness-runtime — worktree",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1 +1 @@
1
- {"version":3,"file":"trigger.d.ts","sourceRoot":"","sources":["../src/trigger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAIvD;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAS3E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC9B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GACjB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAiB/C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC7B,WAAW,EAAE,MAAM,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAAE,CAqCxD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CACnC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,WAAW,GAAE,oBAAoB,CAAC,aAAa,CAAe,GAC5D,oBAAoB,GAAG,IAAI,CAc7B;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAG3D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEtD"}
1
+ {"version":3,"file":"trigger.d.ts","sourceRoot":"","sources":["../src/trigger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAIvD;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAS3E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC9B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GACjB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAiB/C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC7B,WAAW,EAAE,MAAM,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAAE,CAoCxD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CACnC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,WAAW,GAAE,oBAAoB,CAAC,aAAa,CAAe,GAC5D,oBAAoB,GAAG,IAAI,CAc7B;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAG3D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEtD"}
@@ -4,7 +4,7 @@
4
4
  * Detects when an agent reads a prompt from {project}/wiki/*
5
5
  * This triggers the write-review loop.
6
6
  */
7
- import { existsSync } from "fs";
7
+ import { existsSync, readdirSync, statSync } from "fs";
8
8
  import { join, relative } from "path";
9
9
  const DEFAULT_WIKI_DIR = "wiki";
10
10
  /**
@@ -47,7 +47,6 @@ export function getWikiPrompts(projectPath) {
47
47
  }
48
48
  const prompts = [];
49
49
  function scanDir(dir) {
50
- const { readdirSync, statSync } = require("fs");
51
50
  try {
52
51
  for (const entry of readdirSync(dir)) {
53
52
  const fullPath = join(dir, entry);
@@ -1 +1 @@
1
- {"version":3,"file":"trigger.js","sourceRoot":"","sources":["../src/trigger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"trigger.js","sourceRoot":"","sources":["../src/trigger.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moocoding/write-review",
3
- "version": "1.1.439",
3
+ "version": "1.1.441",
4
4
  "description": "Two-agent write-review loop with blackboard coordination",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -5,7 +5,7 @@
5
5
  * This triggers the write-review loop.
6
6
  */
7
7
 
8
- import { existsSync } from "fs";
8
+ import { existsSync, readdirSync, statSync } from "fs";
9
9
  import { join, relative } from "path";
10
10
  import type { ReviewTriggerContext } from "./types.js";
11
11
 
@@ -65,7 +65,6 @@ export function getWikiPrompts(
65
65
  const prompts: { path: string; category: string; filename: string }[] = [];
66
66
 
67
67
  function scanDir(dir: string): void {
68
- const { readdirSync, statSync } = require("fs");
69
68
  try {
70
69
  for (const entry of readdirSync(dir)) {
71
70
  const fullPath = join(dir, entry);
@@ -130,16 +130,26 @@ export function stripComments(source: string): string {
130
130
  return scanSource(source).code;
131
131
  }
132
132
 
133
- /** The import forms that carry a specifier. */
134
- const IMPORT_PATTERNS: RegExp[] = [
133
+ /** The STATIC import forms that carry a specifier. */
134
+ const STATIC_IMPORT_PATTERNS: RegExp[] = [
135
135
  // import ... from "..." / export ... from "..."
136
136
  /(?:^|[\n;])[ \t]*(import|export)\s+(type\s+)?[^;\n]*?from\s*["']([^"']+)["']/g,
137
137
  // import "..." (side effect)
138
138
  /(?:^|[\n;])[ \t]*import\s*["']([^"']+)["']/g,
139
+ ];
140
+
141
+ /** The DYNAMIC import form that carries a specifier. */
142
+ const DYNAMIC_IMPORT_PATTERNS: RegExp[] = [
139
143
  // import("...") (dynamic)
140
144
  /import\s*\(\s*["']([^"']+)["']\s*\)/g,
141
145
  ];
142
146
 
147
+ /** The import forms that carry a specifier. */
148
+ const IMPORT_PATTERNS: RegExp[] = [
149
+ ...STATIC_IMPORT_PATTERNS,
150
+ ...DYNAMIC_IMPORT_PATTERNS,
151
+ ];
152
+
143
153
  /**
144
154
  * Every VALUE import of a source file.
145
155
  *
@@ -149,10 +159,27 @@ const IMPORT_PATTERNS: RegExp[] = [
149
159
  * is documentation, not an import.
150
160
  */
151
161
  export function extractValueImports(source: string): string[] {
162
+ return collectSpecifiers(source, IMPORT_PATTERNS);
163
+ }
164
+
165
+ /**
166
+ * Every STATIC value import of a source file.
167
+ *
168
+ * A dynamic import is a different thing: it is resolved when the code
169
+ * reaches it, so a module that loads one at run time may be an optional
170
+ * dependency. A static import is resolved when the module is loaded, so
171
+ * the package must carry it.
172
+ */
173
+ export function extractStaticValueImports(source: string): string[] {
174
+ return collectSpecifiers(source, STATIC_IMPORT_PATTERNS);
175
+ }
176
+
177
+ /** The specifiers of the given import forms. */
178
+ function collectSpecifiers(source: string, patterns: RegExp[]): string[] {
152
179
  const { code, isCodeAt } = scanSource(source);
153
180
  const specifiers: string[] = [];
154
181
 
155
- for (const pattern of IMPORT_PATTERNS) {
182
+ for (const pattern of patterns) {
156
183
  for (const match of code.matchAll(pattern)) {
157
184
  // The match must start in code, not inside a literal.
158
185
  if (match.index === undefined || !isCodeAt(match.index)) continue;
@@ -183,6 +210,19 @@ export function extractBareImports(source: string): string[] {
183
210
  return extractValueImports(source).filter((specifier) => !specifier.startsWith("."));
184
211
  }
185
212
 
213
+ /**
214
+ * Every STATIC bare value import of a source file.
215
+ *
216
+ * A static bare import is a package the module needs when it is loaded.
217
+ * The published package must declare it, or the consumer cannot import
218
+ * the module at all.
219
+ */
220
+ export function extractStaticBareImports(source: string): string[] {
221
+ return extractStaticValueImports(source).filter(
222
+ (specifier) => !specifier.startsWith("."),
223
+ );
224
+ }
225
+
186
226
  /**
187
227
  * The package a specifier names.
188
228
  *
@@ -194,6 +234,152 @@ export function packageNameOf(specifier: string): string {
194
234
  return specifier.split("/")[0];
195
235
  }
196
236
 
237
+ /** Is the character part of an identifier? */
238
+ function isWordChar(char: string | undefined): boolean {
239
+ return char !== undefined && /[A-Za-z0-9_$]/.test(char);
240
+ }
241
+
242
+ /**
243
+ * Every `require(...)` call that runs when the module is loaded.
244
+ *
245
+ * The published package is an ES module (`"type": "module"`), and Node has
246
+ * no `require` in an ES module. A `require` in the body of a function is
247
+ * harmless as long as nobody calls that function - but a `require` at the
248
+ * top level of the module throws the moment the module is imported.
249
+ *
250
+ * The scanner walks the code and counts the braces, so it knows whether a
251
+ * call sits inside a function body. The content of a string or a template
252
+ * literal is not code and is skipped.
253
+ */
254
+ /**
255
+ * The blocks that are not a function body.
256
+ *
257
+ * A `require` inside one of them still runs when the module is loaded:
258
+ * `if (cond) { require("x") }` is a load time call, not a call that waits
259
+ * for a function to run.
260
+ */
261
+ const LOAD_TIME_BLOCK_KEYWORDS =
262
+ /^(?:if|for|while|switch|try|catch|finally|do|else|class|enum)\b/;
263
+
264
+ /**
265
+ * A `require` call in a source file.
266
+ */
267
+ export interface RequireCall {
268
+ /** The module the call names. */
269
+ specifier: string;
270
+ /** Whether the call runs when the module is loaded. */
271
+ moduleScope: boolean;
272
+ }
273
+
274
+ /**
275
+ * Every `require` call of a source file.
276
+ *
277
+ * The scope analysis is textual: a block opens a function scope unless it
278
+ * belongs to a statement that runs at load time, and an arrow function
279
+ * with an expression body ends with its statement.
280
+ */
281
+ export function findRequireCalls(source: string): RequireCall[] {
282
+ const { code, isCodeAt } = scanSource(source);
283
+ const calls: RequireCall[] = [];
284
+ let functionDepth = 0;
285
+ let arrowDepth = 0;
286
+
287
+ for (let i = 0; i < code.length; i += 1) {
288
+ if (!isCodeAt(i)) continue;
289
+ const char = code[i];
290
+ if (char === "{") {
291
+ if (!opensLoadTimeBlock(code, i)) functionDepth += 1;
292
+ continue;
293
+ }
294
+ if (char === "}") {
295
+ functionDepth -= 1;
296
+ continue;
297
+ }
298
+ if (char === ";" && functionDepth === 0) {
299
+ // The end of a statement ends an arrow function whose body is
300
+ // an expression: `const load = () => require("x");`.
301
+ arrowDepth = 0;
302
+ continue;
303
+ }
304
+ if (char === "=" && code[i + 1] === ">") {
305
+ if (functionDepth === 0) arrowDepth += 1;
306
+ i += 1;
307
+ continue;
308
+ }
309
+ if (!code.startsWith("require", i)) continue;
310
+ if (isWordChar(code[i - 1]) || isWordChar(code[i + 7])) continue;
311
+ let j = i + 7;
312
+ while (j < code.length && /\s/.test(code[j])) j += 1;
313
+ if (code[j] !== "(") continue;
314
+ const end = code.indexOf(")", j);
315
+ const argument = code.slice(j + 1, end === -1 ? j + 1 : end).trim();
316
+ // A call inside a call at the top level still runs at load time.
317
+ const moduleScope = functionDepth === 0 && arrowDepth === 0;
318
+ calls.push({ specifier: unquoteSpecifier(argument), moduleScope });
319
+ i = j;
320
+ }
321
+
322
+ return calls;
323
+ }
324
+
325
+ /**
326
+ * Every `require` that runs when the module is loaded.
327
+ *
328
+ * The published package is an ES module and Node has no `require` there:
329
+ * a call at the top level of a module throws the moment the module is
330
+ * imported. A `require` inside a function body only runs when that
331
+ * function runs, so it is not a problem for the import itself.
332
+ */
333
+ export function findModuleScopeRequires(source: string): string[] {
334
+ return findRequireCalls(source)
335
+ .filter((call) => call.moduleScope)
336
+ .map((call) => call.specifier);
337
+ }
338
+
339
+ /**
340
+ * Whether the file creates its own `require`.
341
+ *
342
+ * An ES module has no `require`, but a module that builds one with
343
+ * `createRequire` owns a working `require`. Such a file is not broken by
344
+ * a `require` call.
345
+ */
346
+ export function hasLocalRequire(source: string): boolean {
347
+ return /(?:const|let|var)\s+require\s*=\s*createRequire\s*\(/.test(source);
348
+ }
349
+
350
+ /**
351
+ * Whether the block that starts at the given position runs at load time.
352
+ *
353
+ * The text between the block and the statement before it names the kind of
354
+ * the block: `try {` is a load time block, `function read() {` is a
355
+ * function scope.
356
+ */
357
+ function opensLoadTimeBlock(code: string, braceIndex: number): boolean {
358
+ let start = braceIndex - 1;
359
+ while (start >= 0) {
360
+ const char = code[start];
361
+ if (char === ";" || char === "{" || char === "}") {
362
+ start += 1;
363
+ break;
364
+ }
365
+ start -= 1;
366
+ }
367
+ if (start < 0) start = 0;
368
+ const statement = code.slice(start, braceIndex).trim();
369
+ return LOAD_TIME_BLOCK_KEYWORDS.test(statement);
370
+ }
371
+
372
+ /** Remove the quotes of a module specifier. */
373
+ function unquoteSpecifier(specifier: string): string {
374
+ if (specifier.length < 2) return specifier;
375
+ const first = specifier[0];
376
+ const last = specifier[specifier.length - 1];
377
+ if ((first === '"' || first === "'") && first === last) {
378
+ return specifier.slice(1, -1);
379
+ }
380
+ return specifier;
381
+ }
382
+
197
383
  /**
198
384
  * The files a relative specifier may point at.
199
385
  *
@@ -84,9 +84,11 @@ async function setWorkspaceVersion(
84
84
  return;
85
85
  }
86
86
  pkg.version = version;
87
- // Re-serialize via JSON.parse→stringify to collapse any duplicate keys
88
- // (duplicate "version" keys are valid JSON but cause bun install to warn/fail)
89
- await writeFile(pkgPath, `${JSON.stringify(JSON.parse(JSON.stringify(pkg)), null, 2)}\n`);
87
+ // The parse above already collapsed any duplicate keys (a duplicate
88
+ // "version" key is valid JSON but makes bun install warn or fail), so the
89
+ // plain serialization is enough. It cannot throw: the value came from
90
+ // JSON.parse and holds nothing but JSON types.
91
+ await writeFile(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
90
92
  const name =
91
93
  typeof pkg.name === "string"
92
94
  ? `${pkg.name}@${version}`
@@ -14,6 +14,8 @@
14
14
  import { existsSync, writeFileSync, appendFileSync, readFileSync } from "node:fs";
15
15
  import { join } from "node:path";
16
16
  import { createServer } from "node:http";
17
+ import { createRequire } from "node:module";
18
+ const require = createRequire(import.meta.url);
17
19
 
18
20
  // --- Configuration ---
19
21
  const BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN;
@@ -26,23 +26,26 @@ import { join, relative } from "node:path";
26
26
  * Maximum tolerated number of type errors per project. A project that is
27
27
  * not listed must type check cleanly.
28
28
  */
29
+ // Every project type checks cleanly. A non-zero entry is a debt that hides
30
+ // a real error, so the baseline stays at zero until a project genuinely
31
+ // compiles.
29
32
  const BASELINES = new Map([
30
33
  ["a2a-adapter", 0],
31
- ["clipboard-plugin", 1],
34
+ ["clipboard-plugin", 0],
32
35
  ["provider-router", 0],
33
36
  ["providers", 0],
34
37
  ["quota-manager", 0],
35
38
  ["runtime", 0],
36
- ["voice-api", 16],
39
+ ["voice-api", 0],
37
40
  ["worktree", 0],
38
- ["harness", 20],
41
+ ["harness", 0],
39
42
  // The scripts of the repository type check cleanly. The project
40
43
  // lives in `scripts/tsconfig.json`, so the language server reads the
41
44
  // same configuration as the compiler and no longer answers with a
42
45
  // project that has no node types.
43
46
  ["scripts", 0],
44
47
  ["scripts/release", 0],
45
- ["root", 2],
48
+ ["root", 0],
46
49
  ["new-modules", 0],
47
50
  ]);
48
51
 
@@ -28,11 +28,15 @@
28
28
 
29
29
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
30
30
  import { execFile, spawnSync } from "node:child_process";
31
+ import { builtinModules } from "node:module";
31
32
  import { join, resolve, dirname, relative } from "node:path";
32
33
  import { fileURLToPath } from "node:url";
33
34
  import {
34
35
  extractBareImports,
35
36
  extractRelativeValueImports,
37
+ extractStaticBareImports,
38
+ findRequireCalls,
39
+ hasLocalRequire,
36
40
  packageNameOf,
37
41
  resolveRelativeImport,
38
42
  } from "./lib/runtime-imports.js";
@@ -55,7 +59,9 @@ interface Problem {
55
59
  | "missing-package"
56
60
  | "forbidden-path"
57
61
  | "missing-plugin"
58
- | "sensitive-content";
62
+ | "sensitive-content"
63
+ | "undeclared-dependency"
64
+ | "esm-require";
59
65
  detail: string;
60
66
  }
61
67
 
@@ -269,11 +275,17 @@ function checkSensitiveContent(files: string[]): void {
269
275
  );
270
276
  return;
271
277
  }
278
+ // A file that cannot be read is a file that was not checked. The
279
+ // check fails closed for the same reason it fails closed on a
280
+ // missing term list: "nothing was found" must not mean "nothing
281
+ // was looked at".
282
+ let unreadable = 0;
272
283
  for (const file of files) {
273
284
  let content: string;
274
285
  try {
275
286
  content = readFileSync(join(ROOT, file), "utf8");
276
287
  } catch {
288
+ unreadable++;
277
289
  continue;
278
290
  }
279
291
  for (const found of scanText(content, file, terms)) {
@@ -284,8 +296,14 @@ function checkSensitiveContent(files: string[]): void {
284
296
  }
285
297
  }
286
298
  console.log(
287
- `[verify-package-contents] the sensitive content scan looked at ${files.length} published file(s) with the list of ${source}`,
299
+ `[verify-package-contents] the sensitive content scan looked at ${files.length - unreadable} published file(s) with the list of ${source}`,
288
300
  );
301
+ if (unreadable > 0) {
302
+ problems.push({
303
+ kind: "sensitive-content",
304
+ detail: `${unreadable} published file(s) could not be read, so the sensitive content scan did not cover them`,
305
+ });
306
+ }
289
307
  }
290
308
 
291
309
  /**
@@ -559,6 +577,7 @@ function workspacePackageNames(): Set<string> {
559
577
  function checkRelativeImports(files: string[]): void {
560
578
  const published = new Set(files);
561
579
  const workspaceNames = workspacePackageNames();
580
+
562
581
  for (const path of files) {
563
582
  if (!/\.(ts|mts|cts|mjs|js|cjs)$/.test(path)) continue;
564
583
  if (path.endsWith(".d.ts") || path.endsWith(".d.mts")) continue;
@@ -593,6 +612,144 @@ function checkRelativeImports(files: string[]): void {
593
612
  }
594
613
  }
595
614
 
615
+ /**
616
+ * Every package that the published package declares.
617
+ *
618
+ * The consumer installs one package, so that one package has to carry the
619
+ * dependencies of every module it ships. A module that imports a package
620
+ * the manifest does not name cannot be imported by the consumer: the
621
+ * dependency is missing from the install.
622
+ *
623
+ * A dynamic import is a different case: it is resolved when the code
624
+ * reaches it, so a module that loads one at run time may treat it as an
625
+ * optional dependency. Only a static import is checked here.
626
+ */
627
+ function declaredDependencyNames(): Set<string> {
628
+ const names = new Set<string>();
629
+ let manifest: {
630
+ dependencies?: Record<string, string>;
631
+ optionalDependencies?: Record<string, string>;
632
+ peerDependencies?: Record<string, string>;
633
+ };
634
+ try {
635
+ manifest = JSON.parse(readFileSync(join(ROOT, "package.json"), "utf8"));
636
+ } catch {
637
+ return names;
638
+ }
639
+ for (const group of [
640
+ manifest.dependencies,
641
+ manifest.optionalDependencies,
642
+ manifest.peerDependencies,
643
+ ]) {
644
+ for (const name of Object.keys(group ?? {})) names.add(name);
645
+ }
646
+ return names;
647
+ }
648
+
649
+ /**
650
+ * The names that a published module may import without a declaration.
651
+ *
652
+ * A Node builtin is always there. A test runner is only there when the
653
+ * tests run, and a published module never imports one at run time.
654
+ */
655
+ const ALWAYS_AVAILABLE_NAMES = new Set([
656
+ ...builtinModules,
657
+ ...builtinModules.map((name) => `node:${name}`),
658
+ "bun:test",
659
+ "node:test",
660
+ ]);
661
+
662
+ /**
663
+ * Every static import of a published file must name a declared package.
664
+ *
665
+ * The check runs on the file list that npm itself produced, so it covers
666
+ * exactly what a consumer receives - the compiled output included.
667
+ */
668
+ function checkDeclaredDependencies(files: string[]): void {
669
+ const declared = declaredDependencyNames();
670
+ const workspaces = workspacePackageNames();
671
+ for (const path of files) {
672
+ if (!/\.(ts|mts|cts|mjs|js|cjs)$/.test(path)) continue;
673
+ if (path.endsWith(".d.ts") || path.endsWith(".d.mts")) continue;
674
+ const full = join(ROOT, path);
675
+ if (!existsSync(full)) continue;
676
+ const content = readFileSync(full, "utf8");
677
+ for (const specifier of extractStaticBareImports(content)) {
678
+ const name = packageNameOf(specifier);
679
+ if (!name) continue;
680
+ if (ALWAYS_AVAILABLE_NAMES.has(name)) continue;
681
+ if (declared.has(name) || workspaces.has(name)) continue;
682
+ problems.push({
683
+ kind: "undeclared-dependency",
684
+ detail: `${path} imports ${name}, which the published package does not declare - a consumer cannot import this module`,
685
+ });
686
+ }
687
+ }
688
+ }
689
+
690
+ /**
691
+ * A published module must not call `require` when it is loaded.
692
+ *
693
+ * The published package is an ES module (`"type": "module"`), and Node
694
+ * has no `require` there: a call at the top level of a module throws the
695
+ * moment the module is imported. A `require` inside a function is only a
696
+ * problem when that function runs, so only the module scope is checked.
697
+ */
698
+ /**
699
+ * The module system of a published file.
700
+ *
701
+ * A file that belongs to a CommonJS package may call `require`. A file
702
+ * that belongs to an ES module may not: Node has no `require` there.
703
+ */
704
+ function moduleTypeOf(path: string): "module" | "commonjs" {
705
+ let dir = dirname(resolve(ROOT, path));
706
+ for (;;) {
707
+ const manifestPath = join(dir, "package.json");
708
+ if (existsSync(manifestPath)) {
709
+ try {
710
+ const manifest = JSON.parse(readFileSync(manifestPath, "utf8")) as {
711
+ type?: string;
712
+ };
713
+ return manifest.type === "commonjs" ? "commonjs" : "module";
714
+ } catch {
715
+ return "module";
716
+ }
717
+ }
718
+ const parent = dirname(dir);
719
+ if (parent === dir) return "module";
720
+ dir = parent;
721
+ }
722
+ }
723
+
724
+ /**
725
+ * A published module must not call the global `require`.
726
+ *
727
+ * The published package is an ES module, and Node has no `require` there:
728
+ * a call at the top level of a module throws the moment the module is
729
+ * imported, and a call inside a function throws when that function runs.
730
+ *
731
+ * A module that builds its own `require` with `createRequire` owns a
732
+ * working `require` and is not affected.
733
+ */
734
+ function checkModuleScopeRequires(files: string[]): void {
735
+ for (const path of files) {
736
+ if (!path.endsWith(".js")) continue;
737
+ if (moduleTypeOf(path) !== "module") continue;
738
+ const full = join(ROOT, path);
739
+ if (!existsSync(full)) continue;
740
+ const content = readFileSync(full, "utf8");
741
+ if (hasLocalRequire(content)) continue;
742
+ for (const call of findRequireCalls(content)) {
743
+ problems.push({
744
+ kind: "esm-require",
745
+ detail: call.moduleScope
746
+ ? `${path} calls require(${call.specifier}) when the module is loaded, but the published package is an ES module`
747
+ : `${path} calls require(${call.specifier}), but the published package is an ES module and has no require`,
748
+ });
749
+ }
750
+ }
751
+ }
752
+
596
753
  /** The tarball npm would publish must contain the built output. */
597
754
  function inspectTarball(files: string[]): void {
598
755
  for (const file of files) {
@@ -663,6 +820,8 @@ if (publishedFiles.length === 0) {
663
820
  });
664
821
  } else {
665
822
  checkRelativeImports(publishedFiles);
823
+ checkDeclaredDependencies(publishedFiles);
824
+ checkModuleScopeRequires(publishedFiles);
666
825
  checkSensitiveContent(publishedFiles);
667
826
  if (verifyTarball) inspectTarball(publishedFiles);
668
827
  }