byterover-cli 0.3.4 → 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/update-notifier.js +1 -5
- 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,5 +1,6 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
2
|
import type { IProjectConfigStore } from '../../core/interfaces/i-project-config-store.js';
|
|
3
|
+
import type { ITerminal } from '../../core/interfaces/i-terminal.js';
|
|
3
4
|
export default class CipherAgentSetPrompt extends Command {
|
|
4
5
|
static args: {
|
|
5
6
|
prompt: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
@@ -7,6 +8,7 @@ export default class CipherAgentSetPrompt extends Command {
|
|
|
7
8
|
static description: string;
|
|
8
9
|
static examples: string[];
|
|
9
10
|
static hidden: boolean;
|
|
11
|
+
protected terminal: ITerminal;
|
|
10
12
|
protected createServices(): {
|
|
11
13
|
projectConfigStore: IProjectConfigStore;
|
|
12
14
|
};
|
|
@@ -2,6 +2,7 @@ import { Args, Command } from '@oclif/core';
|
|
|
2
2
|
import { isDevelopment } from '../../config/environment.js';
|
|
3
3
|
import { BrvConfig } from '../../core/domain/entities/brv-config.js';
|
|
4
4
|
import { ProjectConfigStore } from '../../infra/config/file-config-store.js';
|
|
5
|
+
import { OclifTerminal } from '../../infra/terminal/oclif-terminal.js';
|
|
5
6
|
import { getErrorMessage } from '../../utils/error-helpers.js';
|
|
6
7
|
export default class CipherAgentSetPrompt extends Command {
|
|
7
8
|
static args = {
|
|
@@ -13,27 +14,31 @@ export default class CipherAgentSetPrompt extends Command {
|
|
|
13
14
|
'<%= config.bin %> <%= command.id %> "You are an expert in refactoring and code quality improvements"',
|
|
14
15
|
];
|
|
15
16
|
static hidden = !isDevelopment();
|
|
17
|
+
terminal = {};
|
|
16
18
|
createServices() {
|
|
19
|
+
this.terminal = new OclifTerminal(this);
|
|
17
20
|
return {
|
|
18
21
|
projectConfigStore: new ProjectConfigStore(),
|
|
19
22
|
};
|
|
20
23
|
}
|
|
21
24
|
async run() {
|
|
25
|
+
const { projectConfigStore } = this.createServices();
|
|
22
26
|
if (!isDevelopment()) {
|
|
23
|
-
this.error('This command is only available in development environment');
|
|
27
|
+
this.terminal.error('This command is only available in development environment');
|
|
28
|
+
return;
|
|
24
29
|
}
|
|
25
30
|
const { args } = await this.parse(CipherAgentSetPrompt);
|
|
26
31
|
try {
|
|
27
|
-
const { projectConfigStore } = this.createServices();
|
|
28
32
|
// Check if config exists
|
|
29
33
|
const configExists = await projectConfigStore.exists();
|
|
30
34
|
if (!configExists) {
|
|
31
|
-
this.error('No ByteRover config found. Please run "byterover init" first to initialize the project.');
|
|
35
|
+
this.terminal.error('No ByteRover config found. Please run "byterover init" first to initialize the project.');
|
|
32
36
|
}
|
|
33
37
|
// Read existing config
|
|
34
38
|
const existingConfig = await projectConfigStore.read();
|
|
35
39
|
if (!existingConfig) {
|
|
36
|
-
this.error('Failed to read existing config.');
|
|
40
|
+
this.terminal.error('Failed to read existing config.');
|
|
41
|
+
return;
|
|
37
42
|
}
|
|
38
43
|
// Create updated config with new system prompt
|
|
39
44
|
const updatedConfig = new BrvConfig({
|
|
@@ -42,12 +47,12 @@ export default class CipherAgentSetPrompt extends Command {
|
|
|
42
47
|
});
|
|
43
48
|
// Write updated config
|
|
44
49
|
await projectConfigStore.write(updatedConfig);
|
|
45
|
-
this.log('✓ CipherAgent system prompt updated successfully!');
|
|
46
|
-
this.log('\nNew prompt:');
|
|
47
|
-
this.log(args.prompt);
|
|
50
|
+
this.terminal.log('✓ CipherAgent system prompt updated successfully!');
|
|
51
|
+
this.terminal.log('\nNew prompt:');
|
|
52
|
+
this.terminal.log(args.prompt);
|
|
48
53
|
}
|
|
49
54
|
catch (error) {
|
|
50
|
-
this.error(`Failed to set system prompt: ${getErrorMessage(error)}`);
|
|
55
|
+
this.terminal.error(`Failed to set system prompt: ${getErrorMessage(error)}`);
|
|
51
56
|
}
|
|
52
57
|
}
|
|
53
58
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
2
|
import type { IProjectConfigStore } from '../../core/interfaces/i-project-config-store.js';
|
|
3
|
+
import type { ITerminal } from '../../core/interfaces/i-terminal.js';
|
|
3
4
|
export default class CipherAgentShowPrompt extends Command {
|
|
4
5
|
static description: string;
|
|
5
6
|
static examples: string[];
|
|
6
7
|
static hidden: boolean;
|
|
8
|
+
protected terminal: ITerminal;
|
|
7
9
|
protected createServices(): {
|
|
8
10
|
projectConfigStore: IProjectConfigStore;
|
|
9
11
|
};
|
|
@@ -1,48 +1,53 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
2
|
import { isDevelopment } from '../../config/environment.js';
|
|
3
3
|
import { ProjectConfigStore } from '../../infra/config/file-config-store.js';
|
|
4
|
+
import { OclifTerminal } from '../../infra/terminal/oclif-terminal.js';
|
|
4
5
|
import { getErrorMessage } from '../../utils/error-helpers.js';
|
|
5
6
|
export default class CipherAgentShowPrompt extends Command {
|
|
6
7
|
static description = 'Show the current CipherAgent system prompt [Development only]';
|
|
7
8
|
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
8
9
|
static hidden = !isDevelopment();
|
|
10
|
+
terminal = {};
|
|
9
11
|
createServices() {
|
|
12
|
+
this.terminal = new OclifTerminal(this);
|
|
10
13
|
return {
|
|
11
14
|
projectConfigStore: new ProjectConfigStore(),
|
|
12
15
|
};
|
|
13
16
|
}
|
|
14
17
|
async run() {
|
|
18
|
+
const { projectConfigStore } = this.createServices();
|
|
15
19
|
if (!isDevelopment()) {
|
|
16
|
-
this.error('This command is only available in development environment');
|
|
20
|
+
this.terminal.error('This command is only available in development environment');
|
|
21
|
+
return;
|
|
17
22
|
}
|
|
18
23
|
try {
|
|
19
|
-
const { projectConfigStore } = this.createServices();
|
|
20
24
|
// Check if config exists
|
|
21
25
|
const configExists = await projectConfigStore.exists();
|
|
22
26
|
if (!configExists) {
|
|
23
|
-
this.log('No ByteRover config found.');
|
|
24
|
-
this.log('CipherAgent will use the default system prompt.');
|
|
27
|
+
this.terminal.log('No ByteRover config found.');
|
|
28
|
+
this.terminal.log('CipherAgent will use the default system prompt.');
|
|
25
29
|
return;
|
|
26
30
|
}
|
|
27
31
|
// Read existing config
|
|
28
32
|
const config = await projectConfigStore.read();
|
|
29
33
|
if (!config) {
|
|
30
|
-
this.error('Failed to read config.');
|
|
34
|
+
this.terminal.error('Failed to read config.');
|
|
35
|
+
return;
|
|
31
36
|
}
|
|
32
37
|
// Show system prompt
|
|
33
38
|
if (config.cipherAgentSystemPrompt) {
|
|
34
|
-
this.log('Current CipherAgent system prompt:');
|
|
35
|
-
this.log('─'.repeat(60));
|
|
36
|
-
this.log(config.cipherAgentSystemPrompt);
|
|
37
|
-
this.log('─'.repeat(60));
|
|
39
|
+
this.terminal.log('Current CipherAgent system prompt:');
|
|
40
|
+
this.terminal.log('─'.repeat(60));
|
|
41
|
+
this.terminal.log(config.cipherAgentSystemPrompt);
|
|
42
|
+
this.terminal.log('─'.repeat(60));
|
|
38
43
|
}
|
|
39
44
|
else {
|
|
40
|
-
this.log('No custom system prompt configured.');
|
|
41
|
-
this.log('CipherAgent is using the default system prompt.');
|
|
45
|
+
this.terminal.log('No custom system prompt configured.');
|
|
46
|
+
this.terminal.log('CipherAgent is using the default system prompt.');
|
|
42
47
|
}
|
|
43
48
|
}
|
|
44
49
|
catch (error) {
|
|
45
|
-
this.error(`Failed to show system prompt: ${getErrorMessage(error)}`);
|
|
50
|
+
this.terminal.error(`Failed to show system prompt: ${getErrorMessage(error)}`);
|
|
46
51
|
}
|
|
47
52
|
}
|
|
48
53
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
|
-
import type {
|
|
3
|
-
import type { ITrackingService } from '../core/interfaces/i-tracking-service.js';
|
|
2
|
+
import type { ICurateUseCase } from '../core/interfaces/usecase/i-curate-use-case.js';
|
|
4
3
|
export default class Curate extends Command {
|
|
5
4
|
static args: {
|
|
6
5
|
context: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
@@ -11,64 +10,8 @@ export default class Curate extends Command {
|
|
|
11
10
|
apiKey?: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions> | undefined;
|
|
12
11
|
model?: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions> | undefined;
|
|
13
12
|
verbose?: import("@oclif/core/interfaces").BooleanFlag<boolean> | undefined;
|
|
13
|
+
files: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
14
|
};
|
|
15
|
-
|
|
16
|
-
oclif?: {
|
|
17
|
-
exit: number;
|
|
18
|
-
};
|
|
19
|
-
}): Promise<void>;
|
|
20
|
-
protected createServices(): {
|
|
21
|
-
projectConfigStore: IProjectConfigStore;
|
|
22
|
-
trackingService: ITrackingService;
|
|
23
|
-
};
|
|
24
|
-
/**
|
|
25
|
-
* Create topic folder with context.md file
|
|
26
|
-
* @param targetPath - The parent path where the topic folder will be created
|
|
27
|
-
* @param topicName - The name of the topic folder to create
|
|
28
|
-
* @returns The path to the created context.md file
|
|
29
|
-
*/
|
|
30
|
-
protected createTopicWithContextFile(targetPath: string, topicName: string): string;
|
|
31
|
-
/**
|
|
32
|
-
* Generate a unique session ID for the autonomous agent.
|
|
33
|
-
* Uses crypto.randomUUID() for guaranteed uniqueness (122 bits of entropy).
|
|
34
|
-
*/
|
|
35
|
-
protected generateSessionId(): string;
|
|
36
|
-
/**
|
|
37
|
-
* Navigate through the context tree using file selector
|
|
38
|
-
* Returns the selected path relative to context-tree root
|
|
39
|
-
*/
|
|
40
|
-
protected navigateContextTree(): Promise<null | string>;
|
|
41
|
-
/**
|
|
42
|
-
* Open a file in the default editor
|
|
43
|
-
* @param filePath - The path to the file to open
|
|
44
|
-
*/
|
|
45
|
-
protected openFile(filePath: string): Promise<void>;
|
|
46
|
-
/**
|
|
47
|
-
* Prompt user to enter topic name with validation
|
|
48
|
-
* @param targetPath - The path where the topic folder will be created
|
|
49
|
-
* @returns The topic name or null if cancelled
|
|
50
|
-
*/
|
|
51
|
-
protected promptForTopicName(targetPath: string): Promise<null | string>;
|
|
15
|
+
protected createUseCase(): ICurateUseCase;
|
|
52
16
|
run(): Promise<void>;
|
|
53
|
-
/**
|
|
54
|
-
* Write content to context tree at given path
|
|
55
|
-
*/
|
|
56
|
-
protected writeToContextTree(selectedPath: string, content: string): Promise<void>;
|
|
57
|
-
/**
|
|
58
|
-
* Handle workspace not initialized error
|
|
59
|
-
*/
|
|
60
|
-
private handleWorkspaceError;
|
|
61
|
-
/**
|
|
62
|
-
* Run in autonomous mode using CipherAgent
|
|
63
|
-
*/
|
|
64
|
-
private runAutonomous;
|
|
65
|
-
/**
|
|
66
|
-
* Run in interactive mode with manual prompts
|
|
67
|
-
*/
|
|
68
|
-
private runInteractive;
|
|
69
|
-
/**
|
|
70
|
-
* Setup event listeners for CipherAgent
|
|
71
|
-
*/
|
|
72
|
-
private setupEventListeners;
|
|
73
|
-
private validateTopicName;
|
|
74
17
|
}
|
package/dist/commands/curate.js
CHANGED
|
@@ -1,45 +1,43 @@
|
|
|
1
|
-
import { input } from '@inquirer/prompts';
|
|
2
1
|
import { Args, Command, Flags } from '@oclif/core';
|
|
3
|
-
import
|
|
4
|
-
import { fileSelector, ItemType } from 'inquirer-file-selector';
|
|
5
|
-
import { randomUUID } from 'node:crypto';
|
|
6
|
-
import fs from 'node:fs';
|
|
7
|
-
import path from 'node:path';
|
|
8
|
-
import open from 'open';
|
|
9
|
-
import { CONTEXT_TREE_DOMAINS } from '../config/context-tree-domains.js';
|
|
10
|
-
import { getCurrentConfig, isDevelopment } from '../config/environment.js';
|
|
11
|
-
import { BRV_DIR, CONTEXT_FILE, CONTEXT_TREE_DIR, PROJECT } from '../constants.js';
|
|
12
|
-
import { CipherAgent } from '../infra/cipher/cipher-agent.js';
|
|
13
|
-
import { ExitCode, ExitError, exitWithCode } from '../infra/cipher/exit-codes.js';
|
|
14
|
-
import { WorkspaceNotInitializedError } from '../infra/cipher/validation/workspace-validator.js';
|
|
2
|
+
import { isDevelopment } from '../config/environment.js';
|
|
15
3
|
import { ProjectConfigStore } from '../infra/config/file-config-store.js';
|
|
4
|
+
import { FileGlobalConfigStore } from '../infra/storage/file-global-config-store.js';
|
|
16
5
|
import { KeychainTokenStore } from '../infra/storage/keychain-token-store.js';
|
|
6
|
+
import { OclifTerminal } from '../infra/terminal/oclif-terminal.js';
|
|
17
7
|
import { MixpanelTrackingService } from '../infra/tracking/mixpanel-tracking-service.js';
|
|
18
|
-
import {
|
|
19
|
-
import { formatToolCall, formatToolResult } from '../utils/tool-display-formatter.js';
|
|
20
|
-
// Full path to context tree
|
|
21
|
-
const CONTEXT_TREE_PATH = path.join(BRV_DIR, CONTEXT_TREE_DIR);
|
|
8
|
+
import { CurateUseCase } from '../infra/usecase/curate-use-case.js';
|
|
22
9
|
export default class Curate extends Command {
|
|
23
10
|
static args = {
|
|
24
11
|
context: Args.string({
|
|
25
|
-
description: 'Knowledge context: patterns, decisions, errors, or insights
|
|
12
|
+
description: 'Knowledge context: patterns, decisions, errors, or insights',
|
|
26
13
|
required: false,
|
|
27
14
|
}),
|
|
28
15
|
};
|
|
29
|
-
static description = `Curate context to the context tree (
|
|
30
|
-
|
|
16
|
+
static description = `Curate context to the context tree (autonomous mode)
|
|
17
|
+
|
|
18
|
+
For interactive mode, use REPL: brv repl then /curate
|
|
19
|
+
|
|
20
|
+
Good examples:
|
|
31
21
|
- "Auth uses JWT with 24h expiry. Tokens stored in httpOnly cookies via authMiddleware.ts"
|
|
32
22
|
- "API rate limit is 100 req/min per user. Implemented using Redis with sliding window in rateLimiter.ts"
|
|
33
|
-
Bad:
|
|
23
|
+
Bad examples:
|
|
34
24
|
- "Authentication" or "JWT tokens" (too vague, lacks context)
|
|
35
25
|
- "Rate limiting" (no implementation details or file references)`;
|
|
36
26
|
static examples = [
|
|
37
|
-
'# Interactive mode (manually choose domain/topic)',
|
|
38
|
-
'<%= config.bin %> <%= command.id %>',
|
|
39
|
-
'',
|
|
40
27
|
'# Autonomous mode - LLM auto-categorizes your context',
|
|
41
28
|
'<%= config.bin %> <%= command.id %> "Auth uses JWT with 24h expiry. Tokens stored in httpOnly cookies via authMiddleware.ts"',
|
|
42
29
|
'',
|
|
30
|
+
'# Include relevant files for comprehensive context (use sparingly, max 5 files)',
|
|
31
|
+
'- NOTE: CONTEXT argument must come BEFORE --files flag',
|
|
32
|
+
'- NOTE: For multiple files, repeat --files (or -f) flag for each file',
|
|
33
|
+
'- NOTE: Only text/code files from current project directory.',
|
|
34
|
+
'',
|
|
35
|
+
'## Single file',
|
|
36
|
+
'<%= config.bin %> <%= command.id %> "Authentication middleware validates JWT tokens and attaches user context" -f src/middleware/auth.ts',
|
|
37
|
+
'',
|
|
38
|
+
'## Multiple files',
|
|
39
|
+
'<%= config.bin %> <%= command.id %> "JWT authentication implementation with refresh token rotation" --files src/auth/jwt.ts --files docs/auth.md',
|
|
40
|
+
'',
|
|
43
41
|
...(isDevelopment()
|
|
44
42
|
? [
|
|
45
43
|
'# Autonomous mode with OpenRouter (development only)',
|
|
@@ -51,6 +49,11 @@ Bad:
|
|
|
51
49
|
: []),
|
|
52
50
|
];
|
|
53
51
|
static flags = {
|
|
52
|
+
files: Flags.string({
|
|
53
|
+
char: 'f',
|
|
54
|
+
description: 'Include specific file paths for critical context (max 5 files). Only text/code files from the current project directory are allowed. Use sparingly - only for truly relevant files like docs or key implementation details. NOTE: CONTEXT argument must come BEFORE this flag.',
|
|
55
|
+
multiple: true,
|
|
56
|
+
}),
|
|
54
57
|
...(isDevelopment()
|
|
55
58
|
? {
|
|
56
59
|
apiKey: Flags.string({
|
|
@@ -70,327 +73,28 @@ Bad:
|
|
|
70
73
|
}
|
|
71
74
|
: {}),
|
|
72
75
|
};
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
// Backwards compatibility: also check oclif.exit property
|
|
80
|
-
if (error.oclif?.exit !== undefined) {
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
// For other errors, re-throw to let oclif handle them
|
|
84
|
-
throw error;
|
|
85
|
-
}
|
|
86
|
-
createServices() {
|
|
87
|
-
return {
|
|
76
|
+
createUseCase() {
|
|
77
|
+
const tokenStore = new KeychainTokenStore();
|
|
78
|
+
const globalConfigStore = new FileGlobalConfigStore();
|
|
79
|
+
return new CurateUseCase({
|
|
88
80
|
projectConfigStore: new ProjectConfigStore(),
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
* Create topic folder with context.md file
|
|
94
|
-
* @param targetPath - The parent path where the topic folder will be created
|
|
95
|
-
* @param topicName - The name of the topic folder to create
|
|
96
|
-
* @returns The path to the created context.md file
|
|
97
|
-
*/
|
|
98
|
-
createTopicWithContextFile(targetPath, topicName) {
|
|
99
|
-
const topicPath = path.join(targetPath, topicName);
|
|
100
|
-
const contextFilePath = path.join(topicPath, CONTEXT_FILE);
|
|
101
|
-
// Create the topic directory
|
|
102
|
-
fs.mkdirSync(topicPath, { recursive: true });
|
|
103
|
-
// Create the context.md file with initial content
|
|
104
|
-
const initialContent = `# ${topicName}\n\n<!-- Add your context here -->\n`;
|
|
105
|
-
fs.writeFileSync(contextFilePath, initialContent, 'utf8');
|
|
106
|
-
return contextFilePath;
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Generate a unique session ID for the autonomous agent.
|
|
110
|
-
* Uses crypto.randomUUID() for guaranteed uniqueness (122 bits of entropy).
|
|
111
|
-
*/
|
|
112
|
-
generateSessionId() {
|
|
113
|
-
return randomUUID();
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Navigate through the context tree using file selector
|
|
117
|
-
* Returns the selected path relative to context-tree root
|
|
118
|
-
*/
|
|
119
|
-
async navigateContextTree() {
|
|
120
|
-
const contextTreePath = path.resolve(process.cwd(), CONTEXT_TREE_PATH);
|
|
121
|
-
// Ensure context tree directory exists
|
|
122
|
-
if (!fs.existsSync(contextTreePath)) {
|
|
123
|
-
fs.mkdirSync(contextTreePath, { recursive: true });
|
|
124
|
-
}
|
|
125
|
-
// Ensure predefined domains exist as directories
|
|
126
|
-
for (const domain of CONTEXT_TREE_DOMAINS) {
|
|
127
|
-
const domainPath = path.join(contextTreePath, domain.name);
|
|
128
|
-
if (!fs.existsSync(domainPath)) {
|
|
129
|
-
fs.mkdirSync(domainPath, { recursive: true });
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
while (true) {
|
|
133
|
-
try {
|
|
134
|
-
// eslint-disable-next-line no-await-in-loop
|
|
135
|
-
const selectedItem = await fileSelector({
|
|
136
|
-
allowCancel: true,
|
|
137
|
-
basePath: contextTreePath,
|
|
138
|
-
filter: (item) => item.isDirectory,
|
|
139
|
-
message: 'Target context location:',
|
|
140
|
-
pageSize: 15,
|
|
141
|
-
theme: {
|
|
142
|
-
labels: {
|
|
143
|
-
messages: {
|
|
144
|
-
cancel: 'Selection cancelled.',
|
|
145
|
-
empty: 'No sub-folders. Press Enter to add content here.',
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
},
|
|
149
|
-
type: ItemType.Directory,
|
|
150
|
-
});
|
|
151
|
-
// User cancelled
|
|
152
|
-
if (!selectedItem) {
|
|
153
|
-
return null;
|
|
154
|
-
}
|
|
155
|
-
// Restrict navigation to stay within the context tree
|
|
156
|
-
const normalizedItemPath = path.resolve(selectedItem.path);
|
|
157
|
-
const isValid = normalizedItemPath.startsWith(contextTreePath);
|
|
158
|
-
if (isValid) {
|
|
159
|
-
// Valid selection - proceed
|
|
160
|
-
return selectedItem.path;
|
|
161
|
-
}
|
|
162
|
-
// Invalid selection - retry
|
|
163
|
-
this.log(chalk.red('Invalid selection. Please choose a valid location within the context tree.'));
|
|
164
|
-
}
|
|
165
|
-
catch {
|
|
166
|
-
// Error occurred
|
|
167
|
-
return null;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Open a file in the default editor
|
|
173
|
-
* @param filePath - The path to the file to open
|
|
174
|
-
*/
|
|
175
|
-
async openFile(filePath) {
|
|
176
|
-
await open(filePath);
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Prompt user to enter topic name with validation
|
|
180
|
-
* @param targetPath - The path where the topic folder will be created
|
|
181
|
-
* @returns The topic name or null if cancelled
|
|
182
|
-
*/
|
|
183
|
-
async promptForTopicName(targetPath) {
|
|
184
|
-
try {
|
|
185
|
-
const topicName = await input({
|
|
186
|
-
message: 'New topic name:',
|
|
187
|
-
validate: (value) => this.validateTopicName(value, targetPath),
|
|
188
|
-
});
|
|
189
|
-
return topicName.trim();
|
|
190
|
-
}
|
|
191
|
-
catch {
|
|
192
|
-
return null;
|
|
193
|
-
}
|
|
81
|
+
terminal: new OclifTerminal(this),
|
|
82
|
+
tokenStore,
|
|
83
|
+
trackingService: new MixpanelTrackingService({ globalConfigStore, tokenStore }),
|
|
84
|
+
});
|
|
194
85
|
}
|
|
195
86
|
async run() {
|
|
196
87
|
const { args, flags } = await this.parse(Curate);
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
// Interactive mode: manually prompt for domain/topic/context
|
|
201
|
-
return contextInput ? this.runAutonomous(contextInput, flags) : this.runInteractive();
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* Write content to context tree at given path
|
|
205
|
-
*/
|
|
206
|
-
async writeToContextTree(selectedPath, content) {
|
|
207
|
-
const targetPath = path.join(CONTEXT_TREE_PATH, selectedPath);
|
|
208
|
-
const contextFilePath = path.join(targetPath, CONTEXT_FILE);
|
|
209
|
-
// Create directories if they don't exist
|
|
210
|
-
fs.mkdirSync(targetPath, { recursive: true });
|
|
211
|
-
// Append or create context file
|
|
212
|
-
const timestamp = new Date().toISOString();
|
|
213
|
-
const entry = `\n## Added on ${timestamp}\n\n${content}\n`;
|
|
214
|
-
const isNewFile = !fs.existsSync(contextFilePath);
|
|
215
|
-
const title = path.basename(selectedPath); // Use last segment as title
|
|
216
|
-
if (isNewFile) {
|
|
217
|
-
fs.writeFileSync(contextFilePath, `# ${title}\n${entry}`, 'utf8');
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
fs.appendFileSync(contextFilePath, entry, 'utf8');
|
|
221
|
-
}
|
|
222
|
-
const action = isNewFile ? 'Created' : 'Updated';
|
|
223
|
-
this.log(`\n✓ ${action}: ${contextFilePath}`);
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Handle workspace not initialized error
|
|
227
|
-
*/
|
|
228
|
-
handleWorkspaceError(_error) {
|
|
229
|
-
const message = 'Project not initialized. Please run "brv init" to select your team and workspace.';
|
|
230
|
-
exitWithCode(ExitCode.VALIDATION_ERROR, message);
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* Run in autonomous mode using CipherAgent
|
|
234
|
-
*/
|
|
235
|
-
async runAutonomous(content, flags) {
|
|
236
|
-
const { projectConfigStore, trackingService } = this.createServices();
|
|
237
|
-
try {
|
|
238
|
-
// Get authentication token
|
|
239
|
-
const tokenStore = new KeychainTokenStore();
|
|
240
|
-
const token = await tokenStore.load();
|
|
241
|
-
if (!token) {
|
|
242
|
-
exitWithCode(ExitCode.CONFIG_ERROR, 'Authentication required. Please run "brv login" first.');
|
|
243
|
-
}
|
|
244
|
-
// Load project config
|
|
245
|
-
const brvConfig = await projectConfigStore.read();
|
|
246
|
-
// Validate workspace is initialized
|
|
247
|
-
if (!brvConfig) {
|
|
248
|
-
throw new WorkspaceNotInitializedError('Project not initialized. Please run "brv init" to select your team and workspace.', '.brv');
|
|
249
|
-
}
|
|
250
|
-
// Create LLM config
|
|
251
|
-
const model = flags.model ?? (flags.apiKey ? 'google/gemini-2.5-pro' : 'gemini-2.5-pro');
|
|
252
|
-
const envConfig = getCurrentConfig();
|
|
253
|
-
const llmConfig = {
|
|
254
|
-
accessToken: token.accessToken,
|
|
255
|
-
fileSystemConfig: { workingDirectory: process.cwd() },
|
|
256
|
-
grpcEndpoint: envConfig.llmGrpcEndpoint,
|
|
257
|
-
maxIterations: 10,
|
|
258
|
-
maxTokens: 8192,
|
|
259
|
-
model,
|
|
260
|
-
openRouterApiKey: flags.apiKey,
|
|
261
|
-
projectId: PROJECT,
|
|
262
|
-
sessionKey: token.sessionKey,
|
|
263
|
-
teamId: brvConfig?.teamId ?? '',
|
|
264
|
-
temperature: 0.7,
|
|
265
|
-
verbose: flags.verbose ?? false,
|
|
266
|
-
};
|
|
267
|
-
// Create and start CipherAgent
|
|
268
|
-
const agent = new CipherAgent(llmConfig, brvConfig);
|
|
269
|
-
this.log('Starting autonomous context tree curation...');
|
|
270
|
-
await agent.start();
|
|
271
|
-
try {
|
|
272
|
-
const sessionId = this.generateSessionId();
|
|
273
|
-
// Setup event listeners
|
|
274
|
-
this.setupEventListeners(agent, flags.verbose ?? false);
|
|
275
|
-
// Execute with autonomous mode and add commandType
|
|
276
|
-
const prompt = `Add the following context to the context tree:\n\n${content}`;
|
|
277
|
-
const response = await agent.execute(prompt, sessionId, {
|
|
278
|
-
executionContext: { commandType: 'curate' },
|
|
279
|
-
mode: 'autonomous',
|
|
280
|
-
});
|
|
281
|
-
this.log('\nCipherAgent Response:');
|
|
282
|
-
this.log(response);
|
|
283
|
-
await trackingService.track('mem:curate');
|
|
284
|
-
}
|
|
285
|
-
finally {
|
|
286
|
-
// console.log('Logic for agent stopping and resource cleanup may go here!')
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
catch (error) {
|
|
290
|
-
if (error instanceof WorkspaceNotInitializedError) {
|
|
291
|
-
this.handleWorkspaceError(error);
|
|
292
|
-
return;
|
|
293
|
-
}
|
|
294
|
-
// Throw error to let oclif handle exit code
|
|
295
|
-
this.error(error instanceof Error ? error.message : 'Runtime error occurred', { exit: ExitCode.RUNTIME_ERROR });
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* Run in interactive mode with manual prompts
|
|
300
|
-
*/
|
|
301
|
-
async runInteractive() {
|
|
302
|
-
const { trackingService } = this.createServices();
|
|
303
|
-
try {
|
|
304
|
-
// Navigate to target location in context tree
|
|
305
|
-
const targetPath = await this.navigateContextTree();
|
|
306
|
-
if (!targetPath) {
|
|
307
|
-
this.log('\nOperation cancelled.');
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
// Prompt for topic name with validation
|
|
311
|
-
const topicName = await this.promptForTopicName(targetPath);
|
|
312
|
-
if (!topicName) {
|
|
313
|
-
this.log('\nOperation cancelled.');
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
// Create the topic folder with context.md
|
|
317
|
-
const contextFilePath = this.createTopicWithContextFile(targetPath, topicName);
|
|
318
|
-
this.log(`\nCreated: ${contextFilePath}`);
|
|
319
|
-
// Track the event
|
|
320
|
-
trackingService.track('mem:curate');
|
|
321
|
-
// Auto-open context.md in default editor
|
|
322
|
-
this.log('Opening context.md for editing...');
|
|
323
|
-
await this.openFile(contextFilePath);
|
|
324
|
-
}
|
|
325
|
-
catch (error) {
|
|
326
|
-
this.error(error instanceof Error ? error.message : 'Unexpected error occurred');
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
/**
|
|
330
|
-
* Setup event listeners for CipherAgent
|
|
331
|
-
*/
|
|
332
|
-
setupEventListeners(agent, verbose) {
|
|
333
|
-
if (!agent.agentEventBus) {
|
|
334
|
-
throw new Error('Agent event bus not initialized');
|
|
335
|
-
}
|
|
336
|
-
const eventBus = agent.agentEventBus;
|
|
337
|
-
if (verbose) {
|
|
338
|
-
// Verbose mode: show detailed events
|
|
339
|
-
eventBus.on('llmservice:thinking', () => {
|
|
340
|
-
this.log('🤔 [Event] LLM is thinking...');
|
|
341
|
-
});
|
|
342
|
-
eventBus.on('llmservice:response', (payload) => {
|
|
343
|
-
this.log(`✅ [Event] LLM Response (${payload.provider}/${payload.model})`);
|
|
344
|
-
});
|
|
345
|
-
eventBus.on('llmservice:toolCall', (payload) => {
|
|
346
|
-
const formattedCall = formatToolCall(payload.toolName, payload.args);
|
|
347
|
-
this.log(`🔧 [Event] Tool Call: ${formattedCall}`);
|
|
348
|
-
});
|
|
349
|
-
eventBus.on('llmservice:toolResult', (payload) => {
|
|
350
|
-
const resultSummary = formatToolResult(payload.toolName, payload.success, payload.result, payload.error);
|
|
351
|
-
if (payload.success) {
|
|
352
|
-
this.log(`✓ [Event] Tool Success: ${payload.toolName} → ${resultSummary}`);
|
|
353
|
-
}
|
|
354
|
-
else {
|
|
355
|
-
this.log(`✗ [Event] Tool Error: ${payload.toolName} → ${resultSummary}`);
|
|
356
|
-
}
|
|
357
|
-
});
|
|
358
|
-
eventBus.on('llmservice:error', (payload) => {
|
|
359
|
-
this.log(`❌ [Event] LLM Error: ${payload.error}`);
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
else {
|
|
363
|
-
// Non-verbose mode: show concise tool progress
|
|
364
|
-
eventBus.on('llmservice:toolCall', (payload) => {
|
|
365
|
-
this.log(`🔧 ${payload.toolName} → Executing...`);
|
|
366
|
-
});
|
|
367
|
-
eventBus.on('llmservice:toolResult', (payload) => {
|
|
368
|
-
if (payload.success) {
|
|
369
|
-
this.log(`✅ ${payload.toolName} → Complete`);
|
|
370
|
-
}
|
|
371
|
-
else {
|
|
372
|
-
this.log(`❌ ${payload.toolName} → Failed: ${payload.error ?? 'Unknown error'}`);
|
|
373
|
-
}
|
|
374
|
-
});
|
|
375
|
-
eventBus.on('llmservice:error', (payload) => {
|
|
376
|
-
this.log(addErrorPrefix(payload.error));
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
validateTopicName(value, targetPath) {
|
|
381
|
-
const trimmed = value.trim();
|
|
382
|
-
if (!trimmed) {
|
|
383
|
-
return 'Topic name cannot be empty';
|
|
384
|
-
}
|
|
385
|
-
// Check for invalid characters in folder names (filesystem restrictions)
|
|
386
|
-
if (/[/\0]/.test(trimmed)) {
|
|
387
|
-
return 'Topic name cannot contain "/" or null characters';
|
|
388
|
-
}
|
|
389
|
-
// Check if folder already exists
|
|
390
|
-
const topicPath = path.join(targetPath, trimmed);
|
|
391
|
-
if (fs.existsSync(topicPath)) {
|
|
392
|
-
return `Topic "${trimmed}" already exists at this location`;
|
|
88
|
+
if (!args.context) {
|
|
89
|
+
this.log('Context argument is required.\nFor interactive mode, use REPL: brv /curate');
|
|
90
|
+
return;
|
|
393
91
|
}
|
|
394
|
-
|
|
92
|
+
await this.createUseCase().run({
|
|
93
|
+
apiKey: flags.apiKey,
|
|
94
|
+
context: args.context,
|
|
95
|
+
files: flags.files,
|
|
96
|
+
model: flags.model,
|
|
97
|
+
verbose: flags.verbose,
|
|
98
|
+
});
|
|
395
99
|
}
|
|
396
100
|
}
|
package/dist/commands/foo.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
|
-
import { ICodingAgentLogWatcher } from '../core/interfaces/cipher/i-coding-agent-log-watcher.js';
|
|
3
|
-
import { IProjectConfigStore } from '../core/interfaces/i-project-config-store.js';
|
|
2
|
+
import type { ICodingAgentLogWatcher } from '../core/interfaces/cipher/i-coding-agent-log-watcher.js';
|
|
3
|
+
import type { IProjectConfigStore } from '../core/interfaces/i-project-config-store.js';
|
|
4
|
+
import type { ITerminal } from '../core/interfaces/i-terminal.js';
|
|
4
5
|
export default class Foo extends Command {
|
|
5
6
|
static description: string;
|
|
6
7
|
static hidden: boolean;
|
|
8
|
+
protected terminal: ITerminal;
|
|
7
9
|
protected createServices(): Promise<{
|
|
8
10
|
codingAgentLogWatcher: ICodingAgentLogWatcher;
|
|
9
11
|
projectConfigStore: IProjectConfigStore;
|