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,77 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var gitlab_exports = {};
19
+ __export(gitlab_exports, {
20
+ gitlabApiBase: () => gitlabApiBase,
21
+ readGitlabBranch: () => readGitlabBranch,
22
+ summariseMergeRequest: () => summariseMergeRequest,
23
+ summarisePipeline: () => summarisePipeline
24
+ });
25
+ module.exports = __toCommonJS(gitlab_exports);
26
+ var import_http = require("./http");
27
+ function gitlabApiBase() {
28
+ return (process.env.CODETRELLIS_GITLAB_API || "https://gitlab.com/api/v4").replace(/\/+$/, "");
29
+ }
30
+ const secs = (iso) => iso ? Math.floor(Date.parse(iso) / 1e3) : null;
31
+ function summarisePipeline(status) {
32
+ if (!status || status === "skipped") return null;
33
+ if (status === "success") return "passing";
34
+ if (status === "failed" || status === "canceled") return "failing";
35
+ return "pending";
36
+ }
37
+ function summariseMergeRequest(mr, approvals) {
38
+ if (!mr) return null;
39
+ const state = mr.state === "merged" ? "merged" : mr.state === "opened" ? "open" : "closed";
40
+ const open = state === "open";
41
+ return {
42
+ number: mr.iid,
43
+ ref: `!${mr.iid}`,
44
+ url: mr.web_url,
45
+ state,
46
+ at: state === "merged" ? secs(mr.merged_at) : state === "closed" ? secs(mr.closed_at) : null,
47
+ mergeCommit: state === "merged" ? mr.squash_commit_sha || mr.merge_commit_sha || null : null,
48
+ checks: open ? summarisePipeline(mr.head_pipeline?.status) : null,
49
+ approvals: open ? (approvals?.approved_by ?? []).length : 0,
50
+ changesRequested: open && mr.detailed_merge_status === "requested_changes"
51
+ };
52
+ }
53
+ async function readGitlabBranch(owner, repo, branch, token) {
54
+ const parts = [owner, ...repo.split("/")];
55
+ if (!parts.every((p) => import_http.PART.test(p))) return { ok: false, error: "Not a GitLab project path." };
56
+ const project = `${gitlabApiBase()}/projects/${encodeURIComponent(parts.join("/"))}`;
57
+ const get = (path) => (0, import_http.hostGet)("GitLab", `${project}${path}`, token ? { "PRIVATE-TOKEN": token } : {}, { hasToken: !!token });
58
+ try {
59
+ const list = await get(`/merge_requests?source_branch=${encodeURIComponent(branch)}&state=all&order_by=updated_at&sort=desc&per_page=5`);
60
+ const mr = Array.isArray(list) ? list.find((m) => m.source_branch === branch) ?? null : null;
61
+ if (!mr || mr.state !== "opened") return { ok: true, review: summariseMergeRequest(mr, null) };
62
+ const [detail, approvals] = await Promise.all([
63
+ get(`/merge_requests/${mr.iid}`),
64
+ get(`/merge_requests/${mr.iid}/approvals`)
65
+ ]);
66
+ return { ok: true, review: summariseMergeRequest({ ...mr, ...detail }, approvals) };
67
+ } catch (err) {
68
+ return { ok: false, error: (0, import_http.unreachable)("GitLab", err) };
69
+ }
70
+ }
71
+ // Annotate the CommonJS export names for ESM import in node:
72
+ 0 && (module.exports = {
73
+ gitlabApiBase,
74
+ readGitlabBranch,
75
+ summariseMergeRequest,
76
+ summarisePipeline
77
+ });
@@ -0,0 +1,103 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var host_state_exports = {};
19
+ __export(host_state_exports, {
20
+ HOST_TTL_MS: () => HOST_TTL_MS,
21
+ cachedHostRead: () => cachedHostRead,
22
+ forgetHostReads: () => forgetHostReads,
23
+ overlayHost: () => overlayHost,
24
+ refreshHostReads: () => refreshHostReads
25
+ });
26
+ module.exports = __toCommonJS(host_state_exports);
27
+ var import_detect = require("./detect");
28
+ var import_switch = require("./switch");
29
+ var import_github = require("./github");
30
+ var import_gitlab = require("./gitlab");
31
+ var import_bitbucket = require("./bitbucket");
32
+ const READERS = {
33
+ github: import_github.readGithubBranch,
34
+ gitlab: import_gitlab.readGitlabBranch,
35
+ bitbucket: import_bitbucket.readBitbucketBranch
36
+ };
37
+ const HOST_TTL_MS = 12e4;
38
+ const MAX_BRANCHES = 25;
39
+ const CONCURRENCY = 4;
40
+ const cache = /* @__PURE__ */ new Map();
41
+ const inflight = /* @__PURE__ */ new Map();
42
+ const keyOf = (host, branch) => `${host.hostname}/${host.slug}#${branch}`;
43
+ function forgetHostReads() {
44
+ cache.clear();
45
+ }
46
+ function cachedHostRead(projectRoot, branch) {
47
+ const active = (0, import_switch.activeReviewHost)(projectRoot);
48
+ if (!active) return null;
49
+ return cache.get(keyOf(active.host, branch))?.read ?? null;
50
+ }
51
+ async function refreshHostReads(projectRoot, branches, now = Date.now()) {
52
+ const active = (0, import_switch.activeReviewHost)(projectRoot);
53
+ if (!active || !active.host.kind || !active.host.supported) return;
54
+ const { host, token } = active;
55
+ const kind = active.host.kind;
56
+ const read = READERS[kind];
57
+ const stale = [...new Set(branches)].filter((b) => {
58
+ const e = cache.get(keyOf(host, b));
59
+ return !e || now - e.at >= HOST_TTL_MS;
60
+ }).slice(0, MAX_BRANCHES);
61
+ let next = 0;
62
+ const worker = async () => {
63
+ while (next < stale.length) {
64
+ const branch = stale[next++];
65
+ const key = keyOf(host, branch);
66
+ let p = inflight.get(key);
67
+ if (!p) {
68
+ p = read(host.owner, host.repo, branch, token).finally(() => inflight.delete(key));
69
+ inflight.set(key, p);
70
+ }
71
+ cache.set(key, { at: Date.now(), read: { kind, read: await p } });
72
+ }
73
+ };
74
+ await Promise.all(Array.from({ length: Math.min(CONCURRENCY, stale.length) }, worker));
75
+ }
76
+ function overlayHost(state, kept) {
77
+ if (!kept) return state;
78
+ const { kind, read } = kept;
79
+ const name = (0, import_detect.hostName)(kind);
80
+ const source = kind;
81
+ if (!read.ok) return { ...state, hostNote: read.error };
82
+ const r = read.review;
83
+ const request = kind === "gitlab" ? "merge request" : "pull request";
84
+ if (!r) return { ...state, hostNote: `${name} has no ${request} for this branch.` };
85
+ const review = { number: r.number, ref: r.ref, url: r.url, checks: r.checks, approvals: r.approvals, changesRequested: r.changesRequested };
86
+ if (r.state === "merged") {
87
+ return { ...state, state: "merged", source, how: "pull-request", commit: r.mergeCommit ?? state.commit, at: r.at ?? state.at, review };
88
+ }
89
+ if (r.state === "open") {
90
+ if (state.state === "merged") return { ...state, review, hostNote: `${name} still has ${r.ref} open, but its changes are on ${state.base ?? "the base"}.` };
91
+ return { ...state, state: "in-review", source, review };
92
+ }
93
+ if (state.state === "merged") return { ...state, review, hostNote: `${name} says ${r.ref} was closed without merging; git shows its changes on ${state.base ?? "the base"}.` };
94
+ return { ...state, state: "closed", source, at: r.at ?? state.at, review };
95
+ }
96
+ // Annotate the CommonJS export names for ESM import in node:
97
+ 0 && (module.exports = {
98
+ HOST_TTL_MS,
99
+ cachedHostRead,
100
+ forgetHostReads,
101
+ overlayHost,
102
+ refreshHostReads
103
+ });
@@ -0,0 +1,58 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var http_exports = {};
19
+ __export(http_exports, {
20
+ HostReadError: () => HostReadError,
21
+ PART: () => PART,
22
+ hostGet: () => hostGet,
23
+ unreachable: () => unreachable
24
+ });
25
+ module.exports = __toCommonJS(http_exports);
26
+ class HostReadError extends Error {
27
+ }
28
+ const TIMEOUT_MS = 8e3;
29
+ async function hostGet(name, url, auth, opts) {
30
+ const res = await fetch(url, {
31
+ method: "GET",
32
+ redirect: "error",
33
+ signal: AbortSignal.timeout(TIMEOUT_MS),
34
+ headers: { Accept: "application/json", "User-Agent": "CodeTrellis", ...opts.extraHeaders ?? {}, ...auth }
35
+ });
36
+ if (res.ok) return res.json();
37
+ if (res.status === 401) throw new HostReadError(`${name} refused the token (401). Save a new one in Settings \u2192 Review hosts.`);
38
+ const limited = res.status === 429 || res.status === 403 && res.headers.get("x-ratelimit-remaining") === "0";
39
+ if (limited) {
40
+ const reset = Number(res.headers.get("x-ratelimit-reset") ?? res.headers.get("ratelimit-reset"));
41
+ const when = reset ? `until ${new Date(reset * 1e3).toISOString().slice(11, 16)} UTC` : "for now";
42
+ throw new HostReadError(`${name}'s rate limit is used up ${when}${opts.hasToken ? "" : "; a token raises it"}.`);
43
+ }
44
+ if (res.status === 404) throw new HostReadError(`${name} has no such repository${opts.hasToken ? " that this token can see" : " (a private one needs a token)"} (404).`);
45
+ throw new HostReadError(`${name} answered ${res.status}.`);
46
+ }
47
+ function unreachable(name, err) {
48
+ if (err instanceof HostReadError) return err.message;
49
+ return err?.name === "TimeoutError" ? `${name} did not answer in time.` : `${name} could not be reached.`;
50
+ }
51
+ const PART = /^[A-Za-z0-9_.-]+$/;
52
+ // Annotate the CommonJS export names for ESM import in node:
53
+ 0 && (module.exports = {
54
+ HostReadError,
55
+ PART,
56
+ hostGet,
57
+ unreachable
58
+ });
@@ -0,0 +1,120 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var switch_exports = {};
19
+ __export(switch_exports, {
20
+ ReviewHostError: () => ReviewHostError,
21
+ activeReviewHost: () => activeReviewHost,
22
+ checkToken: () => checkToken,
23
+ forgetReviewHostToken: () => forgetReviewHostToken,
24
+ getReviewHost: () => getReviewHost,
25
+ saveReviewHostToken: () => saveReviewHostToken,
26
+ setReviewHost: () => setReviewHost,
27
+ tokenKey: () => tokenKey
28
+ });
29
+ module.exports = __toCommonJS(switch_exports);
30
+ var import_database = require("../database");
31
+ var import_persistence = require("../persistence");
32
+ var import_secret_store = require("../secret-store");
33
+ var import_detect = require("./detect");
34
+ class ReviewHostError extends Error {
35
+ constructor(status, message) {
36
+ super(message);
37
+ this.status = status;
38
+ }
39
+ status;
40
+ }
41
+ function rowOf(projectRoot) {
42
+ const res = (0, import_database.getDb)().exec("SELECT hostname, slug, enabled, changed_at, changed_by FROM review_hosts WHERE project_root = ?", [projectRoot]);
43
+ const v = res[0]?.values[0];
44
+ return v ? { hostname: String(v[0]), slug: String(v[1]), enabled: Number(v[2]), changed_at: Number(v[3]), changed_by: String(v[4]) } : null;
45
+ }
46
+ const tokenKey = (hostname) => `review-host:${hostname}`;
47
+ function says(d, enabled, turnedOnFor, tokenSaved) {
48
+ if (!d) return "No review host: this project has no remote with an owner and a repository. Its state comes from git.";
49
+ if (!d.kind) return `${d.hostname} has no adapter. State comes from git alone.`;
50
+ const name = (0, import_detect.hostName)(d.kind);
51
+ if (!d.supported) return `${name} is recognised; its adapter comes later. State comes from git alone.`;
52
+ if (turnedOnFor) return `Turned on for ${turnedOnFor}, but the remote now names ${d.hostname}/${d.slug}. Off until you turn it on for this one.`;
53
+ if (!enabled) return `Off. Nothing is sent to ${name}; state comes from git.`;
54
+ return tokenSaved ? `On: reads ${d.hostname}/${d.slug} with your token.` : `On: reads ${d.hostname}/${d.slug} without a token, which works for a public repository only.`;
55
+ }
56
+ function getReviewHost(projectRoot, detected = (0, import_detect.detectProjectHost)(projectRoot)) {
57
+ const row = rowOf(projectRoot);
58
+ const store = (0, import_secret_store.secretStore)();
59
+ const sameRepo = !!row && !!detected && row.hostname === detected.hostname && row.slug === detected.slug;
60
+ const enabled = !!row?.enabled && sameRepo && !!detected?.supported;
61
+ const turnedOnFor = row?.enabled && !sameRepo ? `${row.hostname}/${row.slug}` : null;
62
+ const tokenSaved = !!detected && store.has(tokenKey(detected.hostname));
63
+ return {
64
+ project: projectRoot,
65
+ detected,
66
+ enabled,
67
+ turnedOnFor,
68
+ changedAt: row?.changed_at ?? null,
69
+ changedBy: row?.changed_by ?? null,
70
+ token: { saved: tokenSaved, kind: store.kind, where: store.where },
71
+ says: says(detected, enabled, turnedOnFor, tokenSaved)
72
+ };
73
+ }
74
+ function setReviewHost(projectRoot, enabled, by, detected = (0, import_detect.detectProjectHost)(projectRoot)) {
75
+ if (enabled) {
76
+ if (!detected) throw new ReviewHostError(400, "This project has no remote naming a host, so there is nothing to turn on.");
77
+ if (!detected.supported) throw new ReviewHostError(400, `${detected.kind ? (0, import_detect.hostName)(detected.kind) : detected.hostname} has no adapter yet; its state comes from git.`);
78
+ }
79
+ const hostname = detected?.hostname ?? rowOf(projectRoot)?.hostname ?? "";
80
+ const slug = detected?.slug ?? rowOf(projectRoot)?.slug ?? "";
81
+ (0, import_database.getDb)().run(
82
+ `INSERT INTO review_hosts (project_root, hostname, slug, enabled, changed_at, changed_by) VALUES (?, ?, ?, ?, ?, ?)
83
+ ON CONFLICT(project_root) DO UPDATE SET hostname = excluded.hostname, slug = excluded.slug, enabled = excluded.enabled,
84
+ changed_at = excluded.changed_at, changed_by = excluded.changed_by`,
85
+ [projectRoot, hostname, slug, enabled ? 1 : 0, Date.now(), by]
86
+ );
87
+ (0, import_persistence.markDirty)();
88
+ return getReviewHost(projectRoot, detected);
89
+ }
90
+ function checkToken(token) {
91
+ if (typeof token !== "string") throw new ReviewHostError(400, "token must be a string");
92
+ const t = token.trim();
93
+ if (t.length < 8 || t.length > 255 || !/^[\x21-\x7e]+$/.test(t)) throw new ReviewHostError(400, "That does not look like a token: expected 8\u2013255 printable characters with no spaces.");
94
+ return t;
95
+ }
96
+ function saveReviewHostToken(projectRoot, token, detected = (0, import_detect.detectProjectHost)(projectRoot)) {
97
+ if (!detected?.supported) throw new ReviewHostError(400, "This project's host has no adapter, so a token would not be used.");
98
+ (0, import_secret_store.secretStore)().set(tokenKey(detected.hostname), checkToken(token));
99
+ return getReviewHost(projectRoot, detected);
100
+ }
101
+ function forgetReviewHostToken(projectRoot, detected = (0, import_detect.detectProjectHost)(projectRoot)) {
102
+ if (detected) (0, import_secret_store.secretStore)().delete(tokenKey(detected.hostname));
103
+ return getReviewHost(projectRoot, detected);
104
+ }
105
+ function activeReviewHost(projectRoot) {
106
+ const detected = (0, import_detect.detectProjectHost)(projectRoot);
107
+ if (!getReviewHost(projectRoot, detected).enabled || !detected) return null;
108
+ return { host: detected, token: (0, import_secret_store.secretStore)().get(tokenKey(detected.hostname)) };
109
+ }
110
+ // Annotate the CommonJS export names for ESM import in node:
111
+ 0 && (module.exports = {
112
+ ReviewHostError,
113
+ activeReviewHost,
114
+ checkToken,
115
+ forgetReviewHostToken,
116
+ getReviewHost,
117
+ saveReviewHostToken,
118
+ setReviewHost,
119
+ tokenKey
120
+ });
@@ -0,0 +1,72 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var review_marks_exports = {};
19
+ __export(review_marks_exports, {
20
+ lastMark: () => lastMark,
21
+ markReviewed: () => markReviewed,
22
+ sinceLastLook: () => sinceLastLook
23
+ });
24
+ module.exports = __toCommonJS(review_marks_exports);
25
+ var import_node_child_process = require("node:child_process");
26
+ var import_database = require("./database");
27
+ var import_persistence = require("./persistence");
28
+ function markReviewed(projectRoot, m, now = Date.now()) {
29
+ (0, import_database.getDb)().run(
30
+ `INSERT OR REPLACE INTO review_marks (project_root, target, reviewer, reviewer_type, base, head_commit, findings, at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
31
+ [projectRoot, m.target, m.reviewer, m.reviewerType, m.base, m.commit, JSON.stringify(m.findings), now]
32
+ );
33
+ (0, import_persistence.markDirty)();
34
+ return { ...m, at: now };
35
+ }
36
+ function lastMark(projectRoot, target, reviewer) {
37
+ const r = (0, import_database.getDb)().exec(
38
+ "SELECT target, reviewer, reviewer_type, base, head_commit, findings, at FROM review_marks WHERE project_root = ? AND target = ? AND reviewer = ?",
39
+ [projectRoot, target, reviewer]
40
+ )[0]?.values[0];
41
+ if (!r) return null;
42
+ let findings = [];
43
+ try {
44
+ findings = JSON.parse(String(r[5]));
45
+ } catch {
46
+ findings = [];
47
+ }
48
+ return { target: String(r[0]), reviewer: String(r[1]), reviewerType: String(r[2]), base: String(r[3]), commit: String(r[4]), findings, at: Number(r[6]) };
49
+ }
50
+ const plural = (n, one, many = `${one}s`) => `${n} ${n === 1 ? one : many}`;
51
+ function sinceLastLook(projectRoot, mark, head, findingsNow) {
52
+ let changed = [];
53
+ let gone = false;
54
+ try {
55
+ changed = (0, import_node_child_process.execFileSync)("git", ["-C", projectRoot, "diff", "--name-only", mark.commit, head, "--"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).split("\n").map((s) => s.trim()).filter(Boolean);
56
+ } catch {
57
+ gone = true;
58
+ }
59
+ const now = new Set(findingsNow);
60
+ const then = new Set(mark.findings);
61
+ const addressed = mark.findings.filter((f) => !now.has(f));
62
+ const added = findingsNow.filter((f) => !then.has(f));
63
+ const short = mark.commit.slice(0, 7);
64
+ const words = gone ? `The commit you looked at, ${short}, is no longer in the history (rewritten since): review the whole change again.` : changed.length === 0 ? `Nothing changed since you looked at ${short}.` : `Since you looked at ${short}: ${plural(changed.length, "file")} changed${addressed.length ? `, ${plural(addressed.length, "finding")} addressed` : ""}${added.length ? `, ${added.length} new` : ""}.`;
65
+ return { mark, changed, addressed, added, gone, words };
66
+ }
67
+ // Annotate the CommonJS export names for ESM import in node:
68
+ 0 && (module.exports = {
69
+ lastMark,
70
+ markReviewed,
71
+ sinceLastLook
72
+ });
@@ -0,0 +1,169 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var review_notes_exports = {};
19
+ __export(review_notes_exports, {
20
+ NOTES_REF: () => NOTES_REF,
21
+ REVIEW_NAMESPACE: () => REVIEW_NAMESPACE,
22
+ attestationProblem: () => attestationProblem,
23
+ attestationYaml: () => attestationYaml,
24
+ devicesAt: () => devicesAt,
25
+ noteOn: () => noteOn,
26
+ parseNote: () => parseNote,
27
+ signedBytes: () => signedBytes,
28
+ statementBytes: () => statementBytes,
29
+ verifyReview: () => verifyReview
30
+ });
31
+ module.exports = __toCommonJS(review_notes_exports);
32
+ var import_node_child_process = require("node:child_process");
33
+ var import_yaml = require("yaml");
34
+ var import_signing = require("./task-records/signing");
35
+ const NOTES_REF = "refs/notes/codetrellis-reviews";
36
+ const REVIEW_NAMESPACE = "codetrellis-review";
37
+ const KEYS_DIR = ".codetrellis/keys";
38
+ const MAX_NOTE = 512 * 1024;
39
+ const COMMIT = /^[0-9a-f]{40}$/;
40
+ const shortKey = (fp) => fp.startsWith("SHA256:") ? fp.slice(0, 19) : fp.slice(0, 12);
41
+ const statementBytes = (s) => (0, import_signing.canonicalJson)(s);
42
+ const signedBytes = (bytes) => `${REVIEW_NAMESPACE}
43
+ ${bytes}`;
44
+ function attestationYaml(s, signature) {
45
+ return `---
46
+ # CodeTrellis: a review of this commit, made on a developer's device and signed by its key.
47
+ kind: ${REVIEW_NAMESPACE}
48
+ version: 1
49
+ statement: ${JSON.stringify(statementBytes(s))}
50
+ signature: ${JSON.stringify(signature)}
51
+ `;
52
+ }
53
+ function parseNote(text) {
54
+ if (Buffer.byteLength(text, "utf8") > MAX_NOTE) return { attestations: [], unreadable: 1 };
55
+ const out = [];
56
+ let unreadable = 0;
57
+ for (const doc of (0, import_yaml.parseAllDocuments)(text)) {
58
+ if ("errors" in doc && doc.errors.length) {
59
+ unreadable++;
60
+ continue;
61
+ }
62
+ let raw;
63
+ try {
64
+ raw = doc.toJS({ maxAliasCount: 0 });
65
+ } catch {
66
+ unreadable++;
67
+ continue;
68
+ }
69
+ if (raw === null || raw === void 0) continue;
70
+ const r = raw;
71
+ const signature = (0, import_signing.parseSignature)(r.signature);
72
+ if (r.kind !== REVIEW_NAMESPACE || r.version !== 1 || typeof r.statement !== "string" || !signature) {
73
+ unreadable++;
74
+ continue;
75
+ }
76
+ let s;
77
+ try {
78
+ s = JSON.parse(r.statement);
79
+ } catch {
80
+ unreadable++;
81
+ continue;
82
+ }
83
+ if (s.kind !== REVIEW_NAMESPACE || typeof s.head !== "string" || typeof s.signer !== "string" || !Array.isArray(s.findings)) {
84
+ unreadable++;
85
+ continue;
86
+ }
87
+ out.push({ statement: s, bytes: r.statement, signature });
88
+ }
89
+ return { attestations: out, unreadable };
90
+ }
91
+ const git = (root, args) => {
92
+ try {
93
+ return (0, import_node_child_process.execFileSync)("git", ["-C", root, ...args], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], maxBuffer: 8 * 1024 * 1024 });
94
+ } catch {
95
+ return null;
96
+ }
97
+ };
98
+ function noteOn(root, commit) {
99
+ return git(root, ["notes", `--ref=${NOTES_REF}`, "show", commit]);
100
+ }
101
+ function devicesAt(root, commit) {
102
+ const devices = /* @__PURE__ */ new Map();
103
+ for (const line of (git(root, ["ls-tree", "--name-only", commit, `./${KEYS_DIR}/`]) ?? "").split("\n").map((l) => l.trim()).filter(Boolean).slice(0, 500)) {
104
+ const name = line.split("/").pop();
105
+ const m = /^([a-f0-9]{8,32})\.yaml$/.exec(name);
106
+ if (!m) continue;
107
+ const text = git(root, ["show", `${commit}:./${KEYS_DIR}/${name}`]);
108
+ if (!text) continue;
109
+ const parsed = (0, import_signing.parseKeyIntroduction)(text, m[1]);
110
+ if ("key" in parsed) devices.set(parsed.key.fingerprint, parsed.key.publicKey);
111
+ }
112
+ return devices;
113
+ }
114
+ function attestationProblem(a, commit, devices) {
115
+ if (a.statement.head !== commit) return `it is signed as a review of ${a.statement.head.slice(0, 7)}, not of the commit it is on`;
116
+ if (a.signature.how !== "device") return "it is not signed by a device key";
117
+ if (a.signature.key !== a.statement.signer) return "it names one signer and is signed by another";
118
+ const pub = devices.get(a.signature.key);
119
+ if (!pub) return `its key (${shortKey(a.signature.key)}) is not one the base branch lists under ${KEYS_DIR}/`;
120
+ if (!(0, import_signing.verifyWithDevice)(pub, signedBytes(a.bytes), a.signature.value)) return "its signature does not verify: it was changed after it was signed, or forged";
121
+ return null;
122
+ }
123
+ function verifyReview(root, head, baseCommit) {
124
+ if (!COMMIT.test(head) || !COMMIT.test(baseCommit)) return { state: "none", head, review: null, refused: [], words: "The head or the base is not a commit here." };
125
+ const devices = devicesAt(root, baseCommit);
126
+ const held = (commit) => {
127
+ const text = noteOn(root, commit);
128
+ if (!text) return { ok: null, refused: [] };
129
+ const { attestations, unreadable } = parseNote(text);
130
+ const refused = [];
131
+ let ok = null;
132
+ for (const a of attestations) {
133
+ const why = attestationProblem(a, commit, devices);
134
+ if (why) refused.push({ agent: a.statement.agent, why });
135
+ else if (!ok || a.statement.at > ok.statement.at) ok = a;
136
+ }
137
+ for (let i = 0; i < unreadable; i++) refused.push({ agent: "unknown", why: "it could not be read as a signed review" });
138
+ return { ok, refused };
139
+ };
140
+ const now = held(head);
141
+ const short = head.slice(0, 7);
142
+ if (now.ok) {
143
+ const s = now.ok.statement;
144
+ return { state: "verified", head, review: s, refused: now.refused, words: `\u2713 ${s.agent}'s review of ${short}, signed on a device the base trusts (${shortKey(s.signer)}): ${s.findings.length} finding${s.findings.length === 1 ? "" : "s"}.` };
145
+ }
146
+ const earlier = (git(root, ["rev-list", "--first-parent", `${baseCommit}..${head}`]) ?? "").split("\n").map((l) => l.trim()).filter((c) => COMMIT.test(c) && c !== head).slice(0, 200);
147
+ for (const c of earlier) {
148
+ const e = held(c);
149
+ if (e.ok) {
150
+ const s = e.ok.statement;
151
+ return { state: "stale", head, review: s, refused: now.refused, words: `\u26A0 The latest review is ${s.agent}'s of ${c.slice(0, 7)}, before the last push: it does not count for ${short}. Review the head again.` };
152
+ }
153
+ }
154
+ if (now.refused.length) return { state: "refused", head, review: null, refused: now.refused, words: `\u2717 The review on ${short} is refused: ${now.refused.map((r) => `${r.agent}'s, because ${r.why}`).join("; ")}.` };
155
+ return { state: "none", head, review: null, refused: [], words: `No review on ${short}: review it on your device (codetrellis review, or your agent through get_review_bundle) and push the notes (codetrellis review publish).` };
156
+ }
157
+ // Annotate the CommonJS export names for ESM import in node:
158
+ 0 && (module.exports = {
159
+ NOTES_REF,
160
+ REVIEW_NAMESPACE,
161
+ attestationProblem,
162
+ attestationYaml,
163
+ devicesAt,
164
+ noteOn,
165
+ parseNote,
166
+ signedBytes,
167
+ statementBytes,
168
+ verifyReview
169
+ });