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,584 @@
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 breakpoint_service_exports = {};
29
+ __export(breakpoint_service_exports, {
30
+ ACTIVE_SELECT: () => ACTIVE_SELECT,
31
+ BREAKPOINT_KINDS: () => import_types.BREAKPOINT_KINDS,
32
+ BreakpointError: () => BreakpointError,
33
+ DECISIONS: () => import_types.BREAKPOINT_DECISIONS,
34
+ HIT_SELECT: () => HIT_SELECT,
35
+ MAX_NOTE: () => MAX_NOTE,
36
+ SIGNAL_BREAK_KINDS: () => import_types.SIGNAL_BREAK_KINDS,
37
+ answerHit: () => answerHit,
38
+ cleanNote: () => cleanNote,
39
+ clearBreakpoint: () => clearBreakpoint,
40
+ codeCovers: () => codeCovers,
41
+ codeScope: () => codeScope,
42
+ codeTarget: () => codeTarget,
43
+ countWaitingHits: () => countWaitingHits,
44
+ decisionView: () => decisionView,
45
+ docBreakpoint: () => docBreakpoint,
46
+ enforce: () => enforce,
47
+ getBreakpoint: () => getBreakpoint,
48
+ getHit: () => getHit,
49
+ guardedCall: () => guardedCall,
50
+ hitPayload: () => hitPayload,
51
+ listBreakpoints: () => listBreakpoints,
52
+ listHits: () => listHits,
53
+ onHitAnswered: () => onHitAnswered,
54
+ pausedResult: () => pausedResult,
55
+ rowsOf: () => rowsOf,
56
+ setBreakpoint: () => setBreakpoint,
57
+ specBreakpointOn: () => specBreakpointOn,
58
+ steerText: () => steerText,
59
+ stoppedResult: () => stoppedResult,
60
+ subjectOf: () => subjectOf,
61
+ toBreakpointRow: () => toBreakpointRow,
62
+ toHitRow: () => toHitRow
63
+ });
64
+ module.exports = __toCommonJS(breakpoint_service_exports);
65
+ var import_node_crypto = require("node:crypto");
66
+ var import_node_fs = __toESM(require("node:fs"));
67
+ var import_node_path = __toESM(require("node:path"));
68
+ var import_database = require("./database");
69
+ var import_agent_event_log = require("./agent-event-log");
70
+ var import_types = require("../../shared/types");
71
+ var import_push_notification_service = require("./push-notification-service");
72
+ var import_spec_links_service = require("./spec-links-service");
73
+ const MAX_NOTE = 1e3;
74
+ const MAX_DEPTH = 50;
75
+ function rowsOf(sql, params = []) {
76
+ const res = (0, import_database.getDb)().exec(sql, params);
77
+ if (!res.length) return [];
78
+ const { columns, values } = res[0];
79
+ return values.map((v) => Object.fromEntries(columns.map((c, i) => [c, v[i]])));
80
+ }
81
+ function cleanNote(raw) {
82
+ if (typeof raw !== "string") return null;
83
+ const s = raw.replace(/\r\n?/g, "\n").replace(/[\u0000-\u0009\u000b-\u001f\u007f]+/g, " ").trim();
84
+ return s ? s.slice(0, MAX_NOTE) : null;
85
+ }
86
+ function guardedCall(tool, args) {
87
+ const a = args ?? {};
88
+ const uid = typeof a.uid === "string" && a.uid ? a.uid : null;
89
+ if (!uid) return null;
90
+ const actions = [];
91
+ switch (tool) {
92
+ case "claim_item":
93
+ actions.push({ action: "claim", kind: "task" });
94
+ break;
95
+ case "update_item":
96
+ if (a.status === "in_progress") actions.push({ action: "claim", kind: "task" });
97
+ if (a.status === "done") actions.push({ action: "done", kind: "task" });
98
+ if (a.title !== void 0 || a.body !== void 0 || a.template !== void 0) actions.push({ action: "edit", kind: "spec" });
99
+ break;
100
+ case "restore_item_version":
101
+ actions.push({ action: "edit", kind: "spec" });
102
+ break;
103
+ case "delete_item":
104
+ actions.push({ action: "delete", kind: "task" }, { action: "delete", kind: "spec" });
105
+ break;
106
+ default:
107
+ return null;
108
+ }
109
+ return actions.length ? { itemUid: uid, actions } : null;
110
+ }
111
+ function itemRow(uid) {
112
+ return rowsOf("SELECT uid, parent_uid, plan_uid, title FROM plan_items WHERE uid = ?", [uid])[0] ?? null;
113
+ }
114
+ function lineage(uid) {
115
+ const out = [];
116
+ const seen = /* @__PURE__ */ new Set();
117
+ let at = uid;
118
+ while (at && !seen.has(at) && out.length < MAX_DEPTH) {
119
+ seen.add(at);
120
+ const row = itemRow(at);
121
+ if (!row) break;
122
+ out.push(row);
123
+ at = row.parent_uid;
124
+ }
125
+ return out;
126
+ }
127
+ function toBreakpoint(r) {
128
+ return {
129
+ id: r.id,
130
+ kind: r.kind,
131
+ target: r.target,
132
+ targetTitle: r.title ?? null,
133
+ planUid: r.plan_uid,
134
+ projectRoot: r.project_root ?? null,
135
+ note: r.note,
136
+ createdAt: Number(r.created_at),
137
+ createdBy: r.created_by,
138
+ createdByType: r.created_by_type
139
+ };
140
+ }
141
+ const ACTIVE_SELECT = `SELECT b.id, b.kind, b.target, b.plan_uid, b.project_root, b.note, b.created_at, b.created_by, b.created_by_type,
142
+ COALESCE(i.title, d.title) AS title
143
+ FROM breakpoints b LEFT JOIN plan_items i ON i.uid = b.target LEFT JOIN plan_documents d ON d.uid = b.target WHERE b.cleared_at IS NULL`;
144
+ function toBreakpointRow(r) {
145
+ return toBreakpoint(r);
146
+ }
147
+ function listBreakpoints(planUid) {
148
+ const rows = planUid ? rowsOf(`${ACTIVE_SELECT} AND b.plan_uid = ? ORDER BY b.created_at`, [planUid]) : rowsOf(`${ACTIVE_SELECT} ORDER BY b.created_at`);
149
+ return rows.map(toBreakpoint);
150
+ }
151
+ function getBreakpoint(id) {
152
+ const r = rowsOf(`${ACTIVE_SELECT} AND b.id = ?`, [id])[0];
153
+ return r ? toBreakpoint(r) : null;
154
+ }
155
+ class BreakpointError extends Error {
156
+ constructor(message, status) {
157
+ super(message);
158
+ this.status = status;
159
+ }
160
+ status;
161
+ }
162
+ function setBreakpoint(input) {
163
+ if (!import_types.BREAKPOINT_KINDS.includes(input.kind)) throw new BreakpointError(`kind must be one of ${import_types.BREAKPOINT_KINDS.join(", ")}`, 400);
164
+ if (input.kind === "proposal") throw new BreakpointError("A proposal breakpoint is raised by a spec change being proposed, not set", 400);
165
+ if (input.kind === "code") return setCodeBreakpoint(input);
166
+ if (input.kind === "signal") return setSignalBreakpoint(input);
167
+ if (input.docUid !== void 0) return setDocBreakpoint(input);
168
+ const item = typeof input.itemUid === "string" ? itemRow(input.itemUid) : null;
169
+ if (!item) throw new BreakpointError("Item not found", 404);
170
+ const kind = input.kind;
171
+ const existing = rowsOf(`${ACTIVE_SELECT} AND b.kind = ? AND b.target = ?`, [kind, item.uid])[0];
172
+ if (existing) return { breakpoint: toBreakpoint(existing), created: false };
173
+ const id = `bp_${(0, import_node_crypto.randomBytes)(6).toString("hex")}`;
174
+ (0, import_database.getDb)().run(
175
+ "INSERT INTO breakpoints (id, kind, target, plan_uid, note, created_at, created_by, created_by_type) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
176
+ [id, kind, item.uid, item.plan_uid, cleanNote(input.note), input.now ?? Date.now(), input.by, input.byType]
177
+ );
178
+ return { breakpoint: getBreakpoint(id), created: true };
179
+ }
180
+ function setDocBreakpoint(input) {
181
+ if (input.kind !== "spec") throw new BreakpointError("A plan document takes a spec breakpoint", 400);
182
+ const doc = typeof input.docUid === "string" ? rowsOf("SELECT uid, plan_uid FROM plan_documents WHERE uid = ?", [input.docUid])[0] : void 0;
183
+ if (!doc) throw new BreakpointError("Document not found", 404);
184
+ const existing = rowsOf(`${ACTIVE_SELECT} AND b.kind = 'spec' AND b.target = ?`, [doc.uid])[0];
185
+ if (existing) return { breakpoint: toBreakpoint(existing), created: false };
186
+ const id = `bp_${(0, import_node_crypto.randomBytes)(6).toString("hex")}`;
187
+ (0, import_database.getDb)().run(
188
+ "INSERT INTO breakpoints (id, kind, target, plan_uid, note, created_at, created_by, created_by_type) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
189
+ [id, "spec", doc.uid, doc.plan_uid, cleanNote(input.note), input.now ?? Date.now(), input.by, input.byType]
190
+ );
191
+ return { breakpoint: getBreakpoint(id), created: true };
192
+ }
193
+ function docBreakpoint(docUid) {
194
+ const r = rowsOf(`${ACTIVE_SELECT} AND b.kind = 'spec' AND b.target = ?`, [docUid])[0];
195
+ return r ? toBreakpoint(r) : null;
196
+ }
197
+ const SYMBOL_RE = /^[A-Za-z_$][\w$.#()]{0,99}$/;
198
+ function codeTarget(projectRoot, rawPath, rawSymbol) {
199
+ if (typeof rawPath !== "string") throw new BreakpointError("A code breakpoint needs a path in the project", 400);
200
+ let p = rawPath.trim().replace(/^\.\/+/, "");
201
+ const folderHint = p.endsWith("/");
202
+ p = p.replace(/\/+$/, "").replace(/\/{2,}/g, "/");
203
+ if (!p || p.length > 300 || p.includes("\0") || p.includes("\\") || p.startsWith("/") || /^[A-Za-z]:/.test(p) || p.startsWith("~") || p.split("/").some((x) => x === ".." || x === "." || x === "")) {
204
+ throw new BreakpointError("A code breakpoint's path must be relative to the project, with no ..", 400);
205
+ }
206
+ let stat;
207
+ try {
208
+ stat = import_node_fs.default.statSync(import_node_path.default.join(projectRoot, p));
209
+ } catch {
210
+ throw new BreakpointError(`No ${p} in the opened project`, 404);
211
+ }
212
+ const folder = stat.isDirectory();
213
+ if (folderHint && !folder) throw new BreakpointError(`${p} is a file, not a folder`, 400);
214
+ if (rawSymbol !== void 0 && rawSymbol !== null && rawSymbol !== "") {
215
+ if (folder) throw new BreakpointError("A function breakpoint is on a file, not a folder", 400);
216
+ if (typeof rawSymbol !== "string" || !SYMBOL_RE.test(rawSymbol)) throw new BreakpointError("symbol must be a name from the file", 400);
217
+ return `${p}#${rawSymbol}`;
218
+ }
219
+ return folder ? `${p}/` : p;
220
+ }
221
+ function codeScope(target) {
222
+ const i = target.indexOf("#");
223
+ return i === -1 ? target : target.slice(0, i);
224
+ }
225
+ function codeCovers(target, file) {
226
+ const scope = codeScope(target);
227
+ return scope.endsWith("/") ? file.startsWith(scope) : file === scope;
228
+ }
229
+ function setCodeBreakpoint(input) {
230
+ if (!input.projectRoot) throw new BreakpointError("No project is open", 409);
231
+ const target = codeTarget(input.projectRoot, input.path, input.symbol);
232
+ const existing = rowsOf(`${ACTIVE_SELECT} AND b.kind = 'code' AND b.target = ? AND b.project_root = ?`, [target, input.projectRoot])[0];
233
+ if (existing) return { breakpoint: toBreakpoint(existing), created: false };
234
+ const id = `bp_${(0, import_node_crypto.randomBytes)(6).toString("hex")}`;
235
+ (0, import_database.getDb)().run(
236
+ "INSERT INTO breakpoints (id, kind, target, project_root, note, created_at, created_by, created_by_type) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
237
+ [id, "code", target, input.projectRoot, cleanNote(input.note), input.now ?? Date.now(), input.by, input.byType]
238
+ );
239
+ return { breakpoint: getBreakpoint(id), created: true };
240
+ }
241
+ function setSignalBreakpoint(input) {
242
+ if (!input.projectRoot) throw new BreakpointError("No project is open", 409);
243
+ if (!import_types.SIGNAL_BREAK_KINDS.includes(input.signal)) {
244
+ throw new BreakpointError(`signal must be one of ${import_types.SIGNAL_BREAK_KINDS.join(", ")}`, 400);
245
+ }
246
+ const target = input.signal;
247
+ const existing = rowsOf(`${ACTIVE_SELECT} AND b.kind = 'signal' AND b.target = ? AND b.project_root = ?`, [target, input.projectRoot])[0];
248
+ if (existing) return { breakpoint: toBreakpoint(existing), created: false };
249
+ const id = `bp_${(0, import_node_crypto.randomBytes)(6).toString("hex")}`;
250
+ (0, import_database.getDb)().run(
251
+ "INSERT INTO breakpoints (id, kind, target, project_root, note, created_at, created_by, created_by_type) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
252
+ [id, "signal", target, input.projectRoot, cleanNote(input.note), input.now ?? Date.now(), input.by, input.byType]
253
+ );
254
+ return { breakpoint: getBreakpoint(id), created: true };
255
+ }
256
+ function clearBreakpoint(input) {
257
+ const bp = getBreakpoint(input.id);
258
+ if (!bp) return { cleared: false, released: [] };
259
+ if (bp.kind === "proposal") throw new BreakpointError("A spec proposal is decided on the proposal: accept, amend or reject", 400);
260
+ const now = input.now ?? Date.now();
261
+ (0, import_database.getDb)().run("UPDATE breakpoints SET cleared_at = ?, cleared_by = ?, cleared_by_type = ? WHERE id = ?", [now, input.by, input.byType, bp.id]);
262
+ const released = [];
263
+ for (const hit of listHits({ state: "waiting" }).filter((h) => h.breakpointId === bp.id)) {
264
+ const answered = answerHit({ ref: hit.ref, decision: "continue", note: "The breakpoint was cleared.", by: input.by, byType: input.byType, now });
265
+ if (answered) released.push(answered);
266
+ }
267
+ return { cleared: true, released };
268
+ }
269
+ function breakpointFor(kind, action, chain) {
270
+ const set = rowsOf(`${ACTIVE_SELECT} AND b.kind = ? AND b.plan_uid = ? ORDER BY b.created_at`, [kind, chain[0].plan_uid]).map(toBreakpoint);
271
+ if (!set.length) return null;
272
+ for (const row of chain) {
273
+ const bp = set.find((b) => b.target === row.uid);
274
+ if (bp) return bp;
275
+ }
276
+ if (action === "delete") {
277
+ const deleted = chain[0].uid;
278
+ return set.find((b) => lineage(b.target).some((r) => r.uid === deleted)) ?? null;
279
+ }
280
+ return null;
281
+ }
282
+ function specBreakpointOn(itemUid) {
283
+ try {
284
+ const chain = lineage(itemUid);
285
+ return chain.length ? breakpointFor("spec", "edit", chain) : null;
286
+ } catch {
287
+ return null;
288
+ }
289
+ }
290
+ const HIT_SELECT = `SELECT h.*, b.kind, b.note AS bp_note, b.target AS bp_target, COALESCE(i.title, d.title) AS title
291
+ FROM breakpoint_hits h LEFT JOIN breakpoints b ON b.id = h.breakpoint_id LEFT JOIN plan_items i ON i.uid = h.item_uid
292
+ LEFT JOIN plan_documents d ON d.uid = h.item_uid`;
293
+ function toHitRow(r) {
294
+ return toHit(r);
295
+ }
296
+ function relianceOf(r) {
297
+ if (r.kind !== "spec" || r.action !== "edit" || Number(r.breach) === 1) return null;
298
+ const rel = (0, import_spec_links_service.reliedOnBy)(r.item_uid);
299
+ if (rel.length === 0) return null;
300
+ return { tasks: new Set(rel.map((x) => x.itemUid)).size, plans: new Set(rel.map((x) => x.planUid)).size };
301
+ }
302
+ function diskChangeOf(r) {
303
+ if (r.action !== "disk") return null;
304
+ const held = rowsOf("SELECT title, body FROM plan_doc_disk_holds WHERE ref = ?", [r.ref])[0];
305
+ const doc = rowsOf("SELECT title, body FROM plan_documents WHERE uid = ?", [r.item_uid])[0];
306
+ if (!held || !doc) return null;
307
+ return { beforeTitle: doc.title, afterTitle: held.title, before: doc.body, after: held.body };
308
+ }
309
+ function toHit(r) {
310
+ const reliedOn = relianceOf(r);
311
+ const diskChange = diskChangeOf(r);
312
+ return {
313
+ ref: r.ref,
314
+ breakpointId: r.breakpoint_id,
315
+ kind: r.kind ?? null,
316
+ breakpointNote: r.bp_note ?? null,
317
+ breakpointTarget: r.bp_target ?? null,
318
+ tool: r.tool,
319
+ action: r.action,
320
+ itemUid: r.item_uid,
321
+ itemTitle: r.title ?? null,
322
+ path: r.path ?? null,
323
+ breach: Number(r.breach) === 1,
324
+ signalId: r.signal_id ?? null,
325
+ planUid: r.plan_uid,
326
+ agent: r.agent,
327
+ sessionId: r.session_id,
328
+ workstreamRoot: r.workstream_root,
329
+ hitAt: Number(r.hit_at),
330
+ decision: r.decision ?? null,
331
+ note: r.note,
332
+ answeredAt: r.answered_at === null ? null : Number(r.answered_at),
333
+ answeredBy: r.answered_by,
334
+ answeredByType: r.answered_by_type,
335
+ ...reliedOn ? { reliedOn } : {},
336
+ ...diskChange ? { diskChange } : {}
337
+ };
338
+ }
339
+ function getHit(ref) {
340
+ const r = rowsOf(`${HIT_SELECT} WHERE h.ref = ?`, [ref])[0];
341
+ return r ? toHit(r) : null;
342
+ }
343
+ function countWaitingHits() {
344
+ return Number(rowsOf("SELECT COUNT(*) AS n FROM breakpoint_hits h WHERE h.answered_at IS NULL")[0]?.n ?? 0);
345
+ }
346
+ function listHits(q = {}) {
347
+ const where = [];
348
+ const params = [];
349
+ if ((q.state ?? "waiting") === "waiting") where.push("h.answered_at IS NULL");
350
+ if (q.planUid) {
351
+ where.push("h.plan_uid = ?");
352
+ params.push(q.planUid);
353
+ }
354
+ const sql = `${HIT_SELECT}${where.length ? ` WHERE ${where.join(" AND ")}` : ""} ORDER BY h.hit_at DESC LIMIT 200`;
355
+ return rowsOf(sql, params).map(toHit).reverse();
356
+ }
357
+ function hitPayload(hit) {
358
+ return {
359
+ ref: hit.ref,
360
+ kind: hit.kind,
361
+ action: hit.action,
362
+ tool: hit.tool,
363
+ itemUid: hit.itemUid,
364
+ itemTitle: hit.itemTitle,
365
+ ...hit.path ? { path: hit.path } : {},
366
+ ...hit.breach ? { breach: true } : {},
367
+ ...hit.signalId ? { signalId: hit.signalId } : {},
368
+ planUid: hit.planUid,
369
+ agent: hit.agent,
370
+ ...hit.workstreamRoot ? { workstreamRoot: hit.workstreamRoot } : {},
371
+ ...hit.reliedOn ? { reliedOn: hit.reliedOn } : {}
372
+ };
373
+ }
374
+ const answeredListeners = [];
375
+ function onHitAnswered(fn) {
376
+ answeredListeners.push(fn);
377
+ }
378
+ function answerHit(input) {
379
+ const hit = getHit(input.ref);
380
+ if (!hit || hit.answeredAt !== null) return null;
381
+ const note = cleanNote(input.note);
382
+ (0, import_database.getDb)().run(
383
+ "UPDATE breakpoint_hits SET decision = ?, note = ?, answered_at = ?, answered_by = ?, answered_by_type = ? WHERE ref = ? AND answered_at IS NULL",
384
+ [input.decision, note, input.now ?? Date.now(), input.by, input.byType, input.ref]
385
+ );
386
+ const answered = getHit(input.ref);
387
+ (0, import_agent_event_log.recordBreakpointEvent)("breakpoint_answered", {
388
+ ...hitPayload(answered),
389
+ decision: answered.decision,
390
+ note: answered.note,
391
+ waitedMs: (answered.answeredAt ?? 0) - answered.hitAt,
392
+ by: input.by,
393
+ byType: input.byType
394
+ }, input.byType);
395
+ for (const fn of answeredListeners) {
396
+ try {
397
+ fn(answered);
398
+ } catch (err) {
399
+ console.warn("[Breakpoints] answer listener failed:", err);
400
+ }
401
+ }
402
+ return answered;
403
+ }
404
+ function workstreamOf(sessionId) {
405
+ if (!sessionId) return null;
406
+ try {
407
+ return rowsOf("SELECT workstream_root AS root FROM agent_sessions WHERE session_id = ?", [sessionId])[0]?.root ?? null;
408
+ } catch {
409
+ return null;
410
+ }
411
+ }
412
+ function enforce(tool, args, caller, now = Date.now()) {
413
+ let call;
414
+ let chain;
415
+ try {
416
+ call = guardedCall(tool, args);
417
+ if (!call) return { kind: "pass" };
418
+ chain = lineage(call.itemUid);
419
+ if (!chain.length) return { kind: "pass" };
420
+ } catch {
421
+ return { kind: "pass" };
422
+ }
423
+ for (const { action, kind } of call.actions) {
424
+ let bp;
425
+ try {
426
+ bp = breakpointFor(kind, action, chain);
427
+ } catch {
428
+ bp = null;
429
+ }
430
+ if (!bp) continue;
431
+ const open = rowsOf(
432
+ `${HIT_SELECT} WHERE h.breakpoint_id = ? AND h.item_uid = ? AND h.action = ? AND h.agent = ? AND h.consumed_at IS NULL ORDER BY h.hit_at`,
433
+ [bp.id, call.itemUid, action, caller.agent]
434
+ ).map(toHit);
435
+ const answered = open.find((h) => h.answeredAt !== null);
436
+ if (answered) {
437
+ (0, import_database.getDb)().run("UPDATE breakpoint_hits SET consumed_at = ? WHERE ref = ?", [now, answered.ref]);
438
+ if (answered.decision === "stop") return { kind: "stop", hit: answered };
439
+ continue;
440
+ }
441
+ const waiting = open.find((h) => h.answeredAt === null);
442
+ if (waiting) return { kind: "paused", hit: waiting, fresh: false };
443
+ const ref = `bp-${(0, import_node_crypto.randomBytes)(5).toString("hex")}`;
444
+ (0, import_database.getDb)().run(
445
+ `INSERT INTO breakpoint_hits (ref, breakpoint_id, tool, action, item_uid, plan_uid, agent, session_id, workstream_root, hit_at)
446
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
447
+ [ref, bp.id, tool, action, call.itemUid, chain[0].plan_uid, caller.agent, caller.sessionId, workstreamOf(caller.sessionId), now]
448
+ );
449
+ const hit = getHit(ref);
450
+ (0, import_agent_event_log.recordBreakpointEvent)("breakpoint_hit", { ...hitPayload(hit), breakpointId: bp.id, on: bp.target, onTitle: bp.targetTitle }, caller.agent);
451
+ void (0, import_push_notification_service.pushForBreakpoint)(hit).catch(() => {
452
+ });
453
+ return { kind: "paused", hit, fresh: true };
454
+ }
455
+ const spent = rowsOf(
456
+ `${HIT_SELECT} WHERE h.item_uid = ? AND h.agent = ? AND h.consumed_at = ? ORDER BY h.answered_at DESC`,
457
+ [call.itemUid, caller.agent, now]
458
+ ).map(toHit)[0];
459
+ return spent ? { kind: "continue", hit: spent } : { kind: "pass" };
460
+ }
461
+ const DOING = {
462
+ claim: "claiming",
463
+ done: "marking done",
464
+ edit: "changing the description of",
465
+ delete: "deleting",
466
+ edit_code: "changing",
467
+ breach: "changing",
468
+ propose: "changing the spec",
469
+ disk: "changing"
470
+ };
471
+ function subjectOf(hit) {
472
+ return hit.path ?? hit.itemTitle ?? hit.itemUid;
473
+ }
474
+ function said(hit) {
475
+ return hit.answeredByType === "human" ? "A person" : `Someone (${hit.answeredByType ?? "unknown"})`;
476
+ }
477
+ function reliance(hit) {
478
+ if (!hit.reliedOn) return null;
479
+ const rel = (0, import_spec_links_service.reliedOnBy)(hit.itemUid);
480
+ if (rel.length === 0) return null;
481
+ const names = rel.slice(0, 4).map((a) => `"${a.title}" (${a.planTitle})`).join(", ");
482
+ const more = rel.length > 4 ? ` and ${rel.length - 4} more` : "";
483
+ const tasks = new Set(rel.map((x) => x.itemUid)).size;
484
+ const plans = new Set(rel.map((x) => x.planUid)).size;
485
+ return {
486
+ reliedOnBy: rel.map((a) => ({ uid: a.itemUid, title: a.title, plan: a.planTitle })),
487
+ line: ` ${tasks} ${tasks === 1 ? "task" : "tasks"} in ${plans} ${plans === 1 ? "plan" : "plans"} ${tasks === 1 ? "relies" : "rely"} on this page: ${names}${more}. To change a spec others rely on, propose it instead: propose_spec_change(page_uid, section, text, why) is not held, tells their agents so they can say what it means for their work, and a person decides it. If you propose instead, await the proposal's decision rather than this one: this pause stays in the person's inbox for them to answer.`
488
+ };
489
+ }
490
+ function pausedResult(hit) {
491
+ const what = `${DOING[hit.action]} \u201C${subjectOf(hit)}\u201D`;
492
+ const rel = reliance(hit);
493
+ const body = {
494
+ paused: true,
495
+ status: "paused: waiting for a decision",
496
+ ref: hit.ref,
497
+ breakpoint: { kind: hit.kind, note: hit.breakpointNote },
498
+ ...rel ? { reliedOnBy: rel.reliedOnBy } : {},
499
+ message: `paused: waiting for a decision. A person set a breakpoint and wants to be asked before ${what}. Nothing was done. Call await_decision with this ref and wait for their answer, calling it again while it says it is still waiting (this can take a long time; do not work around it). If they say continue, make the same call again.${rel ? rel.line : ""}`
500
+ };
501
+ return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }], _meta: { summary: `Paused at a breakpoint before ${what}` } };
502
+ }
503
+ function stoppedResult(hit) {
504
+ const body = {
505
+ stopped: true,
506
+ ref: hit.ref,
507
+ note: hit.note,
508
+ message: `${said(hit)} answered your breakpoint: stop. Nothing was done.${hit.note ? ` Their note: ${hit.note}` : ""} Do not make this call again unless they ask you to.`
509
+ };
510
+ return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }], _meta: { summary: "Stopped at a breakpoint" } };
511
+ }
512
+ function steerText(hit) {
513
+ if (!hit.note) return null;
514
+ return `${said(hit)} answered your breakpoint (${hit.ref}): continue, with this steer: ${hit.note}`;
515
+ }
516
+ function decisionView(hit) {
517
+ if (hit.answeredAt === null) {
518
+ return {
519
+ status: "waiting",
520
+ ref: hit.ref,
521
+ waitingSince: new Date(hit.hitAt).toISOString(),
522
+ message: "Still waiting for a person. Call await_decision again with the same ref. Do not make the paused call again until they answer."
523
+ };
524
+ }
525
+ if (hit.action === "propose") {
526
+ return {
527
+ status: "answered",
528
+ ref: hit.ref,
529
+ decision: hit.decision === "stop" ? "rejected" : "accepted",
530
+ note: hit.note,
531
+ by: hit.answeredByType,
532
+ at: new Date(hit.answeredAt).toISOString(),
533
+ message: hit.decision === "stop" ? "The spec change was not accepted. Carry on with the spec as it is; the note says why." : "The spec change was accepted and the page has its new version. Work to it."
534
+ };
535
+ }
536
+ const fnAt = hit.breakpointTarget ? hit.breakpointTarget.indexOf("#") : -1;
537
+ const code = fnAt > 0 && hit.breakpointTarget ? `${hit.breakpointTarget.slice(fnAt + 1)} in ${hit.path}` : hit.path;
538
+ const next = hit.breach ? hit.decision === "stop" ? `Stop changing ${code}. Tell the person what you changed there, so they can review or revert it.` : "Carry on; the person has seen the change." : hit.action === "edit_code" ? hit.decision === "stop" ? `Do not change ${code}. Tell the person what you will do instead.` : `Make the edit again; ${code} is open to you now.` : hit.decision === "stop" ? "Do not make the paused call. Stop that work, and tell the person what you will do instead." : "Make the paused call again; it will go through once.";
539
+ return {
540
+ status: "answered",
541
+ ref: hit.ref,
542
+ decision: hit.decision,
543
+ note: hit.note,
544
+ by: hit.answeredByType,
545
+ at: new Date(hit.answeredAt).toISOString(),
546
+ message: next
547
+ };
548
+ }
549
+ // Annotate the CommonJS export names for ESM import in node:
550
+ 0 && (module.exports = {
551
+ ACTIVE_SELECT,
552
+ BREAKPOINT_KINDS,
553
+ BreakpointError,
554
+ DECISIONS,
555
+ HIT_SELECT,
556
+ MAX_NOTE,
557
+ SIGNAL_BREAK_KINDS,
558
+ answerHit,
559
+ cleanNote,
560
+ clearBreakpoint,
561
+ codeCovers,
562
+ codeScope,
563
+ codeTarget,
564
+ countWaitingHits,
565
+ decisionView,
566
+ docBreakpoint,
567
+ enforce,
568
+ getBreakpoint,
569
+ getHit,
570
+ guardedCall,
571
+ hitPayload,
572
+ listBreakpoints,
573
+ listHits,
574
+ onHitAnswered,
575
+ pausedResult,
576
+ rowsOf,
577
+ setBreakpoint,
578
+ specBreakpointOn,
579
+ steerText,
580
+ stoppedResult,
581
+ subjectOf,
582
+ toBreakpointRow,
583
+ toHitRow
584
+ });