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,266 @@
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 update_service_exports = {};
19
+ __export(update_service_exports, {
20
+ checkForUpdate: () => checkForUpdate,
21
+ detectPlatform: () => detectPlatform,
22
+ findDesktopRelease: () => findDesktopRelease,
23
+ getUpdateState: () => getUpdateState,
24
+ pickAssetForPlatform: () => pickAssetForPlatform,
25
+ startUpdatePolling: () => startUpdatePolling,
26
+ stopUpdatePolling: () => stopUpdatePolling
27
+ });
28
+ module.exports = __toCommonJS(update_service_exports);
29
+ var import_build_info = require("../../shared/build-info");
30
+ var import_settings_service = require("./settings-service");
31
+ const POLL_INTERVAL_MS = 24 * 60 * 60 * 1e3;
32
+ const CACHE_TTL_MS = 60 * 60 * 1e3;
33
+ const REQUEST_TIMEOUT_MS = 8e3;
34
+ const DEFAULT_OTA_URL = "https://codetrellis.dev";
35
+ const DEFAULT_GITHUB_REPO = "lionroseway/codetrellis-releases";
36
+ let state = {
37
+ status: "idle",
38
+ lastCheckedAt: null,
39
+ result: null,
40
+ lastError: null,
41
+ platform: detectPlatform(),
42
+ currentVersion: import_build_info.BUILD_INFO.version
43
+ };
44
+ let pollTimer = null;
45
+ let inFlight = null;
46
+ function getUpdateState() {
47
+ return state;
48
+ }
49
+ async function checkForUpdate(opts = {}) {
50
+ if (!opts.force && state.result !== null && state.lastCheckedAt !== null && Date.now() - state.lastCheckedAt < CACHE_TTL_MS) {
51
+ return state;
52
+ }
53
+ if (inFlight) return inFlight;
54
+ inFlight = (async () => {
55
+ state = { ...state, status: "checking" };
56
+ try {
57
+ const result = await runCheck();
58
+ state = {
59
+ ...state,
60
+ status: result.available ? "available" : "up-to-date",
61
+ result,
62
+ lastCheckedAt: Date.now(),
63
+ lastError: null
64
+ };
65
+ } catch (err) {
66
+ state = {
67
+ ...state,
68
+ status: "error",
69
+ lastCheckedAt: Date.now(),
70
+ lastError: err instanceof Error ? err.message : String(err)
71
+ };
72
+ } finally {
73
+ inFlight = null;
74
+ }
75
+ return state;
76
+ })();
77
+ return inFlight;
78
+ }
79
+ function startUpdatePolling() {
80
+ if (pollTimer) return;
81
+ const autoCheck = () => (0, import_settings_service.getSettings)().updates.autoCheck;
82
+ if (autoCheck()) {
83
+ checkForUpdate().catch(() => {
84
+ });
85
+ }
86
+ pollTimer = setInterval(() => {
87
+ if (!autoCheck()) return;
88
+ checkForUpdate().catch(() => {
89
+ });
90
+ }, POLL_INTERVAL_MS);
91
+ if (typeof pollTimer.unref === "function") pollTimer.unref();
92
+ }
93
+ function stopUpdatePolling() {
94
+ if (pollTimer) {
95
+ clearInterval(pollTimer);
96
+ pollTimer = null;
97
+ }
98
+ }
99
+ function getOtaUrl() {
100
+ return process.env.CODETRELLIS_OTA_URL || DEFAULT_OTA_URL;
101
+ }
102
+ function getGithubApi() {
103
+ return (process.env.CODETRELLIS_GITHUB_API || "https://api.github.com").replace(/\/+$/, "");
104
+ }
105
+ function getGithubRepo() {
106
+ return process.env.CODETRELLIS_GITHUB_REPO || DEFAULT_GITHUB_REPO;
107
+ }
108
+ function detectPlatform() {
109
+ const p = process.platform;
110
+ const a = process.arch;
111
+ if (p === "darwin") return a === "arm64" ? "darwin-arm64" : "darwin-x64";
112
+ if (p === "win32") return a === "arm64" ? "win32-arm64" : "win32-x64";
113
+ if (p === "linux") return a === "arm64" ? "linux-arm64" : "linux-x64";
114
+ return `${p}-${a}`;
115
+ }
116
+ async function runCheck() {
117
+ const platform = state.platform;
118
+ const current = state.currentVersion;
119
+ try {
120
+ const websiteResult = await checkViaWebsite(platform, current);
121
+ if (websiteResult) return websiteResult;
122
+ } catch {
123
+ }
124
+ const githubResult = await checkViaGithub(platform, current);
125
+ return githubResult;
126
+ }
127
+ async function checkViaWebsite(platform, current) {
128
+ const base = getOtaUrl().replace(/\/+$/, "");
129
+ const url = `${base}/api/updates/check?platform=${encodeURIComponent(platform)}&current=${encodeURIComponent(current)}`;
130
+ const res = await timedFetch(url, { headers: { Accept: "application/json" } });
131
+ if (!res.ok) return null;
132
+ const ctype = res.headers.get("content-type") || "";
133
+ if (!ctype.includes("application/json")) return null;
134
+ const data = await res.json();
135
+ if (typeof data.available !== "boolean" || typeof data.latest !== "string") {
136
+ return null;
137
+ }
138
+ const newer = data.available === true;
139
+ return {
140
+ available: newer && !!data.download,
141
+ noAssetForPlatform: newer && !data.download,
142
+ latest: data.latest,
143
+ current: data.current ?? current,
144
+ publishedAt: data.publishedAt,
145
+ download: data.download,
146
+ releaseNotes: data.releaseNotes,
147
+ source: "website"
148
+ };
149
+ }
150
+ async function checkViaGithub(platform, current) {
151
+ const repo = getGithubRepo();
152
+ const url = `${getGithubApi()}/repos/${repo}/releases/latest`;
153
+ const res = await timedFetch(url, {
154
+ headers: {
155
+ Accept: "application/vnd.github+json",
156
+ "X-GitHub-Api-Version": "2022-11-28"
157
+ }
158
+ });
159
+ if (!res.ok) {
160
+ throw new Error(`GitHub releases API ${res.status}`);
161
+ }
162
+ const release = await res.json();
163
+ const tag = (release.tag_name || "").replace(/^v/, "");
164
+ if (!tag) throw new Error("GitHub release had no tag");
165
+ const asset = pickAssetForPlatform(release.assets ?? [], platform);
166
+ const newer = compareSemver(tag, current) > 0;
167
+ const available = newer && asset !== null;
168
+ return {
169
+ available,
170
+ noAssetForPlatform: newer && asset === null,
171
+ latest: tag,
172
+ current,
173
+ publishedAt: release.published_at,
174
+ download: asset ? {
175
+ url: asset.browser_download_url,
176
+ filename: asset.name,
177
+ size: asset.size,
178
+ contentType: asset.content_type,
179
+ sha256: extractSha256(asset.digest)
180
+ } : void 0,
181
+ releaseNotes: release.html_url ? { url: release.html_url, markdown: release.body } : void 0,
182
+ source: "github",
183
+ websiteFellBackToGithub: true
184
+ };
185
+ }
186
+ async function findDesktopRelease(platform, version) {
187
+ if (version !== void 0 && !/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(version)) {
188
+ throw new Error(`"${version}" is not a version (for example 0.2.0)`);
189
+ }
190
+ const repo = getGithubRepo();
191
+ const which = version ? `tags/v${encodeURIComponent(version)}` : "latest";
192
+ const res = await timedFetch(`${getGithubApi()}/repos/${repo}/releases/${which}`, {
193
+ headers: { Accept: "application/vnd.github+json", "X-GitHub-Api-Version": "2022-11-28" }
194
+ });
195
+ if (res.status === 404) throw new Error(version ? `There is no CodeTrellis ${version} release` : "There is no CodeTrellis release yet");
196
+ if (!res.ok) throw new Error(`GitHub releases API ${res.status}`);
197
+ const release = await res.json();
198
+ const tag = (release.tag_name || "").replace(/^v/, "");
199
+ if (!tag) throw new Error("GitHub release had no tag");
200
+ const asset = pickAssetForPlatform(release.assets ?? [], platform);
201
+ return {
202
+ version: tag,
203
+ platform,
204
+ download: asset ? { url: asset.browser_download_url, filename: asset.name, size: asset.size, contentType: asset.content_type, sha256: extractSha256(asset.digest) } : null,
205
+ releaseUrl: release.html_url
206
+ };
207
+ }
208
+ function pickAssetForPlatform(assets, platform) {
209
+ const matches = (name, pattern) => pattern.test(name);
210
+ const byPlatform = {
211
+ "darwin-arm64": [/-arm64\.dmg$/i],
212
+ "darwin-x64": [/-x64\.dmg$/i],
213
+ // Windows arm64 runs x64 binaries under emulation, so these are not
214
+ // an arch fallback — they are the artifact that platform is served.
215
+ "win32-x64": [/-Setup-.+\.exe$/i, /-Portable-.+\.exe$/i],
216
+ "win32-arm64": [/-Setup-.+\.exe$/i, /-Portable-.+\.exe$/i],
217
+ "linux-arm64": [/-arm64\.AppImage$/i],
218
+ "linux-x64": [/-x86_64\.AppImage$/i, /(?<!arm64)\.AppImage$/i]
219
+ };
220
+ const patterns = byPlatform[platform] ?? [];
221
+ for (const pattern of patterns) {
222
+ const found = assets.find((a) => matches(a.name, pattern));
223
+ if (found) return found;
224
+ }
225
+ return null;
226
+ }
227
+ function extractSha256(digest) {
228
+ if (!digest) return void 0;
229
+ const m = digest.match(/^sha256:([a-f0-9]{64})$/i);
230
+ return m ? m[1] : void 0;
231
+ }
232
+ function compareSemver(a, b) {
233
+ const partsA = a.split(/[-+]/)[0].split(".").map((n) => parseInt(n, 10) || 0);
234
+ const partsB = b.split(/[-+]/)[0].split(".").map((n) => parseInt(n, 10) || 0);
235
+ const len = Math.max(partsA.length, partsB.length);
236
+ for (let i = 0; i < len; i++) {
237
+ const x = partsA[i] ?? 0;
238
+ const y = partsB[i] ?? 0;
239
+ if (x > y) return 1;
240
+ if (x < y) return -1;
241
+ }
242
+ const preA = a.includes("-");
243
+ const preB = b.includes("-");
244
+ if (preA && !preB) return -1;
245
+ if (!preA && preB) return 1;
246
+ return 0;
247
+ }
248
+ async function timedFetch(url, init) {
249
+ const controller = new AbortController();
250
+ const t = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
251
+ try {
252
+ return await fetch(url, { ...init, signal: controller.signal });
253
+ } finally {
254
+ clearTimeout(t);
255
+ }
256
+ }
257
+ // Annotate the CommonJS export names for ESM import in node:
258
+ 0 && (module.exports = {
259
+ checkForUpdate,
260
+ detectPlatform,
261
+ findDesktopRelease,
262
+ getUpdateState,
263
+ pickAssetForPlatform,
264
+ startUpdatePolling,
265
+ stopUpdatePolling
266
+ });
@@ -0,0 +1,76 @@
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 watch_ignore_exports = {};
29
+ __export(watch_ignore_exports, {
30
+ HEAVY_DIRS: () => HEAVY_DIRS,
31
+ checkoutWatchOptions: () => checkoutWatchOptions,
32
+ isIgnoredByWatchers: () => isIgnoredByWatchers
33
+ });
34
+ module.exports = __toCommonJS(watch_ignore_exports);
35
+ var import_node_path = __toESM(require("node:path"));
36
+ const HEAVY_DIRS = /* @__PURE__ */ new Set([
37
+ "node_modules",
38
+ "dist",
39
+ "out",
40
+ "build",
41
+ "__pycache__",
42
+ "venv",
43
+ "env",
44
+ "target",
45
+ "vendor",
46
+ // Go's convention for fixture input that is deliberately not valid
47
+ // source — mirrors project-scanner's ALWAYS_IGNORED.
48
+ "testdata",
49
+ "coverage",
50
+ "test-results",
51
+ "playwright-report",
52
+ "cypress",
53
+ // Xcode and CocoaPods / Carthage: generated, and in a React Native or
54
+ // Expo checkout the biggest tree there is.
55
+ "Pods",
56
+ "Carthage",
57
+ "DerivedData"
58
+ ]);
59
+ function isIgnoredByWatchers(p, root) {
60
+ const rel = root ? import_node_path.default.relative(root, p) : p;
61
+ if (rel === "") return false;
62
+ if (/(^|[\\/])\.[^\\/]/.test(rel)) return true;
63
+ for (const seg of rel.split(/[\\/]/)) {
64
+ if (HEAVY_DIRS.has(seg)) return true;
65
+ }
66
+ return rel.endsWith(".log");
67
+ }
68
+ function checkoutWatchOptions(root) {
69
+ return { ignored: (p) => isIgnoredByWatchers(p, root), followSymlinks: false };
70
+ }
71
+ // Annotate the CommonJS export names for ESM import in node:
72
+ 0 && (module.exports = {
73
+ HEAVY_DIRS,
74
+ checkoutWatchOptions,
75
+ isIgnoredByWatchers
76
+ });
@@ -0,0 +1,206 @@
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 webhook_egress_exports = {};
29
+ __export(webhook_egress_exports, {
30
+ WebhookBlocked: () => WebhookBlocked,
31
+ isLoopbackAddress: () => isLoopbackAddress,
32
+ isPrivateAddress: () => isPrivateAddress,
33
+ postWebhookJson: () => postWebhookJson,
34
+ resolveWebhookTarget: () => resolveWebhookTarget
35
+ });
36
+ module.exports = __toCommonJS(webhook_egress_exports);
37
+ var import_node_http = __toESM(require("node:http"));
38
+ var import_node_https = __toESM(require("node:https"));
39
+ var import_promises = __toESM(require("node:dns/promises"));
40
+ var import_node_net = __toESM(require("node:net"));
41
+ class WebhookBlocked extends Error {
42
+ code = "EWEBHOOK_BLOCKED";
43
+ constructor(message) {
44
+ super(message);
45
+ this.name = "WebhookBlocked";
46
+ }
47
+ }
48
+ const MAX_RESPONSE_BYTES = 64 * 1024;
49
+ const FORBIDDEN_HEADERS = /* @__PURE__ */ new Set([
50
+ "host",
51
+ "connection",
52
+ "content-length",
53
+ "transfer-encoding",
54
+ "upgrade",
55
+ "keep-alive",
56
+ "proxy-authorization",
57
+ "te",
58
+ "trailer"
59
+ ]);
60
+ function isPrivateAddress(address) {
61
+ const mapped = /^::ffff:(\d+\.\d+\.\d+\.\d+)$/i.exec(address);
62
+ if (mapped) return isPrivateAddress(mapped[1]);
63
+ if (import_node_net.default.isIPv4(address)) {
64
+ const [a, b] = address.split(".").map(Number);
65
+ if (a === 0) return true;
66
+ if (a === 10) return true;
67
+ if (a === 127) return true;
68
+ if (a === 169 && b === 254) return true;
69
+ if (a === 172 && b >= 16 && b <= 31) return true;
70
+ if (a === 192 && b === 168) return true;
71
+ if (a === 192 && b === 0) return true;
72
+ if (a === 100 && b >= 64 && b <= 127) return true;
73
+ if (a === 198 && (b === 18 || b === 19)) return true;
74
+ if (a >= 224) return true;
75
+ return false;
76
+ }
77
+ if (import_node_net.default.isIPv6(address)) {
78
+ const lower = address.toLowerCase();
79
+ if (lower === "::" || lower === "::1") return true;
80
+ if (/^f[cd][0-9a-f]{2}:/.test(lower)) return true;
81
+ if (/^fe[89ab][0-9a-f]:/.test(lower)) return true;
82
+ if (/^ff[0-9a-f]{2}:/.test(lower)) return true;
83
+ return false;
84
+ }
85
+ return true;
86
+ }
87
+ function isLoopbackAddress(address) {
88
+ const mapped = /^::ffff:(\d+\.\d+\.\d+\.\d+)$/i.exec(address);
89
+ if (mapped) return isLoopbackAddress(mapped[1]);
90
+ if (import_node_net.default.isIPv4(address)) return Number(address.split(".")[0]) === 127;
91
+ if (import_node_net.default.isIPv6(address)) return address.toLowerCase() === "::1";
92
+ return false;
93
+ }
94
+ async function resolveWebhookTarget(rawUrl, approvedHosts, opts = {}) {
95
+ let url;
96
+ try {
97
+ url = new URL(rawUrl);
98
+ } catch {
99
+ throw new WebhookBlocked(`Webhook URL is not a URL: ${String(rawUrl).slice(0, 120)}`);
100
+ }
101
+ if (url.protocol !== "https:" && url.protocol !== "http:") {
102
+ throw new WebhookBlocked(
103
+ `Webhook URL must be https (got "${url.protocol}").`
104
+ );
105
+ }
106
+ if (url.username || url.password) {
107
+ throw new WebhookBlocked("Webhook URL must not contain credentials");
108
+ }
109
+ const host = url.hostname.replace(/^\[|\]$/g, "").toLowerCase();
110
+ if (!approvedHosts.some((h) => h.trim().toLowerCase() === host)) {
111
+ throw new WebhookBlocked(
112
+ `Webhook host "${host}" has not been approved. This URL comes from the project's config file, which is part of the repository \u2014 approve the host in Settings \u2192 Channels before it is used.`
113
+ );
114
+ }
115
+ const permitted = (addr) => !isPrivateAddress(addr) || opts.allowLoopback === true && isLoopbackAddress(addr);
116
+ const assertSchemeOkFor = (addr) => {
117
+ if (url.protocol === "https:") return;
118
+ if (opts.allowLoopback === true && isLoopbackAddress(addr)) return;
119
+ throw new WebhookBlocked(
120
+ `Webhook URL must be https (got "${url.protocol}"). A webhook body carries plan data.`
121
+ );
122
+ };
123
+ if (import_node_net.default.isIP(host)) {
124
+ if (!permitted(host)) {
125
+ throw new WebhookBlocked(`Webhook address ${host} is not a public address`);
126
+ }
127
+ assertSchemeOkFor(host);
128
+ return { url, address: host, family: import_node_net.default.isIPv6(host) ? 6 : 4 };
129
+ }
130
+ let records;
131
+ try {
132
+ records = await import_promises.default.lookup(host, { all: true, verbatim: true });
133
+ } catch (err) {
134
+ throw new WebhookBlocked(`Webhook host "${host}" did not resolve: ${err.message}`);
135
+ }
136
+ if (records.length === 0) {
137
+ throw new WebhookBlocked(`Webhook host "${host}" resolved to nothing`);
138
+ }
139
+ const priv = records.filter((r) => !permitted(r.address));
140
+ if (priv.length > 0) {
141
+ throw new WebhookBlocked(
142
+ `Webhook host "${host}" resolves to a non-public address (${priv[0].address})`
143
+ );
144
+ }
145
+ const chosen = records[0];
146
+ assertSchemeOkFor(chosen.address);
147
+ return { url, address: chosen.address, family: chosen.family === 6 ? 6 : 4 };
148
+ }
149
+ function postWebhookJson(target, headers, body, timeoutMs = 5e3) {
150
+ return new Promise((resolve, reject) => {
151
+ const safeHeaders = {};
152
+ for (const [k, v] of Object.entries(headers)) {
153
+ if (!FORBIDDEN_HEADERS.has(k.toLowerCase())) safeHeaders[k] = v;
154
+ }
155
+ const pinnedLookup = (_hostname, _options, callback) => {
156
+ callback(
157
+ null,
158
+ target.address,
159
+ target.family
160
+ );
161
+ };
162
+ const secure = target.url.protocol === "https:";
163
+ const transport = secure ? import_node_https.default : import_node_http.default;
164
+ const req = transport.request(
165
+ {
166
+ protocol: target.url.protocol,
167
+ hostname: target.url.hostname,
168
+ port: target.url.port || (secure ? 443 : 80),
169
+ path: `${target.url.pathname}${target.url.search}`,
170
+ method: "POST",
171
+ headers: { ...safeHeaders, "content-length": Buffer.byteLength(body) },
172
+ // Only meaningful over TLS; harmless on the loopback-only http path.
173
+ ...secure ? { servername: target.url.hostname } : {},
174
+ lookup: pinnedLookup,
175
+ timeout: timeoutMs
176
+ },
177
+ (res) => {
178
+ const status = res.statusCode ?? 0;
179
+ let read = 0;
180
+ res.on("data", (chunk) => {
181
+ read += chunk.length;
182
+ if (read > MAX_RESPONSE_BYTES) res.destroy();
183
+ });
184
+ res.on("end", () => resolve({ status, redirected: status >= 300 && status < 400 }));
185
+ res.on("error", reject);
186
+ if (status >= 300 && status < 400) {
187
+ res.destroy();
188
+ resolve({ status, redirected: true });
189
+ }
190
+ }
191
+ );
192
+ req.on("timeout", () => {
193
+ req.destroy(new Error("Webhook request timed out"));
194
+ });
195
+ req.on("error", reject);
196
+ req.end(body);
197
+ });
198
+ }
199
+ // Annotate the CommonJS export names for ESM import in node:
200
+ 0 && (module.exports = {
201
+ WebhookBlocked,
202
+ isLoopbackAddress,
203
+ isPrivateAddress,
204
+ postWebhookJson,
205
+ resolveWebhookTarget
206
+ });