codetrellis 0.0.0-stage → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (448) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +27 -2
  3. package/bin/codetrellis.mjs +4 -0
  4. package/package.json +41 -4
  5. package/reader/material-reader.mjs +130346 -0
  6. package/resources/tree-sitter/README.md +150 -0
  7. package/resources/tree-sitter/tree-sitter-c-sharp.wasm +0 -0
  8. package/resources/tree-sitter/tree-sitter-go.wasm +0 -0
  9. package/resources/tree-sitter/tree-sitter-java.wasm +0 -0
  10. package/resources/tree-sitter/tree-sitter-javascript.wasm +0 -0
  11. package/resources/tree-sitter/tree-sitter-kotlin.wasm +0 -0
  12. package/resources/tree-sitter/tree-sitter-php.wasm +0 -0
  13. package/resources/tree-sitter/tree-sitter-python.wasm +0 -0
  14. package/resources/tree-sitter/tree-sitter-ruby.wasm +0 -0
  15. package/resources/tree-sitter/tree-sitter-rust.wasm +0 -0
  16. package/resources/tree-sitter/tree-sitter-swift.wasm +0 -0
  17. package/resources/tree-sitter/tree-sitter-tsx.wasm +0 -0
  18. package/resources/tree-sitter/tree-sitter-typescript.wasm +0 -0
  19. package/resources/tree-sitter/tree-sitter.wasm +0 -0
  20. package/src/backend/agent/claude-code-watcher.js +270 -0
  21. package/src/backend/index.js +8 -0
  22. package/src/backend/lib/sha256-file.js +39 -0
  23. package/src/backend/lib/zip-entries.js +98 -0
  24. package/src/backend/lifecycle.js +102 -0
  25. package/src/backend/mcp/binding-headers.js +54 -0
  26. package/src/backend/mcp/client-identity.js +44 -0
  27. package/src/backend/mcp/connector/command.js +110 -0
  28. package/src/backend/mcp/connector/core.js +278 -0
  29. package/src/backend/mcp/connector/files.js +121 -0
  30. package/src/backend/mcp/connector/hook.js +284 -0
  31. package/src/backend/mcp/connector/main.js +126 -0
  32. package/src/backend/mcp/connector/sse-upstream.js +152 -0
  33. package/src/backend/mcp/helpers.js +43 -0
  34. package/src/backend/mcp/prompt-builders.js +104 -0
  35. package/src/backend/mcp/resources.js +197 -0
  36. package/src/backend/mcp/server.js +813 -0
  37. package/src/backend/mcp/skill-guide.js +1528 -0
  38. package/src/backend/mcp/tools/architecture-tools.js +273 -0
  39. package/src/backend/mcp/tools/audio-tools.js +117 -0
  40. package/src/backend/mcp/tools/awareness-tools.js +623 -0
  41. package/src/backend/mcp/tools/budget-tools.js +185 -0
  42. package/src/backend/mcp/tools/channel-tools.js +205 -0
  43. package/src/backend/mcp/tools/contribution-tools.js +181 -0
  44. package/src/backend/mcp/tools/drift-tools.js +252 -0
  45. package/src/backend/mcp/tools/git-tools.js +316 -0
  46. package/src/backend/mcp/tools/governance-tools.js +175 -0
  47. package/src/backend/mcp/tools/graph-tools.js +181 -0
  48. package/src/backend/mcp/tools/intake-tools.js +244 -0
  49. package/src/backend/mcp/tools/mobile-tools.js +118 -0
  50. package/src/backend/mcp/tools/peer-tools.js +330 -0
  51. package/src/backend/mcp/tools/plan-item-tools.js +1601 -0
  52. package/src/backend/mcp/tools/plan-tools.js +680 -0
  53. package/src/backend/mcp/tools/presence-tools.js +185 -0
  54. package/src/backend/mcp/tools/project-config-tools.js +150 -0
  55. package/src/backend/mcp/tools/review-tools.js +172 -0
  56. package/src/backend/mcp/tools/session-tools.js +554 -0
  57. package/src/backend/mcp/tools/system-docs-tools.js +168 -0
  58. package/src/backend/mcp/tools/terminal-tools.js +186 -0
  59. package/src/backend/mcp/tools/test-tools.js +117 -0
  60. package/src/backend/mcp/tools/ui-tools.js +356 -0
  61. package/src/backend/mcp/types.js +15 -0
  62. package/src/backend/middleware/local-auth.js +116 -0
  63. package/src/backend/server.js +5951 -0
  64. package/src/backend/services/agent-event-log.js +350 -0
  65. package/src/backend/services/architecture-rule.js +584 -0
  66. package/src/backend/services/architecture-rules.js +275 -0
  67. package/src/backend/services/artefact-content-service.js +181 -0
  68. package/src/backend/services/artefact-service.js +305 -0
  69. package/src/backend/services/artefact-watcher.js +167 -0
  70. package/src/backend/services/ast-parser.js +327 -0
  71. package/src/backend/services/audio-buffer-service.js +152 -0
  72. package/src/backend/services/awareness-notices.js +139 -0
  73. package/src/backend/services/awareness-replies.js +194 -0
  74. package/src/backend/services/awareness-service.js +344 -0
  75. package/src/backend/services/awareness-signals.js +267 -0
  76. package/src/backend/services/baseline-store.js +83 -0
  77. package/src/backend/services/branch-workstreams.js +341 -0
  78. package/src/backend/services/breakpoint-service.js +584 -0
  79. package/src/backend/services/brief-service.js +299 -0
  80. package/src/backend/services/budget-service.js +528 -0
  81. package/src/backend/services/callsites/base.js +15 -0
  82. package/src/backend/services/callsites/csharp.js +148 -0
  83. package/src/backend/services/callsites/go.js +163 -0
  84. package/src/backend/services/callsites/index.js +53 -0
  85. package/src/backend/services/callsites/kotlin.js +123 -0
  86. package/src/backend/services/callsites/process-env.js +125 -0
  87. package/src/backend/services/callsites/python.js +91 -0
  88. package/src/backend/services/callsites/ruby.js +164 -0
  89. package/src/backend/services/callsites/shared.js +198 -0
  90. package/src/backend/services/callsites/swift.js +115 -0
  91. package/src/backend/services/callsites/typescript.js +87 -0
  92. package/src/backend/services/capability-token.js +108 -0
  93. package/src/backend/services/change-check.js +156 -0
  94. package/src/backend/services/channel-dispatcher-service.js +235 -0
  95. package/src/backend/services/channel-event-file-service.js +125 -0
  96. package/src/backend/services/channel-event-service.js +297 -0
  97. package/src/backend/services/check-runs.js +177 -0
  98. package/src/backend/services/checkout-identity.js +73 -0
  99. package/src/backend/services/claude-code-parallel.js +221 -0
  100. package/src/backend/services/claude-desktop-config.js +186 -0
  101. package/src/backend/services/cli-install.js +249 -0
  102. package/src/backend/services/clock.js +57 -0
  103. package/src/backend/services/cloud-files.js +191 -0
  104. package/src/backend/services/coalesce.js +50 -0
  105. package/src/backend/services/code-breakpoints.js +291 -0
  106. package/src/backend/services/comment-service.js +168 -0
  107. package/src/backend/services/commit-attribution.js +134 -0
  108. package/src/backend/services/commit-edges.js +99 -0
  109. package/src/backend/services/confined-fs.js +241 -0
  110. package/src/backend/services/conformity-gate.js +132 -0
  111. package/src/backend/services/contribution-service.js +409 -0
  112. package/src/backend/services/coverage-service.js +173 -0
  113. package/src/backend/services/criteria-service.js +721 -0
  114. package/src/backend/services/criterion-checks.js +387 -0
  115. package/src/backend/services/criterion-loop-service.js +411 -0
  116. package/src/backend/services/cross-system-service.js +231 -0
  117. package/src/backend/services/database.js +916 -0
  118. package/src/backend/services/db-schema.js +1358 -0
  119. package/src/backend/services/deviation-service.js +344 -0
  120. package/src/backend/services/diff-engine.js +168 -0
  121. package/src/backend/services/evidence.js +363 -0
  122. package/src/backend/services/external-intake-service.js +269 -0
  123. package/src/backend/services/external-pointer-service.js +195 -0
  124. package/src/backend/services/external-refs-service.js +214 -0
  125. package/src/backend/services/file-history.js +158 -0
  126. package/src/backend/services/file-watcher.js +193 -0
  127. package/src/backend/services/folder-requests.js +118 -0
  128. package/src/backend/services/freeze-service.js +189 -0
  129. package/src/backend/services/gemini-cli-hook.js +172 -0
  130. package/src/backend/services/git-activity-service.js +325 -0
  131. package/src/backend/services/git-blobs.js +70 -0
  132. package/src/backend/services/git-branches.js +357 -0
  133. package/src/backend/services/git-checkout.js +153 -0
  134. package/src/backend/services/git-commit-service.js +91 -0
  135. package/src/backend/services/git-env.js +121 -0
  136. package/src/backend/services/git-identity.js +84 -0
  137. package/src/backend/services/git-refs.js +386 -0
  138. package/src/backend/services/git-safety.js +58 -0
  139. package/src/backend/services/grant-guard.js +67 -0
  140. package/src/backend/services/html-view-policy.js +135 -0
  141. package/src/backend/services/human-decision.js +55 -0
  142. package/src/backend/services/importers.js +159 -0
  143. package/src/backend/services/intent-service.js +105 -0
  144. package/src/backend/services/ipc-dispatcher.js +164 -0
  145. package/src/backend/services/item-git-state.js +208 -0
  146. package/src/backend/services/line-changes.js +232 -0
  147. package/src/backend/services/line-history.js +174 -0
  148. package/src/backend/services/local-api-changes.js +40 -0
  149. package/src/backend/services/logger.js +217 -0
  150. package/src/backend/services/material-footprints.js +203 -0
  151. package/src/backend/services/material-place.js +82 -0
  152. package/src/backend/services/material-reader/docx-markdown.js +198 -0
  153. package/src/backend/services/material-reader/fixtures.test-helper.js +169 -0
  154. package/src/backend/services/material-reader/quote.js +44 -0
  155. package/src/backend/services/material-reader/reader-host.js +202 -0
  156. package/src/backend/services/material-signals.js +141 -0
  157. package/src/backend/services/mcp-capabilities.js +390 -0
  158. package/src/backend/services/mdns-service.js +304 -0
  159. package/src/backend/services/mobile-api-server.js +281 -0
  160. package/src/backend/services/mobile-approvals.js +306 -0
  161. package/src/backend/services/mobile-awareness.js +180 -0
  162. package/src/backend/services/mobile-breakpoints.js +115 -0
  163. package/src/backend/services/mobile-budget.js +98 -0
  164. package/src/backend/services/mobile-freeze.js +106 -0
  165. package/src/backend/services/mobile-proposals.js +100 -0
  166. package/src/backend/services/mobile-rpc-service.js +1289 -0
  167. package/src/backend/services/mobile-workstreams.js +160 -0
  168. package/src/backend/services/monorepo-detector.js +131 -0
  169. package/src/backend/services/other-work.js +45 -0
  170. package/src/backend/services/pack-seal.js +129 -0
  171. package/src/backend/services/paired-device-service.js +192 -0
  172. package/src/backend/services/pairing-server.js +323 -0
  173. package/src/backend/services/pairing-service.js +200 -0
  174. package/src/backend/services/pantry-resolution-service.js +166 -0
  175. package/src/backend/services/parsers/base.js +124 -0
  176. package/src/backend/services/parsers/csharp.js +224 -0
  177. package/src/backend/services/parsers/go.js +180 -0
  178. package/src/backend/services/parsers/index.js +101 -0
  179. package/src/backend/services/parsers/java.js +103 -0
  180. package/src/backend/services/parsers/kotlin.js +252 -0
  181. package/src/backend/services/parsers/php.js +113 -0
  182. package/src/backend/services/parsers/python.js +189 -0
  183. package/src/backend/services/parsers/ruby.js +212 -0
  184. package/src/backend/services/parsers/rust.js +97 -0
  185. package/src/backend/services/parsers/swift.js +221 -0
  186. package/src/backend/services/parsers/typescript.js +235 -0
  187. package/src/backend/services/pattern-scan.js +65 -0
  188. package/src/backend/services/patterns.js +281 -0
  189. package/src/backend/services/peer-audit-service.js +123 -0
  190. package/src/backend/services/peer-auth.js +153 -0
  191. package/src/backend/services/peer-capabilities.js +209 -0
  192. package/src/backend/services/peer-connection-service.js +450 -0
  193. package/src/backend/services/peer-grants.js +33 -0
  194. package/src/backend/services/persistence.js +116 -0
  195. package/src/backend/services/personal-sync-service.js +232 -0
  196. package/src/backend/services/pipeline-approvals.js +72 -0
  197. package/src/backend/services/pipeline.js +232 -0
  198. package/src/backend/services/plan-arrivals.js +68 -0
  199. package/src/backend/services/plan-changes-service.js +273 -0
  200. package/src/backend/services/plan-conflict-service.js +288 -0
  201. package/src/backend/services/plan-dependencies.js +91 -0
  202. package/src/backend/services/plan-doc-guard.js +90 -0
  203. package/src/backend/services/plan-documents-service.js +275 -0
  204. package/src/backend/services/plan-event-service.js +154 -0
  205. package/src/backend/services/plan-file-refs.js +106 -0
  206. package/src/backend/services/plan-file-service.js +1564 -0
  207. package/src/backend/services/plan-history-service.js +156 -0
  208. package/src/backend/services/plan-import-service.js +261 -0
  209. package/src/backend/services/plan-item-service.js +1223 -0
  210. package/src/backend/services/plan-migrate-service.js +395 -0
  211. package/src/backend/services/plan-overlay-service.js +173 -0
  212. package/src/backend/services/plan-phases-service.js +182 -0
  213. package/src/backend/services/plan-progress-service.js +134 -0
  214. package/src/backend/services/plan-review-service.js +262 -0
  215. package/src/backend/services/plan-service.js +682 -0
  216. package/src/backend/services/plan-status.js +113 -0
  217. package/src/backend/services/plan-template-publish-service.js +217 -0
  218. package/src/backend/services/plan-templates-service.js +242 -0
  219. package/src/backend/services/plan-templates.js +1164 -0
  220. package/src/backend/services/planned-overlap-actions.js +200 -0
  221. package/src/backend/services/plans-home.js +224 -0
  222. package/src/backend/services/play-forward.js +256 -0
  223. package/src/backend/services/playback-service.js +117 -0
  224. package/src/backend/services/power-service.js +167 -0
  225. package/src/backend/services/power-signals.js +81 -0
  226. package/src/backend/services/pr-draft-service.js +142 -0
  227. package/src/backend/services/presence-service.js +122 -0
  228. package/src/backend/services/pricing.js +60 -0
  229. package/src/backend/services/project-config-service.js +474 -0
  230. package/src/backend/services/project-scanner.js +184 -0
  231. package/src/backend/services/projection-service.js +69 -0
  232. package/src/backend/services/push-notification-service.js +288 -0
  233. package/src/backend/services/recent-projects-service.js +204 -0
  234. package/src/backend/services/record-chain.js +162 -0
  235. package/src/backend/services/recurrence-rule.js +63 -0
  236. package/src/backend/services/recurring-agent.js +89 -0
  237. package/src/backend/services/recurring-scheduler.js +77 -0
  238. package/src/backend/services/recurring-service.js +276 -0
  239. package/src/backend/services/reference-service.js +169 -0
  240. package/src/backend/services/release-public-key.js +30 -0
  241. package/src/backend/services/release-signature.js +64 -0
  242. package/src/backend/services/remote-audio-service.js +224 -0
  243. package/src/backend/services/remote-interaction-service.js +275 -0
  244. package/src/backend/services/remote-terminal-service.js +324 -0
  245. package/src/backend/services/rendition/child/main.js +76 -0
  246. package/src/backend/services/rendition/engine-host.js +249 -0
  247. package/src/backend/services/rendition/engine-lock.js +39 -0
  248. package/src/backend/services/rendition/engine-lock.json +14 -0
  249. package/src/backend/services/rendition/engine-manifest.js +97 -0
  250. package/src/backend/services/rendition/network-proof.js +73 -0
  251. package/src/backend/services/rendition/rendition-service.js +175 -0
  252. package/src/backend/services/replay-frames.js +387 -0
  253. package/src/backend/services/replay-state.js +201 -0
  254. package/src/backend/services/resolvers/base.js +108 -0
  255. package/src/backend/services/resolvers/csharp.js +109 -0
  256. package/src/backend/services/resolvers/go.js +105 -0
  257. package/src/backend/services/resolvers/index.js +60 -0
  258. package/src/backend/services/resolvers/java.js +63 -0
  259. package/src/backend/services/resolvers/kotlin.js +109 -0
  260. package/src/backend/services/resolvers/php.js +89 -0
  261. package/src/backend/services/resolvers/python.js +154 -0
  262. package/src/backend/services/resolvers/ruby.js +103 -0
  263. package/src/backend/services/resolvers/rust.js +77 -0
  264. package/src/backend/services/resolvers/swift.js +98 -0
  265. package/src/backend/services/resolvers/typescript.js +71 -0
  266. package/src/backend/services/retention.js +54 -0
  267. package/src/backend/services/review-architecture.js +236 -0
  268. package/src/backend/services/review-attest.js +68 -0
  269. package/src/backend/services/review-bundle.js +226 -0
  270. package/src/backend/services/review-graduation.js +93 -0
  271. package/src/backend/services/review-host/bitbucket.js +79 -0
  272. package/src/backend/services/review-host/detect.js +80 -0
  273. package/src/backend/services/review-host/github.js +97 -0
  274. package/src/backend/services/review-host/gitlab.js +77 -0
  275. package/src/backend/services/review-host/host-state.js +103 -0
  276. package/src/backend/services/review-host/http.js +58 -0
  277. package/src/backend/services/review-host/switch.js +120 -0
  278. package/src/backend/services/review-marks.js +72 -0
  279. package/src/backend/services/review-notes.js +169 -0
  280. package/src/backend/services/review-other-work.js +90 -0
  281. package/src/backend/services/review-queue-service.js +147 -0
  282. package/src/backend/services/review-risk.js +127 -0
  283. package/src/backend/services/review-task.js +121 -0
  284. package/src/backend/services/rule-approvals.js +275 -0
  285. package/src/backend/services/rule-baseline.js +134 -0
  286. package/src/backend/services/rule-changes.js +162 -0
  287. package/src/backend/services/rule-preview.js +47 -0
  288. package/src/backend/services/rule-proposals.js +104 -0
  289. package/src/backend/services/rule-scope.js +76 -0
  290. package/src/backend/services/rulebook.js +286 -0
  291. package/src/backend/services/rules-at.js +56 -0
  292. package/src/backend/services/rules-overview.js +88 -0
  293. package/src/backend/services/schema-reconciler.js +250 -0
  294. package/src/backend/services/secret-store.js +119 -0
  295. package/src/backend/services/section-workstreams.js +95 -0
  296. package/src/backend/services/self-write-tracker.js +75 -0
  297. package/src/backend/services/sensor-bridge-service.js +285 -0
  298. package/src/backend/services/session-service.js +192 -0
  299. package/src/backend/services/settings-service.js +324 -0
  300. package/src/backend/services/signal-breakpoints.js +172 -0
  301. package/src/backend/services/signed-approval-record.js +86 -0
  302. package/src/backend/services/signed-approvals.js +244 -0
  303. package/src/backend/services/signoff-pack.js +328 -0
  304. package/src/backend/services/signoff-rows.js +114 -0
  305. package/src/backend/services/skill-arrival-service.js +138 -0
  306. package/src/backend/services/skill-model.js +193 -0
  307. package/src/backend/services/skill-use-service.js +140 -0
  308. package/src/backend/services/skills-service.js +150 -0
  309. package/src/backend/services/snapshot-compare-service.js +397 -0
  310. package/src/backend/services/source-control.js +189 -0
  311. package/src/backend/services/spec-links-service.js +123 -0
  312. package/src/backend/services/spec-proposal-withdraw.js +50 -0
  313. package/src/backend/services/spec-proposals-service.js +470 -0
  314. package/src/backend/services/sql/embedded.js +95 -0
  315. package/src/backend/services/sql/index.js +63 -0
  316. package/src/backend/services/sql/refs.js +357 -0
  317. package/src/backend/services/sql/schema.js +312 -0
  318. package/src/backend/services/sql/tokenizer.js +195 -0
  319. package/src/backend/services/stack-overlaps.js +117 -0
  320. package/src/backend/services/stack-service.js +225 -0
  321. package/src/backend/services/state-sync-service.js +384 -0
  322. package/src/backend/services/stuck-sensor-service.js +200 -0
  323. package/src/backend/services/system-discovery.js +481 -0
  324. package/src/backend/services/system-docs-service.js +701 -0
  325. package/src/backend/services/task-attachments-service.js +340 -0
  326. package/src/backend/services/task-grounding.js +60 -0
  327. package/src/backend/services/task-records/check-run-record.js +146 -0
  328. package/src/backend/services/task-records/check-runs.js +115 -0
  329. package/src/backend/services/task-records/heads.js +88 -0
  330. package/src/backend/services/task-records/material-reads.js +225 -0
  331. package/src/backend/services/task-records/read-record.js +100 -0
  332. package/src/backend/services/task-records/record.js +173 -0
  333. package/src/backend/services/task-records/run-record.js +136 -0
  334. package/src/backend/services/task-records/shared-state.js +548 -0
  335. package/src/backend/services/task-records/signing.js +140 -0
  336. package/src/backend/services/task-records/split-signals.js +52 -0
  337. package/src/backend/services/task-records/test-runs.js +164 -0
  338. package/src/backend/services/task-records/trust.js +243 -0
  339. package/src/backend/services/task-rules.js +81 -0
  340. package/src/backend/services/task-workstreams.js +90 -0
  341. package/src/backend/services/terminal-history-service.js +266 -0
  342. package/src/backend/services/terminal-service.js +267 -0
  343. package/src/backend/services/test-clock.js +53 -0
  344. package/src/backend/services/tests/grounding.js +266 -0
  345. package/src/backend/services/tests/junit.js +104 -0
  346. package/src/backend/services/tests/teammate-runs.js +134 -0
  347. package/src/backend/services/tests/test-results.js +234 -0
  348. package/src/backend/services/tree-watcher.js +204 -0
  349. package/src/backend/services/trellis-service.js +204 -0
  350. package/src/backend/services/trusted-roots.js +186 -0
  351. package/src/backend/services/update-download-service.js +342 -0
  352. package/src/backend/services/update-service.js +266 -0
  353. package/src/backend/services/watch-ignore.js +76 -0
  354. package/src/backend/services/webhook-egress.js +206 -0
  355. package/src/backend/services/webrtc-service.js +413 -0
  356. package/src/backend/services/work-changes.js +59 -0
  357. package/src/backend/services/workstream-binding.js +82 -0
  358. package/src/backend/services/workstream-commits.js +116 -0
  359. package/src/backend/services/workstream-imports.js +177 -0
  360. package/src/backend/services/workstream-service.js +335 -0
  361. package/src/backend/services/workstream-symbols.js +223 -0
  362. package/src/backend/services/workstream-watch-service.js +391 -0
  363. package/src/backend/services/worktree-service.js +235 -0
  364. package/src/cli/agent.js +100 -0
  365. package/src/cli/args.js +209 -0
  366. package/src/cli/conformity.js +106 -0
  367. package/src/cli/desktop.js +91 -0
  368. package/src/cli/main.js +411 -0
  369. package/src/cli/pipeline.js +109 -0
  370. package/src/cli/plan-verbs.js +259 -0
  371. package/src/cli/review-adapters.js +220 -0
  372. package/src/cli/review-output.js +93 -0
  373. package/src/cli/review-post.js +89 -0
  374. package/src/cli/review-sink.js +183 -0
  375. package/src/cli/review-skill.js +44 -0
  376. package/src/cli/review-verify.js +104 -0
  377. package/src/cli/review.js +386 -0
  378. package/src/cli/sarif.js +148 -0
  379. package/src/cli/verbs.js +360 -0
  380. package/src/shared/build-info.js +39 -0
  381. package/src/shared/lib/agent-review.js +199 -0
  382. package/src/shared/lib/agent-turns.js +140 -0
  383. package/src/shared/lib/awareness-digest.js +120 -0
  384. package/src/shared/lib/branch-name.js +45 -0
  385. package/src/shared/lib/breakpoint-words.js +118 -0
  386. package/src/shared/lib/budget-words.js +56 -0
  387. package/src/shared/lib/burst.js +69 -0
  388. package/src/shared/lib/call-entry.js +105 -0
  389. package/src/shared/lib/check-compare.js +42 -0
  390. package/src/shared/lib/check-words.js +216 -0
  391. package/src/shared/lib/csv.js +62 -0
  392. package/src/shared/lib/folder-entry.js +87 -0
  393. package/src/shared/lib/freeze-words.js +60 -0
  394. package/src/shared/lib/fuzzy.js +84 -0
  395. package/src/shared/lib/git-state-words.js +80 -0
  396. package/src/shared/lib/grep-entry.js +86 -0
  397. package/src/shared/lib/grounding-line.js +61 -0
  398. package/src/shared/lib/import-line.js +71 -0
  399. package/src/shared/lib/item-status.js +249 -0
  400. package/src/shared/lib/line-changes.js +53 -0
  401. package/src/shared/lib/locator.js +71 -0
  402. package/src/shared/lib/matcher.js +120 -0
  403. package/src/shared/lib/merge-order.js +65 -0
  404. package/src/shared/lib/open-findings.js +68 -0
  405. package/src/shared/lib/other-work.js +108 -0
  406. package/src/shared/lib/package-entry.js +142 -0
  407. package/src/shared/lib/plan-vocab.js +40 -0
  408. package/src/shared/lib/pptx-xml.js +86 -0
  409. package/src/shared/lib/proposal-words.js +61 -0
  410. package/src/shared/lib/recurrence.js +183 -0
  411. package/src/shared/lib/references.js +72 -0
  412. package/src/shared/lib/rule-pattern.js +56 -0
  413. package/src/shared/lib/sdp-fingerprint.js +115 -0
  414. package/src/shared/lib/sdp-minimal.js +123 -0
  415. package/src/shared/lib/secret-paths.js +34 -0
  416. package/src/shared/lib/signal-words.js +172 -0
  417. package/src/shared/lib/signoff.js +56 -0
  418. package/src/shared/lib/skills-note.js +60 -0
  419. package/src/shared/lib/spec-sections.js +78 -0
  420. package/src/shared/lib/symbol-entry.js +60 -0
  421. package/src/shared/lib/tool-phrasing.js +338 -0
  422. package/src/shared/lib/turn-gap.js +27 -0
  423. package/src/shared/lib/workstream-words.js +38 -0
  424. package/src/shared/lib/xlsx-xml.js +144 -0
  425. package/src/shared/lib/zip-reader.js +99 -0
  426. package/src/shared/types/agent.js +27 -0
  427. package/src/shared/types/architecture-rules.js +30 -0
  428. package/src/shared/types/ast.js +15 -0
  429. package/src/shared/types/breakpoint.js +33 -0
  430. package/src/shared/types/channel.js +41 -0
  431. package/src/shared/types/criteria.js +15 -0
  432. package/src/shared/types/graph.js +15 -0
  433. package/src/shared/types/index.js +53 -0
  434. package/src/shared/types/peer.js +36 -0
  435. package/src/shared/types/pipeline.js +15 -0
  436. package/src/shared/types/plan.js +15 -0
  437. package/src/shared/types/play-forward.js +15 -0
  438. package/src/shared/types/power.js +15 -0
  439. package/src/shared/types/presence.js +15 -0
  440. package/src/shared/types/project-config.js +35 -0
  441. package/src/shared/types/project.js +15 -0
  442. package/src/shared/types/record.js +15 -0
  443. package/src/shared/types/recurring.js +15 -0
  444. package/src/shared/types/review.js +15 -0
  445. package/src/shared/types/settings.js +114 -0
  446. package/src/shared/types/stack.js +15 -0
  447. package/src/shared/types/system-doc.js +15 -0
  448. package/src/shared/types/system.js +15 -0
@@ -0,0 +1,474 @@
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 project_config_service_exports = {};
29
+ __export(project_config_service_exports, {
30
+ getEffectiveAttachmentLocation: () => getEffectiveAttachmentLocation,
31
+ getEffectiveDefaultVisibility: () => getEffectiveDefaultVisibility,
32
+ getEffectiveSensorConfig: () => getEffectiveSensorConfig,
33
+ getProjectConfig: () => getProjectConfig,
34
+ invalidateProjectConfigCache: () => invalidateProjectConfigCache,
35
+ listChannelRoutingRules: () => listChannelRoutingRules,
36
+ matchChannelRoutingRules: () => matchChannelRoutingRules,
37
+ parsePlansFolderRef: () => parsePlansFolderRef,
38
+ resetProjectConfigCache: () => resetProjectConfigCache,
39
+ startProjectConfigWatcher: () => startProjectConfigWatcher,
40
+ stopProjectConfigWatcher: () => stopProjectConfigWatcher,
41
+ updateProjectConfig: () => updateProjectConfig
42
+ });
43
+ module.exports = __toCommonJS(project_config_service_exports);
44
+ var import_node_fs = __toESM(require("node:fs"));
45
+ var import_node_path = __toESM(require("node:path"));
46
+ var import_chokidar = __toESM(require("chokidar"));
47
+ var import_types = require("../../shared/types");
48
+ var import_settings_service = require("./settings-service");
49
+ var import_recurrence_rule = require("./recurrence-rule");
50
+ var import_architecture_rule = require("./architecture-rule");
51
+ const CONFIG_DIR = ".codetrellis";
52
+ const CONFIG_FILE = "config.json";
53
+ const cache = /* @__PURE__ */ new Map();
54
+ function configPath(projectRoot) {
55
+ return import_node_path.default.join(projectRoot, CONFIG_DIR, CONFIG_FILE);
56
+ }
57
+ function normaliseProjectRoot(projectRoot) {
58
+ return import_node_path.default.resolve(projectRoot);
59
+ }
60
+ function getProjectConfig(projectRoot) {
61
+ const key = normaliseProjectRoot(projectRoot);
62
+ const cached = cache.get(key);
63
+ if (cached) return cached;
64
+ const filePath = configPath(key);
65
+ if (!import_node_fs.default.existsSync(filePath)) {
66
+ cache.set(key, import_types.EMPTY_PROJECT_CONFIG);
67
+ return import_types.EMPTY_PROJECT_CONFIG;
68
+ }
69
+ try {
70
+ const raw = JSON.parse(import_node_fs.default.readFileSync(filePath, "utf-8"));
71
+ const parsed = parseProjectConfig(raw);
72
+ cache.set(key, parsed);
73
+ return parsed;
74
+ } catch (err) {
75
+ console.warn(`[ProjectConfig] Failed to read ${filePath} \u2014 falling back to empty config:`, err);
76
+ cache.set(key, import_types.EMPTY_PROJECT_CONFIG);
77
+ return import_types.EMPTY_PROJECT_CONFIG;
78
+ }
79
+ }
80
+ function parsePlansFolderRef(raw) {
81
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
82
+ const r = raw;
83
+ if (r.kind === "git") {
84
+ const remote = typeof r.remote === "string" ? r.remote.trim() : "";
85
+ if (!remote || remote.length > 400 || /\s/.test(remote)) return null;
86
+ if (/^[a-z][a-z0-9+.-]*:\/\/[^/@]*:[^/@]*@/i.test(remote)) return null;
87
+ return { kind: "git", remote };
88
+ }
89
+ if (r.kind === "synced") {
90
+ const provider = r.provider === "onedrive" || r.provider === "sharepoint" || r.provider === "folder" ? r.provider : null;
91
+ const place = typeof r.place === "string" ? r.place.trim().replace(/\\/g, "/").replace(/^\/+|\/+$/g, "") : "";
92
+ if (!provider || !place || place.length > 512) return null;
93
+ if (/^[a-z]:/i.test(place) || place.split("/").some((seg) => seg === "" || seg === "." || seg === "..")) return null;
94
+ return { kind: "synced", provider, place };
95
+ }
96
+ return null;
97
+ }
98
+ function updateProjectConfig(projectRoot, patch) {
99
+ const key = normaliseProjectRoot(projectRoot);
100
+ const current = getProjectConfig(key);
101
+ const next = {
102
+ plans: { ...current.plans ?? {}, ...patch.plans ?? {} },
103
+ channels: {
104
+ ...current.channels ?? {},
105
+ ...patch.channels ?? {},
106
+ // Routing rules replaced wholesale when present.
107
+ ...patch.channels?.routing !== void 0 ? { routing: patch.channels.routing } : {}
108
+ },
109
+ // Phase 4.1 — sensors: deep-merge per-sensor group.
110
+ sensors: mergeSensorConfig(current.sensors, patch.sensors),
111
+ // Phase 3.6 — repoRole is a flat scalar; patch wins when present.
112
+ repoRole: patch.repoRole !== void 0 ? patch.repoRole : current.repoRole,
113
+ // Phase 31 §10.1 — also a flat scalar.
114
+ defaultSurface: patch.defaultSurface !== void 0 ? patch.defaultSurface : current.defaultSurface,
115
+ // Phase 6.5 — freeze periods: replace wholesale when present.
116
+ freeze: patch.freeze !== void 0 ? patch.freeze : current.freeze,
117
+ // Phase 32 C4 — recurring playbooks: replaced wholesale, like routing.
118
+ recurring: patch.recurring !== void 0 ? patch.recurring : current.recurring,
119
+ // Phase 32 A7 — architecture rules: replaced wholesale, like recurring.
120
+ rules: patch.rules !== void 0 ? patch.rules : current.rules,
121
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
122
+ };
123
+ if (next.plans) {
124
+ for (const k of Object.keys(next.plans)) {
125
+ if (next.plans[k] === void 0) delete next.plans[k];
126
+ }
127
+ }
128
+ if (next.plans && Object.keys(next.plans).length === 0) {
129
+ delete next.plans;
130
+ }
131
+ if (next.channels && Object.keys(next.channels).length === 0) {
132
+ delete next.channels;
133
+ }
134
+ if (next.sensors && Object.keys(next.sensors).length === 0) {
135
+ delete next.sensors;
136
+ }
137
+ if (next.freeze && !next.freeze.active && !next.freeze.reason) {
138
+ delete next.freeze;
139
+ }
140
+ if (next.repoRole === void 0 || next.repoRole === "mixed") {
141
+ delete next.repoRole;
142
+ }
143
+ if (!next.recurring || next.recurring.length === 0) delete next.recurring;
144
+ if (!next.rules || next.rules.length === 0) delete next.rules;
145
+ if (next.defaultSurface === void 0 || next.defaultSurface === "graph") {
146
+ delete next.defaultSurface;
147
+ }
148
+ saveProjectConfig(key, next);
149
+ cache.set(key, next);
150
+ return next;
151
+ }
152
+ function invalidateProjectConfigCache(projectRoot) {
153
+ if (projectRoot) {
154
+ cache.delete(normaliseProjectRoot(projectRoot));
155
+ } else {
156
+ cache.clear();
157
+ }
158
+ }
159
+ function resetProjectConfigCache() {
160
+ cache.clear();
161
+ }
162
+ function getEffectiveDefaultVisibility(projectRoot) {
163
+ const projectOverride = getProjectConfig(projectRoot).plans?.defaultVisibility;
164
+ return projectOverride ?? (0, import_settings_service.getSettings)().plans.defaultVisibility;
165
+ }
166
+ function getEffectiveAttachmentLocation(projectRoot) {
167
+ const projectOverride = getProjectConfig(projectRoot).plans?.attachmentLocation;
168
+ return projectOverride ?? (0, import_settings_service.getSettings)().plans.attachmentLocation;
169
+ }
170
+ function listChannelRoutingRules(projectRoot) {
171
+ const cfg = getProjectConfig(projectRoot);
172
+ const rules = cfg.channels?.routing ?? [];
173
+ return rules.filter((r) => r.enabled !== false);
174
+ }
175
+ function matchChannelRoutingRules(projectRoot, event) {
176
+ const rules = listChannelRoutingRules(projectRoot);
177
+ return rules.filter((r) => matches(r.when, event));
178
+ }
179
+ function matches(when, event) {
180
+ if (when.eventType && when.eventType !== event.eventType) return false;
181
+ if (when.status && when.status !== event.status) return false;
182
+ if (when.planUid && when.planUid !== event.planUid) return false;
183
+ if (when.itemUid && when.itemUid !== event.itemUid) return false;
184
+ return true;
185
+ }
186
+ function mergeSensorConfig(current, patch) {
187
+ if (!patch) return current;
188
+ if (!current) return patch;
189
+ const merged = {};
190
+ if (current.drift || patch.drift) {
191
+ merged.drift = { ...current.drift ?? {}, ...patch.drift ?? {} };
192
+ }
193
+ if (current.docs || patch.docs) {
194
+ merged.docs = { ...current.docs ?? {}, ...patch.docs ?? {} };
195
+ }
196
+ if (current.stuck || patch.stuck) {
197
+ merged.stuck = { ...current.stuck ?? {}, ...patch.stuck ?? {} };
198
+ }
199
+ if (current.awareness || patch.awareness) {
200
+ merged.awareness = { ...current.awareness ?? {}, ...patch.awareness ?? {} };
201
+ }
202
+ if (merged.drift && Object.keys(merged.drift).length === 0) delete merged.drift;
203
+ if (merged.docs && Object.keys(merged.docs).length === 0) delete merged.docs;
204
+ if (merged.stuck && Object.keys(merged.stuck).length === 0) delete merged.stuck;
205
+ if (merged.awareness && Object.keys(merged.awareness).length === 0) delete merged.awareness;
206
+ return Object.keys(merged).length > 0 ? merged : void 0;
207
+ }
208
+ function getEffectiveSensorConfig(projectRoot) {
209
+ const cfg = getProjectConfig(projectRoot).sensors;
210
+ return {
211
+ drift: {
212
+ enabled: cfg?.drift?.enabled ?? import_types.SENSOR_DEFAULTS.drift.enabled,
213
+ channelEvents: cfg?.drift?.channelEvents ?? import_types.SENSOR_DEFAULTS.drift.channelEvents,
214
+ debounceMs: cfg?.drift?.debounceMs ?? import_types.SENSOR_DEFAULTS.drift.debounceMs
215
+ },
216
+ docs: {
217
+ enabled: cfg?.docs?.enabled ?? import_types.SENSOR_DEFAULTS.docs.enabled,
218
+ channelEvents: cfg?.docs?.channelEvents ?? import_types.SENSOR_DEFAULTS.docs.channelEvents
219
+ },
220
+ stuck: {
221
+ enabled: cfg?.stuck?.enabled ?? import_types.SENSOR_DEFAULTS.stuck.enabled,
222
+ repetitionThreshold: cfg?.stuck?.repetitionThreshold ?? import_types.SENSOR_DEFAULTS.stuck.repetitionThreshold,
223
+ errorLoopThreshold: cfg?.stuck?.errorLoopThreshold ?? import_types.SENSOR_DEFAULTS.stuck.errorLoopThreshold,
224
+ idleMinutes: cfg?.stuck?.idleMinutes ?? import_types.SENSOR_DEFAULTS.stuck.idleMinutes
225
+ },
226
+ awareness: {
227
+ branchWindowDays: validDays(cfg?.awareness?.branchWindowDays) ?? import_types.SENSOR_DEFAULTS.awareness.branchWindowDays,
228
+ // Only an explicit false turns them off: a hand-edited value that is not a boolean keeps the default.
229
+ inlineNotices: cfg?.awareness?.inlineNotices === false ? false : import_types.SENSOR_DEFAULTS.awareness.inlineNotices,
230
+ // Opt-in: only an explicit true holds sign-off.
231
+ holdSignOffOnHighSignals: cfg?.awareness?.holdSignOffOnHighSignals === true
232
+ }
233
+ };
234
+ }
235
+ function validDays(v) {
236
+ return typeof v === "number" && Number.isFinite(v) && v > 0 ? v : void 0;
237
+ }
238
+ const watchersByProject = /* @__PURE__ */ new Map();
239
+ function startProjectConfigWatcher(projectRoot) {
240
+ const key = normaliseProjectRoot(projectRoot);
241
+ if (watchersByProject.has(key)) return;
242
+ const filePath = configPath(key);
243
+ const dir = import_node_path.default.dirname(filePath);
244
+ try {
245
+ import_node_fs.default.mkdirSync(dir, { recursive: true });
246
+ } catch (err) {
247
+ console.warn(`[ProjectConfig] Could not pre-create ${dir}:`, err);
248
+ }
249
+ const watcher = import_chokidar.default.watch(dir, {
250
+ ignoreInitial: true,
251
+ persistent: true,
252
+ depth: 0,
253
+ // only watch the .codetrellis/ root, not subdirectories
254
+ awaitWriteFinish: { stabilityThreshold: 100, pollInterval: 50 }
255
+ });
256
+ watcher.on("all", (event, changedPath) => {
257
+ if (!changedPath) return;
258
+ if (import_node_path.default.basename(changedPath) !== CONFIG_FILE) return;
259
+ if (event !== "add" && event !== "change" && event !== "unlink") return;
260
+ invalidateProjectConfigCache(key);
261
+ });
262
+ watcher.on("error", (err) => {
263
+ console.warn(`[ProjectConfig] Watcher error for ${dir} (continuing):`, err);
264
+ });
265
+ watchersByProject.set(key, watcher);
266
+ }
267
+ async function stopProjectConfigWatcher(projectRoot) {
268
+ const key = normaliseProjectRoot(projectRoot);
269
+ const watcher = watchersByProject.get(key);
270
+ if (!watcher) return;
271
+ watchersByProject.delete(key);
272
+ await watcher.close();
273
+ }
274
+ function saveProjectConfig(projectRoot, config) {
275
+ const filePath = configPath(projectRoot);
276
+ try {
277
+ const dir = import_node_path.default.dirname(filePath);
278
+ if (!import_node_fs.default.existsSync(dir)) {
279
+ import_node_fs.default.mkdirSync(dir, { recursive: true });
280
+ }
281
+ const tmpPath = `${filePath}.tmp`;
282
+ import_node_fs.default.writeFileSync(tmpPath, JSON.stringify(config, null, 2));
283
+ import_node_fs.default.renameSync(tmpPath, filePath);
284
+ } catch (err) {
285
+ console.error(`[ProjectConfig] Failed to save ${filePath}:`, err);
286
+ }
287
+ }
288
+ function parseProjectConfig(raw) {
289
+ if (!raw || typeof raw !== "object") return import_types.EMPTY_PROJECT_CONFIG;
290
+ const r = raw;
291
+ const result = {};
292
+ const plansRaw = r.plans;
293
+ if (plansRaw && typeof plansRaw === "object") {
294
+ const p = plansRaw;
295
+ const plansOut = {};
296
+ if (p.defaultVisibility === "shared" || p.defaultVisibility === "local") {
297
+ plansOut.defaultVisibility = p.defaultVisibility;
298
+ }
299
+ if (p.attachmentLocation === "project" || p.attachmentLocation === "user") {
300
+ plansOut.attachmentLocation = p.attachmentLocation;
301
+ }
302
+ const folder = parsePlansFolderRef(p.folder);
303
+ if (folder) plansOut.folder = folder;
304
+ if (Object.keys(plansOut).length > 0) result.plans = plansOut;
305
+ }
306
+ const channelsRaw = r.channels;
307
+ if (channelsRaw && typeof channelsRaw === "object") {
308
+ const c = channelsRaw;
309
+ const channelsOut = {};
310
+ if (Array.isArray(c.routing)) {
311
+ const rules = [];
312
+ for (const item of c.routing) {
313
+ const rule = parseRoutingRule(item);
314
+ if (rule) rules.push(rule);
315
+ }
316
+ if (rules.length > 0) channelsOut.routing = rules;
317
+ }
318
+ if (Object.keys(channelsOut).length > 0) result.channels = channelsOut;
319
+ }
320
+ const sensorsRaw = r.sensors;
321
+ if (sensorsRaw && typeof sensorsRaw === "object") {
322
+ const s = sensorsRaw;
323
+ const sensors = parseSensorConfig(s);
324
+ if (sensors && Object.keys(sensors).length > 0) result.sensors = sensors;
325
+ }
326
+ if (r.repoRole === "planning" || r.repoRole === "code" || r.repoRole === "mixed") {
327
+ result.repoRole = r.repoRole;
328
+ }
329
+ if (r.defaultSurface === "code" || r.defaultSurface === "brief") {
330
+ result.defaultSurface = r.defaultSurface;
331
+ }
332
+ if (Array.isArray(r.recurring)) {
333
+ const rules = r.recurring.map((x) => (0, import_recurrence_rule.parseRecurrenceRule)(x).rule).filter((x) => !!x);
334
+ if (rules.length > 0) result.recurring = rules;
335
+ }
336
+ if (Array.isArray(r.rules)) {
337
+ const rules = r.rules.map((x) => (0, import_architecture_rule.parseArchitectureRule)(x).rule).filter((x) => !!x);
338
+ if (rules.length > 0) result.rules = rules;
339
+ }
340
+ const freezeRaw = r.freeze;
341
+ if (freezeRaw && typeof freezeRaw === "object") {
342
+ const f = freezeRaw;
343
+ const freeze = {
344
+ active: typeof f.active === "boolean" ? f.active : false
345
+ };
346
+ if (typeof f.reason === "string") freeze.reason = f.reason;
347
+ if (typeof f.since === "string") freeze.since = f.since;
348
+ if (typeof f.until === "string") freeze.until = f.until;
349
+ else if (f.until === null) freeze.until = null;
350
+ if (Array.isArray(f.allowedPlanUids)) {
351
+ freeze.allowedPlanUids = f.allowedPlanUids.filter((u) => typeof u === "string");
352
+ }
353
+ result.freeze = freeze;
354
+ }
355
+ if (typeof r.updatedAt === "string") {
356
+ result.updatedAt = r.updatedAt;
357
+ }
358
+ return result;
359
+ }
360
+ function parseRoutingRule(raw) {
361
+ if (!raw || typeof raw !== "object") return null;
362
+ const r = raw;
363
+ const whenRaw = r.when;
364
+ const when = {};
365
+ if (whenRaw && typeof whenRaw === "object") {
366
+ const w = whenRaw;
367
+ if (typeof w.eventType === "string" && import_types.CHANNEL_EVENT_TYPES.includes(w.eventType)) {
368
+ when.eventType = w.eventType;
369
+ }
370
+ if (typeof w.status === "string" && import_types.CHANNEL_EVENT_STATUSES.includes(w.status)) {
371
+ when.status = w.status;
372
+ }
373
+ if (typeof w.planUid === "string") when.planUid = w.planUid;
374
+ if (typeof w.itemUid === "string") when.itemUid = w.itemUid;
375
+ if (typeof w.minAgeMs === "number" && Number.isFinite(w.minAgeMs)) when.minAgeMs = w.minAgeMs;
376
+ }
377
+ const notifyRaw = r.notify;
378
+ if (!notifyRaw || typeof notifyRaw !== "object") return null;
379
+ const n = notifyRaw;
380
+ if (n.target !== "in-app-toast" && n.target !== "webhook") return null;
381
+ const notify = n.target === "webhook" ? (() => {
382
+ if (typeof n.url !== "string" || !n.url) return null;
383
+ const out = {
384
+ target: "webhook",
385
+ url: n.url
386
+ };
387
+ if (n.headers && typeof n.headers === "object") {
388
+ const hs = {};
389
+ for (const [k, v] of Object.entries(n.headers)) {
390
+ if (typeof v === "string") hs[k] = v;
391
+ }
392
+ if (Object.keys(hs).length > 0) out.headers = hs;
393
+ }
394
+ return out;
395
+ })() : (() => {
396
+ const out = {
397
+ target: "in-app-toast"
398
+ };
399
+ if (n.tone === "info" || n.tone === "warning" || n.tone === "error") out.tone = n.tone;
400
+ if (typeof n.sticky === "boolean") out.sticky = n.sticky;
401
+ return out;
402
+ })();
403
+ if (!notify) return null;
404
+ const rule = { when, notify };
405
+ if (typeof r.id === "string") rule.id = r.id;
406
+ if (typeof r.description === "string") rule.description = r.description;
407
+ if (typeof r.enabled === "boolean") rule.enabled = r.enabled;
408
+ return rule;
409
+ }
410
+ function parseSensorConfig(raw) {
411
+ const result = {};
412
+ const driftRaw = raw.drift;
413
+ if (driftRaw && typeof driftRaw === "object") {
414
+ const d = driftRaw;
415
+ const drift = {};
416
+ if (typeof d.enabled === "boolean") drift.enabled = d.enabled;
417
+ if (typeof d.channelEvents === "boolean") drift.channelEvents = d.channelEvents;
418
+ if (typeof d.debounceMs === "number" && Number.isFinite(d.debounceMs) && d.debounceMs >= 0) {
419
+ drift.debounceMs = d.debounceMs;
420
+ }
421
+ if (Object.keys(drift).length > 0) result.drift = drift;
422
+ }
423
+ const docsRaw = raw.docs;
424
+ if (docsRaw && typeof docsRaw === "object") {
425
+ const d = docsRaw;
426
+ const docs = {};
427
+ if (typeof d.enabled === "boolean") docs.enabled = d.enabled;
428
+ if (typeof d.channelEvents === "boolean") docs.channelEvents = d.channelEvents;
429
+ if (Object.keys(docs).length > 0) result.docs = docs;
430
+ }
431
+ const stuckRaw = raw.stuck;
432
+ if (stuckRaw && typeof stuckRaw === "object") {
433
+ const s = stuckRaw;
434
+ const stuck = {};
435
+ if (typeof s.enabled === "boolean") stuck.enabled = s.enabled;
436
+ if (typeof s.repetitionThreshold === "number" && Number.isFinite(s.repetitionThreshold) && s.repetitionThreshold > 0) {
437
+ stuck.repetitionThreshold = s.repetitionThreshold;
438
+ }
439
+ if (typeof s.errorLoopThreshold === "number" && Number.isFinite(s.errorLoopThreshold) && s.errorLoopThreshold > 0) {
440
+ stuck.errorLoopThreshold = s.errorLoopThreshold;
441
+ }
442
+ if (typeof s.idleMinutes === "number" && Number.isFinite(s.idleMinutes) && s.idleMinutes > 0) {
443
+ stuck.idleMinutes = s.idleMinutes;
444
+ }
445
+ if (Object.keys(stuck).length > 0) result.stuck = stuck;
446
+ }
447
+ const awarenessRaw = raw.awareness;
448
+ if (awarenessRaw && typeof awarenessRaw === "object") {
449
+ const a = awarenessRaw;
450
+ const awareness = {};
451
+ if (typeof a.branchWindowDays === "number" && Number.isFinite(a.branchWindowDays) && a.branchWindowDays > 0) {
452
+ awareness.branchWindowDays = a.branchWindowDays;
453
+ }
454
+ if (typeof a.inlineNotices === "boolean") awareness.inlineNotices = a.inlineNotices;
455
+ if (typeof a.holdSignOffOnHighSignals === "boolean") awareness.holdSignOffOnHighSignals = a.holdSignOffOnHighSignals;
456
+ if (Object.keys(awareness).length > 0) result.awareness = awareness;
457
+ }
458
+ return Object.keys(result).length > 0 ? result : void 0;
459
+ }
460
+ // Annotate the CommonJS export names for ESM import in node:
461
+ 0 && (module.exports = {
462
+ getEffectiveAttachmentLocation,
463
+ getEffectiveDefaultVisibility,
464
+ getEffectiveSensorConfig,
465
+ getProjectConfig,
466
+ invalidateProjectConfigCache,
467
+ listChannelRoutingRules,
468
+ matchChannelRoutingRules,
469
+ parsePlansFolderRef,
470
+ resetProjectConfigCache,
471
+ startProjectConfigWatcher,
472
+ stopProjectConfigWatcher,
473
+ updateProjectConfig
474
+ });
@@ -0,0 +1,184 @@
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 project_scanner_exports = {};
29
+ __export(project_scanner_exports, {
30
+ collectFilePaths: () => collectFilePaths,
31
+ countFiles: () => countFiles,
32
+ listTaggedExtensions: () => listTaggedExtensions,
33
+ listTaggedLanguages: () => listTaggedLanguages,
34
+ scanDirectory: () => scanDirectory
35
+ });
36
+ module.exports = __toCommonJS(project_scanner_exports);
37
+ var import_node_fs = __toESM(require("node:fs"));
38
+ var import_node_path = __toESM(require("node:path"));
39
+ var import_ignore = __toESM(require("ignore"));
40
+ var import_git_checkout = require("./git-checkout");
41
+ const ALWAYS_IGNORED = /* @__PURE__ */ new Set([
42
+ // JS / Node
43
+ "node_modules",
44
+ // Python
45
+ "__pycache__",
46
+ "venv",
47
+ "env",
48
+ // Rust
49
+ "target",
50
+ // PHP / Go vendored deps
51
+ "vendor",
52
+ // Go — `testdata` is the language's convention for fixture input that
53
+ // is deliberately not valid source. Parsing it produces pure noise.
54
+ "testdata"
55
+ ]);
56
+ const LANG_MAP = {
57
+ ".ts": "typescript",
58
+ ".tsx": "typescript",
59
+ ".js": "javascript",
60
+ ".jsx": "javascript",
61
+ ".mjs": "javascript",
62
+ ".cjs": "javascript",
63
+ ".py": "python",
64
+ ".rs": "rust",
65
+ ".go": "go",
66
+ ".java": "java",
67
+ ".php": "php",
68
+ ".rb": "ruby",
69
+ ".rake": "ruby",
70
+ ".cs": "csharp",
71
+ ".kt": "kotlin",
72
+ ".kts": "kotlin",
73
+ ".swift": "swift",
74
+ ".json": "json",
75
+ ".css": "css",
76
+ ".scss": "css",
77
+ ".html": "html",
78
+ ".md": "markdown",
79
+ ".yaml": "yaml",
80
+ ".yml": "yaml",
81
+ ".toml": "toml",
82
+ ".sql": "sql"
83
+ };
84
+ function listTaggedLanguages() {
85
+ return [...new Set(Object.values(LANG_MAP))];
86
+ }
87
+ function listTaggedExtensions() {
88
+ return Object.keys(LANG_MAP);
89
+ }
90
+ function isSourceFile(name) {
91
+ return import_node_path.default.extname(name).toLowerCase() in LANG_MAP;
92
+ }
93
+ function getLanguage(name) {
94
+ return LANG_MAP[import_node_path.default.extname(name).toLowerCase()];
95
+ }
96
+ function loadIgnoreFiles(dirPath) {
97
+ const ig = (0, import_ignore.default)();
98
+ let any = false;
99
+ for (const filename of [".gitignore", ".codetrellis-ignore"]) {
100
+ const filePath = import_node_path.default.join(dirPath, filename);
101
+ try {
102
+ const content = import_node_fs.default.readFileSync(filePath, "utf-8");
103
+ ig.add(content);
104
+ any = true;
105
+ } catch {
106
+ }
107
+ }
108
+ return any ? ig : null;
109
+ }
110
+ function isIgnoredByPatterns(absolutePath, isDir, ctx) {
111
+ for (const { baseDir, ig } of ctx.matchers) {
112
+ let rel = import_node_path.default.relative(baseDir, absolutePath);
113
+ if (!rel || rel.startsWith("..")) continue;
114
+ if (isDir) rel = rel.replace(/\/?$/, "/");
115
+ if (ig.ignores(rel)) return true;
116
+ }
117
+ return false;
118
+ }
119
+ function scanDirectory(dirPath, parent, maxDepth = 10) {
120
+ const ctx = parent ?? { root: dirPath, matchers: [] };
121
+ if (maxDepth <= 0) return [];
122
+ let entries;
123
+ try {
124
+ entries = import_node_fs.default.readdirSync(dirPath, { withFileTypes: true });
125
+ } catch {
126
+ return [];
127
+ }
128
+ const localIgnore = loadIgnoreFiles(dirPath);
129
+ const childCtx = localIgnore ? { root: ctx.root, matchers: [...ctx.matchers, { baseDir: dirPath, ig: localIgnore }] } : ctx;
130
+ const nodes = [];
131
+ entries.sort((a, b) => {
132
+ if (a.isDirectory() !== b.isDirectory()) return a.isDirectory() ? -1 : 1;
133
+ return a.name.localeCompare(b.name);
134
+ });
135
+ for (const entry of entries) {
136
+ if (entry.name === ".git") continue;
137
+ if (entry.isDirectory() && ALWAYS_IGNORED.has(entry.name)) continue;
138
+ const fullPath = import_node_path.default.join(dirPath, entry.name);
139
+ if (isIgnoredByPatterns(fullPath, entry.isDirectory(), childCtx)) continue;
140
+ if (entry.isDirectory()) {
141
+ if ((0, import_git_checkout.isLinkedWorktreeDir)(fullPath)) continue;
142
+ const children = scanDirectory(fullPath, childCtx, maxDepth - 1);
143
+ if (children.length === 0) continue;
144
+ nodes.push({
145
+ name: entry.name,
146
+ path: fullPath,
147
+ type: "directory",
148
+ children
149
+ });
150
+ } else if (isSourceFile(entry.name)) {
151
+ nodes.push({
152
+ name: entry.name,
153
+ path: fullPath,
154
+ type: "file",
155
+ language: getLanguage(entry.name)
156
+ });
157
+ }
158
+ }
159
+ return nodes;
160
+ }
161
+ function countFiles(nodes) {
162
+ let count = 0;
163
+ for (const node of nodes) {
164
+ if (node.type === "file") count++;
165
+ if (node.children) count += countFiles(node.children);
166
+ }
167
+ return count;
168
+ }
169
+ function collectFilePaths(nodes) {
170
+ const paths = [];
171
+ for (const node of nodes) {
172
+ if (node.type === "file") paths.push(node.path);
173
+ if (node.children) paths.push(...collectFilePaths(node.children));
174
+ }
175
+ return paths;
176
+ }
177
+ // Annotate the CommonJS export names for ESM import in node:
178
+ 0 && (module.exports = {
179
+ collectFilePaths,
180
+ countFiles,
181
+ listTaggedExtensions,
182
+ listTaggedLanguages,
183
+ scanDirectory
184
+ });