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
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
|
+
import { useCommands } from '../contexts/use-commands.js';
|
|
5
|
+
/**
|
|
6
|
+
* Generate file suggestions based on @ prefix
|
|
7
|
+
* Returns files from the current working directory matching the search pattern
|
|
8
|
+
*/
|
|
9
|
+
function generateFileSuggestions(searchPattern) {
|
|
10
|
+
try {
|
|
11
|
+
const cwd = process.cwd();
|
|
12
|
+
// If pattern ends with /, list contents of that directory
|
|
13
|
+
let searchDir;
|
|
14
|
+
let searchPrefix;
|
|
15
|
+
if (searchPattern.endsWith('/')) {
|
|
16
|
+
searchDir = searchPattern.slice(0, -1) || '.';
|
|
17
|
+
searchPrefix = '';
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
searchDir = path.dirname(searchPattern) || '.';
|
|
21
|
+
searchPrefix = path.basename(searchPattern).toLowerCase();
|
|
22
|
+
}
|
|
23
|
+
const fullSearchDir = path.resolve(cwd, searchDir);
|
|
24
|
+
// Check if search directory exists and is within cwd
|
|
25
|
+
if (!fs.existsSync(fullSearchDir) || !fullSearchDir.startsWith(cwd)) {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
const entries = fs.readdirSync(fullSearchDir, { withFileTypes: true });
|
|
29
|
+
const suggestions = [];
|
|
30
|
+
for (const entry of entries) {
|
|
31
|
+
// Skip hidden files
|
|
32
|
+
if (entry.name.startsWith('.'))
|
|
33
|
+
continue;
|
|
34
|
+
const name = entry.name.toLowerCase();
|
|
35
|
+
if (!searchPrefix || name.startsWith(searchPrefix)) {
|
|
36
|
+
const relativePath = searchDir === '.' ? entry.name : path.join(searchDir, entry.name);
|
|
37
|
+
const isDir = entry.isDirectory();
|
|
38
|
+
suggestions.push({
|
|
39
|
+
description: isDir ? 'folder' : '',
|
|
40
|
+
label: `${relativePath}${isDir ? '/' : ''}`,
|
|
41
|
+
value: `@${relativePath}${isDir ? '/' : ''}`,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Sort: directories first, then alphabetically
|
|
46
|
+
suggestions.sort((a, b) => {
|
|
47
|
+
const aIsDir = a.description === 'folder';
|
|
48
|
+
const bIsDir = b.description === 'folder';
|
|
49
|
+
if (aIsDir !== bIsDir)
|
|
50
|
+
return aIsDir ? -1 : 1;
|
|
51
|
+
return a.label.localeCompare(b.label);
|
|
52
|
+
});
|
|
53
|
+
return suggestions.slice(0, 20); // Limit to 20 suggestions
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Generate command suggestions based on current input
|
|
61
|
+
*/
|
|
62
|
+
function generateSuggestions(input, commands) {
|
|
63
|
+
const trimmed = input.trim();
|
|
64
|
+
// Check for @ file completion (last word starts with @)
|
|
65
|
+
// Don't show file suggestions if input ends with space (file already selected)
|
|
66
|
+
if (!input.endsWith(' ')) {
|
|
67
|
+
const lastAtMatch = trimmed.match(/@([^\s@]*)$/);
|
|
68
|
+
if (lastAtMatch) {
|
|
69
|
+
const searchPattern = lastAtMatch[1];
|
|
70
|
+
const suggestions = generateFileSuggestions(searchPattern);
|
|
71
|
+
// Filter out already selected files
|
|
72
|
+
const existingFiles = new Set([...trimmed.matchAll(/@([^\s@]+)/g)].map((m) => m[1]));
|
|
73
|
+
return suggestions.filter((s) => {
|
|
74
|
+
const filePath = s.value.slice(1); // Remove @ prefix
|
|
75
|
+
return !existingFiles.has(filePath);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Only suggest for slash command inputs
|
|
80
|
+
if (!trimmed.startsWith('/')) {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
const withoutSlash = trimmed.slice(1);
|
|
84
|
+
const parts = withoutSlash.split(/\s+/);
|
|
85
|
+
const commandPart = parts[0]?.toLowerCase() ?? '';
|
|
86
|
+
// If we're still typing the command name (no space after it)
|
|
87
|
+
if (parts.length === 1) {
|
|
88
|
+
// Filter commands that start with the typed prefix
|
|
89
|
+
const matchingCommands = commands
|
|
90
|
+
.filter((cmd) => !cmd.hidden)
|
|
91
|
+
.filter((cmd) => {
|
|
92
|
+
const nameMatch = cmd.name.toLowerCase().startsWith(commandPart);
|
|
93
|
+
const aliasMatch = cmd.aliases?.some((alias) => alias.toLowerCase().startsWith(commandPart));
|
|
94
|
+
return nameMatch || aliasMatch;
|
|
95
|
+
});
|
|
96
|
+
return matchingCommands.map((cmd) => ({
|
|
97
|
+
args: cmd.args,
|
|
98
|
+
commandKind: cmd.kind,
|
|
99
|
+
description: cmd.description,
|
|
100
|
+
flags: cmd.flags,
|
|
101
|
+
label: `/${cmd.name}`,
|
|
102
|
+
subCommands: cmd.subCommands
|
|
103
|
+
?.filter((sub) => !sub.hidden)
|
|
104
|
+
.map((sub) => ({
|
|
105
|
+
description: sub.description,
|
|
106
|
+
name: sub.name,
|
|
107
|
+
})),
|
|
108
|
+
value: `/${cmd.name}`,
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
// Find the matched command
|
|
112
|
+
const command = commands.find((cmd) => cmd.name === commandPart || cmd.aliases?.includes(commandPart));
|
|
113
|
+
if (!command) {
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
// If command has subcommands, suggest them
|
|
117
|
+
if (command.subCommands?.length && parts.length === 2) {
|
|
118
|
+
const subPart = parts[1]?.toLowerCase() ?? '';
|
|
119
|
+
const matchingSubCommands = command.subCommands
|
|
120
|
+
.filter((sub) => !sub.hidden)
|
|
121
|
+
.filter((sub) => {
|
|
122
|
+
const nameMatch = sub.name.toLowerCase().startsWith(subPart);
|
|
123
|
+
const aliasMatch = sub.aliases?.some((alias) => alias.toLowerCase().startsWith(subPart));
|
|
124
|
+
return nameMatch || aliasMatch;
|
|
125
|
+
});
|
|
126
|
+
return matchingSubCommands.map((sub) => ({
|
|
127
|
+
args: sub.args,
|
|
128
|
+
commandKind: sub.kind,
|
|
129
|
+
description: sub.description,
|
|
130
|
+
flags: sub.flags,
|
|
131
|
+
label: `/${command.name} ${sub.name}`,
|
|
132
|
+
value: `/${command.name} ${sub.name}`,
|
|
133
|
+
}));
|
|
134
|
+
}
|
|
135
|
+
// Future enhancement: use command.completion for argument suggestions
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Hook for slash command auto-completion
|
|
140
|
+
* Generates suggestions based on input and manages selection state
|
|
141
|
+
*/
|
|
142
|
+
export function useSlashCompletion(input) {
|
|
143
|
+
const { commands } = useCommands();
|
|
144
|
+
const [activeIndex, setActiveIndex] = useState(-1);
|
|
145
|
+
// Check if input is a command attempt (starts with /)
|
|
146
|
+
const isCommandAttempt = input.trim().startsWith('/');
|
|
147
|
+
// Check if we're in file completion mode (has @ and not ending with space)
|
|
148
|
+
const isFileCompletion = useMemo(() => !input.endsWith(' ') && /@[^\s@]*$/.test(input.trim()), [input]);
|
|
149
|
+
// Check if the input matches a known command (for when typing arguments)
|
|
150
|
+
const hasMatchedCommand = useMemo(() => {
|
|
151
|
+
// File completion counts as "matched" to avoid showing "no commands found"
|
|
152
|
+
if (isFileCompletion)
|
|
153
|
+
return true;
|
|
154
|
+
if (!isCommandAttempt)
|
|
155
|
+
return false;
|
|
156
|
+
const trimmed = input.trim();
|
|
157
|
+
const withoutSlash = trimmed.slice(1);
|
|
158
|
+
const parts = withoutSlash.split(/\s+/);
|
|
159
|
+
const commandPart = parts[0]?.toLowerCase() ?? '';
|
|
160
|
+
return commands.some((cmd) => cmd.name === commandPart || cmd.aliases?.includes(commandPart));
|
|
161
|
+
}, [commands, input, isCommandAttempt, isFileCompletion]);
|
|
162
|
+
// Generate suggestions based on current input
|
|
163
|
+
const suggestions = useMemo(() => generateSuggestions(input, commands), [commands, input]);
|
|
164
|
+
// Use refs to avoid stale closures
|
|
165
|
+
const activeIndexRef = useRef(activeIndex);
|
|
166
|
+
const suggestionsRef = useRef(suggestions);
|
|
167
|
+
const inputRef = useRef(input);
|
|
168
|
+
const isFileCompletionRef = useRef(isFileCompletion);
|
|
169
|
+
// Keep refs in sync
|
|
170
|
+
activeIndexRef.current = activeIndex;
|
|
171
|
+
suggestionsRef.current = suggestions;
|
|
172
|
+
inputRef.current = input;
|
|
173
|
+
isFileCompletionRef.current = isFileCompletion;
|
|
174
|
+
// Reset active index when suggestions change
|
|
175
|
+
useEffect(() => {
|
|
176
|
+
const newIndex = suggestions.length > 0 ? 0 : -1;
|
|
177
|
+
setActiveIndex(newIndex);
|
|
178
|
+
activeIndexRef.current = newIndex;
|
|
179
|
+
}, [suggestions]);
|
|
180
|
+
const nextSuggestion = useCallback(() => {
|
|
181
|
+
const currentSuggestions = suggestionsRef.current;
|
|
182
|
+
if (currentSuggestions.length === 0)
|
|
183
|
+
return;
|
|
184
|
+
setActiveIndex((prev) => {
|
|
185
|
+
const newIndex = (prev + 1) % currentSuggestions.length;
|
|
186
|
+
activeIndexRef.current = newIndex;
|
|
187
|
+
return newIndex;
|
|
188
|
+
});
|
|
189
|
+
}, []);
|
|
190
|
+
const prevSuggestion = useCallback(() => {
|
|
191
|
+
const currentSuggestions = suggestionsRef.current;
|
|
192
|
+
if (currentSuggestions.length === 0)
|
|
193
|
+
return;
|
|
194
|
+
setActiveIndex((prev) => {
|
|
195
|
+
const newIndex = (prev - 1 + currentSuggestions.length) % currentSuggestions.length;
|
|
196
|
+
activeIndexRef.current = newIndex;
|
|
197
|
+
return newIndex;
|
|
198
|
+
});
|
|
199
|
+
}, []);
|
|
200
|
+
const selectSuggestion = useCallback(() => {
|
|
201
|
+
const currentIndex = activeIndexRef.current;
|
|
202
|
+
const currentSuggestions = suggestionsRef.current;
|
|
203
|
+
if (currentIndex < 0 || currentIndex >= currentSuggestions.length) {
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
const selectedValue = currentSuggestions[currentIndex].value;
|
|
207
|
+
// For file completion, replace the @... part with the selected file
|
|
208
|
+
if (isFileCompletionRef.current) {
|
|
209
|
+
const currentInput = inputRef.current;
|
|
210
|
+
// Replace the @... at the end with the selected file path
|
|
211
|
+
return currentInput.replace(/@[^\s@]*$/, selectedValue);
|
|
212
|
+
}
|
|
213
|
+
return selectedValue;
|
|
214
|
+
}, []);
|
|
215
|
+
const clearSuggestions = useCallback(() => {
|
|
216
|
+
setActiveIndex(-1);
|
|
217
|
+
activeIndexRef.current = -1;
|
|
218
|
+
}, []);
|
|
219
|
+
return {
|
|
220
|
+
activeIndex,
|
|
221
|
+
clearSuggestions,
|
|
222
|
+
hasMatchedCommand,
|
|
223
|
+
isCommandAttempt,
|
|
224
|
+
nextSuggestion,
|
|
225
|
+
prevSuggestion,
|
|
226
|
+
selectSuggestion,
|
|
227
|
+
setActiveIndex,
|
|
228
|
+
suggestions,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tab Navigation Hook
|
|
3
|
+
*/
|
|
4
|
+
import { useApp, useInput } from 'ink';
|
|
5
|
+
import { useEffect, useState } from 'react';
|
|
6
|
+
import { stopQueuePollingService } from '../../infra/cipher/consumer/queue-polling-service.js';
|
|
7
|
+
import { DEFAULT_TAB, TABS } from '../constants.js';
|
|
8
|
+
import { useMode } from '../contexts/use-mode.js';
|
|
9
|
+
import { useOnboarding } from './use-onboarding.js';
|
|
10
|
+
export function useTabNavigation() {
|
|
11
|
+
const { exit } = useApp();
|
|
12
|
+
const { shouldShowOnboarding } = useOnboarding();
|
|
13
|
+
const { mode, setMode } = useMode();
|
|
14
|
+
const [activeTab, setActiveTab] = useState(DEFAULT_TAB);
|
|
15
|
+
// Sync mode with active tab on mount and when activeTab changes
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
setMode(activeTab === 'activity' ? 'activity' : 'console');
|
|
18
|
+
}, [activeTab, setMode]);
|
|
19
|
+
useInput((input, key) => {
|
|
20
|
+
// Tab: cycle through tabs (blocked during onboarding)
|
|
21
|
+
if (key.tab && !shouldShowOnboarding) {
|
|
22
|
+
const currentIndex = TABS.findIndex((t) => t.id === activeTab);
|
|
23
|
+
const nextIndex = currentIndex >= TABS.length - 1 ? 0 : currentIndex + 1;
|
|
24
|
+
const nextTab = TABS[nextIndex].id;
|
|
25
|
+
setActiveTab(nextTab);
|
|
26
|
+
// Mode will be synced by useEffect
|
|
27
|
+
}
|
|
28
|
+
// Quit with Ctrl+C
|
|
29
|
+
if (key.ctrl && input === 'c') {
|
|
30
|
+
stopQueuePollingService();
|
|
31
|
+
exit();
|
|
32
|
+
}
|
|
33
|
+
}, { isActive: mode === 'activity' || mode === 'console' });
|
|
34
|
+
return { activeTab, setActiveTab };
|
|
35
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useVisibleWindow Hook
|
|
3
|
+
*
|
|
4
|
+
* Calculates a visible window of items based on selected index.
|
|
5
|
+
* Used for scrollable lists that show a limited number of items
|
|
6
|
+
* with a sliding window that follows the selection.
|
|
7
|
+
*/
|
|
8
|
+
export interface UseVisibleWindowReturn<T> {
|
|
9
|
+
/** The visible items within the window */
|
|
10
|
+
visibleItems: T[];
|
|
11
|
+
/** The starting index of the window in the original array */
|
|
12
|
+
windowStart: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Hook for calculating a visible window of items
|
|
16
|
+
*
|
|
17
|
+
* @param items - The full array of items
|
|
18
|
+
* @param selectedIndex - The currently selected index
|
|
19
|
+
* @param maxVisibleItems - Maximum number of items to show (default: 7)
|
|
20
|
+
* @returns The visible items and window start index
|
|
21
|
+
*/
|
|
22
|
+
export declare function useVisibleWindow<T>(items: T[], selectedIndex: number, maxVisibleItems?: number): UseVisibleWindowReturn<T>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useVisibleWindow Hook
|
|
3
|
+
*
|
|
4
|
+
* Calculates a visible window of items based on selected index.
|
|
5
|
+
* Used for scrollable lists that show a limited number of items
|
|
6
|
+
* with a sliding window that follows the selection.
|
|
7
|
+
*/
|
|
8
|
+
import { useMemo } from 'react';
|
|
9
|
+
const DEFAULT_MAX_VISIBLE_ITEMS = 7;
|
|
10
|
+
/**
|
|
11
|
+
* Hook for calculating a visible window of items
|
|
12
|
+
*
|
|
13
|
+
* @param items - The full array of items
|
|
14
|
+
* @param selectedIndex - The currently selected index
|
|
15
|
+
* @param maxVisibleItems - Maximum number of items to show (default: 7)
|
|
16
|
+
* @returns The visible items and window start index
|
|
17
|
+
*/
|
|
18
|
+
export function useVisibleWindow(items, selectedIndex, maxVisibleItems = DEFAULT_MAX_VISIBLE_ITEMS) {
|
|
19
|
+
return useMemo(() => {
|
|
20
|
+
if (items.length <= maxVisibleItems) {
|
|
21
|
+
return { visibleItems: items, windowStart: 0 };
|
|
22
|
+
}
|
|
23
|
+
// Calculate window start to keep selected item visible
|
|
24
|
+
let start = 0;
|
|
25
|
+
if (selectedIndex >= maxVisibleItems) {
|
|
26
|
+
// Selected item is beyond visible range, adjust window
|
|
27
|
+
start = selectedIndex - maxVisibleItems + 1;
|
|
28
|
+
}
|
|
29
|
+
// Ensure we don't go past the end
|
|
30
|
+
const maxStart = items.length - maxVisibleItems;
|
|
31
|
+
start = Math.min(start, maxStart);
|
|
32
|
+
return {
|
|
33
|
+
visibleItems: items.slice(start, start + maxVisibleItems),
|
|
34
|
+
windowStart: start,
|
|
35
|
+
};
|
|
36
|
+
}, [items, selectedIndex, maxVisibleItems]);
|
|
37
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { App } from './app.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { App } from './app.js';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* App Providers
|
|
3
|
+
*
|
|
4
|
+
* Composes all context providers in the correct order.
|
|
5
|
+
* Single wrapper for repl-startup.tsx to use.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import type { AuthToken } from '../../core/domain/entities/auth-token.js';
|
|
9
|
+
import type { BrvConfig } from '../../core/domain/entities/brv-config.js';
|
|
10
|
+
import type { IOnboardingPreferenceStore } from '../../core/interfaces/i-onboarding-preference-store.js';
|
|
11
|
+
import type { IProjectConfigStore } from '../../core/interfaces/i-project-config-store.js';
|
|
12
|
+
import type { ITokenStore } from '../../core/interfaces/i-token-store.js';
|
|
13
|
+
import type { ITrackingService } from '../../core/interfaces/i-tracking-service.js';
|
|
14
|
+
interface AppProvidersProps {
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
initialAuthToken?: AuthToken;
|
|
17
|
+
initialBrvConfig?: BrvConfig;
|
|
18
|
+
onboardingPreferenceStore: IOnboardingPreferenceStore;
|
|
19
|
+
projectConfigStore: IProjectConfigStore;
|
|
20
|
+
tokenStore: ITokenStore;
|
|
21
|
+
trackingService: ITrackingService;
|
|
22
|
+
version: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function AppProviders({ children, initialAuthToken, initialBrvConfig, onboardingPreferenceStore, projectConfigStore, tokenStore, trackingService, version, }: AppProvidersProps): React.ReactElement;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { AuthProvider, ConsumerProvider, ServicesProvider } from '../contexts/index.js';
|
|
3
|
+
import { OnboardingProvider } from '../contexts/onboarding-context.js';
|
|
4
|
+
import { CommandsProvider } from '../contexts/use-commands.js';
|
|
5
|
+
import { ModeProvider } from '../contexts/use-mode.js';
|
|
6
|
+
import { ThemeProvider } from '../contexts/use-theme.js';
|
|
7
|
+
export function AppProviders({ children, initialAuthToken, initialBrvConfig, onboardingPreferenceStore, projectConfigStore, tokenStore, trackingService, version, }) {
|
|
8
|
+
return (_jsx(ServicesProvider, { onboardingPreferenceStore: onboardingPreferenceStore, projectConfigStore: projectConfigStore, tokenStore: tokenStore, trackingService: trackingService, version: version, children: _jsx(AuthProvider, { initialAuthToken: initialAuthToken, initialBrvConfig: initialBrvConfig, children: _jsx(ThemeProvider, { children: _jsx(CommandsProvider, { children: _jsx(ModeProvider, { children: _jsx(ConsumerProvider, { children: _jsx(OnboardingProvider, { children: children }) }) }) }) }) }) }));
|
|
9
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command-related types
|
|
3
|
+
*/
|
|
4
|
+
import type React from 'react';
|
|
5
|
+
import type { PromptRequest, StreamingMessage } from './index.js';
|
|
6
|
+
import type { Message } from './messages.js';
|
|
7
|
+
/**
|
|
8
|
+
* Command kind indicates the source/type of command
|
|
9
|
+
* Based on Gemini CLI pattern for extensibility
|
|
10
|
+
*/
|
|
11
|
+
export declare enum CommandKind {
|
|
12
|
+
/** Built-in commands defined in code */
|
|
13
|
+
BUILT_IN = "built-in",
|
|
14
|
+
/** Future: file-based commands */
|
|
15
|
+
FILE = "file",
|
|
16
|
+
/** Commands that dispatch to oclif CLI commands */
|
|
17
|
+
OCLIF = "oclif"
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Command argument definition
|
|
21
|
+
*/
|
|
22
|
+
export interface CommandArg {
|
|
23
|
+
/** Argument description */
|
|
24
|
+
description: string;
|
|
25
|
+
/** Argument name */
|
|
26
|
+
name: string;
|
|
27
|
+
/** Whether the argument is required */
|
|
28
|
+
required?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Command flag definition
|
|
32
|
+
*/
|
|
33
|
+
export interface CommandFlag {
|
|
34
|
+
/** Short flag character (e.g., 'b' for -b) */
|
|
35
|
+
char?: string;
|
|
36
|
+
/** Default value */
|
|
37
|
+
default?: boolean | string;
|
|
38
|
+
/** Flag description */
|
|
39
|
+
description: string;
|
|
40
|
+
/** Flag name (e.g., 'branch' for --branch) */
|
|
41
|
+
name: string;
|
|
42
|
+
/** Flag type */
|
|
43
|
+
type: 'boolean' | 'file' | 'string';
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Context passed to command action functions
|
|
47
|
+
*/
|
|
48
|
+
export interface CommandContext {
|
|
49
|
+
/**
|
|
50
|
+
* Invocation details about the current command execution
|
|
51
|
+
*/
|
|
52
|
+
invocation?: {
|
|
53
|
+
/** Arguments passed to the command (without @file references) */
|
|
54
|
+
args: string;
|
|
55
|
+
/** File references extracted from @filepath tokens */
|
|
56
|
+
files: string[];
|
|
57
|
+
/** Resolved command name */
|
|
58
|
+
name: string;
|
|
59
|
+
/** Full raw input string */
|
|
60
|
+
raw: string;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* All loaded slash commands (for help command, etc.)
|
|
64
|
+
*/
|
|
65
|
+
slashCommands?: readonly SlashCommand[];
|
|
66
|
+
/**
|
|
67
|
+
* UI operations available to commands
|
|
68
|
+
*/
|
|
69
|
+
ui?: {
|
|
70
|
+
/**
|
|
71
|
+
* Add a message to the message history
|
|
72
|
+
*/
|
|
73
|
+
addMessage: (msg: Message) => void;
|
|
74
|
+
/**
|
|
75
|
+
* Clear all messages from the history
|
|
76
|
+
*/
|
|
77
|
+
clearMessages: () => void;
|
|
78
|
+
/**
|
|
79
|
+
* Remove the currently displayed custom dialog
|
|
80
|
+
*/
|
|
81
|
+
removeDialog: () => void;
|
|
82
|
+
/**
|
|
83
|
+
* Set processing state
|
|
84
|
+
*/
|
|
85
|
+
setIsProcessing: (processing: boolean) => void;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* CLI version
|
|
89
|
+
*/
|
|
90
|
+
version?: string;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Subcommand info for display in suggestions
|
|
94
|
+
*/
|
|
95
|
+
export interface CommandSubcommandInfo {
|
|
96
|
+
/** Subcommand description */
|
|
97
|
+
description: string;
|
|
98
|
+
/** Subcommand name */
|
|
99
|
+
name: string;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Suggestion item for auto-completion
|
|
103
|
+
*/
|
|
104
|
+
export interface CommandSuggestion {
|
|
105
|
+
/** Command arguments */
|
|
106
|
+
args?: CommandArg[];
|
|
107
|
+
/** Command kind for styling */
|
|
108
|
+
commandKind?: CommandKind;
|
|
109
|
+
/** Optional description */
|
|
110
|
+
description?: string;
|
|
111
|
+
/** Command flags */
|
|
112
|
+
flags?: CommandFlag[];
|
|
113
|
+
/** Display label */
|
|
114
|
+
label: string;
|
|
115
|
+
/** Subcommands for commands with nested commands */
|
|
116
|
+
subCommands?: CommandSubcommandInfo[];
|
|
117
|
+
/** Value to insert on selection */
|
|
118
|
+
value: string;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Command action return type for displaying a message
|
|
122
|
+
*/
|
|
123
|
+
export interface MessageActionReturn {
|
|
124
|
+
content: string;
|
|
125
|
+
messageType: 'error' | 'info';
|
|
126
|
+
type: 'message';
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Command action return type for quitting the REPL
|
|
130
|
+
*/
|
|
131
|
+
export interface QuitActionReturn {
|
|
132
|
+
type: 'quit';
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Command action return type for rendering a custom dialog component
|
|
136
|
+
*/
|
|
137
|
+
export interface CustomDialogActionReturn {
|
|
138
|
+
component: React.ReactNode;
|
|
139
|
+
type: 'custom_dialog';
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Command action return type for clearing the screen
|
|
143
|
+
*/
|
|
144
|
+
export interface ClearActionReturn {
|
|
145
|
+
type: 'clear';
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Command action return type for streaming output with interactive prompts
|
|
149
|
+
*/
|
|
150
|
+
export interface StreamingActionReturn {
|
|
151
|
+
/**
|
|
152
|
+
* Async function that executes the command
|
|
153
|
+
* @param onMessage - Callback for streaming output messages
|
|
154
|
+
* @param onPrompt - Callback for interactive prompts (search, confirm, select)
|
|
155
|
+
*/
|
|
156
|
+
execute: (onMessage: (msg: StreamingMessage) => void, onPrompt: (prompt: PromptRequest) => void) => Promise<void>;
|
|
157
|
+
type: 'streaming';
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Command action return type for confirming an action
|
|
161
|
+
* Uses callback pattern for handling confirmation result (Gemini CLI pattern)
|
|
162
|
+
*/
|
|
163
|
+
export interface ConfirmActionReturn {
|
|
164
|
+
/**
|
|
165
|
+
* Callback invoked when user makes a choice
|
|
166
|
+
* @param confirmed - true if user confirmed, false if cancelled
|
|
167
|
+
* @returns Optional streaming action to execute after confirmation
|
|
168
|
+
*/
|
|
169
|
+
onConfirm: (confirmed: boolean) => Promise<StreamingActionReturn | void> | StreamingActionReturn | void;
|
|
170
|
+
prompt: string;
|
|
171
|
+
type: 'confirm_action';
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Command action return type for submitting a prompt
|
|
175
|
+
*/
|
|
176
|
+
export interface SubmitPromptReturn {
|
|
177
|
+
content: string;
|
|
178
|
+
type: 'submit_prompt';
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Command action return type for showing query input dialog
|
|
182
|
+
*/
|
|
183
|
+
export interface QueryDialogActionReturn {
|
|
184
|
+
type: 'query_dialog';
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Command action return type for showing curate option dialog
|
|
188
|
+
*/
|
|
189
|
+
export interface CurateDialogActionReturn {
|
|
190
|
+
type: 'curate_dialog';
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Command action return type for refreshing auth state (after logout/login)
|
|
194
|
+
*/
|
|
195
|
+
export interface RefreshAuthActionReturn {
|
|
196
|
+
type: 'refresh_auth';
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Union of all possible command action return types
|
|
200
|
+
*/
|
|
201
|
+
export type SlashCommandActionReturn = ClearActionReturn | ConfirmActionReturn | CurateDialogActionReturn | CustomDialogActionReturn | MessageActionReturn | QueryDialogActionReturn | QuitActionReturn | RefreshAuthActionReturn | StreamingActionReturn | SubmitPromptReturn | void;
|
|
202
|
+
/**
|
|
203
|
+
* Slash command definition (based on Gemini CLI pattern)
|
|
204
|
+
* Supports nested subcommands, auto-completion, and flexible action returns
|
|
205
|
+
*/
|
|
206
|
+
export interface SlashCommand {
|
|
207
|
+
/**
|
|
208
|
+
* Action function that executes the command
|
|
209
|
+
* Optional for commands that only have subcommands
|
|
210
|
+
*/
|
|
211
|
+
action?: (context: CommandContext, args: string) => Promise<SlashCommandActionReturn> | SlashCommandActionReturn;
|
|
212
|
+
/**
|
|
213
|
+
* Alternative names for the command (e.g., 'q' for 'quit')
|
|
214
|
+
*/
|
|
215
|
+
aliases?: string[];
|
|
216
|
+
/**
|
|
217
|
+
* Command arguments definition
|
|
218
|
+
*/
|
|
219
|
+
args?: CommandArg[];
|
|
220
|
+
/**
|
|
221
|
+
* Auto-execute on Enter when selected in suggestions (vs just autocomplete)
|
|
222
|
+
*/
|
|
223
|
+
autoExecute?: boolean;
|
|
224
|
+
/**
|
|
225
|
+
* Argument completion provider for suggestions
|
|
226
|
+
*/
|
|
227
|
+
completion?: (context: CommandContext, partialArg: string) => Promise<string[]> | string[];
|
|
228
|
+
/**
|
|
229
|
+
* Description shown in help
|
|
230
|
+
*/
|
|
231
|
+
description: string;
|
|
232
|
+
/**
|
|
233
|
+
* Command flags definition
|
|
234
|
+
*/
|
|
235
|
+
flags?: CommandFlag[];
|
|
236
|
+
/**
|
|
237
|
+
* Hide from help and suggestions (e.g., for internal commands)
|
|
238
|
+
*/
|
|
239
|
+
hidden?: boolean;
|
|
240
|
+
/**
|
|
241
|
+
* Command kind indicates the source/type of command
|
|
242
|
+
*/
|
|
243
|
+
kind: CommandKind;
|
|
244
|
+
/**
|
|
245
|
+
* Primary command name (without leading slash)
|
|
246
|
+
*/
|
|
247
|
+
name: string;
|
|
248
|
+
/**
|
|
249
|
+
* Nested subcommands (e.g., /space list, /space switch)
|
|
250
|
+
*/
|
|
251
|
+
subCommands?: SlashCommand[];
|
|
252
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command-related types
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Command kind indicates the source/type of command
|
|
6
|
+
* Based on Gemini CLI pattern for extensibility
|
|
7
|
+
*/
|
|
8
|
+
export var CommandKind;
|
|
9
|
+
(function (CommandKind) {
|
|
10
|
+
/** Built-in commands defined in code */
|
|
11
|
+
CommandKind["BUILT_IN"] = "built-in";
|
|
12
|
+
/** Future: file-based commands */
|
|
13
|
+
CommandKind["FILE"] = "file";
|
|
14
|
+
/** Commands that dispatch to oclif CLI commands */
|
|
15
|
+
CommandKind["OCLIF"] = "oclif";
|
|
16
|
+
})(CommandKind || (CommandKind = {}));
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dialog request types for UI state management
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Confirmation request stored in UI state (Gemini CLI pattern)
|
|
6
|
+
* Used by DialogManager to render confirmation dialogs
|
|
7
|
+
*/
|
|
8
|
+
export interface ConfirmationRequest {
|
|
9
|
+
onConfirm: (confirmed: boolean) => void;
|
|
10
|
+
prompt: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Query dialog request stored in UI state
|
|
14
|
+
* Used to render the query input dialog
|
|
15
|
+
*/
|
|
16
|
+
export interface QueryDialogRequest {
|
|
17
|
+
onCancel: () => void;
|
|
18
|
+
onSubmit: (query: string) => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Curate option dialog request stored in UI state
|
|
22
|
+
* Used to render the curate mode selection dialog
|
|
23
|
+
*/
|
|
24
|
+
export interface CurateDialogRequest {
|
|
25
|
+
onCancel: () => void;
|
|
26
|
+
onSelectContextInput: () => void;
|
|
27
|
+
onSelectInteractive: () => void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Curate context input dialog request stored in UI state
|
|
31
|
+
* Used to render the context input dialog for autonomous curating
|
|
32
|
+
*/
|
|
33
|
+
export interface CurateContextInputRequest {
|
|
34
|
+
onCancel: () => void;
|
|
35
|
+
onSubmit: (context: string) => void;
|
|
36
|
+
onToggleMode?: () => void;
|
|
37
|
+
}
|