byterover-cli 0.3.5 → 0.4.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 +119 -63
- package/bin/dev.js +8 -1
- package/bin/run.js +7 -0
- package/dist/commands/cipher-agent/run.d.ts +30 -0
- package/dist/commands/cipher-agent/run.js +123 -61
- package/dist/commands/cipher-agent/set-prompt.d.ts +2 -0
- package/dist/commands/cipher-agent/set-prompt.js +13 -8
- package/dist/commands/cipher-agent/show-prompt.d.ts +2 -0
- package/dist/commands/cipher-agent/show-prompt.js +17 -12
- package/dist/commands/curate.d.ts +3 -60
- package/dist/commands/curate.js +45 -341
- package/dist/commands/foo.d.ts +4 -2
- package/dist/commands/foo.js +21 -16
- package/dist/commands/main.d.ts +9 -0
- package/dist/commands/main.js +34 -0
- package/dist/commands/query.d.ts +2 -48
- package/dist/commands/query.js +19 -287
- package/dist/commands/status.d.ts +2 -13
- package/dist/commands/status.js +12 -91
- package/dist/commands/watch.d.ts +2 -0
- package/dist/commands/watch.js +23 -19
- package/dist/config/environment.d.ts +1 -1
- package/dist/config/environment.js +2 -2
- package/dist/constants.d.ts +4 -5
- package/dist/constants.js +5 -5
- package/dist/core/domain/cipher/errors/storage-error.d.ts +89 -0
- package/dist/core/domain/cipher/errors/storage-error.js +130 -0
- package/dist/core/domain/cipher/queue/types.d.ts +71 -0
- package/dist/core/domain/cipher/queue/types.js +9 -0
- package/dist/core/domain/cipher/storage/message-storage-types.d.ts +218 -0
- package/dist/core/domain/cipher/storage/message-storage-types.js +18 -0
- package/dist/core/domain/cipher/tools/constants.d.ts +1 -0
- package/dist/core/domain/cipher/tools/constants.js +1 -0
- package/dist/core/domain/entities/event.d.ts +1 -1
- package/dist/core/domain/entities/event.js +5 -0
- package/dist/core/domain/entities/global-config.d.ts +36 -0
- package/dist/core/domain/entities/global-config.js +66 -0
- package/dist/core/domain/knowledge/directory-manager.d.ts +10 -0
- package/dist/core/domain/knowledge/directory-manager.js +18 -0
- package/dist/core/domain/knowledge/markdown-writer.d.ts +9 -0
- package/dist/core/domain/knowledge/markdown-writer.js +51 -1
- package/dist/core/interfaces/cipher/i-agent-storage.d.ts +152 -0
- package/dist/core/interfaces/cipher/i-agent-storage.js +1 -0
- package/dist/core/interfaces/cipher/i-cipher-agent.d.ts +2 -0
- package/dist/core/interfaces/cipher/i-key-storage.d.ts +91 -0
- package/dist/core/interfaces/cipher/i-key-storage.js +1 -0
- package/dist/core/interfaces/i-global-config-store.d.ts +34 -0
- package/dist/core/interfaces/i-global-config-store.js +1 -0
- package/dist/core/interfaces/i-onboarding-preference-store.d.ts +20 -0
- package/dist/core/interfaces/i-onboarding-preference-store.js +1 -0
- package/dist/core/interfaces/i-terminal.d.ts +146 -0
- package/dist/core/interfaces/i-terminal.js +1 -0
- package/dist/core/interfaces/i-workspace-detector-service.d.ts +8 -0
- package/dist/core/interfaces/i-workspace-detector-service.js +1 -0
- package/dist/core/interfaces/usecase/i-clear-use-case.d.ts +6 -0
- package/dist/core/interfaces/usecase/i-clear-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-curate-use-case.d.ts +10 -0
- package/dist/core/interfaces/usecase/i-curate-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-generate-rules-use-case.d.ts +3 -0
- package/dist/core/interfaces/usecase/i-generate-rules-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-init-use-case.d.ts +5 -0
- package/dist/core/interfaces/usecase/i-init-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-login-use-case.d.ts +3 -0
- package/dist/core/interfaces/usecase/i-login-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-logout-use-case.d.ts +5 -0
- package/dist/core/interfaces/usecase/i-logout-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-pull-use-case.d.ts +5 -0
- package/dist/core/interfaces/usecase/i-pull-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-push-use-case.d.ts +6 -0
- package/dist/core/interfaces/usecase/i-push-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-query-use-case.d.ts +9 -0
- package/dist/core/interfaces/usecase/i-query-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-space-list-use-case.d.ts +3 -0
- package/dist/core/interfaces/usecase/i-space-list-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-space-switch-use-case.d.ts +3 -0
- package/dist/core/interfaces/usecase/i-space-switch-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-status-use-case.d.ts +5 -0
- package/dist/core/interfaces/usecase/i-status-use-case.js +1 -0
- package/dist/hooks/init/welcome.js +1 -2
- package/dist/infra/cipher/agent-service-factory.d.ts +13 -6
- package/dist/infra/cipher/agent-service-factory.js +40 -16
- package/dist/infra/cipher/cipher-agent.js +4 -4
- package/dist/infra/cipher/consumer/consumer-lock.d.ts +20 -0
- package/dist/infra/cipher/consumer/consumer-lock.js +40 -0
- package/dist/infra/cipher/consumer/consumer-service.d.ts +99 -0
- package/dist/infra/cipher/consumer/consumer-service.js +165 -0
- package/dist/infra/cipher/consumer/execution-consumer.d.ts +121 -0
- package/dist/infra/cipher/consumer/execution-consumer.js +523 -0
- package/dist/infra/cipher/consumer/index.d.ts +33 -0
- package/dist/infra/cipher/consumer/index.js +33 -0
- package/dist/infra/cipher/consumer/queue-polling-service.d.ts +120 -0
- package/dist/infra/cipher/consumer/queue-polling-service.js +248 -0
- package/dist/infra/cipher/http/internal-llm-http-service.d.ts +94 -0
- package/dist/infra/cipher/http/internal-llm-http-service.js +118 -0
- package/dist/infra/cipher/llm/context/compaction/compaction-service.d.ts +106 -0
- package/dist/infra/cipher/llm/context/compaction/compaction-service.js +132 -0
- package/dist/infra/cipher/llm/context/compaction/index.d.ts +9 -0
- package/dist/infra/cipher/llm/context/compaction/index.js +9 -0
- package/dist/infra/cipher/llm/context/context-manager.d.ts +46 -2
- package/dist/infra/cipher/llm/context/context-manager.js +68 -4
- package/dist/infra/cipher/llm/context/rw-lock.d.ts +72 -0
- package/dist/infra/cipher/llm/context/rw-lock.js +145 -0
- package/dist/infra/cipher/llm/generators/byterover-content-generator.d.ts +7 -7
- package/dist/infra/cipher/llm/generators/byterover-content-generator.js +8 -8
- package/dist/infra/cipher/llm/internal-llm-service.js +2 -0
- package/dist/infra/cipher/session/session-manager.d.ts +4 -4
- package/dist/infra/cipher/session/session-manager.js +5 -5
- package/dist/infra/cipher/storage/agent-storage.d.ts +246 -0
- package/dist/infra/cipher/storage/agent-storage.js +956 -0
- package/dist/infra/cipher/storage/dual-format-history-storage.d.ts +77 -0
- package/dist/infra/cipher/storage/dual-format-history-storage.js +149 -0
- package/dist/infra/cipher/storage/granular-history-storage.d.ts +65 -0
- package/dist/infra/cipher/storage/granular-history-storage.js +118 -0
- package/dist/infra/cipher/storage/message-storage-service.d.ts +108 -0
- package/dist/infra/cipher/storage/message-storage-service.js +529 -0
- package/dist/infra/cipher/storage/process-utils.d.ts +16 -0
- package/dist/infra/cipher/storage/process-utils.js +43 -0
- package/dist/infra/cipher/storage/sqlite-key-storage.d.ts +105 -0
- package/dist/infra/cipher/storage/sqlite-key-storage.js +404 -0
- package/dist/infra/cipher/system-prompt/simple-prompt-factory.d.ts +1 -0
- package/dist/infra/cipher/system-prompt/simple-prompt-factory.js +7 -0
- package/dist/infra/cipher/tools/default-policy-rules.js +1 -1
- package/dist/infra/cipher/tools/implementations/curate-tool.d.ts +10 -0
- package/dist/infra/cipher/tools/implementations/curate-tool.js +371 -0
- package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.js +11 -8
- package/dist/infra/cipher/tools/tool-manager.d.ts +8 -2
- package/dist/infra/cipher/tools/tool-manager.js +29 -2
- package/dist/infra/cipher/tools/tool-registry.js +7 -0
- package/dist/infra/http/authenticated-http-client.d.ts +21 -0
- package/dist/infra/http/authenticated-http-client.js +38 -0
- package/dist/infra/repl/commands/arg-parser.d.ts +97 -0
- package/dist/infra/repl/commands/arg-parser.js +129 -0
- package/dist/infra/repl/commands/clear-command.d.ts +5 -0
- package/dist/infra/repl/commands/clear-command.js +61 -0
- package/dist/infra/repl/commands/curate-command.d.ts +9 -0
- package/dist/infra/repl/commands/curate-command.js +88 -0
- package/dist/infra/repl/commands/gen-rules-command.d.ts +7 -0
- package/dist/infra/repl/commands/gen-rules-command.js +38 -0
- package/dist/infra/repl/commands/index.d.ts +8 -0
- package/dist/infra/repl/commands/index.js +36 -0
- package/dist/infra/repl/commands/init-command.d.ts +7 -0
- package/dist/infra/repl/commands/init-command.js +83 -0
- package/dist/infra/repl/commands/login-command.d.ts +7 -0
- package/dist/infra/repl/commands/login-command.js +50 -0
- package/dist/infra/repl/commands/logout-command.d.ts +5 -0
- package/dist/infra/repl/commands/logout-command.js +48 -0
- package/dist/infra/repl/commands/pull-command.d.ts +5 -0
- package/dist/infra/repl/commands/pull-command.js +61 -0
- package/dist/infra/repl/commands/push-command.d.ts +5 -0
- package/dist/infra/repl/commands/push-command.js +66 -0
- package/dist/infra/repl/commands/query-command.d.ts +5 -0
- package/dist/infra/repl/commands/query-command.js +66 -0
- package/dist/infra/repl/commands/space/index.d.ts +5 -0
- package/dist/infra/repl/commands/space/index.js +14 -0
- package/dist/infra/repl/commands/space/list-command.d.ts +5 -0
- package/dist/infra/repl/commands/space/list-command.js +70 -0
- package/dist/infra/repl/commands/space/switch-command.d.ts +5 -0
- package/dist/infra/repl/commands/space/switch-command.js +37 -0
- package/dist/infra/repl/commands/status-command.d.ts +5 -0
- package/dist/infra/repl/commands/status-command.js +39 -0
- package/dist/infra/repl/repl-startup.d.ts +18 -0
- package/dist/infra/repl/repl-startup.js +26 -0
- package/dist/infra/storage/file-global-config-store.d.ts +22 -0
- package/dist/infra/storage/file-global-config-store.js +65 -0
- package/dist/infra/storage/file-onboarding-preference-store.d.ts +10 -0
- package/dist/infra/storage/file-onboarding-preference-store.js +46 -0
- package/dist/infra/terminal/oclif-terminal.d.ts +19 -0
- package/dist/infra/terminal/oclif-terminal.js +60 -0
- package/dist/infra/terminal/repl-terminal.d.ts +31 -0
- package/dist/infra/terminal/repl-terminal.js +116 -0
- package/dist/infra/tracking/mixpanel-tracking-service.d.ts +11 -1
- package/dist/infra/tracking/mixpanel-tracking-service.js +18 -13
- package/dist/infra/usecase/clear-use-case.d.ts +20 -0
- package/dist/infra/usecase/clear-use-case.js +58 -0
- package/dist/infra/usecase/curate-use-case.d.ts +66 -0
- package/dist/infra/usecase/curate-use-case.js +283 -0
- package/dist/{commands/gen-rules.d.ts → infra/usecase/generate-rules-use-case.d.ts} +14 -20
- package/dist/{commands/gen-rules.js → infra/usecase/generate-rules-use-case.js} +59 -78
- package/dist/infra/usecase/init-use-case.d.ts +139 -0
- package/dist/{commands/init.js → infra/usecase/init-use-case.js} +184 -230
- package/dist/infra/usecase/login-use-case.d.ts +28 -0
- package/dist/infra/usecase/login-use-case.js +88 -0
- package/dist/infra/usecase/logout-use-case.d.ts +22 -0
- package/dist/infra/usecase/logout-use-case.js +51 -0
- package/dist/infra/usecase/pull-use-case.d.ts +35 -0
- package/dist/infra/usecase/pull-use-case.js +89 -0
- package/dist/infra/usecase/push-use-case.d.ts +37 -0
- package/dist/infra/usecase/push-use-case.js +124 -0
- package/dist/infra/usecase/query-use-case.d.ts +78 -0
- package/dist/infra/usecase/query-use-case.js +401 -0
- package/dist/infra/usecase/space-list-use-case.d.ts +27 -0
- package/dist/infra/usecase/space-list-use-case.js +64 -0
- package/dist/infra/usecase/space-switch-use-case.d.ts +36 -0
- package/dist/infra/usecase/space-switch-use-case.js +140 -0
- package/dist/infra/usecase/status-use-case.d.ts +27 -0
- package/dist/infra/usecase/status-use-case.js +97 -0
- package/dist/infra/workspace/workspace-detector-service.d.ts +3 -6
- package/dist/resources/prompts/curate-context-tree-curation.yml +23 -11
- package/dist/resources/prompts/query-context-tree-retrieval.yml +3 -4
- package/dist/resources/prompts/system-prompt.yml +1 -1
- package/dist/resources/prompts/tool-outputs.yml +4 -3
- package/dist/templates/sections/command-reference.md +12 -0
- package/dist/templates/sections/workflow.md +10 -1
- package/dist/tui/app.d.ts +9 -0
- package/dist/tui/app.js +26 -0
- package/dist/tui/components/enter-prompt.d.ts +13 -0
- package/dist/tui/components/enter-prompt.js +15 -0
- package/dist/tui/components/execution/execution-changes.d.ts +14 -0
- package/dist/tui/components/execution/execution-changes.js +15 -0
- package/dist/tui/components/execution/execution-content.d.ts +25 -0
- package/dist/tui/components/execution/execution-content.js +67 -0
- package/dist/tui/components/execution/execution-input.d.ts +12 -0
- package/dist/tui/components/execution/execution-input.js +16 -0
- package/dist/tui/components/execution/execution-progress.d.ts +21 -0
- package/dist/tui/components/execution/execution-progress.js +21 -0
- package/dist/tui/components/execution/execution-status.d.ts +13 -0
- package/dist/tui/components/execution/execution-status.js +19 -0
- package/dist/tui/components/execution/index.d.ts +11 -0
- package/dist/tui/components/execution/index.js +11 -0
- package/dist/tui/components/execution/log-item.d.ts +17 -0
- package/dist/tui/components/execution/log-item.js +25 -0
- package/dist/tui/components/footer.d.ts +5 -0
- package/dist/tui/components/footer.js +12 -0
- package/dist/tui/components/header.d.ts +18 -0
- package/dist/tui/components/header.js +18 -0
- package/dist/tui/components/index.d.ts +17 -0
- package/dist/tui/components/index.js +14 -0
- package/dist/tui/components/inline-prompts/index.d.ts +15 -0
- package/dist/tui/components/inline-prompts/index.js +10 -0
- package/dist/tui/components/inline-prompts/inline-confirm.d.ts +17 -0
- package/dist/tui/components/inline-prompts/inline-confirm.js +32 -0
- package/dist/tui/components/inline-prompts/inline-file-selector.d.ts +43 -0
- package/dist/tui/components/inline-prompts/inline-file-selector.js +185 -0
- package/dist/tui/components/inline-prompts/inline-input.d.ts +19 -0
- package/dist/tui/components/inline-prompts/inline-input.js +32 -0
- package/dist/tui/components/inline-prompts/inline-search.d.ts +20 -0
- package/dist/tui/components/inline-prompts/inline-search.js +50 -0
- package/dist/tui/components/inline-prompts/inline-select.d.ts +20 -0
- package/dist/tui/components/inline-prompts/inline-select.js +34 -0
- package/dist/tui/components/logo.d.ts +43 -0
- package/dist/tui/components/logo.js +103 -0
- package/dist/tui/components/message-item.d.ts +12 -0
- package/dist/tui/components/message-item.js +12 -0
- package/dist/tui/components/onboarding/copyable-prompt.d.ts +15 -0
- package/dist/tui/components/onboarding/copyable-prompt.js +65 -0
- package/dist/tui/components/onboarding/index.d.ts +7 -0
- package/dist/tui/components/onboarding/index.js +6 -0
- package/dist/tui/components/onboarding/onboarding-flow.d.ts +13 -0
- package/dist/tui/components/onboarding/onboarding-flow.js +304 -0
- package/dist/tui/components/onboarding/onboarding-step.d.ts +23 -0
- package/dist/tui/components/onboarding/onboarding-step.js +12 -0
- package/dist/tui/components/output-log.d.ts +14 -0
- package/dist/tui/components/output-log.js +13 -0
- package/dist/tui/components/scrollable-list.d.ts +30 -0
- package/dist/tui/components/scrollable-list.js +121 -0
- package/dist/tui/components/suggestions.d.ts +16 -0
- package/dist/tui/components/suggestions.js +162 -0
- package/dist/tui/components/tab-bar.d.ts +10 -0
- package/dist/tui/components/tab-bar.js +12 -0
- package/dist/tui/constants.d.ts +11 -0
- package/dist/tui/constants.js +13 -0
- package/dist/tui/contexts/auth-context.d.ts +30 -0
- package/dist/tui/contexts/auth-context.js +153 -0
- package/dist/tui/contexts/consumer.d.ts +31 -0
- package/dist/tui/contexts/consumer.js +56 -0
- package/dist/tui/contexts/index.d.ts +6 -0
- package/dist/tui/contexts/index.js +6 -0
- package/dist/tui/contexts/onboarding-context.d.ts +43 -0
- package/dist/tui/contexts/onboarding-context.js +181 -0
- package/dist/tui/contexts/services-context.d.ts +29 -0
- package/dist/tui/contexts/services-context.js +20 -0
- package/dist/tui/contexts/use-commands.d.ts +29 -0
- package/dist/tui/contexts/use-commands.js +53 -0
- package/dist/tui/contexts/use-mode.d.ts +43 -0
- package/dist/tui/contexts/use-mode.js +76 -0
- package/dist/tui/contexts/use-theme.d.ts +53 -0
- package/dist/tui/contexts/use-theme.js +60 -0
- package/dist/tui/hooks/index.d.ts +17 -0
- package/dist/tui/hooks/index.js +14 -0
- package/dist/tui/hooks/use-activity-logs.d.ts +26 -0
- package/dist/tui/hooks/use-activity-logs.js +90 -0
- package/dist/tui/hooks/use-consumer.d.ts +12 -0
- package/dist/tui/hooks/use-consumer.js +50 -0
- package/dist/tui/hooks/use-onboarding.d.ts +7 -0
- package/dist/tui/hooks/use-onboarding.js +6 -0
- package/dist/tui/hooks/use-queue-polling.d.ts +31 -0
- package/dist/tui/hooks/use-queue-polling.js +90 -0
- package/dist/tui/hooks/use-slash-command-processor.d.ts +16 -0
- package/dist/tui/hooks/use-slash-command-processor.js +132 -0
- package/dist/tui/hooks/use-slash-completion.d.ts +30 -0
- package/dist/tui/hooks/use-slash-completion.js +230 -0
- package/dist/tui/hooks/use-tab-navigation.d.ts +10 -0
- package/dist/tui/hooks/use-tab-navigation.js +35 -0
- package/dist/tui/hooks/use-visible-window.d.ts +22 -0
- package/dist/tui/hooks/use-visible-window.js +37 -0
- package/dist/tui/index.d.ts +1 -0
- package/dist/tui/index.js +1 -0
- package/dist/tui/providers/app-providers.d.ts +25 -0
- package/dist/tui/providers/app-providers.js +9 -0
- package/dist/tui/types/commands.d.ts +252 -0
- package/dist/tui/types/commands.js +16 -0
- package/dist/tui/types/dialogs.d.ts +37 -0
- package/dist/tui/types/dialogs.js +4 -0
- package/dist/tui/types/index.d.ts +11 -0
- package/dist/tui/types/index.js +7 -0
- package/dist/tui/types/messages.d.ts +55 -0
- package/dist/tui/types/messages.js +4 -0
- package/dist/tui/types/prompts.d.ts +100 -0
- package/dist/tui/types/prompts.js +4 -0
- package/dist/tui/types/ui.d.ts +14 -0
- package/dist/tui/types/ui.js +4 -0
- package/dist/tui/types.d.ts +1 -0
- package/dist/tui/types.js +1 -0
- package/dist/tui/views/command-view.d.ts +12 -0
- package/dist/tui/views/command-view.js +451 -0
- package/dist/tui/views/index.d.ts +6 -0
- package/dist/tui/views/index.js +6 -0
- package/dist/tui/views/login-view.d.ts +10 -0
- package/dist/tui/views/login-view.js +30 -0
- package/dist/tui/views/logs-view.d.ts +11 -0
- package/dist/tui/views/logs-view.js +73 -0
- package/dist/utils/file-validator.d.ts +16 -0
- package/dist/utils/file-validator.js +81 -0
- package/dist/utils/global-config-path.d.ts +15 -0
- package/dist/utils/global-config-path.js +38 -0
- package/oclif.manifest.json +29 -315
- package/package.json +11 -4
- package/dist/commands/clear.d.ts +0 -19
- package/dist/commands/clear.js +0 -78
- package/dist/commands/init.d.ts +0 -130
- package/dist/commands/login.d.ts +0 -22
- package/dist/commands/login.js +0 -108
- package/dist/commands/logout.d.ts +0 -16
- package/dist/commands/logout.js +0 -61
- package/dist/commands/pull.d.ts +0 -33
- package/dist/commands/pull.js +0 -115
- package/dist/commands/push.d.ts +0 -35
- package/dist/commands/push.js +0 -160
- package/dist/commands/space/list.d.ts +0 -25
- package/dist/commands/space/list.js +0 -114
- package/dist/commands/space/switch.d.ts +0 -36
- package/dist/commands/space/switch.js +0 -160
- package/dist/infra/cipher/grpc/internal-llm-grpc-service.d.ts +0 -149
- package/dist/infra/cipher/grpc/internal-llm-grpc-service.js +0 -364
- package/dist/infra/cipher/grpc/internal-llm-grpc.proto +0 -94
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
import { confirm, search, select } from '@inquirer/prompts';
|
|
2
|
-
import { Command, Flags, ux } from '@oclif/core';
|
|
3
1
|
import { access, readFile, rm } from 'node:fs/promises';
|
|
4
2
|
import { join } from 'node:path';
|
|
5
|
-
import { getCurrentConfig } from '
|
|
6
|
-
import { ACE_DIR, BRV_CONFIG_VERSION, BRV_DIR, DEFAULT_BRANCH, PROJECT_CONFIG_FILE } from '
|
|
7
|
-
import { AGENT_VALUES } from '
|
|
8
|
-
import { BrvConfig } from '
|
|
9
|
-
import { BrvConfigVersionError } from '
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
3
|
+
import { getCurrentConfig } from '../../config/environment.js';
|
|
4
|
+
import { ACE_DIR, BRV_CONFIG_VERSION, BRV_DIR, DEFAULT_BRANCH, PROJECT_CONFIG_FILE } from '../../constants.js';
|
|
5
|
+
import { AGENT_VALUES } from '../../core/domain/entities/agent.js';
|
|
6
|
+
import { BrvConfig } from '../../core/domain/entities/brv-config.js';
|
|
7
|
+
import { BrvConfigVersionError } from '../../core/domain/errors/brv-config-version-error.js';
|
|
8
|
+
import { AGENT_RULE_CONFIGS } from '../rule/agent-rule-config.js';
|
|
9
|
+
import { BRV_RULE_MARKERS, BRV_RULE_TAG } from '../rule/constants.js';
|
|
10
|
+
import { WorkspaceDetectorService } from '../workspace/workspace-detector-service.js';
|
|
11
|
+
export class InitUseCase {
|
|
12
|
+
cogitPullService;
|
|
13
|
+
contextTreeService;
|
|
14
|
+
contextTreeSnapshotService;
|
|
15
|
+
contextTreeWriterService;
|
|
16
|
+
fileService;
|
|
17
|
+
legacyRuleDetector;
|
|
18
|
+
projectConfigStore;
|
|
19
|
+
spaceService;
|
|
20
|
+
teamService;
|
|
21
|
+
templateService;
|
|
22
|
+
terminal;
|
|
23
|
+
tokenStore;
|
|
24
|
+
trackingService;
|
|
25
|
+
constructor(options) {
|
|
26
|
+
this.cogitPullService = options.cogitPullService;
|
|
27
|
+
this.contextTreeService = options.contextTreeService;
|
|
28
|
+
this.contextTreeSnapshotService = options.contextTreeSnapshotService;
|
|
29
|
+
this.contextTreeWriterService = options.contextTreeWriterService;
|
|
30
|
+
this.fileService = options.fileService;
|
|
31
|
+
this.legacyRuleDetector = options.legacyRuleDetector;
|
|
32
|
+
this.projectConfigStore = options.projectConfigStore;
|
|
33
|
+
this.spaceService = options.spaceService;
|
|
34
|
+
this.teamService = options.teamService;
|
|
35
|
+
this.templateService = options.templateService;
|
|
36
|
+
this.terminal = options.terminal;
|
|
37
|
+
this.tokenStore = options.tokenStore;
|
|
38
|
+
this.trackingService = options.trackingService;
|
|
39
|
+
}
|
|
40
40
|
async aceDirectoryExists(baseDir) {
|
|
41
41
|
const dir = baseDir ?? process.cwd();
|
|
42
42
|
const acePath = join(dir, BRV_DIR, ACE_DIR);
|
|
@@ -50,69 +50,38 @@ export default class Init extends Command {
|
|
|
50
50
|
}
|
|
51
51
|
async cleanupBeforeReInitialization() {
|
|
52
52
|
const brvDir = join(process.cwd(), BRV_DIR);
|
|
53
|
-
this.log('\n Cleaning up existing ByteRover directory...');
|
|
54
|
-
|
|
53
|
+
this.terminal.log('\n Cleaning up existing ByteRover directory...');
|
|
54
|
+
this.terminal.actionStart(` Removing ${BRV_DIR}/`);
|
|
55
55
|
try {
|
|
56
56
|
await rm(brvDir, { force: true, recursive: true });
|
|
57
|
-
|
|
57
|
+
this.terminal.actionStop('✓');
|
|
58
58
|
}
|
|
59
59
|
catch (error) {
|
|
60
|
-
|
|
60
|
+
this.terminal.actionStop('✗');
|
|
61
61
|
throw new Error(`Failed to remove ${BRV_DIR}/: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
async confirmReInitialization(config) {
|
|
65
65
|
if (this.isLegacyProjectConfig(config)) {
|
|
66
66
|
const versionStatus = config.currentVersion === undefined ? 'missing' : `${config.currentVersion} → ${BRV_CONFIG_VERSION}`;
|
|
67
|
-
this.log(`\n⚠️ Project has an outdated configuration (version: ${versionStatus})`);
|
|
67
|
+
this.terminal.log(`\n⚠️ Project has an outdated configuration (version: ${versionStatus})`);
|
|
68
68
|
}
|
|
69
69
|
else {
|
|
70
|
-
this.log('\n Project is already initialized');
|
|
70
|
+
this.terminal.log('\n Project is already initialized');
|
|
71
71
|
}
|
|
72
|
-
this.log(` Team: ${config.teamName}`);
|
|
73
|
-
this.log(` Space: ${config.spaceName}`);
|
|
74
|
-
this.log(` Config: ${join(process.cwd(), BRV_DIR, PROJECT_CONFIG_FILE)}`);
|
|
75
|
-
this.log('\n Re-initializing will:');
|
|
76
|
-
this.log(` - Remove the entire ${BRV_DIR}/ directory and all its contents`);
|
|
77
|
-
this.log(' - Allow you to select a new team/space');
|
|
78
|
-
this.log(' - Create a fresh configuration and Context Tree');
|
|
79
|
-
this.log(' - Regenerate rule instructions\n');
|
|
80
|
-
return confirm({
|
|
72
|
+
this.terminal.log(` Team: ${config.teamName}`);
|
|
73
|
+
this.terminal.log(` Space: ${config.spaceName}`);
|
|
74
|
+
this.terminal.log(` Config: ${join(process.cwd(), BRV_DIR, PROJECT_CONFIG_FILE)}`);
|
|
75
|
+
this.terminal.log('\n Re-initializing will:');
|
|
76
|
+
this.terminal.log(` - Remove the entire ${BRV_DIR}/ directory and all its contents`);
|
|
77
|
+
this.terminal.log(' - Allow you to select a new team/space');
|
|
78
|
+
this.terminal.log(' - Create a fresh configuration and Context Tree');
|
|
79
|
+
this.terminal.log(' - Regenerate rule instructions\n');
|
|
80
|
+
return this.terminal.confirm({
|
|
81
81
|
default: false,
|
|
82
82
|
message: 'Continue with re-initialization?',
|
|
83
83
|
});
|
|
84
84
|
}
|
|
85
|
-
createServices() {
|
|
86
|
-
const envConfig = getCurrentConfig();
|
|
87
|
-
const tokenStore = new KeychainTokenStore();
|
|
88
|
-
const trackingService = new MixpanelTrackingService(tokenStore);
|
|
89
|
-
const fileService = new FsFileService();
|
|
90
|
-
const templateLoader = new FsTemplateLoader(fileService);
|
|
91
|
-
const ruleTemplateService = new RuleTemplateService(templateLoader);
|
|
92
|
-
const legacyRuleDetector = new LegacyRuleDetector();
|
|
93
|
-
const contextTreeSnapshotService = new FileContextTreeSnapshotService();
|
|
94
|
-
return {
|
|
95
|
-
cogitPullService: new HttpCogitPullService({
|
|
96
|
-
apiBaseUrl: envConfig.cogitApiBaseUrl,
|
|
97
|
-
}),
|
|
98
|
-
contextTreeService: new FileContextTreeService(),
|
|
99
|
-
contextTreeSnapshotService,
|
|
100
|
-
contextTreeWriterService: new FileContextTreeWriterService({ snapshotService: contextTreeSnapshotService }),
|
|
101
|
-
fileService,
|
|
102
|
-
legacyRuleDetector,
|
|
103
|
-
projectConfigStore: new ProjectConfigStore(),
|
|
104
|
-
// ruleWriterService: new RuleWriterService(fileService, ruleTemplateService),
|
|
105
|
-
spaceService: new HttpSpaceService({
|
|
106
|
-
apiBaseUrl: envConfig.apiBaseUrl,
|
|
107
|
-
}),
|
|
108
|
-
teamService: new HttpTeamService({
|
|
109
|
-
apiBaseUrl: envConfig.apiBaseUrl,
|
|
110
|
-
}),
|
|
111
|
-
templateService: ruleTemplateService,
|
|
112
|
-
tokenStore,
|
|
113
|
-
trackingService,
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
85
|
detectWorkspacesForAgent(agent) {
|
|
117
86
|
const detector = new WorkspaceDetectorService();
|
|
118
87
|
const result = detector.detectWorkspaces(agent);
|
|
@@ -121,42 +90,44 @@ export default class Init extends Command {
|
|
|
121
90
|
cwd: result.cwd,
|
|
122
91
|
};
|
|
123
92
|
}
|
|
124
|
-
async ensureAuthenticated(
|
|
125
|
-
const token = await tokenStore.load();
|
|
93
|
+
async ensureAuthenticated() {
|
|
94
|
+
const token = await this.tokenStore.load();
|
|
126
95
|
if (token === undefined) {
|
|
127
|
-
this.
|
|
96
|
+
this.terminal.log('Not authenticated. Please run "brv login" first.');
|
|
97
|
+
return undefined;
|
|
128
98
|
}
|
|
129
99
|
if (!token.isValid()) {
|
|
130
|
-
this.
|
|
100
|
+
this.terminal.log('Authentication token expired. Please run "brv login" again.');
|
|
101
|
+
return undefined;
|
|
131
102
|
}
|
|
132
103
|
return token;
|
|
133
104
|
}
|
|
134
|
-
async fetchAndSelectSpace(
|
|
135
|
-
|
|
136
|
-
const { spaces } = await spaceService.getSpaces(token.accessToken, token.sessionKey, team.id, { fetchAll: true });
|
|
137
|
-
|
|
105
|
+
async fetchAndSelectSpace(token, team) {
|
|
106
|
+
this.terminal.actionStart('\nFetching all spaces');
|
|
107
|
+
const { spaces } = await this.spaceService.getSpaces(token.accessToken, token.sessionKey, team.id, { fetchAll: true });
|
|
108
|
+
this.terminal.actionStop();
|
|
138
109
|
if (spaces.length === 0) {
|
|
139
|
-
this.log(`No spaces found in team "${team.getDisplayName()}"`);
|
|
140
|
-
this.log(`Please visit ${getCurrentConfig().webAppUrl} to create your first space for ${team.getDisplayName()}.`);
|
|
110
|
+
this.terminal.log(`No spaces found in team "${team.getDisplayName()}"`);
|
|
111
|
+
this.terminal.log(`Please visit ${getCurrentConfig().webAppUrl} to create your first space for ${team.getDisplayName()}.`);
|
|
141
112
|
return undefined;
|
|
142
113
|
}
|
|
143
|
-
this.log();
|
|
114
|
+
this.terminal.log();
|
|
144
115
|
return this.promptForSpaceSelection(spaces);
|
|
145
116
|
}
|
|
146
|
-
async fetchAndSelectTeam(
|
|
147
|
-
|
|
148
|
-
const { teams } = await teamService.getTeams(token.accessToken, token.sessionKey, { fetchAll: true });
|
|
149
|
-
|
|
117
|
+
async fetchAndSelectTeam(token) {
|
|
118
|
+
this.terminal.actionStart('Fetching all teams');
|
|
119
|
+
const { teams } = await this.teamService.getTeams(token.accessToken, token.sessionKey, { fetchAll: true });
|
|
120
|
+
this.terminal.actionStop();
|
|
150
121
|
if (teams.length === 0) {
|
|
151
|
-
this.log('No teams found.');
|
|
152
|
-
this.log(`Please visit ${getCurrentConfig().webAppUrl} to create your first team.`);
|
|
122
|
+
this.terminal.log('No teams found.');
|
|
123
|
+
this.terminal.log(`Please visit ${getCurrentConfig().webAppUrl} to create your first team.`);
|
|
153
124
|
return undefined;
|
|
154
125
|
}
|
|
155
|
-
this.log();
|
|
126
|
+
this.terminal.log();
|
|
156
127
|
return this.promptForTeamSelection(teams);
|
|
157
128
|
}
|
|
158
|
-
async generateRulesForAgent(selectedAgent
|
|
159
|
-
this.log(`Generating rules for: ${selectedAgent}`);
|
|
129
|
+
async generateRulesForAgent(selectedAgent) {
|
|
130
|
+
this.terminal.log(`Generating rules for: ${selectedAgent}`);
|
|
160
131
|
// try {
|
|
161
132
|
// await ruleWriterService.writeRule(agent, false)
|
|
162
133
|
// this.log(`✅ Successfully generated rule file for ${agent}`)
|
|
@@ -175,24 +146,22 @@ export default class Init extends Command {
|
|
|
175
146
|
// }
|
|
176
147
|
const { filePath, writeMode } = AGENT_RULE_CONFIGS[selectedAgent];
|
|
177
148
|
// STEP 1: Check if file exists
|
|
178
|
-
const fileExists = await fileService.exists(filePath);
|
|
149
|
+
const fileExists = await this.fileService.exists(filePath);
|
|
179
150
|
if (!fileExists) {
|
|
180
151
|
// Scenario A: File doesn't exist
|
|
181
152
|
const shouldCreate = await this.promptForFileCreation(selectedAgent, filePath);
|
|
182
153
|
if (!shouldCreate) {
|
|
183
|
-
this.log(`Skipped rule file creation for ${selectedAgent}`);
|
|
154
|
+
this.terminal.log(`Skipped rule file creation for ${selectedAgent}`);
|
|
184
155
|
return;
|
|
185
156
|
}
|
|
186
157
|
await this.createNewRuleFile({
|
|
187
158
|
agent: selectedAgent,
|
|
188
159
|
filePath,
|
|
189
|
-
fileService,
|
|
190
|
-
templateService,
|
|
191
160
|
});
|
|
192
161
|
return;
|
|
193
162
|
}
|
|
194
163
|
// STEP 2: File exists - read content
|
|
195
|
-
const content = await fileService.read(filePath);
|
|
164
|
+
const content = await this.fileService.read(filePath);
|
|
196
165
|
// STEP 3: Check for LEGACY rules (priority: clean these up first)
|
|
197
166
|
const hasFooterTag = content.includes(`${BRV_RULE_TAG} ${selectedAgent}`);
|
|
198
167
|
const hasBoundaryMarkers = content.includes(BRV_RULE_MARKERS.START) && content.includes(BRV_RULE_MARKERS.END);
|
|
@@ -203,9 +172,6 @@ export default class Init extends Command {
|
|
|
203
172
|
agent: selectedAgent,
|
|
204
173
|
content,
|
|
205
174
|
filePath,
|
|
206
|
-
fileService,
|
|
207
|
-
legacyRuleDetector,
|
|
208
|
-
templateService,
|
|
209
175
|
});
|
|
210
176
|
return;
|
|
211
177
|
}
|
|
@@ -214,15 +180,13 @@ export default class Init extends Command {
|
|
|
214
180
|
// Scenario C: New rules exist - prompt for overwrite
|
|
215
181
|
const shouldOverwrite = await this.promptForOverwriteConfirmation(selectedAgent);
|
|
216
182
|
if (!shouldOverwrite) {
|
|
217
|
-
this.log(`Skipped rule file update for ${selectedAgent}`);
|
|
183
|
+
this.terminal.log(`Skipped rule file update for ${selectedAgent}`);
|
|
218
184
|
return;
|
|
219
185
|
}
|
|
220
186
|
await this.replaceExistingRules({
|
|
221
187
|
agent: selectedAgent,
|
|
222
188
|
content,
|
|
223
189
|
filePath,
|
|
224
|
-
fileService,
|
|
225
|
-
templateService,
|
|
226
190
|
writeMode,
|
|
227
191
|
});
|
|
228
192
|
return;
|
|
@@ -231,17 +195,15 @@ export default class Init extends Command {
|
|
|
231
195
|
await this.appendRulesToFile({
|
|
232
196
|
agent: selectedAgent,
|
|
233
197
|
filePath,
|
|
234
|
-
fileService,
|
|
235
|
-
templateService,
|
|
236
198
|
writeMode,
|
|
237
199
|
});
|
|
238
200
|
}
|
|
239
|
-
async getExistingConfig(
|
|
240
|
-
const exists = await projectConfigStore.exists();
|
|
201
|
+
async getExistingConfig() {
|
|
202
|
+
const exists = await this.projectConfigStore.exists();
|
|
241
203
|
if (!exists)
|
|
242
204
|
return undefined;
|
|
243
205
|
try {
|
|
244
|
-
const projectConfig = await projectConfigStore.read();
|
|
206
|
+
const projectConfig = await this.projectConfigStore.read();
|
|
245
207
|
if (projectConfig === undefined) {
|
|
246
208
|
throw new Error('Configuration file exists but cannot be read. Please check .brv/config.json');
|
|
247
209
|
}
|
|
@@ -266,13 +228,13 @@ export default class Init extends Command {
|
|
|
266
228
|
}
|
|
267
229
|
}
|
|
268
230
|
async initializeMemoryContextDir(name, initFn) {
|
|
269
|
-
this.log(`\nInitializing ${name}...`);
|
|
231
|
+
this.terminal.log(`\nInitializing ${name}...`);
|
|
270
232
|
try {
|
|
271
233
|
const path = await initFn();
|
|
272
|
-
this.log(`✓ ${name} initialized in ${path}`);
|
|
234
|
+
this.terminal.log(`✓ ${name} initialized in ${path}`);
|
|
273
235
|
}
|
|
274
236
|
catch (error) {
|
|
275
|
-
this.warn(`${name} initialization skipped: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
237
|
+
this.terminal.warn(`${name} initialization skipped: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
276
238
|
}
|
|
277
239
|
}
|
|
278
240
|
isLegacyProjectConfig(config) {
|
|
@@ -287,13 +249,13 @@ export default class Init extends Command {
|
|
|
287
249
|
return normalizedPath === 'README.md';
|
|
288
250
|
}
|
|
289
251
|
async promptAceDeprecationRemoval() {
|
|
290
|
-
this.log('\n The ACE system is being deprecated.');
|
|
291
|
-
this.log(' ByteRover is migrating to the new Context Tree system for improved');
|
|
292
|
-
this.log(' memory organization and retrieval.');
|
|
293
|
-
this.log('');
|
|
294
|
-
this.log(' We detected an existing ACE folder at .brv/ace/');
|
|
295
|
-
this.log(' This folder and all its contents can be safely removed.\n');
|
|
296
|
-
return confirm({
|
|
252
|
+
this.terminal.log('\n The ACE system is being deprecated.');
|
|
253
|
+
this.terminal.log(' ByteRover is migrating to the new Context Tree system for improved');
|
|
254
|
+
this.terminal.log(' memory organization and retrieval.');
|
|
255
|
+
this.terminal.log('');
|
|
256
|
+
this.terminal.log(' We detected an existing ACE folder at .brv/ace/');
|
|
257
|
+
this.terminal.log(' This folder and all its contents can be safely removed.\n');
|
|
258
|
+
return this.terminal.confirm({
|
|
297
259
|
default: true,
|
|
298
260
|
message: 'Remove the ACE folder and its contents?',
|
|
299
261
|
});
|
|
@@ -308,16 +270,15 @@ export default class Init extends Command {
|
|
|
308
270
|
name: agent,
|
|
309
271
|
value: agent,
|
|
310
272
|
}));
|
|
311
|
-
|
|
273
|
+
return this.terminal.search({
|
|
312
274
|
message: 'Which agent you are using (type to search):',
|
|
313
|
-
|
|
275
|
+
source(input) {
|
|
314
276
|
if (!input)
|
|
315
277
|
return AGENTS;
|
|
316
278
|
return AGENTS.filter((agent) => agent.name.toLowerCase().includes(input.toLowerCase()) ||
|
|
317
279
|
agent.value.toLowerCase().includes(input.toLowerCase()));
|
|
318
280
|
},
|
|
319
281
|
});
|
|
320
|
-
return answer;
|
|
321
282
|
}
|
|
322
283
|
/**
|
|
323
284
|
* Prompts the user to choose cleanup strategy for legacy rules.
|
|
@@ -325,7 +286,7 @@ export default class Init extends Command {
|
|
|
325
286
|
* @returns The chosen cleanup strategy
|
|
326
287
|
*/
|
|
327
288
|
async promptForCleanupStrategy() {
|
|
328
|
-
return select({
|
|
289
|
+
return this.terminal.select({
|
|
329
290
|
choices: [
|
|
330
291
|
{
|
|
331
292
|
description: 'New rules will be added with boundary markers. You manually remove old sections at your convenience.',
|
|
@@ -349,7 +310,7 @@ export default class Init extends Command {
|
|
|
349
310
|
* @returns True if the user wants to create the file, false otherwise
|
|
350
311
|
*/
|
|
351
312
|
async promptForFileCreation(agent, filePath) {
|
|
352
|
-
return confirm({
|
|
313
|
+
return this.terminal.confirm({
|
|
353
314
|
default: true,
|
|
354
315
|
message: `Rule file '${filePath}' doesn't exist. Create it with ByteRover rules?`,
|
|
355
316
|
});
|
|
@@ -359,13 +320,13 @@ export default class Init extends Command {
|
|
|
359
320
|
* This method is protected to allow test overrides.
|
|
360
321
|
*/
|
|
361
322
|
async promptForOverwriteConfirmation(agent) {
|
|
362
|
-
return confirm({
|
|
323
|
+
return this.terminal.confirm({
|
|
363
324
|
default: true,
|
|
364
325
|
message: `Rule file already exists for ${agent}. Overwrite?`,
|
|
365
326
|
});
|
|
366
327
|
}
|
|
367
328
|
async promptForSpaceSelection(spaces) {
|
|
368
|
-
const selectedSpaceId = await select({
|
|
329
|
+
const selectedSpaceId = await this.terminal.select({
|
|
369
330
|
choices: spaces.map((space) => ({
|
|
370
331
|
name: space.getDisplayName(),
|
|
371
332
|
value: space.id,
|
|
@@ -374,12 +335,13 @@ export default class Init extends Command {
|
|
|
374
335
|
});
|
|
375
336
|
const selectedSpace = spaces.find((space) => space.id === selectedSpaceId);
|
|
376
337
|
if (!selectedSpace) {
|
|
377
|
-
this.
|
|
338
|
+
this.terminal.log('Space selection failed');
|
|
339
|
+
return undefined;
|
|
378
340
|
}
|
|
379
341
|
return selectedSpace;
|
|
380
342
|
}
|
|
381
343
|
async promptForTeamSelection(teams) {
|
|
382
|
-
const selectedTeamId = await select({
|
|
344
|
+
const selectedTeamId = await this.terminal.select({
|
|
383
345
|
choices: teams.map((team) => ({
|
|
384
346
|
name: team.name,
|
|
385
347
|
value: team.id,
|
|
@@ -388,7 +350,8 @@ export default class Init extends Command {
|
|
|
388
350
|
});
|
|
389
351
|
const selectedTeam = teams.find((team) => team.id === selectedTeamId);
|
|
390
352
|
if (!selectedTeam) {
|
|
391
|
-
this.
|
|
353
|
+
this.terminal.log('Team selection failed');
|
|
354
|
+
return undefined;
|
|
392
355
|
}
|
|
393
356
|
return selectedTeam;
|
|
394
357
|
}
|
|
@@ -397,30 +360,28 @@ export default class Init extends Command {
|
|
|
397
360
|
const acePath = join(dir, BRV_DIR, ACE_DIR);
|
|
398
361
|
await rm(acePath, { force: true, recursive: true });
|
|
399
362
|
}
|
|
400
|
-
async run() {
|
|
363
|
+
async run(options) {
|
|
401
364
|
try {
|
|
402
|
-
const
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
const authToken = await this.ensureAuthenticated(tokenStore);
|
|
407
|
-
const existingConfig = await this.getExistingConfig(projectConfigStore);
|
|
365
|
+
const authToken = await this.ensureAuthenticated();
|
|
366
|
+
if (!authToken)
|
|
367
|
+
return;
|
|
368
|
+
const existingConfig = await this.getExistingConfig();
|
|
408
369
|
if (existingConfig) {
|
|
409
|
-
const shouldCleanup =
|
|
370
|
+
const shouldCleanup = options.force ? true : await this.confirmReInitialization(existingConfig);
|
|
410
371
|
if (shouldCleanup) {
|
|
411
372
|
await this.cleanupBeforeReInitialization();
|
|
412
|
-
this.log('\n');
|
|
373
|
+
this.terminal.log('\n');
|
|
413
374
|
}
|
|
414
375
|
else {
|
|
415
|
-
this.log('\nCancelled. Project configuration unchanged.');
|
|
376
|
+
this.terminal.log('\nCancelled. Project configuration unchanged.');
|
|
416
377
|
return;
|
|
417
378
|
}
|
|
418
379
|
}
|
|
419
|
-
this.log('Initializing ByteRover project...\n');
|
|
420
|
-
const selectedTeam = await this.fetchAndSelectTeam(
|
|
380
|
+
this.terminal.log('Initializing ByteRover project...\n');
|
|
381
|
+
const selectedTeam = await this.fetchAndSelectTeam(authToken);
|
|
421
382
|
if (!selectedTeam)
|
|
422
383
|
return;
|
|
423
|
-
const selectedSpace = await this.fetchAndSelectSpace(
|
|
384
|
+
const selectedSpace = await this.fetchAndSelectSpace(authToken, selectedTeam);
|
|
424
385
|
if (!selectedSpace)
|
|
425
386
|
return;
|
|
426
387
|
// Handle ACE deprecation - check for existing ACE folder and offer removal
|
|
@@ -429,46 +390,44 @@ export default class Init extends Command {
|
|
|
429
390
|
const shouldRemoveAce = await this.promptAceDeprecationRemoval();
|
|
430
391
|
if (shouldRemoveAce) {
|
|
431
392
|
await this.removeAceDirectory();
|
|
432
|
-
this.log('✓ ACE folder removed');
|
|
393
|
+
this.terminal.log('✓ ACE folder removed');
|
|
433
394
|
}
|
|
434
395
|
}
|
|
435
396
|
// Sync from remote or initialize context tree with templates
|
|
436
397
|
await this.syncFromRemoteOrInitialize({
|
|
437
|
-
cogitPullService,
|
|
438
|
-
contextTreeService,
|
|
439
|
-
contextTreeSnapshotService,
|
|
440
|
-
contextTreeWriterService,
|
|
441
398
|
projectConfig: { spaceId: selectedSpace.id, teamId: selectedTeam.id },
|
|
442
399
|
token: authToken,
|
|
443
400
|
});
|
|
444
|
-
this.log();
|
|
401
|
+
this.terminal.log();
|
|
445
402
|
const selectedAgent = await this.promptForAgentSelection();
|
|
446
|
-
this.log('Detecting workspaces...');
|
|
403
|
+
this.terminal.log('Detecting workspaces...');
|
|
447
404
|
const { chatLogPath, cwd } = this.detectWorkspacesForAgent(selectedAgent);
|
|
448
|
-
this.log(`✓ Detected workspace: ${cwd}`);
|
|
405
|
+
this.terminal.log(`✓ Detected workspace: ${cwd}`);
|
|
449
406
|
const config = BrvConfig.fromSpace({
|
|
450
407
|
chatLogPath,
|
|
451
408
|
cwd,
|
|
452
409
|
ide: selectedAgent,
|
|
453
410
|
space: selectedSpace,
|
|
454
411
|
});
|
|
455
|
-
await projectConfigStore.write(config);
|
|
456
|
-
this.log(`\nGenerate rule instructions for coding agents to work with ByteRover correctly`);
|
|
457
|
-
this.log();
|
|
458
|
-
await this.generateRulesForAgent(selectedAgent
|
|
459
|
-
await trackingService.track('rule:generate');
|
|
460
|
-
await trackingService.track('space:init');
|
|
412
|
+
await this.projectConfigStore.write(config);
|
|
413
|
+
this.terminal.log(`\nGenerate rule instructions for coding agents to work with ByteRover correctly`);
|
|
414
|
+
this.terminal.log();
|
|
415
|
+
await this.generateRulesForAgent(selectedAgent);
|
|
416
|
+
await this.trackingService.track('rule:generate');
|
|
417
|
+
await this.trackingService.track('space:init');
|
|
461
418
|
this.logSuccess(selectedSpace);
|
|
462
419
|
}
|
|
463
420
|
catch (error) {
|
|
464
|
-
|
|
421
|
+
// Stop action if it's in progress
|
|
422
|
+
this.terminal.actionStop();
|
|
423
|
+
this.terminal.error(`Initialization failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
465
424
|
}
|
|
466
425
|
}
|
|
467
426
|
async syncFromRemoteOrInitialize(params) {
|
|
468
427
|
// Pull from remote - fail if network/API error
|
|
469
|
-
this.log('\nSyncing from ByteRover...');
|
|
428
|
+
this.terminal.log('\nSyncing from ByteRover...');
|
|
470
429
|
try {
|
|
471
|
-
const coGitSnapshot = await
|
|
430
|
+
const coGitSnapshot = await this.cogitPullService.pull({
|
|
472
431
|
accessToken: params.token.accessToken,
|
|
473
432
|
branch: DEFAULT_BRANCH,
|
|
474
433
|
sessionKey: params.token.sessionKey,
|
|
@@ -481,15 +440,15 @@ export default class Init extends Command {
|
|
|
481
440
|
(coGitSnapshot.files.length === 1 && this.isReadmePlaceholder(coGitSnapshot.files[0].path));
|
|
482
441
|
if (isEmptySpace) {
|
|
483
442
|
// Remote is empty - ignore placeholder, create templates with empty snapshot
|
|
484
|
-
await this.initializeMemoryContextDir('context tree', () =>
|
|
485
|
-
await
|
|
486
|
-
this.log('✓ Context tree initialized');
|
|
443
|
+
await this.initializeMemoryContextDir('context tree', () => this.contextTreeService.initialize());
|
|
444
|
+
await this.contextTreeSnapshotService.initEmptySnapshot();
|
|
445
|
+
this.terminal.log('✓ Context tree initialized');
|
|
487
446
|
}
|
|
488
447
|
else {
|
|
489
448
|
// Remote has real data - sync it to local
|
|
490
|
-
await
|
|
491
|
-
await
|
|
492
|
-
this.log(`✓ Synced ${coGitSnapshot.files.length} context files from remote`);
|
|
449
|
+
await this.contextTreeWriterService.sync({ files: [...coGitSnapshot.files] });
|
|
450
|
+
await this.contextTreeSnapshotService.saveSnapshot();
|
|
451
|
+
this.terminal.log(`✓ Synced ${coGitSnapshot.files.length} context files from remote`);
|
|
493
452
|
}
|
|
494
453
|
}
|
|
495
454
|
catch (error) {
|
|
@@ -500,48 +459,46 @@ export default class Init extends Command {
|
|
|
500
459
|
* Appends ByteRover rules to a file that has no ByteRover content.
|
|
501
460
|
*/
|
|
502
461
|
async appendRulesToFile(params) {
|
|
503
|
-
const { agent, filePath,
|
|
504
|
-
const ruleContent = await templateService.generateRuleContent(agent);
|
|
462
|
+
const { agent, filePath, writeMode } = params;
|
|
463
|
+
const ruleContent = await this.templateService.generateRuleContent(agent);
|
|
505
464
|
// For dedicated ByteRover files, overwrite; for shared instruction files, append
|
|
506
465
|
const mode = writeMode === 'overwrite' ? 'overwrite' : 'append';
|
|
507
|
-
await fileService.write(ruleContent, filePath, mode);
|
|
508
|
-
this.log(`✅ Successfully added rule file for ${agent}`);
|
|
466
|
+
await this.fileService.write(ruleContent, filePath, mode);
|
|
467
|
+
this.terminal.log(`✅ Successfully added rule file for ${agent}`);
|
|
509
468
|
}
|
|
510
469
|
/**
|
|
511
470
|
* Creates a new rule file with ByteRover rules.
|
|
512
471
|
*/
|
|
513
472
|
async createNewRuleFile(params) {
|
|
514
|
-
const { agent, filePath
|
|
515
|
-
const ruleContent = await templateService.generateRuleContent(agent);
|
|
516
|
-
await fileService.write(ruleContent, filePath, 'overwrite');
|
|
517
|
-
this.log(`✅ Successfully created rule file for ${agent} at ${filePath}`);
|
|
473
|
+
const { agent, filePath } = params;
|
|
474
|
+
const ruleContent = await this.templateService.generateRuleContent(agent);
|
|
475
|
+
await this.fileService.write(ruleContent, filePath, 'overwrite');
|
|
476
|
+
this.terminal.log(`✅ Successfully created rule file for ${agent} at ${filePath}`);
|
|
518
477
|
}
|
|
519
478
|
async handleLegacyRulesCleanup(params) {
|
|
520
|
-
const { agent, content, filePath
|
|
521
|
-
const detectionResult = legacyRuleDetector.detectLegacyRules(content, agent);
|
|
479
|
+
const { agent, content, filePath } = params;
|
|
480
|
+
const detectionResult = this.legacyRuleDetector.detectLegacyRules(content, agent);
|
|
522
481
|
const { reliableMatches, uncertainMatches } = detectionResult;
|
|
523
|
-
this.log(`\n⚠️ Detected ${reliableMatches.length + uncertainMatches.length} old ByteRover rule section(s) in ${filePath}:\n`);
|
|
482
|
+
this.terminal.log(`\n⚠️ Detected ${reliableMatches.length + uncertainMatches.length} old ByteRover rule section(s) in ${filePath}:\n`);
|
|
524
483
|
if (reliableMatches.length > 0) {
|
|
525
|
-
this.log('Reliable matches:');
|
|
484
|
+
this.terminal.log('Reliable matches:');
|
|
526
485
|
for (const [index, match] of reliableMatches.entries()) {
|
|
527
|
-
this.log(` Section ${index + 1}: lines ${match.startLine}-${match.endLine}`);
|
|
486
|
+
this.terminal.log(` Section ${index + 1}: lines ${match.startLine}-${match.endLine}`);
|
|
528
487
|
}
|
|
529
|
-
this.log();
|
|
488
|
+
this.terminal.log();
|
|
530
489
|
}
|
|
531
490
|
if (uncertainMatches.length > 0) {
|
|
532
|
-
this.log(' ⚠️ Uncertain matches (cannot determine start):');
|
|
491
|
+
this.terminal.log(' ⚠️ Uncertain matches (cannot determine start):');
|
|
533
492
|
for (const match of uncertainMatches) {
|
|
534
|
-
this.log(` Footer found at line ${match.footerLine}`);
|
|
535
|
-
this.log(` Reason: ${match.reason}`);
|
|
493
|
+
this.terminal.log(` Footer found at line ${match.footerLine}`);
|
|
494
|
+
this.terminal.log(` Reason: ${match.reason}`);
|
|
536
495
|
}
|
|
537
|
-
this.log();
|
|
538
|
-
this.log('⚠️ Due to uncertain matches, only manual cleanup is available.\n');
|
|
496
|
+
this.terminal.log();
|
|
497
|
+
this.terminal.log('⚠️ Due to uncertain matches, only manual cleanup is available.\n');
|
|
539
498
|
await this.performManualCleanup({
|
|
540
499
|
agent,
|
|
541
500
|
filePath,
|
|
542
|
-
fileService,
|
|
543
501
|
reliableMatches,
|
|
544
|
-
templateService,
|
|
545
502
|
uncertainMatches,
|
|
546
503
|
});
|
|
547
504
|
return;
|
|
@@ -551,69 +508,65 @@ export default class Init extends Command {
|
|
|
551
508
|
? this.performManualCleanup({
|
|
552
509
|
agent,
|
|
553
510
|
filePath,
|
|
554
|
-
fileService,
|
|
555
511
|
reliableMatches,
|
|
556
|
-
templateService,
|
|
557
512
|
uncertainMatches,
|
|
558
513
|
})
|
|
559
514
|
: this.performAutomaticCleanup({
|
|
560
515
|
agent,
|
|
561
516
|
filePath,
|
|
562
|
-
fileService,
|
|
563
517
|
reliableMatches,
|
|
564
|
-
templateService,
|
|
565
518
|
}));
|
|
566
519
|
}
|
|
567
520
|
logSuccess(space) {
|
|
568
|
-
this.log(`\n✓ Project initialized successfully!`);
|
|
569
|
-
this.log(`✓ Connected to space: ${space.getDisplayName()}`);
|
|
570
|
-
this.log(`✓ Configuration saved to: ${BRV_DIR}/${PROJECT_CONFIG_FILE}`);
|
|
571
|
-
this.log("NOTE: It's recommended to add .brv/ to your .gitignore file since ByteRover already takes care of memory/context versioning for you.");
|
|
521
|
+
this.terminal.log(`\n✓ Project initialized successfully!`);
|
|
522
|
+
this.terminal.log(`✓ Connected to space: ${space.getDisplayName()}`);
|
|
523
|
+
this.terminal.log(`✓ Configuration saved to: ${BRV_DIR}/${PROJECT_CONFIG_FILE}`);
|
|
524
|
+
this.terminal.log("NOTE: It's recommended to add .brv/ to your .gitignore file since ByteRover already takes care of memory/context versioning for you.");
|
|
572
525
|
}
|
|
573
526
|
async performAutomaticCleanup(params) {
|
|
574
|
-
const { agent, filePath,
|
|
575
|
-
const backupPath = await fileService.createBackup(filePath);
|
|
576
|
-
this.log(`📦 Backup created: ${backupPath}`);
|
|
577
|
-
let content = await fileService.read(filePath);
|
|
527
|
+
const { agent, filePath, reliableMatches } = params;
|
|
528
|
+
const backupPath = await this.fileService.createBackup(filePath);
|
|
529
|
+
this.terminal.log(`📦 Backup created: ${backupPath}`);
|
|
530
|
+
let content = await this.fileService.read(filePath);
|
|
578
531
|
// Remove all reliable matches (in reverse order to preserve line numbers)
|
|
579
532
|
const sortedMatches = [...reliableMatches].sort((a, b) => b.startLine - a.startLine);
|
|
580
533
|
for (const match of sortedMatches) {
|
|
581
534
|
content = content.replace(match.content, '');
|
|
582
535
|
}
|
|
583
536
|
// Write cleaned content
|
|
584
|
-
await fileService.write(content, filePath, 'overwrite');
|
|
537
|
+
await this.fileService.write(content, filePath, 'overwrite');
|
|
585
538
|
// Append new rules
|
|
586
|
-
const ruleContent = await templateService.generateRuleContent(agent);
|
|
587
|
-
await fileService.write(ruleContent, filePath, 'append');
|
|
588
|
-
this.log(`✅ Removed ${reliableMatches.length} old ByteRover section(s)`);
|
|
589
|
-
this.log(`✅ Added new rules with boundary markers`);
|
|
590
|
-
this.log(`\nYou can safely delete the backup file once verified.`);
|
|
539
|
+
const ruleContent = await this.templateService.generateRuleContent(agent);
|
|
540
|
+
await this.fileService.write(ruleContent, filePath, 'append');
|
|
541
|
+
this.terminal.log(`✅ Removed ${reliableMatches.length} old ByteRover section(s)`);
|
|
542
|
+
this.terminal.log(`✅ Added new rules with boundary markers`);
|
|
543
|
+
this.terminal.log(`\nYou can safely delete the backup file once verified.`);
|
|
591
544
|
}
|
|
592
545
|
async performManualCleanup(params) {
|
|
593
|
-
const { agent, filePath,
|
|
594
|
-
const ruleContent = await templateService.generateRuleContent(agent);
|
|
595
|
-
await fileService.write(ruleContent, filePath, 'append');
|
|
596
|
-
this.log(`✅ New ByteRover rules added with boundary markers\n`);
|
|
597
|
-
this.log('Please manually remove old sections:');
|
|
546
|
+
const { agent, filePath, reliableMatches, uncertainMatches } = params;
|
|
547
|
+
const ruleContent = await this.templateService.generateRuleContent(agent);
|
|
548
|
+
await this.fileService.write(ruleContent, filePath, 'append');
|
|
549
|
+
this.terminal.log(`✅ New ByteRover rules added with boundary markers\n`);
|
|
550
|
+
this.terminal.log('Please manually remove old sections:');
|
|
598
551
|
for (const [index, match] of reliableMatches.entries()) {
|
|
599
|
-
this.log(` - Section ${index + 1}: lines ${match.startLine}-${match.endLine} in ${filePath}`);
|
|
552
|
+
this.terminal.log(` - Section ${index + 1}: lines ${match.startLine}-${match.endLine} in ${filePath}`);
|
|
600
553
|
}
|
|
601
554
|
for (const match of uncertainMatches) {
|
|
602
|
-
this.log(` - Section ending at line ${match.footerLine} in ${filePath}`);
|
|
555
|
+
this.terminal.log(` - Section ending at line ${match.footerLine} in ${filePath}`);
|
|
603
556
|
}
|
|
604
|
-
this.log('\nKeep only the section between:');
|
|
605
|
-
this.log(' <!-- BEGIN BYTEROVER RULES -->');
|
|
606
|
-
this.log(' <!-- END BYTEROVER RULES -->');
|
|
557
|
+
this.terminal.log('\nKeep only the section between:');
|
|
558
|
+
this.terminal.log(' <!-- BEGIN BYTEROVER RULES -->');
|
|
559
|
+
this.terminal.log(' <!-- END BYTEROVER RULES -->');
|
|
607
560
|
}
|
|
608
561
|
/**
|
|
609
562
|
* Replaces existing ByteRover rules (with boundary markers) with new rules.
|
|
610
563
|
*/
|
|
611
564
|
async replaceExistingRules(params) {
|
|
612
|
-
const { agent, content, filePath,
|
|
613
|
-
const ruleContent = await templateService.generateRuleContent(agent);
|
|
565
|
+
const { agent, content, filePath, writeMode } = params;
|
|
566
|
+
const ruleContent = await this.templateService.generateRuleContent(agent);
|
|
614
567
|
if (writeMode === 'overwrite') {
|
|
615
568
|
// For dedicated ByteRover files, just overwrite the entire file
|
|
616
|
-
await fileService.write(ruleContent, filePath, 'overwrite');
|
|
569
|
+
await this.fileService.write(ruleContent, filePath, 'overwrite');
|
|
617
570
|
}
|
|
618
571
|
else {
|
|
619
572
|
// For shared instruction files, replace the section between markers
|
|
@@ -622,13 +575,14 @@ export default class Init extends Command {
|
|
|
622
575
|
const startIndex = content.indexOf(startMarker);
|
|
623
576
|
const endIndex = content.indexOf(endMarker, startIndex);
|
|
624
577
|
if (startIndex === -1 || endIndex === -1) {
|
|
625
|
-
this.
|
|
578
|
+
this.terminal.log('Could not find boundary markers in the file');
|
|
579
|
+
return;
|
|
626
580
|
}
|
|
627
581
|
const before = content.slice(0, startIndex);
|
|
628
582
|
const after = content.slice(endIndex + endMarker.length);
|
|
629
583
|
const newContent = before + ruleContent + after;
|
|
630
|
-
await fileService.write(newContent, filePath, 'overwrite');
|
|
584
|
+
await this.fileService.write(newContent, filePath, 'overwrite');
|
|
631
585
|
}
|
|
632
|
-
this.log(`✅ Successfully updated rule file for ${agent}`);
|
|
586
|
+
this.terminal.log(`✅ Successfully updated rule file for ${agent}`);
|
|
633
587
|
}
|
|
634
588
|
}
|