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,641 @@
1
+ import { glob } from 'glob';
2
+ import { spawn } from 'node:child_process';
3
+ import fs from 'node:fs/promises';
4
+ import { EOL } from 'node:os';
5
+ import path from 'node:path';
6
+ import { DirectoryNotFoundError, EditOperationError, FileNotFoundError, FileTooLargeError, GlobOperationError, InvalidExtensionError, InvalidPathError, InvalidPatternError, PathBlockedError, PathNotAllowedError, PathTraversalError, ReadOperationError, SearchOperationError, ServiceNotInitializedError, StringNotFoundError, StringNotUniqueError, WriteOperationError, } from '../../../core/domain/cipher/errors/file-system-error.js';
7
+ import { getErrorMessage } from '../../../utils/error-helpers.js';
8
+ import { createGitignoreFilter } from './gitignore-filter.js';
9
+ import { collectFileMetadata, escapeIfExactMatch, extractPaths, sortFilesByRecency } from './glob-utils.js';
10
+ import { PathValidator } from './path-validator.js';
11
+ /**
12
+ * File system service implementation.
13
+ * Provides secure, validated file system operations with comprehensive
14
+ * path validation, size limits, and allow/block list enforcement.
15
+ */
16
+ export class FileSystemService {
17
+ config;
18
+ initialized = false;
19
+ pathValidator;
20
+ /**
21
+ * Creates a new file system service
22
+ * @param config - File system configuration (optional, uses defaults)
23
+ */
24
+ constructor(config = {}) {
25
+ // Merge with defaults
26
+ this.config = {
27
+ allowedPaths: config.allowedPaths ?? ['.'],
28
+ blockedExtensions: config.blockedExtensions ?? ['.exe', '.dll', '.so', '.dylib'],
29
+ blockedPaths: config.blockedPaths ?? ['.git', 'node_modules/.bin', '.env', '.byterover'],
30
+ maxFileSize: config.maxFileSize ?? 10 * 1024 * 1024, // 10MB
31
+ workingDirectory: config.workingDirectory ?? process.cwd(),
32
+ };
33
+ this.pathValidator = new PathValidator(this.config);
34
+ }
35
+ /**
36
+ * Edit a file by replacing strings.
37
+ */
38
+ async editFile(filePath, operation, options = {}) {
39
+ this.ensureInitialized();
40
+ // Validate path
41
+ const validation = this.pathValidator.validate(filePath, 'read');
42
+ if (!validation.valid) {
43
+ this.throwValidationError(filePath, validation.error);
44
+ }
45
+ const { normalizedPath } = validation;
46
+ try {
47
+ // Read current content
48
+ const fileContent = await this.readFile(filePath, options);
49
+ let { content } = fileContent;
50
+ // Escape regex special characters for literal string matching
51
+ const escapedOldString = operation.oldString.replaceAll(/[$()*+.?[\u005C\]^{|}]/g, String.raw `\$&`);
52
+ // Count occurrences
53
+ const occurrences = (content.match(new RegExp(escapedOldString, 'g')) || []).length;
54
+ // Check if string exists
55
+ if (occurrences === 0) {
56
+ throw new StringNotFoundError(normalizedPath, operation.oldString);
57
+ }
58
+ // Check if string is unique (if replaceAll is false)
59
+ if (!operation.replaceAll && occurrences > 1) {
60
+ throw new StringNotUniqueError(normalizedPath, operation.oldString, occurrences);
61
+ }
62
+ // Perform replacement
63
+ content = operation.replaceAll
64
+ ? content.replaceAll(operation.oldString, operation.newString)
65
+ : content.replace(operation.oldString, operation.newString);
66
+ // Write back
67
+ const writeResult = await this.writeFile(filePath, content, options);
68
+ return {
69
+ bytesWritten: writeResult.bytesWritten,
70
+ path: normalizedPath,
71
+ replacements: operation.replaceAll ? occurrences : 1,
72
+ success: true,
73
+ };
74
+ }
75
+ catch (error) {
76
+ // Re-throw known errors
77
+ if (error instanceof FileNotFoundError ||
78
+ error instanceof StringNotFoundError ||
79
+ error instanceof StringNotUniqueError ||
80
+ error instanceof PathNotAllowedError ||
81
+ error instanceof PathTraversalError ||
82
+ error instanceof PathBlockedError) {
83
+ throw error;
84
+ }
85
+ // Wrap other errors
86
+ throw new EditOperationError(normalizedPath, getErrorMessage(error));
87
+ }
88
+ }
89
+ /**
90
+ * Find files matching a glob pattern.
91
+ *
92
+ * Features:
93
+ * - Case sensitivity control via `caseSensitive` option
94
+ * - Gitignore filtering via `respectGitignore` option
95
+ * - Smart sorting: recent files (within 24h) first, then alphabetical
96
+ * - Special character handling for paths with glob syntax
97
+ */
98
+ async globFiles(pattern, options = {}) {
99
+ this.ensureInitialized();
100
+ const cwd = options.cwd ?? this.config.workingDirectory;
101
+ const maxResults = options.maxResults ?? 1000;
102
+ const includeMetadata = options.includeMetadata ?? true;
103
+ const caseSensitive = options.caseSensitive ?? true;
104
+ const respectGitignore = options.respectGitignore ?? true;
105
+ try {
106
+ // Handle special characters - escape pattern if it matches an existing file
107
+ const escapedPattern = await escapeIfExactMatch(pattern, cwd);
108
+ // Execute glob with case sensitivity option
109
+ const files = await glob(escapedPattern, {
110
+ absolute: true,
111
+ cwd,
112
+ follow: false, // Don't follow symlinks
113
+ nocase: !caseSensitive, // Case insensitive if caseSensitive is false
114
+ nodir: true, // Only files
115
+ });
116
+ // Initialize gitignore filter if requested
117
+ let gitignoreFilter = null;
118
+ if (respectGitignore) {
119
+ gitignoreFilter = await createGitignoreFilter(cwd);
120
+ }
121
+ // Validate paths and apply gitignore filtering
122
+ const validPaths = [];
123
+ let ignoredCount = 0;
124
+ for (const file of files) {
125
+ // Validate path
126
+ const validation = this.pathValidator.validate(file, 'read');
127
+ if (!validation.valid || !validation.normalizedPath) {
128
+ // Skip invalid paths
129
+ continue;
130
+ }
131
+ // Apply gitignore filter if enabled
132
+ if (gitignoreFilter) {
133
+ const relativePath = path.relative(cwd, validation.normalizedPath);
134
+ if (gitignoreFilter.isIgnored(relativePath)) {
135
+ ignoredCount++;
136
+ continue;
137
+ }
138
+ }
139
+ validPaths.push(validation.normalizedPath);
140
+ }
141
+ const totalFound = validPaths.length;
142
+ // Collect metadata for all valid paths
143
+ const filesWithMetadata = await collectFileMetadata(validPaths, cwd);
144
+ // Sort files: recent files first (within 24h), then alphabetical
145
+ const sortedFiles = sortFilesByRecency(filesWithMetadata);
146
+ // Apply maxResults limit after sorting
147
+ const truncated = sortedFiles.length > maxResults;
148
+ const limitedFiles = sortedFiles.slice(0, maxResults);
149
+ // Convert to FileMetadata format
150
+ const resultFiles = includeMetadata
151
+ ? limitedFiles.map((f) => ({
152
+ isDirectory: false,
153
+ modified: f.modifiedTime,
154
+ path: f.path,
155
+ size: f.size,
156
+ }))
157
+ : extractPaths(limitedFiles).map((p) => ({
158
+ isDirectory: false,
159
+ modified: new Date(),
160
+ path: p,
161
+ size: 0,
162
+ }));
163
+ // Build result message
164
+ const message = this.buildGlobMessage(resultFiles.length, totalFound, ignoredCount, truncated);
165
+ return {
166
+ files: resultFiles,
167
+ ignoredCount,
168
+ message,
169
+ totalFound,
170
+ truncated,
171
+ };
172
+ }
173
+ catch (error) {
174
+ // Check for pattern errors
175
+ if (getErrorMessage(error).includes('Invalid glob pattern')) {
176
+ throw new InvalidPatternError(pattern, getErrorMessage(error));
177
+ }
178
+ throw new GlobOperationError(pattern, getErrorMessage(error));
179
+ }
180
+ }
181
+ /**
182
+ * Initialize the file system service.
183
+ */
184
+ async initialize() {
185
+ if (this.initialized) {
186
+ return;
187
+ }
188
+ // Verify working directory exists
189
+ try {
190
+ const stats = await fs.stat(this.config.workingDirectory);
191
+ if (!stats.isDirectory()) {
192
+ throw new DirectoryNotFoundError(this.config.workingDirectory);
193
+ }
194
+ }
195
+ catch (error) {
196
+ if (error.code === 'ENOENT') {
197
+ throw new DirectoryNotFoundError(this.config.workingDirectory);
198
+ }
199
+ throw error;
200
+ }
201
+ this.initialized = true;
202
+ }
203
+ /**
204
+ * Read the contents of a file.
205
+ */
206
+ async readFile(filePath, options = {}) {
207
+ this.ensureInitialized();
208
+ // Validate path
209
+ const validation = this.pathValidator.validate(filePath, 'read');
210
+ if (!validation.valid) {
211
+ this.throwValidationError(filePath, validation.error);
212
+ }
213
+ const { normalizedPath } = validation;
214
+ try {
215
+ // Check if file exists
216
+ let stats;
217
+ try {
218
+ stats = await fs.stat(normalizedPath);
219
+ }
220
+ catch (error) {
221
+ if (error.code === 'ENOENT') {
222
+ throw new FileNotFoundError(normalizedPath);
223
+ }
224
+ throw error;
225
+ }
226
+ // Check file size
227
+ if (stats.size > this.config.maxFileSize) {
228
+ throw new FileTooLargeError(normalizedPath, stats.size, this.config.maxFileSize);
229
+ }
230
+ // Read file
231
+ const encoding = (options.encoding ?? 'utf8');
232
+ const content = await fs.readFile(normalizedPath, encoding);
233
+ // Handle pagination
234
+ const lines = content.split('\n');
235
+ let selectedLines;
236
+ let truncated = false;
237
+ // Apply offset (1-based, like text editors)
238
+ const { limit, offset: offset1 } = options;
239
+ if (offset1 !== undefined || limit !== undefined) {
240
+ const start = offset1 !== undefined && offset1 > 0 ? Math.max(0, offset1 - 1) : 0;
241
+ const end = limit === undefined ? lines.length : start + limit;
242
+ selectedLines = lines.slice(start, end);
243
+ truncated = end < lines.length;
244
+ }
245
+ else {
246
+ selectedLines = lines;
247
+ }
248
+ const selectedContent = selectedLines.join('\n');
249
+ return {
250
+ content: selectedContent,
251
+ encoding,
252
+ lines: selectedLines.length,
253
+ size: stats.size,
254
+ truncated,
255
+ };
256
+ }
257
+ catch (error) {
258
+ // Re-throw known errors
259
+ if (error instanceof FileNotFoundError ||
260
+ error instanceof FileTooLargeError ||
261
+ error instanceof PathNotAllowedError ||
262
+ error instanceof PathTraversalError ||
263
+ error instanceof PathBlockedError) {
264
+ throw error;
265
+ }
266
+ // Wrap other errors
267
+ throw new ReadOperationError(normalizedPath, getErrorMessage(error));
268
+ }
269
+ }
270
+ /**
271
+ * Search file contents for a pattern.
272
+ * Uses native grep commands (ripgrep, system grep) when available for better performance,
273
+ * falling back to JavaScript implementation when needed.
274
+ */
275
+ async searchContent(pattern, options = {}) {
276
+ this.ensureInitialized();
277
+ const cwd = options.cwd ?? this.config.workingDirectory;
278
+ const maxResults = options.maxResults ?? 100;
279
+ const contextLines = options.contextLines ?? 0;
280
+ // If context lines requested, use JS fallback directly (native grep context parsing is complex)
281
+ if (contextLines > 0) {
282
+ return this.searchContentJS(pattern, options);
283
+ }
284
+ try {
285
+ // Try native strategies in order: ripgrep → system grep → JS fallback
286
+ let matches = null;
287
+ matches = await this.executeRipgrep(pattern, cwd, options);
288
+ if (matches === null) {
289
+ matches = await this.executeSystemGrep(pattern, cwd, options);
290
+ }
291
+ if (matches === null) {
292
+ return this.searchContentJS(pattern, options);
293
+ }
294
+ // Apply maxResults limit
295
+ const truncated = matches.length > maxResults;
296
+ return {
297
+ filesSearched: new Set(matches.map((m) => m.file)).size,
298
+ matches: matches.slice(0, maxResults),
299
+ totalMatches: matches.length,
300
+ truncated,
301
+ };
302
+ }
303
+ catch (error) {
304
+ // Re-throw known errors
305
+ if (error instanceof InvalidPatternError || error instanceof GlobOperationError) {
306
+ throw error;
307
+ }
308
+ throw new SearchOperationError(pattern, getErrorMessage(error));
309
+ }
310
+ }
311
+ /**
312
+ * Write content to a file.
313
+ */
314
+ async writeFile(filePath, content, options = {}) {
315
+ this.ensureInitialized();
316
+ // Validate path
317
+ const validation = this.pathValidator.validate(filePath, 'write');
318
+ if (!validation.valid) {
319
+ this.throwValidationError(filePath, validation.error);
320
+ }
321
+ const { normalizedPath } = validation;
322
+ try {
323
+ // Create parent directories if requested
324
+ if (options.createDirs) {
325
+ const dirname = path.dirname(normalizedPath);
326
+ await fs.mkdir(dirname, { recursive: true });
327
+ }
328
+ // Write file
329
+ const encoding = (options.encoding ?? 'utf8');
330
+ await fs.writeFile(normalizedPath, content, encoding);
331
+ // Get file size
332
+ const stats = await fs.stat(normalizedPath);
333
+ return {
334
+ bytesWritten: stats.size,
335
+ path: normalizedPath,
336
+ success: true,
337
+ };
338
+ }
339
+ catch (error) {
340
+ // Re-throw known errors
341
+ if (error instanceof InvalidExtensionError ||
342
+ error instanceof PathNotAllowedError ||
343
+ error instanceof PathTraversalError ||
344
+ error instanceof PathBlockedError) {
345
+ throw error;
346
+ }
347
+ // Wrap other errors
348
+ throw new WriteOperationError(normalizedPath, getErrorMessage(error));
349
+ }
350
+ }
351
+ /**
352
+ * Builds a human-readable message for glob results.
353
+ */
354
+ buildGlobMessage(returned, total, ignored, truncated) {
355
+ const parts = [];
356
+ if (truncated) {
357
+ parts.push(`Found ${total} files, showing first ${returned}`);
358
+ }
359
+ else {
360
+ parts.push(`Found ${returned} file${returned === 1 ? '' : 's'}`);
361
+ }
362
+ if (ignored > 0) {
363
+ parts.push(`(${ignored} ignored by .gitignore)`);
364
+ }
365
+ return parts.join(' ');
366
+ }
367
+ /**
368
+ * Collects context lines before and after a match.
369
+ */
370
+ collectContextLines(lines, lineIndex, contextLines) {
371
+ const before = [];
372
+ const after = [];
373
+ if (contextLines > 0) {
374
+ // Lines before
375
+ for (let j = Math.max(0, lineIndex - contextLines); j < lineIndex; j++) {
376
+ before.push(lines[j]);
377
+ }
378
+ // Lines after
379
+ for (let j = lineIndex + 1; j < Math.min(lines.length, lineIndex + 1 + contextLines); j++) {
380
+ after.push(lines[j]);
381
+ }
382
+ }
383
+ return { after, before };
384
+ }
385
+ /**
386
+ * Creates a regex from a pattern string.
387
+ */
388
+ createSearchRegex(pattern, caseInsensitive) {
389
+ const flags = caseInsensitive ? 'i' : '';
390
+ try {
391
+ return new RegExp(pattern, flags);
392
+ }
393
+ catch (error) {
394
+ throw new InvalidPatternError(pattern, getErrorMessage(error));
395
+ }
396
+ }
397
+ /**
398
+ * Ensures the service is initialized.
399
+ * @throws ServiceNotInitializedError if not initialized
400
+ */
401
+ ensureInitialized() {
402
+ if (!this.initialized) {
403
+ throw new ServiceNotInitializedError();
404
+ }
405
+ }
406
+ /**
407
+ * Executes ripgrep (rg) for content search.
408
+ * Returns null if rg is not available or fails.
409
+ */
410
+ async executeRipgrep(pattern, cwd, options) {
411
+ if (!(await this.isCommandAvailable('rg')))
412
+ return null;
413
+ const args = ['-n', '--no-heading', '--with-filename'];
414
+ if (options.caseInsensitive)
415
+ args.push('-i');
416
+ // Add exclusions for blocked paths
417
+ for (const blocked of this.config.blockedPaths) {
418
+ args.push('--glob', `!${blocked}`);
419
+ }
420
+ if (options.globPattern)
421
+ args.push('--glob', options.globPattern);
422
+ args.push(pattern, '.'); // Add search path to prevent reading from stdin
423
+ try {
424
+ const output = await this.spawnCommand('rg', args, cwd, options.abortSignal);
425
+ return this.parseGrepOutput(output, cwd);
426
+ }
427
+ catch {
428
+ return null;
429
+ }
430
+ }
431
+ /**
432
+ * Executes system grep for content search.
433
+ * Returns null if grep is not available or fails.
434
+ */
435
+ async executeSystemGrep(pattern, cwd, options) {
436
+ if (!(await this.isCommandAvailable('grep')))
437
+ return null;
438
+ const args = ['-r', '-n', '-H', '-E', '-I'];
439
+ if (options.caseInsensitive)
440
+ args.push('-i');
441
+ // Add exclusions for blocked paths
442
+ for (const blocked of this.config.blockedPaths) {
443
+ args.push(`--exclude-dir=${blocked}`);
444
+ }
445
+ if (options.globPattern)
446
+ args.push(`--include=${options.globPattern}`);
447
+ args.push(pattern, '.');
448
+ try {
449
+ const output = await this.spawnCommand('grep', args, cwd, options.abortSignal);
450
+ return this.parseGrepOutput(output, cwd);
451
+ }
452
+ catch {
453
+ return null;
454
+ }
455
+ }
456
+ /**
457
+ * Checks if a command is available in the system's PATH.
458
+ */
459
+ isCommandAvailable(command) {
460
+ return new Promise((resolve) => {
461
+ const checkCmd = process.platform === 'win32' ? 'where' : 'command';
462
+ const checkArgs = process.platform === 'win32' ? [command] : ['-v', command];
463
+ try {
464
+ const child = spawn(checkCmd, checkArgs, { shell: true, stdio: 'ignore' });
465
+ child.on('close', (code) => resolve(code === 0));
466
+ child.on('error', () => resolve(false));
467
+ }
468
+ catch {
469
+ resolve(false);
470
+ }
471
+ });
472
+ }
473
+ /**
474
+ * Parses output from grep-like commands (filepath:lineNumber:content format).
475
+ */
476
+ parseGrepOutput(output, basePath) {
477
+ const results = [];
478
+ if (!output)
479
+ return results;
480
+ for (const line of output.split(EOL)) {
481
+ if (!line.trim())
482
+ continue;
483
+ // Format: filepath:lineNumber:content
484
+ const firstColon = line.indexOf(':');
485
+ if (firstColon === -1)
486
+ continue;
487
+ const secondColon = line.indexOf(':', firstColon + 1);
488
+ if (secondColon === -1)
489
+ continue;
490
+ const filePath = line.slice(0, firstColon);
491
+ const lineNumber = Number.parseInt(line.slice(firstColon + 1, secondColon), 10);
492
+ const content = line.slice(secondColon + 1);
493
+ if (!Number.isNaN(lineNumber)) {
494
+ results.push({
495
+ file: path.resolve(basePath, filePath),
496
+ line: content,
497
+ lineNumber,
498
+ });
499
+ }
500
+ }
501
+ return results;
502
+ }
503
+ /**
504
+ * JavaScript-based content search implementation.
505
+ * Used as fallback when native grep commands are unavailable or when context lines are needed.
506
+ */
507
+ async searchContentJS(pattern, options = {}) {
508
+ const globPattern = options.globPattern ?? '**/*';
509
+ const cwd = options.cwd ?? this.config.workingDirectory;
510
+ const maxResults = options.maxResults ?? 100;
511
+ const contextLines = options.contextLines ?? 0;
512
+ const caseInsensitive = options.caseInsensitive ?? false;
513
+ try {
514
+ // Create regex
515
+ const regex = this.createSearchRegex(pattern, caseInsensitive);
516
+ // Find files to search
517
+ const globResult = await this.globFiles(globPattern, {
518
+ cwd,
519
+ includeMetadata: false,
520
+ maxResults: 10_000, // Search more files, but limit results
521
+ });
522
+ return await this.searchFiles(globResult.files, regex, maxResults, contextLines);
523
+ }
524
+ catch (error) {
525
+ // Re-throw known errors
526
+ if (error instanceof InvalidPatternError || error instanceof GlobOperationError) {
527
+ throw error;
528
+ }
529
+ throw new SearchOperationError(pattern, getErrorMessage(error));
530
+ }
531
+ }
532
+ /**
533
+ * Searches a single file for a regex pattern.
534
+ */
535
+ async searchFile(filePath, regex, maxMatches, contextLines) {
536
+ const fileContent = await this.readFile(filePath);
537
+ const lines = fileContent.content.split('\n');
538
+ const matches = [];
539
+ let totalMatches = 0;
540
+ for (let i = 0; i < lines.length; i++) {
541
+ const line = lines[i];
542
+ if (regex.test(line)) {
543
+ totalMatches++;
544
+ if (matches.length >= maxMatches) {
545
+ break;
546
+ }
547
+ const context = this.collectContextLines(lines, i, contextLines);
548
+ matches.push({
549
+ context: contextLines > 0 ? context : undefined,
550
+ file: filePath,
551
+ line,
552
+ lineNumber: i + 1, // 1-based line numbers
553
+ });
554
+ }
555
+ }
556
+ return { matches, totalMatches };
557
+ }
558
+ /**
559
+ * Searches multiple files for a regex pattern.
560
+ */
561
+ async searchFiles(files, regex, maxResults, contextLines) {
562
+ const matches = [];
563
+ let totalMatches = 0;
564
+ let filesSearched = 0;
565
+ for (const fileInfo of files) {
566
+ filesSearched++;
567
+ try {
568
+ // eslint-disable-next-line no-await-in-loop
569
+ const fileMatches = await this.searchFile(fileInfo.path, regex, maxResults - matches.length, contextLines);
570
+ totalMatches += fileMatches.totalMatches;
571
+ for (const match of fileMatches.matches) {
572
+ matches.push(match);
573
+ if (matches.length >= maxResults) {
574
+ return {
575
+ filesSearched,
576
+ matches,
577
+ totalMatches,
578
+ truncated: true,
579
+ };
580
+ }
581
+ }
582
+ }
583
+ catch {
584
+ // Skip files that can't be read
585
+ continue;
586
+ }
587
+ }
588
+ return {
589
+ filesSearched,
590
+ matches,
591
+ totalMatches,
592
+ truncated: false,
593
+ };
594
+ }
595
+ /**
596
+ * Spawns a command and returns its stdout.
597
+ */
598
+ spawnCommand(cmd, args, cwd, signal) {
599
+ return new Promise((resolve, reject) => {
600
+ const child = spawn(cmd, args, { cwd, windowsHide: true });
601
+ const chunks = [];
602
+ if (signal) {
603
+ signal.addEventListener('abort', () => child.kill());
604
+ }
605
+ child.stdout.on('data', (chunk) => chunks.push(chunk));
606
+ child.on('error', reject);
607
+ child.on('close', (code) => {
608
+ if (code === 0 || code === 1) {
609
+ // 1 = no matches found (not an error)
610
+ resolve(Buffer.concat(chunks).toString('utf8'));
611
+ }
612
+ else {
613
+ reject(new Error(`Command exited with code ${code}`));
614
+ }
615
+ });
616
+ });
617
+ }
618
+ /**
619
+ * Throws the appropriate error based on validation error message.
620
+ */
621
+ throwValidationError(path, error) {
622
+ if (error.includes('empty')) {
623
+ throw new InvalidPathError(path, error);
624
+ }
625
+ if (error.includes('traversal')) {
626
+ throw new PathTraversalError(path);
627
+ }
628
+ if (error.includes('not in allowed paths')) {
629
+ throw new PathNotAllowedError(path, this.config.allowedPaths);
630
+ }
631
+ if (error.includes('blocked')) {
632
+ throw new PathBlockedError(path, error);
633
+ }
634
+ if (error.includes('extension')) {
635
+ const ext = path.split('.').pop() ?? '';
636
+ throw new InvalidExtensionError(path, ext);
637
+ }
638
+ // Fallback
639
+ throw new InvalidPathError(path, error);
640
+ }
641
+ }