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,186 @@
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 trusted_roots_exports = {};
29
+ __export(trusted_roots_exports, {
30
+ evictedHint: () => evictedHint,
31
+ getActiveProjectRoot: () => getActiveProjectRoot,
32
+ isTrustedPlanDir: () => isTrustedPlanDir,
33
+ isTrustedProjectRoot: () => isTrustedProjectRoot,
34
+ listTrustedRoots: () => listTrustedRoots,
35
+ projectRelative: () => projectRelative,
36
+ resolveTrustedPlanDir: () => resolveTrustedPlanDir,
37
+ resolveTrustedProjectRoot: () => resolveTrustedProjectRoot,
38
+ setActiveProjectRoot: () => setActiveProjectRoot
39
+ });
40
+ module.exports = __toCommonJS(trusted_roots_exports);
41
+ var fs = __toESM(require("node:fs"));
42
+ var path = __toESM(require("node:path"));
43
+ var import_confined_fs = require("./confined-fs");
44
+ var import_recent_projects_service = require("./recent-projects-service");
45
+ var import_plans_home = require("./plans-home");
46
+ function canonicaliseForCompare(p) {
47
+ try {
48
+ return fs.realpathSync.native(path.resolve(p));
49
+ } catch {
50
+ return null;
51
+ }
52
+ }
53
+ let activeProjectRoot = null;
54
+ function setActiveProjectRoot(projectPath) {
55
+ activeProjectRoot = projectPath;
56
+ }
57
+ function getActiveProjectRoot() {
58
+ return activeProjectRoot;
59
+ }
60
+ function listTrustedRoots() {
61
+ const roots = /* @__PURE__ */ new Set();
62
+ if (activeProjectRoot) roots.add(activeProjectRoot);
63
+ try {
64
+ for (const p of (0, import_recent_projects_service.listRecentProjects)()) {
65
+ if (p?.path) roots.add(p.path);
66
+ }
67
+ } catch (err) {
68
+ console.warn("[TrustedRoots] Recent projects unavailable, using the active project only:", err);
69
+ }
70
+ return [...roots];
71
+ }
72
+ function resolveTrustedProjectRoot(candidate, label = "projectRoot", opts = {}) {
73
+ if (typeof candidate !== "string" || candidate.trim().length === 0) {
74
+ throw new import_confined_fs.ConfinementError(`${label}: a project path is required`);
75
+ }
76
+ const canonCandidate = canonicaliseForCompare(candidate);
77
+ if (!canonCandidate) {
78
+ if (opts.allowAbsent) {
79
+ const lexical = path.resolve(candidate);
80
+ const known = listTrustedRoots().some((r) => path.resolve(r) === lexical);
81
+ if (known) return lexical;
82
+ }
83
+ throw new import_confined_fs.ConfinementError(
84
+ `${label}: "${candidate}" does not exist or cannot be resolved`
85
+ );
86
+ }
87
+ for (const root of listTrustedRoots()) {
88
+ const canonRoot = canonicaliseForCompare(root);
89
+ if (canonRoot && canonRoot === canonCandidate) return path.resolve(root);
90
+ }
91
+ const evicted = evictedHint(candidate);
92
+ throw new import_confined_fs.ConfinementError(
93
+ `${label}: "${candidate}" is not an opened project. ` + (evicted ? evicted : "Project roots are derived from the projects this app has opened, not from the request.")
94
+ );
95
+ }
96
+ function evictedHint(candidate) {
97
+ if (typeof candidate !== "string" || candidate.trim().length === 0) return null;
98
+ let evicted;
99
+ try {
100
+ evicted = (0, import_recent_projects_service.listEvictedProjects)();
101
+ } catch {
102
+ return null;
103
+ }
104
+ const lexical = path.resolve(candidate);
105
+ const canon = canonicaliseForCompare(candidate);
106
+ const hit = evicted.find(
107
+ (e) => path.resolve(e.path) === lexical || canon !== null && canonicaliseForCompare(e.path) === canon
108
+ );
109
+ if (!hit) return null;
110
+ return `It was opened before, but dropped off Recent Projects on ${new Date(hit.evictedAt).toISOString().slice(0, 10)} when newer projects pushed it past the ${import_recent_projects_service.MAX_RECENT_UNPINNED} unpinned ones kept, and only projects on that list are trusted. Open it again to restore access, and pin it in Recent Projects to stop it dropping off.`;
111
+ }
112
+ function resolveTrustedPlanDir(candidate, label = "planDir") {
113
+ if (typeof candidate !== "string" || candidate.trim().length === 0) {
114
+ throw new import_confined_fs.ConfinementError(`${label}: a plan directory is required`);
115
+ }
116
+ const dir = /[\\/]plan\.ya?ml$/.test(candidate) ? path.dirname(candidate) : candidate;
117
+ let canon;
118
+ try {
119
+ canon = fs.realpathSync.native(path.resolve(dir));
120
+ } catch {
121
+ throw new import_confined_fs.ConfinementError(`${label}: "${candidate}" does not exist or cannot be resolved`);
122
+ }
123
+ for (const root of listTrustedRoots()) {
124
+ const canonRoot = canonicaliseForCompare(root);
125
+ if (canonRoot && path.dirname(canon) === path.join(canonRoot, ".codetrellis", "plans")) return canon;
126
+ }
127
+ const trusted = new Set(listTrustedRoots().map(canonicaliseForCompare).filter(Boolean));
128
+ for (const { project, home } of (0, import_plans_home.linkedPlansHomes)()) {
129
+ const canonHome = canonicaliseForCompare(home);
130
+ if (canonHome && trusted.has(canonicaliseForCompare(project)) && path.dirname(canon) === path.join(canonHome, ".codetrellis", "plans")) return canon;
131
+ }
132
+ throw new import_confined_fs.ConfinementError(
133
+ `${label}: "${candidate}" is not a plan directory (.codetrellis/plans/<slug>) of a project this app has opened.`
134
+ );
135
+ }
136
+ function isTrustedPlanDir(candidate) {
137
+ try {
138
+ resolveTrustedPlanDir(candidate);
139
+ return true;
140
+ } catch {
141
+ return false;
142
+ }
143
+ }
144
+ function isTrustedProjectRoot(candidate) {
145
+ try {
146
+ resolveTrustedProjectRoot(candidate);
147
+ return true;
148
+ } catch {
149
+ return false;
150
+ }
151
+ }
152
+ function projectRelative(projectRoot, absPath) {
153
+ if (!path.isAbsolute(absPath)) return absPath;
154
+ const canonical = (() => {
155
+ try {
156
+ return (0, import_confined_fs.canonicalRoot)(projectRoot);
157
+ } catch {
158
+ return path.resolve(projectRoot);
159
+ }
160
+ })();
161
+ const aliases = [projectRoot, canonical];
162
+ for (const root of listTrustedRoots()) {
163
+ try {
164
+ if ((0, import_confined_fs.canonicalRoot)(root) === canonical) aliases.push(root);
165
+ } catch {
166
+ }
167
+ }
168
+ for (const root of aliases) {
169
+ if (absPath === root) return "";
170
+ const prefix = root.endsWith(path.sep) ? root : root + path.sep;
171
+ if (absPath.startsWith(prefix)) return path.relative(root, absPath);
172
+ }
173
+ return path.relative(projectRoot, absPath);
174
+ }
175
+ // Annotate the CommonJS export names for ESM import in node:
176
+ 0 && (module.exports = {
177
+ evictedHint,
178
+ getActiveProjectRoot,
179
+ isTrustedPlanDir,
180
+ isTrustedProjectRoot,
181
+ listTrustedRoots,
182
+ projectRelative,
183
+ resolveTrustedPlanDir,
184
+ resolveTrustedProjectRoot,
185
+ setActiveProjectRoot
186
+ });
@@ -0,0 +1,342 @@
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 update_download_service_exports = {};
29
+ __export(update_download_service_exports, {
30
+ _internals: () => _internals,
31
+ _resetUpdateDownloadState: () => _resetUpdateDownloadState,
32
+ _setVerifiedForTest: () => _setVerifiedForTest,
33
+ cancelUpdateDownload: () => cancelUpdateDownload,
34
+ getUpdateDownloadState: () => getUpdateDownloadState,
35
+ saveVerifiedUpdateCopy: () => saveVerifiedUpdateCopy,
36
+ startUpdateDownload: () => startUpdateDownload
37
+ });
38
+ module.exports = __toCommonJS(update_download_service_exports);
39
+ var import_node_https = __toESM(require("node:https"));
40
+ var import_node_fs = __toESM(require("node:fs"));
41
+ var import_node_path = __toESM(require("node:path"));
42
+ var import_node_crypto = require("node:crypto");
43
+ var import_persistence = require("./persistence");
44
+ var import_release_signature = require("./release-signature");
45
+ const ALLOWED_HOSTS = /* @__PURE__ */ new Set([
46
+ "github.com",
47
+ "objects.githubusercontent.com",
48
+ "release-assets.githubusercontent.com"
49
+ ]);
50
+ const MAX_REDIRECTS = 3;
51
+ const MAX_BYTES = 600 * 1024 * 1024;
52
+ const REQUEST_TIMEOUT_MS = 3e4;
53
+ const IDLE = {
54
+ phase: "idle",
55
+ version: null,
56
+ filename: null,
57
+ bytesDownloaded: 0,
58
+ totalBytes: null,
59
+ filePath: null,
60
+ error: null,
61
+ sha256: null,
62
+ savedPath: null
63
+ };
64
+ let state = { ...IDLE };
65
+ function assertArtifactMatchesOffer(url, filename, version) {
66
+ const haystack = `${url.pathname} ${filename}`;
67
+ if (!haystack.includes(version)) {
68
+ throw new Error(
69
+ `Refusing the download: the offer is for ${version} but the artifact it names (${filename}) does not carry that version. This is what a downgrade or a swapped release looks like.`
70
+ );
71
+ }
72
+ }
73
+ let inFlight = null;
74
+ let cancelled = false;
75
+ function getUpdateDownloadState() {
76
+ return state;
77
+ }
78
+ function downloadDir() {
79
+ return import_node_path.default.join((0, import_persistence.getSettingsDir)(), "updates");
80
+ }
81
+ function safeFilename(name) {
82
+ const base = import_node_path.default.basename(String(name ?? "")).replace(/[^A-Za-z0-9._-]/g, "");
83
+ if (!base || base === "." || base === "..") return "codetrellis-update";
84
+ return base.slice(0, 128);
85
+ }
86
+ function assertAllowedUrl(raw) {
87
+ let url;
88
+ try {
89
+ url = new URL(raw);
90
+ } catch {
91
+ throw new Error("Update download URL is not a URL");
92
+ }
93
+ if (url.protocol !== "https:") {
94
+ throw new Error(`Update download must be https (got "${url.protocol}")`);
95
+ }
96
+ if (!ALLOWED_HOSTS.has(url.hostname.toLowerCase())) {
97
+ throw new Error(`Update download host "${url.hostname}" is not a release host`);
98
+ }
99
+ return url;
100
+ }
101
+ function digestsEqual(a, b) {
102
+ const x = Buffer.from(String(a ?? "").toLowerCase(), "utf-8");
103
+ const y = Buffer.from(String(b ?? "").toLowerCase(), "utf-8");
104
+ if (x.length !== y.length || x.length === 0) return false;
105
+ return (0, import_node_crypto.timingSafeEqual)(x, y);
106
+ }
107
+ function fetchToFile(url, dest, expectedBytes, hops = 0) {
108
+ return new Promise((resolve, reject) => {
109
+ if (hops > MAX_REDIRECTS) return reject(new Error("Too many redirects"));
110
+ const req = import_node_https.default.get(
111
+ url,
112
+ { timeout: REQUEST_TIMEOUT_MS, headers: { "user-agent": "CodeTrellis" } },
113
+ (res) => {
114
+ const status = res.statusCode ?? 0;
115
+ if (status >= 300 && status < 400 && res.headers.location) {
116
+ res.resume();
117
+ let next;
118
+ try {
119
+ next = assertAllowedUrl(new URL(res.headers.location, url).toString());
120
+ } catch (err) {
121
+ return reject(err);
122
+ }
123
+ return fetchToFile(next, dest, expectedBytes, hops + 1).then(resolve, reject);
124
+ }
125
+ if (status !== 200) {
126
+ res.resume();
127
+ return reject(new Error(`Update download failed: HTTP ${status}`));
128
+ }
129
+ const declared = Number(res.headers["content-length"] ?? 0);
130
+ if (declared && declared > MAX_BYTES) {
131
+ res.destroy();
132
+ return reject(new Error("Update download is larger than we are willing to store"));
133
+ }
134
+ if (declared && expectedBytes && declared !== expectedBytes) {
135
+ res.destroy();
136
+ return reject(new Error("Update download size does not match the published size"));
137
+ }
138
+ state = { ...state, totalBytes: declared || expectedBytes || null };
139
+ const hash = (0, import_node_crypto.createHash)("sha256");
140
+ const out = import_node_fs.default.createWriteStream(dest, { mode: 384 });
141
+ let written = 0;
142
+ const fail = (err) => {
143
+ res.destroy();
144
+ out.destroy();
145
+ reject(err);
146
+ };
147
+ res.on("data", (chunk) => {
148
+ if (cancelled) return fail(new Error("Cancelled"));
149
+ written += chunk.length;
150
+ if (written > MAX_BYTES) return fail(new Error("Update download exceeded its size cap"));
151
+ hash.update(chunk);
152
+ state = { ...state, bytesDownloaded: written };
153
+ });
154
+ res.on("error", fail);
155
+ out.on("error", fail);
156
+ res.pipe(out);
157
+ out.on("finish", () => resolve(hash.digest("hex")));
158
+ }
159
+ );
160
+ req.on("timeout", () => req.destroy(new Error("Update download timed out")));
161
+ req.on("error", reject);
162
+ });
163
+ }
164
+ function startUpdateDownload(version, info) {
165
+ if (inFlight) return inFlight;
166
+ cancelled = false;
167
+ const run = (async () => {
168
+ try {
169
+ const url = assertAllowedUrl(info.url);
170
+ const filename = safeFilename(info.filename || import_node_path.default.basename(url.pathname));
171
+ assertArtifactMatchesOffer(url, filename, version);
172
+ state = { ...IDLE, phase: "preparing", version, filename, totalBytes: info.size ?? null };
173
+ const expectedSha256 = await fetchSignedDigest(url, filename);
174
+ if (cancelled) throw new Error("Cancelled");
175
+ const dir = downloadDir();
176
+ import_node_fs.default.mkdirSync(dir, { recursive: true });
177
+ const dest = import_node_path.default.join(dir, filename);
178
+ const partial = `${dest}.part`;
179
+ state = { ...state, phase: "downloading", bytesDownloaded: 0 };
180
+ try {
181
+ import_node_fs.default.rmSync(partial, { force: true });
182
+ } catch {
183
+ }
184
+ const actual = await fetchToFile(url, partial, info.size ?? null);
185
+ state = { ...state, phase: "verifying" };
186
+ if (!digestsEqual(actual, expectedSha256)) {
187
+ try {
188
+ import_node_fs.default.rmSync(partial, { force: true });
189
+ } catch {
190
+ }
191
+ throw new Error(
192
+ "Downloaded file does not match the published checksum. It has been deleted."
193
+ );
194
+ }
195
+ import_node_fs.default.renameSync(partial, dest);
196
+ state = { ...state, phase: "ready", filePath: dest, sha256: expectedSha256 };
197
+ console.log(`[Update] Verified ${filename} \u2014 sha256 matches the published digest`);
198
+ return state;
199
+ } catch (err) {
200
+ const message = err instanceof Error ? err.message : String(err);
201
+ const wasCancelled = message === "Cancelled" || cancelled;
202
+ if (!wasCancelled) console.warn(`[Update] Download failed: ${message}`);
203
+ state = {
204
+ ...state,
205
+ phase: wasCancelled ? "idle" : "error",
206
+ error: wasCancelled ? null : message,
207
+ filePath: null
208
+ };
209
+ return state;
210
+ }
211
+ })();
212
+ inFlight = run;
213
+ void run.finally(() => {
214
+ if (inFlight === run) inFlight = null;
215
+ });
216
+ return run;
217
+ }
218
+ async function fetchSignedDigest(assetUrl, filename) {
219
+ const base = assetUrl.toString().replace(/\/[^/]*$/, "");
220
+ const manifestUrl = assertAllowedUrl(`${base}/SHA256SUMS`);
221
+ const signatureUrl = assertAllowedUrl(`${base}/SHA256SUMS.sig`);
222
+ let manifest;
223
+ let signature;
224
+ try {
225
+ [manifest, signature] = await Promise.all([
226
+ fetchSmall(manifestUrl),
227
+ fetchSmall(signatureUrl).then((b) => b.toString("utf-8"))
228
+ ]);
229
+ } catch {
230
+ throw new Error(
231
+ "This release does not publish a signed checksum manifest, so the download cannot be verified. Use the download link instead."
232
+ );
233
+ }
234
+ if (!(0, import_release_signature.verifyManifestSignature)(manifest, signature)) {
235
+ throw new Error(
236
+ "The release checksum manifest is not signed by CodeTrellis. Refusing to download."
237
+ );
238
+ }
239
+ const digest = (0, import_release_signature.digestFor)((0, import_release_signature.parseManifest)(manifest.toString("utf-8")), filename);
240
+ if (!digest) {
241
+ throw new Error(`The signed manifest does not list ${filename}. Refusing to download.`);
242
+ }
243
+ return digest;
244
+ }
245
+ function fetchSmall(url, hops = 0) {
246
+ const MAX_SMALL = 64 * 1024;
247
+ return new Promise((resolve, reject) => {
248
+ if (hops > MAX_REDIRECTS) return reject(new Error("Too many redirects"));
249
+ const req = import_node_https.default.get(
250
+ url,
251
+ { timeout: REQUEST_TIMEOUT_MS, headers: { "user-agent": "CodeTrellis" } },
252
+ (res) => {
253
+ const status = res.statusCode ?? 0;
254
+ if (status >= 300 && status < 400 && res.headers.location) {
255
+ res.resume();
256
+ let next;
257
+ try {
258
+ next = assertAllowedUrl(new URL(res.headers.location, url).toString());
259
+ } catch (err) {
260
+ return reject(err);
261
+ }
262
+ return fetchSmall(next, hops + 1).then(resolve, reject);
263
+ }
264
+ if (status !== 200) {
265
+ res.resume();
266
+ return reject(new Error(`HTTP ${status}`));
267
+ }
268
+ const chunks = [];
269
+ let size = 0;
270
+ res.on("data", (c) => {
271
+ size += c.length;
272
+ if (size > MAX_SMALL) {
273
+ res.destroy();
274
+ return reject(new Error("Manifest too large"));
275
+ }
276
+ chunks.push(c);
277
+ });
278
+ res.on("end", () => resolve(Buffer.concat(chunks)));
279
+ res.on("error", reject);
280
+ }
281
+ );
282
+ req.on("timeout", () => req.destroy(new Error("Timed out")));
283
+ req.on("error", reject);
284
+ });
285
+ }
286
+ async function saveVerifiedUpdateCopy(dest) {
287
+ const { phase, filePath, sha256 } = state;
288
+ if (phase !== "ready" || !filePath || !sha256) throw new Error("No verified download to save");
289
+ if (!import_node_path.default.isAbsolute(dest)) throw new Error("The save location must be an absolute path");
290
+ const target = import_node_path.default.resolve(dest);
291
+ if (target === import_node_path.default.resolve(filePath)) return target;
292
+ const partial = `${target}.part`;
293
+ const hash = (0, import_node_crypto.createHash)("sha256");
294
+ await new Promise((resolve, reject) => {
295
+ const input = import_node_fs.default.createReadStream(filePath);
296
+ const out = import_node_fs.default.createWriteStream(partial);
297
+ input.on("data", (c) => hash.update(c));
298
+ input.on("error", reject);
299
+ out.on("error", reject);
300
+ out.on("finish", () => resolve());
301
+ input.pipe(out);
302
+ }).catch((err) => {
303
+ try {
304
+ import_node_fs.default.rmSync(partial, { force: true });
305
+ } catch {
306
+ }
307
+ throw err;
308
+ });
309
+ if (!digestsEqual(hash.digest("hex"), sha256)) {
310
+ try {
311
+ import_node_fs.default.rmSync(partial, { force: true });
312
+ } catch {
313
+ }
314
+ throw new Error("The downloaded file changed on disk since it was verified. Download it again.");
315
+ }
316
+ import_node_fs.default.renameSync(partial, target);
317
+ state = { ...state, savedPath: target };
318
+ return target;
319
+ }
320
+ function cancelUpdateDownload() {
321
+ if (inFlight) cancelled = true;
322
+ return state;
323
+ }
324
+ function _resetUpdateDownloadState() {
325
+ state = { ...IDLE };
326
+ inFlight = null;
327
+ cancelled = false;
328
+ }
329
+ function _setVerifiedForTest(v) {
330
+ state = { ...IDLE, phase: "ready", ...v };
331
+ }
332
+ const _internals = { assertAllowedUrl, safeFilename, digestsEqual, ALLOWED_HOSTS, MAX_BYTES };
333
+ // Annotate the CommonJS export names for ESM import in node:
334
+ 0 && (module.exports = {
335
+ _internals,
336
+ _resetUpdateDownloadState,
337
+ _setVerifiedForTest,
338
+ cancelUpdateDownload,
339
+ getUpdateDownloadState,
340
+ saveVerifiedUpdateCopy,
341
+ startUpdateDownload
342
+ });