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,493 @@
|
|
|
1
|
+
import { Args, Command, Flags } from '@oclif/core';
|
|
2
|
+
import { getCurrentConfig, isDevelopment } from '../../config/environment.js';
|
|
3
|
+
import { PROJECT } from '../../constants.js';
|
|
4
|
+
import { CipherAgent } from '../../infra/cipher/cipher-agent.js';
|
|
5
|
+
import { ExitCode, ExitError, exitWithCode } from '../../infra/cipher/exit-codes.js';
|
|
6
|
+
import { displayInfo, startInteractiveLoop } from '../../infra/cipher/interactive-loop.js';
|
|
7
|
+
import { WorkspaceNotInitializedError } from '../../infra/cipher/validation/workspace-validator.js';
|
|
8
|
+
import { ProjectConfigStore } from '../../infra/config/file-config-store.js';
|
|
9
|
+
import { KeychainTokenStore } from '../../infra/storage/keychain-token-store.js';
|
|
10
|
+
import { formatToolCall, formatToolResult } from '../../utils/tool-display-formatter.js';
|
|
11
|
+
export default class CipherAgentRun extends Command {
|
|
12
|
+
static args = {
|
|
13
|
+
prompt: Args.string({
|
|
14
|
+
description: 'The prompt to send to CipherAgent (optional in interactive mode)',
|
|
15
|
+
required: false,
|
|
16
|
+
}),
|
|
17
|
+
};
|
|
18
|
+
static description = 'Run CipherAgent in interactive or single-execution mode [Development only]';
|
|
19
|
+
static examples = [
|
|
20
|
+
'# Interactive mode (creates new unique session each time)',
|
|
21
|
+
'<%= config.bin %> <%= command.id %>',
|
|
22
|
+
'<%= config.bin %> <%= command.id %> --interactive',
|
|
23
|
+
'',
|
|
24
|
+
'# Continue most recent session in interactive mode',
|
|
25
|
+
'<%= config.bin %> <%= command.id %> -c',
|
|
26
|
+
'<%= config.bin %> <%= command.id %> -c -i',
|
|
27
|
+
'',
|
|
28
|
+
'# Resume specific session in interactive mode',
|
|
29
|
+
'<%= config.bin %> <%= command.id %> -r session-1731686400123-a7b3c9',
|
|
30
|
+
'<%= config.bin %> <%= command.id %> -r session-1731686400123-a7b3c9 -i',
|
|
31
|
+
'',
|
|
32
|
+
'# Single execution mode (creates new unique session)',
|
|
33
|
+
'<%= config.bin %> <%= command.id %> "Analyze the project structure" --no-interactive',
|
|
34
|
+
'<%= config.bin %> <%= command.id %> "Find all TypeScript files" --no-interactive',
|
|
35
|
+
'',
|
|
36
|
+
'# Continue session with a new prompt (headless)',
|
|
37
|
+
'<%= config.bin %> <%= command.id %> -c "What did we discuss?"',
|
|
38
|
+
'<%= config.bin %> <%= command.id %> -r session-1731686400123-a7b3c9 "Continue implementation"',
|
|
39
|
+
'',
|
|
40
|
+
'# Piped input (automatically uses non-interactive mode)',
|
|
41
|
+
'echo "Analyze the codebase" | <%= config.bin %> <%= command.id %>',
|
|
42
|
+
'',
|
|
43
|
+
'# Specify working directory',
|
|
44
|
+
'<%= config.bin %> <%= command.id %> -w /path/to/project',
|
|
45
|
+
'<%= config.bin %> <%= command.id %> --working-directory ~/myproject',
|
|
46
|
+
];
|
|
47
|
+
static flags = {
|
|
48
|
+
...(isDevelopment()
|
|
49
|
+
? {
|
|
50
|
+
apiKey: Flags.string({
|
|
51
|
+
char: 'k',
|
|
52
|
+
description: 'OpenRouter API key (use OpenRouter instead of gRPC backend) [Development only]',
|
|
53
|
+
env: 'OPENROUTER_API_KEY',
|
|
54
|
+
}),
|
|
55
|
+
model: Flags.string({
|
|
56
|
+
char: 'm',
|
|
57
|
+
description: 'Model to use (default: google/gemini-2.5-pro for OpenRouter, gemini-2.5-pro for gRPC) [Development only]',
|
|
58
|
+
}),
|
|
59
|
+
verbose: Flags.boolean({
|
|
60
|
+
char: 'v',
|
|
61
|
+
default: false,
|
|
62
|
+
description: 'Enable verbose debug output for prompt loading and agent operations [Development only]',
|
|
63
|
+
}),
|
|
64
|
+
}
|
|
65
|
+
: {}),
|
|
66
|
+
continue: Flags.boolean({
|
|
67
|
+
char: 'c',
|
|
68
|
+
description: 'Continue most recent session (requires prompt in headless mode)',
|
|
69
|
+
}),
|
|
70
|
+
interactive: Flags.boolean({
|
|
71
|
+
allowNo: true,
|
|
72
|
+
char: 'i',
|
|
73
|
+
description: 'Enable interactive mode (auto-detected from TTY if not specified)',
|
|
74
|
+
}),
|
|
75
|
+
maxTokens: Flags.integer({
|
|
76
|
+
char: 't',
|
|
77
|
+
description: 'Maximum tokens in response (default: 8192)',
|
|
78
|
+
}),
|
|
79
|
+
resume: Flags.string({
|
|
80
|
+
char: 'r',
|
|
81
|
+
description: 'Resume specific session by ID (requires prompt in headless mode)',
|
|
82
|
+
}),
|
|
83
|
+
temperature: Flags.string({
|
|
84
|
+
char: 'T',
|
|
85
|
+
description: 'Temperature for randomness 0-1 (default: 0.2)',
|
|
86
|
+
}),
|
|
87
|
+
workingDirectory: Flags.string({
|
|
88
|
+
char: 'w',
|
|
89
|
+
description: 'Working directory for file operations (default: current directory)',
|
|
90
|
+
}),
|
|
91
|
+
};
|
|
92
|
+
static hidden = !isDevelopment();
|
|
93
|
+
// Override catch to prevent oclif from logging errors that were already displayed
|
|
94
|
+
async catch(error) {
|
|
95
|
+
// Check if error is ExitError (message already displayed by exitWithCode)
|
|
96
|
+
if (error instanceof ExitError) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
// Backwards compatibility: also check oclif.exit property
|
|
100
|
+
if (error.oclif?.exit !== undefined) {
|
|
101
|
+
// Error already displayed by exitWithCode, silently exit
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
// For other errors, re-throw to let oclif handle them
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
createServices() {
|
|
108
|
+
return {
|
|
109
|
+
projectConfigStore: new ProjectConfigStore(),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Generate a unique session ID with timestamp and random component.
|
|
114
|
+
*
|
|
115
|
+
* Format: "session-{timestamp}-{random}"
|
|
116
|
+
* Example: "session-1731686400123-a7b3c9"
|
|
117
|
+
*
|
|
118
|
+
* @returns Unique session ID string
|
|
119
|
+
*/
|
|
120
|
+
generateSessionId() {
|
|
121
|
+
const timestamp = Date.now();
|
|
122
|
+
const random = Math.random().toString(36).slice(2, 8);
|
|
123
|
+
return `${timestamp}-${random}`;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get the most recent session ID from history storage.
|
|
127
|
+
*
|
|
128
|
+
* @param agent - CipherAgent instance
|
|
129
|
+
* @returns Most recent session ID or undefined if no sessions found
|
|
130
|
+
*/
|
|
131
|
+
async getMostRecentSessionId(agent) {
|
|
132
|
+
// Get all session IDs from persisted storage
|
|
133
|
+
const sessionIds = await agent.listPersistedSessions();
|
|
134
|
+
if (sessionIds.length === 0) {
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
// Get metadata for all sessions to find most recent
|
|
138
|
+
let mostRecentId;
|
|
139
|
+
let mostRecentActivity = 0;
|
|
140
|
+
for (const sessionId of sessionIds) {
|
|
141
|
+
// eslint-disable-next-line no-await-in-loop -- Sequential metadata loading required
|
|
142
|
+
const metadata = await agent.getSessionMetadata(sessionId);
|
|
143
|
+
if (metadata && metadata.lastActivity > mostRecentActivity) {
|
|
144
|
+
mostRecentActivity = metadata.lastActivity;
|
|
145
|
+
mostRecentId = sessionId;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return mostRecentId;
|
|
149
|
+
}
|
|
150
|
+
// eslint-disable-next-line complexity
|
|
151
|
+
async run() {
|
|
152
|
+
if (!isDevelopment()) {
|
|
153
|
+
this.error('This command is only available in development environment');
|
|
154
|
+
}
|
|
155
|
+
const { args, flags } = await this.parse(CipherAgentRun);
|
|
156
|
+
try {
|
|
157
|
+
// Get authentication token from keychain
|
|
158
|
+
const tokenStore = new KeychainTokenStore();
|
|
159
|
+
const token = await tokenStore.load();
|
|
160
|
+
if (!token) {
|
|
161
|
+
exitWithCode(ExitCode.CONFIG_ERROR, 'Authentication required. Please run "brv login" first.');
|
|
162
|
+
}
|
|
163
|
+
// Construct the prompt
|
|
164
|
+
const currentPrompt = args.prompt || ''; // Will be handled by interactive mode if empty
|
|
165
|
+
// Determine interactive mode
|
|
166
|
+
// Priority: explicit flag > TTY detection
|
|
167
|
+
const isInteractive = flags.interactive === undefined
|
|
168
|
+
? process.stdin.isTTY === true // Auto-detect from TTY
|
|
169
|
+
: flags.interactive; // User explicitly set --interactive or --no-interactive
|
|
170
|
+
// Validate prompt requirement for non-interactive mode
|
|
171
|
+
if (!isInteractive && !currentPrompt) {
|
|
172
|
+
this.error('Prompt is required in non-interactive mode. Use --interactive flag for interactive mode.');
|
|
173
|
+
}
|
|
174
|
+
// Validate flags: In headless mode, prompt is required for session continuation
|
|
175
|
+
if ((flags.continue || flags.resume) && !isInteractive && !args.prompt) {
|
|
176
|
+
this.error('Session continuation flags (-c/--continue or -r/--resume) require a prompt in headless mode.');
|
|
177
|
+
}
|
|
178
|
+
// Load ByteRover config to get custom system prompt (if configured)
|
|
179
|
+
const { projectConfigStore } = this.createServices();
|
|
180
|
+
const brvConfig = await projectConfigStore.read();
|
|
181
|
+
// Validate workspace is initialized
|
|
182
|
+
if (!brvConfig) {
|
|
183
|
+
throw new WorkspaceNotInitializedError('Project not initialized. Please run "brv init" to select your team and workspace.', '.brv');
|
|
184
|
+
}
|
|
185
|
+
// Create LLM configuration
|
|
186
|
+
const llmConfig = this.createLLMConfig({ ...token, spaceId: brvConfig?.spaceId ?? '', teamId: brvConfig?.teamId ?? '' }, flags);
|
|
187
|
+
// Create CipherAgent with service factory pattern
|
|
188
|
+
const agent = new CipherAgent(llmConfig, brvConfig);
|
|
189
|
+
this.log('Starting CipherAgent...');
|
|
190
|
+
await agent.start();
|
|
191
|
+
try {
|
|
192
|
+
// Resolve session ID based on flags
|
|
193
|
+
const resolvedSessionId = await this.resolveSessionId(agent, flags);
|
|
194
|
+
// Setup event listeners
|
|
195
|
+
this.setupEventListeners(agent, isInteractive);
|
|
196
|
+
if (isInteractive) {
|
|
197
|
+
// Interactive mode: start the loop with event bus for spinner
|
|
198
|
+
await startInteractiveLoop(agent, {
|
|
199
|
+
eventBus: agent.agentEventBus,
|
|
200
|
+
model: llmConfig.model,
|
|
201
|
+
sessionId: resolvedSessionId,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
// Non-interactive mode: single execution
|
|
206
|
+
if (!currentPrompt) {
|
|
207
|
+
this.error('Prompt is required in non-interactive mode.');
|
|
208
|
+
}
|
|
209
|
+
this.log('Executing prompt...');
|
|
210
|
+
const response = await agent.execute(currentPrompt, resolvedSessionId);
|
|
211
|
+
this.log('\nCipherAgent Response:');
|
|
212
|
+
this.log(response);
|
|
213
|
+
// Show agent state
|
|
214
|
+
const state = agent.getState();
|
|
215
|
+
this.log(`\n[Agent State: ${state.currentIteration} iterations]`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
finally {
|
|
219
|
+
// await agent.stop()
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
// Handle workspace not initialized error with friendly message
|
|
224
|
+
if (error instanceof WorkspaceNotInitializedError) {
|
|
225
|
+
this.handleWorkspaceError(error);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
// Handle graceful exit (Ctrl+C) - exit silently without error
|
|
229
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
230
|
+
if (errorMessage.includes('Readline closed')) {
|
|
231
|
+
// Silent exit - cleanup already happened
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
// Generic error handling with proper exit code
|
|
235
|
+
exitWithCode(ExitCode.RUNTIME_ERROR, `Failed to execute CipherAgent: ${errorMessage}`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Validate that a session exists in storage.
|
|
240
|
+
*
|
|
241
|
+
* @param agent - CipherAgent instance
|
|
242
|
+
* @param sessionId - Session ID to validate
|
|
243
|
+
* @returns True if session exists
|
|
244
|
+
*/
|
|
245
|
+
async validateSessionExists(agent, sessionId) {
|
|
246
|
+
const metadata = await agent.getSessionMetadata(sessionId);
|
|
247
|
+
return metadata !== undefined;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Create LLM configuration from flags and environment
|
|
251
|
+
*
|
|
252
|
+
* @param token - Authentication token
|
|
253
|
+
* @param token.accessToken - Access token for authentication
|
|
254
|
+
* @param token.sessionKey - Session key for authentication
|
|
255
|
+
* @param token.spaceId - Space ID for the session
|
|
256
|
+
* @param token.teamId - Team ID for the session
|
|
257
|
+
* @param flags - Command flags
|
|
258
|
+
* @param flags.apiKey - OpenRouter API key for direct service (optional)
|
|
259
|
+
* @param flags.maxTokens - Maximum tokens in response
|
|
260
|
+
* @param flags.model - Model to use
|
|
261
|
+
* @param flags.temperature - Temperature for randomness
|
|
262
|
+
* @param flags.verbose - Enable verbose debug output
|
|
263
|
+
* @param flags.workingDirectory - Working directory for file operations
|
|
264
|
+
* @returns LLM configuration object
|
|
265
|
+
*/
|
|
266
|
+
createLLMConfig(token, flags) {
|
|
267
|
+
// Default model: google/gemini-2.5-pro for OpenRouter, gemini-2.5-pro for gRPC
|
|
268
|
+
const model = flags.model ?? (flags.apiKey ? 'google/gemini-2.5-pro' : 'gemini-2.5-pro');
|
|
269
|
+
const envConfig = getCurrentConfig();
|
|
270
|
+
return {
|
|
271
|
+
accessToken: token.accessToken,
|
|
272
|
+
fileSystemConfig: flags.workingDirectory ? { workingDirectory: flags.workingDirectory } : undefined,
|
|
273
|
+
grpcEndpoint: envConfig.llmGrpcEndpoint,
|
|
274
|
+
maxIterations: 10, // Hardcoded default
|
|
275
|
+
maxTokens: flags.maxTokens ?? 8192, // Default: 8192
|
|
276
|
+
model,
|
|
277
|
+
openRouterApiKey: flags.apiKey, // Map -k flag to OpenRouter API key
|
|
278
|
+
projectId: PROJECT,
|
|
279
|
+
sessionKey: token.sessionKey,
|
|
280
|
+
spaceId: token.spaceId,
|
|
281
|
+
teamId: token.teamId,
|
|
282
|
+
temperature: flags.temperature ? Number.parseFloat(flags.temperature) : 0.2, // Default: 0.2
|
|
283
|
+
verbose: flags.verbose ?? false,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Format tool call for concise display in interactive mode
|
|
288
|
+
*
|
|
289
|
+
* @param toolName - Name of the tool
|
|
290
|
+
* @param args - Tool arguments
|
|
291
|
+
* @returns Formatted string for display
|
|
292
|
+
*/
|
|
293
|
+
formatToolForInteractive(toolName, args) {
|
|
294
|
+
// Provide user-friendly action descriptions
|
|
295
|
+
switch (toolName) {
|
|
296
|
+
case 'bash_exec': {
|
|
297
|
+
const cmd = String(args.command ?? '');
|
|
298
|
+
// Truncate long commands but keep readable
|
|
299
|
+
return cmd.length > 60 ? `Running command...` : `Running: ${cmd}`;
|
|
300
|
+
}
|
|
301
|
+
case 'create_knowledge_topic': {
|
|
302
|
+
return 'Creating knowledge topic...';
|
|
303
|
+
}
|
|
304
|
+
case 'find_knowledge_topics': {
|
|
305
|
+
return 'Querying knowledge base...';
|
|
306
|
+
}
|
|
307
|
+
case 'grep_content': {
|
|
308
|
+
return 'Searching context tree...';
|
|
309
|
+
}
|
|
310
|
+
case 'list_directory': {
|
|
311
|
+
return 'Listing directory...';
|
|
312
|
+
}
|
|
313
|
+
case 'read_file': {
|
|
314
|
+
return `Reading file...`;
|
|
315
|
+
}
|
|
316
|
+
case 'update_knowledge_topic': {
|
|
317
|
+
return 'Updating knowledge topic...';
|
|
318
|
+
}
|
|
319
|
+
case 'write_file': {
|
|
320
|
+
return 'Writing file...';
|
|
321
|
+
}
|
|
322
|
+
default: {
|
|
323
|
+
// For other tools, use a generic format
|
|
324
|
+
return 'Processing...';
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Format tool result summary for display
|
|
330
|
+
*
|
|
331
|
+
* @param toolName - Name of the tool
|
|
332
|
+
* @param result - Tool result data
|
|
333
|
+
* @returns Formatted summary string or empty if no summary needed
|
|
334
|
+
*/
|
|
335
|
+
formatToolResultSummary(toolName, result) {
|
|
336
|
+
try {
|
|
337
|
+
switch (toolName) {
|
|
338
|
+
case 'find_knowledge_topics': {
|
|
339
|
+
// Parse result to count topics
|
|
340
|
+
if (typeof result === 'string') {
|
|
341
|
+
try {
|
|
342
|
+
const parsed = JSON.parse(result);
|
|
343
|
+
const count = Array.isArray(parsed) ? parsed.length : Object.keys(parsed).length;
|
|
344
|
+
return `${count} topics retrieved`;
|
|
345
|
+
}
|
|
346
|
+
catch {
|
|
347
|
+
return '';
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return '';
|
|
351
|
+
}
|
|
352
|
+
case 'grep_content': {
|
|
353
|
+
// Parse result to count matches
|
|
354
|
+
if (typeof result === 'string') {
|
|
355
|
+
const lines = result.split('\n').filter((line) => line.trim());
|
|
356
|
+
return `${lines.length} matches found`;
|
|
357
|
+
}
|
|
358
|
+
return '';
|
|
359
|
+
}
|
|
360
|
+
case 'list_directory': {
|
|
361
|
+
// Parse result to count items
|
|
362
|
+
if (typeof result === 'string') {
|
|
363
|
+
const lines = result.split('\n').filter((line) => line.trim());
|
|
364
|
+
return `${lines.length} items`;
|
|
365
|
+
}
|
|
366
|
+
return '';
|
|
367
|
+
}
|
|
368
|
+
default: {
|
|
369
|
+
return '';
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
catch {
|
|
374
|
+
// If parsing fails, just return empty
|
|
375
|
+
return '';
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Handle workspace not initialized error with friendly message
|
|
380
|
+
*
|
|
381
|
+
* @param _error - WorkspaceNotInitializedError instance (unused, kept for type safety)
|
|
382
|
+
*/
|
|
383
|
+
handleWorkspaceError(_error) {
|
|
384
|
+
const message = 'Project not initialized. Please run "brv init" to select your team and workspace.';
|
|
385
|
+
exitWithCode(ExitCode.VALIDATION_ERROR, message);
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Resolve session ID based on flags
|
|
389
|
+
*
|
|
390
|
+
* @param agent - CipherAgent instance
|
|
391
|
+
* @param flags - Command flags
|
|
392
|
+
* @param flags.continue - Continue most recent session flag
|
|
393
|
+
* @param flags.resume - Resume specific session flag
|
|
394
|
+
* @returns Resolved session ID
|
|
395
|
+
*/
|
|
396
|
+
async resolveSessionId(agent, flags) {
|
|
397
|
+
// Validate flags: -c and -r are mutually exclusive
|
|
398
|
+
if (flags.continue && flags.resume) {
|
|
399
|
+
exitWithCode(ExitCode.VALIDATION_ERROR, 'Cannot use both -c/--continue and -r/--resume flags together. Choose one.');
|
|
400
|
+
}
|
|
401
|
+
if (flags.resume) {
|
|
402
|
+
// Resume specific session by ID
|
|
403
|
+
const sessionExists = await this.validateSessionExists(agent, flags.resume);
|
|
404
|
+
if (!sessionExists) {
|
|
405
|
+
exitWithCode(ExitCode.VALIDATION_ERROR, `Session '${flags.resume}' not found. Use 'brv cipher-agent sessions' to see available sessions.`);
|
|
406
|
+
}
|
|
407
|
+
const metadata = await agent.getSessionMetadata(flags.resume);
|
|
408
|
+
this.log(`📌 Resuming session: ${flags.resume} (${metadata?.messageCount ?? 0} messages)\n`);
|
|
409
|
+
return flags.resume;
|
|
410
|
+
}
|
|
411
|
+
if (flags.continue) {
|
|
412
|
+
// Continue most recent session
|
|
413
|
+
const mostRecentSessionId = await this.getMostRecentSessionId(agent);
|
|
414
|
+
if (!mostRecentSessionId) {
|
|
415
|
+
exitWithCode(ExitCode.VALIDATION_ERROR, 'No previous sessions found. Start a new conversation without -c flag.');
|
|
416
|
+
}
|
|
417
|
+
const metadata = await agent.getSessionMetadata(mostRecentSessionId);
|
|
418
|
+
this.log(`📌 Continuing most recent session: ${mostRecentSessionId} (${metadata?.messageCount ?? 0} messages)\n`);
|
|
419
|
+
return mostRecentSessionId;
|
|
420
|
+
}
|
|
421
|
+
// No continuation flags: generate new unique session ID
|
|
422
|
+
const newSessionId = this.generateSessionId();
|
|
423
|
+
this.log(`🚀 Starting new session: ${newSessionId}\n`);
|
|
424
|
+
return newSessionId;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Setup event listeners based on mode
|
|
428
|
+
*
|
|
429
|
+
* @param agent - CipherAgent instance
|
|
430
|
+
* @param isInteractive - Whether in interactive mode
|
|
431
|
+
*/
|
|
432
|
+
setupEventListeners(agent, isInteractive) {
|
|
433
|
+
if (!agent.agentEventBus) {
|
|
434
|
+
throw new Error('Agent event bus not initialized');
|
|
435
|
+
}
|
|
436
|
+
const eventBus = agent.agentEventBus;
|
|
437
|
+
if (isInteractive) {
|
|
438
|
+
// In interactive mode, show concise tool events for transparency
|
|
439
|
+
eventBus.on('llmservice:toolCall', (payload) => {
|
|
440
|
+
const details = this.formatToolForInteractive(payload.toolName, payload.args);
|
|
441
|
+
// Clean format: 🔧 tool_name → Action description...
|
|
442
|
+
displayInfo(`🔧 ${payload.toolName} → ${details}`);
|
|
443
|
+
});
|
|
444
|
+
eventBus.on('llmservice:toolResult', (payload) => {
|
|
445
|
+
if (payload.success) {
|
|
446
|
+
// Clean format: ✅ tool_name → Complete (with optional summary)
|
|
447
|
+
const summary = this.formatToolResultSummary(payload.toolName, payload.result);
|
|
448
|
+
displayInfo(summary ? `✅ ${payload.toolName} → Complete (${summary})` : `✅ ${payload.toolName} → Complete`);
|
|
449
|
+
}
|
|
450
|
+
else {
|
|
451
|
+
// Clean format: ❌ tool_name → Failed: error message
|
|
452
|
+
const errorMessage = payload.error || 'Unknown error';
|
|
453
|
+
displayInfo(`❌ ${payload.toolName} → Failed: ${errorMessage}`);
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
eventBus.on('llmservice:error', (payload) => {
|
|
457
|
+
const errorMessage = payload.error || 'Unknown error occurred';
|
|
458
|
+
displayInfo(`❌ Error: ${errorMessage}`);
|
|
459
|
+
});
|
|
460
|
+
eventBus.on('cipher:conversationReset', () => {
|
|
461
|
+
displayInfo('🔄 Conversation history cleared');
|
|
462
|
+
});
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
// In non-interactive mode, show verbose event logs for debugging
|
|
466
|
+
eventBus.on('llmservice:thinking', () => {
|
|
467
|
+
this.log('🤔 [Event] LLM is thinking...');
|
|
468
|
+
});
|
|
469
|
+
eventBus.on('llmservice:response', (payload) => {
|
|
470
|
+
this.log(`✅ [Event] LLM Response (${payload.provider}/${payload.model})`);
|
|
471
|
+
});
|
|
472
|
+
eventBus.on('llmservice:toolCall', (payload) => {
|
|
473
|
+
const formattedCall = formatToolCall(payload.toolName, payload.args);
|
|
474
|
+
this.log(`🔧 [Event] Tool Call: ${formattedCall}`);
|
|
475
|
+
});
|
|
476
|
+
eventBus.on('llmservice:toolResult', (payload) => {
|
|
477
|
+
const resultSummary = formatToolResult(payload.toolName, payload.success, payload.result, payload.error);
|
|
478
|
+
if (payload.success) {
|
|
479
|
+
this.log(`✓ [Event] Tool Success: ${payload.toolName} → ${resultSummary}`);
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
this.log(`✗ [Event] Tool Error: ${payload.toolName} → ${resultSummary}`);
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
eventBus.on('llmservice:error', (payload) => {
|
|
486
|
+
const errorMessage = payload.error || 'Unknown error occurred';
|
|
487
|
+
this.log(`❌ [Event] LLM Error: ${errorMessage}`);
|
|
488
|
+
});
|
|
489
|
+
eventBus.on('cipher:conversationReset', () => {
|
|
490
|
+
this.log('🔄 [Event] Conversation Reset');
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import type { IProjectConfigStore } from '../../core/interfaces/i-project-config-store.js';
|
|
3
|
+
export default class CipherAgentSetPrompt extends Command {
|
|
4
|
+
static args: {
|
|
5
|
+
prompt: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
static description: string;
|
|
8
|
+
static examples: string[];
|
|
9
|
+
static hidden: boolean;
|
|
10
|
+
protected createServices(): {
|
|
11
|
+
projectConfigStore: IProjectConfigStore;
|
|
12
|
+
};
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Args, Command } from '@oclif/core';
|
|
2
|
+
import { isDevelopment } from '../../config/environment.js';
|
|
3
|
+
import { BrvConfig } from '../../core/domain/entities/brv-config.js';
|
|
4
|
+
import { ProjectConfigStore } from '../../infra/config/file-config-store.js';
|
|
5
|
+
import { getErrorMessage } from '../../utils/error-helpers.js';
|
|
6
|
+
export default class CipherAgentSetPrompt extends Command {
|
|
7
|
+
static args = {
|
|
8
|
+
prompt: Args.string({ description: 'The system prompt for CipherAgent', required: true }),
|
|
9
|
+
};
|
|
10
|
+
static description = 'Set custom system prompt for CipherAgent [Development only]';
|
|
11
|
+
static examples = [
|
|
12
|
+
'<%= config.bin %> <%= command.id %> "You are a helpful coding assistant specialized in TypeScript"',
|
|
13
|
+
'<%= config.bin %> <%= command.id %> "You are an expert in refactoring and code quality improvements"',
|
|
14
|
+
];
|
|
15
|
+
static hidden = !isDevelopment();
|
|
16
|
+
createServices() {
|
|
17
|
+
return {
|
|
18
|
+
projectConfigStore: new ProjectConfigStore(),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
async run() {
|
|
22
|
+
if (!isDevelopment()) {
|
|
23
|
+
this.error('This command is only available in development environment');
|
|
24
|
+
}
|
|
25
|
+
const { args } = await this.parse(CipherAgentSetPrompt);
|
|
26
|
+
try {
|
|
27
|
+
const { projectConfigStore } = this.createServices();
|
|
28
|
+
// Check if config exists
|
|
29
|
+
const configExists = await projectConfigStore.exists();
|
|
30
|
+
if (!configExists) {
|
|
31
|
+
this.error('No ByteRover config found. Please run "byterover init" first to initialize the project.');
|
|
32
|
+
}
|
|
33
|
+
// Read existing config
|
|
34
|
+
const existingConfig = await projectConfigStore.read();
|
|
35
|
+
if (!existingConfig) {
|
|
36
|
+
this.error('Failed to read existing config.');
|
|
37
|
+
}
|
|
38
|
+
// Create updated config with new system prompt
|
|
39
|
+
const updatedConfig = new BrvConfig({
|
|
40
|
+
...existingConfig,
|
|
41
|
+
cipherAgentSystemPrompt: args.prompt,
|
|
42
|
+
});
|
|
43
|
+
// Write updated config
|
|
44
|
+
await projectConfigStore.write(updatedConfig);
|
|
45
|
+
this.log('✓ CipherAgent system prompt updated successfully!');
|
|
46
|
+
this.log('\nNew prompt:');
|
|
47
|
+
this.log(args.prompt);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
this.error(`Failed to set system prompt: ${getErrorMessage(error)}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import type { IProjectConfigStore } from '../../core/interfaces/i-project-config-store.js';
|
|
3
|
+
export default class CipherAgentShowPrompt extends Command {
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static hidden: boolean;
|
|
7
|
+
protected createServices(): {
|
|
8
|
+
projectConfigStore: IProjectConfigStore;
|
|
9
|
+
};
|
|
10
|
+
run(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { isDevelopment } from '../../config/environment.js';
|
|
3
|
+
import { ProjectConfigStore } from '../../infra/config/file-config-store.js';
|
|
4
|
+
import { getErrorMessage } from '../../utils/error-helpers.js';
|
|
5
|
+
export default class CipherAgentShowPrompt extends Command {
|
|
6
|
+
static description = 'Show the current CipherAgent system prompt [Development only]';
|
|
7
|
+
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
8
|
+
static hidden = !isDevelopment();
|
|
9
|
+
createServices() {
|
|
10
|
+
return {
|
|
11
|
+
projectConfigStore: new ProjectConfigStore(),
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
async run() {
|
|
15
|
+
if (!isDevelopment()) {
|
|
16
|
+
this.error('This command is only available in development environment');
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
const { projectConfigStore } = this.createServices();
|
|
20
|
+
// Check if config exists
|
|
21
|
+
const configExists = await projectConfigStore.exists();
|
|
22
|
+
if (!configExists) {
|
|
23
|
+
this.log('No ByteRover config found.');
|
|
24
|
+
this.log('CipherAgent will use the default system prompt.');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
// Read existing config
|
|
28
|
+
const config = await projectConfigStore.read();
|
|
29
|
+
if (!config) {
|
|
30
|
+
this.error('Failed to read config.');
|
|
31
|
+
}
|
|
32
|
+
// Show system prompt
|
|
33
|
+
if (config.cipherAgentSystemPrompt) {
|
|
34
|
+
this.log('Current CipherAgent system prompt:');
|
|
35
|
+
this.log('─'.repeat(60));
|
|
36
|
+
this.log(config.cipherAgentSystemPrompt);
|
|
37
|
+
this.log('─'.repeat(60));
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
this.log('No custom system prompt configured.');
|
|
41
|
+
this.log('CipherAgent is using the default system prompt.');
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
this.error(`Failed to show system prompt: ${getErrorMessage(error)}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
package/dist/commands/clear.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
|
+
import type { IContextTreeService } from '../core/interfaces/i-context-tree-service.js';
|
|
3
|
+
import type { IContextTreeSnapshotService } from '../core/interfaces/i-context-tree-snapshot-service.js';
|
|
2
4
|
export default class Clear extends Command {
|
|
3
5
|
static args: {
|
|
4
6
|
directory: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
@@ -9,5 +11,9 @@ export default class Clear extends Command {
|
|
|
9
11
|
yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
12
|
};
|
|
11
13
|
protected confirmClear(): Promise<boolean>;
|
|
14
|
+
protected createServices(): {
|
|
15
|
+
contextTreeService: IContextTreeService;
|
|
16
|
+
contextTreeSnapshotService: IContextTreeSnapshotService;
|
|
17
|
+
};
|
|
12
18
|
run(): Promise<void>;
|
|
13
19
|
}
|