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,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raw Parser Service Factory
|
|
3
|
+
* Routes IDE-based parsing requests to the appropriate parser service
|
|
4
|
+
* Supports: Claude Code, Cursor, GitHub Copilot, Codex
|
|
5
|
+
*/
|
|
6
|
+
import { Agent } from '../../../core/domain/entities/agent.js';
|
|
7
|
+
import { IRawParserService } from '../../../core/interfaces/parser/i-raw-parser-service.js';
|
|
8
|
+
/**
|
|
9
|
+
* Raw Parser Service Factory
|
|
10
|
+
* Creates and returns appropriate parser service for the given IDE
|
|
11
|
+
*/
|
|
12
|
+
export declare class RawParserServiceFactory {
|
|
13
|
+
private static readonly SUPPORTED_IDES;
|
|
14
|
+
/**
|
|
15
|
+
* Create a raw parser service for the specified IDE
|
|
16
|
+
*
|
|
17
|
+
* Factory method that instantiates the appropriate raw parser service
|
|
18
|
+
* based on the provided IDE type. Routes to specialized service classes.
|
|
19
|
+
*
|
|
20
|
+
* @param ide - The IDE type: 'Claude Code', 'Cursor', 'Github Copilot', or 'Codex'
|
|
21
|
+
* @returns The appropriate raw parser service instance
|
|
22
|
+
* @throws Error if IDE is not supported
|
|
23
|
+
*/
|
|
24
|
+
static createRawParserService(ide: Agent): IRawParserService;
|
|
25
|
+
/**
|
|
26
|
+
* Get list of supported IDEs
|
|
27
|
+
*
|
|
28
|
+
* Returns array of all IDE types that have corresponding raw parser services.
|
|
29
|
+
*
|
|
30
|
+
* @returns Array of supported IDE type strings
|
|
31
|
+
*/
|
|
32
|
+
static getSupportedIDEs(): Agent[];
|
|
33
|
+
/**
|
|
34
|
+
* Check if IDE is supported
|
|
35
|
+
*
|
|
36
|
+
* Validates whether the provided IDE string corresponds to a supported IDE.
|
|
37
|
+
*
|
|
38
|
+
* @param ide - IDE name to validate
|
|
39
|
+
* @returns True if IDE is in supported list, false otherwise
|
|
40
|
+
*/
|
|
41
|
+
static isSupported(ide: Agent): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Parse conversations for the specified IDE
|
|
44
|
+
*
|
|
45
|
+
* Creates appropriate service and delegates to its parse method to extract
|
|
46
|
+
* and transform raw conversation data from IDE storage.
|
|
47
|
+
*
|
|
48
|
+
* @param ide - The IDE type (Claude Code, Cursor, Github Copilot, Codex)
|
|
49
|
+
* @param customDir - Path to custom directory containing IDE session data
|
|
50
|
+
* @param outputDir - Optional output directory (defaults to process.cwd()/.brv/logs/{ide}/raw)
|
|
51
|
+
* @returns Promise resolving to true if parsing succeeded, false otherwise
|
|
52
|
+
*/
|
|
53
|
+
static parseConversations(ide: Agent, customDir: string, outputDir?: string): Promise<boolean>;
|
|
54
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raw Parser Service Factory
|
|
3
|
+
* Routes IDE-based parsing requests to the appropriate parser service
|
|
4
|
+
* Supports: Claude Code, Cursor, GitHub Copilot, Codex
|
|
5
|
+
*/
|
|
6
|
+
import { ClaudeRawService } from './raw-claude-service.js';
|
|
7
|
+
import { CodexRawService } from './raw-codex-service.js';
|
|
8
|
+
import { CopilotRawService } from './raw-copilot-service.js';
|
|
9
|
+
import { CursorRawService } from './raw-cursor-service.js';
|
|
10
|
+
/**
|
|
11
|
+
* Raw Parser Service Factory
|
|
12
|
+
* Creates and returns appropriate parser service for the given IDE
|
|
13
|
+
*/
|
|
14
|
+
export class RawParserServiceFactory {
|
|
15
|
+
static SUPPORTED_IDES = ['Claude Code', 'Cursor', 'Github Copilot', 'Codex'];
|
|
16
|
+
/**
|
|
17
|
+
* Create a raw parser service for the specified IDE
|
|
18
|
+
*
|
|
19
|
+
* Factory method that instantiates the appropriate raw parser service
|
|
20
|
+
* based on the provided IDE type. Routes to specialized service classes.
|
|
21
|
+
*
|
|
22
|
+
* @param ide - The IDE type: 'Claude Code', 'Cursor', 'Github Copilot', or 'Codex'
|
|
23
|
+
* @returns The appropriate raw parser service instance
|
|
24
|
+
* @throws Error if IDE is not supported
|
|
25
|
+
*/
|
|
26
|
+
static createRawParserService(ide) {
|
|
27
|
+
switch (ide) {
|
|
28
|
+
case 'Claude Code': {
|
|
29
|
+
return new ClaudeRawService(ide);
|
|
30
|
+
}
|
|
31
|
+
case 'Codex': {
|
|
32
|
+
return new CodexRawService(ide);
|
|
33
|
+
}
|
|
34
|
+
case 'Cursor': {
|
|
35
|
+
return new CursorRawService(ide);
|
|
36
|
+
}
|
|
37
|
+
case 'Github Copilot': {
|
|
38
|
+
return new CopilotRawService(ide);
|
|
39
|
+
}
|
|
40
|
+
default: {
|
|
41
|
+
throw new Error(`Unsupported IDE: ${ide}. Supported IDEs are: claude, cursor, copilot, codex`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get list of supported IDEs
|
|
47
|
+
*
|
|
48
|
+
* Returns array of all IDE types that have corresponding raw parser services.
|
|
49
|
+
*
|
|
50
|
+
* @returns Array of supported IDE type strings
|
|
51
|
+
*/
|
|
52
|
+
static getSupportedIDEs() {
|
|
53
|
+
return [...this.SUPPORTED_IDES];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Check if IDE is supported
|
|
57
|
+
*
|
|
58
|
+
* Validates whether the provided IDE string corresponds to a supported IDE.
|
|
59
|
+
*
|
|
60
|
+
* @param ide - IDE name to validate
|
|
61
|
+
* @returns True if IDE is in supported list, false otherwise
|
|
62
|
+
*/
|
|
63
|
+
static isSupported(ide) {
|
|
64
|
+
return this.getSupportedIDEs().includes(ide);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Parse conversations for the specified IDE
|
|
68
|
+
*
|
|
69
|
+
* Creates appropriate service and delegates to its parse method to extract
|
|
70
|
+
* and transform raw conversation data from IDE storage.
|
|
71
|
+
*
|
|
72
|
+
* @param ide - The IDE type (Claude Code, Cursor, Github Copilot, Codex)
|
|
73
|
+
* @param customDir - Path to custom directory containing IDE session data
|
|
74
|
+
* @param outputDir - Optional output directory (defaults to process.cwd()/.brv/logs/{ide}/raw)
|
|
75
|
+
* @returns Promise resolving to true if parsing succeeded, false otherwise
|
|
76
|
+
*/
|
|
77
|
+
static async parseConversations(ide, customDir, outputDir) {
|
|
78
|
+
const service = this.createRawParserService(ide);
|
|
79
|
+
return service.parse(customDir, outputDir);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Space } from '../../core/domain/entities/space.js';
|
|
2
|
+
import { getErrorMessage } from '../../utils/error-helpers.js';
|
|
2
3
|
import { AuthenticatedHttpClient } from '../http/authenticated-http-client.js';
|
|
3
4
|
export class HttpSpaceService {
|
|
4
5
|
config;
|
|
@@ -34,7 +35,7 @@ export class HttpSpaceService {
|
|
|
34
35
|
};
|
|
35
36
|
}
|
|
36
37
|
catch (error) {
|
|
37
|
-
throw new Error(`Failed to fetch spaces: ${error
|
|
38
|
+
throw new Error(`Failed to fetch spaces: ${getErrorMessage(error)}`);
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
async fetchAllSpaces(httpClient, teamId) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Team } from '../../core/domain/entities/team.js';
|
|
2
|
+
import { getErrorMessage } from '../../utils/error-helpers.js';
|
|
2
3
|
import { AuthenticatedHttpClient } from '../http/authenticated-http-client.js';
|
|
3
4
|
export class HttpTeamService {
|
|
4
5
|
config;
|
|
@@ -36,7 +37,7 @@ export class HttpTeamService {
|
|
|
36
37
|
};
|
|
37
38
|
}
|
|
38
39
|
catch (error) {
|
|
39
|
-
throw new Error(`Failed to fetch teams: ${error
|
|
40
|
+
throw new Error(`Failed to fetch teams: ${getErrorMessage(error)}`);
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
43
|
async fetchAllTeams(httpClient, isActive) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { User } from '../../core/domain/entities/user.js';
|
|
2
|
+
import { getErrorMessage } from '../../utils/error-helpers.js';
|
|
2
3
|
import { AuthenticatedHttpClient } from '../http/authenticated-http-client.js';
|
|
3
4
|
export class HttpUserService {
|
|
4
5
|
config;
|
|
@@ -17,7 +18,7 @@ export class HttpUserService {
|
|
|
17
18
|
return this.mapToUser(response.data);
|
|
18
19
|
}
|
|
19
20
|
catch (error) {
|
|
20
|
-
throw new Error(`Failed to fetch user information: ${error
|
|
21
|
+
throw new Error(`Failed to fetch user information: ${getErrorMessage(error)}`);
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
24
|
mapToUser(userData) {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { FileEvent, IFileWatcherService } from '../../core/interfaces/i-file-watcher-service.js';
|
|
2
|
+
export declare class FileWatcherService implements IFileWatcherService {
|
|
3
|
+
private eventHandler;
|
|
4
|
+
private watcher;
|
|
5
|
+
constructor();
|
|
6
|
+
setFileEventHandler(handler: (event: FileEvent) => Promise<void>): void;
|
|
7
|
+
start(paths: string[]): Promise<void>;
|
|
8
|
+
stop(): Promise<void>;
|
|
9
|
+
private invokeHandler;
|
|
10
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { watch } from 'chokidar';
|
|
2
|
+
export class FileWatcherService {
|
|
3
|
+
eventHandler;
|
|
4
|
+
watcher;
|
|
5
|
+
constructor() {
|
|
6
|
+
this.eventHandler = undefined;
|
|
7
|
+
this.watcher = undefined;
|
|
8
|
+
}
|
|
9
|
+
setFileEventHandler(handler) {
|
|
10
|
+
this.eventHandler = handler;
|
|
11
|
+
}
|
|
12
|
+
async start(paths) {
|
|
13
|
+
this.watcher = watch(paths, {
|
|
14
|
+
// `false` means the `add` events will be emitted for files already existing when the watcher starts.
|
|
15
|
+
// May need to change to `true` in the future because:
|
|
16
|
+
// - We only care about NEW LOGS that agents write AFTER we start watching.
|
|
17
|
+
// - We don't want to process old/existing log files that were already there.
|
|
18
|
+
// - Cleaner output - no flood of events when watcher starts.
|
|
19
|
+
ignoreInitial: true,
|
|
20
|
+
// Keep watching indefinitely (we want a long-running watcher)
|
|
21
|
+
persistent: true,
|
|
22
|
+
});
|
|
23
|
+
// Register event LISTENERS for all file system events
|
|
24
|
+
// Note: invokeHandler is async and handles errors internally
|
|
25
|
+
this.watcher.on('add', async (path) => {
|
|
26
|
+
await this.invokeHandler('add', path);
|
|
27
|
+
});
|
|
28
|
+
this.watcher.on('addDir', async (path) => {
|
|
29
|
+
await this.invokeHandler('addDir', path);
|
|
30
|
+
});
|
|
31
|
+
this.watcher.on('change', async (path) => {
|
|
32
|
+
await this.invokeHandler('change', path);
|
|
33
|
+
});
|
|
34
|
+
this.watcher.on('unlink', async (path) => {
|
|
35
|
+
await this.invokeHandler('unlink', path);
|
|
36
|
+
});
|
|
37
|
+
this.watcher.on('unlinkDir', async (path) => {
|
|
38
|
+
await this.invokeHandler('unlinkDir', path);
|
|
39
|
+
});
|
|
40
|
+
// Wait for watcher to be ready.
|
|
41
|
+
// The 'ready' event fires when
|
|
42
|
+
// chokidar has completed its initial scan of the directories (regardless of ignoreInitial setting)
|
|
43
|
+
// With ignoreInitial: false, the timeline is:
|
|
44
|
+
// 1. chokidar.watch() called
|
|
45
|
+
// 2. Scans directories
|
|
46
|
+
// 3. Emits 'add' events for 100 existing files
|
|
47
|
+
// 4. 'ready' event fires ← "Done with initial scan"
|
|
48
|
+
// 5. Now watching for new changes
|
|
49
|
+
//
|
|
50
|
+
// With ignoreInitial: true, timeline is:
|
|
51
|
+
// 1. chokidar.watch() called
|
|
52
|
+
// 2. Scans directories (still happens!)
|
|
53
|
+
// 3. Doesn't emit 'add' events for existing files
|
|
54
|
+
// 4. 'ready' event fires ← "Done with initial scan"
|
|
55
|
+
// 5. Now watching for new changes
|
|
56
|
+
// 'ready' is still useful for ignoreInitial: true.
|
|
57
|
+
await new Promise((resolve) => {
|
|
58
|
+
this.watcher?.on('ready', () => {
|
|
59
|
+
resolve();
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
async stop() {
|
|
64
|
+
if (this.watcher !== undefined) {
|
|
65
|
+
await this.watcher.close();
|
|
66
|
+
this.watcher = undefined;
|
|
67
|
+
}
|
|
68
|
+
this.eventHandler = undefined;
|
|
69
|
+
}
|
|
70
|
+
async invokeHandler(type, path) {
|
|
71
|
+
if (this.eventHandler !== undefined) {
|
|
72
|
+
const event = { path, type };
|
|
73
|
+
try {
|
|
74
|
+
await this.eventHandler(event);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
console.error(`[FileWatcherService] Error in event handler for ${type} ${path}:`, error);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Agent } from '../../core/domain/entities/agent.js';
|
|
2
|
+
export type WorkspaceInfo = {
|
|
3
|
+
chatLogPath: string;
|
|
4
|
+
cwd: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Service to detect IDE workspaces that contain the current working directory
|
|
8
|
+
* Supports: VS Code (Github Copilot), Cursor, Claude, and Codex
|
|
9
|
+
*/
|
|
10
|
+
export declare class WorkspaceDetectorService {
|
|
11
|
+
private readonly claudeUserPath;
|
|
12
|
+
private readonly codexUserPath;
|
|
13
|
+
private readonly cursorUserPath;
|
|
14
|
+
private readonly cwd;
|
|
15
|
+
private readonly vscodeUserPath;
|
|
16
|
+
constructor(cwd?: string);
|
|
17
|
+
/**
|
|
18
|
+
* Detect workspaces for the given IDE
|
|
19
|
+
*
|
|
20
|
+
* Supports: Github Copilot (VSCode), Cursor, Claude Code, Codex
|
|
21
|
+
*
|
|
22
|
+
* chatLogPath:
|
|
23
|
+
* - For Cursor/VSCode: Path to workspace storage folder if workspace.json matches cwd
|
|
24
|
+
* - For Claude Code: Path to claude project folder matching cwd (with special naming pattern)
|
|
25
|
+
* - For Codex: Direct path to codex sessions folder
|
|
26
|
+
*/
|
|
27
|
+
detectWorkspaces(agent: Agent): WorkspaceInfo;
|
|
28
|
+
/**
|
|
29
|
+
* Convert current working directory to Claude Code folder name format
|
|
30
|
+
* Example: /Users/datpham/dpmemories/byterover-cli -> -Users-datpham-dpmemories-byterover-cli
|
|
31
|
+
*/
|
|
32
|
+
private cwdToClaudeFolderName;
|
|
33
|
+
/**
|
|
34
|
+
* Detect Claude Code workspaces
|
|
35
|
+
* Claude Code stores projects in ~/.claude/projects with folder names like "-Users-datpham-dpmemories-byterover-cli"
|
|
36
|
+
* These folder names are derived from the project path with slashes replaced by dashes
|
|
37
|
+
*/
|
|
38
|
+
private detectClaudeWorkspaces;
|
|
39
|
+
/**
|
|
40
|
+
* Detect Codex workspaces
|
|
41
|
+
* Codex uses a single sessions folder
|
|
42
|
+
*/
|
|
43
|
+
private detectCodexWorkspaces;
|
|
44
|
+
/**
|
|
45
|
+
* Detect Cursor workspaces
|
|
46
|
+
*/
|
|
47
|
+
private detectCursorWorkspaces;
|
|
48
|
+
/**
|
|
49
|
+
* Detect VSCode workspaces (Github Copilot)
|
|
50
|
+
*/
|
|
51
|
+
private detectVSCodeWorkspaces;
|
|
52
|
+
/**
|
|
53
|
+
* Detect workspaces using workspace.json file (VSCode, Cursor)
|
|
54
|
+
*/
|
|
55
|
+
private detectWorkspacesByFile;
|
|
56
|
+
/**
|
|
57
|
+
* Check if current working directory is within the given workspace folder
|
|
58
|
+
*/
|
|
59
|
+
private isCurrentDirInWorkspace;
|
|
60
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
/**
|
|
5
|
+
* Service to detect IDE workspaces that contain the current working directory
|
|
6
|
+
* Supports: VS Code (Github Copilot), Cursor, Claude, and Codex
|
|
7
|
+
*/
|
|
8
|
+
export class WorkspaceDetectorService {
|
|
9
|
+
claudeUserPath;
|
|
10
|
+
codexUserPath;
|
|
11
|
+
cursorUserPath;
|
|
12
|
+
cwd;
|
|
13
|
+
vscodeUserPath;
|
|
14
|
+
constructor(cwd = process.cwd()) {
|
|
15
|
+
this.cwd = cwd;
|
|
16
|
+
this.vscodeUserPath = join(homedir(), 'Library/Application Support/Code/User/workspaceStorage');
|
|
17
|
+
this.cursorUserPath = join(homedir(), 'Library/Application Support/Cursor/User/workspaceStorage');
|
|
18
|
+
this.claudeUserPath = join(homedir(), '.claude/projects');
|
|
19
|
+
this.codexUserPath = join(homedir(), '.codex/sessions');
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Detect workspaces for the given IDE
|
|
23
|
+
*
|
|
24
|
+
* Supports: Github Copilot (VSCode), Cursor, Claude Code, Codex
|
|
25
|
+
*
|
|
26
|
+
* chatLogPath:
|
|
27
|
+
* - For Cursor/VSCode: Path to workspace storage folder if workspace.json matches cwd
|
|
28
|
+
* - For Claude Code: Path to claude project folder matching cwd (with special naming pattern)
|
|
29
|
+
* - For Codex: Direct path to codex sessions folder
|
|
30
|
+
*/
|
|
31
|
+
detectWorkspaces(agent) {
|
|
32
|
+
const chatLogPath = '';
|
|
33
|
+
switch (agent) {
|
|
34
|
+
case 'Claude Code': {
|
|
35
|
+
return this.detectClaudeWorkspaces(chatLogPath);
|
|
36
|
+
}
|
|
37
|
+
case 'Codex': {
|
|
38
|
+
return this.detectCodexWorkspaces(chatLogPath);
|
|
39
|
+
}
|
|
40
|
+
case 'Cursor': {
|
|
41
|
+
return this.detectCursorWorkspaces(chatLogPath);
|
|
42
|
+
}
|
|
43
|
+
case 'Github Copilot': {
|
|
44
|
+
return this.detectVSCodeWorkspaces(chatLogPath);
|
|
45
|
+
}
|
|
46
|
+
default: {
|
|
47
|
+
return { chatLogPath, cwd: this.cwd };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Convert current working directory to Claude Code folder name format
|
|
53
|
+
* Example: /Users/datpham/dpmemories/byterover-cli -> -Users-datpham-dpmemories-byterover-cli
|
|
54
|
+
*/
|
|
55
|
+
cwdToClaudeFolderName(cwd) {
|
|
56
|
+
// Remove leading slash and replace all slashes with dashes, then prepend dash
|
|
57
|
+
return '-' + cwd.slice(1).replaceAll('/', '-');
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Detect Claude Code workspaces
|
|
61
|
+
* Claude Code stores projects in ~/.claude/projects with folder names like "-Users-datpham-dpmemories-byterover-cli"
|
|
62
|
+
* These folder names are derived from the project path with slashes replaced by dashes
|
|
63
|
+
*/
|
|
64
|
+
detectClaudeWorkspaces(chatLogPath) {
|
|
65
|
+
try {
|
|
66
|
+
if (!existsSync(this.claudeUserPath)) {
|
|
67
|
+
return { chatLogPath, cwd: this.cwd };
|
|
68
|
+
}
|
|
69
|
+
// Convert cwd to Claude folder name format: /Users/datpham/dpmemories/byterover-cli -> -Users-datpham-dpmemories-byterover-cli
|
|
70
|
+
const claudeFolderName = this.cwdToClaudeFolderName(this.cwd);
|
|
71
|
+
const projectFolders = readdirSync(this.claudeUserPath);
|
|
72
|
+
for (const folderName of projectFolders) {
|
|
73
|
+
const folderPath = join(this.claudeUserPath, folderName);
|
|
74
|
+
// Check if this folder matches the current working directory
|
|
75
|
+
if (folderName === claudeFolderName) {
|
|
76
|
+
chatLogPath = folderPath;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// Ignore directory read errors
|
|
83
|
+
}
|
|
84
|
+
return { chatLogPath, cwd: this.cwd };
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Detect Codex workspaces
|
|
88
|
+
* Codex uses a single sessions folder
|
|
89
|
+
*/
|
|
90
|
+
detectCodexWorkspaces(chatLogPath) {
|
|
91
|
+
try {
|
|
92
|
+
if (existsSync(this.codexUserPath)) {
|
|
93
|
+
chatLogPath = this.codexUserPath;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// Ignore errors
|
|
98
|
+
}
|
|
99
|
+
return { chatLogPath, cwd: this.cwd };
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Detect Cursor workspaces
|
|
103
|
+
*/
|
|
104
|
+
detectCursorWorkspaces(chatLogPath) {
|
|
105
|
+
return this.detectWorkspacesByFile(this.cursorUserPath, chatLogPath);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Detect VSCode workspaces (Github Copilot)
|
|
109
|
+
*/
|
|
110
|
+
detectVSCodeWorkspaces(chatLogPath) {
|
|
111
|
+
return this.detectWorkspacesByFile(this.vscodeUserPath, chatLogPath);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Detect workspaces using workspace.json file (VSCode, Cursor)
|
|
115
|
+
*/
|
|
116
|
+
detectWorkspacesByFile(userPath, chatLogPath) {
|
|
117
|
+
try {
|
|
118
|
+
if (!existsSync(userPath)) {
|
|
119
|
+
return { chatLogPath, cwd: this.cwd };
|
|
120
|
+
}
|
|
121
|
+
const workspaceIds = readdirSync(userPath);
|
|
122
|
+
for (const wsId of workspaceIds) {
|
|
123
|
+
const wsPath = join(userPath, wsId);
|
|
124
|
+
const workspaceFile = join(wsPath, 'workspace.json');
|
|
125
|
+
if (!existsSync(workspaceFile)) {
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
const content = readFileSync(workspaceFile, 'utf8');
|
|
130
|
+
const data = JSON.parse(content);
|
|
131
|
+
// Only handle single folder windows (workspace files are ignored)
|
|
132
|
+
if (!data.folder) {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
const folderPath = decodeURIComponent(data.folder.replace('file://', ''));
|
|
136
|
+
// Set chatLogPath ONLY if folder exactly matches cwd
|
|
137
|
+
if (folderPath === this.cwd) {
|
|
138
|
+
chatLogPath = wsPath;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
// Ignore JSON parse errors
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// Ignore directory read errors
|
|
148
|
+
}
|
|
149
|
+
return { chatLogPath, cwd: this.cwd };
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Check if current working directory is within the given workspace folder
|
|
153
|
+
*/
|
|
154
|
+
isCurrentDirInWorkspace(folderPath) {
|
|
155
|
+
// Exact match
|
|
156
|
+
if (this.cwd === folderPath) {
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
// Check if current dir is a subdirectory
|
|
160
|
+
if (this.cwd.startsWith(folderPath + '/')) {
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
description: "context tree curation instructions"
|
|
2
|
+
prompt: |
|
|
3
|
+
|
|
4
|
+
Your task is to assemble relevant high-level information (context) from the input data which will be saved to the context tree in the following steps.
|
|
5
|
+
|
|
6
|
+
The information should be sufficient to understand what the user has provided to the coding assistant as the important context so that the coding assistant can use it to complete the task at hand. When organizing the context, keep in mind the hierarchical structure with a maximum of 2 levels: domain → topic → subtopic. If subtopics contain complex information, break them into separate topics rather than creating deeper nesting.
|
|
7
|
+
|
|
8
|
+
The context tree captures:
|
|
9
|
+
- the domains of the context
|
|
10
|
+
- the topics of the context
|
|
11
|
+
- the subtopics of the context (maximum one level under topics)
|
|
12
|
+
- the code snippets of the context
|
|
13
|
+
- the content of the context
|
|
14
|
+
|
|
15
|
+
For doing that, you will need to acquire information from the chat history with the corresponding tools. Use the `detect_domains` tool to get the overview of the domains and the related segments of text that are relevant to the domain in the current user's inputs.
|
|
16
|
+
|
|
17
|
+
After collecting all the information, follow these steps to understand and update the context tree:
|
|
18
|
+
|
|
19
|
+
1. **Explore existing context**: Use `glob_files` and `grep_content` to understand the current related context in the context tree. You may use bash commands (e.g., `ls`, `find`) to list directories if necessary to navigate the context tree structure.
|
|
20
|
+
|
|
21
|
+
2. **Find existing knowledge**: Use `find_knowledge_topics` to retrieve concise information about existing knowledge topics in the context tree that relate to the current domain and text segments.
|
|
22
|
+
|
|
23
|
+
3. **Create or update knowledge**: Once you have gathered all information about:
|
|
24
|
+
- The current domain and text segments from the user's input data
|
|
25
|
+
- The existing context in the context tree
|
|
26
|
+
Use the `create_knowledge_topic` tool to create new knowledge topics or update existing ones. Ensure that:
|
|
27
|
+
- The context is well-structured and MUST meet **Context quality requirements**
|
|
28
|
+
- There is no duplication with existing context
|
|
29
|
+
- The information is clear and easy to understand
|
|
30
|
+
|
|
31
|
+
4. **Context quality requirements**: Each context in the `contexts` array must:
|
|
32
|
+
- Important: Minimum 2-4 sentences per context. Otherwise, DO NOT add that context.
|
|
33
|
+
- A developer should understand the concept without reading source code
|
|
34
|
+
- Include names of functions, classes, patterns, or key concepts
|
|
35
|
+
|
|
36
|
+
AVOID vague contexts like:
|
|
37
|
+
- "Hook system"
|
|
38
|
+
- "Error handling"
|
|
39
|
+
|
|
40
|
+
WRITE detailed contexts like:
|
|
41
|
+
- "The hook system allows registering callbacks for lifecycle events. Register hooks using
|
|
42
|
+
`HookRegistry.register(hookName, callback)` and trigger them with `HookRegistry.trigger(hookName, context)`. Hooks are used to:
|
|
43
|
+
support async callbacks and are commonly used for: pre/post tool execution, agent lifecycle events, and custom
|
|
44
|
+
integrations."
|
|
45
|
+
|
|
46
|
+
- "Error handling follows a custom error class pattern. All custom errors extend `BaseError` and include: error
|
|
47
|
+
code, message, context object, and optional cause. Use `ErrorHandler.wrap(fn)` for consistent error boundaries across
|
|
48
|
+
async operations."
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
description: "autonomous execution instructions"
|
|
2
|
+
prompt: |
|
|
3
|
+
|
|
4
|
+
CRITICAL: Autonomous Execution Required
|
|
5
|
+
|
|
6
|
+
You are currently in autonomous mode. You can use all tools to process the input data and perform the CREATE, READ, UPDATE and DELETE operations on the context tree without any human intervention.
|
|
7
|
+
|
|
8
|
+
excluded_tools: []
|
|
9
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
description: "context tree retrieval instructions for query command"
|
|
2
|
+
prompt: |
|
|
3
|
+
|
|
4
|
+
Your task is to search and retrieve relevant information from the context tree to answer the user's query.
|
|
5
|
+
Prioritize tool call efficiency for tools that can be run in parallel.
|
|
6
|
+
ONLY give up on search in the last iteration.
|
|
7
|
+
|
|
8
|
+
Follow these steps to provide comprehensive answers:
|
|
9
|
+
|
|
10
|
+
1. **Understand the query**: Analyze what the user is asking for - which domains, topics, or specific information they need.
|
|
11
|
+
|
|
12
|
+
2. **Search strategically**:
|
|
13
|
+
- Use `find_knowledge_topics` to locate relevant topics across domains with pattern matching
|
|
14
|
+
- Use `read_file` to read the full content of relevant context.md files
|
|
15
|
+
- Use `grep_content` to search for specific terms, code snippets, or patterns within context files
|
|
16
|
+
- Use `glob_files` to find files by path patterns if needed
|
|
17
|
+
- For multi-part queries (queries that include words like "and"), use tools in parallel:
|
|
18
|
+
- Use `find_knowledge_topics` and `read_file` multiple times to get all relevant topics and their full content.
|
|
19
|
+
- If ANY of these tools don't depend on each other, try to run them in the same iteration.
|
|
20
|
+
|
|
21
|
+
- Consider the context tree structure: `.brv/context-tree/{domain}/{topic}/context.md`
|
|
22
|
+
|
|
23
|
+
3. **Read relevant content**:
|
|
24
|
+
- Use `read_file` to read the full content of relevant context.md files
|
|
25
|
+
- Read multiple files if the query spans multiple domains or topics
|
|
26
|
+
|
|
27
|
+
4. **Synthesize and present**:
|
|
28
|
+
- Organize findings by domain and topic
|
|
29
|
+
- Important: Even if you don't have the answer, provide the best answer you can with the information gathered.
|
|
30
|
+
- Include relevant content excerpts with their source paths (e.g., "From code_style/best_practices:")
|
|
31
|
+
- Provide clear, structured answers with citations.
|
|
32
|
+
- If multiple topics are relevant, group them logically
|
|
33
|
+
|
|
34
|
+
5. **Be thorough but efficient**:
|
|
35
|
+
- Search progressively - start broad, then narrow down based on findings
|
|
36
|
+
- Use pattern matching to avoid reading entire tree
|
|
37
|
+
- If initial search returns too many results, refine with more specific patterns
|
|
38
|
+
- If search returns no results, try broader patterns or alternative terms
|
|
39
|
+
|
|
40
|
+
Available domains in the context tree:
|
|
41
|
+
- `code_style` - Coding standards, style guidelines, quality standards
|
|
42
|
+
- `design` - UI/UX design, component libraries, themes, design systems
|
|
43
|
+
- `structure` - Project structure, architecture, component organization
|
|
44
|
+
- `compliance` - Security policies, compliance requirements, best practices
|
|
45
|
+
- `testing` - Testing strategies, test implementation, quality assurance
|
|
46
|
+
- `bug_fixes` - Bug fixing procedures, common issues, troubleshooting guides
|
|
47
|
+
|
|
48
|
+
excluded_tools: []
|
|
49
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Reflection prompts for task completion checking
|
|
2
|
+
# These prompts help the agent assess progress and determine when tasks are complete
|
|
3
|
+
description: Reflection prompts for task completion self-assessment
|
|
4
|
+
prompt: "Reflection prompts for task completion"
|
|
5
|
+
|
|
6
|
+
prompts:
|
|
7
|
+
completion_check: |
|
|
8
|
+
For every iteration, consider whether you have gathered sufficient information to answer the users' question.
|
|
9
|
+
|
|
10
|
+
mid_point_check: |
|
|
11
|
+
You've used {{current_iteration}} iterations ({{remaining_iterations}} remaining). Review your progress:
|
|
12
|
+
- Do you have enough information to answer all parts of the question?
|
|
13
|
+
- If yes, provide your answer now. If it is a multi-part question, provide your answer for each part. Stop exploring or running more tools.
|
|
14
|
+
- If no, please continue exploring or running more tools for missing parts of the question.
|
|
15
|
+
- However, DO NOT declare you can't answer the question and keep searching if you have at least one iteration left.
|
|
16
|
+
|
|
17
|
+
near_max_iterations: |
|
|
18
|
+
NOTICE: You are approaching the iteration limit ({{current_iteration}}/{{max_iterations}}).
|
|
19
|
+
To ensure task completion:
|
|
20
|
+
- If this is the last iteration, don't running any more tools. Try to answer all parts of the question using the information you already have.
|
|
21
|
+
- Answer the question immediately if possible. Run tools ONLY IF you still have at least one iteration left.
|
|
22
|
+
- However, DO NOT declare you can't answer the question and keep searching if you have at least one iteration left.
|
|
23
|
+
|
|
24
|
+
final_iteration: |
|
|
25
|
+
FINAL ITERATION: This is your last opportunity to respond.
|
|
26
|
+
Review what you've learned from your previous tool calls and provide your answer now.
|
|
27
|
+
Summarize your findings and give the best answer you can with the information gathered.
|