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,528 @@
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 budget_service_exports = {};
29
+ __export(budget_service_exports, {
30
+ OPEN_TURN_FLUSH_MS: () => OPEN_TURN_FLUSH_MS,
31
+ TURN_GAP_MS: () => import_turn_gap.TURN_GAP_MS,
32
+ WARN_AT: () => WARN_AT,
33
+ acknowledgeBudgetChange: () => acknowledgeBudgetChange,
34
+ budgetState: () => budgetState,
35
+ checkBudget: () => checkBudget,
36
+ closeTurn: () => closeTurn,
37
+ flaggedBudgetChanges: () => flaggedBudgetChanges,
38
+ flushIdleTurns: () => flushIdleTurns,
39
+ forecast: () => forecast,
40
+ getBudget: () => getBudget,
41
+ getBudgetReport: () => getBudgetReport,
42
+ getUnattributedTokenReports: () => getUnattributedTokenReports,
43
+ isFlaggedActor: () => isFlaggedActor,
44
+ isTurnClosed: () => isTurnClosed,
45
+ listBudgetChanges: () => listBudgetChanges,
46
+ listOpenTurns: () => listOpenTurns,
47
+ markBudgetNotified: () => markBudgetNotified,
48
+ minutesBetween: () => minutesBetween,
49
+ noteItemFocus: () => noteItemFocus,
50
+ recordActivity: () => recordActivity,
51
+ recordTokens: () => recordTokens,
52
+ resetBudgetState: () => resetBudgetState,
53
+ runBudgetSweep: () => runBudgetSweep,
54
+ setBudget: () => setBudget,
55
+ startBudgetSweep: () => startBudgetSweep,
56
+ stopBudgetSweep: () => stopBudgetSweep
57
+ });
58
+ module.exports = __toCommonJS(budget_service_exports);
59
+ var import_database = require("./database");
60
+ var import_turn_gap = require("../../shared/lib/turn-gap");
61
+ var import_persistence = require("./persistence");
62
+ var import_pricing = require("./pricing");
63
+ const OPEN_TURN_FLUSH_MS = 2 * 6e4;
64
+ const WARN_AT = 0.8;
65
+ function isFlaggedActor(actorType) {
66
+ return actorType !== "human";
67
+ }
68
+ function isTurnClosed(turn, now, gapMs = import_turn_gap.TURN_GAP_MS) {
69
+ return now - turn.lastActivityAt > gapMs;
70
+ }
71
+ function forecast(spent, completionRatio, floor = 0.1) {
72
+ if (spent <= 0) return null;
73
+ if (completionRatio === null || completionRatio < floor) return null;
74
+ if (completionRatio >= 1) return spent;
75
+ return spent / completionRatio;
76
+ }
77
+ function budgetState(report) {
78
+ const b = report.budget;
79
+ if (!b || b.minutes === null && b.costUsd === null) return "none";
80
+ if (b.exempt) return "exempt";
81
+ const fractions = [];
82
+ if (b.minutes !== null && b.minutes > 0) fractions.push(report.spentMinutes / b.minutes);
83
+ if (b.costUsd !== null && b.costUsd > 0 && report.spentCostUsd !== null) {
84
+ fractions.push(report.spentCostUsd / b.costUsd);
85
+ }
86
+ if (fractions.length === 0) return "none";
87
+ const worst = Math.max(...fractions);
88
+ if (worst >= 1) return "over";
89
+ if (worst >= WARN_AT) return "warn";
90
+ return "ok";
91
+ }
92
+ function minutesBetween(startedAt, endedAt) {
93
+ return Math.max(0, endedAt - startedAt) / 6e4;
94
+ }
95
+ const openTurns = /* @__PURE__ */ new Map();
96
+ let unattributedTokenReports = 0;
97
+ function getUnattributedTokenReports() {
98
+ return unattributedTokenReports;
99
+ }
100
+ function resetBudgetState() {
101
+ openTurns.clear();
102
+ unattributedTokenReports = 0;
103
+ }
104
+ function listOpenTurns() {
105
+ return [...openTurns.values()];
106
+ }
107
+ function emptyTokens() {
108
+ return { inputTokens: 0, outputTokens: 0, cacheWriteTokens: 0, cacheReadTokens: 0 };
109
+ }
110
+ function recordActivity(params) {
111
+ const now = params.timestamp ?? Date.now();
112
+ const existing = openTurns.get(params.sessionId);
113
+ if (existing && !isTurnClosed(existing, now)) {
114
+ existing.lastActivityAt = now;
115
+ if (params.planUid) existing.planUid = params.planUid;
116
+ if (params.itemUid) existing.itemUid = params.itemUid;
117
+ if (params.agentType) existing.agentType = params.agentType;
118
+ if (params.agentModel) existing.agentModel = params.agentModel;
119
+ return;
120
+ }
121
+ if (existing) closeTurn(params.sessionId, existing.lastActivityAt);
122
+ openTurns.set(params.sessionId, {
123
+ sessionId: params.sessionId,
124
+ planUid: params.planUid ?? null,
125
+ itemUid: params.itemUid ?? null,
126
+ agentType: params.agentType ?? null,
127
+ agentModel: params.agentModel ?? null,
128
+ startedAt: now,
129
+ lastActivityAt: now,
130
+ tokens: emptyTokens()
131
+ });
132
+ }
133
+ function noteItemFocus(sessionId, itemUid, planUid) {
134
+ const turn = openTurns.get(sessionId);
135
+ if (!turn) return;
136
+ turn.itemUid = itemUid;
137
+ if (planUid) turn.planUid = planUid;
138
+ }
139
+ function recordTokens(params) {
140
+ const turn = openTurns.get(params.sessionId);
141
+ if (!turn) {
142
+ unattributedTokenReports += 1;
143
+ return;
144
+ }
145
+ turn.tokens.inputTokens += params.tokens.inputTokens ?? 0;
146
+ turn.tokens.outputTokens += params.tokens.outputTokens ?? 0;
147
+ turn.tokens.cacheWriteTokens = (turn.tokens.cacheWriteTokens ?? 0) + (params.tokens.cacheWriteTokens ?? 0);
148
+ turn.tokens.cacheReadTokens = (turn.tokens.cacheReadTokens ?? 0) + (params.tokens.cacheReadTokens ?? 0);
149
+ if (params.model) turn.agentModel = params.model;
150
+ }
151
+ function closeTurn(sessionId, endedAt) {
152
+ const turn = openTurns.get(sessionId);
153
+ if (!turn) return null;
154
+ openTurns.delete(sessionId);
155
+ if (!turn.planUid) return null;
156
+ const entry = {
157
+ planUid: turn.planUid,
158
+ itemUid: turn.itemUid,
159
+ sessionId: turn.sessionId,
160
+ agentType: turn.agentType,
161
+ agentModel: turn.agentModel,
162
+ startedAt: turn.startedAt,
163
+ endedAt: endedAt ?? turn.lastActivityAt,
164
+ tokens: turn.tokens,
165
+ costUsd: (0, import_pricing.costOf)(turn.agentModel, turn.tokens)
166
+ };
167
+ persistEntry(entry);
168
+ return entry;
169
+ }
170
+ function flushIdleTurns(now = Date.now()) {
171
+ const flushed = [];
172
+ for (const [sessionId, turn] of [...openTurns.entries()]) {
173
+ if (now - turn.lastActivityAt > OPEN_TURN_FLUSH_MS) {
174
+ const entry = closeTurn(sessionId, turn.lastActivityAt);
175
+ if (entry) flushed.push(entry);
176
+ }
177
+ }
178
+ return flushed;
179
+ }
180
+ function persistEntry(entry) {
181
+ try {
182
+ const db = (0, import_database.getDb)();
183
+ db.run(
184
+ `INSERT INTO item_time_entries
185
+ (plan_uid, item_uid, session_id, agent_type, agent_model, started_at, ended_at,
186
+ input_tokens, output_tokens, cache_write_tokens, cache_read_tokens, cost_usd, pricing_version)
187
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
188
+ [
189
+ entry.planUid,
190
+ entry.itemUid,
191
+ entry.sessionId,
192
+ entry.agentType,
193
+ entry.agentModel,
194
+ entry.startedAt,
195
+ entry.endedAt,
196
+ entry.tokens.inputTokens,
197
+ entry.tokens.outputTokens,
198
+ entry.tokens.cacheWriteTokens ?? 0,
199
+ entry.tokens.cacheReadTokens ?? 0,
200
+ entry.costUsd,
201
+ import_pricing.PRICING_VERSION
202
+ ]
203
+ );
204
+ (0, import_persistence.markDirty)();
205
+ } catch (err) {
206
+ console.warn("[Budget] Failed to persist a time entry:", err);
207
+ }
208
+ }
209
+ function getBudget(planUid) {
210
+ try {
211
+ const db = (0, import_database.getDb)();
212
+ const res = db.exec(
213
+ `SELECT plan_uid, minutes, cost_usd, exempt, notified_at FROM plan_budgets WHERE plan_uid = ?`,
214
+ [planUid]
215
+ );
216
+ const row = res[0]?.values[0];
217
+ if (!row) return null;
218
+ return {
219
+ planUid: row[0],
220
+ minutes: row[1] ?? null,
221
+ costUsd: row[2] ?? null,
222
+ exempt: Boolean(row[3]),
223
+ notifiedAt: row[4] ?? null
224
+ };
225
+ } catch {
226
+ return null;
227
+ }
228
+ }
229
+ function setBudget(params) {
230
+ const db = (0, import_database.getDb)();
231
+ const existing = getBudget(params.planUid);
232
+ const next = {
233
+ planUid: params.planUid,
234
+ minutes: params.minutes !== void 0 ? params.minutes : existing?.minutes ?? null,
235
+ costUsd: params.costUsd !== void 0 ? params.costUsd : existing?.costUsd ?? null,
236
+ exempt: params.exempt !== void 0 ? params.exempt : existing?.exempt ?? false,
237
+ // Raising a ceiling clears the warning watermark, so the next 80%
238
+ // crossing warns again rather than staying silent forever.
239
+ notifiedAt: null
240
+ };
241
+ db.run(
242
+ `INSERT INTO plan_budgets (plan_uid, minutes, cost_usd, exempt, notified_at, updated_at)
243
+ VALUES (?, ?, ?, ?, ?, ?)
244
+ ON CONFLICT(plan_uid) DO UPDATE SET
245
+ minutes = excluded.minutes,
246
+ cost_usd = excluded.cost_usd,
247
+ exempt = excluded.exempt,
248
+ notified_at = excluded.notified_at,
249
+ updated_at = excluded.updated_at`,
250
+ [next.planUid, next.minutes, next.costUsd, next.exempt ? 1 : 0, null, Date.now()]
251
+ );
252
+ const ceiling = (b) => ({ minutes: b.minutes, costUsd: b.costUsd, exempt: b.exempt });
253
+ const before = existing ? ceiling(existing) : null;
254
+ const after = ceiling(next);
255
+ if (params.by && JSON.stringify(before) !== JSON.stringify(after)) {
256
+ db.run(
257
+ `INSERT INTO plan_budget_changes (plan_uid, actor, actor_type, channel, before_json, after_json, created_at)
258
+ VALUES (?, ?, ?, ?, ?, ?, ?)`,
259
+ [
260
+ next.planUid,
261
+ params.by.actor,
262
+ params.by.actorType,
263
+ params.by.channel,
264
+ before ? JSON.stringify(before) : null,
265
+ JSON.stringify(after),
266
+ Date.now()
267
+ ]
268
+ );
269
+ }
270
+ (0, import_persistence.markDirty)();
271
+ return next;
272
+ }
273
+ function toChange(r) {
274
+ const actorType = r[3];
275
+ const acknowledgedAt = r[8] ?? null;
276
+ return {
277
+ id: r[0],
278
+ planUid: r[1],
279
+ actor: r[2],
280
+ actorType,
281
+ channel: r[4],
282
+ before: r[5] ? JSON.parse(r[5]) : null,
283
+ after: JSON.parse(r[6]),
284
+ at: r[7],
285
+ flagged: isFlaggedActor(actorType) && acknowledgedAt === null,
286
+ acknowledgedAt,
287
+ acknowledgedBy: r[9] ?? null
288
+ };
289
+ }
290
+ const CHANGE_COLUMNS = "id, plan_uid, actor, actor_type, channel, before_json, after_json, created_at, acknowledged_at, acknowledged_by";
291
+ function listBudgetChanges(planUid, limit = 50) {
292
+ try {
293
+ const res = (0, import_database.getDb)().exec(
294
+ `SELECT ${CHANGE_COLUMNS} FROM plan_budget_changes WHERE plan_uid = ? ORDER BY created_at DESC, id DESC LIMIT ?`,
295
+ [planUid, limit]
296
+ );
297
+ return (res[0]?.values ?? []).map(toChange);
298
+ } catch {
299
+ return [];
300
+ }
301
+ }
302
+ function flaggedBudgetChanges(planUid) {
303
+ return listBudgetChanges(planUid, 500).filter((c) => c.flagged).reverse();
304
+ }
305
+ function acknowledgeBudgetChange(planUid, id, by) {
306
+ const db = (0, import_database.getDb)();
307
+ db.run(
308
+ `UPDATE plan_budget_changes SET acknowledged_at = ?, acknowledged_by = ?
309
+ WHERE plan_uid = ? AND id = ? AND acknowledged_at IS NULL`,
310
+ [Date.now(), by, planUid, id]
311
+ );
312
+ (0, import_persistence.markDirty)();
313
+ const res = db.exec(`SELECT ${CHANGE_COLUMNS} FROM plan_budget_changes WHERE plan_uid = ? AND id = ?`, [planUid, id]);
314
+ const row = res[0]?.values[0];
315
+ return row ? toChange(row) : null;
316
+ }
317
+ function markBudgetNotified(planUid, at = Date.now()) {
318
+ try {
319
+ (0, import_database.getDb)().run(`UPDATE plan_budgets SET notified_at = ? WHERE plan_uid = ?`, [at, planUid]);
320
+ (0, import_persistence.markDirty)();
321
+ } catch {
322
+ }
323
+ }
324
+ function rollup(planUid) {
325
+ const out = {
326
+ spentMinutes: 0,
327
+ spentCostUsd: null,
328
+ byAgent: /* @__PURE__ */ new Map(),
329
+ byItem: /* @__PURE__ */ new Map(),
330
+ pricingVersions: /* @__PURE__ */ new Set()
331
+ };
332
+ let res;
333
+ try {
334
+ res = (0, import_database.getDb)().exec(
335
+ `SELECT item_uid, agent_type, started_at, ended_at, cost_usd, pricing_version
336
+ FROM item_time_entries WHERE plan_uid = ?`,
337
+ [planUid]
338
+ );
339
+ } catch {
340
+ return out;
341
+ }
342
+ for (const row of res[0]?.values ?? []) {
343
+ const itemUid = row[0];
344
+ const agentType = row[1] ?? "unknown";
345
+ const minutes = minutesBetween(row[2], row[3]);
346
+ const cost = row[4];
347
+ const priced = row[5];
348
+ if (cost !== null && priced) out.pricingVersions.add(priced);
349
+ out.spentMinutes += minutes;
350
+ if (cost !== null) out.spentCostUsd = (out.spentCostUsd ?? 0) + cost;
351
+ const agent = out.byAgent.get(agentType) ?? { minutes: 0, costUsd: null };
352
+ agent.minutes += minutes;
353
+ if (cost !== null) agent.costUsd = (agent.costUsd ?? 0) + cost;
354
+ out.byAgent.set(agentType, agent);
355
+ if (itemUid) out.byItem.set(itemUid, (out.byItem.get(itemUid) ?? 0) + minutes);
356
+ }
357
+ return out;
358
+ }
359
+ function itemEstimates(planUid) {
360
+ try {
361
+ const res = (0, import_database.getDb)().exec(
362
+ `SELECT uid, status, estimate_minutes, estimate_cost_usd FROM plan_items WHERE plan_uid = ?`,
363
+ [planUid]
364
+ );
365
+ return (res[0]?.values ?? []).map((r) => ({
366
+ uid: r[0],
367
+ status: r[1] ?? null,
368
+ estimateMinutes: r[2] ?? null,
369
+ estimateCostUsd: r[3] ?? null
370
+ }));
371
+ } catch {
372
+ return [];
373
+ }
374
+ }
375
+ function getBudgetReport(planUid) {
376
+ const spent = rollup(planUid);
377
+ const items = itemEstimates(planUid);
378
+ const estimateMinutes = items.reduce(
379
+ (acc, i) => i.estimateMinutes === null ? acc : (acc ?? 0) + i.estimateMinutes,
380
+ null
381
+ );
382
+ const estimateCostUsd = items.reduce(
383
+ (acc, i) => i.estimateCostUsd === null ? acc : (acc ?? 0) + i.estimateCostUsd,
384
+ null
385
+ );
386
+ const actionable = items.filter((i) => i.status !== null);
387
+ const resolved = actionable.filter((i) => i.status === "done" || i.status === "skipped").length;
388
+ const completionRatio = actionable.length > 0 ? resolved / actionable.length : null;
389
+ const pricingVersions = [...spent.pricingVersions].sort();
390
+ const overruns = items.filter((i) => i.estimateMinutes !== null && (spent.byItem.get(i.uid) ?? 0) > i.estimateMinutes).map((i) => ({
391
+ itemUid: i.uid,
392
+ estimateMinutes: i.estimateMinutes,
393
+ spentMinutes: spent.byItem.get(i.uid) ?? 0
394
+ })).sort((a, b) => b.spentMinutes - b.estimateMinutes - (a.spentMinutes - a.estimateMinutes));
395
+ return {
396
+ planUid,
397
+ budget: getBudget(planUid),
398
+ spentMinutes: spent.spentMinutes,
399
+ spentCostUsd: spent.spentCostUsd,
400
+ estimateMinutes,
401
+ estimateCostUsd,
402
+ forecastMinutes: forecast(spent.spentMinutes, completionRatio),
403
+ forecastCostUsd: spent.spentCostUsd === null ? null : forecast(spent.spentCostUsd, completionRatio),
404
+ completionRatio,
405
+ byAgent: [...spent.byAgent.entries()].map(([agentType, v]) => ({ agentType, ...v })),
406
+ overruns,
407
+ // The version the TOTAL was priced under, not the one in force now.
408
+ // With nothing priced yet, the current table is the honest answer:
409
+ // it is what the next row will use.
410
+ pricingVersion: pricingVersions.length === 0 ? import_pricing.PRICING_VERSION : pricingVersions.length === 1 ? pricingVersions[0] : "mixed",
411
+ pricingVersions,
412
+ flaggedChanges: flaggedBudgetChanges(planUid)
413
+ };
414
+ }
415
+ function checkBudget(planUid) {
416
+ const report = getBudgetReport(planUid);
417
+ const state = budgetState(report);
418
+ switch (state) {
419
+ case "over":
420
+ return {
421
+ allowed: false,
422
+ state,
423
+ reason: "This plan is past its budget. Stop and ask the human to raise the ceiling or exempt the plan.",
424
+ report
425
+ };
426
+ case "warn":
427
+ return {
428
+ allowed: true,
429
+ state,
430
+ reason: "This plan is past 80% of its budget. Finish what is in flight; do not start more.",
431
+ report
432
+ };
433
+ case "exempt":
434
+ return { allowed: true, state, reason: "This plan is exempt from its budget.", report };
435
+ case "ok":
436
+ return { allowed: true, state, reason: "Within budget.", report };
437
+ default:
438
+ return { allowed: true, state, reason: "No budget set for this plan.", report };
439
+ }
440
+ }
441
+ let sweepTimer = null;
442
+ function plansWithBudgets() {
443
+ try {
444
+ const res = (0, import_database.getDb)().exec(
445
+ `SELECT plan_uid FROM plan_budgets WHERE (minutes IS NOT NULL OR cost_usd IS NOT NULL) AND exempt = 0`
446
+ );
447
+ return (res[0]?.values ?? []).map((r) => r[0]);
448
+ } catch {
449
+ return [];
450
+ }
451
+ }
452
+ async function runBudgetSweep(now = Date.now()) {
453
+ flushIdleTurns(now);
454
+ for (const planUid of plansWithBudgets()) {
455
+ try {
456
+ const report = getBudgetReport(planUid);
457
+ const state = budgetState(report);
458
+ if (state !== "warn" && state !== "over") continue;
459
+ if (report.budget?.notifiedAt) continue;
460
+ const spentCost = report.spentCostUsd;
461
+ const parts = [];
462
+ if (report.budget?.minutes) {
463
+ parts.push(`${report.spentMinutes.toFixed(0)}m of ${report.budget.minutes}m`);
464
+ }
465
+ if (report.budget?.costUsd && spentCost !== null) {
466
+ parts.push(`$${spentCost.toFixed(2)} of $${report.budget.costUsd.toFixed(2)}`);
467
+ }
468
+ const { postChannelEvent } = await Promise.resolve().then(() => __toESM(require("./channel-event-service")));
469
+ const { dispatchChannelEvent } = await Promise.resolve().then(() => __toESM(require("./channel-dispatcher-service")));
470
+ const event = postChannelEvent({
471
+ planUid,
472
+ eventType: "need-decision",
473
+ payload: {
474
+ message: state === "over" ? `This plan is over budget (${parts.join(", ")}). Raise the ceiling, exempt the plan, or stop.` : `This plan has passed 80% of its budget (${parts.join(", ")}).`
475
+ },
476
+ author: "codetrellis",
477
+ authorType: "system"
478
+ });
479
+ markBudgetNotified(planUid, now);
480
+ await dispatchChannelEvent(event);
481
+ } catch (err) {
482
+ console.warn(`[Budget] Sweep failed for plan ${planUid}:`, err);
483
+ }
484
+ }
485
+ }
486
+ function startBudgetSweep(intervalMs = 6e4) {
487
+ if (sweepTimer) return;
488
+ sweepTimer = setInterval(() => {
489
+ void runBudgetSweep();
490
+ }, intervalMs);
491
+ sweepTimer.unref?.();
492
+ }
493
+ function stopBudgetSweep() {
494
+ if (sweepTimer) {
495
+ clearInterval(sweepTimer);
496
+ sweepTimer = null;
497
+ }
498
+ }
499
+ // Annotate the CommonJS export names for ESM import in node:
500
+ 0 && (module.exports = {
501
+ OPEN_TURN_FLUSH_MS,
502
+ TURN_GAP_MS,
503
+ WARN_AT,
504
+ acknowledgeBudgetChange,
505
+ budgetState,
506
+ checkBudget,
507
+ closeTurn,
508
+ flaggedBudgetChanges,
509
+ flushIdleTurns,
510
+ forecast,
511
+ getBudget,
512
+ getBudgetReport,
513
+ getUnattributedTokenReports,
514
+ isFlaggedActor,
515
+ isTurnClosed,
516
+ listBudgetChanges,
517
+ listOpenTurns,
518
+ markBudgetNotified,
519
+ minutesBetween,
520
+ noteItemFocus,
521
+ recordActivity,
522
+ recordTokens,
523
+ resetBudgetState,
524
+ runBudgetSweep,
525
+ setBudget,
526
+ startBudgetSweep,
527
+ stopBudgetSweep
528
+ });
@@ -0,0 +1,15 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __copyProps = (to, from, except, desc) => {
6
+ if (from && typeof from === "object" || typeof from === "function") {
7
+ for (let key of __getOwnPropNames(from))
8
+ if (!__hasOwnProp.call(to, key) && key !== except)
9
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
10
+ }
11
+ return to;
12
+ };
13
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
14
+ var base_exports = {};
15
+ module.exports = __toCommonJS(base_exports);
@@ -0,0 +1,148 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var csharp_exports = {};
19
+ __export(csharp_exports, {
20
+ csharpCallsites: () => csharpCallsites
21
+ });
22
+ module.exports = __toCommonJS(csharp_exports);
23
+ var import_shared = require("./shared");
24
+ const ROUTE_ATTR_RE = /\[\s*Route\s*\(\s*"([^"]*)"\s*\)\s*\]/;
25
+ const CLASS_RE = /\b(?:class|record)\s+(\w+)/;
26
+ const HTTP_ATTR_RE = /\[\s*Http(Get|Post|Put|Patch|Delete|Head|Options)\s*(?:\(\s*"([^"]*)"\s*\))?\s*\]/g;
27
+ const METHOD_DECL_RE = /\b(?:public|internal|protected|private)\s+[\w<>,[\]?\s]*?\b(\w+)\s*\(/;
28
+ const MAP_VERB_RE = /(\w+)\s*\.\s*Map(Get|Post|Put|Patch|Delete|Head|Options)\s*\(\s*"([^"]*)"/g;
29
+ const MAP_METHODS_RE = /(\w+)\s*\.\s*MapMethods\s*\(\s*"([^"]*)"\s*,\s*[^)]*?\{([^}]*)\}/g;
30
+ const MAP_GROUP_RE = /(?:var|\w[\w<>.]*)\s+(\w+)\s*=\s*(\w+)\s*\.\s*MapGroup\s*\(\s*"([^"]*)"/;
31
+ const CLIENT_CALL_RE = /(\w+)\s*\.\s*((Get|Post|Put|Patch|Delete)(?:Async|FromJsonAsync|AsJsonAsync|StringAsync|ByteArrayAsync|StreamAsync))(?:<[^>]*>)?\s*\(\s*(?:new\s+Uri\s*\(\s*)?[$@]*"([^"]*)"/g;
32
+ const REQUEST_MESSAGE_RE = /new\s+HttpRequestMessage\s*\(\s*HttpMethod\s*\.\s*(Get|Post|Put|Patch|Delete|Head|Options)\s*,\s*[$@]*"([^"]*)"/g;
33
+ const REFIT_ATTR_RE = /\[\s*(?<!Http)(Get|Post|Put|Patch|Delete|Head|Options)\s*\(\s*"([^"]*)"\s*\)\s*\]/g;
34
+ const csharpCallsites = {
35
+ language: "csharp",
36
+ extract(content, _filePath) {
37
+ return [...extractRoutes(content), ...extractOutbound(content)];
38
+ }
39
+ };
40
+ function controllerToken(className) {
41
+ return className.replace(/Controller$/, "").toLowerCase();
42
+ }
43
+ function expandTokens(pattern, className, actionName) {
44
+ let p = pattern;
45
+ if (className) p = p.replace(/\[controller\]/gi, controllerToken(className));
46
+ if (actionName) p = p.replace(/\[action\]/gi, actionName.toLowerCase());
47
+ return p;
48
+ }
49
+ function extractRoutes(content) {
50
+ const lines = content.split("\n").map((l) => (0, import_shared.stripLineComment)(l, "//"));
51
+ const out = [];
52
+ const groupPrefix = /* @__PURE__ */ new Map();
53
+ for (let sweep = 0; sweep < 2; sweep++) {
54
+ for (const line of lines) {
55
+ const m = MAP_GROUP_RE.exec(line);
56
+ if (!m) continue;
57
+ const [, name, parent, literal] = m;
58
+ groupPrefix.set(name, (0, import_shared.joinPath)(groupPrefix.get(parent) ?? "", literal));
59
+ }
60
+ }
61
+ const blockStack = [];
62
+ let depth = 0;
63
+ let className = null;
64
+ let classPrefix = "";
65
+ let pendingRoute = null;
66
+ let pendingVerbs = [];
67
+ for (let i = 0; i < lines.length; i++) {
68
+ const line = lines[i];
69
+ const lineNo = i + 1;
70
+ const depthBefore = depth;
71
+ depth += (0, import_shared.countBraces)(line);
72
+ const blockPrefix = (0, import_shared.unwindBlocks)(blockStack, depthBefore);
73
+ const routeAttr = ROUTE_ATTR_RE.exec(line);
74
+ const classDecl = CLASS_RE.exec(line);
75
+ if (classDecl) {
76
+ className = classDecl[1];
77
+ classPrefix = pendingRoute ? expandTokens(pendingRoute, className, null) : "";
78
+ pendingRoute = null;
79
+ pendingVerbs = [];
80
+ continue;
81
+ }
82
+ if (routeAttr) {
83
+ pendingRoute = routeAttr[1];
84
+ }
85
+ HTTP_ATTR_RE.lastIndex = 0;
86
+ let m;
87
+ while (m = HTTP_ATTR_RE.exec(line)) {
88
+ pendingVerbs.push({ verb: m[1], literal: m[2] ?? null, line: lineNo });
89
+ }
90
+ if (pendingVerbs.length > 0) {
91
+ const decl = METHOD_DECL_RE.exec(line);
92
+ if (decl) {
93
+ const actionName = decl[1];
94
+ for (const pending of pendingVerbs) {
95
+ const tail = pending.literal ?? pendingRoute ?? "";
96
+ const full = (0, import_shared.joinPath)(classPrefix, expandTokens(tail, className, actionName));
97
+ out.push((0, import_shared.route)(pending.line, pending.verb, full || "/", `[Http${pending.verb}]`));
98
+ }
99
+ pendingVerbs = [];
100
+ pendingRoute = null;
101
+ }
102
+ continue;
103
+ }
104
+ MAP_VERB_RE.lastIndex = 0;
105
+ while (m = MAP_VERB_RE.exec(line)) {
106
+ const [, recv, verb, literal] = m;
107
+ const prefix = groupPrefix.get(recv) ?? blockPrefix;
108
+ out.push((0, import_shared.route)(lineNo, verb, (0, import_shared.joinPath)(prefix, literal), `${recv}.Map${verb}`));
109
+ }
110
+ MAP_METHODS_RE.lastIndex = 0;
111
+ while (m = MAP_METHODS_RE.exec(line)) {
112
+ const [, recv, literal, verbList] = m;
113
+ const prefix = groupPrefix.get(recv) ?? blockPrefix;
114
+ const verbs = verbList.split(",").map((s) => s.replace(/["'\s]/g, "").toUpperCase()).filter((s) => import_shared.VERB_SET.has(s));
115
+ for (const verb of verbs) {
116
+ out.push((0, import_shared.route)(lineNo, verb, (0, import_shared.joinPath)(prefix, literal), `${recv}.MapMethods`));
117
+ }
118
+ }
119
+ }
120
+ return out;
121
+ }
122
+ function extractOutbound(content) {
123
+ const out = [];
124
+ let m;
125
+ CLIENT_CALL_RE.lastIndex = 0;
126
+ while (m = CLIENT_CALL_RE.exec(content)) {
127
+ const [, recv, fullName, verb, url] = m;
128
+ if (!(0, import_shared.isLikelyApiPath)(url)) continue;
129
+ out.push((0, import_shared.call)((0, import_shared.lineOf)(content, m.index), verb, url, `${recv}.${fullName}`));
130
+ }
131
+ REQUEST_MESSAGE_RE.lastIndex = 0;
132
+ while (m = REQUEST_MESSAGE_RE.exec(content)) {
133
+ const [, verb, url] = m;
134
+ if (!(0, import_shared.isLikelyApiPath)(url)) continue;
135
+ out.push((0, import_shared.call)((0, import_shared.lineOf)(content, m.index), verb, url, "new HttpRequestMessage"));
136
+ }
137
+ REFIT_ATTR_RE.lastIndex = 0;
138
+ while (m = REFIT_ATTR_RE.exec(content)) {
139
+ const [, verb, url] = m;
140
+ if (!(0, import_shared.isLikelyApiPath)(url)) continue;
141
+ out.push((0, import_shared.call)((0, import_shared.lineOf)(content, m.index), verb, url, `[${verb}] (Refit)`));
142
+ }
143
+ return out;
144
+ }
145
+ // Annotate the CommonJS export names for ESM import in node:
146
+ 0 && (module.exports = {
147
+ csharpCallsites
148
+ });