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,363 @@
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 evidence_exports = {};
19
+ __export(evidence_exports, {
20
+ EVIDENCE_FORMAT: () => EVIDENCE_FORMAT,
21
+ EVIDENCE_VERSION: () => EVIDENCE_VERSION,
22
+ EvidenceError: () => EvidenceError,
23
+ MAX_EVIDENCE_ENTRIES: () => MAX_EVIDENCE_ENTRIES,
24
+ buildEvidence: () => buildEvidence,
25
+ decisionsBetween: () => decisionsBetween,
26
+ evidenceFromText: () => evidenceFromText,
27
+ renderEvidenceHtml: () => renderEvidenceHtml,
28
+ sealEvidence: () => sealEvidence,
29
+ verifyEvidence: () => verifyEvidence
30
+ });
31
+ module.exports = __toCommonJS(evidence_exports);
32
+ var import_database = require("./database");
33
+ var import_record_chain = require("./record-chain");
34
+ var import_replay_frames = require("./replay-frames");
35
+ var import_replay_state = require("./replay-state");
36
+ var import_plan_service = require("./plan-service");
37
+ var import_signoff_pack = require("./signoff-pack");
38
+ var import_pack_seal = require("./pack-seal");
39
+ var import_tool_phrasing = require("../../shared/lib/tool-phrasing");
40
+ const EVIDENCE_FORMAT = "codetrellis-evidence";
41
+ const EVIDENCE_VERSION = 1;
42
+ const MAX_EVIDENCE_ENTRIES = 2e4;
43
+ const MAX_FRAMES = 2e3;
44
+ class EvidenceError extends Error {
45
+ constructor(message, status = 400) {
46
+ super(message);
47
+ this.status = status;
48
+ }
49
+ status;
50
+ }
51
+ const HOW = 'digest = sha256(JSON.stringify([event.id, event.at, event.source, event.type, event.sessionId, event.agentType, event.payload])); hash = sha256(prev + "\\n" + seq + "\\n" + event.id + "\\n" + digest), hex, where prev is the hash before (record.before.hash for the first entry).';
52
+ const DECISION_TYPES = /* @__PURE__ */ new Set(["breakpoint_hit", "breakpoint_answered", "criterion_decided", "signal_answered", "spec_decided", "rule_changed", "retention_changed"]);
53
+ const day = (ms) => new Date(ms).toISOString().slice(0, 10);
54
+ const minute = (ms) => new Date(ms).toISOString().replace("T", " ").slice(0, 16);
55
+ function rowsOf(sql, params = []) {
56
+ const res = (0, import_database.getDb)().exec(sql, params);
57
+ if (!res.length) return [];
58
+ const { columns, values } = res[0];
59
+ return values.map((v) => Object.fromEntries(columns.map((c, i) => [c, v[i]])));
60
+ }
61
+ function linkBefore(at) {
62
+ const last = rowsOf("SELECT seq, hash FROM record_chain WHERE linked_at < ? ORDER BY seq DESC LIMIT 1", [at])[0];
63
+ if (last) return { seq: Number(last.seq), hash: last.hash };
64
+ const a = rowsOf("SELECT through_seq, hash FROM record_anchor WHERE id = 1")[0];
65
+ return a ? { seq: Number(a.through_seq), hash: a.hash } : { seq: 0, hash: import_record_chain.GENESIS };
66
+ }
67
+ function entriesIn(from, to) {
68
+ const n = Number(rowsOf("SELECT COUNT(*) AS n FROM record_chain WHERE linked_at >= ? AND linked_at <= ?", [from, to])[0]?.n ?? 0);
69
+ if (n > MAX_EVIDENCE_ENTRIES) {
70
+ throw new EvidenceError(`That window holds ${n.toLocaleString("en-GB")} record entries; one export carries at most ${MAX_EVIDENCE_ENTRIES.toLocaleString("en-GB")}. Choose a shorter window.`);
71
+ }
72
+ const rows = rowsOf(
73
+ `SELECT c.seq, c.linked_at, c.digest, c.prev, c.hash, e.id, e.at, e.source, e.type, e.session_id, e.agent_type, e.payload
74
+ FROM record_chain c LEFT JOIN agent_events e ON e.id = c.event_id
75
+ WHERE c.linked_at >= ? AND c.linked_at <= ? ORDER BY c.seq ASC`,
76
+ [from, to]
77
+ );
78
+ const before = rows.length ? { seq: Number(rows[0].seq) - 1, hash: rows[0].prev } : linkBefore(from);
79
+ const entries = rows.map((r) => ({
80
+ seq: Number(r.seq),
81
+ linkedAt: Number(r.linked_at),
82
+ digest: r.digest,
83
+ hash: r.hash,
84
+ event: r.id === null ? null : {
85
+ id: r.id,
86
+ at: Number(r.at),
87
+ source: String(r.source),
88
+ type: String(r.type),
89
+ sessionId: r.session_id ?? null,
90
+ agentType: r.agent_type ?? null,
91
+ payload: String(r.payload)
92
+ }
93
+ }));
94
+ return { before, entries };
95
+ }
96
+ function parsePayload(raw) {
97
+ try {
98
+ const v = JSON.parse(raw);
99
+ return v && typeof v === "object" ? v : {};
100
+ } catch {
101
+ return {};
102
+ }
103
+ }
104
+ function decisionsOf(entries) {
105
+ return entries.filter((e) => e.event && DECISION_TYPES.has(e.event.type)).map((e) => {
106
+ const ev = e.event;
107
+ const phrased = (0, import_tool_phrasing.phraseEvent)({ id: ev.id, timestamp: ev.at, source: ev.source, type: ev.type, payload: parsePayload(ev.payload) });
108
+ return { seq: e.seq, at: ev.at, type: ev.type, words: phrased.text };
109
+ });
110
+ }
111
+ function decisionsBetween(from, to, limit = 200) {
112
+ const types = [...DECISION_TYPES];
113
+ const rows = rowsOf(
114
+ `SELECT c.seq, c.linked_at, c.digest, c.prev, c.hash, e.id, e.at, e.source, e.type, e.session_id, e.agent_type, e.payload
115
+ FROM record_chain c JOIN agent_events e ON e.id = c.event_id
116
+ WHERE c.linked_at >= ? AND c.linked_at <= ? AND e.type IN (${types.map(() => "?").join(",")})
117
+ ORDER BY c.seq ASC LIMIT ?`,
118
+ [from, to, ...types, Math.min(Math.max(1, Math.floor(limit)), 1e3)]
119
+ );
120
+ return decisionsOf(rows.map((r) => ({
121
+ seq: Number(r.seq),
122
+ linkedAt: Number(r.linked_at),
123
+ digest: r.digest,
124
+ hash: r.hash,
125
+ event: { id: r.id, at: Number(r.at), source: String(r.source), type: String(r.type), sessionId: r.session_id ?? null, agentType: r.agent_type ?? null, payload: String(r.payload) }
126
+ })));
127
+ }
128
+ function moment(projectPath, at) {
129
+ const { sinceFrame: _diff, projectPath: _path, ...rest } = (0, import_replay_state.stateAt)(projectPath, at, false);
130
+ return rest;
131
+ }
132
+ function buildEvidence(req, now = Date.now()) {
133
+ let projectPath;
134
+ let from;
135
+ let to;
136
+ let plan = null;
137
+ let signoffPack = null;
138
+ if (req.planUid) {
139
+ const p = (0, import_plan_service.getPlan)(req.planUid);
140
+ if (!p) throw new EvidenceError(`Plan ${req.planUid} not found`, 404);
141
+ projectPath = p.projectPath;
142
+ from = p.createdAt;
143
+ to = p.status === "completed" || p.status === "archived" ? Math.max(p.updatedAt, p.createdAt) : now;
144
+ plan = { uid: p.uid, title: p.title };
145
+ signoffPack = (0, import_signoff_pack.buildSignoffPack)(p.uid, new Date(now));
146
+ } else {
147
+ if (!req.projectPath) throw new EvidenceError("Name a plan, or a project and a window (from, to)");
148
+ if (!Number.isFinite(req.from) || !Number.isFinite(req.to)) throw new EvidenceError("from and to must be times in milliseconds");
149
+ projectPath = req.projectPath;
150
+ from = req.from;
151
+ to = Math.min(req.to, now);
152
+ if (from > to) throw new EvidenceError("from must be before to");
153
+ }
154
+ const { before, entries } = entriesIn(from, to);
155
+ const last = entries[entries.length - 1];
156
+ const words = `${plan ? `The plan \u201C${plan.title}\u201D: ` : ""}${minute(from)} to ${minute(to)} UTC, ${entries.length.toLocaleString("en-GB")} record entr${entries.length === 1 ? "y" : "ies"}`;
157
+ return {
158
+ format: EVIDENCE_FORMAT,
159
+ version: EVIDENCE_VERSION,
160
+ generatedAt: new Date(now).toISOString(),
161
+ window: { from, to, projectPath, plan, words },
162
+ record: { how: HOW, before, through: last ? { seq: last.seq, hash: last.hash } : before, entries },
163
+ frames: (0, import_replay_frames.listFrames)(projectPath, { from, to, limit: MAX_FRAMES }),
164
+ start: moment(projectPath, from),
165
+ end: moment(projectPath, to),
166
+ decisions: decisionsOf(entries),
167
+ signoffPack
168
+ };
169
+ }
170
+ function sealEvidence(e) {
171
+ return (0, import_pack_seal.sealDocument)(import_pack_seal.EVIDENCE_NAMESPACE, e);
172
+ }
173
+ const MAX_PROBLEMS = 50;
174
+ const label = (p) => `#${p.seq}${p.type ? ` (${p.type.replace(/_/g, " ")}${p.agentType ? ` by ${p.agentType}` : ""}${p.at ? `, ${day(p.at)}` : ""})` : ""}`;
175
+ function str(v) {
176
+ return typeof v === "string" ? v : null;
177
+ }
178
+ function num(v) {
179
+ return typeof v === "number" && Number.isFinite(v) ? v : null;
180
+ }
181
+ function entriesOf(doc) {
182
+ const record = doc.record;
183
+ if (!record || !Array.isArray(record.entries)) return null;
184
+ const b = record.before;
185
+ const before = b && num(b.seq) !== null && str(b.hash) ? { seq: num(b.seq), hash: str(b.hash) } : null;
186
+ const entries = [];
187
+ for (const raw of record.entries.slice(0, MAX_EVIDENCE_ENTRIES)) {
188
+ const e = raw ?? {};
189
+ const ev = e.event;
190
+ entries.push({
191
+ seq: num(e.seq) ?? -1,
192
+ linkedAt: num(e.linkedAt) ?? 0,
193
+ digest: str(e.digest) ?? "",
194
+ hash: str(e.hash) ?? "",
195
+ event: ev && typeof ev === "object" ? {
196
+ id: str(ev.id) ?? "",
197
+ at: num(ev.at) ?? 0,
198
+ source: str(ev.source) ?? "",
199
+ type: str(ev.type) ?? "",
200
+ sessionId: str(ev.sessionId),
201
+ agentType: str(ev.agentType),
202
+ payload: str(ev.payload) ?? ""
203
+ } : null
204
+ });
205
+ }
206
+ return { before, entries };
207
+ }
208
+ function checkChain(before, entries) {
209
+ const problems = [];
210
+ const say = (p) => {
211
+ if (problems.length < MAX_PROBLEMS) problems.push(p);
212
+ };
213
+ let prev = before?.hash ?? "";
214
+ let expected = (before?.seq ?? -1) + 1;
215
+ for (const e of entries) {
216
+ const info = { type: e.event?.type ?? null, agentType: e.event?.agentType ?? null, at: e.event?.at ?? null };
217
+ if (!before || e.seq !== expected) say({ seq: e.seq, kind: "relinked", ...info });
218
+ else if ((0, import_record_chain.linkHash)(prev, e.seq, e.event?.id ?? "", e.digest) !== e.hash) say({ seq: e.seq, kind: "relinked", ...info });
219
+ if (!e.event) say({ seq: e.seq, kind: "missing", ...info });
220
+ else if ((0, import_record_chain.digestOf)({ id: e.event.id, at: e.event.at, source: e.event.source, type: e.event.type, session_id: e.event.sessionId, agent_type: e.event.agentType, payload: e.event.payload }) !== e.digest) {
221
+ say({ seq: e.seq, kind: "changed", ...info });
222
+ }
223
+ prev = e.hash;
224
+ expected = e.seq + 1;
225
+ }
226
+ const ok = problems.length === 0;
227
+ const span = entries.length ? ` (#${entries[0].seq} to #${entries[entries.length - 1].seq})` : "";
228
+ const n = `${entries.length.toLocaleString("en-GB")} record entr${entries.length === 1 ? "y" : "ies"}`;
229
+ const WORDS = {
230
+ changed: "its event does not match its digest",
231
+ relinked: "its link does not follow from the one before",
232
+ missing: "its event was already gone when it was exported"
233
+ };
234
+ const words = ok ? entries.length ? `Its ${n}${span} recompute into one unbroken chain.` : "It carries no record entries." : `Its record entries do not recompute: ${problems.slice(0, 3).map((p) => `${label(p)}: ${WORDS[p.kind]}`).join("; ")}.`;
235
+ return { ok, entries: entries.length, problems, words };
236
+ }
237
+ function checkHere(entries) {
238
+ const db = (0, import_database.getDb)();
239
+ const anchorSeq = Number(db.exec("SELECT through_seq FROM record_anchor WHERE id = 1")[0]?.values[0]?.[0] ?? 0);
240
+ const problems = [];
241
+ let trimmed = 0;
242
+ for (const e of entries) {
243
+ if (problems.length >= MAX_PROBLEMS) break;
244
+ const info = { type: e.event?.type ?? null, agentType: e.event?.agentType ?? null, at: e.event?.at ?? null };
245
+ const link = rowsOf("SELECT hash, event_id FROM record_chain WHERE seq = ?", [e.seq])[0];
246
+ if (!link) {
247
+ if (e.seq <= anchorSeq) trimmed++;
248
+ else problems.push({ seq: e.seq, kind: "removed", ...info });
249
+ continue;
250
+ }
251
+ if (link.hash !== e.hash) {
252
+ problems.push({ seq: e.seq, kind: "relinked", ...info });
253
+ continue;
254
+ }
255
+ const ev = rowsOf(
256
+ "SELECT id, at, source, type, session_id, agent_type, payload FROM agent_events WHERE id = ?",
257
+ [link.event_id]
258
+ )[0];
259
+ if (!ev) {
260
+ if (e.event) problems.push({ seq: e.seq, kind: "removed", ...info });
261
+ continue;
262
+ }
263
+ if ((0, import_record_chain.digestOf)(ev) !== e.digest) problems.push({ seq: e.seq, kind: "changed", ...info });
264
+ }
265
+ const WORDS = {
266
+ changed: "its content was changed in this computer's record since",
267
+ removed: "it was removed from this computer's record since",
268
+ relinked: "its link in this computer's record was changed since"
269
+ };
270
+ if (problems.length) {
271
+ return { state: "differs", problems, words: `Since it was exported: ${problems.slice(0, 3).map((p) => `${label(p)}: ${WORDS[p.kind]}`).join("; ")}.` };
272
+ }
273
+ if (trimmed) {
274
+ return { state: "trimmed", problems, words: `This computer's record still matches it, except ${trimmed.toLocaleString("en-GB")} entr${trimmed === 1 ? "y" : "ies"} retention has removed since.` };
275
+ }
276
+ return { state: "matches", problems, words: entries.length ? "This computer's record still holds every entry in it, unchanged." : "This computer's record has nothing to compare." };
277
+ }
278
+ function verifyEvidence(doc) {
279
+ const d = doc && typeof doc === "object" ? doc : {};
280
+ if (d.format !== EVIDENCE_FORMAT) throw new EvidenceError("That file is not a CodeTrellis evidence export");
281
+ const seal = (0, import_pack_seal.checkDocumentSeal)(import_pack_seal.EVIDENCE_NAMESPACE, "export", d);
282
+ const read = entriesOf(d);
283
+ const chain = read ? checkChain(read.before, read.entries) : { ok: false, entries: 0, problems: [], words: "It carries no record entries that can be read." };
284
+ const here = seal.state === "this-computer" && read ? checkHere(read.entries) : {
285
+ state: "not-here",
286
+ problems: [],
287
+ words: seal.state === "changed" || seal.state === "unsigned" ? "Its signature does not hold, so who made it is not known and this computer's record was not compared." : "It was made on another computer, so this one has no record of it to compare."
288
+ };
289
+ const ok = (seal.state === "this-computer" || seal.state === "teammate") && chain.ok && here.state !== "differs";
290
+ return { ok, seal, chain, here, words: [seal.words, chain.words, here.words].filter(Boolean).join(" ") };
291
+ }
292
+ function evidenceFromText(text) {
293
+ const trimmed = text.trim();
294
+ try {
295
+ if (trimmed.startsWith("{")) return JSON.parse(trimmed);
296
+ const m = trimmed.match(/<script type="application\/json" id="codetrellis-evidence">([\s\S]*?)<\/script>/);
297
+ if (!m) throw new EvidenceError("No evidence data in that file");
298
+ return JSON.parse(m[1]);
299
+ } catch (err) {
300
+ if (err instanceof EvidenceError) throw err;
301
+ throw new EvidenceError("That file is not a readable evidence export");
302
+ }
303
+ }
304
+ function stackSection(title, m) {
305
+ const plans = m.stack.plans.map((p) => `<li><b>${(0, import_signoff_pack.esc)(p.title)}</b> <span class="muted">${(0, import_signoff_pack.esc)(p.status)}</span><ul>${p.tasks.map((t) => `<li>${(0, import_signoff_pack.esc)(t.title)} <span class="muted">${(0, import_signoff_pack.esc)(t.status ?? "")}${t.assignee ? ` \xB7 ${(0, import_signoff_pack.esc)(t.assignee)}` : ""}${t.workstream ? ` \xB7 ${(0, import_signoff_pack.esc)(t.workstream)}` : ""}</span></li>`).join("")}</ul></li>`).join("");
306
+ const signals = m.signals.map((s) => `<li>${(0, import_signoff_pack.esc)(s.summary)} <span class="muted">${(0, import_signoff_pack.esc)(s.severity)}</span></li>`).join("");
307
+ return `<h2>${(0, import_signoff_pack.esc)(title)} <span class="muted">${(0, import_signoff_pack.esc)(minute(m.at))} UTC</span></h2>
308
+ <h3>The stack</h3>${plans ? `<ul>${plans}</ul>` : '<p class="muted">Nothing under way.</p>'}
309
+ <h3>Signals open</h3>${signals ? `<ul>${signals}</ul>` : '<p class="muted">None.</p>'}
310
+ <p class="muted">${m.waiting.length === 0 ? "Nothing was waiting on a person." : `${m.waiting.length} call${m.waiting.length === 1 ? " was" : "s were"} waiting on a person.`}</p>`;
311
+ }
312
+ function renderEvidenceHtml(e) {
313
+ const title = e.window.plan ? `Evidence \u2014 ${e.window.plan.title}` : "Evidence";
314
+ const decisions = e.decisions.map((d) => `<tr><td>#${d.seq}</td><td>${(0, import_signoff_pack.esc)(minute(d.at))}</td><td>${(0, import_signoff_pack.esc)(d.words)}</td></tr>`).join("");
315
+ const frames = e.frames.map((f) => `<tr><td>${(0, import_signoff_pack.esc)(minute(f.at))}</td><td>${(0, import_signoff_pack.esc)(f.reasons.join(", "))}</td><td><code>${(0, import_signoff_pack.esc)((f.commitSha ?? "").slice(0, 10))}</code> ${(0, import_signoff_pack.esc)(f.branch ?? "")}</td><td>${(0, import_signoff_pack.esc)(f.agentType ?? "")}</td></tr>`).join("");
316
+ return `<!doctype html>
317
+ <html lang="en">
318
+ <head>
319
+ <meta charset="utf-8">
320
+ <meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'">
321
+ <title>${(0, import_signoff_pack.esc)(title)}</title>
322
+ <style>
323
+ body { font: 13px/1.5 -apple-system, "Segoe UI", Helvetica, Arial, sans-serif; color: #111; max-width: 860px; margin: 32px auto; padding: 0 24px; }
324
+ h1 { font-size: 22px; margin: 0 0 4px; }
325
+ h2 { font-size: 16px; margin: 28px 0 8px; border-bottom: 1px solid #ddd; padding-bottom: 4px; }
326
+ h3 { font-size: 13px; margin: 12px 0 4px; }
327
+ .muted { color: #666; font-weight: normal; font-size: 12px; }
328
+ code { font: 11px ui-monospace, Menlo, Consolas, monospace; color: #444; word-break: break-all; }
329
+ table { border-collapse: collapse; width: 100%; font-size: 12px; }
330
+ td, th { border-bottom: 1px solid #eee; padding: 4px 6px; text-align: left; vertical-align: top; }
331
+ </style>
332
+ </head>
333
+ <body>
334
+ <h1>${(0, import_signoff_pack.esc)(title)}</h1>
335
+ <p class="muted">${(0, import_signoff_pack.esc)(e.window.words)} \xB7 ${(0, import_signoff_pack.esc)(e.window.projectPath)} \xB7 generated ${(0, import_signoff_pack.esc)(e.generatedAt.replace("T", " ").slice(0, 16))} UTC by CodeTrellis</p>
336
+ ${e.seal ? `<p class="muted" id="seal">Signed by the computer with key <code>${(0, import_signoff_pack.esc)(e.seal.key)}</code>, with its record at entry #${(0, import_signoff_pack.esc)(String(e.sealedRecord?.seq ?? 0))}. Verify it in CodeTrellis: a changed byte, a broken chain, or a record changed since, shows.</p>` : ""}
337
+ <h2>Breakpoints and decisions</h2>
338
+ ${decisions ? `<table><thead><tr><th>Entry</th><th>When (UTC)</th><th>What</th></tr></thead><tbody>${decisions}</tbody></table>` : '<p class="muted">None in this window.</p>'}
339
+ ${stackSection("At the start", e.start)}
340
+ ${stackSection("At the end", e.end)}
341
+ <h2>Recorded moments</h2>
342
+ ${frames ? `<table><thead><tr><th>When (UTC)</th><th>Why</th><th>Commit</th><th>Agent</th></tr></thead><tbody>${frames}</tbody></table>` : '<p class="muted">None in this window.</p>'}
343
+ <h2>The record</h2>
344
+ <p class="muted">${e.record.entries.length.toLocaleString("en-GB")} entries, from the link after #${e.record.before.seq} (<code>${(0, import_signoff_pack.esc)(e.record.before.hash.slice(0, 16))}\u2026</code>) through #${e.record.through.seq} (<code>${(0, import_signoff_pack.esc)(e.record.through.hash.slice(0, 16))}\u2026</code>). Each recomputes from the data in this file: ${(0, import_signoff_pack.esc)(e.record.how)}</p>
345
+ ${e.signoffPack ? `<h2>Sign-off pack</h2><p class="muted">${e.signoffPack.rows.filter((r) => r.state === "met").length} of ${e.signoffPack.rows.length} criteria met; ${e.signoffPack.files.length} file${e.signoffPack.files.length === 1 ? "" : "s"} with hashes. The pack is in this file's data.</p>` : ""}
346
+ <script type="application/json" id="codetrellis-evidence">${(0, import_signoff_pack.scriptJson)(e)}</script>
347
+ </body>
348
+ </html>
349
+ `;
350
+ }
351
+ // Annotate the CommonJS export names for ESM import in node:
352
+ 0 && (module.exports = {
353
+ EVIDENCE_FORMAT,
354
+ EVIDENCE_VERSION,
355
+ EvidenceError,
356
+ MAX_EVIDENCE_ENTRIES,
357
+ buildEvidence,
358
+ decisionsBetween,
359
+ evidenceFromText,
360
+ renderEvidenceHtml,
361
+ sealEvidence,
362
+ verifyEvidence
363
+ });
@@ -0,0 +1,269 @@
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 external_intake_service_exports = {};
29
+ __export(external_intake_service_exports, {
30
+ MAX_INTAKE_DEPTH: () => MAX_INTAKE_DEPTH,
31
+ acceptanceSection: () => acceptanceSection,
32
+ findPlanByExternalKey: () => findPlanByExternalKey,
33
+ flattenIntake: () => flattenIntake,
34
+ getPlanExternalRefs: () => getPlanExternalRefs,
35
+ getSyncState: () => getSyncState,
36
+ intakeBody: () => intakeBody,
37
+ intakeKind: () => intakeKind,
38
+ keyFromUrl: () => keyFromUrl,
39
+ markSynced: () => markSynced,
40
+ sameUrl: () => sameUrl,
41
+ setPlanExternalRef: () => setPlanExternalRef
42
+ });
43
+ module.exports = __toCommonJS(external_intake_service_exports);
44
+ var _lazy___plan_file_service = __toESM(require("./plan-file-service"));
45
+ var import_node_crypto = require("node:crypto");
46
+ var import_database = require("./database");
47
+ var import_persistence = require("./persistence");
48
+ var import_external_refs_service = require("./external-refs-service");
49
+ const MAX_INTAKE_DEPTH = 3;
50
+ function getPlanExternalRefs(planUid) {
51
+ try {
52
+ const res = (0, import_database.getDb)().exec(
53
+ `SELECT uid, plan_uid, kind, url, title, external_key, author, author_type, created_at
54
+ FROM plan_external_refs WHERE plan_uid = ? ORDER BY created_at ASC`,
55
+ [planUid]
56
+ );
57
+ return (res[0]?.values ?? []).map((r) => ({
58
+ uid: r[0],
59
+ planUid: r[1],
60
+ kind: r[2],
61
+ url: r[3],
62
+ title: r[4],
63
+ externalKey: r[5] ?? null,
64
+ author: r[6],
65
+ authorType: r[7],
66
+ createdAt: r[8]
67
+ }));
68
+ } catch {
69
+ return [];
70
+ }
71
+ }
72
+ function sameUrl(a, b) {
73
+ const norm = (u) => {
74
+ try {
75
+ const p = new URL(u);
76
+ return `${p.protocol.toLowerCase()}//${p.host.toLowerCase()}${p.pathname.replace(/\/+$/, "")}${p.search}`;
77
+ } catch {
78
+ return u.trim().replace(/\/+$/, "");
79
+ }
80
+ };
81
+ return norm(a) === norm(b);
82
+ }
83
+ function findPlanByExternalKey(key) {
84
+ if (!key) return null;
85
+ try {
86
+ const res = (0, import_database.getDb)().exec(
87
+ `SELECT r.plan_uid
88
+ FROM plan_external_refs r
89
+ JOIN plans p ON p.uid = r.plan_uid
90
+ WHERE r.external_key = ? AND p.status != 'archived'
91
+ ORDER BY r.created_at ASC LIMIT 1`,
92
+ [key]
93
+ );
94
+ return res[0]?.values?.[0]?.[0] ?? null;
95
+ } catch {
96
+ return null;
97
+ }
98
+ }
99
+ function writePlanThrough(planUid) {
100
+ try {
101
+ _lazy___plan_file_service.scheduleWriteThrough(planUid);
102
+ } catch {
103
+ }
104
+ }
105
+ function setPlanExternalRef(input) {
106
+ const db = (0, import_database.getDb)();
107
+ const kind = input.kind ?? (0, import_external_refs_service.inferKind)(input.url);
108
+ const key = input.key ?? keyFromUrl(input.url, kind);
109
+ const title = input.title?.trim() || key || input.url;
110
+ const now = Date.now();
111
+ const refs = getPlanExternalRefs(input.planUid);
112
+ const existing = key ? refs.find((r) => r.externalKey === key) : refs.find((r) => r.externalKey === null && sameUrl(r.url, input.url));
113
+ if (existing) {
114
+ db.run(`UPDATE plan_external_refs SET url = ?, title = ?, kind = ? WHERE uid = ?`, [
115
+ input.url,
116
+ title,
117
+ kind,
118
+ existing.uid
119
+ ]);
120
+ (0, import_persistence.markDirty)();
121
+ writePlanThrough(input.planUid);
122
+ return { ...existing, url: input.url, title, kind };
123
+ }
124
+ const uid = (0, import_node_crypto.randomUUID)();
125
+ const author = input.author ?? "human";
126
+ const authorType = input.authorType ?? "human";
127
+ db.run(
128
+ `INSERT INTO plan_external_refs (uid, plan_uid, kind, url, title, external_key, author, author_type, created_at)
129
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
130
+ [uid, input.planUid, kind, input.url, title, key, author, authorType, now]
131
+ );
132
+ (0, import_persistence.markDirty)();
133
+ writePlanThrough(input.planUid);
134
+ return {
135
+ uid,
136
+ planUid: input.planUid,
137
+ kind,
138
+ url: input.url,
139
+ title,
140
+ externalKey: key,
141
+ author,
142
+ authorType,
143
+ createdAt: now
144
+ };
145
+ }
146
+ function keyFromUrl(url, kind) {
147
+ const k = kind ?? (0, import_external_refs_service.inferKind)(url);
148
+ const patterns = {
149
+ jira: /\/browse\/([A-Z][A-Z0-9_]+-\d+)/i,
150
+ linear: /\/issue\/([A-Z][A-Z0-9_]+-\d+)/i,
151
+ github_issue: /github\.com\/([^/]+\/[^/]+)\/issues\/(\d+)/i,
152
+ github_pr: /github\.com\/([^/]+\/[^/]+)\/pull\/(\d+)/i
153
+ };
154
+ const re = patterns[k];
155
+ if (!re) return null;
156
+ const m = re.exec(url);
157
+ if (!m) return null;
158
+ return m.length > 2 ? `${m[1]}#${m[2]}` : m[1].toUpperCase();
159
+ }
160
+ function acceptanceSection(criteria) {
161
+ const clean = criteria.map((c) => c.trim()).filter(Boolean);
162
+ if (clean.length === 0) return "";
163
+ return ["", "## Acceptance criteria", ...clean.map((c) => `- [ ] ${c}`), ""].join("\n");
164
+ }
165
+ function suggestTransition(status) {
166
+ switch (status) {
167
+ case "in_progress":
168
+ return "In Progress";
169
+ case "done":
170
+ return "Done";
171
+ case "blocked":
172
+ return "Blocked";
173
+ case "pending":
174
+ case "assigned":
175
+ return "To Do";
176
+ default:
177
+ return null;
178
+ }
179
+ }
180
+ function getSyncState(planUid) {
181
+ const db = (0, import_database.getDb)();
182
+ let lastSyncedAt = null;
183
+ try {
184
+ const res = db.exec(`SELECT last_synced_at FROM external_sync_state WHERE plan_uid = ?`, [planUid]);
185
+ const row = res[0]?.values[0];
186
+ if (row) lastSyncedAt = row[0];
187
+ } catch {
188
+ }
189
+ const changed = [];
190
+ try {
191
+ const res = db.exec(
192
+ `SELECT i.uid, i.title, i.status, i.updated_at, r.external_key, r.url
193
+ FROM plan_items i
194
+ JOIN external_refs r ON r.item_uid = i.uid
195
+ WHERE i.plan_uid = ?
196
+ AND r.external_key IS NOT NULL
197
+ AND (? IS NULL OR i.updated_at > ?)
198
+ ORDER BY i.updated_at ASC`,
199
+ [planUid, lastSyncedAt, lastSyncedAt]
200
+ );
201
+ for (const row of res[0]?.values ?? []) {
202
+ const status = row[2] ?? null;
203
+ changed.push({
204
+ itemUid: row[0],
205
+ title: row[1],
206
+ status,
207
+ updatedAt: row[3],
208
+ externalKey: row[4],
209
+ url: row[5],
210
+ suggestedTransition: suggestTransition(status)
211
+ });
212
+ }
213
+ } catch {
214
+ }
215
+ return { planUid, lastSyncedAt, changed, planRefs: getPlanExternalRefs(planUid) };
216
+ }
217
+ function markSynced(planUid, syncedBy, note) {
218
+ const now = Date.now();
219
+ (0, import_database.getDb)().run(
220
+ `INSERT INTO external_sync_state (plan_uid, last_synced_at, synced_by, note)
221
+ VALUES (?, ?, ?, ?)
222
+ ON CONFLICT(plan_uid) DO UPDATE SET
223
+ last_synced_at = excluded.last_synced_at,
224
+ synced_by = excluded.synced_by,
225
+ note = excluded.note`,
226
+ [planUid, now, syncedBy ?? null, note ?? null]
227
+ );
228
+ (0, import_persistence.markDirty)();
229
+ return { lastSyncedAt: now };
230
+ }
231
+ function flattenIntake(roots, maxDepth = MAX_INTAKE_DEPTH) {
232
+ const out = [];
233
+ const walk = (node, depth, parentIndex) => {
234
+ const index = out.length;
235
+ out.push({ node, depth, parentIndex });
236
+ const canNest = depth + 1 <= maxDepth - 1;
237
+ const childDepth = canNest ? depth + 1 : depth;
238
+ const childParent = canNest ? index : parentIndex;
239
+ for (const child of node.children ?? []) {
240
+ walk(child, childDepth, childParent);
241
+ }
242
+ };
243
+ for (const root of roots) walk(root, 0, null);
244
+ return out;
245
+ }
246
+ function intakeBody(node) {
247
+ const body = (node.body ?? "").trim();
248
+ const acceptance = acceptanceSection(node.acceptance ?? []);
249
+ return [body, acceptance].filter(Boolean).join("\n");
250
+ }
251
+ function intakeKind(node, depth) {
252
+ if (node.kind) return node.kind;
253
+ return depth === 0 && (node.children?.length ?? 0) > 0 ? "object" : "action";
254
+ }
255
+ // Annotate the CommonJS export names for ESM import in node:
256
+ 0 && (module.exports = {
257
+ MAX_INTAKE_DEPTH,
258
+ acceptanceSection,
259
+ findPlanByExternalKey,
260
+ flattenIntake,
261
+ getPlanExternalRefs,
262
+ getSyncState,
263
+ intakeBody,
264
+ intakeKind,
265
+ keyFromUrl,
266
+ markSynced,
267
+ sameUrl,
268
+ setPlanExternalRef
269
+ });