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,1223 @@
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 plan_item_service_exports = {};
29
+ __export(plan_item_service_exports, {
30
+ PlanItemStructureError: () => PlanItemStructureError,
31
+ applyRecordedState: () => applyRecordedState,
32
+ assertValidParent: () => assertValidParent,
33
+ claimItem: () => claimItem,
34
+ createItem: () => createItem,
35
+ deleteItem: () => deleteItem,
36
+ dependencyLookup: () => dependencyLookup,
37
+ dependencyStateOf: () => dependencyStateOf,
38
+ getChildren: () => getChildren,
39
+ getEffectiveVisibility: () => getEffectiveVisibility,
40
+ getItem: () => getItem,
41
+ getNextItem: () => getNextItem,
42
+ listAllItems: () => listAllItems,
43
+ listItemSummaries: () => listItemSummaries,
44
+ listItemVersions: () => listItemVersions,
45
+ listItemsForExport: () => listItemsForExport,
46
+ moveItem: () => moveItem,
47
+ planWaits: () => planWaits,
48
+ resolveClaimPolicy: () => resolveClaimPolicy,
49
+ resolveClaimPolicyWithSource: () => resolveClaimPolicyWithSource,
50
+ resolveConstraints: () => resolveConstraints,
51
+ resolveConstraintsWithSource: () => resolveConstraintsWithSource,
52
+ resolveExecutionConfigWithSource: () => resolveExecutionConfigWithSource,
53
+ resolveSkills: () => resolveSkills,
54
+ resolveSkillsWithSource: () => resolveSkillsWithSource,
55
+ restoreItemVersion: () => restoreItemVersion,
56
+ setStateWriteListener: () => setStateWriteListener,
57
+ setStatusChangeListener: () => setStatusChangeListener,
58
+ updateItem: () => updateItem,
59
+ withoutStateRecords: () => withoutStateRecords
60
+ });
61
+ module.exports = __toCommonJS(plan_item_service_exports);
62
+ var import_item_status = require("../../shared/lib/item-status");
63
+ var import_node_crypto = require("node:crypto");
64
+ var import_spec_proposal_withdraw = require("./spec-proposal-withdraw");
65
+ var import_database = require("./database");
66
+ var import_persistence = require("./persistence");
67
+ var import_agent_event_log = require("./agent-event-log");
68
+ var import_skill_model = require("./skill-model");
69
+ var import_plan_event_service = require("./plan-event-service");
70
+ var import_criteria_service = require("./criteria-service");
71
+ var import_plan_dependencies = require("./plan-dependencies");
72
+ var _lazy___plan_file_service = __toESM(require("./plan-file-service"));
73
+ const ITEM_COLUMNS = `uid, plan_uid, parent_uid, sort_order, kind,
74
+ title, body, template,
75
+ status, assignee, assignee_type, assignee_model,
76
+ progress_percent, blocked_reason,
77
+ scope_path, file_specs, symbol_specs, new_connections, removed_conns, dependencies,
78
+ skills, skills_mode, claim_policy, claim_policy_mode, execution_config, execution_config_mode,
79
+ constraints, constraints_mode, requires_approval,
80
+ author, author_type, created_at, updated_at, migrated_from,
81
+ visibility, visibility_override, assignee_session, workstream`;
82
+ function rowToItem(r) {
83
+ return {
84
+ uid: r[0],
85
+ planUid: r[1],
86
+ parentUid: r[2] ?? null,
87
+ sortOrder: r[3],
88
+ kind: r[4],
89
+ title: r[5],
90
+ body: r[6] ?? "",
91
+ template: r[7] ?? null,
92
+ status: r[8] ?? null,
93
+ assignee: r[9] ?? null,
94
+ assigneeType: r[10] ?? null,
95
+ assigneeModel: r[11] ?? null,
96
+ progressPercent: r[12] ?? null,
97
+ blockedReason: r[13] ?? null,
98
+ scopePath: r[14] ?? null,
99
+ fileSpecs: parseJsonArray(r[15]),
100
+ symbolSpecs: parseJsonArray(r[16]),
101
+ newConnections: parseJsonArray(r[17]),
102
+ removedConnections: parseJsonArray(r[18]),
103
+ dependencies: parseJsonArray(r[19]),
104
+ // Phase 17.N-Q
105
+ skills: parseJsonArray(r[20]),
106
+ skillsMode: r[21] ?? "inherit",
107
+ claimPolicy: parseJsonOrNull(r[22]),
108
+ claimPolicyMode: r[23] ?? "inherit",
109
+ executionConfig: parseJsonOrNull(r[24]),
110
+ executionConfigMode: r[25] ?? "inherit",
111
+ // Phase 17.F
112
+ constraints: parseJsonOrNull(r[26]),
113
+ constraintsMode: r[27] ?? "inherit",
114
+ // Phase 17.K
115
+ requiresApproval: !!r[28],
116
+ author: r[29],
117
+ authorType: r[30],
118
+ createdAt: r[31],
119
+ updatedAt: r[32],
120
+ migratedFrom: r[33] ?? null,
121
+ // Phase 3.2 — per-item sharing
122
+ visibility: r[34] ?? "shared",
123
+ overrideParentVisibility: !!r[35],
124
+ assigneeSession: r[36] ?? null,
125
+ workstream: r[37] ?? null
126
+ };
127
+ }
128
+ function parseJsonArray(s) {
129
+ if (!s) return [];
130
+ try {
131
+ const parsed = JSON.parse(s);
132
+ return Array.isArray(parsed) ? parsed : [];
133
+ } catch {
134
+ return [];
135
+ }
136
+ }
137
+ function parseJsonOrNull(s) {
138
+ if (!s) return null;
139
+ try {
140
+ return JSON.parse(s);
141
+ } catch {
142
+ return null;
143
+ }
144
+ }
145
+ function metaSnapshotOf(item) {
146
+ return {
147
+ title: item.title,
148
+ template: item.template,
149
+ status: item.status,
150
+ assignee: item.assignee,
151
+ assigneeType: item.assigneeType,
152
+ assigneeModel: item.assigneeModel,
153
+ progressPercent: item.progressPercent,
154
+ blockedReason: item.blockedReason,
155
+ scopePath: item.scopePath,
156
+ fileSpecs: item.fileSpecs,
157
+ symbolSpecs: item.symbolSpecs,
158
+ newConnections: item.newConnections,
159
+ removedConnections: item.removedConnections,
160
+ dependencies: item.dependencies,
161
+ parentUid: item.parentUid,
162
+ sortOrder: item.sortOrder,
163
+ // Phase 17.N-Q
164
+ skills: item.skills,
165
+ skillsMode: item.skillsMode,
166
+ claimPolicy: item.claimPolicy,
167
+ claimPolicyMode: item.claimPolicyMode,
168
+ executionConfig: item.executionConfig,
169
+ executionConfigMode: item.executionConfigMode,
170
+ // Phase 17.F
171
+ constraints: item.constraints,
172
+ constraintsMode: item.constraintsMode,
173
+ // Phase 17.K
174
+ requiresApproval: item.requiresApproval,
175
+ // Phase 3.2
176
+ visibility: item.visibility,
177
+ overrideParentVisibility: item.overrideParentVisibility,
178
+ // Phase 32 C5.1
179
+ workstream: item.workstream ?? null
180
+ };
181
+ }
182
+ function getItem(uid) {
183
+ const result = (0, import_database.getDb)().exec(
184
+ `SELECT ${ITEM_COLUMNS} FROM plan_items WHERE uid = ?`,
185
+ [uid]
186
+ );
187
+ if (!result[0]?.values[0]) return null;
188
+ return rowToItem(result[0].values[0]);
189
+ }
190
+ function getChildren(planUid, parentUid) {
191
+ const db = (0, import_database.getDb)();
192
+ if (parentUid === null) {
193
+ const r2 = db.exec(
194
+ `SELECT ${ITEM_COLUMNS} FROM plan_items
195
+ WHERE plan_uid = ? AND parent_uid IS NULL
196
+ ORDER BY sort_order ASC, created_at ASC`,
197
+ [planUid]
198
+ );
199
+ return (r2[0]?.values ?? []).map(rowToItem);
200
+ }
201
+ const r = db.exec(
202
+ `SELECT ${ITEM_COLUMNS} FROM plan_items
203
+ WHERE plan_uid = ? AND parent_uid = ?
204
+ ORDER BY sort_order ASC, created_at ASC`,
205
+ [planUid, parentUid]
206
+ );
207
+ return (r[0]?.values ?? []).map(rowToItem);
208
+ }
209
+ function listAllItems(planUid) {
210
+ const r = (0, import_database.getDb)().exec(
211
+ `SELECT ${ITEM_COLUMNS} FROM plan_items
212
+ WHERE plan_uid = ?
213
+ ORDER BY sort_order ASC, created_at ASC`,
214
+ [planUid]
215
+ );
216
+ return (r[0]?.values ?? []).map(rowToItem);
217
+ }
218
+ function listItemSummaries(planUid) {
219
+ const db = (0, import_database.getDb)();
220
+ const r = db.exec(
221
+ `SELECT i.uid, i.plan_uid, i.parent_uid, i.sort_order, i.kind,
222
+ i.title, i.template, i.status, i.assignee, i.progress_percent,
223
+ (SELECT COUNT(*) FROM plan_items c WHERE c.parent_uid = i.uid) AS child_count,
224
+ i.visibility, i.visibility_override
225
+ FROM plan_items i
226
+ WHERE i.plan_uid = ?
227
+ ORDER BY i.sort_order ASC, i.created_at ASC`,
228
+ [planUid]
229
+ );
230
+ if (!r[0]) return [];
231
+ return r[0].values.map((row) => ({
232
+ uid: row[0],
233
+ planUid: row[1],
234
+ parentUid: row[2] ?? null,
235
+ sortOrder: row[3],
236
+ kind: row[4],
237
+ title: row[5],
238
+ template: row[6] ?? null,
239
+ status: row[7] ?? null,
240
+ assignee: row[8] ?? null,
241
+ progressPercent: row[9] ?? null,
242
+ childCount: row[10] ?? 0,
243
+ visibility: row[11] ?? "shared",
244
+ overrideParentVisibility: row[12] === 1
245
+ }));
246
+ }
247
+ function createItemImpl(input) {
248
+ const db = (0, import_database.getDb)();
249
+ const uid = input.uid ?? (0, import_node_crypto.randomUUID)();
250
+ assertValidParent(input.planUid, null, input.parentUid);
251
+ const now = Date.now();
252
+ const createdAt = input.createdAt ?? now;
253
+ const updatedAt = input.updatedAt ?? now;
254
+ let sortOrder = input.sortOrder;
255
+ if (sortOrder === void 0) {
256
+ const r = db.exec(
257
+ input.parentUid == null ? `SELECT COALESCE(MAX(sort_order), -1) + 1
258
+ FROM plan_items WHERE plan_uid = ? AND parent_uid IS NULL` : `SELECT COALESCE(MAX(sort_order), -1) + 1
259
+ FROM plan_items WHERE plan_uid = ? AND parent_uid = ?`,
260
+ input.parentUid == null ? [input.planUid] : [input.planUid, input.parentUid]
261
+ );
262
+ sortOrder = r[0]?.values[0]?.[0] ?? 0;
263
+ }
264
+ const isAction = input.kind === "action";
265
+ db.run(
266
+ `INSERT INTO plan_items
267
+ (uid, plan_uid, parent_uid, sort_order, kind,
268
+ title, body, template,
269
+ status, assignee, assignee_type, assignee_model,
270
+ progress_percent, blocked_reason,
271
+ scope_path, file_specs, symbol_specs, new_connections, removed_conns, dependencies,
272
+ skills, skills_mode, claim_policy, claim_policy_mode, execution_config, execution_config_mode,
273
+ constraints, constraints_mode, requires_approval,
274
+ author, author_type, created_at, updated_at, migrated_from,
275
+ visibility, visibility_override, workstream)
276
+ VALUES (?, ?, ?, ?, ?,
277
+ ?, ?, ?,
278
+ ?, ?, ?, ?,
279
+ ?, ?,
280
+ ?, ?, ?, ?, ?, ?,
281
+ ?, ?, ?, ?, ?, ?,
282
+ ?, ?, ?,
283
+ ?, ?, ?, ?, ?,
284
+ ?, ?, ?)`,
285
+ [
286
+ uid,
287
+ input.planUid,
288
+ input.parentUid ?? null,
289
+ sortOrder,
290
+ input.kind,
291
+ input.title,
292
+ input.body ?? "",
293
+ input.template ?? null,
294
+ isAction ? input.status ?? "pending" : null,
295
+ isAction ? input.assignee ?? null : null,
296
+ isAction ? input.assigneeType ?? null : null,
297
+ isAction ? input.assigneeModel ?? null : null,
298
+ // Phase 15.B — migrator preserves legacy progress / blocker
299
+ // values; native creation passes neither so they default null.
300
+ isAction ? input.progressPercent ?? null : null,
301
+ isAction ? input.blockedReason ?? null : null,
302
+ isAction ? input.scopePath ?? null : null,
303
+ JSON.stringify(isAction ? input.fileSpecs ?? [] : []),
304
+ JSON.stringify(isAction ? input.symbolSpecs ?? [] : []),
305
+ JSON.stringify(isAction ? input.newConnections ?? [] : []),
306
+ JSON.stringify(isAction ? input.removedConnections ?? [] : []),
307
+ JSON.stringify(isAction ? input.dependencies ?? [] : []),
308
+ // Phase 17.N-Q
309
+ // Phase 32 C1: whatever the source (panel, plan file, template), stored normalised.
310
+ JSON.stringify((0, import_skill_model.normaliseSkills)(input.skills).skills),
311
+ input.skillsMode ?? "inherit",
312
+ input.claimPolicy ? JSON.stringify(input.claimPolicy) : null,
313
+ input.claimPolicyMode ?? "inherit",
314
+ input.executionConfig ? JSON.stringify(input.executionConfig) : null,
315
+ input.executionConfigMode ?? "inherit",
316
+ // Phase 17.F
317
+ input.constraints ? JSON.stringify(input.constraints) : null,
318
+ input.constraintsMode ?? "inherit",
319
+ // Phase 17.K
320
+ input.requiresApproval ? 1 : 0,
321
+ input.author,
322
+ input.authorType,
323
+ createdAt,
324
+ updatedAt,
325
+ input.migratedFrom ?? null,
326
+ // Phase 3.2 — per-item sharing
327
+ input.visibility ?? "shared",
328
+ input.overrideParentVisibility ? 1 : 0,
329
+ // Phase 32 C5.1
330
+ input.workstream ?? null
331
+ ]
332
+ );
333
+ (0, import_persistence.markDirty)();
334
+ const item = getItem(uid);
335
+ if (!item) {
336
+ throw new Error(`createItem: failed to read back inserted item ${uid}`);
337
+ }
338
+ writeVersionRow(item, 1, "Created", input.author, input.authorType, createdAt);
339
+ (0, import_plan_event_service.appendPlanEvent)({
340
+ planUid: input.planUid,
341
+ itemUid: uid,
342
+ eventType: "item_created",
343
+ afterState: { uid, kind: input.kind, title: input.title, parentUid: input.parentUid ?? null, sortOrder },
344
+ summary: `${input.kind === "action" ? "\u26A1" : "\u{1F4CB}"} created "${input.title}"`,
345
+ author: input.author,
346
+ authorType: input.authorType,
347
+ createdAt
348
+ });
349
+ return item;
350
+ }
351
+ class PlanItemStructureError extends Error {
352
+ }
353
+ function assertValidParent(planUid, itemUid, parentUid) {
354
+ if (parentUid == null) return;
355
+ if (itemUid !== null && parentUid === itemUid) throw new PlanItemStructureError("An item cannot be its own parent");
356
+ const parent = getItem(parentUid);
357
+ if (!parent) throw new PlanItemStructureError(`No item ${parentUid} to put it under`);
358
+ if (parent.planUid !== planUid) throw new PlanItemStructureError("The new parent belongs to a different plan");
359
+ if (itemUid === null) return;
360
+ const seen = /* @__PURE__ */ new Set([parent.uid]);
361
+ for (let cursor = parent.parentUid; cursor; cursor = getItem(cursor)?.parentUid ?? null) {
362
+ if (cursor === itemUid) throw new PlanItemStructureError("That would put the item under one of its own sub-items");
363
+ if (seen.has(cursor)) break;
364
+ seen.add(cursor);
365
+ }
366
+ }
367
+ let statusListener = null;
368
+ function setStatusChangeListener(fn) {
369
+ statusListener = fn;
370
+ }
371
+ let stateWriteListener = null;
372
+ let stateFromElsewhere = 0;
373
+ function setStateWriteListener(fn) {
374
+ stateWriteListener = fn;
375
+ }
376
+ function withoutStateRecords(fn) {
377
+ stateFromElsewhere++;
378
+ try {
379
+ return fn();
380
+ } finally {
381
+ stateFromElsewhere--;
382
+ }
383
+ }
384
+ function applyRecordedState(uid, state, author) {
385
+ return withoutStateRecords(() => updateItemImpl(uid, { ...state, ...author, changeSummary: "from a teammate's record" }));
386
+ }
387
+ const RECORDED_FIELDS = ["status", "assignee", "progressPercent", "blockedReason"];
388
+ function updateItemImpl(uid, updates) {
389
+ const db = (0, import_database.getDb)();
390
+ const before = getItem(uid);
391
+ if (!before) return null;
392
+ if (updates.parentUid !== void 0 && updates.parentUid !== before.parentUid) {
393
+ assertValidParent(before.planUid, uid, updates.parentUid);
394
+ }
395
+ const now = Date.now();
396
+ const sets = ["updated_at = ?"];
397
+ const params = [now];
398
+ let contentChanged = false;
399
+ const structuralEvents = [];
400
+ if (updates.title !== void 0 && updates.title !== before.title) {
401
+ sets.push("title = ?");
402
+ params.push(updates.title);
403
+ contentChanged = true;
404
+ structuralEvents.push({
405
+ eventType: "item_renamed",
406
+ before: { title: before.title },
407
+ after: { title: updates.title },
408
+ kind: "renamed"
409
+ });
410
+ }
411
+ const bodyChanged = updates.body !== void 0 && updates.body !== before.body;
412
+ if (bodyChanged) {
413
+ sets.push("body = ?");
414
+ params.push(updates.body);
415
+ contentChanged = true;
416
+ }
417
+ if (updates.template !== void 0 && updates.template !== before.template) {
418
+ sets.push("template = ?");
419
+ params.push(updates.template);
420
+ contentChanged = true;
421
+ }
422
+ if (before.kind === "action") {
423
+ if (updates.status !== void 0 && updates.status !== before.status) {
424
+ sets.push("status = ?");
425
+ params.push(updates.status);
426
+ contentChanged = true;
427
+ structuralEvents.push({
428
+ eventType: "status_changed",
429
+ before: { status: before.status },
430
+ after: { status: updates.status },
431
+ kind: "status_changed"
432
+ });
433
+ }
434
+ if (updates.assignee !== void 0 && updates.assignee !== before.assignee) {
435
+ sets.push("assignee = ?");
436
+ params.push(updates.assignee);
437
+ contentChanged = true;
438
+ }
439
+ if (updates.assigneeType !== void 0 && updates.assigneeType !== before.assigneeType) {
440
+ sets.push("assignee_type = ?");
441
+ params.push(updates.assigneeType);
442
+ contentChanged = true;
443
+ }
444
+ if (updates.assigneeModel !== void 0 && updates.assigneeModel !== before.assigneeModel) {
445
+ sets.push("assignee_model = ?");
446
+ params.push(updates.assigneeModel);
447
+ contentChanged = true;
448
+ }
449
+ if (updates.assigneeSession !== void 0 && updates.assigneeSession !== (before.assigneeSession ?? null)) {
450
+ sets.push("assignee_session = ?");
451
+ params.push(updates.assigneeSession);
452
+ } else if (updates.assignee === null && before.assigneeSession) {
453
+ sets.push("assignee_session = NULL");
454
+ }
455
+ if (updates.progressPercent !== void 0 && updates.progressPercent !== before.progressPercent) {
456
+ sets.push("progress_percent = ?");
457
+ params.push(updates.progressPercent);
458
+ contentChanged = true;
459
+ }
460
+ if (updates.blockedReason !== void 0 && updates.blockedReason !== before.blockedReason) {
461
+ sets.push("blocked_reason = ?");
462
+ params.push(updates.blockedReason);
463
+ contentChanged = true;
464
+ }
465
+ if (updates.scopePath !== void 0 && updates.scopePath !== before.scopePath) {
466
+ sets.push("scope_path = ?");
467
+ params.push(updates.scopePath);
468
+ contentChanged = true;
469
+ }
470
+ if (updates.fileSpecs !== void 0) {
471
+ sets.push("file_specs = ?");
472
+ params.push(JSON.stringify(updates.fileSpecs));
473
+ contentChanged = true;
474
+ }
475
+ if (updates.symbolSpecs !== void 0) {
476
+ sets.push("symbol_specs = ?");
477
+ params.push(JSON.stringify(updates.symbolSpecs));
478
+ contentChanged = true;
479
+ }
480
+ if (updates.newConnections !== void 0 || updates.removedConnections !== void 0) {
481
+ let effectiveNew = updates.newConnections ?? before.newConnections ?? [];
482
+ let effectiveRemoved = updates.removedConnections ?? before.removedConnections ?? [];
483
+ if (effectiveNew.length > 0 && effectiveRemoved.length > 0) {
484
+ const edgeKey = (e) => `${e.from}\0${e.to}`;
485
+ const newKeys = new Set(effectiveNew.map(edgeKey));
486
+ const removedKeys = new Set(effectiveRemoved.map(edgeKey));
487
+ const dupes = new Set([...newKeys].filter((k) => removedKeys.has(k)));
488
+ if (dupes.size > 0) {
489
+ effectiveNew = effectiveNew.filter((e) => !dupes.has(edgeKey(e)));
490
+ effectiveRemoved = effectiveRemoved.filter((e) => !dupes.has(edgeKey(e)));
491
+ }
492
+ }
493
+ sets.push("new_connections = ?");
494
+ params.push(JSON.stringify(effectiveNew));
495
+ sets.push("removed_conns = ?");
496
+ params.push(JSON.stringify(effectiveRemoved));
497
+ contentChanged = true;
498
+ }
499
+ if (updates.dependencies !== void 0) {
500
+ sets.push("dependencies = ?");
501
+ params.push(JSON.stringify(updates.dependencies));
502
+ contentChanged = true;
503
+ }
504
+ }
505
+ if (updates.skills !== void 0) {
506
+ sets.push("skills = ?");
507
+ params.push(JSON.stringify((0, import_skill_model.normaliseSkills)(updates.skills).skills));
508
+ contentChanged = true;
509
+ }
510
+ if (updates.skillsMode !== void 0 && updates.skillsMode !== before.skillsMode) {
511
+ sets.push("skills_mode = ?");
512
+ params.push(updates.skillsMode);
513
+ contentChanged = true;
514
+ }
515
+ if (updates.workstream !== void 0 && (updates.workstream ?? null) !== (before.workstream ?? null)) {
516
+ sets.push("workstream = ?");
517
+ params.push(updates.workstream ?? null);
518
+ contentChanged = true;
519
+ }
520
+ if (updates.claimPolicy !== void 0) {
521
+ sets.push("claim_policy = ?");
522
+ params.push(updates.claimPolicy ? JSON.stringify(updates.claimPolicy) : null);
523
+ contentChanged = true;
524
+ }
525
+ if (updates.claimPolicyMode !== void 0 && updates.claimPolicyMode !== before.claimPolicyMode) {
526
+ sets.push("claim_policy_mode = ?");
527
+ params.push(updates.claimPolicyMode);
528
+ contentChanged = true;
529
+ }
530
+ if (updates.executionConfig !== void 0) {
531
+ sets.push("execution_config = ?");
532
+ params.push(updates.executionConfig ? JSON.stringify(updates.executionConfig) : null);
533
+ contentChanged = true;
534
+ }
535
+ if (updates.executionConfigMode !== void 0 && updates.executionConfigMode !== before.executionConfigMode) {
536
+ sets.push("execution_config_mode = ?");
537
+ params.push(updates.executionConfigMode);
538
+ contentChanged = true;
539
+ }
540
+ if (updates.constraints !== void 0) {
541
+ sets.push("constraints = ?");
542
+ params.push(updates.constraints ? JSON.stringify(updates.constraints) : null);
543
+ contentChanged = true;
544
+ }
545
+ if (updates.constraintsMode !== void 0 && updates.constraintsMode !== before.constraintsMode) {
546
+ sets.push("constraints_mode = ?");
547
+ params.push(updates.constraintsMode);
548
+ contentChanged = true;
549
+ }
550
+ if (updates.requiresApproval !== void 0 && updates.requiresApproval !== before.requiresApproval) {
551
+ sets.push("requires_approval = ?");
552
+ params.push(updates.requiresApproval ? 1 : 0);
553
+ contentChanged = true;
554
+ }
555
+ if (updates.visibility !== void 0 && updates.visibility !== before.visibility) {
556
+ sets.push("visibility = ?");
557
+ params.push(updates.visibility);
558
+ contentChanged = true;
559
+ }
560
+ if (updates.overrideParentVisibility !== void 0 && updates.overrideParentVisibility !== before.overrideParentVisibility) {
561
+ sets.push("visibility_override = ?");
562
+ params.push(updates.overrideParentVisibility ? 1 : 0);
563
+ contentChanged = true;
564
+ }
565
+ if (updates.parentUid !== void 0 && updates.parentUid !== before.parentUid) {
566
+ sets.push("parent_uid = ?");
567
+ params.push(updates.parentUid);
568
+ structuralEvents.push({
569
+ eventType: "reparented",
570
+ before: { parentUid: before.parentUid },
571
+ after: { parentUid: updates.parentUid },
572
+ kind: "reparented"
573
+ });
574
+ }
575
+ if (updates.sortOrder !== void 0 && updates.sortOrder !== before.sortOrder) {
576
+ sets.push("sort_order = ?");
577
+ params.push(updates.sortOrder);
578
+ structuralEvents.push({
579
+ eventType: "reordered",
580
+ before: { sortOrder: before.sortOrder },
581
+ after: { sortOrder: updates.sortOrder },
582
+ kind: "reordered"
583
+ });
584
+ }
585
+ if (sets.length === 1) {
586
+ return before;
587
+ }
588
+ params.push(uid);
589
+ db.run(`UPDATE plan_items SET ${sets.join(", ")} WHERE uid = ?`, params);
590
+ (0, import_persistence.markDirty)();
591
+ const after = getItem(uid);
592
+ if (!after) return null;
593
+ after.updatedAt = now;
594
+ if (contentChanged) {
595
+ const version = nextVersionFor(uid);
596
+ writeVersionRow(after, version, updates.changeSummary ?? null, updates.author, updates.authorType, now);
597
+ if (bodyChanged) {
598
+ (0, import_agent_event_log.recordBodyEdit)({
599
+ kind: "item",
600
+ planUid: after.planUid,
601
+ uid: after.uid,
602
+ title: after.title,
603
+ version,
604
+ author: updates.author ?? null,
605
+ authorType: updates.authorType ?? null,
606
+ changeSummary: updates.changeSummary ?? null
607
+ });
608
+ }
609
+ }
610
+ for (const ev of structuralEvents) {
611
+ (0, import_plan_event_service.appendPlanEvent)({
612
+ planUid: after.planUid,
613
+ itemUid: after.uid,
614
+ eventType: ev.eventType,
615
+ beforeState: ev.before,
616
+ afterState: ev.after,
617
+ summary: structuralSummary(after, ev.kind, ev.before, ev.after),
618
+ author: updates.author,
619
+ authorType: updates.authorType
620
+ });
621
+ }
622
+ if (statusListener && structuralEvents.some((ev) => ev.kind === "status_changed")) {
623
+ try {
624
+ statusListener({ planUid: after.planUid, itemUid: after.uid, status: after.status ?? null });
625
+ } catch {
626
+ }
627
+ }
628
+ if (stateWriteListener && !stateFromElsewhere && after.kind === "action" && RECORDED_FIELDS.some((k) => (after[k] ?? null) !== (before[k] ?? null))) {
629
+ try {
630
+ stateWriteListener(after, { author: updates.author ?? "someone", authorType: updates.authorType ?? "unknown" });
631
+ } catch {
632
+ }
633
+ }
634
+ return after;
635
+ }
636
+ function moveItemImpl(uid, input) {
637
+ const before = getItem(uid);
638
+ if (!before) return null;
639
+ if (input.newParentUid !== void 0 && input.newParentUid !== before.parentUid) {
640
+ assertValidParent(before.planUid, uid, input.newParentUid);
641
+ }
642
+ const now = Date.now();
643
+ const db = (0, import_database.getDb)();
644
+ const sets = ["updated_at = ?"];
645
+ const params = [now];
646
+ let isReparent = false;
647
+ let isReorder = false;
648
+ if (input.newParentUid !== void 0 && input.newParentUid !== before.parentUid) {
649
+ sets.push("parent_uid = ?");
650
+ params.push(input.newParentUid);
651
+ isReparent = true;
652
+ }
653
+ if (input.newSortOrder !== void 0 && input.newSortOrder !== before.sortOrder) {
654
+ sets.push("sort_order = ?");
655
+ params.push(input.newSortOrder);
656
+ isReorder = true;
657
+ }
658
+ if (sets.length === 1) return before;
659
+ params.push(uid);
660
+ db.run(`UPDATE plan_items SET ${sets.join(", ")} WHERE uid = ?`, params);
661
+ (0, import_persistence.markDirty)();
662
+ (0, import_plan_event_service.appendPlanEvent)({
663
+ planUid: before.planUid,
664
+ itemUid: uid,
665
+ eventType: isReparent ? "item_moved" : "reordered",
666
+ beforeState: { parentUid: before.parentUid, sortOrder: before.sortOrder },
667
+ afterState: {
668
+ parentUid: input.newParentUid ?? before.parentUid,
669
+ sortOrder: input.newSortOrder ?? before.sortOrder
670
+ },
671
+ summary: input.summary ?? defaultMoveSummary(before, isReparent, isReorder),
672
+ author: input.author,
673
+ authorType: input.authorType
674
+ });
675
+ return getItem(uid);
676
+ }
677
+ function deleteItemImpl(uid, input) {
678
+ const db = (0, import_database.getDb)();
679
+ const root = getItem(uid);
680
+ if (!root) return [];
681
+ const cascade = input.cascade !== false;
682
+ const toDelete = cascade ? collectSubtree(uid) : [uid];
683
+ const beforeSnapshots = [];
684
+ for (const u of toDelete) {
685
+ const item = getItem(u);
686
+ if (item) beforeSnapshots.push({ uid: u, row: item });
687
+ }
688
+ for (const u of [...toDelete].reverse()) {
689
+ db.run(`DELETE FROM plan_item_versions WHERE item_uid = ?`, [u]);
690
+ db.run(`DELETE FROM plan_items WHERE uid = ?`, [u]);
691
+ }
692
+ (0, import_persistence.markDirty)();
693
+ (0, import_plan_event_service.appendPlanEvent)({
694
+ planUid: root.planUid,
695
+ itemUid: uid,
696
+ eventType: "item_deleted",
697
+ beforeState: { items: beforeSnapshots, cascade },
698
+ summary: cascade && toDelete.length > 1 ? `\u{1F5D1} deleted "${root.title}" + ${toDelete.length - 1} child${toDelete.length === 2 ? "" : "ren"}` : `\u{1F5D1} deleted "${root.title}"`,
699
+ author: input.author,
700
+ authorType: input.authorType
701
+ });
702
+ return toDelete;
703
+ }
704
+ function collectSubtree(rootUid) {
705
+ const db = (0, import_database.getDb)();
706
+ const result = [];
707
+ const stack = [rootUid];
708
+ while (stack.length > 0) {
709
+ const u = stack.pop();
710
+ result.push(u);
711
+ const r = db.exec(`SELECT uid FROM plan_items WHERE parent_uid = ?`, [u]);
712
+ if (r[0]) {
713
+ for (const row of r[0].values) stack.push(row[0]);
714
+ }
715
+ }
716
+ return result;
717
+ }
718
+ function nextVersionFor(itemUid) {
719
+ const r = (0, import_database.getDb)().exec(
720
+ `SELECT COALESCE(MAX(version), 0) + 1 FROM plan_item_versions WHERE item_uid = ?`,
721
+ [itemUid]
722
+ );
723
+ return r[0]?.values[0]?.[0] ?? 1;
724
+ }
725
+ function writeVersionRow(item, version, changeSummary, author, authorType, createdAt) {
726
+ (0, import_database.getDb)().run(
727
+ `INSERT INTO plan_item_versions
728
+ (item_uid, version, body_snapshot, meta_snapshot, change_summary, author, author_type, created_at)
729
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
730
+ [
731
+ item.uid,
732
+ version,
733
+ item.body ?? "",
734
+ JSON.stringify(metaSnapshotOf(item)),
735
+ changeSummary,
736
+ author,
737
+ authorType,
738
+ createdAt
739
+ ]
740
+ );
741
+ }
742
+ function listItemVersions(itemUid) {
743
+ const r = (0, import_database.getDb)().exec(
744
+ `SELECT id, item_uid, version, body_snapshot, meta_snapshot, change_summary, author, author_type, created_at
745
+ FROM plan_item_versions
746
+ WHERE item_uid = ?
747
+ ORDER BY version DESC`,
748
+ [itemUid]
749
+ );
750
+ if (!r[0]) return [];
751
+ return r[0].values.map((row) => ({
752
+ id: row[0],
753
+ itemUid: row[1],
754
+ version: row[2],
755
+ bodySnapshot: row[3] ?? "",
756
+ metaSnapshot: parseJsonObj(row[4]),
757
+ changeSummary: row[5] ?? null,
758
+ author: row[6],
759
+ authorType: row[7],
760
+ createdAt: row[8]
761
+ }));
762
+ }
763
+ function parseJsonObj(s) {
764
+ if (!s) return {};
765
+ try {
766
+ const v = JSON.parse(s);
767
+ return typeof v === "object" && v !== null ? v : {};
768
+ } catch {
769
+ return {};
770
+ }
771
+ }
772
+ function restoreItemVersion(itemUid, version, author, authorType) {
773
+ const versions = listItemVersions(itemUid);
774
+ const target = versions.find((v) => v.version === version);
775
+ if (!target) return null;
776
+ const meta = target.metaSnapshot;
777
+ const updates = {
778
+ body: target.bodySnapshot,
779
+ title: typeof meta.title === "string" ? meta.title : void 0,
780
+ template: meta.template === null || typeof meta.template === "string" ? meta.template : void 0,
781
+ status: typeof meta.status === "string" ? meta.status : void 0,
782
+ assignee: typeof meta.assignee === "string" || meta.assignee === null ? meta.assignee : void 0,
783
+ assigneeType: typeof meta.assigneeType === "string" || meta.assigneeType === null ? meta.assigneeType : void 0,
784
+ assigneeModel: typeof meta.assigneeModel === "string" || meta.assigneeModel === null ? meta.assigneeModel : void 0,
785
+ progressPercent: typeof meta.progressPercent === "number" || meta.progressPercent === null ? meta.progressPercent : void 0,
786
+ blockedReason: typeof meta.blockedReason === "string" || meta.blockedReason === null ? meta.blockedReason : void 0,
787
+ scopePath: typeof meta.scopePath === "string" || meta.scopePath === null ? meta.scopePath : void 0,
788
+ fileSpecs: Array.isArray(meta.fileSpecs) ? meta.fileSpecs : void 0,
789
+ symbolSpecs: Array.isArray(meta.symbolSpecs) ? meta.symbolSpecs : void 0,
790
+ newConnections: Array.isArray(meta.newConnections) ? meta.newConnections : void 0,
791
+ removedConnections: Array.isArray(meta.removedConnections) ? meta.removedConnections : void 0,
792
+ dependencies: Array.isArray(meta.dependencies) ? meta.dependencies : void 0,
793
+ changeSummary: `Restored v${version}`,
794
+ author,
795
+ authorType
796
+ };
797
+ const restored = updateItem(itemUid, updates);
798
+ if (!restored) return null;
799
+ (0, import_plan_event_service.appendPlanEvent)({
800
+ planUid: restored.planUid,
801
+ itemUid,
802
+ eventType: "item_restored",
803
+ afterState: { restoredFromVersion: version },
804
+ summary: `\u21A9 restored "${restored.title}" to v${version}`,
805
+ author,
806
+ authorType
807
+ });
808
+ return restored;
809
+ }
810
+ function sameClaimant(other, agentId, sessionId) {
811
+ if (sessionId && other.assigneeSession) return other.assigneeSession === sessionId;
812
+ return other.assignee === agentId;
813
+ }
814
+ function resolveClaimPolicy(item) {
815
+ return resolveClaimPolicyWithSource(item).value;
816
+ }
817
+ function resolveClaimPolicyWithSource(item) {
818
+ let cur = item;
819
+ while (cur) {
820
+ if (cur.claimPolicy) return { value: cur.claimPolicy, fromUid: cur.uid, fromTitle: cur.title };
821
+ cur = cur.parentUid ? getItem(cur.parentUid) : null;
822
+ }
823
+ return { value: { mode: "any" }, fromUid: null, fromTitle: null };
824
+ }
825
+ function resolveExecutionConfigWithSource(item) {
826
+ let cur = item;
827
+ while (cur) {
828
+ if (cur.executionConfig) return { value: cur.executionConfig, fromUid: cur.uid, fromTitle: cur.title };
829
+ cur = cur.parentUid ? getItem(cur.parentUid) : null;
830
+ }
831
+ return { value: null, fromUid: null, fromTitle: null };
832
+ }
833
+ function resolveSkills(item) {
834
+ const chain = [];
835
+ let cur = item;
836
+ while (cur) {
837
+ chain.unshift(cur);
838
+ cur = cur.parentUid ? getItem(cur.parentUid) : null;
839
+ }
840
+ let resolved = [];
841
+ for (const ancestor of chain) {
842
+ const skills = ancestor.skills ?? [];
843
+ if (skills.length === 0 && ancestor.skillsMode === "inherit") continue;
844
+ if (ancestor.skillsMode === "replace") {
845
+ resolved = [...skills];
846
+ } else if (ancestor.skillsMode === "none") {
847
+ resolved = [];
848
+ } else {
849
+ const byName = new Map(resolved.map((s) => [s.name, s]));
850
+ for (const s of skills) byName.set(s.name, s);
851
+ resolved = Array.from(byName.values());
852
+ }
853
+ }
854
+ return resolved;
855
+ }
856
+ function resolveSkillsWithSource(item) {
857
+ const chain = [];
858
+ let cur = item;
859
+ while (cur) {
860
+ chain.unshift(cur);
861
+ cur = cur.parentUid ? getItem(cur.parentUid) : null;
862
+ }
863
+ let resolved = /* @__PURE__ */ new Map();
864
+ for (const ancestor of chain) {
865
+ const skills = ancestor.skills ?? [];
866
+ if (skills.length === 0 && ancestor.skillsMode === "inherit") continue;
867
+ const here = skills.map((skill) => [skill.name, { skill, fromUid: ancestor.uid, fromTitle: ancestor.title }]);
868
+ if (ancestor.skillsMode === "replace") resolved = new Map(here);
869
+ else if (ancestor.skillsMode === "none") resolved = /* @__PURE__ */ new Map();
870
+ else for (const [k, v] of here) resolved.set(k, v);
871
+ }
872
+ return [...resolved.values()];
873
+ }
874
+ function resolveConstraints(item) {
875
+ return resolveConstraintsWithSource(item).value;
876
+ }
877
+ function resolveConstraintsWithSource(item) {
878
+ const chain = [];
879
+ let cur = item;
880
+ while (cur) {
881
+ chain.unshift(cur);
882
+ cur = cur.parentUid ? getItem(cur.parentUid) : null;
883
+ }
884
+ let resolved = {};
885
+ let from = null;
886
+ for (const ancestor of chain) {
887
+ const c = ancestor.constraints;
888
+ const mode = ancestor.constraintsMode ?? "inherit";
889
+ if (mode === "none") {
890
+ resolved = {};
891
+ from = ancestor;
892
+ continue;
893
+ }
894
+ if (mode === "replace" && c) {
895
+ resolved = { ...c };
896
+ from = ancestor;
897
+ continue;
898
+ }
899
+ if (!c) continue;
900
+ resolved = {
901
+ excludePaths: [...resolved.excludePaths ?? [], ...c.excludePaths ?? []],
902
+ excludeSymbols: [...resolved.excludeSymbols ?? [], ...c.excludeSymbols ?? []],
903
+ lockInterfaces: resolved.lockInterfaces || c.lockInterfaces || false,
904
+ requireTests: resolved.requireTests || c.requireTests || false,
905
+ requireLint: resolved.requireLint || c.requireLint || false,
906
+ maxFilesTouched: c.maxFilesTouched ?? resolved.maxFilesTouched ?? null,
907
+ maxLinesChanged: c.maxLinesChanged ?? resolved.maxLinesChanged ?? null,
908
+ customRules: [...resolved.customRules ?? [], ...c.customRules ?? []]
909
+ };
910
+ from = ancestor;
911
+ }
912
+ return { value: resolved, fromUid: from?.uid ?? null, fromTitle: from?.title ?? null };
913
+ }
914
+ function claimItemImpl(uid, agentId, agentType, model, capabilities, sessionId, actor) {
915
+ const item = getItem(uid);
916
+ if (!item) return { ok: false, reason: "Item not found" };
917
+ if (item.kind !== "action") {
918
+ return { ok: false, reason: "Only Actions can be claimed (this is an Object)." };
919
+ }
920
+ if (item.assignee || item.status !== "pending") {
921
+ return { ok: false, reason: "Action already claimed or not pending." };
922
+ }
923
+ const policy = resolveClaimPolicy(item);
924
+ if (policy.mode === "human-only") {
925
+ return { ok: false, reason: "This task is restricted to human-only completion." };
926
+ }
927
+ if (policy.mode === "assigned") {
928
+ if (policy.assignToType === "human") {
929
+ return { ok: false, reason: "This task is assigned to a human." };
930
+ }
931
+ if (policy.assignTo && policy.assignTo !== agentId) {
932
+ return { ok: false, reason: `This task is assigned to a specific agent (${policy.assignTo}).` };
933
+ }
934
+ }
935
+ if (policy.allowedAgentTypes && policy.allowedAgentTypes.length > 0) {
936
+ if (!policy.allowedAgentTypes.includes(agentType)) {
937
+ return { ok: false, reason: `This task is restricted to agent types: ${policy.allowedAgentTypes.join(", ")}. You are: ${agentType}.` };
938
+ }
939
+ }
940
+ if (policy.allowedModels && policy.allowedModels.length > 0 && model) {
941
+ if (!policy.allowedModels.includes(model)) {
942
+ return { ok: false, reason: `This task is restricted to models: ${policy.allowedModels.join(", ")}. You are using: ${model}.` };
943
+ }
944
+ }
945
+ if (policy.mode === "match-skills" || policy.mode === "any") {
946
+ const requiredSkills = resolveSkills(item).filter((s) => s.required);
947
+ if (requiredSkills.length > 0 && capabilities) {
948
+ const capNames = new Set(capabilities.map((c) => c.name));
949
+ const missing = requiredSkills.filter((s) => !capNames.has(s.name));
950
+ if (missing.length > 0) {
951
+ return {
952
+ ok: false,
953
+ reason: `This task requires skills you don't have: ${missing.map((s) => `${s.name} (${s.source})`).join(", ")}.`
954
+ };
955
+ }
956
+ } else if (requiredSkills.length > 0 && !capabilities) {
957
+ if (policy.mode === "match-skills") {
958
+ return {
959
+ ok: false,
960
+ reason: `This task requires skills (${requiredSkills.map((s) => s.name).join(", ")}) but you haven't declared capabilities. Use register_session with capabilities.`
961
+ };
962
+ }
963
+ }
964
+ }
965
+ const myFiles = /* @__PURE__ */ new Set();
966
+ for (const fs of item.fileSpecs ?? []) {
967
+ if (fs.path) myFiles.add(fs.path);
968
+ if (fs.moveTo) myFiles.add(fs.moveTo);
969
+ }
970
+ const conflicts = [];
971
+ if (myFiles.size > 0) {
972
+ const others = listAllItems(item.planUid).filter(
973
+ (o) => o.uid !== uid && o.kind === "action" && (o.status === "in_progress" || o.status === "assigned") && !sameClaimant(o, agentId, sessionId)
974
+ );
975
+ for (const other of others) {
976
+ const overlap = (other.fileSpecs ?? []).flatMap((fs) => [fs.path, fs.moveTo].filter(Boolean)).filter((p) => myFiles.has(p));
977
+ if (overlap.length > 0) {
978
+ conflicts.push(`Action "${other.title}" (${other.assignee}) also affects: ${overlap.join(", ")}`);
979
+ }
980
+ }
981
+ }
982
+ updateItem(uid, {
983
+ status: "assigned",
984
+ assignee: agentId,
985
+ assigneeType: agentType,
986
+ assigneeModel: model ?? null,
987
+ assigneeSession: sessionId ?? null,
988
+ // Who made the claim, from how it arrived: the agent itself over MCP,
989
+ // the person (or `unverified`) over REST, which can claim on an agent's
990
+ // behalf. The claimant alone when no caller is given.
991
+ author: actor?.author ?? agentId,
992
+ authorType: actor?.authorType ?? "agent",
993
+ changeSummary: "Claimed"
994
+ });
995
+ const waiting = item.kind === "action" ? dependencyStateOf(item) : null;
996
+ return {
997
+ ok: true,
998
+ conflicts: conflicts.length > 0 ? conflicts : void 0,
999
+ waitsOn: waiting && !waiting.met ? waiting.waits.map((w) => w.words) : void 0
1000
+ };
1001
+ }
1002
+ const dependencyLookup = {
1003
+ getItem,
1004
+ planTitle(planUid) {
1005
+ const r = (0, import_database.getDb)().exec("SELECT title FROM plans WHERE uid = ?", [planUid]);
1006
+ return r[0]?.values[0]?.[0] ?? null;
1007
+ }
1008
+ };
1009
+ function dependencyStateOf(item, local) {
1010
+ return (0, import_plan_dependencies.dependencyState)(item, dependencyLookup, local);
1011
+ }
1012
+ function planWaits(planUid) {
1013
+ const all = listAllItems(planUid);
1014
+ const local = new Map(all.map((i) => [i.uid, i]));
1015
+ const out = [];
1016
+ for (const item of all) {
1017
+ if (item.kind !== "action" || item.status !== "pending") continue;
1018
+ const state = dependencyStateOf(item, local);
1019
+ if (!state.met) out.push({ itemUid: item.uid, itemTitle: item.title, waits: state.waits, sentence: (0, import_plan_dependencies.waitSentence)(item.title, state) });
1020
+ }
1021
+ return out;
1022
+ }
1023
+ function getNextItem(planUid, parentUid, accept) {
1024
+ const all = listAllItems(planUid);
1025
+ const local = new Map(all.map((i) => [i.uid, i]));
1026
+ let candidates = all.filter(
1027
+ (i) => i.kind === "action" && i.status === "pending" && !i.assignee && (!accept || accept(i))
1028
+ );
1029
+ if (parentUid !== void 0) {
1030
+ candidates = candidates.filter((i) => i.parentUid === parentUid);
1031
+ }
1032
+ const held = [];
1033
+ candidates = candidates.filter((i) => {
1034
+ const state = dependencyStateOf(i, local);
1035
+ if (!state.met) held.push({ item: i, state });
1036
+ return state.met;
1037
+ });
1038
+ candidates.sort((a, b) => a.sortOrder - b.sortOrder);
1039
+ if (candidates.length === 0) {
1040
+ const first = held.sort((a, b) => a.item.sortOrder - b.item.sortOrder)[0];
1041
+ return first ? { item: null, waiting: { itemUid: first.item.uid, itemTitle: first.item.title, reason: (0, import_plan_dependencies.waitSentence)(first.item.title, first.state) } } : { item: null };
1042
+ }
1043
+ const next = candidates[0];
1044
+ const siblings = all.filter((i) => i.parentUid === next.parentUid && i.kind === "action").sort((a, b) => a.sortOrder - b.sortOrder);
1045
+ const myIdx = siblings.findIndex((s) => s.uid === next.uid);
1046
+ if (myIdx > 0) {
1047
+ const prev = siblings[myIdx - 1];
1048
+ const unmet = prev.status === "done" ? (0, import_criteria_service.unmetHumanCriteria)(prev.uid) : [];
1049
+ if (unmet.length > 0) {
1050
+ return {
1051
+ item: null,
1052
+ gated: {
1053
+ itemUid: next.uid,
1054
+ itemTitle: next.title,
1055
+ reason: `Waiting for a person to sign off "${prev.title}" (${unmet.map((c) => `"${c.text}"`).join(", ")}) before proceeding.`
1056
+ }
1057
+ };
1058
+ }
1059
+ }
1060
+ return { item: next };
1061
+ }
1062
+ function structuralSummary(after, kind, beforeState, afterState) {
1063
+ const icon = after.kind === "action" ? "\u26A1" : "\u{1F4CB}";
1064
+ switch (kind) {
1065
+ case "renamed": {
1066
+ const b = beforeState?.title ?? "?";
1067
+ return `${icon} renamed "${b}" \u2192 "${after.title}"`;
1068
+ }
1069
+ case "status_changed": {
1070
+ const b = beforeState?.status ?? "?";
1071
+ const a = afterState?.status ?? "?";
1072
+ return `${icon} "${after.title}" ${b} \u2192 ${a}`;
1073
+ }
1074
+ case "reparented":
1075
+ return `${icon} moved "${after.title}"`;
1076
+ case "reordered":
1077
+ return `${icon} reordered "${after.title}"`;
1078
+ case "kind_transmuted":
1079
+ return `${icon} transmuted "${after.title}"`;
1080
+ }
1081
+ }
1082
+ function defaultMoveSummary(item, isReparent, isReorder) {
1083
+ const icon = item.kind === "action" ? "\u26A1" : "\u{1F4CB}";
1084
+ if (isReparent && isReorder) return `${icon} moved "${item.title}"`;
1085
+ if (isReparent) return `${icon} re-parented "${item.title}"`;
1086
+ return `${icon} reordered "${item.title}"`;
1087
+ }
1088
+ function getEffectiveVisibility(itemUid) {
1089
+ const item = getItem(itemUid);
1090
+ if (!item) return "shared";
1091
+ if (item.visibility === "local") return "local";
1092
+ if (item.overrideParentVisibility) return "shared";
1093
+ let cursor = item.parentUid;
1094
+ const seen = /* @__PURE__ */ new Set([itemUid]);
1095
+ while (cursor) {
1096
+ if (seen.has(cursor)) break;
1097
+ seen.add(cursor);
1098
+ const ancestor = getItem(cursor);
1099
+ if (!ancestor) break;
1100
+ if (ancestor.visibility === "local") return "local";
1101
+ if (ancestor.overrideParentVisibility) return "shared";
1102
+ cursor = ancestor.parentUid;
1103
+ }
1104
+ return "shared";
1105
+ }
1106
+ function listItemsForExport(planUid) {
1107
+ const all = listAllItems(planUid);
1108
+ const byUid = new Map(all.map((i) => [i.uid, i]));
1109
+ const visibilityCache = /* @__PURE__ */ new Map();
1110
+ function effective(uid) {
1111
+ const cached = visibilityCache.get(uid);
1112
+ if (cached) return cached;
1113
+ const item = byUid.get(uid);
1114
+ if (!item) {
1115
+ visibilityCache.set(uid, "shared");
1116
+ return "shared";
1117
+ }
1118
+ if (item.visibility === "local") {
1119
+ visibilityCache.set(uid, "local");
1120
+ return "local";
1121
+ }
1122
+ if (item.overrideParentVisibility) {
1123
+ visibilityCache.set(uid, "shared");
1124
+ return "shared";
1125
+ }
1126
+ if (!item.parentUid) {
1127
+ visibilityCache.set(uid, "shared");
1128
+ return "shared";
1129
+ }
1130
+ const parentEff = effective(item.parentUid);
1131
+ visibilityCache.set(uid, parentEff);
1132
+ return parentEff;
1133
+ }
1134
+ const result = [];
1135
+ for (const item of all) {
1136
+ if (effective(item.uid) !== "shared") continue;
1137
+ let exportParentUid = null;
1138
+ let cursor = item.parentUid;
1139
+ const seen = /* @__PURE__ */ new Set([item.uid]);
1140
+ while (cursor) {
1141
+ if (seen.has(cursor)) break;
1142
+ seen.add(cursor);
1143
+ if (effective(cursor) === "shared") {
1144
+ exportParentUid = cursor;
1145
+ break;
1146
+ }
1147
+ const ancestor = byUid.get(cursor);
1148
+ if (!ancestor) break;
1149
+ cursor = ancestor.parentUid;
1150
+ }
1151
+ result.push({ item, exportParentUid });
1152
+ }
1153
+ return result;
1154
+ }
1155
+ function writeThrough(planUid) {
1156
+ if (!planUid) return;
1157
+ try {
1158
+ _lazy___plan_file_service.scheduleWriteThrough(planUid);
1159
+ } catch {
1160
+ }
1161
+ }
1162
+ function createItem(input) {
1163
+ const item = createItemImpl(input);
1164
+ writeThrough(item.planUid);
1165
+ return item;
1166
+ }
1167
+ function updateItem(uid, updates) {
1168
+ const item = updateItemImpl(uid, updates);
1169
+ if (!(0, import_item_status.isStateOnly)(updates)) writeThrough(item?.planUid);
1170
+ return item;
1171
+ }
1172
+ function moveItem(uid, input) {
1173
+ const item = moveItemImpl(uid, input);
1174
+ writeThrough(item?.planUid);
1175
+ return item;
1176
+ }
1177
+ function deleteItem(uid, input) {
1178
+ const planUid = getItem(uid)?.planUid;
1179
+ const deleted = deleteItemImpl(uid, input);
1180
+ if (deleted.length) {
1181
+ const marks = deleted.map(() => "?").join(",");
1182
+ (0, import_database.getDb)().run(`DELETE FROM spec_links WHERE item_uid IN (${marks}) OR page_uid IN (${marks})`, [...deleted, ...deleted]);
1183
+ (0, import_spec_proposal_withdraw.withdrawProposals)({ pageUids: deleted }, "The page was deleted.");
1184
+ writeThrough(planUid);
1185
+ }
1186
+ return deleted;
1187
+ }
1188
+ function claimItem(uid, agentId, agentType, model, capabilities, sessionId, actor) {
1189
+ return claimItemImpl(uid, agentId, agentType, model, capabilities, sessionId, actor);
1190
+ }
1191
+ // Annotate the CommonJS export names for ESM import in node:
1192
+ 0 && (module.exports = {
1193
+ PlanItemStructureError,
1194
+ applyRecordedState,
1195
+ assertValidParent,
1196
+ claimItem,
1197
+ createItem,
1198
+ deleteItem,
1199
+ dependencyLookup,
1200
+ dependencyStateOf,
1201
+ getChildren,
1202
+ getEffectiveVisibility,
1203
+ getItem,
1204
+ getNextItem,
1205
+ listAllItems,
1206
+ listItemSummaries,
1207
+ listItemVersions,
1208
+ listItemsForExport,
1209
+ moveItem,
1210
+ planWaits,
1211
+ resolveClaimPolicy,
1212
+ resolveClaimPolicyWithSource,
1213
+ resolveConstraints,
1214
+ resolveConstraintsWithSource,
1215
+ resolveExecutionConfigWithSource,
1216
+ resolveSkills,
1217
+ resolveSkillsWithSource,
1218
+ restoreItemVersion,
1219
+ setStateWriteListener,
1220
+ setStatusChangeListener,
1221
+ updateItem,
1222
+ withoutStateRecords
1223
+ });