byterover-cli 0.2.0 → 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 (498) 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 +53 -2
  18. package/dist/commands/init.js +279 -66
  19. package/dist/commands/login.js +9 -4
  20. package/dist/commands/logout.d.ts +16 -0
  21. package/dist/commands/logout.js +61 -0
  22. package/dist/commands/pull.d.ts +33 -0
  23. package/dist/commands/pull.js +115 -0
  24. package/dist/commands/push.d.ts +13 -13
  25. package/dist/commands/push.js +81 -101
  26. package/dist/commands/query.d.ts +63 -0
  27. package/dist/commands/query.js +349 -0
  28. package/dist/commands/space/list.d.ts +5 -2
  29. package/dist/commands/space/list.js +60 -56
  30. package/dist/commands/space/switch.d.ts +16 -0
  31. package/dist/commands/space/switch.js +102 -53
  32. package/dist/commands/status.d.ts +5 -2
  33. package/dist/commands/status.js +43 -33
  34. package/dist/commands/watch.d.ts +23 -0
  35. package/dist/commands/watch.js +171 -0
  36. package/dist/config/auth.config.js +14 -2
  37. package/dist/config/context-tree-domains.d.ts +12 -0
  38. package/dist/config/context-tree-domains.js +29 -0
  39. package/dist/config/environment.d.ts +6 -0
  40. package/dist/config/environment.js +9 -2
  41. package/dist/constants.d.ts +5 -0
  42. package/dist/constants.js +6 -0
  43. package/dist/core/domain/cipher/agent/agent-state-machine.d.ts +128 -0
  44. package/dist/core/domain/cipher/agent/agent-state-machine.js +183 -0
  45. package/dist/core/domain/cipher/agent/agent-state.d.ts +77 -0
  46. package/dist/core/domain/cipher/agent/agent-state.js +59 -0
  47. package/dist/core/domain/cipher/agent/index.d.ts +7 -0
  48. package/dist/core/domain/cipher/agent/index.js +7 -0
  49. package/dist/core/domain/cipher/agent-events/index.d.ts +8 -0
  50. package/dist/core/domain/cipher/agent-events/index.js +7 -0
  51. package/dist/core/domain/cipher/agent-events/types.d.ts +419 -0
  52. package/dist/core/domain/cipher/agent-events/types.js +42 -0
  53. package/dist/core/domain/cipher/blob/types.d.ts +108 -0
  54. package/dist/core/domain/cipher/errors/blob-error.d.ts +36 -0
  55. package/dist/core/domain/cipher/errors/blob-error.js +68 -0
  56. package/dist/core/domain/cipher/errors/file-system-error.d.ts +211 -0
  57. package/dist/core/domain/cipher/errors/file-system-error.js +291 -0
  58. package/dist/core/domain/cipher/errors/llm-error.d.ts +120 -0
  59. package/dist/core/domain/cipher/errors/llm-error.js +161 -0
  60. package/dist/core/domain/cipher/errors/memory-error.d.ts +35 -0
  61. package/dist/core/domain/cipher/errors/memory-error.js +62 -0
  62. package/dist/core/domain/cipher/errors/process-error-code.d.ts +97 -0
  63. package/dist/core/domain/cipher/errors/process-error-code.js +98 -0
  64. package/dist/core/domain/cipher/errors/process-error.d.ts +135 -0
  65. package/dist/core/domain/cipher/errors/process-error.js +173 -0
  66. package/dist/core/domain/cipher/errors/session-error.d.ts +56 -0
  67. package/dist/core/domain/cipher/errors/session-error.js +74 -0
  68. package/dist/core/domain/cipher/errors/tool-error.d.ts +57 -0
  69. package/dist/core/domain/cipher/errors/tool-error.js +81 -0
  70. package/dist/core/domain/cipher/file-system/types.d.ts +203 -0
  71. package/dist/core/domain/cipher/memory/types.d.ts +102 -0
  72. package/dist/core/domain/cipher/memory/types.js +4 -0
  73. package/dist/core/domain/cipher/parsed-interaction.d.ts +47 -0
  74. package/dist/core/domain/cipher/parsed-interaction.js +25 -0
  75. package/dist/core/domain/cipher/process/types.d.ts +286 -0
  76. package/dist/core/domain/cipher/session/types.d.ts +54 -0
  77. package/dist/core/domain/cipher/storage/history-types.d.ts +38 -0
  78. package/dist/core/domain/cipher/system-prompt/types.d.ts +131 -0
  79. package/dist/core/domain/cipher/todos/index.d.ts +4 -0
  80. package/dist/core/domain/cipher/todos/index.js +4 -0
  81. package/dist/core/domain/cipher/todos/types.d.ts +57 -0
  82. package/dist/core/domain/cipher/todos/types.js +5 -0
  83. package/dist/core/domain/cipher/tools/constants.d.ts +28 -0
  84. package/dist/core/domain/cipher/tools/constants.js +24 -0
  85. package/dist/core/domain/cipher/tools/tool-error.d.ts +183 -0
  86. package/dist/core/domain/cipher/tools/tool-error.js +246 -0
  87. package/dist/core/domain/cipher/tools/types.d.ts +145 -0
  88. package/dist/core/domain/entities/brv-config.d.ts +42 -6
  89. package/dist/core/domain/entities/brv-config.js +115 -17
  90. package/dist/core/domain/entities/cogit-push-context.d.ts +38 -0
  91. package/dist/core/domain/entities/cogit-push-context.js +91 -0
  92. package/dist/core/domain/entities/cogit-push-response.d.ts +20 -0
  93. package/dist/core/domain/entities/cogit-push-response.js +31 -0
  94. package/dist/core/domain/entities/cogit-snapshot-author.d.ts +24 -0
  95. package/dist/core/domain/entities/cogit-snapshot-author.js +39 -0
  96. package/dist/core/domain/entities/cogit-snapshot-file.d.ts +34 -0
  97. package/dist/core/domain/entities/cogit-snapshot-file.js +59 -0
  98. package/dist/core/domain/entities/cogit-snapshot.d.ts +31 -0
  99. package/dist/core/domain/entities/cogit-snapshot.js +58 -0
  100. package/dist/core/domain/entities/context-tree-index.d.ts +26 -0
  101. package/dist/core/domain/entities/context-tree-index.js +27 -0
  102. package/dist/core/domain/entities/context-tree-snapshot.d.ts +56 -0
  103. package/dist/core/domain/entities/context-tree-snapshot.js +83 -0
  104. package/dist/core/domain/entities/event.d.ts +1 -1
  105. package/dist/core/domain/entities/event.js +4 -1
  106. package/dist/core/domain/entities/parser.d.ts +567 -0
  107. package/dist/core/domain/entities/parser.js +10 -0
  108. package/dist/core/domain/entities/playbook.d.ts +2 -23
  109. package/dist/core/domain/entities/playbook.js +2 -70
  110. package/dist/core/domain/errors/brv-config-version-error.d.ts +16 -0
  111. package/dist/core/domain/errors/brv-config-version-error.js +21 -0
  112. package/dist/core/domain/knowledge/directory-manager.d.ts +80 -0
  113. package/dist/core/domain/knowledge/directory-manager.js +145 -0
  114. package/dist/core/domain/knowledge/markdown-writer.d.ts +18 -0
  115. package/dist/core/domain/knowledge/markdown-writer.js +18 -0
  116. package/dist/core/domain/knowledge/relation-parser.d.ts +90 -0
  117. package/dist/core/domain/knowledge/relation-parser.js +131 -0
  118. package/dist/core/interfaces/cipher/cipher-services.d.ts +71 -0
  119. package/dist/core/interfaces/cipher/cipher-services.js +1 -0
  120. package/dist/core/interfaces/cipher/i-blob-storage.d.ts +78 -0
  121. package/dist/core/interfaces/cipher/i-blob-storage.js +1 -0
  122. package/dist/core/interfaces/cipher/i-chat-session.d.ts +62 -0
  123. package/dist/core/interfaces/cipher/i-chat-session.js +1 -0
  124. package/dist/core/interfaces/cipher/i-cipher-agent.d.ts +88 -0
  125. package/dist/core/interfaces/cipher/i-cipher-agent.js +1 -0
  126. package/dist/core/interfaces/cipher/i-coding-agent-log-parser.d.ts +20 -0
  127. package/dist/core/interfaces/cipher/i-coding-agent-log-parser.js +1 -0
  128. package/dist/core/interfaces/cipher/i-coding-agent-log-watcher.d.ts +31 -0
  129. package/dist/core/interfaces/cipher/i-coding-agent-log-watcher.js +1 -0
  130. package/dist/core/interfaces/cipher/i-content-generator.d.ts +120 -0
  131. package/dist/core/interfaces/cipher/i-content-generator.js +12 -0
  132. package/dist/core/interfaces/cipher/i-event-emitter.d.ts +76 -0
  133. package/dist/core/interfaces/cipher/i-event-emitter.js +1 -0
  134. package/dist/core/interfaces/cipher/i-file-system.d.ts +68 -0
  135. package/dist/core/interfaces/cipher/i-file-system.js +1 -0
  136. package/dist/core/interfaces/cipher/i-history-storage.d.ts +53 -0
  137. package/dist/core/interfaces/cipher/i-history-storage.js +1 -0
  138. package/dist/core/interfaces/cipher/i-llm-provider.d.ts +14 -0
  139. package/dist/core/interfaces/cipher/i-llm-provider.js +1 -0
  140. package/dist/core/interfaces/cipher/i-llm-service.d.ts +62 -0
  141. package/dist/core/interfaces/cipher/i-llm-service.js +1 -0
  142. package/dist/core/interfaces/cipher/i-logger.d.ts +78 -0
  143. package/dist/core/interfaces/cipher/i-logger.js +28 -0
  144. package/dist/core/interfaces/cipher/i-message-formatter.d.ts +44 -0
  145. package/dist/core/interfaces/cipher/i-message-formatter.js +1 -0
  146. package/dist/core/interfaces/cipher/i-policy-engine.d.ts +102 -0
  147. package/dist/core/interfaces/cipher/i-policy-engine.js +9 -0
  148. package/dist/core/interfaces/cipher/i-process-service.d.ts +65 -0
  149. package/dist/core/interfaces/cipher/i-process-service.js +1 -0
  150. package/dist/core/interfaces/cipher/i-system-prompt-contributor.d.ts +25 -0
  151. package/dist/core/interfaces/cipher/i-system-prompt-contributor.js +1 -0
  152. package/dist/core/interfaces/cipher/i-tokenizer.d.ts +15 -0
  153. package/dist/core/interfaces/cipher/i-tokenizer.js +1 -0
  154. package/dist/core/interfaces/cipher/i-tool-provider.d.ts +64 -0
  155. package/dist/core/interfaces/cipher/i-tool-provider.js +1 -0
  156. package/dist/core/interfaces/cipher/i-tool-scheduler.d.ts +103 -0
  157. package/dist/core/interfaces/cipher/i-tool-scheduler.js +11 -0
  158. package/dist/core/interfaces/cipher/llm-types.d.ts +46 -0
  159. package/dist/core/interfaces/cipher/llm-types.js +5 -0
  160. package/dist/core/interfaces/cipher/message-types.d.ts +118 -0
  161. package/dist/core/interfaces/cipher/message-types.js +5 -0
  162. package/dist/core/interfaces/cipher/tokenizer-types.d.ts +11 -0
  163. package/dist/core/interfaces/cipher/tokenizer-types.js +14 -0
  164. package/dist/core/interfaces/i-cogit-pull-service.d.ts +24 -0
  165. package/dist/core/interfaces/i-cogit-pull-service.js +1 -0
  166. package/dist/core/interfaces/i-cogit-push-service.d.ts +27 -0
  167. package/dist/core/interfaces/i-cogit-push-service.js +1 -0
  168. package/dist/core/interfaces/i-context-file-reader.d.ts +32 -0
  169. package/dist/core/interfaces/i-context-file-reader.js +1 -0
  170. package/dist/core/interfaces/i-context-tree-service.d.ts +21 -0
  171. package/dist/core/interfaces/i-context-tree-service.js +1 -0
  172. package/dist/core/interfaces/i-context-tree-snapshot-service.d.ts +36 -0
  173. package/dist/core/interfaces/i-context-tree-snapshot-service.js +1 -0
  174. package/dist/core/interfaces/i-context-tree-writer-service.d.ts +32 -0
  175. package/dist/core/interfaces/i-context-tree-writer-service.js +1 -0
  176. package/dist/core/interfaces/i-file-watcher-service.d.ts +41 -0
  177. package/dist/core/interfaces/i-file-watcher-service.js +1 -0
  178. package/dist/core/interfaces/i-rule-template-service.d.ts +0 -4
  179. package/dist/core/interfaces/i-rule-template-service.js +1 -4
  180. package/dist/core/interfaces/parser/i-clean-parser-service.d.ts +18 -0
  181. package/dist/core/interfaces/parser/i-clean-parser-service.js +1 -0
  182. package/dist/core/interfaces/parser/i-raw-parser-service.d.ts +17 -0
  183. package/dist/core/interfaces/parser/i-raw-parser-service.js +1 -0
  184. package/dist/core/interfaces/parser/i-session-normalizer.d.ts +56 -0
  185. package/dist/core/interfaces/parser/i-session-normalizer.js +1 -0
  186. package/dist/hooks/command_not_found/handle-invalid-commands.d.ts +7 -0
  187. package/dist/hooks/command_not_found/handle-invalid-commands.js +32 -0
  188. package/dist/hooks/error/clean-errors.d.ts +7 -0
  189. package/dist/hooks/error/clean-errors.js +50 -0
  190. package/dist/hooks/init/welcome.js +72 -1
  191. package/dist/hooks/prerun/validate-brv-config-version.d.ts +28 -0
  192. package/dist/hooks/prerun/validate-brv-config-version.js +43 -0
  193. package/dist/infra/cipher/agent-service-factory.d.ts +86 -0
  194. package/dist/infra/cipher/agent-service-factory.js +212 -0
  195. package/dist/infra/cipher/blob/blob-storage-factory.d.ts +13 -0
  196. package/dist/infra/cipher/blob/blob-storage-factory.js +14 -0
  197. package/dist/infra/cipher/blob/index.d.ts +10 -0
  198. package/dist/infra/cipher/blob/index.js +12 -0
  199. package/dist/infra/cipher/blob/migrations.d.ts +63 -0
  200. package/dist/infra/cipher/blob/migrations.js +148 -0
  201. package/dist/infra/cipher/blob/sqlite-blob-storage.d.ts +82 -0
  202. package/dist/infra/cipher/blob/sqlite-blob-storage.js +307 -0
  203. package/dist/infra/cipher/cipher-agent-state-manager.d.ts +63 -0
  204. package/dist/infra/cipher/cipher-agent-state-manager.js +108 -0
  205. package/dist/infra/cipher/cipher-agent.d.ts +182 -0
  206. package/dist/infra/cipher/cipher-agent.js +317 -0
  207. package/dist/infra/cipher/command-parser.d.ts +23 -0
  208. package/dist/infra/cipher/command-parser.js +85 -0
  209. package/dist/infra/cipher/display/todo-display.d.ts +23 -0
  210. package/dist/infra/cipher/display/todo-display.js +129 -0
  211. package/dist/infra/cipher/events/event-emitter.d.ts +137 -0
  212. package/dist/infra/cipher/events/event-emitter.js +158 -0
  213. package/dist/infra/cipher/exit-codes.d.ts +44 -0
  214. package/dist/infra/cipher/exit-codes.js +58 -0
  215. package/dist/infra/cipher/file-system/file-system-service.d.ts +105 -0
  216. package/dist/infra/cipher/file-system/file-system-service.js +641 -0
  217. package/dist/infra/cipher/file-system/gitignore-filter.d.ts +77 -0
  218. package/dist/infra/cipher/file-system/gitignore-filter.js +120 -0
  219. package/dist/infra/cipher/file-system/glob-utils.d.ts +60 -0
  220. package/dist/infra/cipher/file-system/glob-utils.js +120 -0
  221. package/dist/infra/cipher/file-system/path-validator.d.ts +69 -0
  222. package/dist/infra/cipher/file-system/path-validator.js +184 -0
  223. package/dist/infra/cipher/grpc/internal-llm-grpc-service.d.ts +149 -0
  224. package/dist/infra/cipher/grpc/internal-llm-grpc-service.js +364 -0
  225. package/dist/infra/cipher/grpc/internal-llm-grpc.proto +94 -0
  226. package/dist/infra/cipher/interactive-commands.d.ts +16 -0
  227. package/dist/infra/cipher/interactive-commands.js +198 -0
  228. package/dist/infra/cipher/interactive-loop.d.ts +24 -0
  229. package/dist/infra/cipher/interactive-loop.js +352 -0
  230. package/dist/infra/cipher/llm/context/async-mutex.d.ts +59 -0
  231. package/dist/infra/cipher/llm/context/async-mutex.js +92 -0
  232. package/dist/infra/cipher/llm/context/compression/index.d.ts +6 -0
  233. package/dist/infra/cipher/llm/context/compression/index.js +5 -0
  234. package/dist/infra/cipher/llm/context/compression/middle-removal.d.ts +40 -0
  235. package/dist/infra/cipher/llm/context/compression/middle-removal.js +76 -0
  236. package/dist/infra/cipher/llm/context/compression/oldest-removal.d.ts +38 -0
  237. package/dist/infra/cipher/llm/context/compression/oldest-removal.js +53 -0
  238. package/dist/infra/cipher/llm/context/compression/types.d.ts +36 -0
  239. package/dist/infra/cipher/llm/context/compression/types.js +1 -0
  240. package/dist/infra/cipher/llm/context/context-manager.d.ts +234 -0
  241. package/dist/infra/cipher/llm/context/context-manager.js +419 -0
  242. package/dist/infra/cipher/llm/context/index.d.ts +2 -0
  243. package/dist/infra/cipher/llm/context/index.js +2 -0
  244. package/dist/infra/cipher/llm/context/loop-detector.d.ts +125 -0
  245. package/dist/infra/cipher/llm/context/loop-detector.js +194 -0
  246. package/dist/infra/cipher/llm/context/utils.d.ts +17 -0
  247. package/dist/infra/cipher/llm/context/utils.js +89 -0
  248. package/dist/infra/cipher/llm/formatters/claude-formatter.d.ts +54 -0
  249. package/dist/infra/cipher/llm/formatters/claude-formatter.js +182 -0
  250. package/dist/infra/cipher/llm/formatters/gemini-formatter.d.ts +69 -0
  251. package/dist/infra/cipher/llm/formatters/gemini-formatter.js +253 -0
  252. package/dist/infra/cipher/llm/formatters/openrouter-formatter.d.ts +47 -0
  253. package/dist/infra/cipher/llm/formatters/openrouter-formatter.js +238 -0
  254. package/dist/infra/cipher/llm/generators/byterover-content-generator.d.ts +92 -0
  255. package/dist/infra/cipher/llm/generators/byterover-content-generator.js +211 -0
  256. package/dist/infra/cipher/llm/generators/index.d.ts +13 -0
  257. package/dist/infra/cipher/llm/generators/index.js +13 -0
  258. package/dist/infra/cipher/llm/generators/logging-content-generator.d.ts +104 -0
  259. package/dist/infra/cipher/llm/generators/logging-content-generator.js +182 -0
  260. package/dist/infra/cipher/llm/generators/openrouter-content-generator.d.ts +93 -0
  261. package/dist/infra/cipher/llm/generators/openrouter-content-generator.js +254 -0
  262. package/dist/infra/cipher/llm/generators/retryable-content-generator.d.ts +90 -0
  263. package/dist/infra/cipher/llm/generators/retryable-content-generator.js +157 -0
  264. package/dist/infra/cipher/llm/index.d.ts +9 -0
  265. package/dist/infra/cipher/llm/index.js +13 -0
  266. package/dist/infra/cipher/llm/internal-llm-service.d.ts +308 -0
  267. package/dist/infra/cipher/llm/internal-llm-service.js +724 -0
  268. package/dist/infra/cipher/llm/openrouter-llm-service.d.ts +183 -0
  269. package/dist/infra/cipher/llm/openrouter-llm-service.js +386 -0
  270. package/dist/infra/cipher/llm/response-validator.d.ts +89 -0
  271. package/dist/infra/cipher/llm/response-validator.js +157 -0
  272. package/dist/infra/cipher/llm/retry/index.d.ts +10 -0
  273. package/dist/infra/cipher/llm/retry/index.js +10 -0
  274. package/dist/infra/cipher/llm/retry/retry-policy.d.ts +74 -0
  275. package/dist/infra/cipher/llm/retry/retry-policy.js +146 -0
  276. package/dist/infra/cipher/llm/retry/retry-with-backoff.d.ts +113 -0
  277. package/dist/infra/cipher/llm/retry/retry-with-backoff.js +247 -0
  278. package/dist/infra/cipher/llm/thought-parser.d.ts +145 -0
  279. package/dist/infra/cipher/llm/thought-parser.js +190 -0
  280. package/dist/infra/cipher/llm/tokenizers/claude-tokenizer.d.ts +47 -0
  281. package/dist/infra/cipher/llm/tokenizers/claude-tokenizer.js +55 -0
  282. package/dist/infra/cipher/llm/tokenizers/default-tokenizer.d.ts +31 -0
  283. package/dist/infra/cipher/llm/tokenizers/default-tokenizer.js +38 -0
  284. package/dist/infra/cipher/llm/tokenizers/gemini-tokenizer.d.ts +37 -0
  285. package/dist/infra/cipher/llm/tokenizers/gemini-tokenizer.js +45 -0
  286. package/dist/infra/cipher/llm/tokenizers/openrouter-tokenizer.d.ts +29 -0
  287. package/dist/infra/cipher/llm/tokenizers/openrouter-tokenizer.js +37 -0
  288. package/dist/infra/cipher/llm/tool-output-processor.d.ts +117 -0
  289. package/dist/infra/cipher/llm/tool-output-processor.js +153 -0
  290. package/dist/infra/cipher/logger/console-logger.d.ts +42 -0
  291. package/dist/infra/cipher/logger/console-logger.js +63 -0
  292. package/dist/infra/cipher/logger/event-based-logger.d.ts +54 -0
  293. package/dist/infra/cipher/logger/event-based-logger.js +92 -0
  294. package/dist/infra/cipher/memory/index.d.ts +6 -0
  295. package/dist/infra/cipher/memory/index.js +7 -0
  296. package/dist/infra/cipher/memory/memory-manager.d.ts +136 -0
  297. package/dist/infra/cipher/memory/memory-manager.js +523 -0
  298. package/dist/infra/cipher/parsers/coding-agent-log-parser.d.ts +24 -0
  299. package/dist/infra/cipher/parsers/coding-agent-log-parser.js +51 -0
  300. package/dist/infra/cipher/process/command-validator.d.ts +59 -0
  301. package/dist/infra/cipher/process/command-validator.js +266 -0
  302. package/dist/infra/cipher/process/index.d.ts +8 -0
  303. package/dist/infra/cipher/process/index.js +8 -0
  304. package/dist/infra/cipher/process/process-service.d.ts +95 -0
  305. package/dist/infra/cipher/process/process-service.js +439 -0
  306. package/dist/infra/cipher/session/chat-session.d.ts +80 -0
  307. package/dist/infra/cipher/session/chat-session.js +165 -0
  308. package/dist/infra/cipher/session/index.d.ts +6 -0
  309. package/dist/infra/cipher/session/index.js +5 -0
  310. package/dist/infra/cipher/session/session-event-forwarder.d.ts +37 -0
  311. package/dist/infra/cipher/session/session-event-forwarder.js +83 -0
  312. package/dist/infra/cipher/session/session-manager.d.ts +109 -0
  313. package/dist/infra/cipher/session/session-manager.js +172 -0
  314. package/dist/infra/cipher/storage/blob-history-storage.d.ts +76 -0
  315. package/dist/infra/cipher/storage/blob-history-storage.js +178 -0
  316. package/dist/infra/cipher/system-prompt/simple-prompt-factory.d.ts +105 -0
  317. package/dist/infra/cipher/system-prompt/simple-prompt-factory.js +290 -0
  318. package/dist/infra/cipher/tools/core-tool-scheduler.d.ts +99 -0
  319. package/dist/infra/cipher/tools/core-tool-scheduler.js +161 -0
  320. package/dist/infra/cipher/tools/default-policy-rules.d.ts +26 -0
  321. package/dist/infra/cipher/tools/default-policy-rules.js +125 -0
  322. package/dist/infra/cipher/tools/implementations/bash-exec-tool.d.ts +12 -0
  323. package/dist/infra/cipher/tools/implementations/bash-exec-tool.js +93 -0
  324. package/dist/infra/cipher/tools/implementations/bash-output-tool.d.ts +12 -0
  325. package/dist/infra/cipher/tools/implementations/bash-output-tool.js +47 -0
  326. package/dist/infra/cipher/tools/implementations/create-knowledge-topic-tool.d.ts +11 -0
  327. package/dist/infra/cipher/tools/implementations/create-knowledge-topic-tool.js +142 -0
  328. package/dist/infra/cipher/tools/implementations/delete-memory-tool.d.ts +12 -0
  329. package/dist/infra/cipher/tools/implementations/delete-memory-tool.js +37 -0
  330. package/dist/infra/cipher/tools/implementations/detect-domains-tool.d.ts +7 -0
  331. package/dist/infra/cipher/tools/implementations/detect-domains-tool.js +73 -0
  332. package/dist/infra/cipher/tools/implementations/edit-file-tool.d.ts +13 -0
  333. package/dist/infra/cipher/tools/implementations/edit-file-tool.js +50 -0
  334. package/dist/infra/cipher/tools/implementations/edit-memory-tool.d.ts +13 -0
  335. package/dist/infra/cipher/tools/implementations/edit-memory-tool.js +53 -0
  336. package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.d.ts +7 -0
  337. package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.js +421 -0
  338. package/dist/infra/cipher/tools/implementations/glob-files-tool.d.ts +18 -0
  339. package/dist/infra/cipher/tools/implementations/glob-files-tool.js +70 -0
  340. package/dist/infra/cipher/tools/implementations/grep-content-tool.d.ts +12 -0
  341. package/dist/infra/cipher/tools/implementations/grep-content-tool.js +77 -0
  342. package/dist/infra/cipher/tools/implementations/kill-process-tool.d.ts +12 -0
  343. package/dist/infra/cipher/tools/implementations/kill-process-tool.js +55 -0
  344. package/dist/infra/cipher/tools/implementations/list-memories-tool.d.ts +12 -0
  345. package/dist/infra/cipher/tools/implementations/list-memories-tool.js +63 -0
  346. package/dist/infra/cipher/tools/implementations/read-file-tool.d.ts +12 -0
  347. package/dist/infra/cipher/tools/implementations/read-file-tool.js +54 -0
  348. package/dist/infra/cipher/tools/implementations/read-memory-tool.d.ts +12 -0
  349. package/dist/infra/cipher/tools/implementations/read-memory-tool.js +39 -0
  350. package/dist/infra/cipher/tools/implementations/search-history-tool.d.ts +10 -0
  351. package/dist/infra/cipher/tools/implementations/search-history-tool.js +36 -0
  352. package/dist/infra/cipher/tools/implementations/write-file-tool.d.ts +12 -0
  353. package/dist/infra/cipher/tools/implementations/write-file-tool.js +52 -0
  354. package/dist/infra/cipher/tools/implementations/write-memory-tool.d.ts +13 -0
  355. package/dist/infra/cipher/tools/implementations/write-memory-tool.js +52 -0
  356. package/dist/infra/cipher/tools/implementations/write-todos-tool.d.ts +10 -0
  357. package/dist/infra/cipher/tools/implementations/write-todos-tool.js +165 -0
  358. package/dist/infra/cipher/tools/index.d.ts +18 -0
  359. package/dist/infra/cipher/tools/index.js +19 -0
  360. package/dist/infra/cipher/tools/policy-engine.d.ts +80 -0
  361. package/dist/infra/cipher/tools/policy-engine.js +110 -0
  362. package/dist/infra/cipher/tools/tool-invocation-queue.d.ts +191 -0
  363. package/dist/infra/cipher/tools/tool-invocation-queue.js +254 -0
  364. package/dist/infra/cipher/tools/tool-invocation.d.ts +216 -0
  365. package/dist/infra/cipher/tools/tool-invocation.js +294 -0
  366. package/dist/infra/cipher/tools/tool-manager.d.ts +135 -0
  367. package/dist/infra/cipher/tools/tool-manager.js +209 -0
  368. package/dist/infra/cipher/tools/tool-markers.d.ts +48 -0
  369. package/dist/infra/cipher/tools/tool-markers.js +49 -0
  370. package/dist/infra/cipher/tools/tool-provider.d.ts +77 -0
  371. package/dist/infra/cipher/tools/tool-provider.js +196 -0
  372. package/dist/infra/cipher/tools/tool-registry.d.ts +52 -0
  373. package/dist/infra/cipher/tools/tool-registry.js +144 -0
  374. package/dist/infra/cipher/tools/utils/schema-converter.d.ts +10 -0
  375. package/dist/infra/cipher/tools/utils/schema-converter.js +29 -0
  376. package/dist/infra/cipher/validation/workspace-validator.d.ts +19 -0
  377. package/dist/infra/cipher/validation/workspace-validator.js +37 -0
  378. package/dist/infra/cipher/watcher/coding-agent-log-watcher.d.ts +14 -0
  379. package/dist/infra/cipher/watcher/coding-agent-log-watcher.js +55 -0
  380. package/dist/infra/cogit/context-tree-to-push-context-mapper.d.ts +21 -0
  381. package/dist/infra/cogit/context-tree-to-push-context-mapper.js +32 -0
  382. package/dist/infra/cogit/http-cogit-pull-service.d.ts +15 -0
  383. package/dist/infra/cogit/http-cogit-pull-service.js +30 -0
  384. package/dist/infra/cogit/http-cogit-push-service.d.ts +17 -0
  385. package/dist/infra/cogit/http-cogit-push-service.js +104 -0
  386. package/dist/infra/config/file-config-store.js +9 -3
  387. package/dist/infra/context-tree/file-context-file-reader.d.ts +14 -0
  388. package/dist/infra/context-tree/file-context-file-reader.js +46 -0
  389. package/dist/infra/context-tree/file-context-tree-service.d.ts +14 -0
  390. package/dist/infra/context-tree/file-context-tree-service.js +46 -0
  391. package/dist/infra/context-tree/file-context-tree-snapshot-service.d.ts +34 -0
  392. package/dist/infra/context-tree/file-context-tree-snapshot-service.js +117 -0
  393. package/dist/infra/context-tree/file-context-tree-writer-service.d.ts +22 -0
  394. package/dist/infra/context-tree/file-context-tree-writer-service.js +61 -0
  395. package/dist/infra/memory/http-memory-retrieval-service.js +2 -1
  396. package/dist/infra/memory/http-memory-storage-service.js +4 -3
  397. package/dist/infra/parsers/clean/clean-claude-service.d.ts +111 -0
  398. package/dist/infra/parsers/clean/clean-claude-service.js +271 -0
  399. package/dist/infra/parsers/clean/clean-codex-service.d.ts +231 -0
  400. package/dist/infra/parsers/clean/clean-codex-service.js +534 -0
  401. package/dist/infra/parsers/clean/clean-copilot-service.d.ts +255 -0
  402. package/dist/infra/parsers/clean/clean-copilot-service.js +729 -0
  403. package/dist/infra/parsers/clean/clean-cursor-service.d.ts +161 -0
  404. package/dist/infra/parsers/clean/clean-cursor-service.js +432 -0
  405. package/dist/infra/parsers/clean/clean-parser-service-factory.d.ts +54 -0
  406. package/dist/infra/parsers/clean/clean-parser-service-factory.js +80 -0
  407. package/dist/infra/parsers/clean/shared.d.ts +84 -0
  408. package/dist/infra/parsers/clean/shared.js +273 -0
  409. package/dist/infra/parsers/raw/raw-claude-service.d.ts +195 -0
  410. package/dist/infra/parsers/raw/raw-claude-service.js +548 -0
  411. package/dist/infra/parsers/raw/raw-codex-service.d.ts +313 -0
  412. package/dist/infra/parsers/raw/raw-codex-service.js +782 -0
  413. package/dist/infra/parsers/raw/raw-copilot-service.d.ts +196 -0
  414. package/dist/infra/parsers/raw/raw-copilot-service.js +558 -0
  415. package/dist/infra/parsers/raw/raw-cursor-service.d.ts +316 -0
  416. package/dist/infra/parsers/raw/raw-cursor-service.js +818 -0
  417. package/dist/infra/parsers/raw/raw-parser-service-factory.d.ts +54 -0
  418. package/dist/infra/parsers/raw/raw-parser-service-factory.js +81 -0
  419. package/dist/infra/rule/constants.d.ts +4 -0
  420. package/dist/infra/rule/constants.js +4 -0
  421. package/dist/infra/rule/rule-template-service.js +1 -1
  422. package/dist/infra/rule/rule-writer-service.js +1 -5
  423. package/dist/infra/space/http-space-service.js +2 -1
  424. package/dist/infra/team/http-team-service.js +2 -1
  425. package/dist/infra/user/http-user-service.js +2 -1
  426. package/dist/infra/watcher/file-watcher-service.d.ts +10 -0
  427. package/dist/infra/watcher/file-watcher-service.js +81 -0
  428. package/dist/infra/workspace/workspace-detector-service.d.ts +60 -0
  429. package/dist/infra/workspace/workspace-detector-service.js +165 -0
  430. package/dist/resources/prompts/curate-context-tree-curation.yml +48 -0
  431. package/dist/resources/prompts/modes/autonomous.yml +9 -0
  432. package/dist/resources/prompts/query-context-tree-retrieval.yml +49 -0
  433. package/dist/resources/prompts/reflection.yml +27 -0
  434. package/dist/resources/prompts/system-prompt.yml +82 -0
  435. package/dist/resources/prompts/tool-outputs.yml +30 -0
  436. package/dist/templates/README.md +6 -7
  437. package/dist/templates/sections/command-reference.md +40 -93
  438. package/dist/templates/sections/workflow.md +3 -30
  439. package/dist/utils/emoji-helpers.d.ts +38 -0
  440. package/dist/utils/emoji-helpers.js +42 -0
  441. package/dist/utils/error-handler.d.ts +51 -0
  442. package/dist/utils/error-handler.js +169 -0
  443. package/dist/utils/error-helpers.d.ts +30 -0
  444. package/dist/utils/error-helpers.js +47 -0
  445. package/dist/utils/file-helpers.d.ts +15 -0
  446. package/dist/utils/file-helpers.js +44 -0
  447. package/dist/utils/oclif-error-helpers.d.ts +40 -0
  448. package/dist/utils/oclif-error-helpers.js +46 -0
  449. package/dist/utils/tool-display-formatter.d.ts +53 -0
  450. package/dist/utils/tool-display-formatter.js +257 -0
  451. package/oclif.manifest.json +422 -142
  452. package/package.json +29 -10
  453. package/dist/commands/add.d.ts +0 -49
  454. package/dist/commands/add.js +0 -192
  455. package/dist/commands/complete.d.ts +0 -108
  456. package/dist/commands/complete.js +0 -340
  457. package/dist/commands/retrieve.d.ts +0 -26
  458. package/dist/commands/retrieve.js +0 -101
  459. package/dist/core/domain/entities/curator-output.d.ts +0 -14
  460. package/dist/core/domain/entities/curator-output.js +0 -23
  461. package/dist/core/domain/entities/delta-batch.d.ts +0 -30
  462. package/dist/core/domain/entities/delta-batch.js +0 -52
  463. package/dist/core/domain/entities/delta-operation.d.ts +0 -31
  464. package/dist/core/domain/entities/delta-operation.js +0 -50
  465. package/dist/core/domain/entities/executor-output.d.ts +0 -27
  466. package/dist/core/domain/entities/executor-output.js +0 -33
  467. package/dist/core/domain/entities/reflector-output.d.ts +0 -38
  468. package/dist/core/domain/entities/reflector-output.js +0 -44
  469. package/dist/core/interfaces/i-ace-prompt-builder.d.ts +0 -48
  470. package/dist/core/interfaces/i-bullet-content-store.d.ts +0 -36
  471. package/dist/core/interfaces/i-delta-store.d.ts +0 -15
  472. package/dist/core/interfaces/i-executor-output-store.d.ts +0 -14
  473. package/dist/core/interfaces/i-playbook-service.d.ts +0 -69
  474. package/dist/core/interfaces/i-playbook-store.d.ts +0 -38
  475. package/dist/core/interfaces/i-reflection-store.d.ts +0 -21
  476. package/dist/infra/ace/ace-file-utils.d.ts +0 -46
  477. package/dist/infra/ace/ace-file-utils.js +0 -83
  478. package/dist/infra/ace/ace-prompt-templates.d.ts +0 -13
  479. package/dist/infra/ace/ace-prompt-templates.js +0 -177
  480. package/dist/infra/ace/file-bullet-content-store.d.ts +0 -27
  481. package/dist/infra/ace/file-bullet-content-store.js +0 -89
  482. package/dist/infra/ace/file-delta-store.d.ts +0 -9
  483. package/dist/infra/ace/file-delta-store.js +0 -26
  484. package/dist/infra/ace/file-executor-output-store.d.ts +0 -9
  485. package/dist/infra/ace/file-executor-output-store.js +0 -26
  486. package/dist/infra/ace/file-playbook-store.d.ts +0 -29
  487. package/dist/infra/ace/file-playbook-store.js +0 -107
  488. package/dist/infra/ace/file-reflection-store.d.ts +0 -10
  489. package/dist/infra/ace/file-reflection-store.js +0 -55
  490. package/dist/infra/playbook/file-playbook-service.d.ts +0 -42
  491. package/dist/infra/playbook/file-playbook-service.js +0 -132
  492. /package/dist/core/{interfaces/i-ace-prompt-builder.js → domain/cipher/blob/types.js} +0 -0
  493. /package/dist/core/{interfaces/i-bullet-content-store.js → domain/cipher/file-system/types.js} +0 -0
  494. /package/dist/core/{interfaces/i-delta-store.js → domain/cipher/process/types.js} +0 -0
  495. /package/dist/core/{interfaces/i-executor-output-store.js → domain/cipher/session/types.js} +0 -0
  496. /package/dist/core/{interfaces/i-playbook-service.js → domain/cipher/storage/history-types.js} +0 -0
  497. /package/dist/core/{interfaces/i-playbook-store.js → domain/cipher/system-prompt/types.js} +0 -0
  498. /package/dist/core/{interfaces/i-reflection-store.js → domain/cipher/tools/types.js} +0 -0
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Result of filtering paths through gitignore rules.
3
+ */
4
+ export interface FilterResult {
5
+ /** Paths that passed the filter (not ignored) */
6
+ filtered: string[];
7
+ /** Number of paths that were ignored */
8
+ ignoredCount: number;
9
+ }
10
+ /**
11
+ * GitignoreFilter handles .gitignore-based file filtering.
12
+ *
13
+ * It reads .gitignore files from the project root and applies
14
+ * the ignore rules to filter out paths that should be excluded.
15
+ *
16
+ * Usage:
17
+ * ```typescript
18
+ * const filter = new GitignoreFilter('/path/to/project')
19
+ * await filter.initialize()
20
+ * const result = filter.filterPaths(['src/index.ts', 'node_modules/pkg/index.js'])
21
+ * // result.filtered = ['src/index.ts']
22
+ * // result.ignoredCount = 1
23
+ * ```
24
+ */
25
+ export declare class GitignoreFilter {
26
+ private ig;
27
+ private initialized;
28
+ private readonly rootPath;
29
+ /**
30
+ * Creates a new GitignoreFilter instance.
31
+ *
32
+ * @param rootPath - Root path of the project to search for .gitignore files
33
+ */
34
+ constructor(rootPath: string);
35
+ /**
36
+ * Filters an array of paths, removing those that match gitignore rules.
37
+ *
38
+ * @param relativePaths - Array of paths relative to the root to filter
39
+ * @returns FilterResult with filtered paths and ignored count
40
+ * @throws Error if filter not initialized
41
+ */
42
+ filterPaths(relativePaths: string[]): FilterResult;
43
+ /**
44
+ * Initializes the filter by reading .gitignore files.
45
+ * Must be called before using filterPaths or isIgnored.
46
+ *
47
+ * Reads:
48
+ * - .gitignore from the root path
49
+ * - Optionally could be extended to read nested .gitignore files
50
+ *
51
+ * Always adds common ignore patterns:
52
+ * - .git directory
53
+ */
54
+ initialize(): Promise<void>;
55
+ /**
56
+ * Checks if a single path is ignored by gitignore rules.
57
+ *
58
+ * @param relativePath - Path relative to the root to check
59
+ * @returns true if the path should be ignored
60
+ * @throws Error if filter not initialized
61
+ */
62
+ isIgnored(relativePath: string): boolean;
63
+ /**
64
+ * Checks if the filter has been initialized.
65
+ *
66
+ * @returns true if initialize() has been called
67
+ */
68
+ isInitialized(): boolean;
69
+ }
70
+ /**
71
+ * Creates and initializes a GitignoreFilter for the given path.
72
+ * Convenience function that combines construction and initialization.
73
+ *
74
+ * @param rootPath - Root path of the project
75
+ * @returns Initialized GitignoreFilter instance
76
+ */
77
+ export declare function createGitignoreFilter(rootPath: string): Promise<GitignoreFilter>;
@@ -0,0 +1,120 @@
1
+ import ignore from 'ignore';
2
+ import fs from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ /**
5
+ * GitignoreFilter handles .gitignore-based file filtering.
6
+ *
7
+ * It reads .gitignore files from the project root and applies
8
+ * the ignore rules to filter out paths that should be excluded.
9
+ *
10
+ * Usage:
11
+ * ```typescript
12
+ * const filter = new GitignoreFilter('/path/to/project')
13
+ * await filter.initialize()
14
+ * const result = filter.filterPaths(['src/index.ts', 'node_modules/pkg/index.js'])
15
+ * // result.filtered = ['src/index.ts']
16
+ * // result.ignoredCount = 1
17
+ * ```
18
+ */
19
+ export class GitignoreFilter {
20
+ ig;
21
+ initialized = false;
22
+ rootPath;
23
+ /**
24
+ * Creates a new GitignoreFilter instance.
25
+ *
26
+ * @param rootPath - Root path of the project to search for .gitignore files
27
+ */
28
+ constructor(rootPath) {
29
+ this.rootPath = rootPath;
30
+ this.ig = ignore();
31
+ }
32
+ /**
33
+ * Filters an array of paths, removing those that match gitignore rules.
34
+ *
35
+ * @param relativePaths - Array of paths relative to the root to filter
36
+ * @returns FilterResult with filtered paths and ignored count
37
+ * @throws Error if filter not initialized
38
+ */
39
+ filterPaths(relativePaths) {
40
+ if (!this.initialized) {
41
+ throw new Error('GitignoreFilter not initialized. Call initialize() first.');
42
+ }
43
+ const filtered = [];
44
+ let ignoredCount = 0;
45
+ for (const relativePath of relativePaths) {
46
+ // Normalize path separators
47
+ const normalizedPath = relativePath.split(path.sep).join('/');
48
+ if (this.ig.ignores(normalizedPath)) {
49
+ ignoredCount++;
50
+ }
51
+ else {
52
+ filtered.push(relativePath);
53
+ }
54
+ }
55
+ return { filtered, ignoredCount };
56
+ }
57
+ /**
58
+ * Initializes the filter by reading .gitignore files.
59
+ * Must be called before using filterPaths or isIgnored.
60
+ *
61
+ * Reads:
62
+ * - .gitignore from the root path
63
+ * - Optionally could be extended to read nested .gitignore files
64
+ *
65
+ * Always adds common ignore patterns:
66
+ * - .git directory
67
+ */
68
+ async initialize() {
69
+ if (this.initialized) {
70
+ return;
71
+ }
72
+ // Always ignore .git directory
73
+ this.ig.add('.git');
74
+ // Try to read .gitignore from root
75
+ const gitignorePath = path.join(this.rootPath, '.gitignore');
76
+ try {
77
+ const content = await fs.readFile(gitignorePath, 'utf8');
78
+ this.ig.add(content);
79
+ }
80
+ catch {
81
+ // .gitignore doesn't exist or can't be read, continue without it
82
+ }
83
+ this.initialized = true;
84
+ }
85
+ /**
86
+ * Checks if a single path is ignored by gitignore rules.
87
+ *
88
+ * @param relativePath - Path relative to the root to check
89
+ * @returns true if the path should be ignored
90
+ * @throws Error if filter not initialized
91
+ */
92
+ isIgnored(relativePath) {
93
+ if (!this.initialized) {
94
+ throw new Error('GitignoreFilter not initialized. Call initialize() first.');
95
+ }
96
+ // Normalize path separators for cross-platform compatibility
97
+ const normalizedPath = relativePath.split(path.sep).join('/');
98
+ return this.ig.ignores(normalizedPath);
99
+ }
100
+ /**
101
+ * Checks if the filter has been initialized.
102
+ *
103
+ * @returns true if initialize() has been called
104
+ */
105
+ isInitialized() {
106
+ return this.initialized;
107
+ }
108
+ }
109
+ /**
110
+ * Creates and initializes a GitignoreFilter for the given path.
111
+ * Convenience function that combines construction and initialization.
112
+ *
113
+ * @param rootPath - Root path of the project
114
+ * @returns Initialized GitignoreFilter instance
115
+ */
116
+ export async function createGitignoreFilter(rootPath) {
117
+ const filter = new GitignoreFilter(rootPath);
118
+ await filter.initialize();
119
+ return filter;
120
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * File metadata for sorting purposes.
3
+ */
4
+ export interface FileMetadata {
5
+ modifiedTime: Date;
6
+ path: string;
7
+ size: number;
8
+ }
9
+ /**
10
+ * Default recency threshold: 24 hours in milliseconds.
11
+ * Files modified within this period are considered "recent".
12
+ */
13
+ export declare const RECENCY_THRESHOLD_MS: number;
14
+ /**
15
+ * Collects metadata for a list of file paths.
16
+ *
17
+ * @param filePaths - Array of file paths to collect metadata for
18
+ * @param basePath - Base path for resolving relative paths
19
+ * @returns Promise resolving to array of FileMetadata objects
20
+ */
21
+ export declare function collectFileMetadata(filePaths: string[], basePath: string): Promise<FileMetadata[]>;
22
+ /**
23
+ * Sorts files by recency with smart ordering:
24
+ * - Files modified within the recency threshold come first (newest to oldest)
25
+ * - Older files are sorted alphabetically
26
+ *
27
+ * This approach prioritizes recently modified files for developer convenience
28
+ * while maintaining predictable ordering for older files.
29
+ *
30
+ * @param files - Array of FileMetadata to sort
31
+ * @param recencyThresholdMs - Threshold in ms for considering a file "recent" (default: 24 hours)
32
+ * @returns Sorted array of FileMetadata
33
+ */
34
+ export declare function sortFilesByRecency(files: FileMetadata[], recencyThresholdMs?: number): FileMetadata[];
35
+ /**
36
+ * Escapes a pattern if it matches an actual file/directory.
37
+ *
38
+ * This handles edge cases where file/directory names contain glob special characters
39
+ * (e.g., `[test]`, `(dashboard)`, `file?.txt`). If the pattern exactly matches
40
+ * an existing path, we escape it to prevent glob interpretation.
41
+ *
42
+ * @param pattern - The glob pattern to potentially escape
43
+ * @param cwd - Current working directory for checking file existence
44
+ * @returns The pattern, escaped if it matches an existing file
45
+ */
46
+ export declare function escapeIfExactMatch(pattern: string, cwd: string): Promise<string>;
47
+ /**
48
+ * Escapes glob special characters in a string.
49
+ *
50
+ * @param str - String to escape
51
+ * @returns Escaped string safe for use in glob patterns
52
+ */
53
+ export declare function escapeGlobCharacters(str: string): string;
54
+ /**
55
+ * Extracts paths from FileMetadata array.
56
+ *
57
+ * @param files - Array of FileMetadata
58
+ * @returns Array of file paths
59
+ */
60
+ export declare function extractPaths(files: FileMetadata[]): string[];
@@ -0,0 +1,120 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ /**
4
+ * Default recency threshold: 24 hours in milliseconds.
5
+ * Files modified within this period are considered "recent".
6
+ */
7
+ export const RECENCY_THRESHOLD_MS = 24 * 60 * 60 * 1000;
8
+ /**
9
+ * Collects metadata for a list of file paths.
10
+ *
11
+ * @param filePaths - Array of file paths to collect metadata for
12
+ * @param basePath - Base path for resolving relative paths
13
+ * @returns Promise resolving to array of FileMetadata objects
14
+ */
15
+ export async function collectFileMetadata(filePaths, basePath) {
16
+ const results = [];
17
+ for (const filePath of filePaths) {
18
+ try {
19
+ const fullPath = path.isAbsolute(filePath) ? filePath : path.join(basePath, filePath);
20
+ // eslint-disable-next-line no-await-in-loop
21
+ const stats = await fs.stat(fullPath);
22
+ results.push({
23
+ modifiedTime: stats.mtime,
24
+ path: filePath,
25
+ size: stats.size,
26
+ });
27
+ }
28
+ catch {
29
+ // If we can't stat the file, include it with default metadata
30
+ results.push({
31
+ modifiedTime: new Date(0),
32
+ path: filePath,
33
+ size: 0,
34
+ });
35
+ }
36
+ }
37
+ return results;
38
+ }
39
+ /**
40
+ * Sorts files by recency with smart ordering:
41
+ * - Files modified within the recency threshold come first (newest to oldest)
42
+ * - Older files are sorted alphabetically
43
+ *
44
+ * This approach prioritizes recently modified files for developer convenience
45
+ * while maintaining predictable ordering for older files.
46
+ *
47
+ * @param files - Array of FileMetadata to sort
48
+ * @param recencyThresholdMs - Threshold in ms for considering a file "recent" (default: 24 hours)
49
+ * @returns Sorted array of FileMetadata
50
+ */
51
+ export function sortFilesByRecency(files, recencyThresholdMs = RECENCY_THRESHOLD_MS) {
52
+ const now = Date.now();
53
+ const threshold = now - recencyThresholdMs;
54
+ // Partition files into recent and old
55
+ const recentFiles = [];
56
+ const oldFiles = [];
57
+ for (const file of files) {
58
+ if (file.modifiedTime.getTime() >= threshold) {
59
+ recentFiles.push(file);
60
+ }
61
+ else {
62
+ oldFiles.push(file);
63
+ }
64
+ }
65
+ // Sort recent files by modification time (newest first)
66
+ recentFiles.sort((a, b) => b.modifiedTime.getTime() - a.modifiedTime.getTime());
67
+ // Sort old files alphabetically by path
68
+ oldFiles.sort((a, b) => a.path.localeCompare(b.path));
69
+ return [...recentFiles, ...oldFiles];
70
+ }
71
+ /**
72
+ * Glob special characters that need escaping.
73
+ */
74
+ const GLOB_SPECIAL_CHARS = /[*?[\]{}()!@#]/;
75
+ /**
76
+ * Escapes a pattern if it matches an actual file/directory.
77
+ *
78
+ * This handles edge cases where file/directory names contain glob special characters
79
+ * (e.g., `[test]`, `(dashboard)`, `file?.txt`). If the pattern exactly matches
80
+ * an existing path, we escape it to prevent glob interpretation.
81
+ *
82
+ * @param pattern - The glob pattern to potentially escape
83
+ * @param cwd - Current working directory for checking file existence
84
+ * @returns The pattern, escaped if it matches an existing file
85
+ */
86
+ export async function escapeIfExactMatch(pattern, cwd) {
87
+ // If pattern doesn't contain special characters, no escaping needed
88
+ if (!GLOB_SPECIAL_CHARS.test(pattern)) {
89
+ return pattern;
90
+ }
91
+ // Check if the pattern exactly matches a file or directory
92
+ const fullPath = path.isAbsolute(pattern) ? pattern : path.join(cwd, pattern);
93
+ try {
94
+ await fs.access(fullPath);
95
+ // File/directory exists, escape special characters
96
+ return escapeGlobCharacters(pattern);
97
+ }
98
+ catch {
99
+ // File doesn't exist, treat as glob pattern
100
+ return pattern;
101
+ }
102
+ }
103
+ /**
104
+ * Escapes glob special characters in a string.
105
+ *
106
+ * @param str - String to escape
107
+ * @returns Escaped string safe for use in glob patterns
108
+ */
109
+ export function escapeGlobCharacters(str) {
110
+ return str.replaceAll(/([*?[\]{}()!@#])/g, String.raw `\$1`);
111
+ }
112
+ /**
113
+ * Extracts paths from FileMetadata array.
114
+ *
115
+ * @param files - Array of FileMetadata
116
+ * @returns Array of file paths
117
+ */
118
+ export function extractPaths(files) {
119
+ return files.map((f) => f.path);
120
+ }
@@ -0,0 +1,69 @@
1
+ import type { FileSystemConfig, ValidationResult } from '../../../core/domain/cipher/file-system/types.js';
2
+ /**
3
+ * Validates file paths against security policies.
4
+ * Implements defense-in-depth with multiple layers of validation:
5
+ * 1. Empty path check
6
+ * 2. Path normalization
7
+ * 3. Path traversal detection
8
+ * 4. Allowed paths whitelist
9
+ * 5. Blocked paths blacklist
10
+ * 6. File extension validation
11
+ */
12
+ export declare class PathValidator {
13
+ private readonly blockedExtensions;
14
+ private readonly normalizedAllowedPaths;
15
+ private readonly normalizedBlockedPaths;
16
+ private readonly workingDirectory;
17
+ /**
18
+ * Creates a new path validator
19
+ * @param config - File system configuration
20
+ */
21
+ constructor(config: FileSystemConfig);
22
+ /**
23
+ * Validates a file path against all security policies.
24
+ *
25
+ * @param filePath - Path to validate
26
+ * @param operation - Operation type ('read' or 'write')
27
+ * @returns Validation result with normalized path or error message
28
+ */
29
+ validate(filePath: string, operation: 'read' | 'write'): ValidationResult;
30
+ /**
31
+ * Checks if a file has a blocked extension.
32
+ *
33
+ * @param filePath - File path to check
34
+ * @returns True if extension is blocked
35
+ */
36
+ private hasBlockedExtension;
37
+ /**
38
+ * Checks if a path is within the allowed paths.
39
+ *
40
+ * @param normalizedPath - Normalized absolute path
41
+ * @returns True if path is allowed
42
+ */
43
+ private isPathAllowed;
44
+ /**
45
+ * Checks if a path matches any blocked path patterns.
46
+ * Supports both absolute and relative blocked paths.
47
+ *
48
+ * @param normalizedPath - Normalized absolute path
49
+ * @returns Error message if blocked, false if not blocked
50
+ */
51
+ private isPathBlocked;
52
+ /**
53
+ * Checks if a path contains path traversal attempts.
54
+ * Detects both explicit traversal sequences and resolved paths outside working directory.
55
+ *
56
+ * @param originalPath - Original path provided by user
57
+ * @param normalizedPath - Normalized absolute path
58
+ * @returns True if path traversal detected
59
+ */
60
+ private isPathTraversal;
61
+ /**
62
+ * Normalizes and resolves a file path to an absolute path.
63
+ * Uses realpath to resolve symlinks if the path exists.
64
+ *
65
+ * @param filePath - Path to normalize
66
+ * @returns Normalized absolute path
67
+ */
68
+ private normalizeAndResolve;
69
+ }
@@ -0,0 +1,184 @@
1
+ import { realpathSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { getErrorMessage } from '../../../utils/error-helpers.js';
4
+ /**
5
+ * Validates file paths against security policies.
6
+ * Implements defense-in-depth with multiple layers of validation:
7
+ * 1. Empty path check
8
+ * 2. Path normalization
9
+ * 3. Path traversal detection
10
+ * 4. Allowed paths whitelist
11
+ * 5. Blocked paths blacklist
12
+ * 6. File extension validation
13
+ */
14
+ export class PathValidator {
15
+ blockedExtensions;
16
+ normalizedAllowedPaths;
17
+ normalizedBlockedPaths;
18
+ workingDirectory;
19
+ /**
20
+ * Creates a new path validator
21
+ * @param config - File system configuration
22
+ */
23
+ constructor(config) {
24
+ this.workingDirectory = path.resolve(config.workingDirectory);
25
+ this.blockedExtensions = new Set(config.blockedExtensions.map((ext) => ext.toLowerCase()));
26
+ // Normalize and resolve all allowed paths to absolute paths
27
+ this.normalizedAllowedPaths = config.allowedPaths.map((allowedPath) => path.resolve(this.workingDirectory, allowedPath));
28
+ // Normalize blocked paths
29
+ this.normalizedBlockedPaths = config.blockedPaths.map((blockedPath) => path.isAbsolute(blockedPath) ? path.normalize(blockedPath) : blockedPath);
30
+ }
31
+ /**
32
+ * Validates a file path against all security policies.
33
+ *
34
+ * @param filePath - Path to validate
35
+ * @param operation - Operation type ('read' or 'write')
36
+ * @returns Validation result with normalized path or error message
37
+ */
38
+ validate(filePath, operation) {
39
+ // 1. Check for empty path
40
+ if (!filePath || filePath.trim().length === 0) {
41
+ return {
42
+ error: 'Path cannot be empty',
43
+ valid: false,
44
+ };
45
+ }
46
+ // 2. Normalize and resolve the path
47
+ let normalizedPath;
48
+ try {
49
+ normalizedPath = this.normalizeAndResolve(filePath);
50
+ }
51
+ catch (error) {
52
+ return {
53
+ error: `Failed to resolve path: ${getErrorMessage(error)}`,
54
+ valid: false,
55
+ };
56
+ }
57
+ // 3. Check for path traversal
58
+ if (this.isPathTraversal(filePath, normalizedPath)) {
59
+ return {
60
+ error: 'Path traversal detected',
61
+ valid: false,
62
+ };
63
+ }
64
+ // 4. Check if path is in allowed paths
65
+ if (!this.isPathAllowed(normalizedPath)) {
66
+ return {
67
+ error: `Path not in allowed paths. Allowed: ${this.normalizedAllowedPaths.join(', ')}`,
68
+ valid: false,
69
+ };
70
+ }
71
+ // 5. Check if path is blocked
72
+ const blockReason = this.isPathBlocked(normalizedPath);
73
+ if (blockReason) {
74
+ return {
75
+ error: blockReason,
76
+ valid: false,
77
+ };
78
+ }
79
+ // 6. Check file extension (only for write operations to prevent creating dangerous files)
80
+ if (operation === 'write' && this.hasBlockedExtension(filePath)) {
81
+ const ext = path.extname(filePath).toLowerCase();
82
+ return {
83
+ error: `File extension blocked: ${ext}`,
84
+ valid: false,
85
+ };
86
+ }
87
+ return {
88
+ normalizedPath,
89
+ valid: true,
90
+ };
91
+ }
92
+ /**
93
+ * Checks if a file has a blocked extension.
94
+ *
95
+ * @param filePath - File path to check
96
+ * @returns True if extension is blocked
97
+ */
98
+ hasBlockedExtension(filePath) {
99
+ const ext = path.extname(filePath).toLowerCase();
100
+ return this.blockedExtensions.has(ext);
101
+ }
102
+ /**
103
+ * Checks if a path is within the allowed paths.
104
+ *
105
+ * @param normalizedPath - Normalized absolute path
106
+ * @returns True if path is allowed
107
+ */
108
+ isPathAllowed(normalizedPath) {
109
+ return this.normalizedAllowedPaths.some((allowedPath) => {
110
+ const relative = path.relative(allowedPath, normalizedPath);
111
+ // Path is allowed if it's within the allowed path (doesn't start with ..)
112
+ return !relative.startsWith('..') && !path.isAbsolute(relative);
113
+ });
114
+ }
115
+ /**
116
+ * Checks if a path matches any blocked path patterns.
117
+ * Supports both absolute and relative blocked paths.
118
+ *
119
+ * @param normalizedPath - Normalized absolute path
120
+ * @returns Error message if blocked, false if not blocked
121
+ */
122
+ isPathBlocked(normalizedPath) {
123
+ // Check against all allowed path roots
124
+ for (const allowedRoot of this.normalizedAllowedPaths) {
125
+ for (const blocked of this.normalizedBlockedPaths) {
126
+ // If blocked path is absolute, check directly
127
+ if (path.isAbsolute(blocked)) {
128
+ const blockedFull = path.normalize(blocked);
129
+ if (normalizedPath === blockedFull || normalizedPath.startsWith(blockedFull + path.sep)) {
130
+ return `Within blocked directory: ${blocked}`;
131
+ }
132
+ }
133
+ else {
134
+ // If blocked path is relative, check against all allowed roots
135
+ const blockedFull = path.resolve(allowedRoot, blocked);
136
+ if (normalizedPath === blockedFull || normalizedPath.startsWith(blockedFull + path.sep)) {
137
+ return `Within blocked directory: ${blocked}`;
138
+ }
139
+ }
140
+ }
141
+ }
142
+ return false;
143
+ }
144
+ /**
145
+ * Checks if a path contains path traversal attempts.
146
+ * Detects both explicit traversal sequences and resolved paths outside working directory.
147
+ *
148
+ * @param originalPath - Original path provided by user
149
+ * @param normalizedPath - Normalized absolute path
150
+ * @returns True if path traversal detected
151
+ */
152
+ isPathTraversal(originalPath, normalizedPath) {
153
+ // Check for explicit traversal sequences
154
+ if (originalPath.includes('../') || originalPath.includes('..\\')) {
155
+ // Verify that the resolved path doesn't escape working directory
156
+ const relative = path.relative(this.workingDirectory, normalizedPath);
157
+ if (relative.startsWith('..') || path.isAbsolute(relative)) {
158
+ return true;
159
+ }
160
+ }
161
+ return false;
162
+ }
163
+ /**
164
+ * Normalizes and resolves a file path to an absolute path.
165
+ * Uses realpath to resolve symlinks if the path exists.
166
+ *
167
+ * @param filePath - Path to normalize
168
+ * @returns Normalized absolute path
169
+ */
170
+ normalizeAndResolve(filePath) {
171
+ // First resolve relative to working directory
172
+ let normalizedPath = path.resolve(this.workingDirectory, filePath);
173
+ // Try to resolve symlinks if path exists
174
+ try {
175
+ // Use native variant to preserve casing on Windows
176
+ normalizedPath = realpathSync.native(normalizedPath);
177
+ }
178
+ catch {
179
+ // Path doesn't exist yet (e.g., for writes) - use resolved path as-is
180
+ normalizedPath = path.normalize(normalizedPath);
181
+ }
182
+ return normalizedPath;
183
+ }
184
+ }