codetrellis 0.0.0-stage → 0.3.0

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 (448) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +27 -2
  3. package/bin/codetrellis.mjs +4 -0
  4. package/package.json +41 -4
  5. package/reader/material-reader.mjs +130346 -0
  6. package/resources/tree-sitter/README.md +150 -0
  7. package/resources/tree-sitter/tree-sitter-c-sharp.wasm +0 -0
  8. package/resources/tree-sitter/tree-sitter-go.wasm +0 -0
  9. package/resources/tree-sitter/tree-sitter-java.wasm +0 -0
  10. package/resources/tree-sitter/tree-sitter-javascript.wasm +0 -0
  11. package/resources/tree-sitter/tree-sitter-kotlin.wasm +0 -0
  12. package/resources/tree-sitter/tree-sitter-php.wasm +0 -0
  13. package/resources/tree-sitter/tree-sitter-python.wasm +0 -0
  14. package/resources/tree-sitter/tree-sitter-ruby.wasm +0 -0
  15. package/resources/tree-sitter/tree-sitter-rust.wasm +0 -0
  16. package/resources/tree-sitter/tree-sitter-swift.wasm +0 -0
  17. package/resources/tree-sitter/tree-sitter-tsx.wasm +0 -0
  18. package/resources/tree-sitter/tree-sitter-typescript.wasm +0 -0
  19. package/resources/tree-sitter/tree-sitter.wasm +0 -0
  20. package/src/backend/agent/claude-code-watcher.js +270 -0
  21. package/src/backend/index.js +8 -0
  22. package/src/backend/lib/sha256-file.js +39 -0
  23. package/src/backend/lib/zip-entries.js +98 -0
  24. package/src/backend/lifecycle.js +102 -0
  25. package/src/backend/mcp/binding-headers.js +54 -0
  26. package/src/backend/mcp/client-identity.js +44 -0
  27. package/src/backend/mcp/connector/command.js +110 -0
  28. package/src/backend/mcp/connector/core.js +278 -0
  29. package/src/backend/mcp/connector/files.js +121 -0
  30. package/src/backend/mcp/connector/hook.js +284 -0
  31. package/src/backend/mcp/connector/main.js +126 -0
  32. package/src/backend/mcp/connector/sse-upstream.js +152 -0
  33. package/src/backend/mcp/helpers.js +43 -0
  34. package/src/backend/mcp/prompt-builders.js +104 -0
  35. package/src/backend/mcp/resources.js +197 -0
  36. package/src/backend/mcp/server.js +813 -0
  37. package/src/backend/mcp/skill-guide.js +1528 -0
  38. package/src/backend/mcp/tools/architecture-tools.js +273 -0
  39. package/src/backend/mcp/tools/audio-tools.js +117 -0
  40. package/src/backend/mcp/tools/awareness-tools.js +623 -0
  41. package/src/backend/mcp/tools/budget-tools.js +185 -0
  42. package/src/backend/mcp/tools/channel-tools.js +205 -0
  43. package/src/backend/mcp/tools/contribution-tools.js +181 -0
  44. package/src/backend/mcp/tools/drift-tools.js +252 -0
  45. package/src/backend/mcp/tools/git-tools.js +316 -0
  46. package/src/backend/mcp/tools/governance-tools.js +175 -0
  47. package/src/backend/mcp/tools/graph-tools.js +181 -0
  48. package/src/backend/mcp/tools/intake-tools.js +244 -0
  49. package/src/backend/mcp/tools/mobile-tools.js +118 -0
  50. package/src/backend/mcp/tools/peer-tools.js +330 -0
  51. package/src/backend/mcp/tools/plan-item-tools.js +1601 -0
  52. package/src/backend/mcp/tools/plan-tools.js +680 -0
  53. package/src/backend/mcp/tools/presence-tools.js +185 -0
  54. package/src/backend/mcp/tools/project-config-tools.js +150 -0
  55. package/src/backend/mcp/tools/review-tools.js +172 -0
  56. package/src/backend/mcp/tools/session-tools.js +554 -0
  57. package/src/backend/mcp/tools/system-docs-tools.js +168 -0
  58. package/src/backend/mcp/tools/terminal-tools.js +186 -0
  59. package/src/backend/mcp/tools/test-tools.js +117 -0
  60. package/src/backend/mcp/tools/ui-tools.js +356 -0
  61. package/src/backend/mcp/types.js +15 -0
  62. package/src/backend/middleware/local-auth.js +116 -0
  63. package/src/backend/server.js +5951 -0
  64. package/src/backend/services/agent-event-log.js +350 -0
  65. package/src/backend/services/architecture-rule.js +584 -0
  66. package/src/backend/services/architecture-rules.js +275 -0
  67. package/src/backend/services/artefact-content-service.js +181 -0
  68. package/src/backend/services/artefact-service.js +305 -0
  69. package/src/backend/services/artefact-watcher.js +167 -0
  70. package/src/backend/services/ast-parser.js +327 -0
  71. package/src/backend/services/audio-buffer-service.js +152 -0
  72. package/src/backend/services/awareness-notices.js +139 -0
  73. package/src/backend/services/awareness-replies.js +194 -0
  74. package/src/backend/services/awareness-service.js +344 -0
  75. package/src/backend/services/awareness-signals.js +267 -0
  76. package/src/backend/services/baseline-store.js +83 -0
  77. package/src/backend/services/branch-workstreams.js +341 -0
  78. package/src/backend/services/breakpoint-service.js +584 -0
  79. package/src/backend/services/brief-service.js +299 -0
  80. package/src/backend/services/budget-service.js +528 -0
  81. package/src/backend/services/callsites/base.js +15 -0
  82. package/src/backend/services/callsites/csharp.js +148 -0
  83. package/src/backend/services/callsites/go.js +163 -0
  84. package/src/backend/services/callsites/index.js +53 -0
  85. package/src/backend/services/callsites/kotlin.js +123 -0
  86. package/src/backend/services/callsites/process-env.js +125 -0
  87. package/src/backend/services/callsites/python.js +91 -0
  88. package/src/backend/services/callsites/ruby.js +164 -0
  89. package/src/backend/services/callsites/shared.js +198 -0
  90. package/src/backend/services/callsites/swift.js +115 -0
  91. package/src/backend/services/callsites/typescript.js +87 -0
  92. package/src/backend/services/capability-token.js +108 -0
  93. package/src/backend/services/change-check.js +156 -0
  94. package/src/backend/services/channel-dispatcher-service.js +235 -0
  95. package/src/backend/services/channel-event-file-service.js +125 -0
  96. package/src/backend/services/channel-event-service.js +297 -0
  97. package/src/backend/services/check-runs.js +177 -0
  98. package/src/backend/services/checkout-identity.js +73 -0
  99. package/src/backend/services/claude-code-parallel.js +221 -0
  100. package/src/backend/services/claude-desktop-config.js +186 -0
  101. package/src/backend/services/cli-install.js +249 -0
  102. package/src/backend/services/clock.js +57 -0
  103. package/src/backend/services/cloud-files.js +191 -0
  104. package/src/backend/services/coalesce.js +50 -0
  105. package/src/backend/services/code-breakpoints.js +291 -0
  106. package/src/backend/services/comment-service.js +168 -0
  107. package/src/backend/services/commit-attribution.js +134 -0
  108. package/src/backend/services/commit-edges.js +99 -0
  109. package/src/backend/services/confined-fs.js +241 -0
  110. package/src/backend/services/conformity-gate.js +132 -0
  111. package/src/backend/services/contribution-service.js +409 -0
  112. package/src/backend/services/coverage-service.js +173 -0
  113. package/src/backend/services/criteria-service.js +721 -0
  114. package/src/backend/services/criterion-checks.js +387 -0
  115. package/src/backend/services/criterion-loop-service.js +411 -0
  116. package/src/backend/services/cross-system-service.js +231 -0
  117. package/src/backend/services/database.js +916 -0
  118. package/src/backend/services/db-schema.js +1358 -0
  119. package/src/backend/services/deviation-service.js +344 -0
  120. package/src/backend/services/diff-engine.js +168 -0
  121. package/src/backend/services/evidence.js +363 -0
  122. package/src/backend/services/external-intake-service.js +269 -0
  123. package/src/backend/services/external-pointer-service.js +195 -0
  124. package/src/backend/services/external-refs-service.js +214 -0
  125. package/src/backend/services/file-history.js +158 -0
  126. package/src/backend/services/file-watcher.js +193 -0
  127. package/src/backend/services/folder-requests.js +118 -0
  128. package/src/backend/services/freeze-service.js +189 -0
  129. package/src/backend/services/gemini-cli-hook.js +172 -0
  130. package/src/backend/services/git-activity-service.js +325 -0
  131. package/src/backend/services/git-blobs.js +70 -0
  132. package/src/backend/services/git-branches.js +357 -0
  133. package/src/backend/services/git-checkout.js +153 -0
  134. package/src/backend/services/git-commit-service.js +91 -0
  135. package/src/backend/services/git-env.js +121 -0
  136. package/src/backend/services/git-identity.js +84 -0
  137. package/src/backend/services/git-refs.js +386 -0
  138. package/src/backend/services/git-safety.js +58 -0
  139. package/src/backend/services/grant-guard.js +67 -0
  140. package/src/backend/services/html-view-policy.js +135 -0
  141. package/src/backend/services/human-decision.js +55 -0
  142. package/src/backend/services/importers.js +159 -0
  143. package/src/backend/services/intent-service.js +105 -0
  144. package/src/backend/services/ipc-dispatcher.js +164 -0
  145. package/src/backend/services/item-git-state.js +208 -0
  146. package/src/backend/services/line-changes.js +232 -0
  147. package/src/backend/services/line-history.js +174 -0
  148. package/src/backend/services/local-api-changes.js +40 -0
  149. package/src/backend/services/logger.js +217 -0
  150. package/src/backend/services/material-footprints.js +203 -0
  151. package/src/backend/services/material-place.js +82 -0
  152. package/src/backend/services/material-reader/docx-markdown.js +198 -0
  153. package/src/backend/services/material-reader/fixtures.test-helper.js +169 -0
  154. package/src/backend/services/material-reader/quote.js +44 -0
  155. package/src/backend/services/material-reader/reader-host.js +202 -0
  156. package/src/backend/services/material-signals.js +141 -0
  157. package/src/backend/services/mcp-capabilities.js +390 -0
  158. package/src/backend/services/mdns-service.js +304 -0
  159. package/src/backend/services/mobile-api-server.js +281 -0
  160. package/src/backend/services/mobile-approvals.js +306 -0
  161. package/src/backend/services/mobile-awareness.js +180 -0
  162. package/src/backend/services/mobile-breakpoints.js +115 -0
  163. package/src/backend/services/mobile-budget.js +98 -0
  164. package/src/backend/services/mobile-freeze.js +106 -0
  165. package/src/backend/services/mobile-proposals.js +100 -0
  166. package/src/backend/services/mobile-rpc-service.js +1289 -0
  167. package/src/backend/services/mobile-workstreams.js +160 -0
  168. package/src/backend/services/monorepo-detector.js +131 -0
  169. package/src/backend/services/other-work.js +45 -0
  170. package/src/backend/services/pack-seal.js +129 -0
  171. package/src/backend/services/paired-device-service.js +192 -0
  172. package/src/backend/services/pairing-server.js +323 -0
  173. package/src/backend/services/pairing-service.js +200 -0
  174. package/src/backend/services/pantry-resolution-service.js +166 -0
  175. package/src/backend/services/parsers/base.js +124 -0
  176. package/src/backend/services/parsers/csharp.js +224 -0
  177. package/src/backend/services/parsers/go.js +180 -0
  178. package/src/backend/services/parsers/index.js +101 -0
  179. package/src/backend/services/parsers/java.js +103 -0
  180. package/src/backend/services/parsers/kotlin.js +252 -0
  181. package/src/backend/services/parsers/php.js +113 -0
  182. package/src/backend/services/parsers/python.js +189 -0
  183. package/src/backend/services/parsers/ruby.js +212 -0
  184. package/src/backend/services/parsers/rust.js +97 -0
  185. package/src/backend/services/parsers/swift.js +221 -0
  186. package/src/backend/services/parsers/typescript.js +235 -0
  187. package/src/backend/services/pattern-scan.js +65 -0
  188. package/src/backend/services/patterns.js +281 -0
  189. package/src/backend/services/peer-audit-service.js +123 -0
  190. package/src/backend/services/peer-auth.js +153 -0
  191. package/src/backend/services/peer-capabilities.js +209 -0
  192. package/src/backend/services/peer-connection-service.js +450 -0
  193. package/src/backend/services/peer-grants.js +33 -0
  194. package/src/backend/services/persistence.js +116 -0
  195. package/src/backend/services/personal-sync-service.js +232 -0
  196. package/src/backend/services/pipeline-approvals.js +72 -0
  197. package/src/backend/services/pipeline.js +232 -0
  198. package/src/backend/services/plan-arrivals.js +68 -0
  199. package/src/backend/services/plan-changes-service.js +273 -0
  200. package/src/backend/services/plan-conflict-service.js +288 -0
  201. package/src/backend/services/plan-dependencies.js +91 -0
  202. package/src/backend/services/plan-doc-guard.js +90 -0
  203. package/src/backend/services/plan-documents-service.js +275 -0
  204. package/src/backend/services/plan-event-service.js +154 -0
  205. package/src/backend/services/plan-file-refs.js +106 -0
  206. package/src/backend/services/plan-file-service.js +1564 -0
  207. package/src/backend/services/plan-history-service.js +156 -0
  208. package/src/backend/services/plan-import-service.js +261 -0
  209. package/src/backend/services/plan-item-service.js +1223 -0
  210. package/src/backend/services/plan-migrate-service.js +395 -0
  211. package/src/backend/services/plan-overlay-service.js +173 -0
  212. package/src/backend/services/plan-phases-service.js +182 -0
  213. package/src/backend/services/plan-progress-service.js +134 -0
  214. package/src/backend/services/plan-review-service.js +262 -0
  215. package/src/backend/services/plan-service.js +682 -0
  216. package/src/backend/services/plan-status.js +113 -0
  217. package/src/backend/services/plan-template-publish-service.js +217 -0
  218. package/src/backend/services/plan-templates-service.js +242 -0
  219. package/src/backend/services/plan-templates.js +1164 -0
  220. package/src/backend/services/planned-overlap-actions.js +200 -0
  221. package/src/backend/services/plans-home.js +224 -0
  222. package/src/backend/services/play-forward.js +256 -0
  223. package/src/backend/services/playback-service.js +117 -0
  224. package/src/backend/services/power-service.js +167 -0
  225. package/src/backend/services/power-signals.js +81 -0
  226. package/src/backend/services/pr-draft-service.js +142 -0
  227. package/src/backend/services/presence-service.js +122 -0
  228. package/src/backend/services/pricing.js +60 -0
  229. package/src/backend/services/project-config-service.js +474 -0
  230. package/src/backend/services/project-scanner.js +184 -0
  231. package/src/backend/services/projection-service.js +69 -0
  232. package/src/backend/services/push-notification-service.js +288 -0
  233. package/src/backend/services/recent-projects-service.js +204 -0
  234. package/src/backend/services/record-chain.js +162 -0
  235. package/src/backend/services/recurrence-rule.js +63 -0
  236. package/src/backend/services/recurring-agent.js +89 -0
  237. package/src/backend/services/recurring-scheduler.js +77 -0
  238. package/src/backend/services/recurring-service.js +276 -0
  239. package/src/backend/services/reference-service.js +169 -0
  240. package/src/backend/services/release-public-key.js +30 -0
  241. package/src/backend/services/release-signature.js +64 -0
  242. package/src/backend/services/remote-audio-service.js +224 -0
  243. package/src/backend/services/remote-interaction-service.js +275 -0
  244. package/src/backend/services/remote-terminal-service.js +324 -0
  245. package/src/backend/services/rendition/child/main.js +76 -0
  246. package/src/backend/services/rendition/engine-host.js +249 -0
  247. package/src/backend/services/rendition/engine-lock.js +39 -0
  248. package/src/backend/services/rendition/engine-lock.json +14 -0
  249. package/src/backend/services/rendition/engine-manifest.js +97 -0
  250. package/src/backend/services/rendition/network-proof.js +73 -0
  251. package/src/backend/services/rendition/rendition-service.js +175 -0
  252. package/src/backend/services/replay-frames.js +387 -0
  253. package/src/backend/services/replay-state.js +201 -0
  254. package/src/backend/services/resolvers/base.js +108 -0
  255. package/src/backend/services/resolvers/csharp.js +109 -0
  256. package/src/backend/services/resolvers/go.js +105 -0
  257. package/src/backend/services/resolvers/index.js +60 -0
  258. package/src/backend/services/resolvers/java.js +63 -0
  259. package/src/backend/services/resolvers/kotlin.js +109 -0
  260. package/src/backend/services/resolvers/php.js +89 -0
  261. package/src/backend/services/resolvers/python.js +154 -0
  262. package/src/backend/services/resolvers/ruby.js +103 -0
  263. package/src/backend/services/resolvers/rust.js +77 -0
  264. package/src/backend/services/resolvers/swift.js +98 -0
  265. package/src/backend/services/resolvers/typescript.js +71 -0
  266. package/src/backend/services/retention.js +54 -0
  267. package/src/backend/services/review-architecture.js +236 -0
  268. package/src/backend/services/review-attest.js +68 -0
  269. package/src/backend/services/review-bundle.js +226 -0
  270. package/src/backend/services/review-graduation.js +93 -0
  271. package/src/backend/services/review-host/bitbucket.js +79 -0
  272. package/src/backend/services/review-host/detect.js +80 -0
  273. package/src/backend/services/review-host/github.js +97 -0
  274. package/src/backend/services/review-host/gitlab.js +77 -0
  275. package/src/backend/services/review-host/host-state.js +103 -0
  276. package/src/backend/services/review-host/http.js +58 -0
  277. package/src/backend/services/review-host/switch.js +120 -0
  278. package/src/backend/services/review-marks.js +72 -0
  279. package/src/backend/services/review-notes.js +169 -0
  280. package/src/backend/services/review-other-work.js +90 -0
  281. package/src/backend/services/review-queue-service.js +147 -0
  282. package/src/backend/services/review-risk.js +127 -0
  283. package/src/backend/services/review-task.js +121 -0
  284. package/src/backend/services/rule-approvals.js +275 -0
  285. package/src/backend/services/rule-baseline.js +134 -0
  286. package/src/backend/services/rule-changes.js +162 -0
  287. package/src/backend/services/rule-preview.js +47 -0
  288. package/src/backend/services/rule-proposals.js +104 -0
  289. package/src/backend/services/rule-scope.js +76 -0
  290. package/src/backend/services/rulebook.js +286 -0
  291. package/src/backend/services/rules-at.js +56 -0
  292. package/src/backend/services/rules-overview.js +88 -0
  293. package/src/backend/services/schema-reconciler.js +250 -0
  294. package/src/backend/services/secret-store.js +119 -0
  295. package/src/backend/services/section-workstreams.js +95 -0
  296. package/src/backend/services/self-write-tracker.js +75 -0
  297. package/src/backend/services/sensor-bridge-service.js +285 -0
  298. package/src/backend/services/session-service.js +192 -0
  299. package/src/backend/services/settings-service.js +324 -0
  300. package/src/backend/services/signal-breakpoints.js +172 -0
  301. package/src/backend/services/signed-approval-record.js +86 -0
  302. package/src/backend/services/signed-approvals.js +244 -0
  303. package/src/backend/services/signoff-pack.js +328 -0
  304. package/src/backend/services/signoff-rows.js +114 -0
  305. package/src/backend/services/skill-arrival-service.js +138 -0
  306. package/src/backend/services/skill-model.js +193 -0
  307. package/src/backend/services/skill-use-service.js +140 -0
  308. package/src/backend/services/skills-service.js +150 -0
  309. package/src/backend/services/snapshot-compare-service.js +397 -0
  310. package/src/backend/services/source-control.js +189 -0
  311. package/src/backend/services/spec-links-service.js +123 -0
  312. package/src/backend/services/spec-proposal-withdraw.js +50 -0
  313. package/src/backend/services/spec-proposals-service.js +470 -0
  314. package/src/backend/services/sql/embedded.js +95 -0
  315. package/src/backend/services/sql/index.js +63 -0
  316. package/src/backend/services/sql/refs.js +357 -0
  317. package/src/backend/services/sql/schema.js +312 -0
  318. package/src/backend/services/sql/tokenizer.js +195 -0
  319. package/src/backend/services/stack-overlaps.js +117 -0
  320. package/src/backend/services/stack-service.js +225 -0
  321. package/src/backend/services/state-sync-service.js +384 -0
  322. package/src/backend/services/stuck-sensor-service.js +200 -0
  323. package/src/backend/services/system-discovery.js +481 -0
  324. package/src/backend/services/system-docs-service.js +701 -0
  325. package/src/backend/services/task-attachments-service.js +340 -0
  326. package/src/backend/services/task-grounding.js +60 -0
  327. package/src/backend/services/task-records/check-run-record.js +146 -0
  328. package/src/backend/services/task-records/check-runs.js +115 -0
  329. package/src/backend/services/task-records/heads.js +88 -0
  330. package/src/backend/services/task-records/material-reads.js +225 -0
  331. package/src/backend/services/task-records/read-record.js +100 -0
  332. package/src/backend/services/task-records/record.js +173 -0
  333. package/src/backend/services/task-records/run-record.js +136 -0
  334. package/src/backend/services/task-records/shared-state.js +548 -0
  335. package/src/backend/services/task-records/signing.js +140 -0
  336. package/src/backend/services/task-records/split-signals.js +52 -0
  337. package/src/backend/services/task-records/test-runs.js +164 -0
  338. package/src/backend/services/task-records/trust.js +243 -0
  339. package/src/backend/services/task-rules.js +81 -0
  340. package/src/backend/services/task-workstreams.js +90 -0
  341. package/src/backend/services/terminal-history-service.js +266 -0
  342. package/src/backend/services/terminal-service.js +267 -0
  343. package/src/backend/services/test-clock.js +53 -0
  344. package/src/backend/services/tests/grounding.js +266 -0
  345. package/src/backend/services/tests/junit.js +104 -0
  346. package/src/backend/services/tests/teammate-runs.js +134 -0
  347. package/src/backend/services/tests/test-results.js +234 -0
  348. package/src/backend/services/tree-watcher.js +204 -0
  349. package/src/backend/services/trellis-service.js +204 -0
  350. package/src/backend/services/trusted-roots.js +186 -0
  351. package/src/backend/services/update-download-service.js +342 -0
  352. package/src/backend/services/update-service.js +266 -0
  353. package/src/backend/services/watch-ignore.js +76 -0
  354. package/src/backend/services/webhook-egress.js +206 -0
  355. package/src/backend/services/webrtc-service.js +413 -0
  356. package/src/backend/services/work-changes.js +59 -0
  357. package/src/backend/services/workstream-binding.js +82 -0
  358. package/src/backend/services/workstream-commits.js +116 -0
  359. package/src/backend/services/workstream-imports.js +177 -0
  360. package/src/backend/services/workstream-service.js +335 -0
  361. package/src/backend/services/workstream-symbols.js +223 -0
  362. package/src/backend/services/workstream-watch-service.js +391 -0
  363. package/src/backend/services/worktree-service.js +235 -0
  364. package/src/cli/agent.js +100 -0
  365. package/src/cli/args.js +209 -0
  366. package/src/cli/conformity.js +106 -0
  367. package/src/cli/desktop.js +91 -0
  368. package/src/cli/main.js +411 -0
  369. package/src/cli/pipeline.js +109 -0
  370. package/src/cli/plan-verbs.js +259 -0
  371. package/src/cli/review-adapters.js +220 -0
  372. package/src/cli/review-output.js +93 -0
  373. package/src/cli/review-post.js +89 -0
  374. package/src/cli/review-sink.js +183 -0
  375. package/src/cli/review-skill.js +44 -0
  376. package/src/cli/review-verify.js +104 -0
  377. package/src/cli/review.js +386 -0
  378. package/src/cli/sarif.js +148 -0
  379. package/src/cli/verbs.js +360 -0
  380. package/src/shared/build-info.js +39 -0
  381. package/src/shared/lib/agent-review.js +199 -0
  382. package/src/shared/lib/agent-turns.js +140 -0
  383. package/src/shared/lib/awareness-digest.js +120 -0
  384. package/src/shared/lib/branch-name.js +45 -0
  385. package/src/shared/lib/breakpoint-words.js +118 -0
  386. package/src/shared/lib/budget-words.js +56 -0
  387. package/src/shared/lib/burst.js +69 -0
  388. package/src/shared/lib/call-entry.js +105 -0
  389. package/src/shared/lib/check-compare.js +42 -0
  390. package/src/shared/lib/check-words.js +216 -0
  391. package/src/shared/lib/csv.js +62 -0
  392. package/src/shared/lib/folder-entry.js +87 -0
  393. package/src/shared/lib/freeze-words.js +60 -0
  394. package/src/shared/lib/fuzzy.js +84 -0
  395. package/src/shared/lib/git-state-words.js +80 -0
  396. package/src/shared/lib/grep-entry.js +86 -0
  397. package/src/shared/lib/grounding-line.js +61 -0
  398. package/src/shared/lib/import-line.js +71 -0
  399. package/src/shared/lib/item-status.js +249 -0
  400. package/src/shared/lib/line-changes.js +53 -0
  401. package/src/shared/lib/locator.js +71 -0
  402. package/src/shared/lib/matcher.js +120 -0
  403. package/src/shared/lib/merge-order.js +65 -0
  404. package/src/shared/lib/open-findings.js +68 -0
  405. package/src/shared/lib/other-work.js +108 -0
  406. package/src/shared/lib/package-entry.js +142 -0
  407. package/src/shared/lib/plan-vocab.js +40 -0
  408. package/src/shared/lib/pptx-xml.js +86 -0
  409. package/src/shared/lib/proposal-words.js +61 -0
  410. package/src/shared/lib/recurrence.js +183 -0
  411. package/src/shared/lib/references.js +72 -0
  412. package/src/shared/lib/rule-pattern.js +56 -0
  413. package/src/shared/lib/sdp-fingerprint.js +115 -0
  414. package/src/shared/lib/sdp-minimal.js +123 -0
  415. package/src/shared/lib/secret-paths.js +34 -0
  416. package/src/shared/lib/signal-words.js +172 -0
  417. package/src/shared/lib/signoff.js +56 -0
  418. package/src/shared/lib/skills-note.js +60 -0
  419. package/src/shared/lib/spec-sections.js +78 -0
  420. package/src/shared/lib/symbol-entry.js +60 -0
  421. package/src/shared/lib/tool-phrasing.js +338 -0
  422. package/src/shared/lib/turn-gap.js +27 -0
  423. package/src/shared/lib/workstream-words.js +38 -0
  424. package/src/shared/lib/xlsx-xml.js +144 -0
  425. package/src/shared/lib/zip-reader.js +99 -0
  426. package/src/shared/types/agent.js +27 -0
  427. package/src/shared/types/architecture-rules.js +30 -0
  428. package/src/shared/types/ast.js +15 -0
  429. package/src/shared/types/breakpoint.js +33 -0
  430. package/src/shared/types/channel.js +41 -0
  431. package/src/shared/types/criteria.js +15 -0
  432. package/src/shared/types/graph.js +15 -0
  433. package/src/shared/types/index.js +53 -0
  434. package/src/shared/types/peer.js +36 -0
  435. package/src/shared/types/pipeline.js +15 -0
  436. package/src/shared/types/plan.js +15 -0
  437. package/src/shared/types/play-forward.js +15 -0
  438. package/src/shared/types/power.js +15 -0
  439. package/src/shared/types/presence.js +15 -0
  440. package/src/shared/types/project-config.js +35 -0
  441. package/src/shared/types/project.js +15 -0
  442. package/src/shared/types/record.js +15 -0
  443. package/src/shared/types/recurring.js +15 -0
  444. package/src/shared/types/review.js +15 -0
  445. package/src/shared/types/settings.js +114 -0
  446. package/src/shared/types/stack.js +15 -0
  447. package/src/shared/types/system-doc.js +15 -0
  448. package/src/shared/types/system.js +15 -0
@@ -0,0 +1,387 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+ var criterion_checks_exports = {};
29
+ __export(criterion_checks_exports, {
30
+ MAX_CHECK_READ_BYTES: () => MAX_CHECK_READ_BYTES,
31
+ MTIME_SLACK_MS: () => MTIME_SLACK_MS,
32
+ checkLocator: () => checkLocator,
33
+ junitCounts: () => junitCounts,
34
+ mp4DurationSeconds: () => mp4DurationSeconds,
35
+ pdfPageCount: () => pdfPageCount,
36
+ runChecks: () => runChecks,
37
+ workbookSheets: () => workbookSheets
38
+ });
39
+ module.exports = __toCommonJS(criterion_checks_exports);
40
+ var import_junit = require("./tests/junit");
41
+ var import_node_fs = __toESM(require("node:fs"));
42
+ var import_node_path = __toESM(require("node:path"));
43
+ var import_confined_fs = require("./confined-fs");
44
+ var import_zip_entries = require("../lib/zip-entries");
45
+ var import_xlsx_xml = require("../../shared/lib/xlsx-xml");
46
+ var import_locator = require("../../shared/lib/locator");
47
+ var import_csv = require("../../shared/lib/csv");
48
+ var import_material_place = require("./material-place");
49
+ var import_cloud_files = require("./cloud-files");
50
+ const MAX_CHECK_READ_BYTES = 50 * 1024 * 1024;
51
+ const MTIME_SLACK_MS = 2e3;
52
+ const pass = (message, attachmentUid = null) => ({ status: "pass", message, attachmentUid });
53
+ const fail = (message, attachmentUid = null) => ({ status: "fail", message, attachmentUid });
54
+ const unverified = (message, attachmentUid = null) => ({ status: "unverified", message, attachmentUid });
55
+ function readForCheck(projectRoot, a) {
56
+ const at = (0, import_material_place.locateStored)(a.path, projectRoot);
57
+ if (!at) return { ok: false, finding: unverified(`${a.path} is in a plans folder not linked on this device, so it was not checked`, a.uid) };
58
+ const { root, rel } = at;
59
+ try {
60
+ const abs = (0, import_confined_fs.resolveWithin)(root, rel, "artefact");
61
+ const st = import_node_fs.default.lstatSync(abs);
62
+ if (!st.isFile()) return { ok: false, finding: fail(`${a.path} is no longer a regular file in the project`, a.uid) };
63
+ if ((0, import_cloud_files.isPlaceholder)(abs)) return { ok: false, finding: unverified(`${a.path} is not on this device yet, so its contents were not checked`, a.uid) };
64
+ if (st.size > MAX_CHECK_READ_BYTES) {
65
+ return { ok: false, finding: unverified(`${a.path} is larger than ${MAX_CHECK_READ_BYTES / 1024 / 1024} MB, so its contents were not checked`, a.uid) };
66
+ }
67
+ return { ok: true, buf: (0, import_confined_fs.readFileWithin)(root, rel, "artefact") };
68
+ } catch {
69
+ return { ok: false, finding: fail(`${a.path} is not in the project any more, or is now a link`, a.uid) };
70
+ }
71
+ }
72
+ const extOf = (p) => import_node_path.default.extname(p).slice(1).toLowerCase();
73
+ function zipText(buf, name, entries) {
74
+ const b = (0, import_zip_entries.readZipEntry)(buf, name, { entries });
75
+ return b ? b.toString("utf8") : null;
76
+ }
77
+ function workbookSheets(buf) {
78
+ const entries = (0, import_zip_entries.listZipEntries)(buf);
79
+ const workbook = zipText(buf, "xl/workbook.xml", entries);
80
+ if (!workbook) throw new Error("no xl/workbook.xml");
81
+ const rels = zipText(buf, "xl/_rels/workbook.xml.rels", entries) ?? "";
82
+ return (0, import_xlsx_xml.parseWorkbookSheets)(workbook, rels).map((s) => {
83
+ const xml = s.part ? zipText(buf, s.part, entries) : null;
84
+ return { name: s.name, dimension: xml ? (0, import_xlsx_xml.sheetDimension)(xml) : null };
85
+ });
86
+ }
87
+ function officeText(buf, ext) {
88
+ const entries = (0, import_zip_entries.listZipEntries)(buf);
89
+ const parts = ext === "docx" ? ["word/document.xml"] : ext === "pptx" ? entries.map((e) => e.name).filter((n) => /^ppt\/slides\/slide\d+\.xml$/.test(n)) : ["xl/sharedStrings.xml"];
90
+ return parts.map((p) => zipText(buf, p, entries) ?? "").map((xml) => (0, import_xlsx_xml.decodeXml)(xml.replace(/<\/(w:p|a:p|si)>/g, "\n").replace(/<[^>]+>/g, ""))).join("\n");
91
+ }
92
+ function slideCount(buf) {
93
+ return (0, import_zip_entries.listZipEntries)(buf).filter((e) => /^ppt\/slides\/slide\d+\.xml$/.test(e.name)).length;
94
+ }
95
+ function pdfPageCount(buf) {
96
+ const s = buf.toString("latin1");
97
+ let best = 0;
98
+ for (const m of s.matchAll(/<<(?:(?!<<|>>)[\s\S])*?\/Type\s*\/Pages\b(?:(?!<<|>>)[\s\S])*?>>/g)) {
99
+ const count = m[0].match(/\/Count\s+(\d+)/);
100
+ if (count) best = Math.max(best, Number(count[1]));
101
+ }
102
+ if (best > 0) return best;
103
+ const pages = s.match(/\/Type\s*\/Page(?![a-zA-Z])/g)?.length ?? 0;
104
+ return pages > 0 ? pages : null;
105
+ }
106
+ function mp4DurationSeconds(buf) {
107
+ const i = buf.indexOf("mvhd", 0, "latin1");
108
+ if (i < 0 || i + 32 > buf.length) return null;
109
+ const version = buf[i + 4];
110
+ const timescale = version === 1 ? buf.readUInt32BE(i + 24) : buf.readUInt32BE(i + 16);
111
+ const duration = version === 1 ? Number(buf.readBigUInt64BE(i + 28)) : buf.readUInt32BE(i + 20);
112
+ return timescale > 0 ? duration / timescale : null;
113
+ }
114
+ function rangeInside(range, dimension) {
115
+ const r = (0, import_locator.parseRange)(range);
116
+ const d = (0, import_locator.parseRange)(dimension);
117
+ if (!r || !d) return true;
118
+ return r.from.col >= d.from.col && r.from.row >= d.from.row && r.to.col <= d.to.col && r.to.row <= d.to.row;
119
+ }
120
+ function toSeconds(t) {
121
+ if (typeof t === "number" && Number.isFinite(t)) return t;
122
+ if (typeof t !== "string") return null;
123
+ const parts = t.trim().split(":").map(Number);
124
+ if (parts.some((n) => !Number.isFinite(n))) return null;
125
+ return parts.reduce((acc, n) => acc * 60 + n, 0);
126
+ }
127
+ const squash = (s) => s.replace(/\s+/g, " ").trim().toLowerCase();
128
+ function checkLocator(root, a, locator) {
129
+ if (!locator || typeof locator !== "object" || Array.isArray(locator)) {
130
+ return [fail(`The locator for ${a.path} must be an object such as {"sheet": "Regional", "range": "C14"}`, a.uid)];
131
+ }
132
+ const loc = locator;
133
+ const ext = extOf(a.path);
134
+ const read = readForCheck(root, a);
135
+ if (!read.ok) return [read.finding];
136
+ const buf = read.buf;
137
+ const out = [];
138
+ const known = /* @__PURE__ */ new Set(["sheet", "range", "page", "t", "lines", "text"]);
139
+ try {
140
+ if ("sheet" in loc || "range" in loc) {
141
+ const sheet = typeof loc.sheet === "string" ? loc.sheet : null;
142
+ const range = typeof loc.range === "string" ? loc.range.trim() : null;
143
+ if (range !== null && !(0, import_locator.parseRange)(range)) {
144
+ out.push(fail(`"${range}" is not a cell or range \u2014 write it as C14 or A1:F20`, a.uid));
145
+ } else if (ext === "xlsx" || ext === "xlsm") {
146
+ const sheets = workbookSheets(buf);
147
+ const target = sheet === null ? sheets[0] : sheets.find((s) => s.name === sheet);
148
+ if (!target) {
149
+ out.push(fail(`${a.path} has no sheet "${sheet}" \u2014 it has ${sheets.map((s) => `"${s.name}"`).join(", ") || "none"}`, a.uid));
150
+ } else if (range && target.dimension && !rangeInside(range, target.dimension)) {
151
+ out.push(fail(`${target.name}!${range} is outside what ${a.path} has in that sheet (${target.dimension})`, a.uid));
152
+ } else {
153
+ out.push(pass(`${a.path} has ${range ? `${target.name}!${range}` : `a sheet "${target.name}"`}`, a.uid));
154
+ }
155
+ } else if (ext === "csv") {
156
+ const { rows, cols } = (0, import_csv.csvShape)((0, import_csv.parseCsv)(buf.toString("utf8")));
157
+ const r = range ? (0, import_locator.parseRange)(range) : null;
158
+ if (r && (r.to.row > rows || r.to.col > cols)) {
159
+ out.push(fail(`${range} is outside ${a.path}, which has ${rows} rows and ${cols} columns`, a.uid));
160
+ } else {
161
+ out.push(pass(`${a.path} has ${range ?? "that sheet"}`, a.uid));
162
+ }
163
+ } else if (ext === "xls") {
164
+ out.push(unverified(`${a.path} is an old-format workbook; its sheets are not read yet`, a.uid));
165
+ } else {
166
+ out.push(fail(`A {sheet, range} locator points into a workbook; ${a.path} is a .${ext} file`, a.uid));
167
+ }
168
+ }
169
+ if ("page" in loc) {
170
+ const page = loc.page;
171
+ if (typeof page !== "number" || !Number.isInteger(page) || page < 1) {
172
+ out.push(fail(`page must be a whole number from 1 \u2014 got ${JSON.stringify(page)}`, a.uid));
173
+ } else {
174
+ const count = ext === "pdf" ? pdfPageCount(buf) : ext === "pptx" ? slideCount(buf) : void 0;
175
+ if (count === void 0) {
176
+ out.push(ext === "docx" ? unverified(`${a.path} is a Word document; its pages depend on layout and are not checked`, a.uid) : fail(`A {page} locator points into a PDF or a deck; ${a.path} is a .${ext} file`, a.uid));
177
+ } else if (count === null) {
178
+ out.push(unverified(`The page count of ${a.path} could not be read`, a.uid));
179
+ } else if (page > count) {
180
+ out.push(fail(`${a.path} has ${count} ${ext === "pptx" ? "slides" : "pages"}; ${page} is not one of them`, a.uid));
181
+ } else {
182
+ out.push(pass(`${a.path} has ${ext === "pptx" ? "slide" : "page"} ${page}`, a.uid));
183
+ }
184
+ }
185
+ }
186
+ if ("t" in loc) {
187
+ const t = toSeconds(loc.t);
188
+ if (t === null || t < 0) {
189
+ out.push(fail(`t must be seconds or mm:ss \u2014 got ${JSON.stringify(loc.t)}`, a.uid));
190
+ } else if (ext === "mp4" || ext === "mov") {
191
+ const d = mp4DurationSeconds(buf);
192
+ if (d === null) out.push(unverified(`The length of ${a.path} could not be read`, a.uid));
193
+ else if (t > d) out.push(fail(`${a.path} is ${Math.round(d)}s long; ${loc.t} is past the end`, a.uid));
194
+ else out.push(pass(`${a.path} reaches ${loc.t}`, a.uid));
195
+ } else if (ext === "webm") {
196
+ out.push(unverified(`The length of a .webm file is not read yet`, a.uid));
197
+ } else {
198
+ out.push(fail(`A {t} locator points into a video; ${a.path} is a .${ext} file`, a.uid));
199
+ }
200
+ }
201
+ if ("lines" in loc) {
202
+ const span = (0, import_locator.toSpan)(loc.lines);
203
+ if (!span || span.start < 1 || span.end < span.start) {
204
+ out.push(fail(`lines must be a line number or a span such as "10-20" \u2014 got ${JSON.stringify(loc.lines)}`, a.uid));
205
+ } else if (!import_locator.TEXT_EXTS.has(ext)) {
206
+ out.push(fail(`A {lines} locator points into a text file; ${a.path} is a .${ext} file`, a.uid));
207
+ } else {
208
+ const count = buf.toString("utf8").split(/\r?\n/).length;
209
+ if (span.end > count) out.push(fail(`${a.path} has ${count} lines; ${span.end} is past the end`, a.uid));
210
+ else out.push(pass(`${a.path} has lines ${span.start}${span.end !== span.start ? `\u2013${span.end}` : ""}`, a.uid));
211
+ }
212
+ }
213
+ if ("text" in loc) {
214
+ const quote = typeof loc.text === "string" ? squash(loc.text) : "";
215
+ if (!quote) {
216
+ out.push(fail(`text must be the words being cited`, a.uid));
217
+ } else {
218
+ const body = import_locator.TEXT_EXTS.has(ext) ? buf.toString("utf8") : ext === "docx" || ext === "pptx" || ext === "xlsx" || ext === "xlsm" ? officeText(buf, ext) : null;
219
+ if (body === null) out.push(unverified(`Text is not read from .${ext} files yet, so the quote was not checked`, a.uid));
220
+ else if (!squash(body).includes(quote)) out.push(fail(`${a.path} does not contain "${String(loc.text).slice(0, 80)}"`, a.uid));
221
+ else out.push(pass(`${a.path} contains the quoted words`, a.uid));
222
+ }
223
+ }
224
+ } catch (err) {
225
+ out.push(unverified(`${a.path} could not be read as a .${ext} file (${err.message})`, a.uid));
226
+ }
227
+ const unknown = Object.keys(loc).filter((k) => !known.has(k));
228
+ if (unknown.length) {
229
+ out.push(unverified(`Locator keys ${unknown.join(", ")} are not ones CodeTrellis checks`, a.uid));
230
+ }
231
+ if (out.length === 0) out.push(fail(`The locator for ${a.path} names no place \u2014 use sheet/range, page, t, lines or text`, a.uid));
232
+ return out;
233
+ }
234
+ function junitCounts(xml) {
235
+ const attr = (tag, name) => Number(tag.match(new RegExp(`\\b${name}="(\\d+)"`))?.[1] ?? 0);
236
+ const top = xml.match(/<testsuites\b[^>]*>/);
237
+ if (top && /\btests="\d+"/.test(top[0])) {
238
+ return { tests: attr(top[0], "tests"), failures: attr(top[0], "failures"), errors: attr(top[0], "errors") };
239
+ }
240
+ const suites = [...xml.matchAll(/<testsuite\b[^>]*>/g)].map((m) => m[0]);
241
+ if (suites.length === 0) return null;
242
+ return suites.reduce(
243
+ (acc, s) => ({ tests: acc.tests + attr(s, "tests"), failures: acc.failures + attr(s, "failures"), errors: acc.errors + attr(s, "errors") }),
244
+ { tests: 0, failures: 0, errors: 0 }
245
+ );
246
+ }
247
+ const when = (ms) => new Date(ms).toISOString().slice(0, 16).replace("T", " ");
248
+ function runChecks(ctx) {
249
+ const findings = [];
250
+ const { root } = ctx;
251
+ const kind = ctx.criterion.kind;
252
+ const offered = ctx.evidence.filter((e) => e.attachmentUid);
253
+ if (kind !== "manual") {
254
+ for (const e of offered) {
255
+ if (!e.artefact) {
256
+ findings.push(fail(
257
+ `Attachment ${e.attachmentUid} is not a file recorded on this item \u2014 record it with record_artefact first`,
258
+ e.attachmentUid
259
+ ));
260
+ } else if (!e.artefact.sha256) {
261
+ findings.push(fail(`${e.artefact.path} is no longer in the project`, e.artefact.uid));
262
+ }
263
+ }
264
+ }
265
+ if (!root && kind !== "manual") {
266
+ findings.push(unverified("This item's project is not open in CodeTrellis, so its files could not be checked"));
267
+ return finish(ctx, findings);
268
+ }
269
+ const files = (roles) => {
270
+ const fromEvidence = offered.map((e) => e.artefact).filter((a) => !!a && !!a.sha256 && roles.includes(a.role));
271
+ return fromEvidence.length || offered.length ? fromEvidence : ctx.itemArtefacts.filter((a) => a.sha256 && roles.includes(a.role));
272
+ };
273
+ switch (kind) {
274
+ case "manual":
275
+ findings.push(pass("Nothing mechanical to check \u2014 this is a person's judgement"));
276
+ break;
277
+ case "artefact": {
278
+ const outputs = files(["output", "evidence"]);
279
+ if (outputs.length === 0) {
280
+ findings.push(fail('No output file is recorded for this item \u2014 record_artefact(path, role: "output") the file the work produced'));
281
+ }
282
+ for (const a of outputs) {
283
+ if (a.mtime !== null && a.mtime < ctx.itemStartedAt - MTIME_SLACK_MS) {
284
+ findings.push(fail(`${a.path} was last changed ${when(a.mtime)}, before this item started (${when(ctx.itemStartedAt)}) \u2014 it is not this work's output`, a.uid));
285
+ } else {
286
+ findings.push(pass(`${a.path} is in the project and changed since the item started`, a.uid));
287
+ }
288
+ }
289
+ break;
290
+ }
291
+ case "citation": {
292
+ const cited = ctx.evidence.filter((e) => e.artefact?.role === "material");
293
+ if (cited.length === 0) {
294
+ findings.push(fail('Cite the material this rests on: attach it as role "material" and give a locator \u2014 {sheet, range}, {page}, {lines}, {text} or {t}'));
295
+ }
296
+ for (const e of cited) {
297
+ if (e.locator === null || e.locator === void 0) {
298
+ findings.push(fail(`Citing ${e.artefact.path} needs a locator saying where in it`, e.artefact.uid));
299
+ }
300
+ if (ctx.materialsRead) {
301
+ findings.push(ctx.materialsRead.has(e.artefact.uid) ? pass(`${e.artefact.path} was read through read_material while this item was under way`, e.artefact.uid) : unverified(`${e.artefact.path} was not read through read_material while this item was under way, so nothing shows it was opened`, e.artefact.uid));
302
+ }
303
+ }
304
+ break;
305
+ }
306
+ case "test": {
307
+ const reports = files(["evidence", "output"]);
308
+ if (reports.length === 0) {
309
+ findings.push(fail("Attach the test report as evidence (a JUnit .xml, or the run's log)"));
310
+ }
311
+ for (const a of reports) {
312
+ if (ctx.lastTargetChangeAt !== null && a.mtime !== null && a.mtime < ctx.lastTargetChangeAt - MTIME_SLACK_MS) {
313
+ findings.push({
314
+ ...fail(`\u26A0 tests older than the code: ${a.path} ran ${when(a.mtime)}, before the last change to this item's files (${when(ctx.lastTargetChangeAt)}) \u2014 run the tests again`, a.uid),
315
+ reason: "tests_older"
316
+ });
317
+ continue;
318
+ }
319
+ const read = readForCheck(root, a);
320
+ if (!read.ok) {
321
+ findings.push(read.finding);
322
+ continue;
323
+ }
324
+ const xml = /\.xml$/i.test(a.path) ? read.buf.toString("utf8") : null;
325
+ const parsed = xml !== null ? (0, import_junit.parseJUnit)(xml) : null;
326
+ const counts = parsed && parsed.cases.length ? { tests: parsed.totals.tests, failures: parsed.totals.failed, errors: parsed.totals.errors } : xml !== null ? junitCounts(xml) : null;
327
+ if (counts && ctx.onTestReport) {
328
+ try {
329
+ ctx.onTestReport(a);
330
+ } catch {
331
+ }
332
+ }
333
+ if (!counts) {
334
+ findings.push(unverified(`${a.path} is not a JUnit report, so its pass and fail counts were not read`, a.uid));
335
+ } else if (counts.failures + counts.errors > 0) {
336
+ const cases = (parsed?.cases ?? []).filter((c) => c.result === "failed" || c.result === "error");
337
+ const named = cases.slice(0, 3).map((c) => `${(0, import_junit.testLabel)(c)}${c.message ? ` (${c.message})` : ""}`);
338
+ const more = cases.length > 3 ? `; and ${cases.length - 3} more` : "";
339
+ findings.push(fail(`${a.path} reports ${counts.failures + counts.errors} of ${counts.tests} tests failing${named.length ? `: ${named.join("; ")}${more}` : ""}`, a.uid));
340
+ } else if (counts.tests === 0) {
341
+ findings.push(fail(`${a.path} reports no tests run`, a.uid));
342
+ } else {
343
+ findings.push(pass(`${a.path}: ${counts.tests} tests, none failing`, a.uid));
344
+ }
345
+ }
346
+ break;
347
+ }
348
+ case "code": {
349
+ const code = ctx.code;
350
+ if (!code) break;
351
+ if ("unavailable" in code) findings.push(unverified(`The item's changes could not be reviewed: ${code.unavailable}`));
352
+ else if (code.verdict === "landed") findings.push(pass("Every file this item names has changed"));
353
+ else if (code.verdict === "no-targets") findings.push(unverified("This item names no files, so its changes cannot be checked"));
354
+ else if (code.verdict === "untouched") findings.push(fail(`None of this item's files have changed yet: ${code.missing.join(", ")}`));
355
+ else findings.push(fail(`Not changed yet: ${code.missing.join(", ")}`));
356
+ for (const s of ctx.openHighSignals ?? []) {
357
+ findings.push(fail(`A high overlap with other work is still open (${s.heading}): ${s.words} Answer it on the Awareness tab, or fix it, and check again.`));
358
+ }
359
+ break;
360
+ }
361
+ }
362
+ for (const e of ctx.evidence) {
363
+ if (e.artefact && e.artefact.sha256 && e.locator !== null && e.locator !== void 0) {
364
+ findings.push(...checkLocator(root, e.artefact, e.locator));
365
+ }
366
+ }
367
+ return finish(ctx, findings);
368
+ }
369
+ function finish(ctx, findings) {
370
+ return {
371
+ criterionUid: ctx.criterion.uid,
372
+ itemUid: ctx.criterion.itemUid,
373
+ ok: !findings.some((f) => f.status === "fail"),
374
+ findings
375
+ };
376
+ }
377
+ // Annotate the CommonJS export names for ESM import in node:
378
+ 0 && (module.exports = {
379
+ MAX_CHECK_READ_BYTES,
380
+ MTIME_SLACK_MS,
381
+ checkLocator,
382
+ junitCounts,
383
+ mp4DurationSeconds,
384
+ pdfPageCount,
385
+ runChecks,
386
+ workbookSheets
387
+ });