@orion-agents/orion-code 0.1.4 → 0.1.6

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 (540) hide show
  1. package/README.md +73 -38
  2. package/README.zh-CN.md +32 -10
  3. package/dist/agents/coder.d.ts.map +1 -1
  4. package/dist/agents/coder.js.map +1 -1
  5. package/dist/agents/fork.d.ts +12 -4
  6. package/dist/agents/fork.d.ts.map +1 -1
  7. package/dist/agents/fork.js +28 -32
  8. package/dist/agents/fork.js.map +1 -1
  9. package/dist/agents/leader.d.ts.map +1 -1
  10. package/dist/agents/leader.js.map +1 -1
  11. package/dist/agents/worker-pool.d.ts.map +1 -1
  12. package/dist/agents/worker-pool.js +38 -29
  13. package/dist/agents/worker-pool.js.map +1 -1
  14. package/dist/cli.d.ts +1 -1
  15. package/dist/cli.d.ts.map +1 -1
  16. package/dist/cli.js +4 -1
  17. package/dist/cli.js.map +1 -1
  18. package/dist/commands/context-commands.d.ts +4 -0
  19. package/dist/commands/context-commands.d.ts.map +1 -0
  20. package/dist/commands/context-commands.js +74 -0
  21. package/dist/commands/context-commands.js.map +1 -0
  22. package/dist/commands/context-tool-command-handlers.d.ts +13 -0
  23. package/dist/commands/context-tool-command-handlers.d.ts.map +1 -0
  24. package/dist/commands/context-tool-command-handlers.js +617 -0
  25. package/dist/commands/context-tool-command-handlers.js.map +1 -0
  26. package/dist/commands/core-command-handlers.d.ts +12 -0
  27. package/dist/commands/core-command-handlers.d.ts.map +1 -0
  28. package/dist/commands/core-command-handlers.js +805 -0
  29. package/dist/commands/core-command-handlers.js.map +1 -0
  30. package/dist/commands/diagnostic-command-handlers.d.ts +14 -0
  31. package/dist/commands/diagnostic-command-handlers.d.ts.map +1 -0
  32. package/dist/commands/diagnostic-command-handlers.js +1043 -0
  33. package/dist/commands/diagnostic-command-handlers.js.map +1 -0
  34. package/dist/commands/diagnostic-commands.d.ts +4 -0
  35. package/dist/commands/diagnostic-commands.d.ts.map +1 -0
  36. package/dist/commands/diagnostic-commands.js +175 -0
  37. package/dist/commands/diagnostic-commands.js.map +1 -0
  38. package/dist/commands/index.d.ts +9 -10
  39. package/dist/commands/index.d.ts.map +1 -1
  40. package/dist/commands/index.js +42 -3563
  41. package/dist/commands/index.js.map +1 -1
  42. package/dist/commands/legacy-commands.d.ts +4 -0
  43. package/dist/commands/legacy-commands.d.ts.map +1 -0
  44. package/dist/commands/legacy-commands.js +44 -0
  45. package/dist/commands/legacy-commands.js.map +1 -0
  46. package/dist/commands/model-command-handlers.d.ts +15 -0
  47. package/dist/commands/model-command-handlers.d.ts.map +1 -0
  48. package/dist/commands/model-command-handlers.js +526 -0
  49. package/dist/commands/model-command-handlers.js.map +1 -0
  50. package/dist/commands/model-commands.d.ts +4 -0
  51. package/dist/commands/model-commands.d.ts.map +1 -0
  52. package/dist/commands/model-commands.js +85 -0
  53. package/dist/commands/model-commands.js.map +1 -0
  54. package/dist/commands/parser.d.ts +12 -0
  55. package/dist/commands/parser.d.ts.map +1 -1
  56. package/dist/commands/parser.js +48 -7
  57. package/dist/commands/parser.js.map +1 -1
  58. package/dist/commands/registry.d.ts +4 -0
  59. package/dist/commands/registry.d.ts.map +1 -0
  60. package/dist/commands/registry.js +566 -0
  61. package/dist/commands/registry.js.map +1 -0
  62. package/dist/commands/session-command-handlers.d.ts +10 -0
  63. package/dist/commands/session-command-handlers.d.ts.map +1 -0
  64. package/dist/commands/session-command-handlers.js +626 -0
  65. package/dist/commands/session-command-handlers.js.map +1 -0
  66. package/dist/commands/session-commands.d.ts +4 -0
  67. package/dist/commands/session-commands.d.ts.map +1 -0
  68. package/dist/commands/session-commands.js +102 -0
  69. package/dist/commands/session-commands.js.map +1 -0
  70. package/dist/commands/system-commands.d.ts +4 -0
  71. package/dist/commands/system-commands.d.ts.map +1 -0
  72. package/dist/commands/system-commands.js +80 -0
  73. package/dist/commands/system-commands.js.map +1 -0
  74. package/dist/commands/target-command.d.ts +1 -1
  75. package/dist/commands/target-command.d.ts.map +1 -1
  76. package/dist/commands/target-command.js +42 -6
  77. package/dist/commands/target-command.js.map +1 -1
  78. package/dist/commands/tool-commands.d.ts +4 -0
  79. package/dist/commands/tool-commands.d.ts.map +1 -0
  80. package/dist/commands/tool-commands.js +49 -0
  81. package/dist/commands/tool-commands.js.map +1 -0
  82. package/dist/commands/types.d.ts +69 -5
  83. package/dist/commands/types.d.ts.map +1 -1
  84. package/dist/commands/types.js +3 -4
  85. package/dist/commands/types.js.map +1 -1
  86. package/dist/commands/workflow-command-handlers.d.ts +7 -0
  87. package/dist/commands/workflow-command-handlers.d.ts.map +1 -0
  88. package/dist/commands/workflow-command-handlers.js +32 -0
  89. package/dist/commands/workflow-command-handlers.js.map +1 -0
  90. package/dist/commands/workflow-commands.d.ts +4 -0
  91. package/dist/commands/workflow-commands.d.ts.map +1 -0
  92. package/dist/commands/workflow-commands.js +124 -0
  93. package/dist/commands/workflow-commands.js.map +1 -0
  94. package/dist/core/checkpoint.d.ts +12 -4
  95. package/dist/core/checkpoint.d.ts.map +1 -1
  96. package/dist/core/checkpoint.js +114 -28
  97. package/dist/core/checkpoint.js.map +1 -1
  98. package/dist/core/cost-tracker.d.ts +17 -1
  99. package/dist/core/cost-tracker.d.ts.map +1 -1
  100. package/dist/core/cost-tracker.js +24 -8
  101. package/dist/core/cost-tracker.js.map +1 -1
  102. package/dist/core/warn-dedup.d.ts +3 -0
  103. package/dist/core/warn-dedup.d.ts.map +1 -1
  104. package/dist/core/warn-dedup.js +6 -6
  105. package/dist/core/warn-dedup.js.map +1 -1
  106. package/dist/framework/index.d.ts +1 -1
  107. package/dist/framework/index.d.ts.map +1 -1
  108. package/dist/framework/index.js.map +1 -1
  109. package/dist/framework/prompt.d.ts +2 -2
  110. package/dist/framework/query.d.ts +2 -2
  111. package/dist/framework/query.d.ts.map +1 -1
  112. package/dist/framework/query.js +57 -10
  113. package/dist/framework/query.js.map +1 -1
  114. package/dist/framework/store.d.ts +15 -6
  115. package/dist/framework/store.d.ts.map +1 -1
  116. package/dist/framework/store.js +18 -0
  117. package/dist/framework/store.js.map +1 -1
  118. package/dist/framework/tool-scheduler.d.ts +16 -13
  119. package/dist/framework/tool-scheduler.d.ts.map +1 -1
  120. package/dist/framework/tool-scheduler.js +155 -38
  121. package/dist/framework/tool-scheduler.js.map +1 -1
  122. package/dist/framework/tool.d.ts +39 -2
  123. package/dist/framework/tool.d.ts.map +1 -1
  124. package/dist/framework/tool.js +27 -1
  125. package/dist/framework/tool.js.map +1 -1
  126. package/dist/harness/assembler.d.ts.map +1 -1
  127. package/dist/harness/assembler.js +4 -2
  128. package/dist/harness/assembler.js.map +1 -1
  129. package/dist/harness/drift-guard.d.ts.map +1 -1
  130. package/dist/harness/drift-guard.js +9 -1
  131. package/dist/harness/drift-guard.js.map +1 -1
  132. package/dist/harness/evidence.d.ts.map +1 -1
  133. package/dist/harness/evidence.js +3 -2
  134. package/dist/harness/evidence.js.map +1 -1
  135. package/dist/harness/safety.d.ts +11 -1
  136. package/dist/harness/safety.d.ts.map +1 -1
  137. package/dist/harness/safety.js +112 -16
  138. package/dist/harness/safety.js.map +1 -1
  139. package/dist/index.d.ts +1 -4
  140. package/dist/index.d.ts.map +1 -1
  141. package/dist/index.js.map +1 -1
  142. package/dist/init.d.ts +4 -8
  143. package/dist/init.d.ts.map +1 -1
  144. package/dist/init.js +4 -4
  145. package/dist/init.js.map +1 -1
  146. package/dist/ink-ui/App.d.ts +2 -2
  147. package/dist/ink-ui/components/Markdown.d.ts.map +1 -1
  148. package/dist/ink-ui/components/Markdown.js.map +1 -1
  149. package/dist/ink-ui/components/PixelHorseBanner.d.ts +2 -2
  150. package/dist/ink-ui/components/StatusLine.d.ts +2 -2
  151. package/dist/ink-ui/launch.d.ts +2 -2
  152. package/dist/ink-ui/screens/ReplScreen.d.ts +4 -3
  153. package/dist/ink-ui/screens/ReplScreen.d.ts.map +1 -1
  154. package/dist/ink-ui/screens/ReplScreen.js +103 -31
  155. package/dist/ink-ui/screens/ReplScreen.js.map +1 -1
  156. package/dist/memory/relevant-finder.d.ts +2 -1
  157. package/dist/memory/relevant-finder.d.ts.map +1 -1
  158. package/dist/memory/relevant-finder.js +17 -8
  159. package/dist/memory/relevant-finder.js.map +1 -1
  160. package/dist/memory/semantic-config.d.ts +9 -0
  161. package/dist/memory/semantic-config.d.ts.map +1 -0
  162. package/dist/memory/semantic-config.js +16 -0
  163. package/dist/memory/semantic-config.js.map +1 -0
  164. package/dist/memory/semantic-search.d.ts +1 -6
  165. package/dist/memory/semantic-search.d.ts.map +1 -1
  166. package/dist/memory/semantic-search.js +3 -15
  167. package/dist/memory/semantic-search.js.map +1 -1
  168. package/dist/memory/storage.d.ts +23 -0
  169. package/dist/memory/storage.d.ts.map +1 -1
  170. package/dist/memory/storage.js +116 -9
  171. package/dist/memory/storage.js.map +1 -1
  172. package/dist/memory/validation.d.ts +3 -0
  173. package/dist/memory/validation.d.ts.map +1 -1
  174. package/dist/memory/validation.js +123 -10
  175. package/dist/memory/validation.js.map +1 -1
  176. package/dist/memory/vector-store.d.ts +30 -0
  177. package/dist/memory/vector-store.d.ts.map +1 -1
  178. package/dist/memory/vector-store.js +160 -21
  179. package/dist/memory/vector-store.js.map +1 -1
  180. package/dist/migration/command.d.ts.map +1 -1
  181. package/dist/migration/command.js +0 -1
  182. package/dist/migration/command.js.map +1 -1
  183. package/dist/migration/migrate.d.ts.map +1 -1
  184. package/dist/migration/migrate.js +59 -107
  185. package/dist/migration/migrate.js.map +1 -1
  186. package/dist/migration/types.d.ts +0 -1
  187. package/dist/migration/types.d.ts.map +1 -1
  188. package/dist/print-ui/launch.d.ts +13 -3
  189. package/dist/print-ui/launch.d.ts.map +1 -1
  190. package/dist/print-ui/launch.js +28 -3
  191. package/dist/print-ui/launch.js.map +1 -1
  192. package/dist/product/environment.d.ts +3 -5
  193. package/dist/product/environment.d.ts.map +1 -1
  194. package/dist/product/environment.js +4 -32
  195. package/dist/product/environment.js.map +1 -1
  196. package/dist/product/index.d.ts +1 -1
  197. package/dist/product/index.d.ts.map +1 -1
  198. package/dist/product/index.js +1 -3
  199. package/dist/product/index.js.map +1 -1
  200. package/dist/product/paths.d.ts.map +1 -1
  201. package/dist/product/paths.js +16 -11
  202. package/dist/product/paths.js.map +1 -1
  203. package/dist/runtime/agent-runtime-controller.d.ts +4 -2
  204. package/dist/runtime/agent-runtime-controller.d.ts.map +1 -1
  205. package/dist/runtime/agent-runtime-controller.js +129 -15
  206. package/dist/runtime/agent-runtime-controller.js.map +1 -1
  207. package/dist/runtime/agent-runtime-protocol.d.ts +15 -0
  208. package/dist/runtime/agent-runtime-protocol.d.ts.map +1 -1
  209. package/dist/runtime/agent-runtime-protocol.js +6 -0
  210. package/dist/runtime/agent-runtime-protocol.js.map +1 -1
  211. package/dist/runtime/chat-checkpoint.d.ts +17 -0
  212. package/dist/runtime/chat-checkpoint.d.ts.map +1 -0
  213. package/dist/runtime/chat-checkpoint.js +108 -0
  214. package/dist/runtime/chat-checkpoint.js.map +1 -0
  215. package/dist/runtime/chat-controller.d.ts +10 -51
  216. package/dist/runtime/chat-controller.d.ts.map +1 -1
  217. package/dist/runtime/chat-controller.js +256 -1070
  218. package/dist/runtime/chat-controller.js.map +1 -1
  219. package/dist/runtime/chat-effort.d.ts +5 -0
  220. package/dist/runtime/chat-effort.d.ts.map +1 -0
  221. package/dist/runtime/chat-effort.js +47 -0
  222. package/dist/runtime/chat-effort.js.map +1 -0
  223. package/dist/runtime/chat-presentation.d.ts +60 -0
  224. package/dist/runtime/chat-presentation.d.ts.map +1 -0
  225. package/dist/runtime/chat-presentation.js +537 -0
  226. package/dist/runtime/chat-presentation.js.map +1 -0
  227. package/dist/runtime/chat-trace.d.ts +52 -0
  228. package/dist/runtime/chat-trace.d.ts.map +1 -0
  229. package/dist/runtime/chat-trace.js +234 -0
  230. package/dist/runtime/chat-trace.js.map +1 -0
  231. package/dist/runtime/chat-workspace.d.ts +22 -0
  232. package/dist/runtime/chat-workspace.d.ts.map +1 -0
  233. package/dist/runtime/chat-workspace.js +154 -0
  234. package/dist/runtime/chat-workspace.js.map +1 -0
  235. package/dist/runtime/goals/accounting.js +1 -1
  236. package/dist/runtime/goals/accounting.js.map +1 -1
  237. package/dist/runtime/goals/completion-audit.d.ts.map +1 -1
  238. package/dist/runtime/goals/completion-audit.js +5 -4
  239. package/dist/runtime/goals/completion-audit.js.map +1 -1
  240. package/dist/runtime/goals/coordinator.d.ts +3 -0
  241. package/dist/runtime/goals/coordinator.d.ts.map +1 -1
  242. package/dist/runtime/goals/coordinator.js +56 -2
  243. package/dist/runtime/goals/coordinator.js.map +1 -1
  244. package/dist/runtime/goals/prompt.d.ts +1 -1
  245. package/dist/runtime/goals/prompt.d.ts.map +1 -1
  246. package/dist/runtime/goals/prompt.js +4 -3
  247. package/dist/runtime/goals/prompt.js.map +1 -1
  248. package/dist/runtime/goals/tools.d.ts +32 -8
  249. package/dist/runtime/goals/tools.d.ts.map +1 -1
  250. package/dist/runtime/goals/tools.js +187 -11
  251. package/dist/runtime/goals/tools.js.map +1 -1
  252. package/dist/runtime/goals/types.d.ts +9 -0
  253. package/dist/runtime/goals/types.d.ts.map +1 -1
  254. package/dist/runtime/goals/types.js +1 -0
  255. package/dist/runtime/goals/types.js.map +1 -1
  256. package/dist/runtime/loop-budget.d.ts +2 -2
  257. package/dist/runtime/rich-text/markdown-parser.d.ts +2 -0
  258. package/dist/runtime/rich-text/markdown-parser.d.ts.map +1 -1
  259. package/dist/runtime/rich-text/markdown-parser.js +50 -10
  260. package/dist/runtime/rich-text/markdown-parser.js.map +1 -1
  261. package/dist/runtime/subagents/index.d.ts +2 -2
  262. package/dist/runtime/subagents/index.d.ts.map +1 -1
  263. package/dist/runtime/subagents/index.js +2 -1
  264. package/dist/runtime/subagents/index.js.map +1 -1
  265. package/dist/runtime/subagents/policy.d.ts +1 -1
  266. package/dist/runtime/subagents/policy.d.ts.map +1 -1
  267. package/dist/runtime/subagents/policy.js.map +1 -1
  268. package/dist/runtime/subagents/presets.d.ts +2 -2
  269. package/dist/runtime/subagents/research-artifact.d.ts +7 -0
  270. package/dist/runtime/subagents/research-artifact.d.ts.map +1 -1
  271. package/dist/runtime/subagents/research-artifact.js +73 -27
  272. package/dist/runtime/subagents/research-artifact.js.map +1 -1
  273. package/dist/runtime/subagents/research-contract.d.ts +18 -4
  274. package/dist/runtime/subagents/research-contract.d.ts.map +1 -1
  275. package/dist/runtime/subagents/research-contract.js +122 -17
  276. package/dist/runtime/subagents/research-contract.js.map +1 -1
  277. package/dist/runtime/subagents/research-renderer.d.ts +27 -11
  278. package/dist/runtime/subagents/research-renderer.d.ts.map +1 -1
  279. package/dist/runtime/subagents/research-renderer.js +34 -2
  280. package/dist/runtime/subagents/research-renderer.js.map +1 -1
  281. package/dist/runtime/subagents/result-parser.d.ts +1 -5
  282. package/dist/runtime/subagents/result-parser.d.ts.map +1 -1
  283. package/dist/runtime/subagents/result-parser.js +5 -72
  284. package/dist/runtime/subagents/result-parser.js.map +1 -1
  285. package/dist/runtime/subagents/runtime-integration.d.ts +13 -7
  286. package/dist/runtime/subagents/runtime-integration.d.ts.map +1 -1
  287. package/dist/runtime/subagents/runtime-integration.js +112 -2
  288. package/dist/runtime/subagents/runtime-integration.js.map +1 -1
  289. package/dist/runtime/subagents/supervisor.d.ts +15 -1
  290. package/dist/runtime/subagents/supervisor.d.ts.map +1 -1
  291. package/dist/runtime/subagents/supervisor.js +58 -3
  292. package/dist/runtime/subagents/supervisor.js.map +1 -1
  293. package/dist/runtime/subagents/tool.d.ts +2 -2
  294. package/dist/runtime/subagents/tool.d.ts.map +1 -1
  295. package/dist/runtime/subagents/tool.js +129 -9
  296. package/dist/runtime/subagents/tool.js.map +1 -1
  297. package/dist/runtime/subagents/types.d.ts +20 -0
  298. package/dist/runtime/subagents/types.d.ts.map +1 -1
  299. package/dist/runtime/subagents/types.js.map +1 -1
  300. package/dist/runtime/subagents/web-research-adapter.d.ts +4 -2
  301. package/dist/runtime/subagents/web-research-adapter.d.ts.map +1 -1
  302. package/dist/runtime/subagents/web-research-adapter.js +81 -15
  303. package/dist/runtime/subagents/web-research-adapter.js.map +1 -1
  304. package/dist/runtime/ui-events.d.ts +36 -8
  305. package/dist/runtime/ui-events.d.ts.map +1 -1
  306. package/dist/runtime/ui-events.js.map +1 -1
  307. package/dist/runtime/ui-view-model.d.ts +53 -4
  308. package/dist/runtime/ui-view-model.d.ts.map +1 -1
  309. package/dist/runtime/ui-view-model.js +190 -10
  310. package/dist/runtime/ui-view-model.js.map +1 -1
  311. package/dist/services/agent-runner.d.ts +5 -2
  312. package/dist/services/agent-runner.d.ts.map +1 -1
  313. package/dist/services/agent-runner.js +18 -18
  314. package/dist/services/agent-runner.js.map +1 -1
  315. package/dist/services/atomic-write.d.ts +9 -1
  316. package/dist/services/atomic-write.d.ts.map +1 -1
  317. package/dist/services/atomic-write.js +55 -2
  318. package/dist/services/atomic-write.js.map +1 -1
  319. package/dist/services/auth/auth.d.ts +11 -7
  320. package/dist/services/auth/auth.d.ts.map +1 -1
  321. package/dist/services/auth/auth.js +117 -31
  322. package/dist/services/auth/auth.js.map +1 -1
  323. package/dist/services/auth/aws.d.ts +2 -0
  324. package/dist/services/auth/aws.d.ts.map +1 -1
  325. package/dist/services/auth/aws.js +126 -12
  326. package/dist/services/auth/aws.js.map +1 -1
  327. package/dist/services/auth/index.d.ts +1 -1
  328. package/dist/services/auth/index.d.ts.map +1 -1
  329. package/dist/services/auth/index.js +2 -1
  330. package/dist/services/auth/index.js.map +1 -1
  331. package/dist/services/auto-fix/autoFixConfig.d.ts +0 -3
  332. package/dist/services/auto-fix/autoFixConfig.d.ts.map +1 -1
  333. package/dist/services/auto-fix/autoFixConfig.js +25 -8
  334. package/dist/services/auto-fix/autoFixConfig.js.map +1 -1
  335. package/dist/services/auto-fix/autoFixHook.d.ts +7 -0
  336. package/dist/services/auto-fix/autoFixHook.d.ts.map +1 -1
  337. package/dist/services/auto-fix/autoFixHook.js +10 -1
  338. package/dist/services/auto-fix/autoFixHook.js.map +1 -1
  339. package/dist/services/compact/auto-compact.d.ts +2 -0
  340. package/dist/services/compact/auto-compact.d.ts.map +1 -1
  341. package/dist/services/compact/auto-compact.js +15 -1
  342. package/dist/services/compact/auto-compact.js.map +1 -1
  343. package/dist/services/compact/compact.d.ts.map +1 -1
  344. package/dist/services/compact/compact.js +9 -11
  345. package/dist/services/compact/compact.js.map +1 -1
  346. package/dist/services/compact/summary-generator.d.ts.map +1 -1
  347. package/dist/services/compact/summary-generator.js +28 -4
  348. package/dist/services/compact/summary-generator.js.map +1 -1
  349. package/dist/services/compact/tool-call-groups.d.ts +19 -0
  350. package/dist/services/compact/tool-call-groups.d.ts.map +1 -0
  351. package/dist/services/compact/tool-call-groups.js +105 -0
  352. package/dist/services/compact/tool-call-groups.js.map +1 -0
  353. package/dist/services/concurrent-sessions.d.ts +4 -0
  354. package/dist/services/concurrent-sessions.d.ts.map +1 -1
  355. package/dist/services/concurrent-sessions.js +59 -12
  356. package/dist/services/concurrent-sessions.js.map +1 -1
  357. package/dist/services/config.d.ts +8 -4
  358. package/dist/services/config.d.ts.map +1 -1
  359. package/dist/services/config.js +15 -71
  360. package/dist/services/config.js.map +1 -1
  361. package/dist/services/doctor.d.ts +2 -2
  362. package/dist/services/doctor.js.map +1 -1
  363. package/dist/services/effort.d.ts +40 -0
  364. package/dist/services/effort.d.ts.map +1 -0
  365. package/dist/services/effort.js +88 -0
  366. package/dist/services/effort.js.map +1 -0
  367. package/dist/services/file-glob.d.ts.map +1 -1
  368. package/dist/services/file-glob.js +22 -2
  369. package/dist/services/file-glob.js.map +1 -1
  370. package/dist/services/file-lock.d.ts +7 -0
  371. package/dist/services/file-lock.d.ts.map +1 -0
  372. package/dist/services/file-lock.js +193 -0
  373. package/dist/services/file-lock.js.map +1 -0
  374. package/dist/services/global-config.d.ts +9 -0
  375. package/dist/services/global-config.d.ts.map +1 -1
  376. package/dist/services/global-config.js +79 -4
  377. package/dist/services/global-config.js.map +1 -1
  378. package/dist/services/goal-storage.d.ts.map +1 -1
  379. package/dist/services/goal-storage.js +35 -11
  380. package/dist/services/goal-storage.js.map +1 -1
  381. package/dist/services/llm.d.ts +35 -17
  382. package/dist/services/llm.d.ts.map +1 -1
  383. package/dist/services/llm.js +249 -113
  384. package/dist/services/llm.js.map +1 -1
  385. package/dist/services/mcp/transports.d.ts +0 -1
  386. package/dist/services/mcp/transports.d.ts.map +1 -1
  387. package/dist/services/mcp/transports.js +12 -13
  388. package/dist/services/mcp/transports.js.map +1 -1
  389. package/dist/services/model-context.d.ts +8 -0
  390. package/dist/services/model-context.d.ts.map +1 -1
  391. package/dist/services/model-context.js +111 -7
  392. package/dist/services/model-context.js.map +1 -1
  393. package/dist/services/model-registry.d.ts +3 -0
  394. package/dist/services/model-registry.d.ts.map +1 -1
  395. package/dist/services/model-registry.js +59 -2
  396. package/dist/services/model-registry.js.map +1 -1
  397. package/dist/services/provider-diagnostics.d.ts +1 -1
  398. package/dist/services/provider-diagnostics.d.ts.map +1 -1
  399. package/dist/services/provider-diagnostics.js +30 -16
  400. package/dist/services/provider-diagnostics.js.map +1 -1
  401. package/dist/services/provider-resilience/coordinator.d.ts +8 -3
  402. package/dist/services/provider-resilience/coordinator.d.ts.map +1 -1
  403. package/dist/services/provider-resilience/coordinator.js +86 -19
  404. package/dist/services/provider-resilience/coordinator.js.map +1 -1
  405. package/dist/services/provider-resilience/error-classifier.d.ts +1 -0
  406. package/dist/services/provider-resilience/error-classifier.d.ts.map +1 -1
  407. package/dist/services/provider-resilience/error-classifier.js +50 -26
  408. package/dist/services/provider-resilience/error-classifier.js.map +1 -1
  409. package/dist/services/provider-resilience/index.d.ts +3 -3
  410. package/dist/services/provider-resilience/index.d.ts.map +1 -1
  411. package/dist/services/provider-resilience/index.js +3 -1
  412. package/dist/services/provider-resilience/index.js.map +1 -1
  413. package/dist/services/provider-resilience/request-gate.d.ts +6 -0
  414. package/dist/services/provider-resilience/request-gate.d.ts.map +1 -1
  415. package/dist/services/provider-resilience/request-gate.js +24 -9
  416. package/dist/services/provider-resilience/request-gate.js.map +1 -1
  417. package/dist/services/provider-resilience/types.d.ts +10 -1
  418. package/dist/services/provider-resilience/types.d.ts.map +1 -1
  419. package/dist/services/provider-resilience/types.js.map +1 -1
  420. package/dist/services/redaction.d.ts.map +1 -1
  421. package/dist/services/redaction.js +29 -1
  422. package/dist/services/redaction.js.map +1 -1
  423. package/dist/services/session-index.d.ts.map +1 -1
  424. package/dist/services/session-index.js +75 -44
  425. package/dist/services/session-index.js.map +1 -1
  426. package/dist/services/session-memory/sessionMemory.d.ts.map +1 -1
  427. package/dist/services/session-memory/sessionMemory.js +6 -3
  428. package/dist/services/session-memory/sessionMemory.js.map +1 -1
  429. package/dist/services/session-storage.d.ts +12 -0
  430. package/dist/services/session-storage.d.ts.map +1 -1
  431. package/dist/services/session-storage.js +301 -230
  432. package/dist/services/session-storage.js.map +1 -1
  433. package/dist/services/storage-maintenance.d.ts.map +1 -1
  434. package/dist/services/storage-maintenance.js +25 -7
  435. package/dist/services/storage-maintenance.js.map +1 -1
  436. package/dist/services/task-manager.d.ts +6 -1
  437. package/dist/services/task-manager.d.ts.map +1 -1
  438. package/dist/services/task-manager.js +18 -4
  439. package/dist/services/task-manager.js.map +1 -1
  440. package/dist/services/tool-allowlist.d.ts +20 -10
  441. package/dist/services/tool-allowlist.d.ts.map +1 -1
  442. package/dist/services/tool-allowlist.js +64 -15
  443. package/dist/services/tool-allowlist.js.map +1 -1
  444. package/dist/services/usage-state.d.ts +10 -0
  445. package/dist/services/usage-state.d.ts.map +1 -1
  446. package/dist/services/usage-state.js +116 -45
  447. package/dist/services/usage-state.js.map +1 -1
  448. package/dist/services/verification-profile.d.ts.map +1 -1
  449. package/dist/services/verification-profile.js +23 -3
  450. package/dist/services/verification-profile.js.map +1 -1
  451. package/dist/services/workspace-diff.d.ts +14 -0
  452. package/dist/services/workspace-diff.d.ts.map +1 -1
  453. package/dist/services/workspace-diff.js +60 -11
  454. package/dist/services/workspace-diff.js.map +1 -1
  455. package/dist/services/yaml-config.d.ts.map +1 -1
  456. package/dist/services/yaml-config.js +2 -1
  457. package/dist/services/yaml-config.js.map +1 -1
  458. package/dist/skills/loader.d.ts.map +1 -1
  459. package/dist/skills/loader.js +23 -9
  460. package/dist/skills/loader.js.map +1 -1
  461. package/dist/skills/runtime.d.ts +3 -3
  462. package/dist/skills/runtime.d.ts.map +1 -1
  463. package/dist/skills/runtime.js +37 -4
  464. package/dist/skills/runtime.js.map +1 -1
  465. package/dist/skills/types.d.ts +1 -1
  466. package/dist/skills/types.d.ts.map +1 -1
  467. package/dist/terminal-ui/launch.d.ts +26 -8
  468. package/dist/terminal-ui/launch.d.ts.map +1 -1
  469. package/dist/terminal-ui/launch.js +82 -39
  470. package/dist/terminal-ui/launch.js.map +1 -1
  471. package/dist/tools/bash_security.d.ts +17 -0
  472. package/dist/tools/bash_security.d.ts.map +1 -1
  473. package/dist/tools/bash_security.js +233 -27
  474. package/dist/tools/bash_security.js.map +1 -1
  475. package/dist/tools/git.d.ts +8 -8
  476. package/dist/tools/git.d.ts.map +1 -1
  477. package/dist/tools/git.js +248 -55
  478. package/dist/tools/git.js.map +1 -1
  479. package/dist/tools/index.d.ts +13 -3
  480. package/dist/tools/index.d.ts.map +1 -1
  481. package/dist/tools/index.js +262 -30
  482. package/dist/tools/index.js.map +1 -1
  483. package/dist/tools/lsp.d.ts +74 -6
  484. package/dist/tools/lsp.d.ts.map +1 -1
  485. package/dist/tools/lsp.js +24 -5
  486. package/dist/tools/lsp.js.map +1 -1
  487. package/dist/tools/mcp.d.ts +11 -4
  488. package/dist/tools/mcp.d.ts.map +1 -1
  489. package/dist/tools/mcp.js +99 -3
  490. package/dist/tools/mcp.js.map +1 -1
  491. package/dist/tools/plan.d.ts +4 -4
  492. package/dist/tools/sandbox.d.ts +5 -1
  493. package/dist/tools/sandbox.d.ts.map +1 -1
  494. package/dist/tools/sandbox.js +29 -13
  495. package/dist/tools/sandbox.js.map +1 -1
  496. package/dist/tools/todo.d.ts +3 -3
  497. package/dist/tools/web.d.ts +15 -4
  498. package/dist/tools/web.d.ts.map +1 -1
  499. package/dist/tools/web.js +240 -26
  500. package/dist/tools/web.js.map +1 -1
  501. package/dist/tui-ui/launch.d.ts +3 -3
  502. package/dist/tui-ui/launch.d.ts.map +1 -1
  503. package/dist/tui-ui/launch.js +3 -3
  504. package/dist/tui-ui/launch.js.map +1 -1
  505. package/dist/tui-ui/layout.d.ts.map +1 -1
  506. package/dist/tui-ui/layout.js +19 -5
  507. package/dist/tui-ui/layout.js.map +1 -1
  508. package/dist/tui-ui/pickers.d.ts.map +1 -1
  509. package/dist/tui-ui/pickers.js +1 -0
  510. package/dist/tui-ui/pickers.js.map +1 -1
  511. package/dist/tui-ui/runner.d.ts +2 -1
  512. package/dist/tui-ui/runner.d.ts.map +1 -1
  513. package/dist/tui-ui/runner.js +18 -29
  514. package/dist/tui-ui/runner.js.map +1 -1
  515. package/dist/tui-ui/state.d.ts +13 -1
  516. package/dist/tui-ui/state.d.ts.map +1 -1
  517. package/dist/tui-ui/state.js +28 -1
  518. package/dist/tui-ui/state.js.map +1 -1
  519. package/dist/ui/markdown.js.map +1 -1
  520. package/dist/utils/debug-log.d.ts +3 -3
  521. package/dist/utils/debug-log.d.ts.map +1 -1
  522. package/dist/utils/debug-log.js +7 -4
  523. package/dist/utils/debug-log.js.map +1 -1
  524. package/dist/utils/json.d.ts +6 -0
  525. package/dist/utils/json.d.ts.map +1 -0
  526. package/dist/utils/json.js +66 -0
  527. package/dist/utils/json.js.map +1 -0
  528. package/dist/utils/mask.d.ts +8 -1
  529. package/dist/utils/mask.d.ts.map +1 -1
  530. package/dist/utils/mask.js +10 -12
  531. package/dist/utils/mask.js.map +1 -1
  532. package/dist/utils/observability.d.ts +22 -0
  533. package/dist/utils/observability.d.ts.map +1 -0
  534. package/dist/utils/observability.js +80 -0
  535. package/dist/utils/observability.js.map +1 -0
  536. package/dist/utils/token-estimate.d.ts +8 -0
  537. package/dist/utils/token-estimate.d.ts.map +1 -1
  538. package/dist/utils/token-estimate.js +30 -17
  539. package/dist/utils/token-estimate.js.map +1 -1
  540. package/package.json +9 -8
@@ -12,6 +12,7 @@ exports.getProjectKey = getProjectKey;
12
12
  exports.isSessionMetaFile = isSessionMetaFile;
13
13
  exports.createSession = createSession;
14
14
  exports.saveSessionMeta = saveSessionMeta;
15
+ exports.updateSessionEffort = updateSessionEffort;
15
16
  exports.loadSessionMeta = loadSessionMeta;
16
17
  exports.updateSessionStats = updateSessionStats;
17
18
  exports.resumeSession = resumeSession;
@@ -34,6 +35,7 @@ exports.appendSessionMessage = appendSessionMessage;
34
35
  exports.appendSessionMessages = appendSessionMessages;
35
36
  exports.truncateSessionToLastComplete = truncateSessionToLastComplete;
36
37
  exports.removeLastIncompleteAssistantMessage = removeLastIncompleteAssistantMessage;
38
+ exports.removeTrailingSessionUserMessage = removeTrailingSessionUserMessage;
37
39
  exports.readSessionMessages = readSessionMessages;
38
40
  exports.appendSessionTraceEvent = appendSessionTraceEvent;
39
41
  exports.readSessionTraceEvents = readSessionTraceEvents;
@@ -50,7 +52,9 @@ const child_process_1 = require("child_process");
50
52
  const path_1 = require("path");
51
53
  const config_dir_1 = require("./config-dir");
52
54
  const atomic_write_1 = require("./atomic-write");
55
+ const file_lock_1 = require("./file-lock");
53
56
  const session_index_1 = require("./session-index");
57
+ const tool_call_groups_1 = require("./compact/tool-call-groups");
54
58
  const redaction_1 = require("./redaction");
55
59
  const debug_log_1 = require("../utils/debug-log");
56
60
  const goal_storage_1 = require("./goal-storage");
@@ -238,6 +242,15 @@ function normalizeSessionMeta(session) {
238
242
  gitBranch: session.gitBranch ?? getGitBranch(projectPath),
239
243
  };
240
244
  }
245
+ function tryNormalizeSessionMeta(session, sourcePath) {
246
+ try {
247
+ return normalizeSessionMeta(session);
248
+ }
249
+ catch (error) {
250
+ (0, debug_log_1.debugError)('session-storage.normalizeSessionMeta', error, sourcePath);
251
+ return null;
252
+ }
253
+ }
241
254
  function uniquePaths(paths) {
242
255
  return [...new Set(paths)];
243
256
  }
@@ -366,103 +379,129 @@ function createSession(projectPath, model) {
366
379
  function saveSessionMeta(session) {
367
380
  (0, config_dir_1.ensureConfigDir)();
368
381
  const normalized = normalizeSessionMeta(session);
369
- const payload = JSON.stringify(normalized, null, 2);
370
382
  (0, config_dir_1.ensureProjectDir)(normalized.projectPath);
371
- (0, atomic_write_1.atomicWriteFileSync)((0, config_dir_1.getProjectSessionMetaPath)(normalized.projectPath, normalized.id), payload, {
372
- mode: 0o600,
383
+ const metaPath = (0, config_dir_1.getProjectSessionMetaPath)(normalized.projectPath, normalized.id);
384
+ (0, file_lock_1.withFileLockSync)(metaPath, () => {
385
+ writeSessionMetaUnlocked(normalized);
386
+ });
387
+ }
388
+ function writeSessionMetaUnlocked(session) {
389
+ const normalized = normalizeSessionMeta(session);
390
+ (0, config_dir_1.ensureProjectDir)(normalized.projectPath);
391
+ (0, atomic_write_1.atomicWriteFileSync)((0, config_dir_1.getProjectSessionMetaPath)(normalized.projectPath, normalized.id), JSON.stringify(normalized, null, 2), { mode: 0o600 });
392
+ }
393
+ function findSessionMetaPath(sessionId) {
394
+ const projectsDir = (0, config_dir_1.getProjectsDir)();
395
+ if (!(0, fs_1.existsSync)(projectsDir))
396
+ return null;
397
+ for (const projectKey of (0, fs_1.readdirSync)(projectsDir)) {
398
+ const path = (0, path_1.join)(projectsDir, projectKey, 'sessions', `${sessionId}.json`);
399
+ if ((0, fs_1.existsSync)(path) && readSessionMetaAtPath(path))
400
+ return path;
401
+ }
402
+ return null;
403
+ }
404
+ function readSessionMetaAtPath(path) {
405
+ const session = parseSessionMetaFile(path);
406
+ return session ? tryNormalizeSessionMeta(session, path) : null;
407
+ }
408
+ /**
409
+ * Serialize a session read-modify-write transaction across Orion processes.
410
+ * The metadata path is rediscovered before each transaction and re-read only
411
+ * after the lock is held, so a stale snapshot can never overwrite a concurrent
412
+ * message/stat update.
413
+ */
414
+ function withLockedSession(sessionId, operation) {
415
+ const metaPath = findSessionMetaPath(sessionId);
416
+ if (!metaPath)
417
+ return null;
418
+ return (0, file_lock_1.withFileLockSync)(metaPath, () => {
419
+ const session = readSessionMetaAtPath(metaPath);
420
+ if (!session)
421
+ return null;
422
+ return operation(session);
423
+ }, { waitMs: 10000 });
424
+ }
425
+ function mutateSessionMeta(sessionId, mutation) {
426
+ return withLockedSession(sessionId, session => {
427
+ mutation(session);
428
+ writeSessionMetaUnlocked(session);
429
+ return session;
430
+ });
431
+ }
432
+ function updateSessionEffort(sessionId, effortPreference) {
433
+ return mutateSessionMeta(sessionId, session => {
434
+ if (effortPreference === undefined || effortPreference === 'auto') {
435
+ delete session.effortPreference;
436
+ }
437
+ else {
438
+ session.effortPreference = effortPreference;
439
+ }
373
440
  });
374
441
  }
375
442
  /**
376
443
  * 加载会话元数据
377
444
  */
378
445
  function loadSessionMeta(sessionId) {
379
- const projectsDir = (0, config_dir_1.getProjectsDir)();
380
- if ((0, fs_1.existsSync)(projectsDir)) {
381
- for (const projectKey of (0, fs_1.readdirSync)(projectsDir)) {
382
- const path = (0, path_1.join)(projectsDir, projectKey, 'sessions', `${sessionId}.json`);
383
- if (!(0, fs_1.existsSync)(path))
384
- continue;
385
- const session = parseSessionMetaFile(path);
386
- if (session) {
387
- return normalizeSessionMeta(session);
388
- }
389
- }
390
- }
391
- return null;
446
+ const path = findSessionMetaPath(sessionId);
447
+ return path ? readSessionMetaAtPath(path) : null;
392
448
  }
393
449
  /**
394
450
  * 更新会话统计
395
451
  */
396
452
  function updateSessionStats(sessionId, tokens, cost) {
397
- const session = loadSessionMeta(sessionId);
398
- if (!session)
399
- return;
400
- session.tokenCount += tokens;
401
- session.cost += cost;
402
- session.updatedAt = Date.now();
403
- session.updatedAtIso = new Date(session.updatedAt).toISOString();
404
- saveSessionMeta(session);
405
- }
406
- function touchSession(sessionId, messageDelta = 0) {
407
- const session = loadSessionMeta(sessionId);
408
- if (!session)
409
- return null;
410
- session.updatedAt = Date.now();
411
- session.updatedAtIso = new Date(session.updatedAt).toISOString();
412
- session.messageCount = (session.messageCount ?? 0) + messageDelta;
413
- saveSessionMeta(session);
414
- return session;
453
+ mutateSessionMeta(sessionId, session => {
454
+ session.tokenCount += tokens;
455
+ session.cost += cost;
456
+ session.updatedAt = Date.now();
457
+ session.updatedAtIso = new Date(session.updatedAt).toISOString();
458
+ });
415
459
  }
416
460
  /**
417
461
  * Mark a saved session as active again and refresh project metadata.
418
462
  */
419
463
  function resumeSession(sessionId) {
420
- const session = loadSessionMeta(sessionId);
421
- if (!session)
422
- return null;
423
- session.endTime = undefined;
424
- session.gitBranch = getGitBranch(session.projectPath);
425
- session.updatedAt = Date.now();
426
- session.updatedAtIso = new Date(session.updatedAt).toISOString();
427
- saveSessionMeta(session);
428
- return session;
464
+ return mutateSessionMeta(sessionId, session => {
465
+ session.endTime = undefined;
466
+ session.gitBranch = getGitBranch(session.projectPath);
467
+ session.updatedAt = Date.now();
468
+ session.updatedAtIso = new Date(session.updatedAt).toISOString();
469
+ });
429
470
  }
430
471
  /** Keep the session metadata's additive Goal binding in sync with its sidecar. */
431
472
  function updateSessionGoalBinding(sessionId, goal) {
432
- const session = loadSessionMeta(sessionId);
433
- if (!session)
434
- return null;
435
- session.activeGoalId = goal?.goalId;
436
- session.activeGoalObjective = goal?.objective;
437
- session.updatedAt = Date.now();
438
- session.updatedAtIso = new Date(session.updatedAt).toISOString();
439
- saveSessionMeta(session);
440
- return session;
473
+ return mutateSessionMeta(sessionId, session => {
474
+ session.activeGoalId = goal?.goalId;
475
+ session.activeGoalObjective = goal?.objective;
476
+ session.updatedAt = Date.now();
477
+ session.updatedAtIso = new Date(session.updatedAt).toISOString();
478
+ });
441
479
  }
442
480
  /**
443
481
  * 更新会话 Harness 状态。
444
482
  */
445
483
  function updateSessionHarnessState(sessionId, harnessState) {
446
- const session = loadSessionMeta(sessionId);
447
- if (!session)
448
- return;
449
- const fullState = (0, harness_1.upgradeHarnessState)(harnessState, { cwd: session.cwd ?? session.projectPath });
450
- const sidecar = {
451
- version: 2,
452
- sessionId,
453
- projectPath: session.projectPath,
454
- state: fullState,
455
- contextCapsule: fullState.capsule,
456
- updatedAt: Date.now(),
457
- diagnostics: fullState.diagnostics,
458
- };
459
- (0, config_dir_1.ensureProjectDir)(session.projectPath);
460
- (0, atomic_write_1.atomicWriteFileSync)((0, config_dir_1.getProjectSessionHarnessPath)(session.projectPath, sessionId), JSON.stringify(sidecar, null, 2), { mode: 0o600 });
461
- session.harnessState = (0, harness_1.summarizeHarnessStateForMeta)(fullState);
462
- session.contextCapsule = fullState.capsule;
463
- session.updatedAt = Date.now();
464
- session.updatedAtIso = new Date(session.updatedAt).toISOString();
465
- saveSessionMeta(session);
484
+ withLockedSession(sessionId, session => {
485
+ const fullState = (0, harness_1.upgradeHarnessState)(harnessState, {
486
+ cwd: session.cwd ?? session.projectPath,
487
+ });
488
+ const sidecar = {
489
+ version: 2,
490
+ sessionId,
491
+ projectPath: session.projectPath,
492
+ state: fullState,
493
+ contextCapsule: fullState.capsule,
494
+ updatedAt: Date.now(),
495
+ diagnostics: fullState.diagnostics,
496
+ };
497
+ (0, config_dir_1.ensureProjectDir)(session.projectPath);
498
+ (0, atomic_write_1.atomicWriteFileSync)((0, config_dir_1.getProjectSessionHarnessPath)(session.projectPath, sessionId), JSON.stringify(sidecar, null, 2), { mode: 0o600 });
499
+ session.harnessState = (0, harness_1.summarizeHarnessStateForMeta)(fullState);
500
+ session.contextCapsule = fullState.capsule;
501
+ session.updatedAt = Date.now();
502
+ session.updatedAtIso = new Date(session.updatedAt).toISOString();
503
+ writeSessionMetaUnlocked(session);
504
+ });
466
505
  }
467
506
  function loadSessionHarnessState(sessionId) {
468
507
  const session = loadSessionMeta(sessionId);
@@ -496,23 +535,18 @@ function loadSessionHarnessState(sessionId) {
496
535
  function updateSessionSkills(sessionId, skills) {
497
536
  if (skills.length === 0)
498
537
  return;
499
- const session = loadSessionMeta(sessionId);
500
- if (!session)
501
- return;
502
- session.skillsUsed = [...new Set([...(session.skillsUsed || []), ...skills])];
503
- session.updatedAt = Date.now();
504
- session.updatedAtIso = new Date(session.updatedAt).toISOString();
505
- saveSessionMeta(session);
538
+ mutateSessionMeta(sessionId, session => {
539
+ session.skillsUsed = [...new Set([...(session.skillsUsed || []), ...skills])];
540
+ session.updatedAt = Date.now();
541
+ session.updatedAtIso = new Date(session.updatedAt).toISOString();
542
+ });
506
543
  }
507
544
  function markSessionTranscriptDisplayStart(sessionId, timestamp = Date.now()) {
508
- const session = loadSessionMeta(sessionId);
509
- if (!session)
510
- return null;
511
- session.transcriptDisplayStartTime = timestamp;
512
- session.updatedAt = timestamp;
513
- session.updatedAtIso = new Date(timestamp).toISOString();
514
- saveSessionMeta(session);
515
- return session;
545
+ return mutateSessionMeta(sessionId, session => {
546
+ session.transcriptDisplayStartTime = timestamp;
547
+ session.updatedAt = timestamp;
548
+ session.updatedAtIso = new Date(timestamp).toISOString();
549
+ });
516
550
  }
517
551
  function persistSessionCompactHistory(sessionId, messages, timestamp = Date.now()) {
518
552
  const session = loadSessionMeta(sessionId);
@@ -544,51 +578,53 @@ function loadSessionCompactCheckpoint(sessionId) {
544
578
  return checkpoint;
545
579
  }
546
580
  function commitSessionCompactCheckpoint(input) {
547
- const session = loadSessionMeta(input.sessionId);
548
- if (!session)
549
- throw new Error(`Session not found: ${input.sessionId}`);
550
- const rawCount = readSessionMessages(input.sessionId).length;
551
- if (input.sourceMessageCount < 0 || input.sourceMessageCount > rawCount) {
552
- throw new Error(`Invalid compact source boundary ${input.sourceMessageCount}; transcript has ${rawCount} messages`);
553
- }
554
- const createdAt = input.createdAt ?? Date.now();
555
- const checkpoint = {
556
- version: 1,
557
- checkpointId: (0, crypto_1.randomUUID)(),
558
- sessionId: input.sessionId,
559
- createdAt,
560
- mode: input.mode,
561
- modelId: input.modelId,
562
- sourceMessageCount: input.sourceMessageCount,
563
- transcriptStartMessageIndex: Math.max(0, Math.min(input.sourceMessageCount, input.transcriptStartMessageIndex)),
564
- modelHistory: input.modelHistory
565
- .filter(message => message.role !== 'system')
566
- .map(message => ({ ...message })),
567
- summary: {
568
- ...input.summary,
581
+ const checkpoint = withLockedSession(input.sessionId, session => {
582
+ const rawCount = readSessionMessagesForSession(session).length;
583
+ if (input.sourceMessageCount < 0 || input.sourceMessageCount > rawCount) {
584
+ throw new Error(`Invalid compact source boundary ${input.sourceMessageCount}; transcript has ${rawCount} messages`);
585
+ }
586
+ const createdAt = input.createdAt ?? Date.now();
587
+ const nextCheckpoint = {
588
+ version: 1,
589
+ checkpointId: (0, crypto_1.randomUUID)(),
590
+ sessionId: input.sessionId,
591
+ createdAt,
592
+ mode: input.mode,
593
+ modelId: input.modelId,
569
594
  sourceMessageCount: input.sourceMessageCount,
570
- },
571
- beforeUsage: { ...input.beforeUsage },
572
- afterUsage: { ...input.afterUsage },
573
- };
574
- const previousId = session.activeCompactCheckpointId;
575
- const previousTime = session.lastCompactAt;
576
- session.activeCompactCheckpointId = checkpoint.checkpointId;
577
- session.lastCompactAt = createdAt;
578
- session.updatedAt = createdAt;
579
- session.updatedAtIso = new Date(createdAt).toISOString();
580
- // Commit the pointer before replacing the atomic sidecar. If the process
581
- // crashes between writes, the loader safely uses the last valid sidecar.
582
- saveSessionMeta(session);
583
- try {
584
- (0, atomic_write_1.atomicWriteFileSync)((0, config_dir_1.getProjectSessionCompactPath)(session.projectPath, input.sessionId), JSON.stringify(checkpoint, null, 2), { mode: 0o600 });
585
- }
586
- catch (error) {
587
- session.activeCompactCheckpointId = previousId;
588
- session.lastCompactAt = previousTime;
589
- saveSessionMeta(session);
590
- throw error;
591
- }
595
+ transcriptStartMessageIndex: Math.max(0, Math.min(input.sourceMessageCount, input.transcriptStartMessageIndex)),
596
+ modelHistory: input.modelHistory
597
+ .filter(message => message.role !== 'system')
598
+ .map(message => ({ ...message })),
599
+ summary: {
600
+ ...input.summary,
601
+ sourceMessageCount: input.sourceMessageCount,
602
+ },
603
+ beforeUsage: { ...input.beforeUsage },
604
+ afterUsage: { ...input.afterUsage },
605
+ };
606
+ const previousId = session.activeCompactCheckpointId;
607
+ const previousTime = session.lastCompactAt;
608
+ session.activeCompactCheckpointId = nextCheckpoint.checkpointId;
609
+ session.lastCompactAt = createdAt;
610
+ session.updatedAt = createdAt;
611
+ session.updatedAtIso = new Date(createdAt).toISOString();
612
+ // Commit the pointer before replacing the atomic sidecar. If the process
613
+ // crashes between writes, the loader safely uses the last valid sidecar.
614
+ writeSessionMetaUnlocked(session);
615
+ try {
616
+ (0, atomic_write_1.atomicWriteFileSync)((0, config_dir_1.getProjectSessionCompactPath)(session.projectPath, input.sessionId), JSON.stringify(nextCheckpoint, null, 2), { mode: 0o600 });
617
+ }
618
+ catch (error) {
619
+ session.activeCompactCheckpointId = previousId;
620
+ session.lastCompactAt = previousTime;
621
+ writeSessionMetaUnlocked(session);
622
+ throw error;
623
+ }
624
+ return nextCheckpoint;
625
+ });
626
+ if (!checkpoint)
627
+ throw new Error(`Session not found: ${input.sessionId}`);
592
628
  return checkpoint;
593
629
  }
594
630
  function loadSessionTranscriptMessages(sessionId) {
@@ -612,22 +648,17 @@ function hasPersistedCompactContext(messages) {
612
648
  * 结束会话
613
649
  */
614
650
  function endSession(sessionId) {
615
- const session = loadSessionMeta(sessionId);
616
- if (!session)
617
- return;
618
- session.endTime = Date.now();
619
- session.updatedAt = session.endTime;
620
- session.updatedAtIso = new Date(session.updatedAt).toISOString();
621
- saveSessionMeta(session);
651
+ mutateSessionMeta(sessionId, session => {
652
+ session.endTime = Date.now();
653
+ session.updatedAt = session.endTime;
654
+ session.updatedAtIso = new Date(session.updatedAt).toISOString();
655
+ });
622
656
  }
623
657
  /**
624
658
  * 更新会话任务摘要
625
659
  * 从会话消息中提取关键信息并更新元数据
626
660
  */
627
661
  function updateSessionSummary(sessionId, messages) {
628
- const session = loadSessionMeta(sessionId);
629
- if (!session)
630
- return;
631
662
  // 提取工具使用列表
632
663
  const toolsUsed = [];
633
664
  const filesModified = [];
@@ -655,14 +686,15 @@ function updateSessionSummary(sessionId, messages) {
655
686
  // 提取任务摘要(从第一个用户消息)
656
687
  const firstUserMsg = messages.find(m => m.role === 'user' && m.content);
657
688
  const taskSummary = (0, redaction_1.redactTraceText)(firstUserMsg?.content ?? '').slice(0, 100);
658
- // 更新 session
659
- session.toolsUsed = [...new Set(toolsUsed)]; // unique
660
- session.filesModified = [...new Set(filesModified)]; // unique
661
- session.taskSummary = taskSummary.length > 100 ? taskSummary.slice(0, 100) + '...' : taskSummary;
662
- session.messageCount = messages.length;
663
- session.updatedAt = Date.now();
664
- session.updatedAtIso = new Date(session.updatedAt).toISOString();
665
- saveSessionMeta(session);
689
+ mutateSessionMeta(sessionId, session => {
690
+ session.toolsUsed = [...new Set(toolsUsed)]; // unique
691
+ session.filesModified = [...new Set(filesModified)]; // unique
692
+ session.taskSummary =
693
+ taskSummary.length > 100 ? taskSummary.slice(0, 100) + '...' : taskSummary;
694
+ session.messageCount = messages.length;
695
+ session.updatedAt = Date.now();
696
+ session.updatedAtIso = new Date(session.updatedAt).toISOString();
697
+ });
666
698
  }
667
699
  /**
668
700
  * 获取项目最近的会话
@@ -734,15 +766,19 @@ function readProjectHistory(projectPath, limit) {
734
766
  function appendSessionMessage(sessionId, message) {
735
767
  (0, config_dir_1.ensureConfigDir)();
736
768
  const line = JSON.stringify(message) + '\n';
737
- const session = touchSession(sessionId, 1);
738
- if (!session)
739
- return;
740
- (0, config_dir_1.ensureProjectDir)(session.projectPath);
741
- (0, fs_1.appendFileSync)((0, config_dir_1.getProjectSessionMessagesPath)(session.projectPath, sessionId), line, {
742
- mode: 0o600,
769
+ withLockedSession(sessionId, session => {
770
+ (0, config_dir_1.ensureProjectDir)(session.projectPath);
771
+ (0, fs_1.appendFileSync)((0, config_dir_1.getProjectSessionMessagesPath)(session.projectPath, sessionId), line, {
772
+ mode: 0o600,
773
+ });
774
+ // Keep transcript, metadata, and search index inside the same session
775
+ // critical section so concurrent processes cannot lose counters.
776
+ (0, session_index_1.updateSessionIndex)(sessionId, session.projectPath, message);
777
+ session.updatedAt = Date.now();
778
+ session.updatedAtIso = new Date(session.updatedAt).toISOString();
779
+ session.messageCount = (session.messageCount ?? 0) + 1;
780
+ writeSessionMetaUnlocked(session);
743
781
  });
744
- // Update session index for fast search
745
- (0, session_index_1.updateSessionIndex)(sessionId, session.projectPath, message);
746
782
  }
747
783
  /**
748
784
  * 追加多条会话消息
@@ -752,16 +788,19 @@ function appendSessionMessages(sessionId, messages) {
752
788
  return;
753
789
  (0, config_dir_1.ensureConfigDir)();
754
790
  const lines = messages.map(m => JSON.stringify(m)).join('\n') + '\n';
755
- const session = touchSession(sessionId, messages.length);
756
- if (!session)
757
- return;
758
- (0, config_dir_1.ensureProjectDir)(session.projectPath);
759
- (0, fs_1.appendFileSync)((0, config_dir_1.getProjectSessionMessagesPath)(session.projectPath, sessionId), lines, {
760
- mode: 0o600,
791
+ withLockedSession(sessionId, session => {
792
+ (0, config_dir_1.ensureProjectDir)(session.projectPath);
793
+ (0, fs_1.appendFileSync)((0, config_dir_1.getProjectSessionMessagesPath)(session.projectPath, sessionId), lines, {
794
+ mode: 0o600,
795
+ });
796
+ for (const message of messages) {
797
+ (0, session_index_1.updateSessionIndex)(sessionId, session.projectPath, message);
798
+ }
799
+ session.updatedAt = Date.now();
800
+ session.updatedAtIso = new Date(session.updatedAt).toISOString();
801
+ session.messageCount = (session.messageCount ?? 0) + messages.length;
802
+ writeSessionMetaUnlocked(session);
761
803
  });
762
- for (const message of messages) {
763
- (0, session_index_1.updateSessionIndex)(sessionId, session.projectPath, message);
764
- }
765
804
  }
766
805
  function isFinalAssistantMessage(message) {
767
806
  return message.role === 'assistant' && (!message.tool_calls || message.tool_calls.length === 0);
@@ -772,26 +811,30 @@ function findLastCompleteBoundary(messages) {
772
811
  return messages.length;
773
812
  }
774
813
  const tail = messages.slice(lastUserIndex + 1);
775
- return tail.some(isFinalAssistantMessage) ? messages.length : lastUserIndex;
814
+ if (tail.some(isFinalAssistantMessage)) {
815
+ return messages.length;
816
+ }
817
+ // No final assistant answer follows the last user prompt: the turn is
818
+ // incomplete. Keep the user prompt itself (lastUserIndex + 1) and only drop
819
+ // the partial assistant/tool tail — an abort must not delete what the user
820
+ // actually typed (Issue #49: off-by-one previously returned lastUserIndex and
821
+ // sliced the prompt away).
822
+ return lastUserIndex + 1;
776
823
  }
777
- function overwriteSessionMessages(sessionId, messages) {
778
- (0, config_dir_1.ensureConfigDir)();
779
- const session = loadSessionMeta(sessionId);
780
- if (!session)
781
- return;
824
+ function overwriteSessionMessagesUnlocked(session, messages) {
782
825
  const content = messages.length > 0 ? messages.map(message => JSON.stringify(message)).join('\n') + '\n' : '';
783
826
  (0, config_dir_1.ensureProjectDir)(session.projectPath);
784
- (0, atomic_write_1.atomicWriteFileSync)((0, config_dir_1.getProjectSessionMessagesPath)(session.projectPath, sessionId), content, {
827
+ (0, atomic_write_1.atomicWriteFileSync)((0, config_dir_1.getProjectSessionMessagesPath)(session.projectPath, session.id), content, {
785
828
  mode: 0o600,
786
829
  });
787
- (0, session_index_1.deleteSessionIndex)(sessionId, session.projectPath);
830
+ (0, session_index_1.deleteSessionIndex)(session.id, session.projectPath);
788
831
  for (const message of messages) {
789
- (0, session_index_1.updateSessionIndex)(sessionId, session.projectPath, message);
832
+ (0, session_index_1.updateSessionIndex)(session.id, session.projectPath, message);
790
833
  }
791
834
  session.messageCount = messages.length;
792
835
  session.updatedAt = Date.now();
793
836
  session.updatedAtIso = new Date(session.updatedAt).toISOString();
794
- saveSessionMeta(session);
837
+ writeSessionMetaUnlocked(session);
795
838
  }
796
839
  /**
797
840
  * Remove a trailing incomplete turn from the persisted session transcript.
@@ -802,18 +845,38 @@ function overwriteSessionMessages(sessionId, messages) {
802
845
  * resurrect partial state.
803
846
  */
804
847
  function truncateSessionToLastComplete(sessionId) {
805
- const messages = readSessionMessages(sessionId);
806
- const boundary = findLastCompleteBoundary(messages);
807
- if (boundary === messages.length) {
808
- return messages;
809
- }
810
- const truncated = messages.slice(0, boundary);
811
- overwriteSessionMessages(sessionId, truncated);
812
- return truncated;
848
+ return (withLockedSession(sessionId, session => {
849
+ const messages = readSessionMessagesForSession(session);
850
+ const boundary = findLastCompleteBoundary(messages);
851
+ if (boundary === messages.length)
852
+ return messages;
853
+ const truncated = messages.slice(0, boundary);
854
+ overwriteSessionMessagesUnlocked(session, truncated);
855
+ return truncated;
856
+ }) ?? []);
813
857
  }
814
858
  function removeLastIncompleteAssistantMessage(sessionId) {
815
859
  return truncateSessionToLastComplete(sessionId);
816
860
  }
861
+ /**
862
+ * Remove the trailing user message from a failed turn so a provider/tool
863
+ * failure does not leave a dangling prompt in the persisted session that would
864
+ * be replayed on resume. The caller must guarantee the trailing message was
865
+ * appended by the turn that just failed (i.e. `persistAsUserMessage !== false`);
866
+ * this is a no-op when the last message is not a user message.
867
+ */
868
+ function removeTrailingSessionUserMessage(sessionId) {
869
+ return (withLockedSession(sessionId, session => {
870
+ const messages = readSessionMessagesForSession(session);
871
+ if (messages.length === 0)
872
+ return messages;
873
+ if (messages[messages.length - 1].role !== 'user')
874
+ return messages;
875
+ const truncated = messages.slice(0, -1);
876
+ overwriteSessionMessagesUnlocked(session, truncated);
877
+ return truncated;
878
+ }) ?? []);
879
+ }
817
880
  /**
818
881
  * 读取会话消息
819
882
  */
@@ -821,6 +884,10 @@ function readSessionMessages(sessionId) {
821
884
  const session = loadSessionMeta(sessionId);
822
885
  if (!session)
823
886
  return [];
887
+ return readSessionMessagesForSession(session);
888
+ }
889
+ function readSessionMessagesForSession(session) {
890
+ const sessionId = session.id;
824
891
  const path = (0, config_dir_1.getProjectSessionMessagesPath)(session.projectPath, sessionId);
825
892
  if (!(0, fs_1.existsSync)(path))
826
893
  return [];
@@ -833,9 +900,12 @@ function readSessionMessages(sessionId) {
833
900
  messages.push(JSON.parse(lines[i]));
834
901
  }
835
902
  catch (error) {
836
- // A missing turn can orphan later tool results, so only restore the valid prefix.
903
+ // A single corrupted line must not silently truncate the whole session
904
+ // (which would drop every later turn on resume). Skip only the bad line
905
+ // and keep the rest, mirroring readHistory's behaviour. The corruption
906
+ // is still recorded for observability (#68).
837
907
  (0, debug_log_1.debugError)('session-storage.parseMessageLine', error, `${path}:${i + 1}`);
838
- break;
908
+ continue;
839
909
  }
840
910
  }
841
911
  return messages;
@@ -914,10 +984,10 @@ function loadSessionHistory(sessionId) {
914
984
  const messages = readSessionMessages(sessionId);
915
985
  const checkpoint = loadSessionCompactCheckpoint(sessionId);
916
986
  if (checkpoint) {
917
- return [
987
+ return (0, tool_call_groups_1.sealToolCallGroups)([
918
988
  ...checkpoint.modelHistory.map(message => ({ ...message })),
919
989
  ...messages.slice(checkpoint.sourceMessageCount).map(sessionMessageToModelMessage),
920
- ];
990
+ ]);
921
991
  }
922
992
  const session = loadSessionMeta(sessionId);
923
993
  const displayStartTime = session?.transcriptDisplayStartTime;
@@ -928,7 +998,7 @@ function loadSessionHistory(sessionId) {
928
998
  ? afterDisplayStart
929
999
  : messages;
930
1000
  }
931
- return modelVisibleMessages.map(sessionMessageToModelMessage);
1001
+ return (0, tool_call_groups_1.sealToolCallGroups)(modelVisibleMessages.map(sessionMessageToModelMessage));
932
1002
  }
933
1003
  function sessionMessageToModelMessage(message) {
934
1004
  const result = {
@@ -958,9 +1028,12 @@ function listSessions(limit) {
958
1028
  const files = (0, fs_1.readdirSync)(projectSessionsDir).filter(isSessionMetaFile);
959
1029
  for (const file of files) {
960
1030
  const rawSession = parseSessionMetaFile((0, path_1.join)(projectSessionsDir, file));
961
- if (rawSession) {
962
- upsertNewestSession(sessionsById, normalizeSessionMeta(rawSession));
963
- }
1031
+ if (!rawSession)
1032
+ continue;
1033
+ const sourcePath = (0, path_1.join)(projectSessionsDir, file);
1034
+ const normalized = tryNormalizeSessionMeta(rawSession, sourcePath);
1035
+ if (normalized)
1036
+ upsertNewestSession(sessionsById, normalized);
964
1037
  }
965
1038
  }
966
1039
  }
@@ -978,9 +1051,12 @@ function listProjectSessions(projectPath, limit) {
978
1051
  const files = (0, fs_1.readdirSync)(projectSessionsDir).filter(isSessionMetaFile);
979
1052
  for (const file of files) {
980
1053
  const rawSession = parseSessionMetaFile((0, path_1.join)(projectSessionsDir, file));
981
- if (rawSession) {
982
- upsertNewestSession(sessionsById, normalizeSessionMeta(rawSession));
983
- }
1054
+ if (!rawSession)
1055
+ continue;
1056
+ const sourcePath = (0, path_1.join)(projectSessionsDir, file);
1057
+ const normalized = tryNormalizeSessionMeta(rawSession, sourcePath);
1058
+ if (normalized)
1059
+ upsertNewestSession(sessionsById, normalized);
984
1060
  }
985
1061
  }
986
1062
  const sessions = sortSessionsNewestFirst(Array.from(sessionsById.values()));
@@ -1026,48 +1102,43 @@ function lookupSessionRef(ref, projectPath, options = {}) {
1026
1102
  * Rename a session for easier picker/resume targeting.
1027
1103
  */
1028
1104
  function renameSession(sessionId, name) {
1029
- const session = loadSessionMeta(sessionId);
1030
- if (!session)
1031
- return null;
1032
1105
  const trimmed = name.trim();
1033
- session.name = trimmed || undefined;
1034
- session.updatedAt = Date.now();
1035
- session.updatedAtIso = new Date(session.updatedAt).toISOString();
1036
- saveSessionMeta(session);
1037
- return session;
1106
+ return mutateSessionMeta(sessionId, session => {
1107
+ session.name = trimmed || undefined;
1108
+ session.updatedAt = Date.now();
1109
+ session.updatedAtIso = new Date(session.updatedAt).toISOString();
1110
+ });
1038
1111
  }
1039
1112
  /**
1040
1113
  * 删除会话
1041
1114
  */
1042
1115
  function deleteSession(sessionId) {
1043
- const session = loadSessionMeta(sessionId);
1044
- if (!session)
1045
- return false;
1046
- let deleted = false;
1047
- const paths = [
1048
- (0, config_dir_1.getProjectSessionMetaPath)(session.projectPath, sessionId),
1049
- (0, config_dir_1.getProjectSessionMessagesPath)(session.projectPath, sessionId),
1050
- (0, config_dir_1.getProjectSessionHarnessPath)(session.projectPath, sessionId),
1051
- (0, config_dir_1.getProjectSessionCompactPath)(session.projectPath, sessionId),
1052
- (0, config_dir_1.getProjectSessionTracePath)(session.projectPath, sessionId),
1053
- ];
1054
- // Preserve a durable deletion fence so a stale writer in another process
1055
- // cannot recreate the Goal after the rest of the session is removed.
1056
- const goalPath = (0, path_1.join)((0, config_dir_1.getProjectSessionsDir)(session.projectPath), `${sessionId}.goal.json`);
1057
- const hadGoal = (0, fs_1.existsSync)(goalPath);
1058
- const goalDeletion = (0, goal_storage_1.deleteGoal)(session.projectPath, sessionId);
1059
- if (!goalDeletion.ok) {
1060
- return false;
1061
- }
1062
- if (hadGoal)
1063
- deleted = true;
1064
- (0, session_index_1.deleteSessionIndex)(sessionId, session.projectPath);
1065
- for (const path of uniquePaths(paths)) {
1066
- if ((0, fs_1.existsSync)(path)) {
1067
- (0, fs_1.unlinkSync)(path);
1116
+ return (withLockedSession(sessionId, session => {
1117
+ let deleted = false;
1118
+ const paths = [
1119
+ (0, config_dir_1.getProjectSessionMetaPath)(session.projectPath, sessionId),
1120
+ (0, config_dir_1.getProjectSessionMessagesPath)(session.projectPath, sessionId),
1121
+ (0, config_dir_1.getProjectSessionHarnessPath)(session.projectPath, sessionId),
1122
+ (0, config_dir_1.getProjectSessionCompactPath)(session.projectPath, sessionId),
1123
+ (0, config_dir_1.getProjectSessionTracePath)(session.projectPath, sessionId),
1124
+ ];
1125
+ // Preserve a durable deletion fence so a stale writer in another process
1126
+ // cannot recreate the Goal after the rest of the session is removed.
1127
+ const goalPath = (0, path_1.join)((0, config_dir_1.getProjectSessionsDir)(session.projectPath), `${sessionId}.goal.json`);
1128
+ const hadGoal = (0, fs_1.existsSync)(goalPath);
1129
+ const goalDeletion = (0, goal_storage_1.deleteGoal)(session.projectPath, sessionId);
1130
+ if (!goalDeletion.ok)
1131
+ return false;
1132
+ if (hadGoal)
1068
1133
  deleted = true;
1134
+ (0, session_index_1.deleteSessionIndex)(sessionId, session.projectPath);
1135
+ for (const path of uniquePaths(paths)) {
1136
+ if ((0, fs_1.existsSync)(path)) {
1137
+ (0, fs_1.unlinkSync)(path);
1138
+ deleted = true;
1139
+ }
1069
1140
  }
1070
- }
1071
- return deleted;
1141
+ return deleted;
1142
+ }) ?? false);
1072
1143
  }
1073
1144
  //# sourceMappingURL=session-storage.js.map