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,356 @@
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 ui_tools_exports = {};
29
+ __export(ui_tools_exports, {
30
+ register: () => register
31
+ });
32
+ module.exports = __toCommonJS(ui_tools_exports);
33
+ var _lazy_______services_mdns_service = __toESM(require("../../services/mdns-service"));
34
+ var import_node_fs = __toESM(require("node:fs"));
35
+ var import_zod = require("zod");
36
+ var import_grant_guard = require("../../services/grant-guard");
37
+ function register(server, deps) {
38
+ server.registerTool(
39
+ "ui_ready",
40
+ {
41
+ description: "Is the CodeTrellis window actually usable right now? Reports whether the app shell is mounted, whether a blocking dialog covers it, whether a project is open, which workspace and side-panel tab are showing, which file or recorded file is on screen, and which acceptance criteria are visible and in what state. Call this before driving the UI: every other tool answers from the backend and will happily succeed while the window shows something else entirely.",
42
+ inputSchema: {}
43
+ },
44
+ async () => {
45
+ const nonce = `ur-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
46
+ const p = new Promise((resolve, reject) => {
47
+ const timer = setTimeout(() => {
48
+ deps.pendingResponses.delete(nonce);
49
+ reject(new Error("No answer from the window \u2014 is the CodeTrellis UI open?"));
50
+ }, 5e3);
51
+ deps.pendingResponses.set(nonce, { resolve, reject, timer });
52
+ });
53
+ deps.broadcast("ui-ready-request", { nonce });
54
+ try {
55
+ return { content: [{ type: "text", text: await p }] };
56
+ } catch (err) {
57
+ return {
58
+ content: [{
59
+ type: "text",
60
+ text: JSON.stringify({
61
+ ready: false,
62
+ reason: err instanceof Error ? err.message : String(err)
63
+ })
64
+ }],
65
+ isError: true
66
+ };
67
+ }
68
+ }
69
+ );
70
+ server.registerTool(
71
+ "screenshot",
72
+ {
73
+ description: "Capture a screenshot of the CodeTrellis UI and return it as a base64-encoded PNG image. Use this to see the current state of the graph, plan workspace, terminal output, or any other part of the UI. The screenshot is taken from the connected browser/Electron window. Optionally target a specific panel to capture only that area.",
74
+ inputSchema: {
75
+ panel: import_zod.z.enum(["full", "graph", "plan", "terminal"]).optional().describe(
76
+ 'Which panel to capture. "full" = entire window (default). "graph" = dependency graph canvas. "plan" = plan workspace. "terminal" = terminal panel.'
77
+ )
78
+ }
79
+ },
80
+ async ({ panel }) => {
81
+ if (deps.captureElectronScreenshot) {
82
+ try {
83
+ const base64 = await deps.captureElectronScreenshot();
84
+ return {
85
+ content: [{
86
+ type: "image",
87
+ data: base64,
88
+ mimeType: "image/png"
89
+ }]
90
+ };
91
+ } catch (err) {
92
+ return { content: [{ type: "text", text: `Electron screenshot failed: ${err instanceof Error ? err.message : String(err)}` }], isError: true };
93
+ }
94
+ }
95
+ const nonce = `ss-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
96
+ const target = panel ?? "full";
97
+ const p = new Promise((resolve, reject) => {
98
+ const timer = setTimeout(() => {
99
+ deps.pendingResponses.delete(nonce);
100
+ reject(new Error("Screenshot timed out \u2014 is the CodeTrellis UI open in a browser?"));
101
+ }, 1e4);
102
+ deps.pendingResponses.set(nonce, { resolve, reject, timer });
103
+ });
104
+ deps.broadcast("ui-screenshot-request", { nonce, panel: target });
105
+ try {
106
+ const base64 = await p;
107
+ if (!base64) {
108
+ return { content: [{ type: "text", text: "Screenshot capture failed \u2014 the frontend returned empty data (html-to-image may have hit a canvas-tainting error)." }], isError: true };
109
+ }
110
+ return {
111
+ content: [{
112
+ type: "image",
113
+ data: base64,
114
+ mimeType: "image/png"
115
+ }]
116
+ };
117
+ } catch (err) {
118
+ return { content: [{ type: "text", text: err instanceof Error ? err.message : String(err) }], isError: true };
119
+ }
120
+ }
121
+ );
122
+ server.registerTool(
123
+ "select_item",
124
+ {
125
+ description: "Navigate the plan workspace to a specific item by UID. The item will be selected in the sidebar tree and its body/properties will appear in the canvas. If the plan workspace is not open, it will be opened automatically.",
126
+ inputSchema: {
127
+ item_uid: import_zod.z.string().describe("UID of the plan item to select."),
128
+ plan_uid: import_zod.z.string().optional().describe("Plan UID (auto-detected from the item if omitted).")
129
+ }
130
+ },
131
+ async ({ item_uid, plan_uid }) => {
132
+ const item = deps.planItemService.getItem(item_uid);
133
+ if (!item) {
134
+ return { content: [{ type: "text", text: `Item ${item_uid} not found.` }], isError: true };
135
+ }
136
+ if (plan_uid && plan_uid !== item.planUid) {
137
+ return { content: [{ type: "text", text: `Item ${item_uid} is in plan ${item.planUid}, not ${plan_uid}.` }], isError: true };
138
+ }
139
+ const resolvedPlanUid = item.planUid;
140
+ deps.broadcast("ui-navigate", { target: "plan", planUid: resolvedPlanUid });
141
+ deps.broadcast("ui-select-item", { planUid: resolvedPlanUid, itemUid: item_uid });
142
+ return { content: [{ type: "text", text: `Selected item ${item_uid} in plan ${resolvedPlanUid}` }] };
143
+ }
144
+ );
145
+ server.registerTool(
146
+ "open_project",
147
+ {
148
+ description: "Open and scan a project directory in CodeTrellis. Parses the codebase, builds the dependency graph, and makes the project available to every tool that takes a project_path. Use this during onboarding to load a project for the first time.",
149
+ inputSchema: {
150
+ path: import_zod.z.string().describe("Absolute path to the project root directory.")
151
+ }
152
+ },
153
+ async ({ path: projectPath }) => {
154
+ try {
155
+ const stats = await deps.scanProject(projectPath);
156
+ deps.broadcast("ui-open-project", { path: projectPath });
157
+ return {
158
+ content: [{
159
+ type: "text",
160
+ text: `Opened ${projectPath} \u2014 ${stats.fileCount} files, ${stats.symbolCount} symbols, ${stats.importCount} imports (${stats.resolvedImports} resolved)`
161
+ }]
162
+ };
163
+ } catch (err) {
164
+ return {
165
+ content: [{
166
+ type: "text",
167
+ text: `Could not open ${projectPath}: ${err instanceof Error ? err.message : String(err)}`
168
+ }],
169
+ isError: true
170
+ };
171
+ }
172
+ }
173
+ );
174
+ server.registerTool(
175
+ "clipboard_write",
176
+ {
177
+ description: "Copy text to the user's clipboard. Use this to share code snippets, plan prompts, architecture summaries, or any text the user might want to paste elsewhere.",
178
+ inputSchema: {
179
+ text: import_zod.z.string().describe("The text to copy to the clipboard.")
180
+ }
181
+ },
182
+ async ({ text }) => {
183
+ deps.broadcast("ui-clipboard-write", { text });
184
+ return { content: [{ type: "text", text: `Copied ${text.length} chars to clipboard` }] };
185
+ }
186
+ );
187
+ server.registerTool(
188
+ "clipboard_read",
189
+ {
190
+ description: "Read the current contents of the user's clipboard. Useful for importing text the user has copied from another app (a GitHub issue, a Slack message, code from their editor, etc.).",
191
+ inputSchema: {}
192
+ },
193
+ async () => {
194
+ const nonce = `cb-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
195
+ const p = new Promise((resolve, reject) => {
196
+ const timer = setTimeout(() => {
197
+ deps.pendingResponses.delete(nonce);
198
+ reject(new Error("Clipboard read timed out \u2014 is the CodeTrellis UI open and focused?"));
199
+ }, 1e4);
200
+ deps.pendingResponses.set(nonce, { resolve, reject, timer });
201
+ });
202
+ deps.broadcast("ui-clipboard-read", { nonce });
203
+ try {
204
+ const text = await p;
205
+ return { content: [{ type: "text", text: text || "(clipboard is empty)" }] };
206
+ } catch (err) {
207
+ return { content: [{ type: "text", text: err instanceof Error ? err.message : String(err) }], isError: true };
208
+ }
209
+ }
210
+ );
211
+ server.registerTool(
212
+ "get_settings",
213
+ {
214
+ description: "Read the current CodeTrellis settings \u2014 identity (display name, email), MCP server config (port, auto-detect), plan defaults (visibility, attachment location), and data directory.",
215
+ inputSchema: {}
216
+ },
217
+ async () => {
218
+ const settings = deps.getSettings();
219
+ return { content: [{ type: "text", text: JSON.stringify(settings, null, 2) }] };
220
+ }
221
+ );
222
+ server.registerTool(
223
+ "update_settings",
224
+ {
225
+ description: "Update CodeTrellis settings. Pass only the fields you want to change \u2014 unmentioned fields are preserved. Nested objects are deep-merged. Note: changing the MCP port requires a server restart to take effect.",
226
+ inputSchema: {
227
+ identity: import_zod.z.object({
228
+ displayName: import_zod.z.string().optional().describe("Display name shown in attributions."),
229
+ email: import_zod.z.string().optional().describe("Email used as canonical author key.")
230
+ }).optional().describe("Identity settings."),
231
+ mcp: import_zod.z.object({
232
+ port: import_zod.z.number().optional().describe("Preferred MCP port (default 19432)."),
233
+ autodetectOnCollision: import_zod.z.boolean().optional().describe("Try next ports if preferred is in use.")
234
+ }).optional().describe("MCP server settings."),
235
+ plans: import_zod.z.object({
236
+ defaultVisibility: import_zod.z.enum(["shared", "local"]).optional().describe('"shared" = export to .codetrellis/plans/, "local" = DB-only.'),
237
+ attachmentLocation: import_zod.z.enum(["project", "user"]).optional().describe('"project" = in repo, "user" = user data dir.')
238
+ }).optional().describe("Plan default settings."),
239
+ data: import_zod.z.object({
240
+ dataDirOverride: import_zod.z.string().optional().describe("Override for ~/.codetrellis/ data directory. Empty = default."),
241
+ personalSyncPath: import_zod.z.string().optional().describe("Path to personal sync folder (git repo, iCloud, Dropbox). Empty = no sync."),
242
+ personalSyncMode: import_zod.z.enum(["none", "selective", "full"]).optional().describe("What to sync: none, selective (settings+projects), or full (entire pantry).")
243
+ }).optional().describe("Data and sync settings."),
244
+ device: import_zod.z.object({
245
+ deviceName: import_zod.z.string().optional().describe("Human-readable name for this machine (shown to peers). Empty = hostname."),
246
+ advertise: import_zod.z.boolean().optional().describe("Whether to advertise via mDNS on the local network."),
247
+ shareAudio: import_zod.z.boolean().optional().describe("Whether to share audio capture with paired devices.")
248
+ }).optional().describe("Device discovery and pairing settings. Changes to advertise/deviceName take effect immediately (live mDNS restart)."),
249
+ firstRunComplete: import_zod.z.boolean().optional().describe("Set to true after the first-run wizard completes.")
250
+ }
251
+ },
252
+ async ({ identity, mcp, plans, data, device, firstRunComplete }) => {
253
+ const patch = {};
254
+ if (identity) patch.identity = identity;
255
+ if (mcp) patch.mcp = mcp;
256
+ if (plans) patch.plans = plans;
257
+ if (data) patch.data = data;
258
+ if (device) patch.device = device;
259
+ if (firstRunComplete !== void 0) patch.firstRunComplete = firstRunComplete;
260
+ const grant = (0, import_grant_guard.grantChange)(patch, deps.getSettings());
261
+ if (grant) {
262
+ return { content: [{ type: "text", text: (0, import_grant_guard.grantRefusal)(grant.field, grant.where) }], isError: true };
263
+ }
264
+ const updated = deps.updateSettings(patch);
265
+ if (device?.advertise !== void 0 || device?.deviceName !== void 0) {
266
+ try {
267
+ const mdns = _lazy_______services_mdns_service;
268
+ if (updated.device.advertise) {
269
+ mdns.startMdns(updated.device.deviceName || void 0);
270
+ } else {
271
+ mdns.stopMdns();
272
+ }
273
+ } catch {
274
+ }
275
+ }
276
+ deps.broadcast("settings-changed", { settings: updated });
277
+ const changes = [];
278
+ if (identity?.displayName !== void 0) changes.push(`display name \u2192 "${identity.displayName}"`);
279
+ if (identity?.email !== void 0) changes.push(`email \u2192 "${identity.email}"`);
280
+ if (mcp?.port !== void 0) changes.push(`MCP port \u2192 ${mcp.port} (restart needed)`);
281
+ if (mcp?.autodetectOnCollision !== void 0) changes.push(`auto-detect port \u2192 ${mcp.autodetectOnCollision}`);
282
+ if (plans?.defaultVisibility !== void 0) changes.push(`plan visibility \u2192 ${plans.defaultVisibility}`);
283
+ if (plans?.attachmentLocation !== void 0) changes.push(`attachment location \u2192 ${plans.attachmentLocation}`);
284
+ if (data?.personalSyncPath !== void 0) changes.push(`sync path \u2192 "${data.personalSyncPath}"`);
285
+ if (data?.personalSyncMode !== void 0) changes.push(`sync mode \u2192 ${data.personalSyncMode}`);
286
+ if (data?.dataDirOverride !== void 0) changes.push(`data dir \u2192 "${data.dataDirOverride || "(default)"}"`);
287
+ if (device?.deviceName !== void 0) changes.push(`device name \u2192 "${device.deviceName || "(hostname)"}"`);
288
+ if (device?.advertise !== void 0) changes.push(`mDNS advertise \u2192 ${device.advertise}`);
289
+ if (device?.shareAudio !== void 0) changes.push(`share audio with peers \u2192 ${device.shareAudio}`);
290
+ if (firstRunComplete !== void 0) changes.push(`first-run complete \u2192 ${firstRunComplete}`);
291
+ return { content: [{ type: "text", text: `Settings updated: ${changes.join(", ")}` }] };
292
+ }
293
+ );
294
+ server.registerTool(
295
+ "get_logs",
296
+ {
297
+ description: "Read the tail of the CodeTrellis application log. Returns the most recent log entries from the current day's log file. Useful for diagnosing errors, checking parse results, or understanding what happened during a scan or agent operation.",
298
+ inputSchema: {
299
+ lines: import_zod.z.number().optional().describe("Approximate number of lines to return (default ~500). Max constrained by 64KB."),
300
+ filter: import_zod.z.string().optional().describe("Optional grep-style filter \u2014 only return lines containing this string (case-insensitive).")
301
+ }
302
+ },
303
+ async ({ lines, filter }) => {
304
+ if (!import_node_fs.default.existsSync(deps.getCurrentLogPath())) {
305
+ return { content: [{ type: "text", text: "No log file: file logging runs in the CodeTrellis desktop app. This backend (web or dev build) logs to its console instead." }] };
306
+ }
307
+ const maxBytes = Math.min(Math.max(1, lines ?? 500) * 200, 64 * 1024);
308
+ let content = deps.tailLog(maxBytes);
309
+ if (filter) {
310
+ const lower = filter.toLowerCase();
311
+ content = content.split("\n").filter((line) => line.toLowerCase().includes(lower)).join("\n");
312
+ }
313
+ if (!content.trim()) {
314
+ return { content: [{ type: "text", text: "(no log entries found)" }] };
315
+ }
316
+ return { content: [{ type: "text", text: content }] };
317
+ }
318
+ );
319
+ server.registerTool(
320
+ "get_log_path",
321
+ {
322
+ description: "Get the path to the current log file and logs directory. Useful if the agent needs to tell the user where to find logs, or to read logs directly from disk.",
323
+ inputSchema: {}
324
+ },
325
+ async () => {
326
+ return {
327
+ content: [{
328
+ type: "text",
329
+ text: JSON.stringify({
330
+ currentLogFile: deps.getCurrentLogPath(),
331
+ logDirectory: deps.getLogDir()
332
+ }, null, 2)
333
+ }]
334
+ };
335
+ }
336
+ );
337
+ server.registerTool(
338
+ "get_app_guide",
339
+ {
340
+ description: 'Get instructions on how to use CodeTrellis. Returns a comprehensive markdown guide covering available MCP tools, workflows, and best practices. Seven flavors: "summary" = project-state-tailored overview with active plans and agents, "quickstart" = minimum viable agent workflow (register \u2192 find plan \u2192 claim \u2192 work \u2192 verify \u2192 done), "power-user" = deep features (phased plans, multi-agent, spec docs, drift, snapshots), "ui-nav" = focused UI navigation skill for sub-agents that drive the interface while the primary agent works, "diagnostics" = logs, settings, baseline, drift detection, architecture conformity, "multi-agent" = terminals, claiming, handoff patterns, session registration, approval gates, "parallel" = working alongside agents in other worktrees: get_awareness, declare_intent, check_footprint, acknowledge_signal.',
341
+ inputSchema: {
342
+ flavor: import_zod.z.enum(["summary", "quickstart", "power-user", "ui-nav", "diagnostics", "multi-agent", "parallel"]).optional().describe(
343
+ 'Which guide to return. Default "summary". Use "quickstart" for first-time setup, "power-user" for advanced features, "ui-nav" for a sub-agent driving the UI, "diagnostics" for logs/settings/drift, "multi-agent" for terminal/claim/handoff workflows, "parallel" when other agents work in other worktrees of this repository.'
344
+ )
345
+ }
346
+ },
347
+ async ({ flavor }) => {
348
+ const guide = deps.buildSkillGuide(flavor ?? "summary");
349
+ return { content: [{ type: "text", text: guide }] };
350
+ }
351
+ );
352
+ }
353
+ // Annotate the CommonJS export names for ESM import in node:
354
+ 0 && (module.exports = {
355
+ register
356
+ });
@@ -0,0 +1,15 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __copyProps = (to, from, except, desc) => {
6
+ if (from && typeof from === "object" || typeof from === "function") {
7
+ for (let key of __getOwnPropNames(from))
8
+ if (!__hasOwnProp.call(to, key) && key !== except)
9
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
10
+ }
11
+ return to;
12
+ };
13
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
14
+ var types_exports = {};
15
+ module.exports = __toCommonJS(types_exports);
@@ -0,0 +1,116 @@
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 local_auth_exports = {};
19
+ __export(local_auth_exports, {
20
+ isUpgradeAuthorised: () => isUpgradeAuthorised,
21
+ localAuthMiddleware: () => localAuthMiddleware
22
+ });
23
+ module.exports = __toCommonJS(local_auth_exports);
24
+ var import_capability_token = require("../services/capability-token");
25
+ const ALLOWED_HOSTS = /* @__PURE__ */ new Set(["127.0.0.1", "localhost", "[::1]", "::1"]);
26
+ function allowedOrigins() {
27
+ const set = /* @__PURE__ */ new Set();
28
+ if (process.env.NODE_ENV !== "production") {
29
+ const devPort = process.env.CODETRELLIS_DEV_ORIGIN_PORT || "5173";
30
+ set.add(`http://localhost:${devPort}`);
31
+ set.add(`http://127.0.0.1:${devPort}`);
32
+ }
33
+ const extra = process.env.CODETRELLIS_EXTRA_ORIGIN;
34
+ if (extra) set.add(extra);
35
+ return set;
36
+ }
37
+ function isPublicPath(pathname) {
38
+ return pathname === "/api/health";
39
+ }
40
+ function localAuthMiddleware(req, res, next) {
41
+ const origin = req.headers.origin;
42
+ const hostHeader = (req.headers.host || "").toString();
43
+ const hostname = hostHeader.replace(/:\d+$/, "").toLowerCase();
44
+ if (hostname && !ALLOWED_HOSTS.has(hostname)) {
45
+ res.status(403).json({ error: "Host not allowed" });
46
+ return;
47
+ }
48
+ if (origin) {
49
+ if (allowedOrigins().has(origin)) {
50
+ res.setHeader("Access-Control-Allow-Origin", origin);
51
+ res.setHeader("Access-Control-Allow-Credentials", "true");
52
+ res.setHeader("Vary", "Origin");
53
+ } else {
54
+ res.setHeader("Vary", "Origin");
55
+ if (!isPublicPath(req.path)) {
56
+ res.status(403).json({ error: "Origin not allowed" });
57
+ return;
58
+ }
59
+ }
60
+ }
61
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");
62
+ res.setHeader(
63
+ "Access-Control-Allow-Headers",
64
+ `Content-Type, Authorization, ${import_capability_token.TOKEN_HEADER}`
65
+ );
66
+ if (req.method === "OPTIONS") {
67
+ if (origin && !allowedOrigins().has(origin)) {
68
+ res.status(403).end();
69
+ return;
70
+ }
71
+ res.sendStatus(204);
72
+ return;
73
+ }
74
+ if (isPublicPath(req.path)) {
75
+ next();
76
+ return;
77
+ }
78
+ const token = (0, import_capability_token.extractToken)(
79
+ req.headers,
80
+ req.originalUrl || req.url
81
+ );
82
+ if (!(0, import_capability_token.verifyCapabilityToken)(token)) {
83
+ res.status(401).json({
84
+ error: "Missing or invalid capability token",
85
+ // Tell a legitimate local client how to authenticate. This leaks
86
+ // nothing to a browser: it is the PATH of the token file, not its
87
+ // contents, and anything that can read that path could have read the
88
+ // file without being told.
89
+ hint: `Send the token from <dataDir>/capability-token as the ${import_capability_token.TOKEN_HEADER} header, an Authorization: Bearer value, or the ${import_capability_token.TOKEN_QUERY_PARAM} query parameter.`
90
+ });
91
+ return;
92
+ }
93
+ next();
94
+ }
95
+ function isUpgradeAuthorised(headers, url) {
96
+ const hostHeader = (headers.host || "").toString();
97
+ const hostname = hostHeader.replace(/:\d+$/, "").toLowerCase();
98
+ if (hostname && !ALLOWED_HOSTS.has(hostname)) {
99
+ return { ok: false, reason: "Host not allowed" };
100
+ }
101
+ const originRaw = headers.origin;
102
+ const origin = Array.isArray(originRaw) ? originRaw[0] : originRaw;
103
+ if (origin && !allowedOrigins().has(origin)) {
104
+ return { ok: false, reason: "Origin not allowed" };
105
+ }
106
+ const token = (0, import_capability_token.extractToken)(headers, url);
107
+ if (!(0, import_capability_token.verifyCapabilityToken)(token)) {
108
+ return { ok: false, reason: "Missing or invalid capability token" };
109
+ }
110
+ return { ok: true };
111
+ }
112
+ // Annotate the CommonJS export names for ESM import in node:
113
+ 0 && (module.exports = {
114
+ isUpgradeAuthorised,
115
+ localAuthMiddleware
116
+ });