devchain-cli 0.23.1 → 0.23.3

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 (261) hide show
  1. package/dist/drizzle/0083_retire_documents.sql +2 -0
  2. package/dist/drizzle/0084_retire_codebase_overview.sql +1 -0
  3. package/dist/drizzle/0085_clumsy_zodiak.sql +166 -0
  4. package/dist/drizzle/meta/0083_snapshot.json +7422 -0
  5. package/dist/drizzle/meta/0084_snapshot.json +7422 -0
  6. package/dist/drizzle/meta/0085_snapshot.json +7446 -0
  7. package/dist/drizzle/meta/_journal.json +21 -0
  8. package/dist/server/app.main.module.js +0 -4
  9. package/dist/server/app.main.module.js.map +1 -1
  10. package/dist/server/app.normal.module.js +0 -4
  11. package/dist/server/app.normal.module.js.map +1 -1
  12. package/dist/server/modules/epic-time/controllers/external-estimate-log.controller.d.ts +1 -0
  13. package/dist/server/modules/epic-time/controllers/external-estimate-log.controller.js +48 -0
  14. package/dist/server/modules/epic-time/controllers/external-estimate-log.controller.js.map +1 -1
  15. package/dist/server/modules/epic-time/models/epic-time.models.d.ts +10 -0
  16. package/dist/server/modules/epic-time/services/epic-estimate-logging.service.d.ts +4 -1
  17. package/dist/server/modules/epic-time/services/epic-estimate-logging.service.js +43 -1
  18. package/dist/server/modules/epic-time/services/epic-estimate-logging.service.js.map +1 -1
  19. package/dist/server/modules/epics/subscribers/epic-assignment-notifier.subscriber.d.ts +1 -0
  20. package/dist/server/modules/epics/subscribers/epic-assignment-notifier.subscriber.js +31 -1
  21. package/dist/server/modules/epics/subscribers/epic-assignment-notifier.subscriber.js.map +1 -1
  22. package/dist/server/modules/external-integrations/connections/stable-integration-connection.d.ts +14 -0
  23. package/dist/server/modules/external-integrations/connections/stable-integration-connection.js +56 -0
  24. package/dist/server/modules/external-integrations/connections/stable-integration-connection.js.map +1 -0
  25. package/dist/server/modules/external-integrations/my-work/external-edit-session.service.d.ts +2 -1
  26. package/dist/server/modules/external-integrations/my-work/external-edit-session.service.js +51 -33
  27. package/dist/server/modules/external-integrations/my-work/external-edit-session.service.js.map +1 -1
  28. package/dist/server/modules/external-integrations/my-work/external-my-work.controller.js +2 -2
  29. package/dist/server/modules/external-integrations/my-work/external-my-work.controller.js.map +1 -1
  30. package/dist/server/modules/external-integrations/my-work/external-my-work.openapi.d.ts +1 -0
  31. package/dist/server/modules/external-integrations/my-work/external-my-work.openapi.js +33 -1
  32. package/dist/server/modules/external-integrations/my-work/external-my-work.openapi.js.map +1 -1
  33. package/dist/server/modules/external-integrations/my-work/external-my-work.service.d.ts +1 -1
  34. package/dist/server/modules/external-integrations/my-work/external-my-work.service.js +41 -48
  35. package/dist/server/modules/external-integrations/my-work/external-my-work.service.js.map +1 -1
  36. package/dist/server/modules/external-integrations/my-work/external-time-mutation.service.js +24 -11
  37. package/dist/server/modules/external-integrations/my-work/external-time-mutation.service.js.map +1 -1
  38. package/dist/server/modules/external-integrations/sessions/external-edit-session.store.js +3 -1
  39. package/dist/server/modules/external-integrations/sessions/external-edit-session.store.js.map +1 -1
  40. package/dist/server/modules/mcp/constants.d.ts +0 -2
  41. package/dist/server/modules/mcp/constants.js +1 -11
  42. package/dist/server/modules/mcp/constants.js.map +1 -1
  43. package/dist/server/modules/mcp/dtos/mcp.dto.d.ts +0 -165
  44. package/dist/server/modules/mcp/dtos/mcp.dto.js +1 -47
  45. package/dist/server/modules/mcp/dtos/mcp.dto.js.map +1 -1
  46. package/dist/server/modules/mcp/services/instructions-resolver.d.ts +4 -13
  47. package/dist/server/modules/mcp/services/instructions-resolver.js +26 -166
  48. package/dist/server/modules/mcp/services/instructions-resolver.js.map +1 -1
  49. package/dist/server/modules/mcp/services/mappers/dto-mappers.d.ts +2 -4
  50. package/dist/server/modules/mcp/services/mappers/dto-mappers.js +0 -22
  51. package/dist/server/modules/mcp/services/mappers/dto-mappers.js.map +1 -1
  52. package/dist/server/modules/mcp/services/mcp-tool-binding.registry.js +1 -2
  53. package/dist/server/modules/mcp/services/mcp-tool-binding.registry.js.map +1 -1
  54. package/dist/server/modules/mcp/services/utils/resource-resolver.d.ts +2 -4
  55. package/dist/server/modules/mcp/services/utils/resource-resolver.js +0 -59
  56. package/dist/server/modules/mcp/services/utils/resource-resolver.js.map +1 -1
  57. package/dist/server/modules/mcp/tool-descriptors/index.js +0 -2
  58. package/dist/server/modules/mcp/tool-descriptors/index.js.map +1 -1
  59. package/dist/server/modules/mcp/tool-descriptors/runtime-bindings.js +0 -2
  60. package/dist/server/modules/mcp/tool-descriptors/runtime-bindings.js.map +1 -1
  61. package/dist/server/modules/projects/helpers/project-import.d.ts +0 -33
  62. package/dist/server/modules/projects/helpers/project-import.js +0 -224
  63. package/dist/server/modules/projects/helpers/project-import.js.map +1 -1
  64. package/dist/server/modules/projects/services/project-registry-import.service.d.ts +3 -6
  65. package/dist/server/modules/projects/services/project-registry-import.service.js +7 -28
  66. package/dist/server/modules/projects/services/project-registry-import.service.js.map +1 -1
  67. package/dist/server/modules/projects/template-codec/codecs/teams.codec.js.map +1 -1
  68. package/dist/server/modules/registry/controllers/registry.controller.js +3 -10
  69. package/dist/server/modules/registry/controllers/registry.controller.js.map +1 -1
  70. package/dist/server/modules/registry/services/registry-orchestration.service.d.ts +11 -3
  71. package/dist/server/modules/registry/services/registry-orchestration.service.js +6 -1
  72. package/dist/server/modules/registry/services/registry-orchestration.service.js.map +1 -1
  73. package/dist/server/modules/session-reader/adapters/claude-session-reader.adapter.d.ts +8 -0
  74. package/dist/server/modules/session-reader/adapters/claude-session-reader.adapter.js +9 -0
  75. package/dist/server/modules/session-reader/adapters/claude-session-reader.adapter.js.map +1 -1
  76. package/dist/server/modules/session-reader/adapters/codex-session-reader.adapter.d.ts +10 -0
  77. package/dist/server/modules/session-reader/adapters/codex-session-reader.adapter.js +13 -0
  78. package/dist/server/modules/session-reader/adapters/codex-session-reader.adapter.js.map +1 -1
  79. package/dist/server/modules/session-reader/adapters/session-reader-adapter.interface.d.ts +20 -1
  80. package/dist/server/modules/session-reader/adapters/session-reader-adapter.interface.js.map +1 -1
  81. package/dist/server/modules/session-reader/controllers/session-reader.controller.d.ts +21 -1
  82. package/dist/server/modules/session-reader/controllers/session-reader.controller.js +49 -3
  83. package/dist/server/modules/session-reader/controllers/session-reader.controller.js.map +1 -1
  84. package/dist/server/modules/session-reader/data/pricing.json +2052 -178
  85. package/dist/server/modules/session-reader/parsers/bounded-line-read.d.ts +2 -0
  86. package/dist/server/modules/session-reader/parsers/bounded-line-read.js +66 -0
  87. package/dist/server/modules/session-reader/parsers/bounded-line-read.js.map +1 -0
  88. package/dist/server/modules/session-reader/parsers/claude-jsonl.parser.d.ts +6 -0
  89. package/dist/server/modules/session-reader/parsers/claude-jsonl.parser.js +44 -13
  90. package/dist/server/modules/session-reader/parsers/claude-jsonl.parser.js.map +1 -1
  91. package/dist/server/modules/session-reader/parsers/codex-jsonl.parser.d.ts +22 -0
  92. package/dist/server/modules/session-reader/parsers/codex-jsonl.parser.js +61 -16
  93. package/dist/server/modules/session-reader/parsers/codex-jsonl.parser.js.map +1 -1
  94. package/dist/server/modules/session-reader/services/bounded-anchor-proof.d.ts +12 -0
  95. package/dist/server/modules/session-reader/services/bounded-anchor-proof.js +103 -0
  96. package/dist/server/modules/session-reader/services/bounded-anchor-proof.js.map +1 -0
  97. package/dist/server/modules/session-reader/services/metrics-merge.d.ts +17 -0
  98. package/dist/server/modules/session-reader/services/metrics-merge.js +114 -0
  99. package/dist/server/modules/session-reader/services/metrics-merge.js.map +1 -0
  100. package/dist/server/modules/session-reader/services/session-cache.service.d.ts +40 -4
  101. package/dist/server/modules/session-reader/services/session-cache.service.js +232 -148
  102. package/dist/server/modules/session-reader/services/session-cache.service.js.map +1 -1
  103. package/dist/server/modules/session-reader/services/session-reader.service.d.ts +15 -1
  104. package/dist/server/modules/session-reader/services/session-reader.service.js +70 -2
  105. package/dist/server/modules/session-reader/services/session-reader.service.js.map +1 -1
  106. package/dist/server/modules/session-reader/services/transcript-watcher.service.d.ts +20 -3
  107. package/dist/server/modules/session-reader/services/transcript-watcher.service.js +538 -197
  108. package/dist/server/modules/session-reader/services/transcript-watcher.service.js.map +1 -1
  109. package/dist/server/modules/sessions/controllers/sessions.controller.d.ts +4 -1
  110. package/dist/server/modules/sessions/controllers/sessions.controller.js +32 -0
  111. package/dist/server/modules/sessions/controllers/sessions.controller.js.map +1 -1
  112. package/dist/server/modules/sessions/services/message-pool.types.d.ts +23 -0
  113. package/dist/server/modules/sessions/services/sessions-message-pool.service.d.ts +5 -2
  114. package/dist/server/modules/sessions/services/sessions-message-pool.service.js +82 -4
  115. package/dist/server/modules/sessions/services/sessions-message-pool.service.js.map +1 -1
  116. package/dist/server/modules/storage/db/schema.d.ts +57 -219
  117. package/dist/server/modules/storage/db/schema.js +15 -27
  118. package/dist/server/modules/storage/db/schema.js.map +1 -1
  119. package/dist/server/modules/storage/interfaces/storage.interface.d.ts +6 -23
  120. package/dist/server/modules/storage/interfaces/storage.interface.js.map +1 -1
  121. package/dist/server/modules/storage/local/delegates/external-estimate-log.delegate.d.ts +6 -1
  122. package/dist/server/modules/storage/local/delegates/external-estimate-log.delegate.js +163 -32
  123. package/dist/server/modules/storage/local/delegates/external-estimate-log.delegate.js.map +1 -1
  124. package/dist/server/modules/storage/local/delegates/external-managed-subtask.delegate.js +11 -1
  125. package/dist/server/modules/storage/local/delegates/external-managed-subtask.delegate.js.map +1 -1
  126. package/dist/server/modules/storage/local/delegates/integration.delegate.d.ts +1 -1
  127. package/dist/server/modules/storage/local/delegates/integration.delegate.js +17 -13
  128. package/dist/server/modules/storage/local/delegates/integration.delegate.js.map +1 -1
  129. package/dist/server/modules/storage/local/delegates/project.delegate.js +1 -10
  130. package/dist/server/modules/storage/local/delegates/project.delegate.js.map +1 -1
  131. package/dist/server/modules/storage/local/local-storage.service.d.ts +6 -9
  132. package/dist/server/modules/storage/local/local-storage.service.js +8 -22
  133. package/dist/server/modules/storage/local/local-storage.service.js.map +1 -1
  134. package/dist/server/modules/storage/models/domain.models.d.ts +14 -20
  135. package/dist/server/modules/storage/models/domain.models.js +2 -1
  136. package/dist/server/modules/storage/models/domain.models.js.map +1 -1
  137. package/dist/server/modules/terminal/services/human-prompt-state.service.d.ts +7 -0
  138. package/dist/server/modules/terminal/services/human-prompt-state.service.js +26 -0
  139. package/dist/server/modules/terminal/services/human-prompt-state.service.js.map +1 -1
  140. package/dist/server/modules/terminal/services/terminal-session/terminal-session.js +3 -2
  141. package/dist/server/modules/terminal/services/terminal-session/terminal-session.js.map +1 -1
  142. package/dist/server/modules/terminal/utils/terminal-activity.js +8 -1
  143. package/dist/server/modules/terminal/utils/terminal-activity.js.map +1 -1
  144. package/dist/server/templates/teams-dev.json +2 -2
  145. package/dist/server/tsconfig.tsbuildinfo +1 -1
  146. package/dist/server/ui/assets/{ExternalRichEditor-FwCAalXO.js → ExternalRichEditor-akgwTdms.js} +24 -24
  147. package/dist/server/ui/assets/ReviewDetailPage-10JU-Gdr.js +1 -0
  148. package/dist/server/ui/assets/ReviewsPage-BIVn-pS5.js +6 -0
  149. package/dist/server/ui/assets/index-Bg8fZbSZ.css +32 -0
  150. package/dist/server/ui/assets/index-DHmiffN1.js +1000 -0
  151. package/dist/server/ui/assets/useReviewSubscription-Xua63feT.js +69 -0
  152. package/dist/server/ui/index.html +2 -2
  153. package/dist/templates/teams-dev.json +2 -2
  154. package/package.json +13 -1
  155. package/dist/server/modules/codebase-overview-analyzer/codebase-overview-analyzer.module.d.ts +0 -2
  156. package/dist/server/modules/codebase-overview-analyzer/codebase-overview-analyzer.module.js +0 -52
  157. package/dist/server/modules/codebase-overview-analyzer/codebase-overview-analyzer.module.js.map +0 -1
  158. package/dist/server/modules/codebase-overview-analyzer/controllers/codebase-overview.controller.d.ts +0 -30
  159. package/dist/server/modules/codebase-overview-analyzer/controllers/codebase-overview.controller.js +0 -230
  160. package/dist/server/modules/codebase-overview-analyzer/controllers/codebase-overview.controller.js.map +0 -1
  161. package/dist/server/modules/codebase-overview-analyzer/repositories/overview-scope.repository.d.ts +0 -24
  162. package/dist/server/modules/codebase-overview-analyzer/repositories/overview-scope.repository.js +0 -191
  163. package/dist/server/modules/codebase-overview-analyzer/repositories/overview-scope.repository.js.map +0 -1
  164. package/dist/server/modules/codebase-overview-analyzer/services/codebase-overview-analyzer.service.d.ts +0 -73
  165. package/dist/server/modules/codebase-overview-analyzer/services/codebase-overview-analyzer.service.js +0 -1133
  166. package/dist/server/modules/codebase-overview-analyzer/services/codebase-overview-analyzer.service.js.map +0 -1
  167. package/dist/server/modules/codebase-overview-analyzer/services/dependency-aggregation.service.d.ts +0 -14
  168. package/dist/server/modules/codebase-overview-analyzer/services/dependency-aggregation.service.js +0 -114
  169. package/dist/server/modules/codebase-overview-analyzer/services/dependency-aggregation.service.js.map +0 -1
  170. package/dist/server/modules/codebase-overview-analyzer/services/district-splitting.service.d.ts +0 -8
  171. package/dist/server/modules/codebase-overview-analyzer/services/district-splitting.service.js +0 -200
  172. package/dist/server/modules/codebase-overview-analyzer/services/district-splitting.service.js.map +0 -1
  173. package/dist/server/modules/codebase-overview-analyzer/services/evidence-query.service.d.ts +0 -11
  174. package/dist/server/modules/codebase-overview-analyzer/services/evidence-query.service.js +0 -164
  175. package/dist/server/modules/codebase-overview-analyzer/services/evidence-query.service.js.map +0 -1
  176. package/dist/server/modules/codebase-overview-analyzer/services/go-adapter.d.ts +0 -2
  177. package/dist/server/modules/codebase-overview-analyzer/services/go-adapter.js +0 -166
  178. package/dist/server/modules/codebase-overview-analyzer/services/go-adapter.js.map +0 -1
  179. package/dist/server/modules/codebase-overview-analyzer/services/hotspot-scoring.service.d.ts +0 -21
  180. package/dist/server/modules/codebase-overview-analyzer/services/hotspot-scoring.service.js +0 -253
  181. package/dist/server/modules/codebase-overview-analyzer/services/hotspot-scoring.service.js.map +0 -1
  182. package/dist/server/modules/codebase-overview-analyzer/services/identity-resolver.service.d.ts +0 -24
  183. package/dist/server/modules/codebase-overview-analyzer/services/identity-resolver.service.js +0 -98
  184. package/dist/server/modules/codebase-overview-analyzer/services/identity-resolver.service.js.map +0 -1
  185. package/dist/server/modules/codebase-overview-analyzer/services/java-adapter.d.ts +0 -2
  186. package/dist/server/modules/codebase-overview-analyzer/services/java-adapter.js +0 -155
  187. package/dist/server/modules/codebase-overview-analyzer/services/java-adapter.js.map +0 -1
  188. package/dist/server/modules/codebase-overview-analyzer/services/language-adapter-registry.service.d.ts +0 -19
  189. package/dist/server/modules/codebase-overview-analyzer/services/language-adapter-registry.service.js +0 -88
  190. package/dist/server/modules/codebase-overview-analyzer/services/language-adapter-registry.service.js.map +0 -1
  191. package/dist/server/modules/codebase-overview-analyzer/services/php-adapter.d.ts +0 -2
  192. package/dist/server/modules/codebase-overview-analyzer/services/php-adapter.js +0 -173
  193. package/dist/server/modules/codebase-overview-analyzer/services/php-adapter.js.map +0 -1
  194. package/dist/server/modules/codebase-overview-analyzer/services/python-adapter.d.ts +0 -2
  195. package/dist/server/modules/codebase-overview-analyzer/services/python-adapter.js +0 -171
  196. package/dist/server/modules/codebase-overview-analyzer/services/python-adapter.js.map +0 -1
  197. package/dist/server/modules/codebase-overview-analyzer/services/ruby-adapter.d.ts +0 -2
  198. package/dist/server/modules/codebase-overview-analyzer/services/ruby-adapter.js +0 -158
  199. package/dist/server/modules/codebase-overview-analyzer/services/ruby-adapter.js.map +0 -1
  200. package/dist/server/modules/codebase-overview-analyzer/services/rust-adapter.d.ts +0 -2
  201. package/dist/server/modules/codebase-overview-analyzer/services/rust-adapter.js +0 -222
  202. package/dist/server/modules/codebase-overview-analyzer/services/rust-adapter.js.map +0 -1
  203. package/dist/server/modules/codebase-overview-analyzer/services/scope-auto-detector.service.d.ts +0 -4
  204. package/dist/server/modules/codebase-overview-analyzer/services/scope-auto-detector.service.js +0 -72
  205. package/dist/server/modules/codebase-overview-analyzer/services/scope-auto-detector.service.js.map +0 -1
  206. package/dist/server/modules/codebase-overview-analyzer/services/scope-resolver.service.d.ts +0 -6
  207. package/dist/server/modules/codebase-overview-analyzer/services/scope-resolver.service.js +0 -37
  208. package/dist/server/modules/codebase-overview-analyzer/services/scope-resolver.service.js.map +0 -1
  209. package/dist/server/modules/codebase-overview-analyzer/services/typescript-adapter.d.ts +0 -2
  210. package/dist/server/modules/codebase-overview-analyzer/services/typescript-adapter.js +0 -108
  211. package/dist/server/modules/codebase-overview-analyzer/services/typescript-adapter.js.map +0 -1
  212. package/dist/server/modules/codebase-overview-analyzer/types/index.d.ts +0 -2
  213. package/dist/server/modules/codebase-overview-analyzer/types/index.js +0 -6
  214. package/dist/server/modules/codebase-overview-analyzer/types/index.js.map +0 -1
  215. package/dist/server/modules/codebase-overview-analyzer/types/overview.types.d.ts +0 -231
  216. package/dist/server/modules/codebase-overview-analyzer/types/overview.types.js +0 -3
  217. package/dist/server/modules/codebase-overview-analyzer/types/overview.types.js.map +0 -1
  218. package/dist/server/modules/codebase-overview-analyzer/types/scope-defaults.d.ts +0 -2
  219. package/dist/server/modules/codebase-overview-analyzer/types/scope-defaults.js +0 -13
  220. package/dist/server/modules/codebase-overview-analyzer/types/scope-defaults.js.map +0 -1
  221. package/dist/server/modules/codebase-overview-analyzer/types/scope.schema.d.ts +0 -54
  222. package/dist/server/modules/codebase-overview-analyzer/types/scope.schema.js +0 -27
  223. package/dist/server/modules/codebase-overview-analyzer/types/scope.schema.js.map +0 -1
  224. package/dist/server/modules/codebase-overview-analyzer/types/scope.types.d.ts +0 -12
  225. package/dist/server/modules/codebase-overview-analyzer/types/scope.types.js +0 -3
  226. package/dist/server/modules/codebase-overview-analyzer/types/scope.types.js.map +0 -1
  227. package/dist/server/modules/codebase-overview-analyzer/utils/constants.d.ts +0 -1
  228. package/dist/server/modules/codebase-overview-analyzer/utils/constants.js +0 -5
  229. package/dist/server/modules/codebase-overview-analyzer/utils/constants.js.map +0 -1
  230. package/dist/server/modules/codebase-overview-analyzer/utils/path-matcher.d.ts +0 -2
  231. package/dist/server/modules/codebase-overview-analyzer/utils/path-matcher.js +0 -17
  232. package/dist/server/modules/codebase-overview-analyzer/utils/path-matcher.js.map +0 -1
  233. package/dist/server/modules/documents/controllers/documents.controller.d.ts +0 -12
  234. package/dist/server/modules/documents/controllers/documents.controller.js +0 -174
  235. package/dist/server/modules/documents/controllers/documents.controller.js.map +0 -1
  236. package/dist/server/modules/documents/documents.module.d.ts +0 -2
  237. package/dist/server/modules/documents/documents.module.js +0 -22
  238. package/dist/server/modules/documents/documents.module.js.map +0 -1
  239. package/dist/server/modules/mcp/services/handlers/document-context.d.ts +0 -8
  240. package/dist/server/modules/mcp/services/handlers/document-context.js +0 -3
  241. package/dist/server/modules/mcp/services/handlers/document-context.js.map +0 -1
  242. package/dist/server/modules/mcp/services/handlers/document-tools.d.ts +0 -6
  243. package/dist/server/modules/mcp/services/handlers/document-tools.js +0 -109
  244. package/dist/server/modules/mcp/services/handlers/document-tools.js.map +0 -1
  245. package/dist/server/modules/mcp/services/utils/document-link-resolver.d.ts +0 -10
  246. package/dist/server/modules/mcp/services/utils/document-link-resolver.js +0 -124
  247. package/dist/server/modules/mcp/services/utils/document-link-resolver.js.map +0 -1
  248. package/dist/server/modules/mcp/tool-descriptors/document.bindings.d.ts +0 -1
  249. package/dist/server/modules/mcp/tool-descriptors/document.bindings.js +0 -19
  250. package/dist/server/modules/mcp/tool-descriptors/document.bindings.js.map +0 -1
  251. package/dist/server/modules/mcp/tool-descriptors/document.metadata.d.ts +0 -2
  252. package/dist/server/modules/mcp/tool-descriptors/document.metadata.js +0 -96
  253. package/dist/server/modules/mcp/tool-descriptors/document.metadata.js.map +0 -1
  254. package/dist/server/modules/storage/local/delegates/document.delegate.d.ts +0 -18
  255. package/dist/server/modules/storage/local/delegates/document.delegate.js +0 -275
  256. package/dist/server/modules/storage/local/delegates/document.delegate.js.map +0 -1
  257. package/dist/server/ui/assets/ReviewDetailPage-D8DVpsJm.js +0 -1
  258. package/dist/server/ui/assets/ReviewsPage-DcWpRFbm.js +0 -6
  259. package/dist/server/ui/assets/index-CV8ydm7w.css +0 -32
  260. package/dist/server/ui/assets/index-Cwe7LxcW.js +0 -1197
  261. package/dist/server/ui/assets/useReviewSubscription-CYoSg-88.js +0 -69
@@ -51,15 +51,17 @@ exports.getTranscriptCacheConfig = getTranscriptCacheConfig;
51
51
  const common_1 = require("@nestjs/common");
52
52
  const node_crypto_1 = require("node:crypto");
53
53
  const fs = __importStar(require("node:fs/promises"));
54
- const estimate_content_tokens_1 = require("../adapters/utils/estimate-content-tokens");
55
- const tool_result_fold_1 = require("../adapters/utils/tool-result-fold");
56
54
  const coalesce_turns_1 = require("../adapters/utils/coalesce-turns");
55
+ const metrics_merge_1 = require("./metrics-merge");
56
+ const bounded_anchor_proof_1 = require("./bounded-anchor-proof");
57
+ const bounded_line_read_1 = require("../parsers/bounded-line-read");
57
58
  const metrics_service_1 = require("../../metrics/services/metrics.service");
59
+ const chunk_builder_1 = require("../builders/chunk-builder");
58
60
  const DEFAULT_CACHE_IDLE_TTL_MS = 10 * 60 * 1_000;
59
61
  const DEFAULT_CACHE_SWEEP_INTERVAL_MS = 60_000;
60
62
  const DEFAULT_CACHE_BUDGET_BYTES = 64 * 1024 * 1024;
61
63
  const SAFE_INTEGER_LOW_BITS = 0x20_0000;
62
- const FILE_HASH_CHUNK_BYTES = 64 * 1024;
64
+ const FULL_PARSE_COST_CAP = 256;
63
65
  function fileSourceVersion(stat) {
64
66
  const digest = (0, node_crypto_1.createHash)('sha256')
65
67
  .update(`${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeMs}`)
@@ -78,6 +80,8 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
78
80
  metricsService;
79
81
  logger = new common_1.Logger(SessionCacheService_1.name);
80
82
  cache = new Map();
83
+ parseFlights = new Map();
84
+ flightGeneration = 0;
81
85
  hits = 0;
82
86
  misses = 0;
83
87
  chunksHits = 0;
@@ -86,6 +90,8 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
86
90
  dtoMisses = 0;
87
91
  budgetUsedBytes = 0;
88
92
  evictions = 0;
93
+ fullParseSeq = 0;
94
+ fullParseCosts = new Map();
89
95
  idleSweepTimer;
90
96
  config;
91
97
  constructor(metricsService, config) {
@@ -104,6 +110,7 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
104
110
  this.idleSweepTimer = undefined;
105
111
  }
106
112
  this.clear();
113
+ this.fullParseCosts.clear();
107
114
  }
108
115
  getCacheStats() {
109
116
  const total = this.hits + this.misses;
@@ -159,6 +166,8 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
159
166
  if (!cached)
160
167
  return undefined;
161
168
  const ref = this.toSourceRef(source, adapter);
169
+ if (cached.sourceIdentity !== this.sourceIdentity(ref))
170
+ return undefined;
162
171
  const freshness = await this.computeFreshness(ref, adapter);
163
172
  return this.takeFreshCachedSession(sessionId, cached, freshness.token, Date.now());
164
173
  }
@@ -169,20 +178,158 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
169
178
  return this.getOrParseResult(sessionId, source, adapter);
170
179
  }
171
180
  async getOrParseResult(sessionId, source, adapter) {
181
+ const sourceIdentity = this.sourceIdentity(this.toSourceRef(source, adapter));
182
+ const arrivalGeneration = this.flightGeneration;
183
+ const existing = this.parseFlights.get(sessionId);
184
+ if (!existing) {
185
+ return (await this.startParseFlight(sessionId, source, adapter).promise).result;
186
+ }
187
+ let flight = existing;
188
+ for (;;) {
189
+ const sameSource = flight.sourceIdentity === sourceIdentity;
190
+ let snapshot;
191
+ try {
192
+ snapshot = await flight.promise;
193
+ }
194
+ catch (error) {
195
+ if (sameSource)
196
+ throw error;
197
+ }
198
+ const shareable = snapshot && !snapshot.absent ? snapshot : undefined;
199
+ if (sameSource && shareable && flight.generation > arrivalGeneration) {
200
+ return this.sharedResult(shareable.result);
201
+ }
202
+ const next = flight.next ?? this.parseFlights.get(sessionId);
203
+ if (next) {
204
+ flight = next;
205
+ continue;
206
+ }
207
+ const refresh = this.startParseFlight(sessionId, source, adapter, sameSource ? shareable : undefined);
208
+ flight.next = refresh;
209
+ return (await refresh.promise).result;
210
+ }
211
+ }
212
+ async refreshIfPresent(sessionId, source, adapter) {
213
+ const snapshot = await this.resolveIfPresentFlight(sessionId, source, adapter);
214
+ return this.toRefreshResult(sessionId, snapshot);
215
+ }
216
+ async resolveIfPresentFlight(sessionId, source, adapter) {
217
+ const sourceIdentity = this.sourceIdentity(this.toSourceRef(source, adapter));
218
+ const arrivalGeneration = this.flightGeneration;
219
+ const existing = this.parseFlights.get(sessionId);
220
+ if (!existing) {
221
+ return this.startParseFlight(sessionId, source, adapter, undefined, 'ifPresent').promise;
222
+ }
223
+ let flight = existing;
224
+ for (;;) {
225
+ const sameSource = flight.sourceIdentity === sourceIdentity;
226
+ let snapshot;
227
+ try {
228
+ snapshot = await flight.promise;
229
+ }
230
+ catch {
231
+ }
232
+ const shareable = snapshot && !snapshot.absent ? snapshot : undefined;
233
+ if (sameSource && shareable && flight.generation > arrivalGeneration) {
234
+ return shareable;
235
+ }
236
+ const next = flight.next ?? this.parseFlights.get(sessionId);
237
+ if (next) {
238
+ flight = next;
239
+ continue;
240
+ }
241
+ const refresh = this.startParseFlight(sessionId, source, adapter, sameSource ? shareable : undefined, 'ifPresent');
242
+ flight.next = refresh;
243
+ return refresh.promise;
244
+ }
245
+ }
246
+ toRefreshResult(sessionId, snapshot) {
247
+ if (snapshot.absent || !snapshot.result) {
248
+ const record = this.fullParseCosts.get(sessionId);
249
+ return record
250
+ ? { present: false, lastFullParse: { seq: record.seq, durationMs: record.durationMs } }
251
+ : { present: false };
252
+ }
253
+ if (snapshot.preParse) {
254
+ return { present: true, preParse: snapshot.preParse, result: snapshot.result };
255
+ }
256
+ return {
257
+ present: true,
258
+ preParse: this.preParseFromResult(snapshot.result),
259
+ result: this.sharedResult(snapshot.result),
260
+ };
261
+ }
262
+ startParseFlight(sessionId, source, adapter, previous, mode = 'always') {
263
+ const sourceIdentity = this.sourceIdentity(this.toSourceRef(source, adapter));
264
+ const flight = {
265
+ sourceIdentity,
266
+ generation: ++this.flightGeneration,
267
+ promise: Promise.resolve()
268
+ .then(() => this.parseSession(sessionId, source, adapter, sourceIdentity, previous, mode))
269
+ .finally(() => {
270
+ if (this.parseFlights.get(sessionId) === flight) {
271
+ this.parseFlights.delete(sessionId);
272
+ }
273
+ }),
274
+ };
275
+ this.parseFlights.set(sessionId, flight);
276
+ return flight;
277
+ }
278
+ sharedResult(result) {
279
+ this.hits += 1;
280
+ return { ...result, cacheHit: true, sourceChangeKind: 'cache-hit', boundaryFold: false };
281
+ }
282
+ async timedFullParse(sessionId, adapter, filePath, threadRef) {
283
+ const startedAt = performance.now();
284
+ const session = threadRef
285
+ ? await adapter.parseFullSession(filePath, threadRef)
286
+ : await adapter.parseFullSession(filePath);
287
+ this.recordFullParse(sessionId, performance.now() - startedAt);
288
+ return session;
289
+ }
290
+ recordFullParse(sessionId, durationMs) {
291
+ this.fullParseSeq += 1;
292
+ if (!this.fullParseCosts.has(sessionId) && this.fullParseCosts.size >= FULL_PARSE_COST_CAP) {
293
+ const oldest = this.fullParseCosts.keys().next().value;
294
+ if (oldest !== undefined)
295
+ this.fullParseCosts.delete(oldest);
296
+ }
297
+ this.fullParseCosts.set(sessionId, { seq: this.fullParseSeq, durationMs });
298
+ }
299
+ async parseSession(sessionId, source, adapter, sourceIdentity, previous, mode = 'always') {
172
300
  const now = Date.now();
173
301
  const ref = this.toSourceRef(source, adapter);
174
302
  const threadRef = typeof source !== 'string' ? ref : undefined;
175
303
  let freshness = await this.computeFreshness(ref, adapter);
176
- const cached = this.cache.get(sessionId);
304
+ const retained = this.cache.get(sessionId);
305
+ const cached = retained?.sourceIdentity === sourceIdentity ? retained : undefined;
306
+ if (mode === 'ifPresent' && !cached) {
307
+ return { absent: true, freshnessToken: freshness.token };
308
+ }
309
+ const preParse = mode === 'ifPresent' && cached ? this.preParseGeneration(cached) : undefined;
310
+ if (previous && JSON.stringify(previous.freshnessToken) === JSON.stringify(freshness.token)) {
311
+ if (cached && cached.session === previous.result?.session)
312
+ this.touchLru(sessionId, cached, now);
313
+ return {
314
+ result: this.sharedResult(previous.result),
315
+ freshnessToken: freshness.token,
316
+ preParse,
317
+ };
318
+ }
177
319
  const freshSession = this.takeFreshCachedSession(sessionId, cached, freshness.token, now);
178
320
  if (freshSession && cached) {
179
- return this.toGetOrParseResult(freshSession, cached, true, 'cache-hit');
321
+ return {
322
+ result: this.toGetOrParseResult(freshSession, cached, true, 'cache-hit'),
323
+ freshnessToken: freshness.token,
324
+ preParse,
325
+ };
180
326
  }
181
327
  this.misses += 1;
182
328
  let session;
183
329
  let lastOffset;
184
330
  let boundaryFold = false;
185
- let acceptedFileDigests;
331
+ let acceptedFileAnchors;
332
+ let continuationState;
186
333
  const sameFileIdentity = ref.kind !== 'file' ||
187
334
  (cached?.fileIdentity !== undefined && cached.fileIdentity === freshness.fileIdentity);
188
335
  const fileReplaced = cached !== undefined && ref.kind === 'file' && !sameFileIdentity;
@@ -190,12 +337,12 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
190
337
  ref.kind === 'file' &&
191
338
  sameFileIdentity &&
192
339
  freshness.size > cached.lastSize;
193
- const growthDigests = sameIdentityGrowth && cached.fileContentDigest !== undefined
194
- ? await this.tryHashFileContent(ref.filePath, freshness, cached.lastOffset)
340
+ const growthAnchors = sameIdentityGrowth && cached.fileContentAnchors !== undefined
341
+ ? await this.tryHashFileAnchors(ref.filePath, freshness, cached.lastOffset)
195
342
  : undefined;
196
343
  const provenSameFileAppend = sameIdentityGrowth &&
197
- cached.fileContentDigest !== undefined &&
198
- growthDigests?.prefixDigest === cached.fileContentDigest;
344
+ cached.fileContentAnchors !== undefined &&
345
+ (0, bounded_anchor_proof_1.anchorsEqual)(growthAnchors, cached.fileContentAnchors);
199
346
  let sourceChangeKind = !cached
200
347
  ? 'unknown-full-parse'
201
348
  : ref.kind === 'db'
@@ -209,26 +356,36 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
209
356
  : freshness.size < cached.lastSize
210
357
  ? 'file-truncation'
211
358
  : 'same-file-rewrite';
212
- if (cached && provenSameFileAppend && growthDigests) {
359
+ if (cached && provenSameFileAppend && cached.fileContentAnchors) {
213
360
  this.logger.debug({ sessionId, lastOffset: cached.lastOffset, currentSize: freshness.size }, 'Incremental parse (source grew)');
214
361
  const incOptions = { byteOffset: cached.lastOffset, includeToolCalls: true };
362
+ if (adapter.incrementalMode === 'delta') {
363
+ incOptions.endByteOffset = freshness.size;
364
+ }
365
+ if (cached.continuationState !== undefined) {
366
+ incOptions.continuationState = cached.continuationState;
367
+ }
215
368
  let tentativeResult = threadRef
216
369
  ? await adapter.parseIncremental(ref.filePath, incOptions, threadRef)
217
370
  : await adapter.parseIncremental(ref.filePath, incOptions);
218
- const postParseDigests = await this.tryHashFileContent(ref.filePath, freshness, freshness.size);
219
- if (postParseDigests?.fullDigest !== growthDigests.fullDigest) {
371
+ const newOffset = tentativeResult.nextByteOffset;
372
+ const prefixHeld = newOffset >= cached.lastOffset &&
373
+ (0, bounded_anchor_proof_1.anchorsEqual)(await this.tryHashFileAnchors(ref.filePath, freshness, cached.lastOffset, true), cached.fileContentAnchors);
374
+ const proofAnchors = prefixHeld
375
+ ? await this.tryHashFileAnchors(ref.filePath, freshness, newOffset, true)
376
+ : undefined;
377
+ if (proofAnchors === undefined) {
220
378
  this.logger.debug({ sessionId }, 'Discarding incremental parse because its proven file revision drifted');
221
379
  tentativeResult = undefined;
222
380
  freshness = await this.computeFreshness(ref, adapter);
223
381
  sourceChangeKind = this.classifyUnsafeFileChange(cached, freshness);
224
- session = threadRef
225
- ? await adapter.parseFullSession(ref.filePath, threadRef)
226
- : await adapter.parseFullSession(ref.filePath);
382
+ session = await this.timedFullParse(sessionId, adapter, ref.filePath, threadRef);
227
383
  lastOffset = freshness.size;
228
384
  }
229
385
  else {
230
386
  const acceptedResult = tentativeResult;
231
- acceptedFileDigests = postParseDigests;
387
+ acceptedFileAnchors = proofAnchors;
388
+ continuationState = acceptedResult.continuationState;
232
389
  const newMessages = acceptedResult.entries;
233
390
  if (adapter.incrementalMode === 'snapshot') {
234
391
  const snapshotMetrics = acceptedResult.metrics ?? cached.session.metrics;
@@ -245,7 +402,7 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
245
402
  boundaryFold = folded.tailMutatedWithoutNewMessage;
246
403
  const mergedMessages = folded.merged;
247
404
  const mergedMetrics = acceptedResult.metrics
248
- ? this.mergeMetrics(cached.session.metrics, acceptedResult.metrics, mergedMessages)
405
+ ? (0, metrics_merge_1.mergeMetrics)(cached.session.metrics, acceptedResult.metrics, (0, metrics_merge_1.deriveMergeInputsFromMessages)(cached.session.metrics, mergedMessages))
249
406
  : cached.session.metrics;
250
407
  session = {
251
408
  ...cached.session,
@@ -265,9 +422,7 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
265
422
  else if (cached && freshness.size < cached.lastSize) {
266
423
  this.logger.debug({ sessionId }, 'Full reparse (source truncated)');
267
424
  }
268
- session = threadRef
269
- ? await adapter.parseFullSession(ref.filePath, threadRef)
270
- : await adapter.parseFullSession(ref.filePath);
425
+ session = await this.timedFullParse(sessionId, adapter, ref.filePath, threadRef);
271
426
  lastOffset = freshness.size;
272
427
  }
273
428
  const coalesced = (0, coalesce_turns_1.coalesceAssistantTurns)(session);
@@ -275,44 +430,51 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
275
430
  session = { ...session, messages: coalesced.messages, metrics: coalesced.metrics };
276
431
  }
277
432
  session = this.withoutDerivedChunks(session);
278
- const fileContentDigest = ref.kind === 'file'
279
- ? lastOffset === freshness.size && acceptedFileDigests !== undefined
280
- ? acceptedFileDigests.fullDigest
281
- : (await this.tryHashFileContent(ref.filePath, freshness, lastOffset))?.prefixDigest
282
- : undefined;
433
+ const fileContentAnchors = await this.resolveStoredAnchors(ref, freshness, lastOffset, acceptedFileAnchors);
283
434
  this.deleteEntry(sessionId);
284
435
  const sourceWeightBytes = this.estimateSourceWeight(ref, session, freshness.size);
285
436
  const entry = {
437
+ sourceIdentity,
286
438
  session,
287
439
  lastOffset,
288
440
  lastSize: freshness.size,
289
441
  lastMtime: freshness.mtimeMs,
290
442
  fileIdentity: freshness.fileIdentity,
291
- fileContentDigest,
443
+ fileContentAnchors,
292
444
  sourceVersion: freshness.sourceVersion,
293
445
  freshnessToken: freshness.token,
294
446
  lastAccessedAt: now,
295
447
  sourceWeightBytes,
296
448
  weights: { parsed: sourceWeightBytes * 2, chunks: 0, dto: 0 },
297
449
  boundaryFold,
450
+ continuationState,
298
451
  };
299
452
  this.cache.set(sessionId, entry);
300
453
  this.budgetUsedBytes += entry.weights.parsed;
301
454
  this.enforceBudget();
302
455
  return {
303
- session,
304
- cacheHit: false,
305
- sourceChangeKind,
306
- lastOffset,
307
- lastSize: freshness.size,
308
- lastMtime: freshness.mtimeMs,
309
- sourceVersion: freshness.sourceVersion,
310
- boundaryFold,
456
+ result: this.toGetOrParseResult(session, entry, false, sourceChangeKind),
457
+ freshnessToken: freshness.token,
458
+ preParse,
311
459
  };
312
460
  }
313
461
  getEntry(sessionId) {
314
462
  return this.cache.get(sessionId);
315
463
  }
464
+ preParseGeneration(entry) {
465
+ return {
466
+ sourceVersion: entry.sourceVersion,
467
+ messageCount: entry.session.messages.length,
468
+ chunkCount: entry.chunks?.chunks.length ?? (0, chunk_builder_1.buildChunks)(entry.session.messages).length,
469
+ };
470
+ }
471
+ preParseFromResult(result) {
472
+ return {
473
+ sourceVersion: result.sourceVersion,
474
+ messageCount: result.session.messages.length,
475
+ chunkCount: result.session.chunks?.length ?? (0, chunk_builder_1.buildChunks)(result.session.messages).length,
476
+ };
477
+ }
316
478
  getChunks(sessionId, sourceVersion) {
317
479
  const entry = this.cache.get(sessionId);
318
480
  if (!entry?.chunks || entry.chunks.sourceVersion !== sourceVersion) {
@@ -394,7 +556,9 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
394
556
  return this.cache.size;
395
557
  }
396
558
  takeFreshCachedSession(sessionId, cached, freshnessToken, now) {
397
- if (!cached || JSON.stringify(cached.freshnessToken) !== JSON.stringify(freshnessToken)) {
559
+ if (!cached ||
560
+ this.cache.get(sessionId) !== cached ||
561
+ JSON.stringify(cached.freshnessToken) !== JSON.stringify(freshnessToken)) {
398
562
  return undefined;
399
563
  }
400
564
  this.logger.debug({ sessionId }, 'Session cache hit');
@@ -411,10 +575,14 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
411
575
  lastSize: entry.lastSize,
412
576
  lastMtime: entry.lastMtime,
413
577
  sourceVersion: entry.sourceVersion,
414
- boundaryFold: entry.boundaryFold,
578
+ boundaryFold: cacheHit ? false : entry.boundaryFold,
579
+ fileContentAnchors: entry.fileContentAnchors,
580
+ continuationState: entry.continuationState,
415
581
  };
416
582
  }
417
583
  touchLru(sessionId, entry, now) {
584
+ if (this.cache.get(sessionId) !== entry)
585
+ return;
418
586
  entry.lastAccessedAt = now;
419
587
  this.cache.delete(sessionId);
420
588
  this.cache.set(sessionId, entry);
@@ -453,27 +621,7 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
453
621
  }
454
622
  foldLeadingContinuationIntoCachedTail(cachedMessages, newMessages) {
455
623
  const tail = cachedMessages[cachedMessages.length - 1];
456
- if (!tail || tail.role !== 'assistant' || newMessages.length === 0) {
457
- return { merged: [...cachedMessages, ...newMessages], tailMutatedWithoutNewMessage: false };
458
- }
459
- let foldCount = 0;
460
- let tailStopReason = tail.stopReason ?? null;
461
- while (foldCount < newMessages.length) {
462
- const m = newMessages[foldCount];
463
- if (m.isSidechain !== tail.isSidechain)
464
- break;
465
- if (m.isCompactSummary)
466
- break;
467
- const isToolResult = (0, tool_result_fold_1.isToolResultOnlyMessage)(m);
468
- const isContinuationAssistant = m.role === 'assistant';
469
- if (!isToolResult && !isContinuationAssistant)
470
- break;
471
- if (isContinuationAssistant && tailStopReason === 'end_turn')
472
- break;
473
- if (isContinuationAssistant)
474
- tailStopReason = m.stopReason ?? null;
475
- foldCount += 1;
476
- }
624
+ const { foldCount, tailMutatedWithoutNewMessage } = (0, metrics_merge_1.computeLeadingContinuationFold)((0, metrics_merge_1.describeTail)(tail), newMessages);
477
625
  if (foldCount === 0) {
478
626
  return { merged: [...cachedMessages, ...newMessages], tailMutatedWithoutNewMessage: false };
479
627
  }
@@ -489,51 +637,7 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
489
637
  const remaining = newMessages.slice(foldCount);
490
638
  return {
491
639
  merged: [...cachedMessages.slice(0, -1), foldedTail, ...remaining],
492
- tailMutatedWithoutNewMessage: remaining.length === 0,
493
- };
494
- }
495
- mergeMetrics(existing, incremental, allMessages) {
496
- const inputTokens = existing.inputTokens + incremental.inputTokens;
497
- const outputTokens = existing.outputTokens + incremental.outputTokens;
498
- const cacheReadTokens = existing.cacheReadTokens + incremental.cacheReadTokens;
499
- const cacheCreationTokens = existing.cacheCreationTokens + incremental.cacheCreationTokens;
500
- const totalTokens = inputTokens + outputTokens + cacheReadTokens + cacheCreationTokens;
501
- let durationMs = existing.durationMs;
502
- if (allMessages.length >= 2) {
503
- durationMs =
504
- allMessages[allMessages.length - 1].timestamp.getTime() -
505
- allMessages[0].timestamp.getTime();
506
- }
507
- const modelsSet = new Set();
508
- if (existing.primaryModel)
509
- modelsSet.add(existing.primaryModel);
510
- if (incremental.primaryModel)
511
- modelsSet.add(incremental.primaryModel);
512
- if (existing.modelsUsed)
513
- existing.modelsUsed.forEach((m) => modelsSet.add(m));
514
- if (incremental.modelsUsed)
515
- incremental.modelsUsed.forEach((m) => modelsSet.add(m));
516
- const modelsUsed = modelsSet.size > 1 ? Array.from(modelsSet) : undefined;
517
- return {
518
- inputTokens,
519
- outputTokens,
520
- cacheReadTokens,
521
- cacheCreationTokens,
522
- totalTokens,
523
- costUsd: existing.costUsd + incremental.costUsd,
524
- primaryModel: incremental.primaryModel ?? existing.primaryModel,
525
- modelsUsed,
526
- isOngoing: incremental.isOngoing,
527
- visibleContextTokens: (0, estimate_content_tokens_1.estimateVisibleFromMessages)(allMessages),
528
- totalContextTokens: incremental.totalContextTokens > 0
529
- ? incremental.totalContextTokens
530
- : existing.totalContextTokens,
531
- contextWindowTokens: incremental.contextWindowTokens ?? existing.contextWindowTokens,
532
- messageCount: allMessages.length,
533
- durationMs,
534
- totalContextConsumption: existing.totalContextConsumption,
535
- compactionCount: existing.compactionCount,
536
- phaseBreakdowns: existing.phaseBreakdowns,
640
+ tailMutatedWithoutNewMessage,
537
641
  };
538
642
  }
539
643
  mergeWarnings(existing, incremental) {
@@ -565,59 +669,31 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
565
669
  }
566
670
  return 'same-file-rewrite';
567
671
  }
568
- async tryHashFileContent(filePath, expected, prefixLength) {
672
+ async tryHashFileAnchors(filePath, expected, offset, allowGrowth = false) {
569
673
  try {
570
- return await this.hashFileContent(filePath, expected, prefixLength);
674
+ return await (0, bounded_anchor_proof_1.hashFileAnchors)(filePath, expected, offset, allowGrowth);
571
675
  }
572
676
  catch (error) {
573
- this.logger.debug({ error, filePath }, 'File prefix proof unavailable — append is unsafe');
677
+ this.logger.debug({ error, filePath }, 'File anchor proof unavailable — append is unsafe');
574
678
  return undefined;
575
679
  }
576
680
  }
577
- async hashFileContent(filePath, expected, prefixLength) {
578
- if (!Number.isSafeInteger(prefixLength) ||
579
- prefixLength < 0 ||
580
- prefixLength > expected.size ||
581
- expected.fileIdentity === undefined) {
582
- throw new Error('Invalid file prefix proof bounds');
583
- }
584
- const handle = await fs.open(filePath, 'r');
585
- const assertStableSnapshot = async () => {
586
- const current = await handle.stat();
587
- if (current.size !== expected.size ||
588
- current.mtime.getTime() !== expected.mtimeMs ||
589
- `${current.dev}:${current.ino}` !== expected.fileIdentity) {
590
- throw new Error('File changed while computing append proof');
591
- }
592
- };
681
+ async resolveStoredAnchors(ref, freshness, lastOffset, acceptedFileAnchors) {
682
+ if (ref.kind !== 'file')
683
+ return undefined;
684
+ if (acceptedFileAnchors)
685
+ return acceptedFileAnchors;
686
+ if (!(await this.snapshotEndsOnLineBoundary(ref.filePath, lastOffset)))
687
+ return undefined;
688
+ return this.tryHashFileAnchors(ref.filePath, freshness, lastOffset);
689
+ }
690
+ async snapshotEndsOnLineBoundary(filePath, offset) {
593
691
  try {
594
- await assertStableSnapshot();
595
- const prefixHash = (0, node_crypto_1.createHash)('sha256');
596
- const fullHash = (0, node_crypto_1.createHash)('sha256');
597
- const buffer = Buffer.allocUnsafe(Math.min(FILE_HASH_CHUNK_BYTES, Math.max(1, expected.size)));
598
- let position = 0;
599
- while (position < expected.size) {
600
- const requested = Math.min(buffer.byteLength, expected.size - position);
601
- const { bytesRead } = await handle.read(buffer, 0, requested, position);
602
- if (bytesRead === 0) {
603
- throw new Error('File ended while computing append proof');
604
- }
605
- const chunk = buffer.subarray(0, bytesRead);
606
- fullHash.update(chunk);
607
- const prefixBytes = Math.min(bytesRead, Math.max(0, prefixLength - position));
608
- if (prefixBytes > 0) {
609
- prefixHash.update(chunk.subarray(0, prefixBytes));
610
- }
611
- position += bytesRead;
612
- }
613
- await assertStableSnapshot();
614
- return {
615
- prefixDigest: prefixHash.digest('hex'),
616
- fullDigest: fullHash.digest('hex'),
617
- };
692
+ return (await (0, bounded_line_read_1.lastCompleteLineEnd)(filePath, 0, offset)) === offset;
618
693
  }
619
- finally {
620
- await handle.close();
694
+ catch (error) {
695
+ this.logger.debug({ error, filePath }, 'Line-boundary probe failed — withholding append proof');
696
+ return false;
621
697
  }
622
698
  }
623
699
  toSourceRef(source, adapter) {
@@ -630,6 +706,14 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
630
706
  }
631
707
  return source;
632
708
  }
709
+ sourceIdentity(ref) {
710
+ return JSON.stringify([
711
+ ref.providerName.trim().toLowerCase(),
712
+ ref.kind,
713
+ ref.filePath,
714
+ ref.kind === 'db' ? ref.providerSessionId : undefined,
715
+ ]);
716
+ }
633
717
  async computeFreshness(ref, adapter) {
634
718
  const { size, mtimeMs, dev, ino, fileIdentity } = await this.statFile(ref.filePath);
635
719
  const adapterToken = adapter.getFreshnessToken