codetrellis 0.0.0-stage → 0.2.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 (449) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +27 -2
  3. package/bin/codetrellis.mjs +4 -0
  4. package/package.json +43 -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/clock.js +57 -0
  102. package/src/backend/services/cloud-files.js +191 -0
  103. package/src/backend/services/coalesce.js +50 -0
  104. package/src/backend/services/code-breakpoints.js +291 -0
  105. package/src/backend/services/comment-service.js +168 -0
  106. package/src/backend/services/commit-attribution.js +134 -0
  107. package/src/backend/services/commit-edges.js +99 -0
  108. package/src/backend/services/confined-fs.js +241 -0
  109. package/src/backend/services/conformity-gate.js +132 -0
  110. package/src/backend/services/contribution-service.js +409 -0
  111. package/src/backend/services/coverage-service.js +173 -0
  112. package/src/backend/services/criteria-service.js +721 -0
  113. package/src/backend/services/criterion-checks.js +387 -0
  114. package/src/backend/services/criterion-loop-service.js +411 -0
  115. package/src/backend/services/cross-system-service.js +231 -0
  116. package/src/backend/services/database.js +916 -0
  117. package/src/backend/services/db-schema.js +1358 -0
  118. package/src/backend/services/deviation-service.js +344 -0
  119. package/src/backend/services/diff-engine.js +168 -0
  120. package/src/backend/services/evidence.js +363 -0
  121. package/src/backend/services/external-intake-service.js +269 -0
  122. package/src/backend/services/external-pointer-service.js +195 -0
  123. package/src/backend/services/external-refs-service.js +214 -0
  124. package/src/backend/services/file-history.js +158 -0
  125. package/src/backend/services/file-watcher.js +193 -0
  126. package/src/backend/services/folder-requests.js +118 -0
  127. package/src/backend/services/freeze-service.js +189 -0
  128. package/src/backend/services/gemini-cli-hook.js +172 -0
  129. package/src/backend/services/git-activity-service.js +325 -0
  130. package/src/backend/services/git-blobs.js +70 -0
  131. package/src/backend/services/git-branches.js +357 -0
  132. package/src/backend/services/git-checkout.js +153 -0
  133. package/src/backend/services/git-commit-service.js +91 -0
  134. package/src/backend/services/git-env.js +121 -0
  135. package/src/backend/services/git-identity.js +84 -0
  136. package/src/backend/services/git-refs.js +386 -0
  137. package/src/backend/services/git-safety.js +58 -0
  138. package/src/backend/services/grant-guard.js +67 -0
  139. package/src/backend/services/html-view-policy.js +135 -0
  140. package/src/backend/services/human-decision.js +55 -0
  141. package/src/backend/services/importers.js +159 -0
  142. package/src/backend/services/intent-service.js +105 -0
  143. package/src/backend/services/ipc-dispatcher.js +164 -0
  144. package/src/backend/services/item-git-state.js +208 -0
  145. package/src/backend/services/line-changes.js +232 -0
  146. package/src/backend/services/line-history.js +174 -0
  147. package/src/backend/services/local-api-changes.js +40 -0
  148. package/src/backend/services/logger.js +217 -0
  149. package/src/backend/services/material-footprints.js +203 -0
  150. package/src/backend/services/material-place.js +82 -0
  151. package/src/backend/services/material-reader/child.js +4 -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/read.js +430 -0
  156. package/src/backend/services/material-reader/reader-host.js +202 -0
  157. package/src/backend/services/material-signals.js +141 -0
  158. package/src/backend/services/mcp-capabilities.js +390 -0
  159. package/src/backend/services/mdns-service.js +304 -0
  160. package/src/backend/services/mobile-api-server.js +281 -0
  161. package/src/backend/services/mobile-approvals.js +306 -0
  162. package/src/backend/services/mobile-awareness.js +180 -0
  163. package/src/backend/services/mobile-breakpoints.js +115 -0
  164. package/src/backend/services/mobile-budget.js +98 -0
  165. package/src/backend/services/mobile-freeze.js +106 -0
  166. package/src/backend/services/mobile-proposals.js +100 -0
  167. package/src/backend/services/mobile-rpc-service.js +1289 -0
  168. package/src/backend/services/mobile-workstreams.js +160 -0
  169. package/src/backend/services/monorepo-detector.js +131 -0
  170. package/src/backend/services/other-work.js +45 -0
  171. package/src/backend/services/pack-seal.js +129 -0
  172. package/src/backend/services/paired-device-service.js +192 -0
  173. package/src/backend/services/pairing-server.js +323 -0
  174. package/src/backend/services/pairing-service.js +200 -0
  175. package/src/backend/services/pantry-resolution-service.js +166 -0
  176. package/src/backend/services/parsers/base.js +124 -0
  177. package/src/backend/services/parsers/csharp.js +224 -0
  178. package/src/backend/services/parsers/go.js +180 -0
  179. package/src/backend/services/parsers/index.js +101 -0
  180. package/src/backend/services/parsers/java.js +103 -0
  181. package/src/backend/services/parsers/kotlin.js +252 -0
  182. package/src/backend/services/parsers/php.js +113 -0
  183. package/src/backend/services/parsers/python.js +189 -0
  184. package/src/backend/services/parsers/ruby.js +212 -0
  185. package/src/backend/services/parsers/rust.js +97 -0
  186. package/src/backend/services/parsers/swift.js +221 -0
  187. package/src/backend/services/parsers/typescript.js +235 -0
  188. package/src/backend/services/pattern-scan.js +65 -0
  189. package/src/backend/services/patterns.js +281 -0
  190. package/src/backend/services/peer-audit-service.js +123 -0
  191. package/src/backend/services/peer-auth.js +153 -0
  192. package/src/backend/services/peer-capabilities.js +209 -0
  193. package/src/backend/services/peer-connection-service.js +450 -0
  194. package/src/backend/services/peer-grants.js +33 -0
  195. package/src/backend/services/persistence.js +116 -0
  196. package/src/backend/services/personal-sync-service.js +232 -0
  197. package/src/backend/services/pipeline-approvals.js +72 -0
  198. package/src/backend/services/pipeline.js +232 -0
  199. package/src/backend/services/plan-arrivals.js +68 -0
  200. package/src/backend/services/plan-changes-service.js +273 -0
  201. package/src/backend/services/plan-conflict-service.js +288 -0
  202. package/src/backend/services/plan-dependencies.js +91 -0
  203. package/src/backend/services/plan-doc-guard.js +90 -0
  204. package/src/backend/services/plan-documents-service.js +275 -0
  205. package/src/backend/services/plan-event-service.js +154 -0
  206. package/src/backend/services/plan-file-refs.js +106 -0
  207. package/src/backend/services/plan-file-service.js +1564 -0
  208. package/src/backend/services/plan-history-service.js +156 -0
  209. package/src/backend/services/plan-import-service.js +261 -0
  210. package/src/backend/services/plan-item-service.js +1223 -0
  211. package/src/backend/services/plan-migrate-service.js +395 -0
  212. package/src/backend/services/plan-overlay-service.js +173 -0
  213. package/src/backend/services/plan-phases-service.js +182 -0
  214. package/src/backend/services/plan-progress-service.js +134 -0
  215. package/src/backend/services/plan-review-service.js +262 -0
  216. package/src/backend/services/plan-service.js +682 -0
  217. package/src/backend/services/plan-status.js +113 -0
  218. package/src/backend/services/plan-template-publish-service.js +217 -0
  219. package/src/backend/services/plan-templates-service.js +242 -0
  220. package/src/backend/services/plan-templates.js +1164 -0
  221. package/src/backend/services/planned-overlap-actions.js +200 -0
  222. package/src/backend/services/plans-home.js +224 -0
  223. package/src/backend/services/play-forward.js +256 -0
  224. package/src/backend/services/playback-service.js +117 -0
  225. package/src/backend/services/power-service.js +167 -0
  226. package/src/backend/services/power-signals.js +81 -0
  227. package/src/backend/services/pr-draft-service.js +142 -0
  228. package/src/backend/services/presence-service.js +122 -0
  229. package/src/backend/services/pricing.js +60 -0
  230. package/src/backend/services/project-config-service.js +474 -0
  231. package/src/backend/services/project-scanner.js +184 -0
  232. package/src/backend/services/projection-service.js +69 -0
  233. package/src/backend/services/push-notification-service.js +288 -0
  234. package/src/backend/services/recent-projects-service.js +204 -0
  235. package/src/backend/services/record-chain.js +162 -0
  236. package/src/backend/services/recurrence-rule.js +63 -0
  237. package/src/backend/services/recurring-agent.js +89 -0
  238. package/src/backend/services/recurring-scheduler.js +77 -0
  239. package/src/backend/services/recurring-service.js +276 -0
  240. package/src/backend/services/reference-service.js +169 -0
  241. package/src/backend/services/release-public-key.js +30 -0
  242. package/src/backend/services/release-signature.js +64 -0
  243. package/src/backend/services/remote-audio-service.js +224 -0
  244. package/src/backend/services/remote-interaction-service.js +275 -0
  245. package/src/backend/services/remote-terminal-service.js +324 -0
  246. package/src/backend/services/rendition/child/main.js +76 -0
  247. package/src/backend/services/rendition/engine-host.js +249 -0
  248. package/src/backend/services/rendition/engine-lock.js +39 -0
  249. package/src/backend/services/rendition/engine-lock.json +14 -0
  250. package/src/backend/services/rendition/engine-manifest.js +97 -0
  251. package/src/backend/services/rendition/network-proof.js +73 -0
  252. package/src/backend/services/rendition/rendition-service.js +175 -0
  253. package/src/backend/services/replay-frames.js +387 -0
  254. package/src/backend/services/replay-state.js +201 -0
  255. package/src/backend/services/resolvers/base.js +108 -0
  256. package/src/backend/services/resolvers/csharp.js +109 -0
  257. package/src/backend/services/resolvers/go.js +105 -0
  258. package/src/backend/services/resolvers/index.js +60 -0
  259. package/src/backend/services/resolvers/java.js +63 -0
  260. package/src/backend/services/resolvers/kotlin.js +109 -0
  261. package/src/backend/services/resolvers/php.js +89 -0
  262. package/src/backend/services/resolvers/python.js +154 -0
  263. package/src/backend/services/resolvers/ruby.js +103 -0
  264. package/src/backend/services/resolvers/rust.js +77 -0
  265. package/src/backend/services/resolvers/swift.js +98 -0
  266. package/src/backend/services/resolvers/typescript.js +71 -0
  267. package/src/backend/services/retention.js +54 -0
  268. package/src/backend/services/review-architecture.js +236 -0
  269. package/src/backend/services/review-attest.js +68 -0
  270. package/src/backend/services/review-bundle.js +226 -0
  271. package/src/backend/services/review-graduation.js +93 -0
  272. package/src/backend/services/review-host/bitbucket.js +79 -0
  273. package/src/backend/services/review-host/detect.js +80 -0
  274. package/src/backend/services/review-host/github.js +97 -0
  275. package/src/backend/services/review-host/gitlab.js +77 -0
  276. package/src/backend/services/review-host/host-state.js +103 -0
  277. package/src/backend/services/review-host/http.js +58 -0
  278. package/src/backend/services/review-host/switch.js +120 -0
  279. package/src/backend/services/review-marks.js +72 -0
  280. package/src/backend/services/review-notes.js +169 -0
  281. package/src/backend/services/review-other-work.js +90 -0
  282. package/src/backend/services/review-queue-service.js +147 -0
  283. package/src/backend/services/review-risk.js +127 -0
  284. package/src/backend/services/review-task.js +121 -0
  285. package/src/backend/services/rule-approvals.js +268 -0
  286. package/src/backend/services/rule-baseline.js +134 -0
  287. package/src/backend/services/rule-changes.js +162 -0
  288. package/src/backend/services/rule-preview.js +47 -0
  289. package/src/backend/services/rule-proposals.js +104 -0
  290. package/src/backend/services/rule-scope.js +76 -0
  291. package/src/backend/services/rulebook.js +286 -0
  292. package/src/backend/services/rules-at.js +56 -0
  293. package/src/backend/services/rules-overview.js +88 -0
  294. package/src/backend/services/schema-reconciler.js +250 -0
  295. package/src/backend/services/secret-store.js +119 -0
  296. package/src/backend/services/section-workstreams.js +95 -0
  297. package/src/backend/services/self-write-tracker.js +75 -0
  298. package/src/backend/services/sensor-bridge-service.js +285 -0
  299. package/src/backend/services/session-service.js +192 -0
  300. package/src/backend/services/settings-service.js +324 -0
  301. package/src/backend/services/signal-breakpoints.js +172 -0
  302. package/src/backend/services/signed-approval-record.js +86 -0
  303. package/src/backend/services/signed-approvals.js +244 -0
  304. package/src/backend/services/signoff-pack.js +328 -0
  305. package/src/backend/services/signoff-rows.js +114 -0
  306. package/src/backend/services/skill-arrival-service.js +138 -0
  307. package/src/backend/services/skill-model.js +193 -0
  308. package/src/backend/services/skill-use-service.js +140 -0
  309. package/src/backend/services/skills-service.js +150 -0
  310. package/src/backend/services/snapshot-compare-service.js +397 -0
  311. package/src/backend/services/source-control.js +189 -0
  312. package/src/backend/services/spec-links-service.js +123 -0
  313. package/src/backend/services/spec-proposal-withdraw.js +50 -0
  314. package/src/backend/services/spec-proposals-service.js +470 -0
  315. package/src/backend/services/sql/embedded.js +95 -0
  316. package/src/backend/services/sql/index.js +63 -0
  317. package/src/backend/services/sql/refs.js +357 -0
  318. package/src/backend/services/sql/schema.js +312 -0
  319. package/src/backend/services/sql/tokenizer.js +195 -0
  320. package/src/backend/services/stack-overlaps.js +117 -0
  321. package/src/backend/services/stack-service.js +225 -0
  322. package/src/backend/services/state-sync-service.js +384 -0
  323. package/src/backend/services/stuck-sensor-service.js +200 -0
  324. package/src/backend/services/system-discovery.js +481 -0
  325. package/src/backend/services/system-docs-service.js +701 -0
  326. package/src/backend/services/task-attachments-service.js +340 -0
  327. package/src/backend/services/task-grounding.js +60 -0
  328. package/src/backend/services/task-records/check-run-record.js +146 -0
  329. package/src/backend/services/task-records/check-runs.js +115 -0
  330. package/src/backend/services/task-records/heads.js +88 -0
  331. package/src/backend/services/task-records/material-reads.js +225 -0
  332. package/src/backend/services/task-records/read-record.js +100 -0
  333. package/src/backend/services/task-records/record.js +173 -0
  334. package/src/backend/services/task-records/run-record.js +136 -0
  335. package/src/backend/services/task-records/shared-state.js +548 -0
  336. package/src/backend/services/task-records/signing.js +140 -0
  337. package/src/backend/services/task-records/split-signals.js +52 -0
  338. package/src/backend/services/task-records/test-runs.js +164 -0
  339. package/src/backend/services/task-records/trust.js +243 -0
  340. package/src/backend/services/task-rules.js +81 -0
  341. package/src/backend/services/task-workstreams.js +90 -0
  342. package/src/backend/services/terminal-history-service.js +266 -0
  343. package/src/backend/services/terminal-service.js +267 -0
  344. package/src/backend/services/test-clock.js +53 -0
  345. package/src/backend/services/tests/grounding.js +266 -0
  346. package/src/backend/services/tests/junit.js +104 -0
  347. package/src/backend/services/tests/teammate-runs.js +134 -0
  348. package/src/backend/services/tests/test-results.js +234 -0
  349. package/src/backend/services/tree-watcher.js +204 -0
  350. package/src/backend/services/trellis-service.js +204 -0
  351. package/src/backend/services/trusted-roots.js +186 -0
  352. package/src/backend/services/update-download-service.js +342 -0
  353. package/src/backend/services/update-service.js +266 -0
  354. package/src/backend/services/watch-ignore.js +76 -0
  355. package/src/backend/services/webhook-egress.js +206 -0
  356. package/src/backend/services/webrtc-service.js +413 -0
  357. package/src/backend/services/work-changes.js +59 -0
  358. package/src/backend/services/workstream-binding.js +82 -0
  359. package/src/backend/services/workstream-commits.js +116 -0
  360. package/src/backend/services/workstream-imports.js +177 -0
  361. package/src/backend/services/workstream-service.js +335 -0
  362. package/src/backend/services/workstream-symbols.js +223 -0
  363. package/src/backend/services/workstream-watch-service.js +391 -0
  364. package/src/backend/services/worktree-service.js +235 -0
  365. package/src/cli/agent.js +100 -0
  366. package/src/cli/args.js +201 -0
  367. package/src/cli/conformity.js +106 -0
  368. package/src/cli/desktop.js +91 -0
  369. package/src/cli/main.js +409 -0
  370. package/src/cli/pipeline.js +109 -0
  371. package/src/cli/plan-verbs.js +259 -0
  372. package/src/cli/review-adapters.js +218 -0
  373. package/src/cli/review-output.js +93 -0
  374. package/src/cli/review-post.js +89 -0
  375. package/src/cli/review-sink.js +183 -0
  376. package/src/cli/review-skill.js +44 -0
  377. package/src/cli/review-verify.js +104 -0
  378. package/src/cli/review.js +386 -0
  379. package/src/cli/sarif.js +148 -0
  380. package/src/cli/verbs.js +359 -0
  381. package/src/shared/build-info.js +39 -0
  382. package/src/shared/lib/agent-review.js +199 -0
  383. package/src/shared/lib/agent-turns.js +140 -0
  384. package/src/shared/lib/awareness-digest.js +120 -0
  385. package/src/shared/lib/branch-name.js +45 -0
  386. package/src/shared/lib/breakpoint-words.js +118 -0
  387. package/src/shared/lib/budget-words.js +56 -0
  388. package/src/shared/lib/burst.js +69 -0
  389. package/src/shared/lib/call-entry.js +105 -0
  390. package/src/shared/lib/check-compare.js +42 -0
  391. package/src/shared/lib/check-words.js +216 -0
  392. package/src/shared/lib/csv.js +62 -0
  393. package/src/shared/lib/folder-entry.js +87 -0
  394. package/src/shared/lib/freeze-words.js +60 -0
  395. package/src/shared/lib/fuzzy.js +84 -0
  396. package/src/shared/lib/git-state-words.js +80 -0
  397. package/src/shared/lib/grep-entry.js +86 -0
  398. package/src/shared/lib/grounding-line.js +61 -0
  399. package/src/shared/lib/import-line.js +71 -0
  400. package/src/shared/lib/item-status.js +249 -0
  401. package/src/shared/lib/line-changes.js +53 -0
  402. package/src/shared/lib/locator.js +71 -0
  403. package/src/shared/lib/matcher.js +120 -0
  404. package/src/shared/lib/merge-order.js +65 -0
  405. package/src/shared/lib/open-findings.js +68 -0
  406. package/src/shared/lib/other-work.js +108 -0
  407. package/src/shared/lib/package-entry.js +142 -0
  408. package/src/shared/lib/plan-vocab.js +40 -0
  409. package/src/shared/lib/pptx-xml.js +86 -0
  410. package/src/shared/lib/proposal-words.js +61 -0
  411. package/src/shared/lib/recurrence.js +183 -0
  412. package/src/shared/lib/references.js +72 -0
  413. package/src/shared/lib/rule-pattern.js +56 -0
  414. package/src/shared/lib/sdp-fingerprint.js +115 -0
  415. package/src/shared/lib/sdp-minimal.js +123 -0
  416. package/src/shared/lib/secret-paths.js +34 -0
  417. package/src/shared/lib/signal-words.js +172 -0
  418. package/src/shared/lib/signoff.js +56 -0
  419. package/src/shared/lib/skills-note.js +60 -0
  420. package/src/shared/lib/spec-sections.js +78 -0
  421. package/src/shared/lib/symbol-entry.js +60 -0
  422. package/src/shared/lib/tool-phrasing.js +338 -0
  423. package/src/shared/lib/turn-gap.js +27 -0
  424. package/src/shared/lib/workstream-words.js +38 -0
  425. package/src/shared/lib/xlsx-xml.js +144 -0
  426. package/src/shared/lib/zip-reader.js +99 -0
  427. package/src/shared/types/agent.js +27 -0
  428. package/src/shared/types/architecture-rules.js +30 -0
  429. package/src/shared/types/ast.js +15 -0
  430. package/src/shared/types/breakpoint.js +33 -0
  431. package/src/shared/types/channel.js +41 -0
  432. package/src/shared/types/criteria.js +15 -0
  433. package/src/shared/types/graph.js +15 -0
  434. package/src/shared/types/index.js +53 -0
  435. package/src/shared/types/peer.js +36 -0
  436. package/src/shared/types/pipeline.js +15 -0
  437. package/src/shared/types/plan.js +15 -0
  438. package/src/shared/types/play-forward.js +15 -0
  439. package/src/shared/types/power.js +15 -0
  440. package/src/shared/types/presence.js +15 -0
  441. package/src/shared/types/project-config.js +35 -0
  442. package/src/shared/types/project.js +15 -0
  443. package/src/shared/types/record.js +15 -0
  444. package/src/shared/types/recurring.js +15 -0
  445. package/src/shared/types/review.js +15 -0
  446. package/src/shared/types/settings.js +114 -0
  447. package/src/shared/types/stack.js +15 -0
  448. package/src/shared/types/system-doc.js +15 -0
  449. package/src/shared/types/system.js +15 -0
@@ -0,0 +1,88 @@
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 heads_exports = {};
19
+ __export(heads_exports, {
20
+ allHeadChecks: () => allHeadChecks,
21
+ allSplits: () => allSplits,
22
+ headOf: () => headOf,
23
+ headsBy: () => headsBy,
24
+ setHead: () => setHead,
25
+ setHeadCheck: () => setHeadCheck,
26
+ splitOf: () => splitOf
27
+ });
28
+ module.exports = __toCommonJS(heads_exports);
29
+ var import_database = require("../database");
30
+ var import_persistence = require("../persistence");
31
+ function headOf(itemUid) {
32
+ const v = (0, import_database.getDb)().exec("SELECT writer, counter, split FROM task_record_heads WHERE item_uid = ?", [itemUid])[0]?.values[0];
33
+ return v ? { writer: String(v[0]), counter: Number(v[1]), split: v[2] ?? null } : null;
34
+ }
35
+ function setHead(itemUid, writer, counter, split, check = null) {
36
+ (0, import_database.getDb)().run(
37
+ `INSERT INTO task_record_heads (item_uid, writer, counter, split, verdict) VALUES (?, ?, ?, ?, ?)
38
+ ON CONFLICT(item_uid) DO UPDATE SET writer = excluded.writer, counter = excluded.counter, split = excluded.split, verdict = excluded.verdict`,
39
+ [itemUid, writer, counter, split, check ? JSON.stringify(check) : null]
40
+ );
41
+ (0, import_persistence.markDirty)();
42
+ }
43
+ function setHeadCheck(itemUid, check) {
44
+ (0, import_database.getDb)().run("UPDATE task_record_heads SET verdict = ? WHERE item_uid = ?", [JSON.stringify(check), itemUid]);
45
+ (0, import_persistence.markDirty)();
46
+ }
47
+ function allHeadChecks() {
48
+ const out = /* @__PURE__ */ new Map();
49
+ for (const r of (0, import_database.getDb)().exec("SELECT item_uid, verdict FROM task_record_heads WHERE verdict IS NOT NULL")[0]?.values ?? []) {
50
+ try {
51
+ out.set(String(r[0]), JSON.parse(String(r[1])));
52
+ } catch {
53
+ }
54
+ }
55
+ return out;
56
+ }
57
+ function headsBy(writer) {
58
+ return ((0, import_database.getDb)().exec("SELECT item_uid, counter FROM task_record_heads WHERE writer = ? AND split IS NULL AND verdict IS NOT NULL", [writer])[0]?.values ?? []).map((r) => ({ itemUid: String(r[0]), counter: Number(r[1]) }));
59
+ }
60
+ function splitOf(itemUid) {
61
+ const s = headOf(itemUid)?.split;
62
+ if (!s) return null;
63
+ try {
64
+ return JSON.parse(s);
65
+ } catch {
66
+ return null;
67
+ }
68
+ }
69
+ function allSplits() {
70
+ const out = /* @__PURE__ */ new Map();
71
+ for (const r of (0, import_database.getDb)().exec("SELECT item_uid, split FROM task_record_heads WHERE split IS NOT NULL")[0]?.values ?? []) {
72
+ try {
73
+ out.set(String(r[0]), JSON.parse(String(r[1])));
74
+ } catch {
75
+ }
76
+ }
77
+ return out;
78
+ }
79
+ // Annotate the CommonJS export names for ESM import in node:
80
+ 0 && (module.exports = {
81
+ allHeadChecks,
82
+ allSplits,
83
+ headOf,
84
+ headsBy,
85
+ setHead,
86
+ setHeadCheck,
87
+ splitOf
88
+ });
@@ -0,0 +1,225 @@
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 material_reads_exports = {};
29
+ __export(material_reads_exports, {
30
+ READS_DIR: () => READS_DIR,
31
+ forgetReadsBy: () => forgetReadsBy,
32
+ forgetTeammateReads: () => forgetTeammateReads,
33
+ materialReadsChoice: () => materialReadsChoice,
34
+ readCounts: () => readCounts,
35
+ readTeammateReads: () => readTeammateReads,
36
+ readerWords: () => readerWords,
37
+ setMaterialReadsChoice: () => setMaterialReadsChoice,
38
+ writeReadRecord: () => writeReadRecord
39
+ });
40
+ module.exports = __toCommonJS(material_reads_exports);
41
+ var import_node_fs = __toESM(require("node:fs"));
42
+ var import_node_path = __toESM(require("node:path"));
43
+ var import_database = require("../database");
44
+ var import_persistence = require("../persistence");
45
+ var import_confined_fs = require("../confined-fs");
46
+ var import_cloud_files = require("../cloud-files");
47
+ var import_plan_service = require("../plan-service");
48
+ var import_plan_item_service = require("../plan-item-service");
49
+ var import_record = require("./record");
50
+ var import_read_record = require("./read-record");
51
+ var import_trust = require("./trust");
52
+ const READS_DIR = import_node_path.default.join(".codetrellis", "reads");
53
+ const MAX_FILES_PER_ITEM = 5e3;
54
+ const FILE = /^([a-f0-9]{8,32})-(\d{1,9})\.yaml$/;
55
+ function materialReadsChoice(projectRoot, sharingTaskState) {
56
+ const v = (0, import_database.getDb)().exec("SELECT enabled, changed_at, changed_by FROM shared_material_reads WHERE project_root = ?", [projectRoot])[0]?.values[0];
57
+ const chosenOn = v ? Number(v[0]) === 1 : true;
58
+ return {
59
+ enabled: sharingTaskState && chosenOn,
60
+ chosen: !!v,
61
+ changedAt: v ? Number(v[1]) : null,
62
+ changedBy: v ? String(v[2]) : null
63
+ };
64
+ }
65
+ function setMaterialReadsChoice(projectRoot, enabled, by) {
66
+ (0, import_database.getDb)().run(
67
+ `INSERT INTO shared_material_reads (project_root, enabled, changed_at, changed_by) VALUES (?, ?, ?, ?)
68
+ ON CONFLICT(project_root) DO UPDATE SET enabled = excluded.enabled, changed_at = excluded.changed_at, changed_by = excluded.changed_by`,
69
+ [projectRoot, enabled ? 1 : 0, Date.now(), by]
70
+ );
71
+ (0, import_persistence.markDirty)();
72
+ }
73
+ function forgetTeammateReads(projectRoot) {
74
+ const trimmed = projectRoot.replace(/[\\/]+$/, "");
75
+ const before = (0, import_database.getDb)().exec("SELECT COUNT(*) FROM teammate_material_reads")[0]?.values[0]?.[0];
76
+ (0, import_database.getDb)().run(
77
+ "DELETE FROM teammate_material_reads WHERE plan_uid IN (SELECT uid FROM plans WHERE project_path = ? OR project_path = ?)",
78
+ [projectRoot, trimmed]
79
+ );
80
+ const after = (0, import_database.getDb)().exec("SELECT COUNT(*) FROM teammate_material_reads")[0]?.values[0]?.[0];
81
+ const gone = Number(before ?? 0) - Number(after ?? 0);
82
+ if (gone) (0, import_persistence.markDirty)();
83
+ return gone;
84
+ }
85
+ function forgetReadsBy(writer) {
86
+ (0, import_database.getDb)().run("DELETE FROM teammate_material_reads WHERE writer = ?", [writer]);
87
+ (0, import_persistence.markDirty)();
88
+ }
89
+ function filesIn(dir) {
90
+ try {
91
+ return import_node_fs.default.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && FILE.test(e.name)).map((e) => e.name).slice(0, MAX_FILES_PER_ITEM);
92
+ } catch {
93
+ return [];
94
+ }
95
+ }
96
+ function readFile(home, dir, name, where) {
97
+ const file = import_node_path.default.join(dir, name);
98
+ if ((0, import_cloud_files.isPlaceholder)(file)) return null;
99
+ let text;
100
+ try {
101
+ text = (0, import_confined_fs.readTextWithin)(home, file, "material-read record");
102
+ } catch {
103
+ return null;
104
+ }
105
+ const parsed = (0, import_read_record.parseReadRecord)(text, where);
106
+ if (!("record" in parsed)) return null;
107
+ const m = FILE.exec(name);
108
+ if (parsed.record.writer !== m[1] || parsed.record.counter !== Number(m[2])) return null;
109
+ return parsed;
110
+ }
111
+ function writeReadRecord(where, read, now = Date.now()) {
112
+ if (!(0, import_record.isRecordId)(read.plan) || !(0, import_record.isRecordId)(read.item)) return null;
113
+ const dir = import_node_path.default.join(where.home, READS_DIR, read.plan, read.item);
114
+ const mine = filesIn(dir).map((name) => ({ name, counter: Number(FILE.exec(name)[2]), writer: FILE.exec(name)[1] })).filter((f) => f.writer === where.me).sort((a, b) => b.counter - a.counter);
115
+ for (const f of mine) {
116
+ const r = readFile(where.home, dir, f.name, read)?.record;
117
+ if (r?.material !== read.material) continue;
118
+ if (r.sha256 === read.sha256) return null;
119
+ break;
120
+ }
121
+ let counter = (mine[0]?.counter ?? 0) + 1;
122
+ while (import_node_fs.default.existsSync(import_node_path.default.join(dir, `${where.me}-${counter}.yaml`))) counter++;
123
+ const record = {
124
+ writer: where.me,
125
+ name: where.name,
126
+ counter,
127
+ at: now,
128
+ plan: read.plan,
129
+ item: read.item,
130
+ by: read.by,
131
+ material: read.material,
132
+ attachment: read.attachment,
133
+ sha256: read.sha256
134
+ };
135
+ const signature = (0, import_trust.signRecord)(where.projectRoot, where.home, record, (0, import_read_record.readRecordBytes)(record));
136
+ return (0, import_confined_fs.writeFileWithin)(where.home, import_node_path.default.join(dir, `${where.me}-${counter}.yaml`), (0, import_read_record.serializeReadRecord)(record, signature), "material-read record");
137
+ }
138
+ function readerWords(r, verifiedAs) {
139
+ const who = verifiedAs ?? r.name;
140
+ const person = r.by.authorType === "human" || r.by.authorType === "unverified" || r.by.author === r.name;
141
+ return person ? who : `${r.by.author} for ${who}`;
142
+ }
143
+ function readTeammateReads(projectRoot, home, me, onlyPlan) {
144
+ const root = import_node_path.default.join(home, READS_DIR);
145
+ const dirs = (d) => {
146
+ try {
147
+ return import_node_fs.default.readdirSync(d, { withFileTypes: true }).filter((e) => e.isDirectory() && (0, import_record.isRecordId)(e.name)).map((e) => e.name);
148
+ } catch {
149
+ return [];
150
+ }
151
+ };
152
+ const known = (writer, item, counter) => !!(0, import_database.getDb)().exec("SELECT 1 FROM teammate_material_reads WHERE writer = ? AND item_uid = ? AND counter = ?", [writer, item, counter])[0]?.values[0];
153
+ let ctx = null;
154
+ let added = 0;
155
+ for (const plan of dirs(root)) {
156
+ if (onlyPlan && plan !== onlyPlan) continue;
157
+ if ((0, import_plan_service.getPlan)(plan)?.projectPath !== projectRoot) continue;
158
+ for (const item of dirs(import_node_path.default.join(root, plan))) {
159
+ const it = (0, import_plan_item_service.getItem)(item);
160
+ if (!it || it.planUid !== plan) continue;
161
+ const dir = import_node_path.default.join(root, plan, item);
162
+ for (const name of filesIn(dir)) {
163
+ const m = FILE.exec(name);
164
+ if (m[1] === me || known(m[1], item, Number(m[2]))) continue;
165
+ const parsed = readFile(home, dir, name, { plan, item });
166
+ if (!parsed) continue;
167
+ const r = parsed.record;
168
+ ctx ??= (0, import_trust.checkContext)(projectRoot);
169
+ const v = (0, import_trust.verifyTaskRecord)(r, parsed.signed, ctx);
170
+ (0, import_database.getDb)().run(
171
+ `INSERT OR IGNORE INTO teammate_material_reads (writer, item_uid, counter, plan_uid, name, reader, attachment_uid, path, sha256, at, verdict)
172
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
173
+ [
174
+ r.writer,
175
+ item,
176
+ r.counter,
177
+ plan,
178
+ v.verified ? v.who : r.name,
179
+ readerWords(r, v.verified ? v.who : null),
180
+ r.attachment,
181
+ r.material,
182
+ r.sha256,
183
+ r.at,
184
+ JSON.stringify(v.verified ? { verified: true, how: v.how, who: v.who } : { verified: false, why: v.why })
185
+ ]
186
+ );
187
+ added++;
188
+ }
189
+ }
190
+ }
191
+ if (added) (0, import_persistence.markDirty)();
192
+ return added;
193
+ }
194
+ function readCounts(projectRoot, home, me) {
195
+ let mine = 0;
196
+ if (home) {
197
+ const root = import_node_path.default.join(home, READS_DIR);
198
+ const dirs = (d) => {
199
+ try {
200
+ return import_node_fs.default.readdirSync(d, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
201
+ } catch {
202
+ return [];
203
+ }
204
+ };
205
+ for (const plan of dirs(root)) for (const item of dirs(import_node_path.default.join(root, plan))) mine += filesIn(import_node_path.default.join(root, plan, item)).filter((n) => n.startsWith(`${me}-`)).length;
206
+ }
207
+ const trimmed = projectRoot.replace(/[\\/]+$/, "");
208
+ const rows = (0, import_database.getDb)().exec(
209
+ `SELECT name FROM teammate_material_reads WHERE plan_uid IN (SELECT uid FROM plans WHERE project_path = ? OR project_path = ?)`,
210
+ [projectRoot, trimmed]
211
+ )[0]?.values ?? [];
212
+ return { mine, teammates: rows.length, people: [...new Set(rows.map((r) => String(r[0])))].sort() };
213
+ }
214
+ // Annotate the CommonJS export names for ESM import in node:
215
+ 0 && (module.exports = {
216
+ READS_DIR,
217
+ forgetReadsBy,
218
+ forgetTeammateReads,
219
+ materialReadsChoice,
220
+ readCounts,
221
+ readTeammateReads,
222
+ readerWords,
223
+ setMaterialReadsChoice,
224
+ writeReadRecord
225
+ });
@@ -0,0 +1,100 @@
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 read_record_exports = {};
19
+ __export(read_record_exports, {
20
+ MAX_READ_RECORD_BYTES: () => MAX_READ_RECORD_BYTES,
21
+ parseReadRecord: () => parseReadRecord,
22
+ readRecordBytes: () => readRecordBytes,
23
+ serializeReadRecord: () => serializeReadRecord
24
+ });
25
+ module.exports = __toCommonJS(read_record_exports);
26
+ var import_yaml = require("yaml");
27
+ var import_signing = require("./signing");
28
+ var import_material_place = require("../material-place");
29
+ const KIND = "material-read";
30
+ const MAX_READ_RECORD_BYTES = 8 * 1024;
31
+ const WRITER = /^[a-f0-9]{8,32}$/;
32
+ const ID = /^[a-z0-9][a-z0-9-]{0,63}$/i;
33
+ const SHA = /^[a-f0-9]{64}$/;
34
+ const text = (v, max) => typeof v === "string" && v.length > 0 ? v.slice(0, max) : null;
35
+ function bodyOf(r) {
36
+ return {
37
+ kind: KIND,
38
+ writer: r.writer,
39
+ name: r.name,
40
+ counter: r.counter,
41
+ at: new Date(r.at).toISOString(),
42
+ plan: r.plan,
43
+ item: r.item,
44
+ by: r.by,
45
+ material: r.material,
46
+ attachment: r.attachment,
47
+ sha256: r.sha256
48
+ };
49
+ }
50
+ function readRecordBytes(r) {
51
+ return (0, import_signing.canonicalJson)(bodyOf(r));
52
+ }
53
+ function serializeReadRecord(r, signature) {
54
+ const body = signature ? { ...bodyOf(r), signature } : bodyOf(r);
55
+ return `# CodeTrellis: which version of a material a task read, written once by one device.
56
+ ${(0, import_yaml.stringify)(body, { lineWidth: 0 })}`;
57
+ }
58
+ function parseReadRecord(source, where) {
59
+ if (Buffer.byteLength(source, "utf8") > MAX_READ_RECORD_BYTES) return { error: "larger than a read record can be" };
60
+ let raw;
61
+ try {
62
+ raw = (0, import_yaml.parse)(source, { maxAliasCount: 0 });
63
+ } catch {
64
+ return { error: "not YAML" };
65
+ }
66
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return { error: "not a record" };
67
+ const { signature: rawSignature, ...r } = raw;
68
+ if (r.kind !== KIND) return { error: "not a material-read record" };
69
+ const writer = typeof r.writer === "string" && WRITER.test(r.writer) ? r.writer : null;
70
+ if (!writer) return { error: "no writer" };
71
+ const counter = Number.isSafeInteger(r.counter) && r.counter > 0 ? r.counter : null;
72
+ if (!counter) return { error: "no counter" };
73
+ if (r.plan !== where.plan || r.item !== where.item) return { error: "names another task than its folder" };
74
+ const material = typeof r.material === "string" && r.material.length <= 1024 && (0, import_material_place.isStoredPlace)(r.material) ? r.material : null;
75
+ if (!material) return { error: "names no material in the project or its plans folder" };
76
+ const at = typeof r.at === "string" ? Date.parse(r.at) : NaN;
77
+ const by = r.by && typeof r.by === "object" ? r.by : {};
78
+ return {
79
+ signed: { bytes: (0, import_signing.canonicalJson)(r), signature: (0, import_signing.parseSignature)(rawSignature) },
80
+ record: {
81
+ writer,
82
+ name: text(r.name, 120) ?? "someone",
83
+ counter,
84
+ at: Number.isFinite(at) ? at : 0,
85
+ plan: where.plan,
86
+ item: where.item,
87
+ by: { author: text(by.author, 120) ?? "someone", authorType: text(by.authorType, 40) ?? "unknown" },
88
+ material,
89
+ attachment: typeof r.attachment === "string" && ID.test(r.attachment) ? r.attachment : null,
90
+ sha256: typeof r.sha256 === "string" && SHA.test(r.sha256) ? r.sha256 : null
91
+ }
92
+ };
93
+ }
94
+ // Annotate the CommonJS export names for ESM import in node:
95
+ 0 && (module.exports = {
96
+ MAX_READ_RECORD_BYTES,
97
+ parseReadRecord,
98
+ readRecordBytes,
99
+ serializeReadRecord
100
+ });
@@ -0,0 +1,173 @@
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 record_exports = {};
19
+ __export(record_exports, {
20
+ MAX_RECORD_BYTES: () => MAX_RECORD_BYTES,
21
+ distinctRecords: () => distinctRecords,
22
+ heads: () => heads,
23
+ isRecordId: () => isRecordId,
24
+ parseRecord: () => parseRecord,
25
+ readItem: () => readItem,
26
+ recordBytes: () => recordBytes,
27
+ recordFileName: () => recordFileName,
28
+ sameState: () => sameState,
29
+ seenOf: () => seenOf,
30
+ serializeRecord: () => serializeRecord,
31
+ supersedes: () => supersedes
32
+ });
33
+ module.exports = __toCommonJS(record_exports);
34
+ var import_yaml = require("yaml");
35
+ var import_signing = require("./signing");
36
+ const MAX_RECORD_BYTES = 16 * 1024;
37
+ const MAX_SEEN = 256;
38
+ const STATUSES = /* @__PURE__ */ new Set(["pending", "assigned", "in_progress", "blocked", "done", "skipped"]);
39
+ const ID = /^[a-z0-9][a-z0-9-]{0,63}$/i;
40
+ const WRITER = /^[a-f0-9]{8,32}$/;
41
+ const text = (v, max) => typeof v === "string" && v.length > 0 ? v.slice(0, max) : null;
42
+ function recordFileName(writer, counter) {
43
+ return `${writer}-${counter}.yaml`;
44
+ }
45
+ function bodyOf(r) {
46
+ return {
47
+ writer: r.writer,
48
+ name: r.name,
49
+ counter: r.counter,
50
+ seen: r.seen,
51
+ at: new Date(r.at).toISOString(),
52
+ plan: r.plan,
53
+ item: r.item,
54
+ by: r.by,
55
+ state: r.state
56
+ };
57
+ }
58
+ function recordBytes(r) {
59
+ return (0, import_signing.canonicalJson)(bodyOf(r));
60
+ }
61
+ function serializeRecord(r, signature) {
62
+ const body = signature ? { ...bodyOf(r), signature } : bodyOf(r);
63
+ return `# CodeTrellis task state, written once by one device and never edited.
64
+ # The state everyone sees is read from all of these; delete none.
65
+ ${(0, import_yaml.stringify)(body, { lineWidth: 0 })}`;
66
+ }
67
+ function parseRecord(source, where) {
68
+ if (Buffer.byteLength(source, "utf8") > MAX_RECORD_BYTES) return { error: "larger than a record can be" };
69
+ let raw;
70
+ try {
71
+ raw = (0, import_yaml.parse)(source, { maxAliasCount: 0 });
72
+ } catch {
73
+ return { error: "not YAML" };
74
+ }
75
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return { error: "not a record" };
76
+ const { signature: rawSignature, ...r } = raw;
77
+ const writer = typeof r.writer === "string" && WRITER.test(r.writer) ? r.writer : null;
78
+ if (!writer) return { error: "no writer" };
79
+ const counter = Number.isSafeInteger(r.counter) && r.counter > 0 ? r.counter : null;
80
+ if (!counter) return { error: "no counter" };
81
+ if (r.plan !== where.plan || r.item !== where.item) return { error: "names another task than its folder" };
82
+ const seen = {};
83
+ if (r.seen && typeof r.seen === "object" && !Array.isArray(r.seen)) {
84
+ const entries = Object.entries(r.seen);
85
+ if (entries.length > MAX_SEEN) return { error: "names too many writers" };
86
+ for (const [w, c] of entries) {
87
+ if (WRITER.test(w) && w !== writer && Number.isSafeInteger(c) && c > 0) seen[w] = c;
88
+ }
89
+ }
90
+ const at = typeof r.at === "string" ? Date.parse(r.at) : NaN;
91
+ const by = r.by && typeof r.by === "object" ? r.by : {};
92
+ const s = r.state && typeof r.state === "object" && !Array.isArray(r.state) ? r.state : null;
93
+ if (!s) return { error: "no state" };
94
+ const status = typeof s.status === "string" && STATUSES.has(s.status) ? s.status : null;
95
+ const pct = typeof s.progressPercent === "number" && Number.isFinite(s.progressPercent) ? Math.max(0, Math.min(100, Math.round(s.progressPercent))) : null;
96
+ return {
97
+ // Everything but the signature, exactly as the file has it: a field
98
+ // added or changed after signing makes these bytes differ.
99
+ signed: { bytes: (0, import_signing.canonicalJson)(r), signature: (0, import_signing.parseSignature)(rawSignature) },
100
+ record: {
101
+ writer,
102
+ name: text(r.name, 120) ?? "someone",
103
+ counter,
104
+ seen,
105
+ at: Number.isFinite(at) ? at : 0,
106
+ plan: where.plan,
107
+ item: where.item,
108
+ by: { author: text(by.author, 120) ?? "someone", authorType: text(by.authorType, 40) ?? "unknown" },
109
+ state: {
110
+ status,
111
+ assignee: text(s.assignee, 200),
112
+ assigneeType: text(s.assigneeType, 40),
113
+ progressPercent: pct,
114
+ blockedReason: text(s.blockedReason, 500)
115
+ }
116
+ }
117
+ };
118
+ }
119
+ function isRecordId(id) {
120
+ return ID.test(id);
121
+ }
122
+ function supersedes(a, b) {
123
+ if (a.writer === b.writer) return a.counter > b.counter;
124
+ return (a.seen[b.writer] ?? 0) >= b.counter;
125
+ }
126
+ function distinctRecords(records) {
127
+ const byKey = /* @__PURE__ */ new Map();
128
+ const clashing = [];
129
+ for (const r of records) {
130
+ const key = `${r.writer}-${r.counter}`;
131
+ const known = byKey.get(key);
132
+ if (!known) {
133
+ byKey.set(key, r);
134
+ continue;
135
+ }
136
+ if (JSON.stringify(known) !== JSON.stringify(r)) clashing.push(r);
137
+ }
138
+ return { records: [...byKey.values()], clashing };
139
+ }
140
+ function heads(records) {
141
+ return records.filter((r) => !records.some((o) => o !== r && supersedes(o, r)));
142
+ }
143
+ function seenOf(records) {
144
+ const out = {};
145
+ for (const r of records) out[r.writer] = Math.max(out[r.writer] ?? 0, r.counter);
146
+ return out;
147
+ }
148
+ function sameState(a, b) {
149
+ return a.status === b.status && a.assignee === b.assignee && a.progressPercent === b.progressPercent && a.blockedReason === b.blockedReason;
150
+ }
151
+ function readItem(records) {
152
+ const { records: distinct } = distinctRecords(records);
153
+ const top = heads(distinct);
154
+ if (top.length === 0) return { kind: "none" };
155
+ const newest = [...top].sort((a, b) => b.at - a.at || (a.writer < b.writer ? -1 : 1));
156
+ if (newest.every((h) => sameState(h.state, newest[0].state))) return { kind: "settled", head: newest[0] };
157
+ return { kind: "split", heads: newest };
158
+ }
159
+ // Annotate the CommonJS export names for ESM import in node:
160
+ 0 && (module.exports = {
161
+ MAX_RECORD_BYTES,
162
+ distinctRecords,
163
+ heads,
164
+ isRecordId,
165
+ parseRecord,
166
+ readItem,
167
+ recordBytes,
168
+ recordFileName,
169
+ sameState,
170
+ seenOf,
171
+ serializeRecord,
172
+ supersedes
173
+ });