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,306 @@
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 mobile_approvals_exports = {};
29
+ __export(mobile_approvals_exports, {
30
+ APPROVAL_METHODS: () => APPROVAL_METHODS,
31
+ PREVIEW_CHUNK_CHARS: () => PREVIEW_CHUNK_CHARS,
32
+ PREVIEW_IMAGE_BYTES: () => PREVIEW_IMAGE_BYTES,
33
+ PREVIEW_TEXT_CHARS: () => PREVIEW_TEXT_CHARS,
34
+ SHEET_CONTEXT: () => SHEET_CONTEXT,
35
+ buildPreview: () => buildPreview,
36
+ handleApprovalMethod: () => handleApprovalMethod,
37
+ sanitiseLocator: () => sanitiseLocator,
38
+ setPreviewImageScaler: () => setPreviewImageScaler,
39
+ toPhone: () => toPhone
40
+ });
41
+ module.exports = __toCommonJS(mobile_approvals_exports);
42
+ var import_node_path = __toESM(require("node:path"));
43
+ var criteriaService = __toESM(require("./criteria-service"));
44
+ var import_artefact_service = require("./artefact-service");
45
+ var import_plan_item_service = require("./plan-item-service");
46
+ var import_task_grounding = require("./task-grounding");
47
+ var import_human_decision = require("./human-decision");
48
+ var import_settings_service = require("./settings-service");
49
+ var import_paired_device_service = require("./paired-device-service");
50
+ var import_peer_capabilities = require("./peer-capabilities");
51
+ var import_peer_audit_service = require("./peer-audit-service");
52
+ var import_sensor_bridge_service = require("./sensor-bridge-service");
53
+ var import_reader_host = require("./material-reader/reader-host");
54
+ var import_locator = require("../../shared/lib/locator");
55
+ var import_xlsx_xml = require("../../shared/lib/xlsx-xml");
56
+ const PREVIEW_TEXT_CHARS = 4e4;
57
+ const PREVIEW_IMAGE_BYTES = 3 * 1024 * 1024;
58
+ const PREVIEW_CHUNK_CHARS = 16e3;
59
+ const SHEET_CONTEXT = { rows: 6, cols: 3 };
60
+ const TRANSFER_ID = /^[A-Za-z0-9-]{8,64}$/;
61
+ let scaler = null;
62
+ function setPreviewImageScaler(fn) {
63
+ scaler = fn;
64
+ }
65
+ const APPROVAL_METHODS = ["criteria.awaiting", "criteria.list", "criterion.decide", "artefact.preview"];
66
+ async function handleApprovalMethod(method, params, peer) {
67
+ switch (method) {
68
+ case "criteria.awaiting":
69
+ return awaiting(params);
70
+ case "criteria.list":
71
+ return criteriaForItem(requireUid(params, "itemUid"));
72
+ case "criterion.decide":
73
+ return decide(requireUid(params, "criterionUid"), params, peer);
74
+ case "artefact.preview":
75
+ return preview(params, peer);
76
+ default:
77
+ throw new Error(`Unknown approval method: ${method}`);
78
+ }
79
+ }
80
+ function awaiting(params) {
81
+ const limit = typeof params.limit === "number" && params.limit > 0 ? Math.min(params.limit, 200) : 100;
82
+ return {
83
+ entries: criteriaService.listAwaitingPerson(limit).map((a) => ({
84
+ ...toPhone(a.criterion),
85
+ itemTitle: a.itemTitle,
86
+ planUid: a.planUid,
87
+ planTitle: a.planTitle
88
+ }))
89
+ };
90
+ }
91
+ async function criteriaForItem(itemUid) {
92
+ const item = (0, import_plan_item_service.getItem)(itemUid);
93
+ if (!item) throw new Error("Item not found");
94
+ await (0, import_artefact_service.refreshArtefactHashes)(itemUid).catch(() => []);
95
+ const g = await (0, import_task_grounding.taskGrounding)(itemUid);
96
+ return {
97
+ item: { uid: item.uid, title: item.title, planUid: item.planUid },
98
+ criteria: criteriaService.listCriteria(itemUid).map(toPhone),
99
+ grounding: g && g.total ? { words: g.words, grounded: g.grounded, grades: Object.fromEntries(g.criteria.map((c) => [c.uid, { grade: c.grade, why: c.why }])) } : null
100
+ };
101
+ }
102
+ async function decide(criterionUid, params, peer) {
103
+ const device = (0, import_paired_device_service.getPairedDevice)(peer.fingerprint);
104
+ if (!device?.confirmedAt) {
105
+ throw new import_peer_capabilities.PeerAuthorizationError("Approving needs a pairing confirmed on the desktop");
106
+ }
107
+ const before = criteriaService.getCriterion(criterionUid);
108
+ if (!before) throw new criteriaService.CriterionError("Criterion not found", 404);
109
+ await (0, import_artefact_service.refreshArtefactHashes)(before.itemUid).catch(() => []);
110
+ const criterion = criteriaService.decideCriterion(
111
+ criterionUid,
112
+ { decision: params.decision, note: params.note, anchor: params.anchor },
113
+ (0, import_human_decision.issueHumanDecision)("phone", (0, import_settings_service.getAuthorKey)("human"), device.alias)
114
+ );
115
+ (0, import_peer_audit_service.recordPeerAudit)({
116
+ kind: "decision",
117
+ fingerprint: peer.fingerprint,
118
+ alias: device.alias,
119
+ method: "criterion.decide",
120
+ detail: `${params.decision === "approved" ? "approved" : "sent back"} criterion ${criterionUid}`
121
+ });
122
+ const planUid = (0, import_plan_item_service.getItem)(criterion.itemUid)?.planUid ?? null;
123
+ if (planUid) (0, import_sensor_bridge_service.resolveCriterionNotices)(planUid, criterionUid);
124
+ peer.broadcast?.("plan-item-criteria-changed", { planUid, itemUid: criterion.itemUid });
125
+ return { criterion: toPhone(criterion) };
126
+ }
127
+ async function preview(params, peer) {
128
+ const transferId = params.transferId;
129
+ if (typeof transferId !== "string" || !TRANSFER_ID.test(transferId)) {
130
+ throw new Error("transferId must be 8\u201364 letters, digits or dashes");
131
+ }
132
+ const attachmentUid = requireUid(params, "attachmentUid");
133
+ const artefact = (0, import_artefact_service.getArtefact)(attachmentUid);
134
+ if (!artefact) throw new Error("No evidence file with that uid");
135
+ const built = await buildPreview(attachmentUid, sanitiseLocator(params.locator));
136
+ const body = JSON.stringify(built);
137
+ const total = Math.max(1, Math.ceil(body.length / PREVIEW_CHUNK_CHARS));
138
+ for (let seq = 0; seq < total; seq++) {
139
+ peer.send({
140
+ mcp: true,
141
+ cmd: "preview.chunk",
142
+ id: transferId,
143
+ seq,
144
+ total,
145
+ data: body.slice(seq * PREVIEW_CHUNK_CHARS, (seq + 1) * PREVIEW_CHUNK_CHARS)
146
+ });
147
+ }
148
+ return { transferId, total, chars: body.length, kind: built.kind };
149
+ }
150
+ async function buildPreview(attachmentUid, locator, read = import_reader_host.readMaterial) {
151
+ const artefact = (0, import_artefact_service.getArtefact)(attachmentUid);
152
+ const ext = artefact ? import_node_path.default.extname(artefact.path).slice(1).toLowerCase() : "";
153
+ const isImage = ["png", "jpg", "jpeg", "gif", "webp"].includes(ext);
154
+ let readAt = isImage ? null : locator;
155
+ let grid;
156
+ if ((ext === "xlsx" || ext === "xlsm") && locator) {
157
+ const cited = locator.range ? (0, import_locator.parseRange)(String(locator.range)) : null;
158
+ if (cited) {
159
+ const firstRow = Math.max(1, cited.from.row - SHEET_CONTEXT.rows);
160
+ const firstCol = Math.max(1, cited.from.col - SHEET_CONTEXT.cols);
161
+ const lastRow = cited.to.row + SHEET_CONTEXT.rows;
162
+ const lastCol = cited.to.col + SHEET_CONTEXT.cols;
163
+ readAt = { ...locator, range: `${(0, import_xlsx_xml.colLetters)(firstCol)}${firstRow}:${(0, import_xlsx_xml.colLetters)(lastCol)}${lastRow}` };
164
+ grid = { firstRow, firstCol, cited };
165
+ } else if (!locator.text) {
166
+ grid = { firstRow: 1, firstCol: 1, cited: null };
167
+ }
168
+ }
169
+ const result = await read(attachmentUid, readAt);
170
+ if (!result.ok) return { kind: "unavailable", name: result.name ?? null, reason: result.reason };
171
+ if (result.kind === "image") {
172
+ const original = Buffer.from(result.base64, "base64");
173
+ const scaled = scaler ? safeScale(original, result.mimeType) : null;
174
+ if (scaled) return { kind: "image", name: result.name, mime: scaled.mime, base64: scaled.bytes.toString("base64"), scaled: true };
175
+ if (original.length > PREVIEW_IMAGE_BYTES) {
176
+ return {
177
+ kind: "unavailable",
178
+ name: result.name,
179
+ reason: `${result.name} is larger than the ${PREVIEW_IMAGE_BYTES / 1024 / 1024} MB the phone is sent \u2014 open it on the desktop`
180
+ };
181
+ }
182
+ return { kind: "image", name: result.name, mime: result.mimeType, base64: result.base64, scaled: false };
183
+ }
184
+ const { reply } = result;
185
+ const notes = [...reply.notes];
186
+ let budget = PREVIEW_TEXT_CHARS;
187
+ const sections = [];
188
+ for (const s of reply.sections) {
189
+ if (budget <= 0) break;
190
+ if (s.body.length > budget) {
191
+ sections.push({ heading: s.heading, body: s.body.slice(0, budget) });
192
+ notes.push("Cut short for the phone \u2014 the whole of it is on the desktop.");
193
+ budget = 0;
194
+ break;
195
+ }
196
+ sections.push(s);
197
+ budget -= s.body.length;
198
+ }
199
+ if (sections.length < reply.sections.length && !notes.some((n) => n.startsWith("Cut short"))) {
200
+ notes.push("Cut short for the phone \u2014 the whole of it is on the desktop.");
201
+ }
202
+ if (grid) {
203
+ return {
204
+ kind: "text",
205
+ name: result.name,
206
+ format: reply.format,
207
+ // The place that was cited, not the wider area read around it.
208
+ where: (0, import_locator.describeLocator)(locator) || reply.where,
209
+ outline: reply.outline,
210
+ sections: sections.map((sec) => ({ ...sec, heading: sec.heading.replace(/,\s*[A-Z]+\d+:[A-Z]+\d+$/, "").replace(/ from A1$/, "") })),
211
+ notes,
212
+ grid
213
+ };
214
+ }
215
+ return {
216
+ kind: "text",
217
+ name: result.name,
218
+ format: reply.format,
219
+ where: reply.where,
220
+ outline: reply.outline,
221
+ sections,
222
+ notes
223
+ };
224
+ }
225
+ function safeScale(bytes, mime) {
226
+ try {
227
+ return scaler?.(bytes, mime) ?? null;
228
+ } catch (err) {
229
+ console.warn("[Approvals] Could not scale an image for the phone:", err);
230
+ return null;
231
+ }
232
+ }
233
+ function requireUid(params, key) {
234
+ const v = params[key];
235
+ if (typeof v !== "string" || !/^[A-Za-z0-9-]{8,64}$/.test(v)) throw new Error(`${key} is required`);
236
+ return v;
237
+ }
238
+ function sanitiseLocator(raw) {
239
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
240
+ const l = raw;
241
+ const out = {};
242
+ const str = (v) => typeof v === "string" && v.length > 0 && v.length <= 200 ? v : void 0;
243
+ const span = (v) => {
244
+ if (typeof v === "number" && Number.isFinite(v)) return v;
245
+ if (Array.isArray(v) && v.length === 2 && v.every((n) => typeof n === "number")) return `${v[0]}-${v[1]}`;
246
+ return str(v);
247
+ };
248
+ out.sheet = str(l.sheet);
249
+ out.range = str(l.range);
250
+ out.page = span(l.page);
251
+ out.lines = span(l.lines);
252
+ out.text = str(l.text);
253
+ for (const k of Object.keys(out)) if (out[k] === void 0) delete out[k];
254
+ return Object.keys(out).length > 0 ? out : null;
255
+ }
256
+ function toEvidence(e) {
257
+ const artefact = e.attachmentUid ? (0, import_artefact_service.getArtefact)(e.attachmentUid) : null;
258
+ const name = artefact ? import_node_path.default.basename(artefact.path) : null;
259
+ return {
260
+ attachmentUid: e.attachmentUid,
261
+ name,
262
+ ext: name ? import_node_path.default.extname(name).slice(1).toLowerCase() || null : null,
263
+ locator: e.locator,
264
+ where: (0, import_locator.describeLocator)(e.locator),
265
+ note: e.note,
266
+ submittedBy: e.submittedBy,
267
+ submittedAt: e.submittedAt
268
+ };
269
+ }
270
+ function toPhone(c) {
271
+ const signoff = c.latestSignoff;
272
+ let changedFiles = [];
273
+ if (c.state === "stale" && signoff?.evidenceHashes) {
274
+ const recorded = signoff.evidenceHashes;
275
+ changedFiles = Object.keys(recorded).filter((uid) => ((0, import_artefact_service.getArtefact)(uid)?.sha256 ?? null) !== recorded[uid]).map((uid) => (0, import_artefact_service.getArtefact)(uid)?.path ?? uid);
276
+ }
277
+ return {
278
+ uid: c.uid,
279
+ itemUid: c.itemUid,
280
+ text: c.text,
281
+ kind: c.kind,
282
+ policy: c.policy,
283
+ state: c.state,
284
+ evidence: c.latestSubmission.map(toEvidence),
285
+ lastDecision: signoff ? { decision: signoff.decision, actor: signoff.actor, channel: signoff.channel, note: signoff.note, at: signoff.createdAt } : null,
286
+ changedFiles,
287
+ // The desktop's rule, the same here (CriteriaBlock): approve anything
288
+ // not already met; send back what was submitted, or take back an
289
+ // approval.
290
+ canApprove: c.state !== "met",
291
+ canSendBack: c.state === "submitted" || c.state === "met"
292
+ };
293
+ }
294
+ // Annotate the CommonJS export names for ESM import in node:
295
+ 0 && (module.exports = {
296
+ APPROVAL_METHODS,
297
+ PREVIEW_CHUNK_CHARS,
298
+ PREVIEW_IMAGE_BYTES,
299
+ PREVIEW_TEXT_CHARS,
300
+ SHEET_CONTEXT,
301
+ buildPreview,
302
+ handleApprovalMethod,
303
+ sanitiseLocator,
304
+ setPreviewImageScaler,
305
+ toPhone
306
+ });
@@ -0,0 +1,180 @@
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 mobile_awareness_exports = {};
19
+ __export(mobile_awareness_exports, {
20
+ AWARENESS_METHODS: () => AWARENESS_METHODS,
21
+ handleAwarenessMethod: () => handleAwarenessMethod,
22
+ phoneChecks: () => phoneChecks,
23
+ phoneNeedsYou: () => phoneNeedsYou,
24
+ phoneSignal: () => phoneSignal
25
+ });
26
+ module.exports = __toCommonJS(mobile_awareness_exports);
27
+ var import_awareness_service = require("./awareness-service");
28
+ var import_awareness_notices = require("./awareness-notices");
29
+ var import_awareness_replies = require("./awareness-replies");
30
+ var import_workstream_service = require("./workstream-service");
31
+ var import_paired_device_service = require("./paired-device-service");
32
+ var import_peer_capabilities = require("./peer-capabilities");
33
+ var import_peer_audit_service = require("./peer-audit-service");
34
+ var import_awareness_digest = require("../../shared/lib/awareness-digest");
35
+ var import_check_runs = require("./check-runs");
36
+ var import_check_run_record = require("./task-records/check-run-record");
37
+ var import_open_findings = require("../../shared/lib/open-findings");
38
+ var import_check_words = require("../../shared/lib/check-words");
39
+ var import_signal_words = require("../../shared/lib/signal-words");
40
+ var import_workstream_words = require("../../shared/lib/workstream-words");
41
+ var import_types = require("../../shared/types");
42
+ const AWARENESS_METHODS = ["awareness.needsYou", "awareness.signal", "awareness.answer", "awareness.reply"];
43
+ const PHONE_FINDINGS = 3;
44
+ function phoneChecks(projectRoot) {
45
+ return (0, import_open_findings.blockingRuns)((0, import_check_runs.listCheckRuns)(projectRoot)).map((r) => {
46
+ const failing = r.findings.filter((f) => f.failing);
47
+ return {
48
+ id: r.id,
49
+ who: r.who,
50
+ ranIn: r.ranIn,
51
+ scope: r.scope,
52
+ at: r.at,
53
+ outcome: (0, import_check_run_record.outcomeWords)(r.outcome),
54
+ findings: failing.slice(0, PHONE_FINDINGS).map((f) => ({ where: `${f.path} ${(0, import_check_words.reachWords)(f.imports)}`, rule: f.rule, fix: f.fix })),
55
+ more: Math.max(0, failing.length - PHONE_FINDINGS)
56
+ };
57
+ });
58
+ }
59
+ async function handleAwarenessMethod(method, params, peer, ctx) {
60
+ switch (method) {
61
+ case "awareness.needsYou":
62
+ return phoneNeedsYou(ctx.projectRoot);
63
+ case "awareness.signal":
64
+ return { signal: await phoneSignal(ctx.projectRoot, idOf(params)) };
65
+ case "awareness.answer":
66
+ return answer(params, peer, ctx);
67
+ case "awareness.reply":
68
+ return reply(params, peer, ctx);
69
+ default:
70
+ throw new Error(`Unknown awareness method: ${method}`);
71
+ }
72
+ }
73
+ const RANK = { high: 0, medium: 1, low: 2 };
74
+ async function phoneNeedsYou(projectRoot) {
75
+ const empty = { projectRoot, digest: { needsYou: 0, low: 0, moreLines: 0, lines: [] }, signals: [], checks: [] };
76
+ if (!projectRoot) return empty;
77
+ const workstreams = await workstreamsOf(projectRoot);
78
+ const label = (root) => (0, import_workstream_words.sideLabel)(root, workstreams);
79
+ const signals = (0, import_awareness_notices.withTold)((0, import_awareness_service.listSignals)(projectRoot));
80
+ const d = (0, import_awareness_digest.buildDigest)(signals, label);
81
+ const inPlay = signals.filter((s) => s.severity !== "low" && (s.state === "open" || s.state === "acknowledged")).sort((a, b) => Number(a.state !== "open") - Number(b.state !== "open") || RANK[a.severity] - RANK[b.severity] || b.lastSeen - a.lastSeen);
82
+ return {
83
+ projectRoot,
84
+ digest: {
85
+ needsYou: d.needsYou,
86
+ low: d.low,
87
+ moreLines: d.moreLines,
88
+ lines: d.lines.map((l) => ({ text: l.text, question: l.question, told: l.told, signalIds: l.signalIds }))
89
+ },
90
+ signals: inPlay.map((s) => toPhoneSignal(s, label)),
91
+ checks: phoneChecks(projectRoot)
92
+ };
93
+ }
94
+ async function phoneSignal(projectRoot, id) {
95
+ if (!projectRoot) throw new Error("No project is open on the desktop");
96
+ const workstreams = await workstreamsOf(projectRoot);
97
+ const s = (0, import_awareness_replies.withReplies)((0, import_awareness_notices.withTold)((0, import_awareness_service.listSignals)(projectRoot))).find((x) => x.id === id);
98
+ if (!s) throw new Error("No such open signal in this project");
99
+ const label = (root) => (0, import_workstream_words.sideLabel)(root, workstreams);
100
+ return {
101
+ ...toPhoneSignal(s, label),
102
+ sideWords: (0, import_signal_words.sideWords)(s, label),
103
+ files: filesOf(s),
104
+ told: (s.told ?? []).map((t) => ({ agentType: t.agentType, toldAt: t.toldAt, ...t.note ? { note: t.note } : {} })),
105
+ replies: s.replies ?? [],
106
+ ...s.stateBy ? { stateBy: s.stateBy, stateAt: s.stateAt } : {},
107
+ ...s.reopened ? { reopened: s.reopened } : {}
108
+ };
109
+ }
110
+ function toPhoneSignal(s, label) {
111
+ return {
112
+ id: s.id,
113
+ kind: s.kind,
114
+ severity: s.severity,
115
+ state: s.state,
116
+ heading: (0, import_signal_words.kindWords)(s),
117
+ summary: s.summary,
118
+ sides: (0, import_signal_words.sideWords)(s, label).map((x) => x.name),
119
+ ...s.subject.material ? { material: s.subject.material } : {},
120
+ firstSeen: s.firstSeen,
121
+ lastSeen: s.lastSeen
122
+ };
123
+ }
124
+ function filesOf(s) {
125
+ const files = /* @__PURE__ */ new Set();
126
+ if (s.subject.material) files.add(s.subject.material);
127
+ if (s.subject.file) files.add(s.subject.file);
128
+ for (const f of s.subject.files ?? []) files.add(f);
129
+ for (const f of s.subject.importers ?? []) files.add(f);
130
+ return [...files];
131
+ }
132
+ function idOf(params) {
133
+ const id = params.id;
134
+ if (typeof id !== "string" || !id) throw new Error("id is required");
135
+ return id;
136
+ }
137
+ function confirmedDevice(peer, what) {
138
+ const device = (0, import_paired_device_service.getPairedDevice)(peer.fingerprint);
139
+ if (!device?.confirmedAt) throw new import_peer_capabilities.PeerAuthorizationError(`${what} needs a pairing confirmed on the desktop`);
140
+ return device;
141
+ }
142
+ async function answer(params, peer, ctx) {
143
+ const id = idOf(params);
144
+ const state = params.state;
145
+ if (!import_types.SETTABLE_SIGNAL_STATES.includes(state)) throw new Error(`state must be one of ${import_types.SETTABLE_SIGNAL_STATES.join(", ")}`);
146
+ const device = confirmedDevice(peer, "Answering a signal");
147
+ if (!ctx.projectRoot) throw new Error("No project is open on the desktop");
148
+ const updated = (0, import_awareness_service.setSignalState)(ctx.projectRoot, id, state, ctx.who);
149
+ if (!updated) throw new Error("No such open signal in this project");
150
+ (0, import_peer_audit_service.recordPeerAudit)({ kind: "decision", fingerprint: peer.fingerprint, alias: device.alias, method: "awareness.answer", detail: `${state} on signal ${id}` });
151
+ peer.broadcast?.("awareness-changed", { projectRoot: ctx.projectRoot });
152
+ return { signal: await phoneSignal(ctx.projectRoot, id) };
153
+ }
154
+ async function reply(params, peer, ctx) {
155
+ const id = idOf(params);
156
+ const message = (0, import_awareness_replies.cleanReply)(params.message);
157
+ if (!message) throw new Error(`message must be 1\u2013${import_awareness_replies.MAX_REPLY} characters`);
158
+ const device = confirmedDevice(peer, "Replying to the agents");
159
+ if (!ctx.projectRoot) throw new Error("No project is open on the desktop");
160
+ const sent = ctx.reply(ctx.projectRoot, id, message, ctx.who);
161
+ if (!sent) throw new Error("No such open signal in this project");
162
+ (0, import_peer_audit_service.recordPeerAudit)({ kind: "decision", fingerprint: peer.fingerprint, alias: device.alias, method: "awareness.reply", detail: `reply on signal ${id}` });
163
+ const { signalId: _s, steers, ...kept } = sent;
164
+ return { reply: kept, steers: steers.length, signal: await phoneSignal(ctx.projectRoot, id) };
165
+ }
166
+ async function workstreamsOf(projectRoot) {
167
+ try {
168
+ return await (0, import_workstream_service.listWorkstreams)(projectRoot, { includeIdle: true });
169
+ } catch {
170
+ return [];
171
+ }
172
+ }
173
+ // Annotate the CommonJS export names for ESM import in node:
174
+ 0 && (module.exports = {
175
+ AWARENESS_METHODS,
176
+ handleAwarenessMethod,
177
+ phoneChecks,
178
+ phoneNeedsYou,
179
+ phoneSignal
180
+ });
@@ -0,0 +1,115 @@
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 mobile_breakpoints_exports = {};
19
+ __export(mobile_breakpoints_exports, {
20
+ BREAKPOINT_METHODS: () => BREAKPOINT_METHODS,
21
+ handleBreakpointMethod: () => handleBreakpointMethod,
22
+ phoneWaiting: () => phoneWaiting,
23
+ toPhoneHit: () => toPhoneHit
24
+ });
25
+ module.exports = __toCommonJS(mobile_breakpoints_exports);
26
+ var import_breakpoint_service = require("./breakpoint-service");
27
+ var import_signal_breakpoints = require("./signal-breakpoints");
28
+ var import_workstream_service = require("./workstream-service");
29
+ var import_paired_device_service = require("./paired-device-service");
30
+ var import_peer_capabilities = require("./peer-capabilities");
31
+ var import_peer_audit_service = require("./peer-audit-service");
32
+ var import_breakpoint_words = require("../../shared/lib/breakpoint-words");
33
+ var import_workstream_words = require("../../shared/lib/workstream-words");
34
+ const BREAKPOINT_METHODS = ["breakpoint.waiting", "breakpoint.answer"];
35
+ async function handleBreakpointMethod(method, params, peer, ctx) {
36
+ switch (method) {
37
+ case "breakpoint.waiting":
38
+ return { hits: await phoneWaiting(ctx.projectRoot) };
39
+ case "breakpoint.answer":
40
+ return answer(params, peer, ctx);
41
+ default:
42
+ throw new Error(`Unknown breakpoint method: ${method}`);
43
+ }
44
+ }
45
+ async function phoneWaiting(projectRoot) {
46
+ if (projectRoot) {
47
+ try {
48
+ (0, import_signal_breakpoints.releaseSettled)(projectRoot);
49
+ } catch {
50
+ }
51
+ }
52
+ const workstreams = await workstreamsOf(projectRoot);
53
+ return (0, import_breakpoint_service.listHits)({ state: "waiting" }).map((h) => toPhoneHit(h, workstreams));
54
+ }
55
+ async function answer(params, peer, ctx) {
56
+ const ref = params.ref;
57
+ if (typeof ref !== "string" || !ref) throw new Error("ref is required");
58
+ const decision = params.decision;
59
+ if (!import_breakpoint_service.DECISIONS.includes(decision)) throw new Error(`decision must be one of ${import_breakpoint_service.DECISIONS.join(", ")}`);
60
+ if (decision === "steer" && !(0, import_breakpoint_service.cleanNote)(params.note)) throw new Error("A steer needs a note for the agent");
61
+ const device = (0, import_paired_device_service.getPairedDevice)(peer.fingerprint);
62
+ if (!device?.confirmedAt) {
63
+ throw new import_peer_capabilities.PeerAuthorizationError("Answering a breakpoint needs a pairing confirmed on the desktop");
64
+ }
65
+ const hit = (0, import_breakpoint_service.getHit)(ref);
66
+ if (!hit) throw new Error("No such breakpoint hit");
67
+ if (hit.kind === "proposal") throw new Error("A spec proposal is decided on the proposal: accept or reject it (proposal.decide).");
68
+ if (hit.answeredAt !== null) return { hit: toPhoneHit(hit, await workstreamsOf(ctx.projectRoot)), alreadyAnswered: true };
69
+ const answered = (0, import_breakpoint_service.answerHit)({ ref, decision, note: params.note, by: ctx.who.author, byType: ctx.who.authorType });
70
+ if (!answered) return { hit: toPhoneHit((0, import_breakpoint_service.getHit)(ref) ?? hit, await workstreamsOf(ctx.projectRoot)), alreadyAnswered: true };
71
+ (0, import_peer_audit_service.recordPeerAudit)({
72
+ kind: "decision",
73
+ fingerprint: peer.fingerprint,
74
+ alias: device.alias,
75
+ method: "breakpoint.answer",
76
+ detail: `${decision} on breakpoint hit ${ref}`
77
+ });
78
+ peer.broadcast?.("breakpoint-answered", { ref: answered.ref, planUid: answered.planUid, decision: answered.decision });
79
+ return { hit: toPhoneHit(answered, await workstreamsOf(ctx.projectRoot)) };
80
+ }
81
+ function toPhoneHit(hit, workstreams) {
82
+ const where = hit.workstreamRoot ? (0, import_workstream_words.sideLabel)(hit.workstreamRoot, workstreams) : null;
83
+ return {
84
+ ref: hit.ref,
85
+ breach: hit.breach,
86
+ headline: (0, import_breakpoint_words.hitHeadline)(hit, where),
87
+ why: (0, import_breakpoint_words.hitWhy)(hit),
88
+ labels: (0, import_breakpoint_words.decisionLabels)(hit),
89
+ breakpointNote: hit.breakpointNote,
90
+ proposalUid: hit.kind === "proposal" ? hit.breakpointTarget : null,
91
+ agent: hit.agent,
92
+ planUid: hit.planUid,
93
+ itemUid: hit.itemUid,
94
+ path: hit.path,
95
+ hitAt: hit.hitAt,
96
+ decision: hit.decision,
97
+ note: hit.note,
98
+ answeredAt: hit.answeredAt
99
+ };
100
+ }
101
+ async function workstreamsOf(projectRoot) {
102
+ if (!projectRoot) return [];
103
+ try {
104
+ return await (0, import_workstream_service.listWorkstreams)(projectRoot, { includeIdle: true });
105
+ } catch {
106
+ return [];
107
+ }
108
+ }
109
+ // Annotate the CommonJS export names for ESM import in node:
110
+ 0 && (module.exports = {
111
+ BREAKPOINT_METHODS,
112
+ handleBreakpointMethod,
113
+ phoneWaiting,
114
+ toPhoneHit
115
+ });