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