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.
- package/README.md +56 -56
- package/bin/dev.js +1 -1
- package/dist/commands/cipher-agent/run.d.ts +111 -0
- package/dist/commands/cipher-agent/run.js +493 -0
- package/dist/commands/cipher-agent/set-prompt.d.ts +14 -0
- package/dist/commands/cipher-agent/set-prompt.js +53 -0
- package/dist/commands/cipher-agent/show-prompt.d.ts +11 -0
- package/dist/commands/cipher-agent/show-prompt.js +48 -0
- package/dist/commands/clear.d.ts +6 -0
- package/dist/commands/clear.js +36 -15
- package/dist/commands/curate.d.ts +74 -0
- package/dist/commands/curate.js +396 -0
- package/dist/commands/foo.d.ts +12 -0
- package/dist/commands/foo.js +61 -0
- package/dist/commands/gen-rules.d.ts +3 -0
- package/dist/commands/gen-rules.js +39 -20
- package/dist/commands/init.d.ts +48 -3
- package/dist/commands/init.js +242 -70
- package/dist/commands/login.js +9 -4
- package/dist/commands/pull.d.ts +33 -0
- package/dist/commands/pull.js +115 -0
- package/dist/commands/push.d.ts +13 -13
- package/dist/commands/push.js +81 -101
- package/dist/commands/query.d.ts +63 -0
- package/dist/commands/query.js +349 -0
- package/dist/commands/space/list.d.ts +5 -2
- package/dist/commands/space/list.js +60 -56
- package/dist/commands/space/switch.d.ts +16 -0
- package/dist/commands/space/switch.js +102 -53
- package/dist/commands/status.d.ts +5 -2
- package/dist/commands/status.js +43 -33
- package/dist/commands/watch.d.ts +23 -0
- package/dist/commands/watch.js +171 -0
- package/dist/config/auth.config.js +14 -2
- package/dist/config/context-tree-domains.d.ts +12 -0
- package/dist/config/context-tree-domains.js +29 -0
- package/dist/config/environment.d.ts +6 -0
- package/dist/config/environment.js +9 -2
- package/dist/constants.d.ts +5 -0
- package/dist/constants.js +6 -0
- package/dist/core/domain/cipher/agent/agent-state-machine.d.ts +128 -0
- package/dist/core/domain/cipher/agent/agent-state-machine.js +183 -0
- package/dist/core/domain/cipher/agent/agent-state.d.ts +77 -0
- package/dist/core/domain/cipher/agent/agent-state.js +59 -0
- package/dist/core/domain/cipher/agent/index.d.ts +7 -0
- package/dist/core/domain/cipher/agent/index.js +7 -0
- package/dist/core/domain/cipher/agent-events/index.d.ts +8 -0
- package/dist/core/domain/cipher/agent-events/index.js +7 -0
- package/dist/core/domain/cipher/agent-events/types.d.ts +419 -0
- package/dist/core/domain/cipher/agent-events/types.js +42 -0
- package/dist/core/domain/cipher/blob/types.d.ts +108 -0
- package/dist/core/domain/cipher/errors/blob-error.d.ts +36 -0
- package/dist/core/domain/cipher/errors/blob-error.js +68 -0
- package/dist/core/domain/cipher/errors/file-system-error.d.ts +211 -0
- package/dist/core/domain/cipher/errors/file-system-error.js +291 -0
- package/dist/core/domain/cipher/errors/llm-error.d.ts +120 -0
- package/dist/core/domain/cipher/errors/llm-error.js +161 -0
- package/dist/core/domain/cipher/errors/memory-error.d.ts +35 -0
- package/dist/core/domain/cipher/errors/memory-error.js +62 -0
- package/dist/core/domain/cipher/errors/process-error-code.d.ts +97 -0
- package/dist/core/domain/cipher/errors/process-error-code.js +98 -0
- package/dist/core/domain/cipher/errors/process-error.d.ts +135 -0
- package/dist/core/domain/cipher/errors/process-error.js +173 -0
- package/dist/core/domain/cipher/errors/session-error.d.ts +56 -0
- package/dist/core/domain/cipher/errors/session-error.js +74 -0
- package/dist/core/domain/cipher/errors/tool-error.d.ts +57 -0
- package/dist/core/domain/cipher/errors/tool-error.js +81 -0
- package/dist/core/domain/cipher/file-system/types.d.ts +203 -0
- package/dist/core/domain/cipher/memory/types.d.ts +102 -0
- package/dist/core/domain/cipher/memory/types.js +4 -0
- package/dist/core/domain/cipher/parsed-interaction.d.ts +47 -0
- package/dist/core/domain/cipher/parsed-interaction.js +25 -0
- package/dist/core/domain/cipher/process/types.d.ts +286 -0
- package/dist/core/domain/cipher/session/types.d.ts +54 -0
- package/dist/core/domain/cipher/storage/history-types.d.ts +38 -0
- package/dist/core/domain/cipher/system-prompt/types.d.ts +131 -0
- package/dist/core/domain/cipher/todos/index.d.ts +4 -0
- package/dist/core/domain/cipher/todos/index.js +4 -0
- package/dist/core/domain/cipher/todos/types.d.ts +57 -0
- package/dist/core/domain/cipher/todos/types.js +5 -0
- package/dist/core/domain/cipher/tools/constants.d.ts +28 -0
- package/dist/core/domain/cipher/tools/constants.js +24 -0
- package/dist/core/domain/cipher/tools/tool-error.d.ts +183 -0
- package/dist/core/domain/cipher/tools/tool-error.js +246 -0
- package/dist/core/domain/cipher/tools/types.d.ts +145 -0
- package/dist/core/domain/entities/brv-config.d.ts +42 -6
- package/dist/core/domain/entities/brv-config.js +115 -17
- package/dist/core/domain/entities/cogit-push-context.d.ts +38 -0
- package/dist/core/domain/entities/cogit-push-context.js +91 -0
- package/dist/core/domain/entities/cogit-push-response.d.ts +20 -0
- package/dist/core/domain/entities/cogit-push-response.js +31 -0
- package/dist/core/domain/entities/cogit-snapshot-author.d.ts +24 -0
- package/dist/core/domain/entities/cogit-snapshot-author.js +39 -0
- package/dist/core/domain/entities/cogit-snapshot-file.d.ts +34 -0
- package/dist/core/domain/entities/cogit-snapshot-file.js +59 -0
- package/dist/core/domain/entities/cogit-snapshot.d.ts +31 -0
- package/dist/core/domain/entities/cogit-snapshot.js +58 -0
- package/dist/core/domain/entities/context-tree-index.d.ts +26 -0
- package/dist/core/domain/entities/context-tree-index.js +27 -0
- package/dist/core/domain/entities/context-tree-snapshot.d.ts +56 -0
- package/dist/core/domain/entities/context-tree-snapshot.js +83 -0
- package/dist/core/domain/entities/event.d.ts +1 -1
- package/dist/core/domain/entities/event.js +3 -1
- package/dist/core/domain/entities/parser.d.ts +567 -0
- package/dist/core/domain/entities/parser.js +10 -0
- package/dist/core/domain/entities/playbook.d.ts +2 -23
- package/dist/core/domain/entities/playbook.js +2 -70
- package/dist/core/domain/errors/brv-config-version-error.d.ts +16 -0
- package/dist/core/domain/errors/brv-config-version-error.js +21 -0
- package/dist/core/domain/knowledge/directory-manager.d.ts +80 -0
- package/dist/core/domain/knowledge/directory-manager.js +145 -0
- package/dist/core/domain/knowledge/markdown-writer.d.ts +18 -0
- package/dist/core/domain/knowledge/markdown-writer.js +18 -0
- package/dist/core/domain/knowledge/relation-parser.d.ts +90 -0
- package/dist/core/domain/knowledge/relation-parser.js +131 -0
- package/dist/core/interfaces/cipher/cipher-services.d.ts +71 -0
- package/dist/core/interfaces/cipher/cipher-services.js +1 -0
- package/dist/core/interfaces/cipher/i-blob-storage.d.ts +78 -0
- package/dist/core/interfaces/cipher/i-blob-storage.js +1 -0
- package/dist/core/interfaces/cipher/i-chat-session.d.ts +62 -0
- package/dist/core/interfaces/cipher/i-chat-session.js +1 -0
- package/dist/core/interfaces/cipher/i-cipher-agent.d.ts +88 -0
- package/dist/core/interfaces/cipher/i-cipher-agent.js +1 -0
- package/dist/core/interfaces/cipher/i-coding-agent-log-parser.d.ts +20 -0
- package/dist/core/interfaces/cipher/i-coding-agent-log-parser.js +1 -0
- package/dist/core/interfaces/cipher/i-coding-agent-log-watcher.d.ts +31 -0
- package/dist/core/interfaces/cipher/i-coding-agent-log-watcher.js +1 -0
- package/dist/core/interfaces/cipher/i-content-generator.d.ts +120 -0
- package/dist/core/interfaces/cipher/i-content-generator.js +12 -0
- package/dist/core/interfaces/cipher/i-event-emitter.d.ts +76 -0
- package/dist/core/interfaces/cipher/i-event-emitter.js +1 -0
- package/dist/core/interfaces/cipher/i-file-system.d.ts +68 -0
- package/dist/core/interfaces/cipher/i-file-system.js +1 -0
- package/dist/core/interfaces/cipher/i-history-storage.d.ts +53 -0
- package/dist/core/interfaces/cipher/i-history-storage.js +1 -0
- package/dist/core/interfaces/cipher/i-llm-provider.d.ts +14 -0
- package/dist/core/interfaces/cipher/i-llm-provider.js +1 -0
- package/dist/core/interfaces/cipher/i-llm-service.d.ts +62 -0
- package/dist/core/interfaces/cipher/i-llm-service.js +1 -0
- package/dist/core/interfaces/cipher/i-logger.d.ts +78 -0
- package/dist/core/interfaces/cipher/i-logger.js +28 -0
- package/dist/core/interfaces/cipher/i-message-formatter.d.ts +44 -0
- package/dist/core/interfaces/cipher/i-message-formatter.js +1 -0
- package/dist/core/interfaces/cipher/i-policy-engine.d.ts +102 -0
- package/dist/core/interfaces/cipher/i-policy-engine.js +9 -0
- package/dist/core/interfaces/cipher/i-process-service.d.ts +65 -0
- package/dist/core/interfaces/cipher/i-process-service.js +1 -0
- package/dist/core/interfaces/cipher/i-system-prompt-contributor.d.ts +25 -0
- package/dist/core/interfaces/cipher/i-system-prompt-contributor.js +1 -0
- package/dist/core/interfaces/cipher/i-tokenizer.d.ts +15 -0
- package/dist/core/interfaces/cipher/i-tokenizer.js +1 -0
- package/dist/core/interfaces/cipher/i-tool-provider.d.ts +64 -0
- package/dist/core/interfaces/cipher/i-tool-provider.js +1 -0
- package/dist/core/interfaces/cipher/i-tool-scheduler.d.ts +103 -0
- package/dist/core/interfaces/cipher/i-tool-scheduler.js +11 -0
- package/dist/core/interfaces/cipher/llm-types.d.ts +46 -0
- package/dist/core/interfaces/cipher/llm-types.js +5 -0
- package/dist/core/interfaces/cipher/message-types.d.ts +118 -0
- package/dist/core/interfaces/cipher/message-types.js +5 -0
- package/dist/core/interfaces/cipher/tokenizer-types.d.ts +11 -0
- package/dist/core/interfaces/cipher/tokenizer-types.js +14 -0
- package/dist/core/interfaces/i-cogit-pull-service.d.ts +24 -0
- package/dist/core/interfaces/i-cogit-pull-service.js +1 -0
- package/dist/core/interfaces/i-cogit-push-service.d.ts +27 -0
- package/dist/core/interfaces/i-cogit-push-service.js +1 -0
- package/dist/core/interfaces/i-context-file-reader.d.ts +32 -0
- package/dist/core/interfaces/i-context-file-reader.js +1 -0
- package/dist/core/interfaces/i-context-tree-service.d.ts +21 -0
- package/dist/core/interfaces/i-context-tree-service.js +1 -0
- package/dist/core/interfaces/i-context-tree-snapshot-service.d.ts +36 -0
- package/dist/core/interfaces/i-context-tree-snapshot-service.js +1 -0
- package/dist/core/interfaces/i-context-tree-writer-service.d.ts +32 -0
- package/dist/core/interfaces/i-context-tree-writer-service.js +1 -0
- package/dist/core/interfaces/i-file-watcher-service.d.ts +41 -0
- package/dist/core/interfaces/i-file-watcher-service.js +1 -0
- package/dist/core/interfaces/parser/i-clean-parser-service.d.ts +18 -0
- package/dist/core/interfaces/parser/i-clean-parser-service.js +1 -0
- package/dist/core/interfaces/parser/i-raw-parser-service.d.ts +17 -0
- package/dist/core/interfaces/parser/i-raw-parser-service.js +1 -0
- package/dist/core/interfaces/parser/i-session-normalizer.d.ts +56 -0
- package/dist/core/interfaces/parser/i-session-normalizer.js +1 -0
- package/dist/hooks/command_not_found/handle-invalid-commands.d.ts +7 -0
- package/dist/hooks/command_not_found/handle-invalid-commands.js +32 -0
- package/dist/hooks/error/clean-errors.d.ts +7 -0
- package/dist/hooks/error/clean-errors.js +50 -0
- package/dist/hooks/init/welcome.js +72 -1
- package/dist/hooks/prerun/validate-brv-config-version.d.ts +28 -0
- package/dist/hooks/prerun/validate-brv-config-version.js +43 -0
- package/dist/infra/cipher/agent-service-factory.d.ts +86 -0
- package/dist/infra/cipher/agent-service-factory.js +212 -0
- package/dist/infra/cipher/blob/blob-storage-factory.d.ts +13 -0
- package/dist/infra/cipher/blob/blob-storage-factory.js +14 -0
- package/dist/infra/cipher/blob/index.d.ts +10 -0
- package/dist/infra/cipher/blob/index.js +12 -0
- package/dist/infra/cipher/blob/migrations.d.ts +63 -0
- package/dist/infra/cipher/blob/migrations.js +148 -0
- package/dist/infra/cipher/blob/sqlite-blob-storage.d.ts +82 -0
- package/dist/infra/cipher/blob/sqlite-blob-storage.js +307 -0
- package/dist/infra/cipher/cipher-agent-state-manager.d.ts +63 -0
- package/dist/infra/cipher/cipher-agent-state-manager.js +108 -0
- package/dist/infra/cipher/cipher-agent.d.ts +182 -0
- package/dist/infra/cipher/cipher-agent.js +317 -0
- package/dist/infra/cipher/command-parser.d.ts +23 -0
- package/dist/infra/cipher/command-parser.js +85 -0
- package/dist/infra/cipher/display/todo-display.d.ts +23 -0
- package/dist/infra/cipher/display/todo-display.js +129 -0
- package/dist/infra/cipher/events/event-emitter.d.ts +137 -0
- package/dist/infra/cipher/events/event-emitter.js +158 -0
- package/dist/infra/cipher/exit-codes.d.ts +44 -0
- package/dist/infra/cipher/exit-codes.js +58 -0
- package/dist/infra/cipher/file-system/file-system-service.d.ts +105 -0
- package/dist/infra/cipher/file-system/file-system-service.js +641 -0
- package/dist/infra/cipher/file-system/gitignore-filter.d.ts +77 -0
- package/dist/infra/cipher/file-system/gitignore-filter.js +120 -0
- package/dist/infra/cipher/file-system/glob-utils.d.ts +60 -0
- package/dist/infra/cipher/file-system/glob-utils.js +120 -0
- package/dist/infra/cipher/file-system/path-validator.d.ts +69 -0
- package/dist/infra/cipher/file-system/path-validator.js +184 -0
- package/dist/infra/cipher/grpc/internal-llm-grpc-service.d.ts +149 -0
- package/dist/infra/cipher/grpc/internal-llm-grpc-service.js +364 -0
- package/dist/infra/cipher/grpc/internal-llm-grpc.proto +94 -0
- package/dist/infra/cipher/interactive-commands.d.ts +16 -0
- package/dist/infra/cipher/interactive-commands.js +198 -0
- package/dist/infra/cipher/interactive-loop.d.ts +24 -0
- package/dist/infra/cipher/interactive-loop.js +352 -0
- package/dist/infra/cipher/llm/context/async-mutex.d.ts +59 -0
- package/dist/infra/cipher/llm/context/async-mutex.js +92 -0
- package/dist/infra/cipher/llm/context/compression/index.d.ts +6 -0
- package/dist/infra/cipher/llm/context/compression/index.js +5 -0
- package/dist/infra/cipher/llm/context/compression/middle-removal.d.ts +40 -0
- package/dist/infra/cipher/llm/context/compression/middle-removal.js +76 -0
- package/dist/infra/cipher/llm/context/compression/oldest-removal.d.ts +38 -0
- package/dist/infra/cipher/llm/context/compression/oldest-removal.js +53 -0
- package/dist/infra/cipher/llm/context/compression/types.d.ts +36 -0
- package/dist/infra/cipher/llm/context/compression/types.js +1 -0
- package/dist/infra/cipher/llm/context/context-manager.d.ts +234 -0
- package/dist/infra/cipher/llm/context/context-manager.js +419 -0
- package/dist/infra/cipher/llm/context/index.d.ts +2 -0
- package/dist/infra/cipher/llm/context/index.js +2 -0
- package/dist/infra/cipher/llm/context/loop-detector.d.ts +125 -0
- package/dist/infra/cipher/llm/context/loop-detector.js +194 -0
- package/dist/infra/cipher/llm/context/utils.d.ts +17 -0
- package/dist/infra/cipher/llm/context/utils.js +89 -0
- package/dist/infra/cipher/llm/formatters/claude-formatter.d.ts +54 -0
- package/dist/infra/cipher/llm/formatters/claude-formatter.js +182 -0
- package/dist/infra/cipher/llm/formatters/gemini-formatter.d.ts +69 -0
- package/dist/infra/cipher/llm/formatters/gemini-formatter.js +253 -0
- package/dist/infra/cipher/llm/formatters/openrouter-formatter.d.ts +47 -0
- package/dist/infra/cipher/llm/formatters/openrouter-formatter.js +238 -0
- package/dist/infra/cipher/llm/generators/byterover-content-generator.d.ts +92 -0
- package/dist/infra/cipher/llm/generators/byterover-content-generator.js +211 -0
- package/dist/infra/cipher/llm/generators/index.d.ts +13 -0
- package/dist/infra/cipher/llm/generators/index.js +13 -0
- package/dist/infra/cipher/llm/generators/logging-content-generator.d.ts +104 -0
- package/dist/infra/cipher/llm/generators/logging-content-generator.js +182 -0
- package/dist/infra/cipher/llm/generators/openrouter-content-generator.d.ts +93 -0
- package/dist/infra/cipher/llm/generators/openrouter-content-generator.js +254 -0
- package/dist/infra/cipher/llm/generators/retryable-content-generator.d.ts +90 -0
- package/dist/infra/cipher/llm/generators/retryable-content-generator.js +157 -0
- package/dist/infra/cipher/llm/index.d.ts +9 -0
- package/dist/infra/cipher/llm/index.js +13 -0
- package/dist/infra/cipher/llm/internal-llm-service.d.ts +308 -0
- package/dist/infra/cipher/llm/internal-llm-service.js +724 -0
- package/dist/infra/cipher/llm/openrouter-llm-service.d.ts +183 -0
- package/dist/infra/cipher/llm/openrouter-llm-service.js +386 -0
- package/dist/infra/cipher/llm/response-validator.d.ts +89 -0
- package/dist/infra/cipher/llm/response-validator.js +157 -0
- package/dist/infra/cipher/llm/retry/index.d.ts +10 -0
- package/dist/infra/cipher/llm/retry/index.js +10 -0
- package/dist/infra/cipher/llm/retry/retry-policy.d.ts +74 -0
- package/dist/infra/cipher/llm/retry/retry-policy.js +146 -0
- package/dist/infra/cipher/llm/retry/retry-with-backoff.d.ts +113 -0
- package/dist/infra/cipher/llm/retry/retry-with-backoff.js +247 -0
- package/dist/infra/cipher/llm/thought-parser.d.ts +145 -0
- package/dist/infra/cipher/llm/thought-parser.js +190 -0
- package/dist/infra/cipher/llm/tokenizers/claude-tokenizer.d.ts +47 -0
- package/dist/infra/cipher/llm/tokenizers/claude-tokenizer.js +55 -0
- package/dist/infra/cipher/llm/tokenizers/default-tokenizer.d.ts +31 -0
- package/dist/infra/cipher/llm/tokenizers/default-tokenizer.js +38 -0
- package/dist/infra/cipher/llm/tokenizers/gemini-tokenizer.d.ts +37 -0
- package/dist/infra/cipher/llm/tokenizers/gemini-tokenizer.js +45 -0
- package/dist/infra/cipher/llm/tokenizers/openrouter-tokenizer.d.ts +29 -0
- package/dist/infra/cipher/llm/tokenizers/openrouter-tokenizer.js +37 -0
- package/dist/infra/cipher/llm/tool-output-processor.d.ts +117 -0
- package/dist/infra/cipher/llm/tool-output-processor.js +153 -0
- package/dist/infra/cipher/logger/console-logger.d.ts +42 -0
- package/dist/infra/cipher/logger/console-logger.js +63 -0
- package/dist/infra/cipher/logger/event-based-logger.d.ts +54 -0
- package/dist/infra/cipher/logger/event-based-logger.js +92 -0
- package/dist/infra/cipher/memory/index.d.ts +6 -0
- package/dist/infra/cipher/memory/index.js +7 -0
- package/dist/infra/cipher/memory/memory-manager.d.ts +136 -0
- package/dist/infra/cipher/memory/memory-manager.js +523 -0
- package/dist/infra/cipher/parsers/coding-agent-log-parser.d.ts +24 -0
- package/dist/infra/cipher/parsers/coding-agent-log-parser.js +51 -0
- package/dist/infra/cipher/process/command-validator.d.ts +59 -0
- package/dist/infra/cipher/process/command-validator.js +266 -0
- package/dist/infra/cipher/process/index.d.ts +8 -0
- package/dist/infra/cipher/process/index.js +8 -0
- package/dist/infra/cipher/process/process-service.d.ts +95 -0
- package/dist/infra/cipher/process/process-service.js +439 -0
- package/dist/infra/cipher/session/chat-session.d.ts +80 -0
- package/dist/infra/cipher/session/chat-session.js +165 -0
- package/dist/infra/cipher/session/index.d.ts +6 -0
- package/dist/infra/cipher/session/index.js +5 -0
- package/dist/infra/cipher/session/session-event-forwarder.d.ts +37 -0
- package/dist/infra/cipher/session/session-event-forwarder.js +83 -0
- package/dist/infra/cipher/session/session-manager.d.ts +109 -0
- package/dist/infra/cipher/session/session-manager.js +172 -0
- package/dist/infra/cipher/storage/blob-history-storage.d.ts +76 -0
- package/dist/infra/cipher/storage/blob-history-storage.js +178 -0
- package/dist/infra/cipher/system-prompt/simple-prompt-factory.d.ts +105 -0
- package/dist/infra/cipher/system-prompt/simple-prompt-factory.js +290 -0
- package/dist/infra/cipher/tools/core-tool-scheduler.d.ts +99 -0
- package/dist/infra/cipher/tools/core-tool-scheduler.js +161 -0
- package/dist/infra/cipher/tools/default-policy-rules.d.ts +26 -0
- package/dist/infra/cipher/tools/default-policy-rules.js +125 -0
- package/dist/infra/cipher/tools/implementations/bash-exec-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/bash-exec-tool.js +93 -0
- package/dist/infra/cipher/tools/implementations/bash-output-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/bash-output-tool.js +47 -0
- package/dist/infra/cipher/tools/implementations/create-knowledge-topic-tool.d.ts +11 -0
- package/dist/infra/cipher/tools/implementations/create-knowledge-topic-tool.js +142 -0
- package/dist/infra/cipher/tools/implementations/delete-memory-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/delete-memory-tool.js +37 -0
- package/dist/infra/cipher/tools/implementations/detect-domains-tool.d.ts +7 -0
- package/dist/infra/cipher/tools/implementations/detect-domains-tool.js +73 -0
- package/dist/infra/cipher/tools/implementations/edit-file-tool.d.ts +13 -0
- package/dist/infra/cipher/tools/implementations/edit-file-tool.js +50 -0
- package/dist/infra/cipher/tools/implementations/edit-memory-tool.d.ts +13 -0
- package/dist/infra/cipher/tools/implementations/edit-memory-tool.js +53 -0
- package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.d.ts +7 -0
- package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.js +421 -0
- package/dist/infra/cipher/tools/implementations/glob-files-tool.d.ts +18 -0
- package/dist/infra/cipher/tools/implementations/glob-files-tool.js +70 -0
- package/dist/infra/cipher/tools/implementations/grep-content-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/grep-content-tool.js +77 -0
- package/dist/infra/cipher/tools/implementations/kill-process-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/kill-process-tool.js +55 -0
- package/dist/infra/cipher/tools/implementations/list-memories-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/list-memories-tool.js +63 -0
- package/dist/infra/cipher/tools/implementations/read-file-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/read-file-tool.js +54 -0
- package/dist/infra/cipher/tools/implementations/read-memory-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/read-memory-tool.js +39 -0
- package/dist/infra/cipher/tools/implementations/search-history-tool.d.ts +10 -0
- package/dist/infra/cipher/tools/implementations/search-history-tool.js +36 -0
- package/dist/infra/cipher/tools/implementations/write-file-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/write-file-tool.js +52 -0
- package/dist/infra/cipher/tools/implementations/write-memory-tool.d.ts +13 -0
- package/dist/infra/cipher/tools/implementations/write-memory-tool.js +52 -0
- package/dist/infra/cipher/tools/implementations/write-todos-tool.d.ts +10 -0
- package/dist/infra/cipher/tools/implementations/write-todos-tool.js +165 -0
- package/dist/infra/cipher/tools/index.d.ts +18 -0
- package/dist/infra/cipher/tools/index.js +19 -0
- package/dist/infra/cipher/tools/policy-engine.d.ts +80 -0
- package/dist/infra/cipher/tools/policy-engine.js +110 -0
- package/dist/infra/cipher/tools/tool-invocation-queue.d.ts +191 -0
- package/dist/infra/cipher/tools/tool-invocation-queue.js +254 -0
- package/dist/infra/cipher/tools/tool-invocation.d.ts +216 -0
- package/dist/infra/cipher/tools/tool-invocation.js +294 -0
- package/dist/infra/cipher/tools/tool-manager.d.ts +135 -0
- package/dist/infra/cipher/tools/tool-manager.js +209 -0
- package/dist/infra/cipher/tools/tool-markers.d.ts +48 -0
- package/dist/infra/cipher/tools/tool-markers.js +49 -0
- package/dist/infra/cipher/tools/tool-provider.d.ts +77 -0
- package/dist/infra/cipher/tools/tool-provider.js +196 -0
- package/dist/infra/cipher/tools/tool-registry.d.ts +52 -0
- package/dist/infra/cipher/tools/tool-registry.js +144 -0
- package/dist/infra/cipher/tools/utils/schema-converter.d.ts +10 -0
- package/dist/infra/cipher/tools/utils/schema-converter.js +29 -0
- package/dist/infra/cipher/validation/workspace-validator.d.ts +19 -0
- package/dist/infra/cipher/validation/workspace-validator.js +37 -0
- package/dist/infra/cipher/watcher/coding-agent-log-watcher.d.ts +14 -0
- package/dist/infra/cipher/watcher/coding-agent-log-watcher.js +55 -0
- package/dist/infra/cogit/context-tree-to-push-context-mapper.d.ts +21 -0
- package/dist/infra/cogit/context-tree-to-push-context-mapper.js +32 -0
- package/dist/infra/cogit/http-cogit-pull-service.d.ts +15 -0
- package/dist/infra/cogit/http-cogit-pull-service.js +30 -0
- package/dist/infra/cogit/http-cogit-push-service.d.ts +17 -0
- package/dist/infra/cogit/http-cogit-push-service.js +104 -0
- package/dist/infra/config/file-config-store.js +9 -3
- package/dist/infra/context-tree/file-context-file-reader.d.ts +14 -0
- package/dist/infra/context-tree/file-context-file-reader.js +46 -0
- package/dist/infra/context-tree/file-context-tree-service.d.ts +14 -0
- package/dist/infra/context-tree/file-context-tree-service.js +46 -0
- package/dist/infra/context-tree/file-context-tree-snapshot-service.d.ts +34 -0
- package/dist/infra/context-tree/file-context-tree-snapshot-service.js +117 -0
- package/dist/infra/context-tree/file-context-tree-writer-service.d.ts +22 -0
- package/dist/infra/context-tree/file-context-tree-writer-service.js +61 -0
- package/dist/infra/memory/http-memory-retrieval-service.js +2 -1
- package/dist/infra/memory/http-memory-storage-service.js +4 -3
- package/dist/infra/parsers/clean/clean-claude-service.d.ts +111 -0
- package/dist/infra/parsers/clean/clean-claude-service.js +271 -0
- package/dist/infra/parsers/clean/clean-codex-service.d.ts +231 -0
- package/dist/infra/parsers/clean/clean-codex-service.js +534 -0
- package/dist/infra/parsers/clean/clean-copilot-service.d.ts +255 -0
- package/dist/infra/parsers/clean/clean-copilot-service.js +729 -0
- package/dist/infra/parsers/clean/clean-cursor-service.d.ts +161 -0
- package/dist/infra/parsers/clean/clean-cursor-service.js +432 -0
- package/dist/infra/parsers/clean/clean-parser-service-factory.d.ts +54 -0
- package/dist/infra/parsers/clean/clean-parser-service-factory.js +80 -0
- package/dist/infra/parsers/clean/shared.d.ts +84 -0
- package/dist/infra/parsers/clean/shared.js +273 -0
- package/dist/infra/parsers/raw/raw-claude-service.d.ts +195 -0
- package/dist/infra/parsers/raw/raw-claude-service.js +548 -0
- package/dist/infra/parsers/raw/raw-codex-service.d.ts +313 -0
- package/dist/infra/parsers/raw/raw-codex-service.js +782 -0
- package/dist/infra/parsers/raw/raw-copilot-service.d.ts +196 -0
- package/dist/infra/parsers/raw/raw-copilot-service.js +558 -0
- package/dist/infra/parsers/raw/raw-cursor-service.d.ts +316 -0
- package/dist/infra/parsers/raw/raw-cursor-service.js +818 -0
- package/dist/infra/parsers/raw/raw-parser-service-factory.d.ts +54 -0
- package/dist/infra/parsers/raw/raw-parser-service-factory.js +81 -0
- package/dist/infra/space/http-space-service.js +2 -1
- package/dist/infra/team/http-team-service.js +2 -1
- package/dist/infra/user/http-user-service.js +2 -1
- package/dist/infra/watcher/file-watcher-service.d.ts +10 -0
- package/dist/infra/watcher/file-watcher-service.js +81 -0
- package/dist/infra/workspace/workspace-detector-service.d.ts +60 -0
- package/dist/infra/workspace/workspace-detector-service.js +165 -0
- package/dist/resources/prompts/curate-context-tree-curation.yml +48 -0
- package/dist/resources/prompts/modes/autonomous.yml +9 -0
- package/dist/resources/prompts/query-context-tree-retrieval.yml +49 -0
- package/dist/resources/prompts/reflection.yml +27 -0
- package/dist/resources/prompts/system-prompt.yml +82 -0
- package/dist/resources/prompts/tool-outputs.yml +30 -0
- package/dist/templates/README.md +6 -7
- package/dist/templates/sections/command-reference.md +40 -111
- package/dist/templates/sections/workflow.md +3 -30
- package/dist/utils/emoji-helpers.d.ts +38 -0
- package/dist/utils/emoji-helpers.js +42 -0
- package/dist/utils/error-handler.d.ts +51 -0
- package/dist/utils/error-handler.js +169 -0
- package/dist/utils/error-helpers.d.ts +30 -0
- package/dist/utils/error-helpers.js +47 -0
- package/dist/utils/file-helpers.d.ts +15 -0
- package/dist/utils/file-helpers.js +44 -0
- package/dist/utils/oclif-error-helpers.d.ts +40 -0
- package/dist/utils/oclif-error-helpers.js +46 -0
- package/dist/utils/tool-display-formatter.d.ts +53 -0
- package/dist/utils/tool-display-formatter.js +257 -0
- package/oclif.manifest.json +381 -141
- package/package.json +27 -6
- package/dist/commands/add.d.ts +0 -49
- package/dist/commands/add.js +0 -192
- package/dist/commands/complete.d.ts +0 -108
- package/dist/commands/complete.js +0 -340
- package/dist/commands/retrieve.d.ts +0 -26
- package/dist/commands/retrieve.js +0 -101
- package/dist/core/domain/entities/curator-output.d.ts +0 -14
- package/dist/core/domain/entities/curator-output.js +0 -23
- package/dist/core/domain/entities/delta-batch.d.ts +0 -30
- package/dist/core/domain/entities/delta-batch.js +0 -52
- package/dist/core/domain/entities/delta-operation.d.ts +0 -31
- package/dist/core/domain/entities/delta-operation.js +0 -50
- package/dist/core/domain/entities/executor-output.d.ts +0 -27
- package/dist/core/domain/entities/executor-output.js +0 -33
- package/dist/core/domain/entities/reflector-output.d.ts +0 -38
- package/dist/core/domain/entities/reflector-output.js +0 -44
- package/dist/core/interfaces/i-ace-prompt-builder.d.ts +0 -48
- package/dist/core/interfaces/i-bullet-content-store.d.ts +0 -36
- package/dist/core/interfaces/i-delta-store.d.ts +0 -15
- package/dist/core/interfaces/i-executor-output-store.d.ts +0 -14
- package/dist/core/interfaces/i-playbook-service.d.ts +0 -69
- package/dist/core/interfaces/i-playbook-store.d.ts +0 -38
- package/dist/core/interfaces/i-reflection-store.d.ts +0 -21
- package/dist/infra/ace/ace-file-utils.d.ts +0 -46
- package/dist/infra/ace/ace-file-utils.js +0 -83
- package/dist/infra/ace/ace-prompt-templates.d.ts +0 -13
- package/dist/infra/ace/ace-prompt-templates.js +0 -177
- package/dist/infra/ace/file-bullet-content-store.d.ts +0 -27
- package/dist/infra/ace/file-bullet-content-store.js +0 -89
- package/dist/infra/ace/file-delta-store.d.ts +0 -9
- package/dist/infra/ace/file-delta-store.js +0 -26
- package/dist/infra/ace/file-executor-output-store.d.ts +0 -9
- package/dist/infra/ace/file-executor-output-store.js +0 -26
- package/dist/infra/ace/file-playbook-store.d.ts +0 -29
- package/dist/infra/ace/file-playbook-store.js +0 -107
- package/dist/infra/ace/file-reflection-store.d.ts +0 -10
- package/dist/infra/ace/file-reflection-store.js +0 -55
- package/dist/infra/playbook/file-playbook-service.d.ts +0 -42
- package/dist/infra/playbook/file-playbook-service.js +0 -132
- /package/dist/core/{interfaces/i-ace-prompt-builder.js → domain/cipher/blob/types.js} +0 -0
- /package/dist/core/{interfaces/i-bullet-content-store.js → domain/cipher/file-system/types.js} +0 -0
- /package/dist/core/{interfaces/i-delta-store.js → domain/cipher/process/types.js} +0 -0
- /package/dist/core/{interfaces/i-executor-output-store.js → domain/cipher/session/types.js} +0 -0
- /package/dist/core/{interfaces/i-playbook-service.js → domain/cipher/storage/history-types.js} +0 -0
- /package/dist/core/{interfaces/i-playbook-store.js → domain/cipher/system-prompt/types.js} +0 -0
- /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
|
+
}
|