byterover-cli 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (490) hide show
  1. package/README.md +56 -56
  2. package/bin/dev.js +1 -1
  3. package/dist/commands/cipher-agent/run.d.ts +111 -0
  4. package/dist/commands/cipher-agent/run.js +493 -0
  5. package/dist/commands/cipher-agent/set-prompt.d.ts +14 -0
  6. package/dist/commands/cipher-agent/set-prompt.js +53 -0
  7. package/dist/commands/cipher-agent/show-prompt.d.ts +11 -0
  8. package/dist/commands/cipher-agent/show-prompt.js +48 -0
  9. package/dist/commands/clear.d.ts +6 -0
  10. package/dist/commands/clear.js +36 -15
  11. package/dist/commands/curate.d.ts +74 -0
  12. package/dist/commands/curate.js +396 -0
  13. package/dist/commands/foo.d.ts +12 -0
  14. package/dist/commands/foo.js +61 -0
  15. package/dist/commands/gen-rules.d.ts +3 -0
  16. package/dist/commands/gen-rules.js +39 -20
  17. package/dist/commands/init.d.ts +48 -3
  18. package/dist/commands/init.js +242 -70
  19. package/dist/commands/login.js +9 -4
  20. package/dist/commands/pull.d.ts +33 -0
  21. package/dist/commands/pull.js +115 -0
  22. package/dist/commands/push.d.ts +13 -13
  23. package/dist/commands/push.js +81 -101
  24. package/dist/commands/query.d.ts +63 -0
  25. package/dist/commands/query.js +349 -0
  26. package/dist/commands/space/list.d.ts +5 -2
  27. package/dist/commands/space/list.js +60 -56
  28. package/dist/commands/space/switch.d.ts +16 -0
  29. package/dist/commands/space/switch.js +102 -53
  30. package/dist/commands/status.d.ts +5 -2
  31. package/dist/commands/status.js +43 -33
  32. package/dist/commands/watch.d.ts +23 -0
  33. package/dist/commands/watch.js +171 -0
  34. package/dist/config/auth.config.js +14 -2
  35. package/dist/config/context-tree-domains.d.ts +12 -0
  36. package/dist/config/context-tree-domains.js +29 -0
  37. package/dist/config/environment.d.ts +6 -0
  38. package/dist/config/environment.js +9 -2
  39. package/dist/constants.d.ts +5 -0
  40. package/dist/constants.js +6 -0
  41. package/dist/core/domain/cipher/agent/agent-state-machine.d.ts +128 -0
  42. package/dist/core/domain/cipher/agent/agent-state-machine.js +183 -0
  43. package/dist/core/domain/cipher/agent/agent-state.d.ts +77 -0
  44. package/dist/core/domain/cipher/agent/agent-state.js +59 -0
  45. package/dist/core/domain/cipher/agent/index.d.ts +7 -0
  46. package/dist/core/domain/cipher/agent/index.js +7 -0
  47. package/dist/core/domain/cipher/agent-events/index.d.ts +8 -0
  48. package/dist/core/domain/cipher/agent-events/index.js +7 -0
  49. package/dist/core/domain/cipher/agent-events/types.d.ts +419 -0
  50. package/dist/core/domain/cipher/agent-events/types.js +42 -0
  51. package/dist/core/domain/cipher/blob/types.d.ts +108 -0
  52. package/dist/core/domain/cipher/errors/blob-error.d.ts +36 -0
  53. package/dist/core/domain/cipher/errors/blob-error.js +68 -0
  54. package/dist/core/domain/cipher/errors/file-system-error.d.ts +211 -0
  55. package/dist/core/domain/cipher/errors/file-system-error.js +291 -0
  56. package/dist/core/domain/cipher/errors/llm-error.d.ts +120 -0
  57. package/dist/core/domain/cipher/errors/llm-error.js +161 -0
  58. package/dist/core/domain/cipher/errors/memory-error.d.ts +35 -0
  59. package/dist/core/domain/cipher/errors/memory-error.js +62 -0
  60. package/dist/core/domain/cipher/errors/process-error-code.d.ts +97 -0
  61. package/dist/core/domain/cipher/errors/process-error-code.js +98 -0
  62. package/dist/core/domain/cipher/errors/process-error.d.ts +135 -0
  63. package/dist/core/domain/cipher/errors/process-error.js +173 -0
  64. package/dist/core/domain/cipher/errors/session-error.d.ts +56 -0
  65. package/dist/core/domain/cipher/errors/session-error.js +74 -0
  66. package/dist/core/domain/cipher/errors/tool-error.d.ts +57 -0
  67. package/dist/core/domain/cipher/errors/tool-error.js +81 -0
  68. package/dist/core/domain/cipher/file-system/types.d.ts +203 -0
  69. package/dist/core/domain/cipher/memory/types.d.ts +102 -0
  70. package/dist/core/domain/cipher/memory/types.js +4 -0
  71. package/dist/core/domain/cipher/parsed-interaction.d.ts +47 -0
  72. package/dist/core/domain/cipher/parsed-interaction.js +25 -0
  73. package/dist/core/domain/cipher/process/types.d.ts +286 -0
  74. package/dist/core/domain/cipher/session/types.d.ts +54 -0
  75. package/dist/core/domain/cipher/storage/history-types.d.ts +38 -0
  76. package/dist/core/domain/cipher/system-prompt/types.d.ts +131 -0
  77. package/dist/core/domain/cipher/todos/index.d.ts +4 -0
  78. package/dist/core/domain/cipher/todos/index.js +4 -0
  79. package/dist/core/domain/cipher/todos/types.d.ts +57 -0
  80. package/dist/core/domain/cipher/todos/types.js +5 -0
  81. package/dist/core/domain/cipher/tools/constants.d.ts +28 -0
  82. package/dist/core/domain/cipher/tools/constants.js +24 -0
  83. package/dist/core/domain/cipher/tools/tool-error.d.ts +183 -0
  84. package/dist/core/domain/cipher/tools/tool-error.js +246 -0
  85. package/dist/core/domain/cipher/tools/types.d.ts +145 -0
  86. package/dist/core/domain/entities/brv-config.d.ts +42 -6
  87. package/dist/core/domain/entities/brv-config.js +115 -17
  88. package/dist/core/domain/entities/cogit-push-context.d.ts +38 -0
  89. package/dist/core/domain/entities/cogit-push-context.js +91 -0
  90. package/dist/core/domain/entities/cogit-push-response.d.ts +20 -0
  91. package/dist/core/domain/entities/cogit-push-response.js +31 -0
  92. package/dist/core/domain/entities/cogit-snapshot-author.d.ts +24 -0
  93. package/dist/core/domain/entities/cogit-snapshot-author.js +39 -0
  94. package/dist/core/domain/entities/cogit-snapshot-file.d.ts +34 -0
  95. package/dist/core/domain/entities/cogit-snapshot-file.js +59 -0
  96. package/dist/core/domain/entities/cogit-snapshot.d.ts +31 -0
  97. package/dist/core/domain/entities/cogit-snapshot.js +58 -0
  98. package/dist/core/domain/entities/context-tree-index.d.ts +26 -0
  99. package/dist/core/domain/entities/context-tree-index.js +27 -0
  100. package/dist/core/domain/entities/context-tree-snapshot.d.ts +56 -0
  101. package/dist/core/domain/entities/context-tree-snapshot.js +83 -0
  102. package/dist/core/domain/entities/event.d.ts +1 -1
  103. package/dist/core/domain/entities/event.js +3 -1
  104. package/dist/core/domain/entities/parser.d.ts +567 -0
  105. package/dist/core/domain/entities/parser.js +10 -0
  106. package/dist/core/domain/entities/playbook.d.ts +2 -23
  107. package/dist/core/domain/entities/playbook.js +2 -70
  108. package/dist/core/domain/errors/brv-config-version-error.d.ts +16 -0
  109. package/dist/core/domain/errors/brv-config-version-error.js +21 -0
  110. package/dist/core/domain/knowledge/directory-manager.d.ts +80 -0
  111. package/dist/core/domain/knowledge/directory-manager.js +145 -0
  112. package/dist/core/domain/knowledge/markdown-writer.d.ts +18 -0
  113. package/dist/core/domain/knowledge/markdown-writer.js +18 -0
  114. package/dist/core/domain/knowledge/relation-parser.d.ts +90 -0
  115. package/dist/core/domain/knowledge/relation-parser.js +131 -0
  116. package/dist/core/interfaces/cipher/cipher-services.d.ts +71 -0
  117. package/dist/core/interfaces/cipher/cipher-services.js +1 -0
  118. package/dist/core/interfaces/cipher/i-blob-storage.d.ts +78 -0
  119. package/dist/core/interfaces/cipher/i-blob-storage.js +1 -0
  120. package/dist/core/interfaces/cipher/i-chat-session.d.ts +62 -0
  121. package/dist/core/interfaces/cipher/i-chat-session.js +1 -0
  122. package/dist/core/interfaces/cipher/i-cipher-agent.d.ts +88 -0
  123. package/dist/core/interfaces/cipher/i-cipher-agent.js +1 -0
  124. package/dist/core/interfaces/cipher/i-coding-agent-log-parser.d.ts +20 -0
  125. package/dist/core/interfaces/cipher/i-coding-agent-log-parser.js +1 -0
  126. package/dist/core/interfaces/cipher/i-coding-agent-log-watcher.d.ts +31 -0
  127. package/dist/core/interfaces/cipher/i-coding-agent-log-watcher.js +1 -0
  128. package/dist/core/interfaces/cipher/i-content-generator.d.ts +120 -0
  129. package/dist/core/interfaces/cipher/i-content-generator.js +12 -0
  130. package/dist/core/interfaces/cipher/i-event-emitter.d.ts +76 -0
  131. package/dist/core/interfaces/cipher/i-event-emitter.js +1 -0
  132. package/dist/core/interfaces/cipher/i-file-system.d.ts +68 -0
  133. package/dist/core/interfaces/cipher/i-file-system.js +1 -0
  134. package/dist/core/interfaces/cipher/i-history-storage.d.ts +53 -0
  135. package/dist/core/interfaces/cipher/i-history-storage.js +1 -0
  136. package/dist/core/interfaces/cipher/i-llm-provider.d.ts +14 -0
  137. package/dist/core/interfaces/cipher/i-llm-provider.js +1 -0
  138. package/dist/core/interfaces/cipher/i-llm-service.d.ts +62 -0
  139. package/dist/core/interfaces/cipher/i-llm-service.js +1 -0
  140. package/dist/core/interfaces/cipher/i-logger.d.ts +78 -0
  141. package/dist/core/interfaces/cipher/i-logger.js +28 -0
  142. package/dist/core/interfaces/cipher/i-message-formatter.d.ts +44 -0
  143. package/dist/core/interfaces/cipher/i-message-formatter.js +1 -0
  144. package/dist/core/interfaces/cipher/i-policy-engine.d.ts +102 -0
  145. package/dist/core/interfaces/cipher/i-policy-engine.js +9 -0
  146. package/dist/core/interfaces/cipher/i-process-service.d.ts +65 -0
  147. package/dist/core/interfaces/cipher/i-process-service.js +1 -0
  148. package/dist/core/interfaces/cipher/i-system-prompt-contributor.d.ts +25 -0
  149. package/dist/core/interfaces/cipher/i-system-prompt-contributor.js +1 -0
  150. package/dist/core/interfaces/cipher/i-tokenizer.d.ts +15 -0
  151. package/dist/core/interfaces/cipher/i-tokenizer.js +1 -0
  152. package/dist/core/interfaces/cipher/i-tool-provider.d.ts +64 -0
  153. package/dist/core/interfaces/cipher/i-tool-provider.js +1 -0
  154. package/dist/core/interfaces/cipher/i-tool-scheduler.d.ts +103 -0
  155. package/dist/core/interfaces/cipher/i-tool-scheduler.js +11 -0
  156. package/dist/core/interfaces/cipher/llm-types.d.ts +46 -0
  157. package/dist/core/interfaces/cipher/llm-types.js +5 -0
  158. package/dist/core/interfaces/cipher/message-types.d.ts +118 -0
  159. package/dist/core/interfaces/cipher/message-types.js +5 -0
  160. package/dist/core/interfaces/cipher/tokenizer-types.d.ts +11 -0
  161. package/dist/core/interfaces/cipher/tokenizer-types.js +14 -0
  162. package/dist/core/interfaces/i-cogit-pull-service.d.ts +24 -0
  163. package/dist/core/interfaces/i-cogit-pull-service.js +1 -0
  164. package/dist/core/interfaces/i-cogit-push-service.d.ts +27 -0
  165. package/dist/core/interfaces/i-cogit-push-service.js +1 -0
  166. package/dist/core/interfaces/i-context-file-reader.d.ts +32 -0
  167. package/dist/core/interfaces/i-context-file-reader.js +1 -0
  168. package/dist/core/interfaces/i-context-tree-service.d.ts +21 -0
  169. package/dist/core/interfaces/i-context-tree-service.js +1 -0
  170. package/dist/core/interfaces/i-context-tree-snapshot-service.d.ts +36 -0
  171. package/dist/core/interfaces/i-context-tree-snapshot-service.js +1 -0
  172. package/dist/core/interfaces/i-context-tree-writer-service.d.ts +32 -0
  173. package/dist/core/interfaces/i-context-tree-writer-service.js +1 -0
  174. package/dist/core/interfaces/i-file-watcher-service.d.ts +41 -0
  175. package/dist/core/interfaces/i-file-watcher-service.js +1 -0
  176. package/dist/core/interfaces/parser/i-clean-parser-service.d.ts +18 -0
  177. package/dist/core/interfaces/parser/i-clean-parser-service.js +1 -0
  178. package/dist/core/interfaces/parser/i-raw-parser-service.d.ts +17 -0
  179. package/dist/core/interfaces/parser/i-raw-parser-service.js +1 -0
  180. package/dist/core/interfaces/parser/i-session-normalizer.d.ts +56 -0
  181. package/dist/core/interfaces/parser/i-session-normalizer.js +1 -0
  182. package/dist/hooks/command_not_found/handle-invalid-commands.d.ts +7 -0
  183. package/dist/hooks/command_not_found/handle-invalid-commands.js +32 -0
  184. package/dist/hooks/error/clean-errors.d.ts +7 -0
  185. package/dist/hooks/error/clean-errors.js +50 -0
  186. package/dist/hooks/init/welcome.js +72 -1
  187. package/dist/hooks/prerun/validate-brv-config-version.d.ts +28 -0
  188. package/dist/hooks/prerun/validate-brv-config-version.js +43 -0
  189. package/dist/infra/cipher/agent-service-factory.d.ts +86 -0
  190. package/dist/infra/cipher/agent-service-factory.js +212 -0
  191. package/dist/infra/cipher/blob/blob-storage-factory.d.ts +13 -0
  192. package/dist/infra/cipher/blob/blob-storage-factory.js +14 -0
  193. package/dist/infra/cipher/blob/index.d.ts +10 -0
  194. package/dist/infra/cipher/blob/index.js +12 -0
  195. package/dist/infra/cipher/blob/migrations.d.ts +63 -0
  196. package/dist/infra/cipher/blob/migrations.js +148 -0
  197. package/dist/infra/cipher/blob/sqlite-blob-storage.d.ts +82 -0
  198. package/dist/infra/cipher/blob/sqlite-blob-storage.js +307 -0
  199. package/dist/infra/cipher/cipher-agent-state-manager.d.ts +63 -0
  200. package/dist/infra/cipher/cipher-agent-state-manager.js +108 -0
  201. package/dist/infra/cipher/cipher-agent.d.ts +182 -0
  202. package/dist/infra/cipher/cipher-agent.js +317 -0
  203. package/dist/infra/cipher/command-parser.d.ts +23 -0
  204. package/dist/infra/cipher/command-parser.js +85 -0
  205. package/dist/infra/cipher/display/todo-display.d.ts +23 -0
  206. package/dist/infra/cipher/display/todo-display.js +129 -0
  207. package/dist/infra/cipher/events/event-emitter.d.ts +137 -0
  208. package/dist/infra/cipher/events/event-emitter.js +158 -0
  209. package/dist/infra/cipher/exit-codes.d.ts +44 -0
  210. package/dist/infra/cipher/exit-codes.js +58 -0
  211. package/dist/infra/cipher/file-system/file-system-service.d.ts +105 -0
  212. package/dist/infra/cipher/file-system/file-system-service.js +641 -0
  213. package/dist/infra/cipher/file-system/gitignore-filter.d.ts +77 -0
  214. package/dist/infra/cipher/file-system/gitignore-filter.js +120 -0
  215. package/dist/infra/cipher/file-system/glob-utils.d.ts +60 -0
  216. package/dist/infra/cipher/file-system/glob-utils.js +120 -0
  217. package/dist/infra/cipher/file-system/path-validator.d.ts +69 -0
  218. package/dist/infra/cipher/file-system/path-validator.js +184 -0
  219. package/dist/infra/cipher/grpc/internal-llm-grpc-service.d.ts +149 -0
  220. package/dist/infra/cipher/grpc/internal-llm-grpc-service.js +364 -0
  221. package/dist/infra/cipher/grpc/internal-llm-grpc.proto +94 -0
  222. package/dist/infra/cipher/interactive-commands.d.ts +16 -0
  223. package/dist/infra/cipher/interactive-commands.js +198 -0
  224. package/dist/infra/cipher/interactive-loop.d.ts +24 -0
  225. package/dist/infra/cipher/interactive-loop.js +352 -0
  226. package/dist/infra/cipher/llm/context/async-mutex.d.ts +59 -0
  227. package/dist/infra/cipher/llm/context/async-mutex.js +92 -0
  228. package/dist/infra/cipher/llm/context/compression/index.d.ts +6 -0
  229. package/dist/infra/cipher/llm/context/compression/index.js +5 -0
  230. package/dist/infra/cipher/llm/context/compression/middle-removal.d.ts +40 -0
  231. package/dist/infra/cipher/llm/context/compression/middle-removal.js +76 -0
  232. package/dist/infra/cipher/llm/context/compression/oldest-removal.d.ts +38 -0
  233. package/dist/infra/cipher/llm/context/compression/oldest-removal.js +53 -0
  234. package/dist/infra/cipher/llm/context/compression/types.d.ts +36 -0
  235. package/dist/infra/cipher/llm/context/compression/types.js +1 -0
  236. package/dist/infra/cipher/llm/context/context-manager.d.ts +234 -0
  237. package/dist/infra/cipher/llm/context/context-manager.js +419 -0
  238. package/dist/infra/cipher/llm/context/index.d.ts +2 -0
  239. package/dist/infra/cipher/llm/context/index.js +2 -0
  240. package/dist/infra/cipher/llm/context/loop-detector.d.ts +125 -0
  241. package/dist/infra/cipher/llm/context/loop-detector.js +194 -0
  242. package/dist/infra/cipher/llm/context/utils.d.ts +17 -0
  243. package/dist/infra/cipher/llm/context/utils.js +89 -0
  244. package/dist/infra/cipher/llm/formatters/claude-formatter.d.ts +54 -0
  245. package/dist/infra/cipher/llm/formatters/claude-formatter.js +182 -0
  246. package/dist/infra/cipher/llm/formatters/gemini-formatter.d.ts +69 -0
  247. package/dist/infra/cipher/llm/formatters/gemini-formatter.js +253 -0
  248. package/dist/infra/cipher/llm/formatters/openrouter-formatter.d.ts +47 -0
  249. package/dist/infra/cipher/llm/formatters/openrouter-formatter.js +238 -0
  250. package/dist/infra/cipher/llm/generators/byterover-content-generator.d.ts +92 -0
  251. package/dist/infra/cipher/llm/generators/byterover-content-generator.js +211 -0
  252. package/dist/infra/cipher/llm/generators/index.d.ts +13 -0
  253. package/dist/infra/cipher/llm/generators/index.js +13 -0
  254. package/dist/infra/cipher/llm/generators/logging-content-generator.d.ts +104 -0
  255. package/dist/infra/cipher/llm/generators/logging-content-generator.js +182 -0
  256. package/dist/infra/cipher/llm/generators/openrouter-content-generator.d.ts +93 -0
  257. package/dist/infra/cipher/llm/generators/openrouter-content-generator.js +254 -0
  258. package/dist/infra/cipher/llm/generators/retryable-content-generator.d.ts +90 -0
  259. package/dist/infra/cipher/llm/generators/retryable-content-generator.js +157 -0
  260. package/dist/infra/cipher/llm/index.d.ts +9 -0
  261. package/dist/infra/cipher/llm/index.js +13 -0
  262. package/dist/infra/cipher/llm/internal-llm-service.d.ts +308 -0
  263. package/dist/infra/cipher/llm/internal-llm-service.js +724 -0
  264. package/dist/infra/cipher/llm/openrouter-llm-service.d.ts +183 -0
  265. package/dist/infra/cipher/llm/openrouter-llm-service.js +386 -0
  266. package/dist/infra/cipher/llm/response-validator.d.ts +89 -0
  267. package/dist/infra/cipher/llm/response-validator.js +157 -0
  268. package/dist/infra/cipher/llm/retry/index.d.ts +10 -0
  269. package/dist/infra/cipher/llm/retry/index.js +10 -0
  270. package/dist/infra/cipher/llm/retry/retry-policy.d.ts +74 -0
  271. package/dist/infra/cipher/llm/retry/retry-policy.js +146 -0
  272. package/dist/infra/cipher/llm/retry/retry-with-backoff.d.ts +113 -0
  273. package/dist/infra/cipher/llm/retry/retry-with-backoff.js +247 -0
  274. package/dist/infra/cipher/llm/thought-parser.d.ts +145 -0
  275. package/dist/infra/cipher/llm/thought-parser.js +190 -0
  276. package/dist/infra/cipher/llm/tokenizers/claude-tokenizer.d.ts +47 -0
  277. package/dist/infra/cipher/llm/tokenizers/claude-tokenizer.js +55 -0
  278. package/dist/infra/cipher/llm/tokenizers/default-tokenizer.d.ts +31 -0
  279. package/dist/infra/cipher/llm/tokenizers/default-tokenizer.js +38 -0
  280. package/dist/infra/cipher/llm/tokenizers/gemini-tokenizer.d.ts +37 -0
  281. package/dist/infra/cipher/llm/tokenizers/gemini-tokenizer.js +45 -0
  282. package/dist/infra/cipher/llm/tokenizers/openrouter-tokenizer.d.ts +29 -0
  283. package/dist/infra/cipher/llm/tokenizers/openrouter-tokenizer.js +37 -0
  284. package/dist/infra/cipher/llm/tool-output-processor.d.ts +117 -0
  285. package/dist/infra/cipher/llm/tool-output-processor.js +153 -0
  286. package/dist/infra/cipher/logger/console-logger.d.ts +42 -0
  287. package/dist/infra/cipher/logger/console-logger.js +63 -0
  288. package/dist/infra/cipher/logger/event-based-logger.d.ts +54 -0
  289. package/dist/infra/cipher/logger/event-based-logger.js +92 -0
  290. package/dist/infra/cipher/memory/index.d.ts +6 -0
  291. package/dist/infra/cipher/memory/index.js +7 -0
  292. package/dist/infra/cipher/memory/memory-manager.d.ts +136 -0
  293. package/dist/infra/cipher/memory/memory-manager.js +523 -0
  294. package/dist/infra/cipher/parsers/coding-agent-log-parser.d.ts +24 -0
  295. package/dist/infra/cipher/parsers/coding-agent-log-parser.js +51 -0
  296. package/dist/infra/cipher/process/command-validator.d.ts +59 -0
  297. package/dist/infra/cipher/process/command-validator.js +266 -0
  298. package/dist/infra/cipher/process/index.d.ts +8 -0
  299. package/dist/infra/cipher/process/index.js +8 -0
  300. package/dist/infra/cipher/process/process-service.d.ts +95 -0
  301. package/dist/infra/cipher/process/process-service.js +439 -0
  302. package/dist/infra/cipher/session/chat-session.d.ts +80 -0
  303. package/dist/infra/cipher/session/chat-session.js +165 -0
  304. package/dist/infra/cipher/session/index.d.ts +6 -0
  305. package/dist/infra/cipher/session/index.js +5 -0
  306. package/dist/infra/cipher/session/session-event-forwarder.d.ts +37 -0
  307. package/dist/infra/cipher/session/session-event-forwarder.js +83 -0
  308. package/dist/infra/cipher/session/session-manager.d.ts +109 -0
  309. package/dist/infra/cipher/session/session-manager.js +172 -0
  310. package/dist/infra/cipher/storage/blob-history-storage.d.ts +76 -0
  311. package/dist/infra/cipher/storage/blob-history-storage.js +178 -0
  312. package/dist/infra/cipher/system-prompt/simple-prompt-factory.d.ts +105 -0
  313. package/dist/infra/cipher/system-prompt/simple-prompt-factory.js +290 -0
  314. package/dist/infra/cipher/tools/core-tool-scheduler.d.ts +99 -0
  315. package/dist/infra/cipher/tools/core-tool-scheduler.js +161 -0
  316. package/dist/infra/cipher/tools/default-policy-rules.d.ts +26 -0
  317. package/dist/infra/cipher/tools/default-policy-rules.js +125 -0
  318. package/dist/infra/cipher/tools/implementations/bash-exec-tool.d.ts +12 -0
  319. package/dist/infra/cipher/tools/implementations/bash-exec-tool.js +93 -0
  320. package/dist/infra/cipher/tools/implementations/bash-output-tool.d.ts +12 -0
  321. package/dist/infra/cipher/tools/implementations/bash-output-tool.js +47 -0
  322. package/dist/infra/cipher/tools/implementations/create-knowledge-topic-tool.d.ts +11 -0
  323. package/dist/infra/cipher/tools/implementations/create-knowledge-topic-tool.js +142 -0
  324. package/dist/infra/cipher/tools/implementations/delete-memory-tool.d.ts +12 -0
  325. package/dist/infra/cipher/tools/implementations/delete-memory-tool.js +37 -0
  326. package/dist/infra/cipher/tools/implementations/detect-domains-tool.d.ts +7 -0
  327. package/dist/infra/cipher/tools/implementations/detect-domains-tool.js +73 -0
  328. package/dist/infra/cipher/tools/implementations/edit-file-tool.d.ts +13 -0
  329. package/dist/infra/cipher/tools/implementations/edit-file-tool.js +50 -0
  330. package/dist/infra/cipher/tools/implementations/edit-memory-tool.d.ts +13 -0
  331. package/dist/infra/cipher/tools/implementations/edit-memory-tool.js +53 -0
  332. package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.d.ts +7 -0
  333. package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.js +421 -0
  334. package/dist/infra/cipher/tools/implementations/glob-files-tool.d.ts +18 -0
  335. package/dist/infra/cipher/tools/implementations/glob-files-tool.js +70 -0
  336. package/dist/infra/cipher/tools/implementations/grep-content-tool.d.ts +12 -0
  337. package/dist/infra/cipher/tools/implementations/grep-content-tool.js +77 -0
  338. package/dist/infra/cipher/tools/implementations/kill-process-tool.d.ts +12 -0
  339. package/dist/infra/cipher/tools/implementations/kill-process-tool.js +55 -0
  340. package/dist/infra/cipher/tools/implementations/list-memories-tool.d.ts +12 -0
  341. package/dist/infra/cipher/tools/implementations/list-memories-tool.js +63 -0
  342. package/dist/infra/cipher/tools/implementations/read-file-tool.d.ts +12 -0
  343. package/dist/infra/cipher/tools/implementations/read-file-tool.js +54 -0
  344. package/dist/infra/cipher/tools/implementations/read-memory-tool.d.ts +12 -0
  345. package/dist/infra/cipher/tools/implementations/read-memory-tool.js +39 -0
  346. package/dist/infra/cipher/tools/implementations/search-history-tool.d.ts +10 -0
  347. package/dist/infra/cipher/tools/implementations/search-history-tool.js +36 -0
  348. package/dist/infra/cipher/tools/implementations/write-file-tool.d.ts +12 -0
  349. package/dist/infra/cipher/tools/implementations/write-file-tool.js +52 -0
  350. package/dist/infra/cipher/tools/implementations/write-memory-tool.d.ts +13 -0
  351. package/dist/infra/cipher/tools/implementations/write-memory-tool.js +52 -0
  352. package/dist/infra/cipher/tools/implementations/write-todos-tool.d.ts +10 -0
  353. package/dist/infra/cipher/tools/implementations/write-todos-tool.js +165 -0
  354. package/dist/infra/cipher/tools/index.d.ts +18 -0
  355. package/dist/infra/cipher/tools/index.js +19 -0
  356. package/dist/infra/cipher/tools/policy-engine.d.ts +80 -0
  357. package/dist/infra/cipher/tools/policy-engine.js +110 -0
  358. package/dist/infra/cipher/tools/tool-invocation-queue.d.ts +191 -0
  359. package/dist/infra/cipher/tools/tool-invocation-queue.js +254 -0
  360. package/dist/infra/cipher/tools/tool-invocation.d.ts +216 -0
  361. package/dist/infra/cipher/tools/tool-invocation.js +294 -0
  362. package/dist/infra/cipher/tools/tool-manager.d.ts +135 -0
  363. package/dist/infra/cipher/tools/tool-manager.js +209 -0
  364. package/dist/infra/cipher/tools/tool-markers.d.ts +48 -0
  365. package/dist/infra/cipher/tools/tool-markers.js +49 -0
  366. package/dist/infra/cipher/tools/tool-provider.d.ts +77 -0
  367. package/dist/infra/cipher/tools/tool-provider.js +196 -0
  368. package/dist/infra/cipher/tools/tool-registry.d.ts +52 -0
  369. package/dist/infra/cipher/tools/tool-registry.js +144 -0
  370. package/dist/infra/cipher/tools/utils/schema-converter.d.ts +10 -0
  371. package/dist/infra/cipher/tools/utils/schema-converter.js +29 -0
  372. package/dist/infra/cipher/validation/workspace-validator.d.ts +19 -0
  373. package/dist/infra/cipher/validation/workspace-validator.js +37 -0
  374. package/dist/infra/cipher/watcher/coding-agent-log-watcher.d.ts +14 -0
  375. package/dist/infra/cipher/watcher/coding-agent-log-watcher.js +55 -0
  376. package/dist/infra/cogit/context-tree-to-push-context-mapper.d.ts +21 -0
  377. package/dist/infra/cogit/context-tree-to-push-context-mapper.js +32 -0
  378. package/dist/infra/cogit/http-cogit-pull-service.d.ts +15 -0
  379. package/dist/infra/cogit/http-cogit-pull-service.js +30 -0
  380. package/dist/infra/cogit/http-cogit-push-service.d.ts +17 -0
  381. package/dist/infra/cogit/http-cogit-push-service.js +104 -0
  382. package/dist/infra/config/file-config-store.js +9 -3
  383. package/dist/infra/context-tree/file-context-file-reader.d.ts +14 -0
  384. package/dist/infra/context-tree/file-context-file-reader.js +46 -0
  385. package/dist/infra/context-tree/file-context-tree-service.d.ts +14 -0
  386. package/dist/infra/context-tree/file-context-tree-service.js +46 -0
  387. package/dist/infra/context-tree/file-context-tree-snapshot-service.d.ts +34 -0
  388. package/dist/infra/context-tree/file-context-tree-snapshot-service.js +117 -0
  389. package/dist/infra/context-tree/file-context-tree-writer-service.d.ts +22 -0
  390. package/dist/infra/context-tree/file-context-tree-writer-service.js +61 -0
  391. package/dist/infra/memory/http-memory-retrieval-service.js +2 -1
  392. package/dist/infra/memory/http-memory-storage-service.js +4 -3
  393. package/dist/infra/parsers/clean/clean-claude-service.d.ts +111 -0
  394. package/dist/infra/parsers/clean/clean-claude-service.js +271 -0
  395. package/dist/infra/parsers/clean/clean-codex-service.d.ts +231 -0
  396. package/dist/infra/parsers/clean/clean-codex-service.js +534 -0
  397. package/dist/infra/parsers/clean/clean-copilot-service.d.ts +255 -0
  398. package/dist/infra/parsers/clean/clean-copilot-service.js +729 -0
  399. package/dist/infra/parsers/clean/clean-cursor-service.d.ts +161 -0
  400. package/dist/infra/parsers/clean/clean-cursor-service.js +432 -0
  401. package/dist/infra/parsers/clean/clean-parser-service-factory.d.ts +54 -0
  402. package/dist/infra/parsers/clean/clean-parser-service-factory.js +80 -0
  403. package/dist/infra/parsers/clean/shared.d.ts +84 -0
  404. package/dist/infra/parsers/clean/shared.js +273 -0
  405. package/dist/infra/parsers/raw/raw-claude-service.d.ts +195 -0
  406. package/dist/infra/parsers/raw/raw-claude-service.js +548 -0
  407. package/dist/infra/parsers/raw/raw-codex-service.d.ts +313 -0
  408. package/dist/infra/parsers/raw/raw-codex-service.js +782 -0
  409. package/dist/infra/parsers/raw/raw-copilot-service.d.ts +196 -0
  410. package/dist/infra/parsers/raw/raw-copilot-service.js +558 -0
  411. package/dist/infra/parsers/raw/raw-cursor-service.d.ts +316 -0
  412. package/dist/infra/parsers/raw/raw-cursor-service.js +818 -0
  413. package/dist/infra/parsers/raw/raw-parser-service-factory.d.ts +54 -0
  414. package/dist/infra/parsers/raw/raw-parser-service-factory.js +81 -0
  415. package/dist/infra/space/http-space-service.js +2 -1
  416. package/dist/infra/team/http-team-service.js +2 -1
  417. package/dist/infra/user/http-user-service.js +2 -1
  418. package/dist/infra/watcher/file-watcher-service.d.ts +10 -0
  419. package/dist/infra/watcher/file-watcher-service.js +81 -0
  420. package/dist/infra/workspace/workspace-detector-service.d.ts +60 -0
  421. package/dist/infra/workspace/workspace-detector-service.js +165 -0
  422. package/dist/resources/prompts/curate-context-tree-curation.yml +48 -0
  423. package/dist/resources/prompts/modes/autonomous.yml +9 -0
  424. package/dist/resources/prompts/query-context-tree-retrieval.yml +49 -0
  425. package/dist/resources/prompts/reflection.yml +27 -0
  426. package/dist/resources/prompts/system-prompt.yml +82 -0
  427. package/dist/resources/prompts/tool-outputs.yml +30 -0
  428. package/dist/templates/README.md +6 -7
  429. package/dist/templates/sections/command-reference.md +40 -111
  430. package/dist/templates/sections/workflow.md +3 -30
  431. package/dist/utils/emoji-helpers.d.ts +38 -0
  432. package/dist/utils/emoji-helpers.js +42 -0
  433. package/dist/utils/error-handler.d.ts +51 -0
  434. package/dist/utils/error-handler.js +169 -0
  435. package/dist/utils/error-helpers.d.ts +30 -0
  436. package/dist/utils/error-helpers.js +47 -0
  437. package/dist/utils/file-helpers.d.ts +15 -0
  438. package/dist/utils/file-helpers.js +44 -0
  439. package/dist/utils/oclif-error-helpers.d.ts +40 -0
  440. package/dist/utils/oclif-error-helpers.js +46 -0
  441. package/dist/utils/tool-display-formatter.d.ts +53 -0
  442. package/dist/utils/tool-display-formatter.js +257 -0
  443. package/oclif.manifest.json +381 -141
  444. package/package.json +27 -6
  445. package/dist/commands/add.d.ts +0 -49
  446. package/dist/commands/add.js +0 -192
  447. package/dist/commands/complete.d.ts +0 -108
  448. package/dist/commands/complete.js +0 -340
  449. package/dist/commands/retrieve.d.ts +0 -26
  450. package/dist/commands/retrieve.js +0 -101
  451. package/dist/core/domain/entities/curator-output.d.ts +0 -14
  452. package/dist/core/domain/entities/curator-output.js +0 -23
  453. package/dist/core/domain/entities/delta-batch.d.ts +0 -30
  454. package/dist/core/domain/entities/delta-batch.js +0 -52
  455. package/dist/core/domain/entities/delta-operation.d.ts +0 -31
  456. package/dist/core/domain/entities/delta-operation.js +0 -50
  457. package/dist/core/domain/entities/executor-output.d.ts +0 -27
  458. package/dist/core/domain/entities/executor-output.js +0 -33
  459. package/dist/core/domain/entities/reflector-output.d.ts +0 -38
  460. package/dist/core/domain/entities/reflector-output.js +0 -44
  461. package/dist/core/interfaces/i-ace-prompt-builder.d.ts +0 -48
  462. package/dist/core/interfaces/i-bullet-content-store.d.ts +0 -36
  463. package/dist/core/interfaces/i-delta-store.d.ts +0 -15
  464. package/dist/core/interfaces/i-executor-output-store.d.ts +0 -14
  465. package/dist/core/interfaces/i-playbook-service.d.ts +0 -69
  466. package/dist/core/interfaces/i-playbook-store.d.ts +0 -38
  467. package/dist/core/interfaces/i-reflection-store.d.ts +0 -21
  468. package/dist/infra/ace/ace-file-utils.d.ts +0 -46
  469. package/dist/infra/ace/ace-file-utils.js +0 -83
  470. package/dist/infra/ace/ace-prompt-templates.d.ts +0 -13
  471. package/dist/infra/ace/ace-prompt-templates.js +0 -177
  472. package/dist/infra/ace/file-bullet-content-store.d.ts +0 -27
  473. package/dist/infra/ace/file-bullet-content-store.js +0 -89
  474. package/dist/infra/ace/file-delta-store.d.ts +0 -9
  475. package/dist/infra/ace/file-delta-store.js +0 -26
  476. package/dist/infra/ace/file-executor-output-store.d.ts +0 -9
  477. package/dist/infra/ace/file-executor-output-store.js +0 -26
  478. package/dist/infra/ace/file-playbook-store.d.ts +0 -29
  479. package/dist/infra/ace/file-playbook-store.js +0 -107
  480. package/dist/infra/ace/file-reflection-store.d.ts +0 -10
  481. package/dist/infra/ace/file-reflection-store.js +0 -55
  482. package/dist/infra/playbook/file-playbook-service.d.ts +0 -42
  483. package/dist/infra/playbook/file-playbook-service.js +0 -132
  484. /package/dist/core/{interfaces/i-ace-prompt-builder.js → domain/cipher/blob/types.js} +0 -0
  485. /package/dist/core/{interfaces/i-bullet-content-store.js → domain/cipher/file-system/types.js} +0 -0
  486. /package/dist/core/{interfaces/i-delta-store.js → domain/cipher/process/types.js} +0 -0
  487. /package/dist/core/{interfaces/i-executor-output-store.js → domain/cipher/session/types.js} +0 -0
  488. /package/dist/core/{interfaces/i-playbook-service.js → domain/cipher/storage/history-types.js} +0 -0
  489. /package/dist/core/{interfaces/i-playbook-store.js → domain/cipher/system-prompt/types.js} +0 -0
  490. /package/dist/core/{interfaces/i-reflection-store.js → domain/cipher/tools/types.js} +0 -0
@@ -0,0 +1,782 @@
1
+ /**
2
+ * Codex Raw Service
3
+ * Consolidates CodexParser + CodexRawParser
4
+ * Parses JSONL transcript files from ~/.codex/sessions/
5
+ */
6
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
7
+ import { readdir, readFile } from 'node:fs/promises';
8
+ import path, { join } from 'node:path';
9
+ // ============================================================================
10
+ // CONSTANTS
11
+ // ============================================================================
12
+ const TITLE_MAX_LENGTH = 100;
13
+ const SUMMARY_TEXT_TYPE = 'summary_text';
14
+ /**
15
+ * Codex Raw Service
16
+ * Handles extraction of Codex sessions from JSONL transcript files
17
+ */
18
+ export class CodexRawService {
19
+ ide;
20
+ /**
21
+ * Initialize Codex Raw Service
22
+ *
23
+ * @param ide - The IDE type (Codex)
24
+ */
25
+ constructor(ide) {
26
+ this.ide = ide;
27
+ }
28
+ /**
29
+ * Main entry point - Parse Codex sessions from a custom directory
30
+ *
31
+ * Parses all JSONL transcript files from a Codex sessions directory,
32
+ * extracts session information, and writes normalized JSON files to output directory.
33
+ * Organizes output by date (YYYY-MM-DD) matching Codex's original directory structure.
34
+ * Returns success status.
35
+ *
36
+ * @param customDir - Path to directory containing Codex session files
37
+ * @param outputDir - Optional output directory (defaults to process.cwd()/.brv/logs/{ide}/raw)
38
+ * @returns Promise resolving to true if parsing succeeded, false otherwise
39
+ */
40
+ async parse(customDir, outputDir) {
41
+ const baseOutputDir = outputDir || path.join(process.cwd(), `.brv/logs/${this.ide}/raw`);
42
+ console.log('🔍 Starting Codex conversation parsing...');
43
+ console.log(`📁 Custom directory: ${customDir}`);
44
+ try {
45
+ // Parse all sessions from the Codex directory
46
+ const sessions = await this.parseSessionDirectory(customDir);
47
+ if (sessions.length === 0) {
48
+ console.log('ℹ️ No Codex sessions found');
49
+ return true;
50
+ }
51
+ console.log(`\n✅ Found ${sessions.length} Codex sessions`);
52
+ // Organize sessions by date (YYYY-MM-DD), matching Codex's original directory structure
53
+ const sessionsByDate = {};
54
+ for (const session of sessions) {
55
+ // Extract date from session's startedAt timestamp
56
+ const date = new Date(session.metadata.startedAt);
57
+ const year = date.getFullYear();
58
+ const month = String(date.getMonth() + 1).padStart(2, '0');
59
+ const day = String(date.getDate()).padStart(2, '0');
60
+ const datePrefix = `${year}-${month}-${day}`;
61
+ if (!sessionsByDate[datePrefix]) {
62
+ sessionsByDate[datePrefix] = [];
63
+ }
64
+ sessionsByDate[datePrefix].push({
65
+ ...session,
66
+ datePrefix,
67
+ });
68
+ }
69
+ console.log(`\n📁 Organized into ${Object.keys(sessionsByDate).length} date(s)`);
70
+ // Export sessions organized by date
71
+ console.log('\n💾 Exporting sessions by date...');
72
+ for (const [datePrefix, dateSessions] of Object.entries(sessionsByDate).sort()) {
73
+ const dateDir = path.join(baseOutputDir, datePrefix);
74
+ if (!existsSync(dateDir)) {
75
+ mkdirSync(dateDir, { recursive: true });
76
+ }
77
+ console.log(`\n 📅 ${datePrefix}`);
78
+ // Export session files for this date
79
+ for (const session of dateSessions) {
80
+ const filename = `${session.id}.json`;
81
+ const filepath = path.join(dateDir, filename);
82
+ writeFileSync(filepath, JSON.stringify(session, null, 2));
83
+ const fileSize = readFileSync(filepath).length;
84
+ const fileSizeKb = (fileSize / 1024).toFixed(1);
85
+ const truncatedTitle = session.title.slice(0, 50);
86
+ console.log(` ✅ ${truncatedTitle}${session.title.length > 50 ? '...' : ''} (${fileSizeKb} KB)`);
87
+ }
88
+ }
89
+ console.log(`\n🎉 Codex export complete! Sessions exported to: ${outputDir}`);
90
+ return true;
91
+ }
92
+ catch (error) {
93
+ console.error('❌ Error during parsing:', error);
94
+ throw error;
95
+ }
96
+ }
97
+ /**
98
+ * Build token usage object with optional cache tokens
99
+ *
100
+ * Constructs a token usage metrics object, including cache tokens only if they're
101
+ * greater than zero. Calculates total tokens as sum of input and output.
102
+ *
103
+ * @param cacheTokens - Number of cached input tokens
104
+ * @param inputTokens - Number of input tokens used
105
+ * @param outputTokens - Number of output tokens generated
106
+ * @returns Token usage object with optional cacheTokens and calculated total
107
+ */
108
+ buildTokenUsageObject(cacheTokens, inputTokens, outputTokens) {
109
+ return {
110
+ cacheTokens: cacheTokens > 0 ? cacheTokens : undefined,
111
+ inputTokens,
112
+ outputTokens,
113
+ totalTokens: inputTokens + outputTokens,
114
+ };
115
+ }
116
+ /**
117
+ * Calculate aggregate session metadata from transcript entries
118
+ *
119
+ * Aggregates token usage, counts message types, extracts timestamps and workspace information.
120
+ * Returns comprehensive metadata including token costs, message counts, duration, and session details.
121
+ *
122
+ * @param entries - Array of transcript entries from JSONL file
123
+ * @param messages - Parsed messages array (for count verification)
124
+ * @param logPath - Log file path (used to extract workspace information)
125
+ * @param sessionMeta - Extracted session metadata (may be null)
126
+ * @returns RawCodexSessionMetadata object with aggregated statistics
127
+ */
128
+ calculateMetadata(entries, messages, logPath, sessionMeta) {
129
+ const { cacheTokens, inputTokens, outputTokens } = this.calculateTokenUsage(entries);
130
+ const { assistantCount, userCount } = this.countMessageTypes(messages);
131
+ const { endedAt, startedAt } = this.extractTimestamps(entries, sessionMeta);
132
+ const duration = new Date(endedAt || new Date()).getTime() - new Date(startedAt).getTime();
133
+ return {
134
+ assistantMessageCount: assistantCount,
135
+ cliVersion: sessionMeta?.cli_version,
136
+ duration,
137
+ endedAt,
138
+ messageCount: messages.length,
139
+ model: sessionMeta?.model_provider || 'unknown',
140
+ modelProvider: sessionMeta?.model_provider,
141
+ originator: sessionMeta?.originator,
142
+ sessionId: this.extractSessionId(logPath),
143
+ source: sessionMeta?.source,
144
+ startedAt,
145
+ tokenUsage: this.buildTokenUsageObject(cacheTokens, inputTokens, outputTokens),
146
+ userMessageCount: userCount,
147
+ workspace: this.extractWorkspace(logPath, sessionMeta),
148
+ };
149
+ }
150
+ /**
151
+ * Calculate total token usage from transcript entries
152
+ *
153
+ * Aggregates token counts from all token_count event messages in the transcript.
154
+ * Includes input tokens, output tokens, and cached input tokens.
155
+ *
156
+ * @param entries - Array of transcript entries to analyze
157
+ * @returns Object with aggregated cacheTokens, inputTokens, and outputTokens
158
+ */
159
+ calculateTokenUsage(entries) {
160
+ let inputTokens = 0;
161
+ let outputTokens = 0;
162
+ let cacheTokens = 0;
163
+ for (const entry of entries) {
164
+ if (!this.isTokenCountEntry(entry)) {
165
+ continue;
166
+ }
167
+ const usage = entry.payload?.info;
168
+ if (usage?.total_token_usage) {
169
+ const tokenUsage = usage.total_token_usage;
170
+ inputTokens += typeof tokenUsage?.input_tokens === 'number' ? tokenUsage.input_tokens : 0;
171
+ outputTokens += typeof tokenUsage?.output_tokens === 'number' ? tokenUsage.output_tokens : 0;
172
+ cacheTokens += typeof tokenUsage?.cached_input_tokens === 'number' ? tokenUsage.cached_input_tokens : 0;
173
+ }
174
+ }
175
+ return { cacheTokens, inputTokens, outputTokens };
176
+ }
177
+ /**
178
+ * Convert Codex content block to normalized content block
179
+ *
180
+ * Transforms a Codex-specific content block into a standardized ContentBlock format.
181
+ * Handles tool_use blocks (preserves id, input, name) and text blocks (normalizes types).
182
+ * Converts input_text type to text type for consistency.
183
+ *
184
+ * @param block - Codex content block to convert
185
+ * @returns Normalized ContentBlock object
186
+ */
187
+ convertCodexContentBlockToContentBlock(block) {
188
+ const contentBlock = {};
189
+ if (block.type === 'tool_use') {
190
+ contentBlock.id = `tool_${Date.now()}`;
191
+ if (block.input)
192
+ contentBlock.input = block.input;
193
+ if (block.name)
194
+ contentBlock.name = block.name;
195
+ }
196
+ else if (block.text) {
197
+ contentBlock.text = block.text;
198
+ }
199
+ contentBlock.type = block.type === 'input_text' ? 'text' : block.type;
200
+ return contentBlock;
201
+ }
202
+ /**
203
+ * Convert Codex transcript entries to normalized messages
204
+ *
205
+ * Transforms raw JSONL transcript entries (messages, function calls, reasoning, token counts) into
206
+ * standardized RawCodexRawMessage objects. Tracks token usage and reasoning context across entries,
207
+ * maintaining order and relationships between tool calls and responses.
208
+ *
209
+ * @param entries - Array of transcript entries from JSONL file
210
+ * @returns Array of normalized RawCodexRawMessage objects
211
+ */
212
+ convertToMessages(entries) {
213
+ const messages = [];
214
+ let currentTokenUsage = null;
215
+ let currentReasoning = null;
216
+ for (const entry of entries) {
217
+ // Track token usage and reasoning from event messages
218
+ if (entry.type === 'event_msg' && entry.payload && this.isEventPayload(entry.payload)) {
219
+ if (entry.payload.type === 'token_count' && entry.payload.info) {
220
+ currentTokenUsage = entry.payload.info.total_token_usage;
221
+ }
222
+ if (entry.payload.type === 'agent_reasoning' && entry.payload.text) {
223
+ currentReasoning = entry.payload.text;
224
+ }
225
+ }
226
+ // Process response items (messages, reasoning, function calls)
227
+ if (entry.type === 'response_item' && entry.payload && this.isResponsePayload(entry.payload)) {
228
+ const { payload } = entry;
229
+ const timestamp = entry.timestamp || new Date().toISOString();
230
+ switch (payload.type) {
231
+ case 'function_call': {
232
+ this.processFunctionCall(payload, messages);
233
+ break;
234
+ }
235
+ case 'function_call_output': {
236
+ this.processFunctionCallOutput(payload, messages);
237
+ break;
238
+ }
239
+ case 'message': {
240
+ this.processMessage(payload, messages, timestamp, currentTokenUsage, currentReasoning);
241
+ // Reset reasoning after message
242
+ currentReasoning = null;
243
+ break;
244
+ }
245
+ case 'reasoning': {
246
+ const newReasoning = this.processReasoningPayload(payload);
247
+ if (newReasoning) {
248
+ currentReasoning = newReasoning;
249
+ }
250
+ break;
251
+ }
252
+ // No default
253
+ }
254
+ }
255
+ }
256
+ return messages;
257
+ }
258
+ /**
259
+ * Convert transcript entry to raw entry format
260
+ *
261
+ * Transforms a transcript entry into the raw entry storage format, filtering entries without payloads
262
+ * and converting ISO timestamp strings to millisecond timestamps. Validates entry types and applies
263
+ * fallback type for invalid entries.
264
+ *
265
+ * @param entry - Transcript entry to convert
266
+ * @returns Converted RawCodexRawEntry object, or null if entry has no payload
267
+ */
268
+ convertTranscriptEntryToRawEntry(entry) {
269
+ // Filter entries that don't have a payload
270
+ if (!entry.payload) {
271
+ return null;
272
+ }
273
+ // Convert timestamp from string to number
274
+ const timestamp = entry.timestamp
275
+ ? new Date(entry.timestamp).getTime()
276
+ : Date.now();
277
+ return {
278
+ payload: entry.payload,
279
+ timestamp,
280
+ type: (entry.type === 'event_msg' || entry.type === 'response_item' || entry.type === 'session_meta' || entry.type === 'turn_context')
281
+ ? entry.type
282
+ : 'response_item', // Default fallback
283
+ };
284
+ }
285
+ /**
286
+ * Count user and assistant messages in a message array
287
+ *
288
+ * Iterates through messages and counts the total number of user and assistant messages.
289
+ * Used for metadata tracking and session statistics.
290
+ *
291
+ * @param messages - Array of messages to count
292
+ * @returns Object with assistantCount and userCount totals
293
+ */
294
+ countMessageTypes(messages) {
295
+ let userCount = 0;
296
+ let assistantCount = 0;
297
+ for (const message of messages) {
298
+ if (message.type === 'user')
299
+ userCount++;
300
+ if (message.type === 'assistant')
301
+ assistantCount++;
302
+ }
303
+ return { assistantCount, userCount };
304
+ }
305
+ /**
306
+ * Extract and normalize content blocks from message content
307
+ *
308
+ * Handles multiple content formats: null/undefined (empty array), strings (wrapped as text block),
309
+ * arrays of blocks/strings (normalized to RawCodexContentBlock array), and objects.
310
+ * Produces consistent RawCodexContentBlock array output for consistent processing.
311
+ *
312
+ * @param content - Raw message content in various formats
313
+ * @returns Array of normalized RawCodexContentBlock objects
314
+ */
315
+ extractContentBlocks(content) {
316
+ const blocks = [];
317
+ // If content is a string, wrap it as a text block
318
+ if (typeof content === 'string') {
319
+ return [{ text: content, type: 'output_text' }];
320
+ }
321
+ // If content is already an array of blocks
322
+ if (Array.isArray(content)) {
323
+ for (const block of content) {
324
+ if (typeof block === 'string') {
325
+ blocks.push({ text: block, type: 'output_text' });
326
+ }
327
+ else if (block && typeof block === 'object') {
328
+ // Check if it's a valid block with a type field
329
+ if ('type' in block) {
330
+ blocks.push(block);
331
+ }
332
+ else {
333
+ // Fallback: wrap as text
334
+ blocks.push({ text: JSON.stringify(block), type: 'output_text' });
335
+ }
336
+ }
337
+ }
338
+ return blocks;
339
+ }
340
+ return [{ text: JSON.stringify(content), type: 'output_text' }];
341
+ }
342
+ /**
343
+ * Extract session ID from Codex log file path
344
+ *
345
+ * Parses the filename from the log path to extract the session ID.
346
+ * Codex session IDs are typically UUIDs in the JSONL filename.
347
+ * Removes the .jsonl extension to get the session ID.
348
+ *
349
+ * @param logPath - Path to Codex session log file
350
+ * @returns Session ID extracted from the filename
351
+ */
352
+ extractSessionId(logPath) {
353
+ // Codex session IDs are typically UUIDs in the filename
354
+ // Format: ~/.codex/sessions/YYYY/MM/DD/{session-id}.jsonl
355
+ const parts = logPath.split('/');
356
+ const filename = parts.at(-1) || '';
357
+ return filename.replace('.jsonl', '');
358
+ }
359
+ /**
360
+ * Extract session metadata from transcript entries
361
+ *
362
+ * Searches transcript entries for session_meta type entries and validates them.
363
+ * Returns the session metadata payload (containing model, CLI version, timestamp, git info).
364
+ * Returns null if no valid session metadata is found.
365
+ *
366
+ * @param entries - Array of transcript entries to search
367
+ * @returns Extracted RawCodexSessionMeta payload, or null if not found
368
+ */
369
+ extractSessionMeta(entries) {
370
+ const sessionMetaEntry = entries.find((e) => e.type === 'session_meta');
371
+ if (sessionMetaEntry && sessionMetaEntry.payload && this.isSessionMetaPayload(sessionMetaEntry.payload)) {
372
+ return sessionMetaEntry.payload;
373
+ }
374
+ return null;
375
+ }
376
+ /**
377
+ * Extract session start and end timestamps
378
+ *
379
+ * Collects timestamps from transcript entries, filters empty values, sorts chronologically.
380
+ * Prefers session metadata timestamp for start time if available, otherwise uses first entry timestamp.
381
+ * Returns last timestamp as end time, or undefined if only one timestamp exists.
382
+ *
383
+ * @param entries - Array of transcript entries with optional timestamp fields
384
+ * @param sessionMeta - Optional session metadata containing preferred start timestamp
385
+ * @returns Object with startedAt and optional endedAt ISO timestamp strings
386
+ */
387
+ extractTimestamps(entries, sessionMeta) {
388
+ const validTimestamps = entries
389
+ .filter((e) => e.timestamp)
390
+ .map((e) => e.timestamp || '')
391
+ .filter((t) => t.trim().length > 0)
392
+ .sort();
393
+ return {
394
+ endedAt: validTimestamps.at(-1),
395
+ startedAt: sessionMeta?.timestamp || validTimestamps[0] || new Date().toISOString(),
396
+ };
397
+ }
398
+ /**
399
+ * Extract session title from first user message
400
+ *
401
+ * Uses the first line of the first user message as the session title.
402
+ * Handles both string and array content formats, extracting text blocks from arrays.
403
+ * Truncates to TITLE_MAX_LENGTH (100 chars) and appends "..." if truncated.
404
+ * Returns default title if no user messages found or first message is empty.
405
+ *
406
+ * @param messages - Array of parsed session messages
407
+ * @returns Session title string (max 100 characters)
408
+ */
409
+ extractTitle(messages) {
410
+ // Use first user message as title
411
+ const firstUserMessage = messages.find((m) => m.type === 'user');
412
+ if (firstUserMessage) {
413
+ let text = '';
414
+ if (typeof firstUserMessage.content === 'string') {
415
+ text = firstUserMessage.content;
416
+ }
417
+ else if (Array.isArray(firstUserMessage.content)) {
418
+ const textBlocks = firstUserMessage.content.filter((b) => typeof b === 'object' && b !== null && 'text' in b && typeof b.text === 'string');
419
+ text = textBlocks.map((b) => b.text).join(' ');
420
+ }
421
+ if (text) {
422
+ const lines = text.split('\n').filter((l) => l.trim());
423
+ if (lines.length > 0) {
424
+ const title = lines[0].slice(0, Math.max(0, TITLE_MAX_LENGTH));
425
+ return title.length === TITLE_MAX_LENGTH ? title + '...' : title;
426
+ }
427
+ }
428
+ }
429
+ return 'Codex Session';
430
+ }
431
+ /**
432
+ * Extract workspace information from session metadata and log path
433
+ *
434
+ * Extracts workspace path and repository information from session metadata (preferred)
435
+ * or falls back to log path if metadata is unavailable. Includes repository name and
436
+ * optional git URL if available in session metadata.
437
+ *
438
+ * @param logPath - Codex session log file path (used as fallback)
439
+ * @param sessionMeta - Optional session metadata containing workspace and git info
440
+ * @returns Object with workspace path and optional repository name/url
441
+ */
442
+ extractWorkspace(logPath, sessionMeta) {
443
+ // Try to get from session metadata first
444
+ if (sessionMeta?.cwd) {
445
+ const parts = sessionMeta.cwd.split('/');
446
+ const name = parts.at(-1) || 'unknown';
447
+ return {
448
+ path: sessionMeta.cwd,
449
+ repository: {
450
+ name,
451
+ url: sessionMeta.git?.repository_url,
452
+ },
453
+ };
454
+ }
455
+ // Fallback: use log path
456
+ return {
457
+ path: logPath,
458
+ };
459
+ }
460
+ /**
461
+ * Type guard for event payload
462
+ *
463
+ * Checks if a payload is a valid RawCodexEventPayload by verifying it's an object
464
+ * with a type field matching token_count or agent_reasoning event types.
465
+ *
466
+ * @param payload - Value to check
467
+ * @returns True if payload is a valid RawCodexEventPayload, false otherwise
468
+ */
469
+ isEventPayload(payload) {
470
+ return (typeof payload === 'object' &&
471
+ payload !== null &&
472
+ 'type' in payload &&
473
+ (payload.type === 'token_count' || payload.type === 'agent_reasoning'));
474
+ }
475
+ /**
476
+ * Type guard for response payload
477
+ *
478
+ * Checks if a payload is a valid RawCodexResponsePayload by verifying it's an object
479
+ * with a type field matching one of: function_call, function_call_output, message, or reasoning.
480
+ *
481
+ * @param payload - Value to check
482
+ * @returns True if payload is a valid RawCodexResponsePayload, false otherwise
483
+ */
484
+ isResponsePayload(payload) {
485
+ return (typeof payload === 'object' &&
486
+ payload !== null &&
487
+ 'type' in payload &&
488
+ ['function_call', 'function_call_output', 'message', 'reasoning'].includes(payload.type));
489
+ }
490
+ /**
491
+ * Type guard for session meta payload
492
+ *
493
+ * Checks if a payload is a valid RawCodexSessionMetaPayload by verifying it's an object
494
+ * containing at least one of: model_provider, cli_version, or timestamp fields.
495
+ *
496
+ * @param payload - Value to check
497
+ * @returns True if payload is a valid RawCodexSessionMetaPayload, false otherwise
498
+ */
499
+ isSessionMetaPayload(payload) {
500
+ return (typeof payload === 'object' &&
501
+ payload !== null &&
502
+ ('model_provider' in payload || 'cli_version' in payload || 'timestamp' in payload));
503
+ }
504
+ /**
505
+ * Check if entry is a token count event
506
+ *
507
+ * Validates that an entry is an event_msg type with an event payload of type 'token_count'
508
+ * and contains token usage information (info field).
509
+ *
510
+ * @param entry - Transcript entry to check
511
+ * @returns True if entry is a valid token count event, false otherwise
512
+ */
513
+ isTokenCountEntry(entry) {
514
+ if (entry.type !== 'event_msg' || !entry.payload || !this.isEventPayload(entry.payload)) {
515
+ return false;
516
+ }
517
+ const payload = entry.payload;
518
+ return payload.type === 'token_count' && payload.info !== undefined;
519
+ }
520
+ /**
521
+ * Parse all Codex session logs in a directory
522
+ *
523
+ * Finds all JSONL files in the directory (including subdirectories), parses them in sequence,
524
+ * and returns array of successfully parsed sessions sorted by start time.
525
+ * Collects and reports any parse errors without failing completely.
526
+ *
527
+ * @param dirPath - Path to directory containing JSONL session files
528
+ * @returns Promise resolving to array of parsed RawCodexRawSession objects
529
+ * @throws Error if directory cannot be read
530
+ */
531
+ /* eslint-disable no-await-in-loop */
532
+ async parseSessionDirectory(dirPath) {
533
+ try {
534
+ const files = await readdir(dirPath, { recursive: true });
535
+ const jsonlFiles = files.filter((f) => typeof f === 'string' && f.endsWith('.jsonl') && !f.includes('-combined'));
536
+ const sessions = [];
537
+ const errors = [];
538
+ for (const file of jsonlFiles) {
539
+ try {
540
+ const fullPath = join(dirPath, file);
541
+ const session = await this.parseSessionLog(fullPath);
542
+ sessions.push(session);
543
+ }
544
+ catch (error) {
545
+ errors.push(`${file}: ${error instanceof Error ? error.message : 'Unknown error'}`);
546
+ }
547
+ }
548
+ if (sessions.length === 0 && errors.length > 0) {
549
+ console.warn(`Failed to parse some logs: ${errors.join(', ')}`);
550
+ }
551
+ // Sort by start time
552
+ sessions.sort((a, b) => a.metadata.startedAt.localeCompare(b.metadata.startedAt));
553
+ return sessions;
554
+ }
555
+ catch (error) {
556
+ throw new Error(`Failed to parse directory: ${error instanceof Error ? error.message : 'Unknown error'}`);
557
+ }
558
+ }
559
+ /* eslint-enable no-await-in-loop */
560
+ /**
561
+ * Parse a single Codex session log file
562
+ *
563
+ * Validates log file format, reads JSONL content, parses each line as a transcript entry,
564
+ * converts entries to messages, extracts session metadata, calculates aggregated statistics,
565
+ * and extracts session title. Handles token usage, function calls, and reasoning payloads.
566
+ *
567
+ * @param logPath - Absolute path to Codex session JSONL file
568
+ * @returns Promise resolving to parsed RawCodexRawSession object
569
+ * @throws Error if file is invalid or cannot be parsed
570
+ */
571
+ async parseSessionLog(logPath) {
572
+ try {
573
+ // Validate first
574
+ const valid = await this.validateLogFile(logPath);
575
+ if (!valid) {
576
+ throw new Error(`Invalid Codex log path: ${logPath}`);
577
+ }
578
+ // Read and parse JSONL file
579
+ const content = await readFile(logPath, 'utf8');
580
+ const lines = content.trim().split('\n').filter((l) => l.trim());
581
+ const entries = [];
582
+ const parseErrors = [];
583
+ for (const [i, line] of lines.entries()) {
584
+ try {
585
+ const entry = JSON.parse(line);
586
+ entries.push(entry);
587
+ }
588
+ catch (error) {
589
+ parseErrors.push(`Line ${i + 1}: ${error instanceof Error ? error.message : 'Parse error'}`);
590
+ }
591
+ }
592
+ if (entries.length === 0) {
593
+ throw new Error(`No valid entries found in ${logPath}`);
594
+ }
595
+ // Extract session info
596
+ const sessionId = this.extractSessionId(logPath);
597
+ const sessionMeta = this.extractSessionMeta(entries);
598
+ const messages = this.convertToMessages(entries);
599
+ const metadata = this.calculateMetadata(entries, messages, logPath, sessionMeta);
600
+ const title = this.extractTitle(messages);
601
+ // Convert transcript entries to raw entries, filtering out entries without payloads
602
+ const rawEntries = entries
603
+ .map((entry) => this.convertTranscriptEntryToRawEntry(entry))
604
+ .filter((entry) => entry !== null);
605
+ return {
606
+ id: sessionId,
607
+ messages,
608
+ metadata,
609
+ rawEntries,
610
+ timestamp: new Date(metadata.startedAt).getTime(),
611
+ title,
612
+ };
613
+ }
614
+ catch (error) {
615
+ throw new Error(`Failed to parse Codex log: ${error instanceof Error ? error.message : 'Unknown error'}`);
616
+ }
617
+ }
618
+ /**
619
+ * Process function call payload and add to last message
620
+ *
621
+ * Extracts function call information from a function_call payload and appends it as a tool_use
622
+ * content block to the last message. Converts string arguments to parsed objects.
623
+ * If last message content is a string, converts it to an array before adding tool block.
624
+ *
625
+ * @param payload - Function call payload containing name, arguments, and call ID
626
+ * @param messages - Messages array to update (modifies last message in place)
627
+ */
628
+ processFunctionCall(payload, messages) {
629
+ if (messages.length === 0)
630
+ return;
631
+ const lastMessage = messages.at(-1);
632
+ if (!lastMessage)
633
+ return;
634
+ const toolBlock = {
635
+ id: `call_${Date.now()}`,
636
+ input: typeof payload.arguments === 'string'
637
+ ? this.safeJsonParse(payload.arguments)
638
+ : payload.arguments,
639
+ name: payload.name || 'unknown',
640
+ type: 'tool_use',
641
+ };
642
+ if (Array.isArray(lastMessage.content)) {
643
+ lastMessage.content.push(toolBlock);
644
+ }
645
+ else {
646
+ // Convert string content to array and add tool block
647
+ const textBlock = {
648
+ text: lastMessage.content,
649
+ type: 'output_text',
650
+ };
651
+ lastMessage.content = [textBlock, toolBlock];
652
+ }
653
+ }
654
+ /**
655
+ * Process function call output and attach to corresponding tool use block
656
+ *
657
+ * Finds the most recent tool_use block in the last message and appends the function output to it.
658
+ * The output field contains the result of the function call execution.
659
+ *
660
+ * @param payload - Function call output payload containing output data
661
+ * @param messages - Messages array to update (modifies last message in place)
662
+ */
663
+ processFunctionCallOutput(payload, messages) {
664
+ if (messages.length === 0)
665
+ return;
666
+ const lastMessage = messages.at(-1);
667
+ if (!lastMessage || !Array.isArray(lastMessage.content))
668
+ return;
669
+ // Find the tool use block with matching call_id
670
+ const toolBlock = lastMessage.content.find((b) => b.type === 'tool_use');
671
+ if (toolBlock) {
672
+ toolBlock.output = payload.output;
673
+ }
674
+ }
675
+ /**
676
+ * Process message payload and add to messages array
677
+ *
678
+ * Converts a message payload into a normalized RawCodexRawMessage and appends to messages array.
679
+ * Handles content block conversion, attaches token usage and reasoning context if available.
680
+ * Collapses single text blocks to strings for backward compatibility.
681
+ *
682
+ * @param payload - Message payload containing role and content
683
+ * @param messages - Messages array to update (appends new message)
684
+ * @param timestamp - ISO timestamp for the message
685
+ * @param currentTokenUsage - Optional token usage metrics to attach to message
686
+ * @param currentReasoning - Optional reasoning content to attach to message
687
+ */
688
+ // eslint-disable-next-line max-params
689
+ processMessage(payload, messages, timestamp, currentTokenUsage, currentReasoning) {
690
+ const role = payload.role;
691
+ const codexContentBlocks = this.extractContentBlocks(payload.content);
692
+ // Convert CodexContentBlock array to ContentBlock array
693
+ const contentBlocks = codexContentBlocks.map((block) => this.convertCodexContentBlockToContentBlock(block));
694
+ messages.push({
695
+ content: contentBlocks.length === 1 && contentBlocks[0].type === 'text'
696
+ ? contentBlocks[0].text
697
+ : contentBlocks.length === 1 && contentBlocks[0].type === 'output_text'
698
+ ? contentBlocks[0].text
699
+ : contentBlocks,
700
+ reasoning: currentReasoning || undefined,
701
+ timestamp,
702
+ tokens: currentTokenUsage
703
+ ? {
704
+ input: currentTokenUsage.input_tokens || 0,
705
+ output: currentTokenUsage.output_tokens || 0,
706
+ }
707
+ : undefined,
708
+ type: role,
709
+ });
710
+ }
711
+ /**
712
+ * Process reasoning payload and extract reasoning text summary
713
+ *
714
+ * Extracts reasoning content from a reasoning payload by filtering summary items of type 'summary_text'
715
+ * and joining their text content. Returns null if no valid reasoning content is found.
716
+ *
717
+ * @param payload - Reasoning payload containing summary array
718
+ * @returns Extracted reasoning text or null if no valid content found
719
+ */
720
+ processReasoningPayload(payload) {
721
+ if (!payload.summary || !Array.isArray(payload.summary))
722
+ return null;
723
+ const summaryTexts = payload.summary
724
+ .filter((s) => 'type' in s && s.type === SUMMARY_TEXT_TYPE)
725
+ .map((s) => s.text);
726
+ return summaryTexts.length > 0 ? summaryTexts.join('\n') : null;
727
+ }
728
+ /**
729
+ * Safely parse JSON string or return object as-is
730
+ *
731
+ * Attempts to parse a JSON string. If input is already an object, returns it directly.
732
+ * Returns empty object on parse errors or non-string/object inputs.
733
+ * Used for defensive parsing of tool call arguments.
734
+ *
735
+ * @param jsonString - String to parse or object to validate
736
+ * @returns Parsed object or empty object if parsing fails
737
+ */
738
+ safeJsonParse(jsonString) {
739
+ if (typeof jsonString === 'object' && jsonString !== null) {
740
+ return jsonString;
741
+ }
742
+ if (typeof jsonString !== 'string') {
743
+ return {};
744
+ }
745
+ try {
746
+ const parsed = JSON.parse(jsonString);
747
+ return typeof parsed === 'object' && parsed !== null ? parsed : {};
748
+ }
749
+ catch {
750
+ return {};
751
+ }
752
+ }
753
+ /**
754
+ * Validate Codex log file format and existence
755
+ *
756
+ * Checks three validation criteria:
757
+ * 1. Path contains /.codex/sessions/ directory marker
758
+ * 2. File has .jsonl extension
759
+ * 3. File exists on filesystem
760
+ * Returns false silently if any check fails.
761
+ *
762
+ * @param logPath - Path to file to validate
763
+ * @returns Promise resolving to true if file is valid Codex log file, false otherwise
764
+ */
765
+ async validateLogFile(logPath) {
766
+ try {
767
+ // Check path contains .codex/sessions/
768
+ if (!logPath.includes('/.codex/sessions/')) {
769
+ return false;
770
+ }
771
+ // Check file extension is .jsonl
772
+ if (!logPath.endsWith('.jsonl')) {
773
+ return false;
774
+ }
775
+ // Check file exists
776
+ return existsSync(logPath);
777
+ }
778
+ catch {
779
+ return false;
780
+ }
781
+ }
782
+ }