@build-astron-co/nimbus 0.2.0 → 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/bin/nimbus +26 -10
- package/bin/nimbus.cmd +41 -0
- package/bin/nimbus.mjs +70 -0
- package/completions/nimbus.bash +38 -0
- package/completions/nimbus.fish +48 -0
- package/completions/nimbus.zsh +81 -0
- package/dist/src/agent/compaction-agent.js +215 -0
- package/dist/src/agent/context-manager.js +385 -0
- package/dist/src/agent/context.js +322 -0
- package/dist/src/agent/deploy-preview.js +395 -0
- package/dist/src/agent/expand-files.js +95 -0
- package/dist/src/agent/index.js +18 -0
- package/dist/src/agent/loop.js +1535 -0
- package/dist/src/agent/modes.js +347 -0
- package/dist/src/agent/permissions.js +396 -0
- package/dist/src/agent/subagents/base.js +67 -0
- package/dist/src/agent/subagents/cost.js +45 -0
- package/dist/src/agent/subagents/explore.js +36 -0
- package/dist/src/agent/subagents/general.js +41 -0
- package/dist/src/agent/subagents/index.js +88 -0
- package/dist/src/agent/subagents/infra.js +52 -0
- package/dist/src/agent/subagents/security.js +60 -0
- package/dist/src/agent/system-prompt.js +860 -0
- package/dist/src/app.js +152 -0
- package/dist/src/audit/activity-log.js +209 -0
- package/dist/src/audit/compliance-checker.js +419 -0
- package/dist/src/audit/cost-tracker.js +231 -0
- package/dist/src/audit/index.js +10 -0
- package/dist/src/audit/security-scanner.js +490 -0
- package/dist/src/auth/guard.js +64 -0
- package/dist/src/auth/index.js +19 -0
- package/dist/src/auth/keychain.js +79 -0
- package/dist/src/auth/oauth.js +389 -0
- package/dist/src/auth/providers.js +415 -0
- package/dist/src/auth/sso.js +87 -0
- package/dist/src/auth/store.js +424 -0
- package/dist/src/auth/types.js +5 -0
- package/dist/src/cli/index.js +8 -0
- package/dist/src/cli/init.js +1048 -0
- package/dist/src/cli/openapi-spec.js +346 -0
- package/dist/src/cli/run.js +505 -0
- package/dist/src/cli/serve-auth.js +56 -0
- package/dist/src/cli/serve.js +432 -0
- package/dist/src/cli/web.js +50 -0
- package/dist/src/cli.js +1574 -0
- package/dist/src/clients/core-engine-client.js +156 -0
- package/dist/src/clients/enterprise-client.js +246 -0
- package/dist/src/clients/generator-client.js +219 -0
- package/dist/src/clients/git-client.js +367 -0
- package/dist/src/clients/github-client.js +229 -0
- package/dist/src/clients/helm-client.js +299 -0
- package/dist/src/clients/index.js +18 -0
- package/dist/src/clients/k8s-client.js +270 -0
- package/dist/src/clients/llm-client.js +119 -0
- package/dist/src/clients/rest-client.js +104 -0
- package/dist/src/clients/service-discovery.js +35 -0
- package/dist/src/clients/terraform-client.js +302 -0
- package/dist/src/clients/tools-client.js +1227 -0
- package/dist/src/clients/ws-client.js +93 -0
- package/dist/src/commands/alias.js +91 -0
- package/dist/src/commands/analyze/index.js +313 -0
- package/dist/src/commands/apply/helm.js +375 -0
- package/dist/src/commands/apply/index.js +176 -0
- package/dist/src/commands/apply/k8s.js +350 -0
- package/dist/src/commands/apply/terraform.js +465 -0
- package/dist/src/commands/ask.js +137 -0
- package/dist/src/commands/audit/index.js +322 -0
- package/dist/src/commands/auth-cloud.js +345 -0
- package/dist/src/commands/auth-list.js +112 -0
- package/dist/src/commands/auth-profile.js +104 -0
- package/dist/src/commands/auth-refresh.js +161 -0
- package/dist/src/commands/auth-status.js +122 -0
- package/dist/src/commands/aws/ec2.js +402 -0
- package/dist/src/commands/aws/iam.js +304 -0
- package/dist/src/commands/aws/index.js +108 -0
- package/dist/src/commands/aws/lambda.js +317 -0
- package/dist/src/commands/aws/rds.js +345 -0
- package/dist/src/commands/aws/s3.js +346 -0
- package/dist/src/commands/aws/vpc.js +302 -0
- package/dist/src/commands/aws-discover.js +413 -0
- package/dist/src/commands/aws-terraform.js +618 -0
- package/dist/src/commands/azure/aks.js +305 -0
- package/dist/src/commands/azure/functions.js +200 -0
- package/dist/src/commands/azure/index.js +93 -0
- package/dist/src/commands/azure/storage.js +378 -0
- package/dist/src/commands/azure/vm.js +291 -0
- package/dist/src/commands/billing/index.js +224 -0
- package/dist/src/commands/chat.js +259 -0
- package/dist/src/commands/completions.js +255 -0
- package/dist/src/commands/config.js +291 -0
- package/dist/src/commands/cost/cloud-cost-estimator.js +211 -0
- package/dist/src/commands/cost/estimator.js +73 -0
- package/dist/src/commands/cost/index.js +625 -0
- package/dist/src/commands/cost/parsers/terraform.js +234 -0
- package/dist/src/commands/cost/parsers/types.js +4 -0
- package/dist/src/commands/cost/pricing/aws.js +501 -0
- package/dist/src/commands/cost/pricing/azure.js +462 -0
- package/dist/src/commands/cost/pricing/gcp.js +359 -0
- package/dist/src/commands/cost/pricing/index.js +24 -0
- package/dist/src/commands/demo.js +196 -0
- package/dist/src/commands/deploy.js +215 -0
- package/dist/src/commands/doctor.js +1291 -0
- package/dist/src/commands/drift/index.js +674 -0
- package/dist/src/commands/explain.js +235 -0
- package/dist/src/commands/export.js +120 -0
- package/dist/src/commands/feedback.js +319 -0
- package/dist/src/commands/fix.js +263 -0
- package/dist/src/commands/fs/index.js +338 -0
- package/dist/src/commands/gcp/compute.js +266 -0
- package/dist/src/commands/gcp/functions.js +221 -0
- package/dist/src/commands/gcp/gke.js +357 -0
- package/dist/src/commands/gcp/iam.js +295 -0
- package/dist/src/commands/gcp/index.js +105 -0
- package/dist/src/commands/gcp/storage.js +232 -0
- package/dist/src/commands/generate-helm.js +1026 -0
- package/dist/src/commands/generate-k8s.js +1263 -0
- package/dist/src/commands/generate-terraform.js +1058 -0
- package/dist/src/commands/gh/index.js +663 -0
- package/dist/src/commands/git/index.js +1208 -0
- package/dist/src/commands/helm/index.js +985 -0
- package/dist/src/commands/help.js +639 -0
- package/dist/src/commands/history.js +120 -0
- package/dist/src/commands/import.js +782 -0
- package/dist/src/commands/incident.js +144 -0
- package/dist/src/commands/index.js +109 -0
- package/dist/src/commands/init.js +955 -0
- package/dist/src/commands/k8s/index.js +979 -0
- package/dist/src/commands/login.js +588 -0
- package/dist/src/commands/logout.js +61 -0
- package/dist/src/commands/logs.js +160 -0
- package/dist/src/commands/onboarding.js +382 -0
- package/dist/src/commands/pipeline.js +153 -0
- package/dist/src/commands/plan/display.js +216 -0
- package/dist/src/commands/plan/index.js +525 -0
- package/dist/src/commands/plugin.js +325 -0
- package/dist/src/commands/preview.js +356 -0
- package/dist/src/commands/profile.js +297 -0
- package/dist/src/commands/questionnaire.js +1021 -0
- package/dist/src/commands/resume.js +35 -0
- package/dist/src/commands/rollback.js +259 -0
- package/dist/src/commands/rollout.js +74 -0
- package/dist/src/commands/runbook.js +307 -0
- package/dist/src/commands/schedule.js +202 -0
- package/dist/src/commands/status.js +213 -0
- package/dist/src/commands/team/index.js +309 -0
- package/dist/src/commands/team-context.js +200 -0
- package/dist/src/commands/template.js +204 -0
- package/dist/src/commands/tf/index.js +989 -0
- package/dist/src/commands/upgrade.js +515 -0
- package/dist/src/commands/usage/index.js +118 -0
- package/dist/src/commands/version.js +145 -0
- package/dist/src/commands/watch.js +127 -0
- package/dist/src/compat/index.js +2 -0
- package/dist/src/compat/runtime.js +10 -0
- package/dist/src/compat/sqlite.js +144 -0
- package/dist/src/config/index.js +6 -0
- package/dist/src/config/manager.js +469 -0
- package/dist/src/config/mode-store.js +57 -0
- package/dist/src/config/profiles.js +66 -0
- package/dist/src/config/safety-policy.js +251 -0
- package/dist/src/config/schema.js +107 -0
- package/dist/src/config/types.js +311 -0
- package/dist/src/config/workspace-state.js +38 -0
- package/dist/src/context/context-db.js +138 -0
- package/dist/src/demo/index.js +295 -0
- package/dist/src/demo/scenarios/full-journey.js +226 -0
- package/dist/src/demo/scenarios/getting-started.js +124 -0
- package/dist/src/demo/scenarios/helm-release.js +334 -0
- package/dist/src/demo/scenarios/k8s-deployment.js +190 -0
- package/dist/src/demo/scenarios/terraform-vpc.js +167 -0
- package/dist/src/demo/types.js +6 -0
- package/dist/src/engine/cost-estimator.js +334 -0
- package/dist/src/engine/diagram-generator.js +192 -0
- package/dist/src/engine/drift-detector.js +688 -0
- package/dist/src/engine/executor.js +832 -0
- package/dist/src/engine/index.js +39 -0
- package/dist/src/engine/orchestrator.js +436 -0
- package/dist/src/engine/planner.js +616 -0
- package/dist/src/engine/safety.js +609 -0
- package/dist/src/engine/verifier.js +664 -0
- package/dist/src/enterprise/audit.js +241 -0
- package/dist/src/enterprise/auth.js +189 -0
- package/dist/src/enterprise/billing.js +512 -0
- package/dist/src/enterprise/index.js +16 -0
- package/dist/src/enterprise/teams.js +315 -0
- package/dist/src/generator/best-practices.js +1375 -0
- package/dist/src/generator/helm.js +495 -0
- package/dist/src/generator/index.js +11 -0
- package/dist/src/generator/intent-parser.js +420 -0
- package/dist/src/generator/kubernetes.js +773 -0
- package/dist/src/generator/terraform.js +1472 -0
- package/dist/src/history/index.js +6 -0
- package/dist/src/history/manager.js +199 -0
- package/dist/src/history/types.js +6 -0
- package/dist/src/hooks/config.js +318 -0
- package/dist/src/hooks/engine.js +317 -0
- package/dist/src/hooks/index.js +2 -0
- package/dist/src/llm/auth-bridge.js +157 -0
- package/dist/src/llm/circuit-breaker.js +116 -0
- package/dist/src/llm/config-loader.js +172 -0
- package/dist/src/llm/cost-calculator.js +137 -0
- package/dist/src/llm/index.js +7 -0
- package/dist/src/llm/model-aliases.js +99 -0
- package/dist/src/llm/provider-registry.js +57 -0
- package/dist/src/llm/providers/anthropic.js +430 -0
- package/dist/src/llm/providers/bedrock.js +409 -0
- package/dist/src/llm/providers/google.js +344 -0
- package/dist/src/llm/providers/ollama.js +661 -0
- package/dist/src/llm/providers/openai-compatible.js +289 -0
- package/dist/src/llm/providers/openai.js +284 -0
- package/dist/src/llm/providers/openrouter.js +293 -0
- package/dist/src/llm/router.js +844 -0
- package/dist/src/llm/types.js +69 -0
- package/dist/src/lsp/client.js +239 -0
- package/dist/src/lsp/languages.js +95 -0
- package/dist/src/lsp/manager.js +243 -0
- package/dist/src/mcp/client.js +289 -0
- package/dist/src/mcp/index.js +5 -0
- package/dist/src/mcp/manager.js +113 -0
- package/dist/src/nimbus.js +212 -0
- package/dist/src/plugins/index.js +13 -0
- package/dist/src/plugins/loader.js +280 -0
- package/dist/src/plugins/manager.js +282 -0
- package/dist/src/plugins/types.js +23 -0
- package/dist/src/scanners/cicd-scanner.js +230 -0
- package/dist/src/scanners/cloud-scanner.js +415 -0
- package/dist/src/scanners/framework-scanner.js +430 -0
- package/dist/src/scanners/iac-scanner.js +350 -0
- package/dist/src/scanners/index.js +454 -0
- package/dist/src/scanners/language-scanner.js +258 -0
- package/dist/src/scanners/package-manager-scanner.js +252 -0
- package/dist/src/scanners/types.js +6 -0
- package/dist/src/sessions/manager.js +395 -0
- package/dist/src/sessions/types.js +4 -0
- package/dist/src/sharing/sync.js +238 -0
- package/dist/src/sharing/viewer.js +131 -0
- package/dist/src/snapshots/index.js +1 -0
- package/dist/src/snapshots/manager.js +432 -0
- package/dist/src/state/artifacts.js +94 -0
- package/dist/src/state/audit.js +73 -0
- package/dist/src/state/billing.js +126 -0
- package/dist/src/state/checkpoints.js +81 -0
- package/dist/src/state/config.js +58 -0
- package/dist/src/state/conversations.js +7 -0
- package/dist/src/state/credentials.js +96 -0
- package/dist/src/state/db.js +53 -0
- package/dist/src/state/index.js +23 -0
- package/dist/src/state/messages.js +76 -0
- package/dist/src/state/projects.js +92 -0
- package/dist/src/state/schema.js +233 -0
- package/dist/src/state/sessions.js +79 -0
- package/dist/src/state/teams.js +131 -0
- package/dist/src/telemetry.js +91 -0
- package/dist/src/tools/aws-ops.js +747 -0
- package/dist/src/tools/azure-ops.js +491 -0
- package/dist/src/tools/file-ops.js +451 -0
- package/dist/src/tools/gcp-ops.js +559 -0
- package/dist/src/tools/git-ops.js +557 -0
- package/dist/src/tools/github-ops.js +460 -0
- package/dist/src/tools/helm-ops.js +634 -0
- package/dist/src/tools/index.js +16 -0
- package/dist/src/tools/k8s-ops.js +579 -0
- package/dist/src/tools/schemas/converter.js +129 -0
- package/dist/src/tools/schemas/devops.js +3319 -0
- package/dist/src/tools/schemas/index.js +19 -0
- package/dist/src/tools/schemas/standard.js +966 -0
- package/dist/src/tools/schemas/types.js +409 -0
- package/dist/src/tools/spawn-exec.js +109 -0
- package/dist/src/tools/terraform-ops.js +627 -0
- package/dist/src/types/config.js +1 -0
- package/dist/src/types/drift.js +4 -0
- package/dist/src/types/enterprise.js +5 -0
- package/dist/src/types/index.js +14 -0
- package/dist/src/types/plan.js +1 -0
- package/dist/src/types/request.js +1 -0
- package/dist/src/types/response.js +1 -0
- package/dist/src/types/service.js +1 -0
- package/dist/src/ui/App.js +1672 -0
- package/dist/src/ui/DeployPreview.js +60 -0
- package/dist/src/ui/FileDiffModal.js +108 -0
- package/dist/src/ui/Header.js +46 -0
- package/dist/src/ui/HelpModal.js +9 -0
- package/dist/src/ui/InputBox.js +408 -0
- package/dist/src/ui/MessageList.js +795 -0
- package/dist/src/ui/PermissionPrompt.js +72 -0
- package/dist/src/ui/StatusBar.js +109 -0
- package/dist/src/ui/TerminalPane.js +31 -0
- package/dist/src/ui/ToolCallDisplay.js +303 -0
- package/dist/src/ui/TreePane.js +83 -0
- package/dist/src/ui/chat-ui.js +721 -0
- package/dist/src/ui/index.js +11 -0
- package/dist/src/ui/ink/index.js +1325 -0
- package/dist/src/ui/streaming.js +137 -0
- package/dist/src/ui/theme.js +78 -0
- package/dist/src/ui/types.js +7 -0
- package/dist/src/utils/analytics.js +61 -0
- package/dist/src/utils/cost-warning.js +25 -0
- package/dist/src/utils/env.js +42 -0
- package/dist/src/utils/errors.js +54 -0
- package/dist/src/utils/event-bus.js +22 -0
- package/dist/src/utils/index.js +16 -0
- package/dist/src/utils/logger.js +150 -0
- package/dist/src/utils/rate-limiter.js +90 -0
- package/dist/src/utils/service-auth.js +36 -0
- package/dist/src/utils/validation.js +39 -0
- package/dist/src/version.js +3 -0
- package/dist/src/watcher/index.js +192 -0
- package/dist/src/wizard/approval.js +275 -0
- package/dist/src/wizard/index.js +13 -0
- package/dist/src/wizard/prompts.js +273 -0
- package/dist/src/wizard/types.js +4 -0
- package/dist/src/wizard/ui.js +453 -0
- package/dist/src/wizard/wizard.js +227 -0
- package/package.json +31 -23
- package/src/__tests__/alias.test.ts +133 -0
- package/src/__tests__/app.test.ts +1 -1
- package/src/__tests__/audit.test.ts +1 -1
- package/src/__tests__/circuit-breaker.test.ts +1 -1
- package/src/__tests__/cli-run.test.ts +237 -1
- package/src/__tests__/compat-sqlite.test.ts +68 -0
- package/src/__tests__/context-manager.test.ts +131 -1
- package/src/__tests__/context.test.ts +1 -1
- package/src/__tests__/devops-terminal-gaps.test.ts +718 -0
- package/src/__tests__/doctor.test.ts +48 -0
- package/src/__tests__/enterprise.test.ts +1 -1
- package/src/__tests__/export.test.ts +236 -0
- package/src/__tests__/gap-11-18-20.test.ts +958 -0
- package/src/__tests__/generator.test.ts +1 -1
- package/src/__tests__/helm-streaming.test.ts +127 -0
- package/src/__tests__/hooks.test.ts +1 -1
- package/src/__tests__/incident.test.ts +179 -0
- package/src/__tests__/init.test.ts +55 -4
- package/src/__tests__/intent-parser.test.ts +1 -1
- package/src/__tests__/llm-router.test.ts +1 -1
- package/src/__tests__/logs.test.ts +107 -0
- package/src/__tests__/loop-errors.test.ts +244 -0
- package/src/__tests__/lsp.test.ts +1 -1
- package/src/__tests__/modes.test.ts +1 -1
- package/src/__tests__/perf-optimizations.test.ts +847 -0
- package/src/__tests__/permissions.test.ts +1 -1
- package/src/__tests__/pipeline.test.ts +50 -0
- package/src/__tests__/polish-phase3.test.ts +340 -0
- package/src/__tests__/profile.test.ts +237 -0
- package/src/__tests__/rollback.test.ts +83 -0
- package/src/__tests__/runbook.test.ts +219 -0
- package/src/__tests__/schedule.test.ts +206 -0
- package/src/__tests__/serve.test.ts +1 -1
- package/src/__tests__/sessions.test.ts +96 -1
- package/src/__tests__/sharing.test.ts +53 -1
- package/src/__tests__/snapshots.test.ts +1 -1
- package/src/__tests__/standalone-migration.test.ts +199 -0
- package/src/__tests__/state-db.test.ts +1 -1
- package/src/__tests__/status.test.ts +158 -0
- package/src/__tests__/stream-with-tools.test.ts +71 -25
- package/src/__tests__/subagents.test.ts +1 -1
- package/src/__tests__/system-prompt.test.ts +82 -3
- package/src/__tests__/terminal-gap-v2.test.ts +395 -0
- package/src/__tests__/terminal-parity.test.ts +393 -0
- package/src/__tests__/tf-apply.test.ts +187 -0
- package/src/__tests__/tool-converter.test.ts +1 -1
- package/src/__tests__/tool-schemas.test.ts +209 -4
- package/src/__tests__/tools.test.ts +4 -3
- package/src/__tests__/version-json.test.ts +184 -0
- package/src/__tests__/version.test.ts +1 -1
- package/src/__tests__/watch.test.ts +129 -0
- package/src/agent/compaction-agent.ts +40 -1
- package/src/agent/context-manager.ts +67 -3
- package/src/agent/deploy-preview.ts +62 -1
- package/src/agent/expand-files.ts +108 -0
- package/src/agent/loop.ts +1312 -31
- package/src/agent/permissions.ts +51 -4
- package/src/agent/system-prompt.ts +573 -19
- package/src/app.ts +58 -0
- package/src/audit/security-scanner.ts +45 -0
- package/src/auth/keychain.ts +82 -0
- package/src/auth/oauth.ts +15 -5
- package/src/cli/init.ts +378 -5
- package/src/cli/run.ts +407 -16
- package/src/cli/serve.ts +78 -1
- package/src/cli/web.ts +10 -6
- package/src/cli.ts +312 -1
- package/src/clients/service-discovery.ts +30 -25
- package/src/commands/alias.ts +100 -0
- package/src/commands/audit/index.ts +121 -2
- package/src/commands/auth-cloud.ts +113 -0
- package/src/commands/auth-refresh.ts +187 -0
- package/src/commands/aws-discover.ts +144 -251
- package/src/commands/aws-terraform.ts +68 -118
- package/src/commands/chat.ts +9 -3
- package/src/commands/completions.ts +268 -0
- package/src/commands/config.ts +26 -0
- package/src/commands/cost/index.ts +218 -2
- package/src/commands/deploy.ts +260 -0
- package/src/commands/doctor.ts +744 -152
- package/src/commands/drift/index.ts +371 -23
- package/src/commands/export.ts +146 -0
- package/src/commands/generate-k8s.ts +9 -61
- package/src/commands/generate-terraform.ts +191 -449
- package/src/commands/help.ts +212 -36
- package/src/commands/history.ts +8 -1
- package/src/commands/incident.ts +166 -0
- package/src/commands/init.ts +5 -0
- package/src/commands/login.ts +86 -1
- package/src/commands/logs.ts +167 -0
- package/src/commands/onboarding.ts +211 -34
- package/src/commands/pipeline.ts +186 -0
- package/src/commands/plugin.ts +398 -0
- package/src/commands/profile.ts +342 -0
- package/src/commands/questionnaire.ts +0 -98
- package/src/commands/resume.ts +26 -34
- package/src/commands/rollback.ts +315 -0
- package/src/commands/rollout.ts +88 -0
- package/src/commands/runbook.ts +346 -0
- package/src/commands/schedule.ts +236 -0
- package/src/commands/status.ts +252 -0
- package/src/commands/team-context.ts +220 -0
- package/src/commands/template.ts +58 -57
- package/src/commands/tf/index.ts +70 -11
- package/src/commands/upgrade.ts +57 -0
- package/src/commands/version.ts +54 -50
- package/src/commands/watch.ts +153 -0
- package/src/compat/runtime.ts +1 -1
- package/src/compat/sqlite.ts +75 -5
- package/src/config/mode-store.ts +62 -0
- package/src/config/profiles.ts +84 -0
- package/src/config/types.ts +83 -1
- package/src/config/workspace-state.ts +53 -0
- package/src/engine/cost-estimator.ts +52 -10
- package/src/engine/executor.ts +33 -2
- package/src/engine/planner.ts +68 -1
- package/src/generator/terraform.ts +8 -0
- package/src/history/manager.ts +2 -74
- package/src/hooks/engine.ts +5 -4
- package/src/llm/cost-calculator.ts +2 -2
- package/src/llm/providers/anthropic.ts +50 -21
- package/src/llm/router.ts +76 -7
- package/src/lsp/languages.ts +3 -0
- package/src/lsp/manager.ts +21 -5
- package/src/nimbus.ts +37 -18
- package/src/sessions/manager.ts +108 -1
- package/src/sharing/sync.ts +4 -0
- package/src/sharing/viewer.ts +66 -0
- package/src/tools/file-ops.ts +22 -0
- package/src/tools/schemas/devops.ts +3007 -117
- package/src/tools/schemas/standard.ts +5 -1
- package/src/tools/schemas/types.ts +31 -1
- package/src/tools/spawn-exec.ts +148 -0
- package/src/ui/App.tsx +1183 -66
- package/src/ui/DeployPreview.tsx +62 -57
- package/src/ui/FileDiffModal.tsx +162 -0
- package/src/ui/Header.tsx +87 -24
- package/src/ui/HelpModal.tsx +57 -0
- package/src/ui/InputBox.tsx +163 -10
- package/src/ui/MessageList.tsx +487 -40
- package/src/ui/PermissionPrompt.tsx +17 -5
- package/src/ui/StatusBar.tsx +122 -3
- package/src/ui/TerminalPane.tsx +84 -0
- package/src/ui/ToolCallDisplay.tsx +252 -18
- package/src/ui/TreePane.tsx +132 -0
- package/src/ui/chat-ui.ts +41 -44
- package/src/ui/ink/index.ts +771 -38
- package/src/ui/streaming.ts +1 -1
- package/src/ui/theme.ts +104 -0
- package/src/ui/types.ts +18 -0
- package/src/version.ts +1 -1
- package/src/watcher/index.ts +66 -15
- package/src/wizard/types.ts +1 -0
- package/src/wizard/ui.ts +1 -1
- package/tsconfig.json +2 -2
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth List Command
|
|
3
|
+
*
|
|
4
|
+
* Display all available providers and their configuration status
|
|
5
|
+
*
|
|
6
|
+
* Usage: nimbus auth list
|
|
7
|
+
*/
|
|
8
|
+
import { logger } from '../utils';
|
|
9
|
+
import { ui } from '../wizard';
|
|
10
|
+
import { authStore, AuthStore, getProviderNames, getProviderInfo } from '../auth';
|
|
11
|
+
/**
|
|
12
|
+
* Run the auth list command
|
|
13
|
+
*/
|
|
14
|
+
export async function authListCommand(options = {}) {
|
|
15
|
+
logger.info('Listing auth providers');
|
|
16
|
+
const providerNames = getProviderNames();
|
|
17
|
+
const status = authStore.getStatus();
|
|
18
|
+
const configuredProviders = new Set(status.providers.map(p => p.name));
|
|
19
|
+
// Build provider data
|
|
20
|
+
const providerData = providerNames.map(name => {
|
|
21
|
+
const info = getProviderInfo(name);
|
|
22
|
+
const credential = authStore.getProvider(name);
|
|
23
|
+
const isConfigured = configuredProviders.has(name);
|
|
24
|
+
const isDefault = status.defaultProvider === name;
|
|
25
|
+
return {
|
|
26
|
+
name,
|
|
27
|
+
displayName: info.displayName,
|
|
28
|
+
description: info.description,
|
|
29
|
+
isConfigured,
|
|
30
|
+
isDefault,
|
|
31
|
+
model: credential?.model || info.models.find(m => m.isDefault)?.id || info.models[0].id,
|
|
32
|
+
apiKey: credential?.apiKey,
|
|
33
|
+
baseUrl: credential?.baseUrl,
|
|
34
|
+
requiresApiKey: info.requiresApiKey,
|
|
35
|
+
apiKeyUrl: info.apiKeyUrl,
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
// JSON output mode
|
|
39
|
+
if (options.json) {
|
|
40
|
+
const safeOutput = providerData.map(p => ({
|
|
41
|
+
name: p.name,
|
|
42
|
+
displayName: p.displayName,
|
|
43
|
+
description: p.description,
|
|
44
|
+
isConfigured: p.isConfigured,
|
|
45
|
+
isDefault: p.isDefault,
|
|
46
|
+
model: p.model,
|
|
47
|
+
apiKey: p.apiKey ? AuthStore.maskApiKey(p.apiKey) : null,
|
|
48
|
+
baseUrl: p.baseUrl,
|
|
49
|
+
requiresApiKey: p.requiresApiKey,
|
|
50
|
+
}));
|
|
51
|
+
// Output sanitized JSON (API keys are already masked above)
|
|
52
|
+
ui.print(JSON.stringify(safeOutput, null, 2));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// Human-readable table output
|
|
56
|
+
ui.newLine();
|
|
57
|
+
ui.section('LLM Providers');
|
|
58
|
+
// Build table data
|
|
59
|
+
const tableData = [];
|
|
60
|
+
for (const provider of providerData) {
|
|
61
|
+
const statusIcon = provider.isConfigured ? ui.color('✓', 'green') : ui.dim('—');
|
|
62
|
+
const statusText = provider.isConfigured ? 'Configured' : 'Not configured';
|
|
63
|
+
let apiKeyDisplay;
|
|
64
|
+
if (provider.isConfigured && provider.apiKey) {
|
|
65
|
+
apiKeyDisplay = AuthStore.maskApiKey(provider.apiKey);
|
|
66
|
+
}
|
|
67
|
+
else if (!provider.requiresApiKey) {
|
|
68
|
+
apiKeyDisplay = ui.dim('(not needed)');
|
|
69
|
+
}
|
|
70
|
+
else if (provider.isConfigured) {
|
|
71
|
+
apiKeyDisplay = ui.dim('(from env)');
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
apiKeyDisplay = ui.dim('—');
|
|
75
|
+
}
|
|
76
|
+
const modelDisplay = provider.isConfigured ? provider.model : ui.dim(provider.model);
|
|
77
|
+
const defaultDisplay = provider.isDefault ? ui.color('★', 'yellow') : '';
|
|
78
|
+
tableData.push({
|
|
79
|
+
provider: `${statusIcon} ${provider.displayName}`,
|
|
80
|
+
status: statusText,
|
|
81
|
+
apiKey: apiKeyDisplay,
|
|
82
|
+
model: modelDisplay,
|
|
83
|
+
default: defaultDisplay,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
// Display table
|
|
87
|
+
ui.table({
|
|
88
|
+
columns: [
|
|
89
|
+
{ key: 'provider', header: 'Provider', width: 25 },
|
|
90
|
+
{ key: 'status', header: 'Status', width: 15 },
|
|
91
|
+
{ key: 'apiKey', header: 'API Key', width: 20 },
|
|
92
|
+
{ key: 'model', header: 'Model', width: 30 },
|
|
93
|
+
{ key: 'default', header: 'Default', width: 8 },
|
|
94
|
+
],
|
|
95
|
+
data: tableData,
|
|
96
|
+
});
|
|
97
|
+
ui.newLine();
|
|
98
|
+
// Show hints for unconfigured providers
|
|
99
|
+
const unconfigured = providerData.filter(p => !p.isConfigured);
|
|
100
|
+
if (unconfigured.length > 0) {
|
|
101
|
+
ui.print(ui.dim('To configure a provider, run `nimbus login`'));
|
|
102
|
+
ui.newLine();
|
|
103
|
+
ui.print(ui.dim('API key URLs:'));
|
|
104
|
+
for (const provider of unconfigured) {
|
|
105
|
+
if (provider.apiKeyUrl) {
|
|
106
|
+
ui.print(ui.dim(` ${provider.displayName}: ${provider.apiKeyUrl}`));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
ui.newLine();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
export default authListCommand;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Profile Commands
|
|
3
|
+
*
|
|
4
|
+
* CLI commands for managing authentication profiles and switching providers
|
|
5
|
+
*/
|
|
6
|
+
import { AuthStore } from '../auth/store';
|
|
7
|
+
import { ui } from '../wizard/ui';
|
|
8
|
+
/**
|
|
9
|
+
* List all configured providers
|
|
10
|
+
*/
|
|
11
|
+
async function authProfileListCommand() {
|
|
12
|
+
ui.header('Auth Profiles');
|
|
13
|
+
const authStore = new AuthStore();
|
|
14
|
+
const status = authStore.getStatus();
|
|
15
|
+
if (!status.hasProviders) {
|
|
16
|
+
ui.warning('No providers configured. Run "nimbus login" to set up authentication.');
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
ui.table({
|
|
20
|
+
columns: [
|
|
21
|
+
{ key: 'name', header: 'Provider' },
|
|
22
|
+
{ key: 'model', header: 'Model' },
|
|
23
|
+
{ key: 'default', header: 'Default' },
|
|
24
|
+
{ key: 'validatedAt', header: 'Validated' },
|
|
25
|
+
],
|
|
26
|
+
data: status.providers.map(p => ({
|
|
27
|
+
name: p.name,
|
|
28
|
+
model: p.model || '-',
|
|
29
|
+
default: p.isDefault ? 'Yes' : '',
|
|
30
|
+
validatedAt: p.validatedAt ? new Date(p.validatedAt).toLocaleDateString() : '-',
|
|
31
|
+
})),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Show the current default provider
|
|
36
|
+
*/
|
|
37
|
+
async function authProfileShowCommand() {
|
|
38
|
+
ui.header('Current Auth Profile');
|
|
39
|
+
const authStore = new AuthStore();
|
|
40
|
+
const defaultProvider = authStore.getDefaultProvider();
|
|
41
|
+
if (!defaultProvider) {
|
|
42
|
+
ui.warning('No default provider set. Run "nimbus login" to configure.');
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const status = authStore.getStatus();
|
|
46
|
+
const providerInfo = status.providers.find(p => p.name === defaultProvider);
|
|
47
|
+
ui.print(` ${ui.color('Provider:', 'cyan')} ${defaultProvider}`);
|
|
48
|
+
if (providerInfo) {
|
|
49
|
+
ui.print(` ${ui.color('Model:', 'cyan')} ${providerInfo.model || '-'}`);
|
|
50
|
+
ui.print(` ${ui.color('Validated:', 'cyan')} ${providerInfo.validatedAt ? new Date(providerInfo.validatedAt).toLocaleDateString() : '-'}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Switch the default provider
|
|
55
|
+
*/
|
|
56
|
+
async function authProfileSwitchCommand(provider) {
|
|
57
|
+
ui.header(`Switch Auth Profile`);
|
|
58
|
+
const authStore = new AuthStore();
|
|
59
|
+
try {
|
|
60
|
+
authStore.setDefaultProvider(provider);
|
|
61
|
+
ui.success(`Default provider switched to "${provider}"`);
|
|
62
|
+
ui.info(`Persisted to ${authStore.getAuthPath()}`);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
ui.error(error.message);
|
|
66
|
+
ui.info('Available providers:');
|
|
67
|
+
const status = authStore.getStatus();
|
|
68
|
+
status.providers.forEach(p => {
|
|
69
|
+
ui.print(` - ${p.name}${p.isDefault ? ' (current default)' : ''}`);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Main auth-profile command router
|
|
75
|
+
*/
|
|
76
|
+
export async function authProfileCommand(subcommand, args) {
|
|
77
|
+
const positionalArgs = [];
|
|
78
|
+
for (let i = 0; i < args.length; i++) {
|
|
79
|
+
const arg = args[i];
|
|
80
|
+
if (!arg.startsWith('-')) {
|
|
81
|
+
positionalArgs.push(arg);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
switch (subcommand) {
|
|
85
|
+
case 'list':
|
|
86
|
+
case 'ls':
|
|
87
|
+
await authProfileListCommand();
|
|
88
|
+
break;
|
|
89
|
+
case 'show':
|
|
90
|
+
await authProfileShowCommand();
|
|
91
|
+
break;
|
|
92
|
+
case 'switch':
|
|
93
|
+
if (positionalArgs.length < 1) {
|
|
94
|
+
ui.error('Usage: nimbus auth-profile switch <provider>');
|
|
95
|
+
ui.info('Example: nimbus auth-profile switch openai');
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
await authProfileSwitchCommand(positionalArgs[0]);
|
|
99
|
+
break;
|
|
100
|
+
default:
|
|
101
|
+
ui.error(`Unknown auth-profile subcommand: ${subcommand || '(none)'}`);
|
|
102
|
+
ui.info('Available commands: list, show, switch <provider>');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Refresh Command
|
|
3
|
+
*
|
|
4
|
+
* Re-validate and refresh cloud provider credentials:
|
|
5
|
+
* - AWS: re-run SSO login or warn about expired temporary credentials
|
|
6
|
+
* - GCP: re-run gcloud auth application-default login
|
|
7
|
+
* - Azure: re-run az login
|
|
8
|
+
*
|
|
9
|
+
* Usage: nimbus auth-refresh [--provider aws|gcp|azure]
|
|
10
|
+
*/
|
|
11
|
+
import { ui } from '../wizard';
|
|
12
|
+
import { exec } from 'node:child_process';
|
|
13
|
+
import { promisify } from 'node:util';
|
|
14
|
+
const execAsync = promisify(exec);
|
|
15
|
+
/** Check if AWS credentials are valid and not expired */
|
|
16
|
+
async function checkAWSCredentials() {
|
|
17
|
+
try {
|
|
18
|
+
const { stdout } = await execAsync('aws sts get-caller-identity --output json', {
|
|
19
|
+
timeout: 10_000,
|
|
20
|
+
});
|
|
21
|
+
const identity = JSON.parse(stdout);
|
|
22
|
+
const isSso = identity.UserId?.includes(':') || false;
|
|
23
|
+
return {
|
|
24
|
+
valid: true,
|
|
25
|
+
message: `Account: ${identity.Account} | User: ${identity.UserId}`,
|
|
26
|
+
sso: isSso,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
const msg = e.message || String(e);
|
|
31
|
+
const isExpired = msg.includes('ExpiredToken') || msg.includes('expired') || msg.includes('token');
|
|
32
|
+
return { valid: false, message: isExpired ? 'Token expired' : msg, sso: false };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Refresh AWS SSO credentials */
|
|
36
|
+
async function refreshAWS(options) {
|
|
37
|
+
ui.header('AWS Credentials');
|
|
38
|
+
const check = await checkAWSCredentials();
|
|
39
|
+
if (check.valid) {
|
|
40
|
+
ui.success(`Credentials valid: ${check.message}`);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
ui.warning(`Credentials invalid: ${check.message}`);
|
|
44
|
+
// G18: Guide user through AWS SSO login if SSO profile detected
|
|
45
|
+
const awsSsoProfile = process.env.AWS_PROFILE;
|
|
46
|
+
if (awsSsoProfile) {
|
|
47
|
+
ui.info(`AWS SSO profile detected: ${awsSsoProfile}`);
|
|
48
|
+
ui.info(`Run in another terminal: aws sso login --profile ${awsSsoProfile}`);
|
|
49
|
+
ui.info('Then press Enter here to retry...');
|
|
50
|
+
// Wait for user to press Enter
|
|
51
|
+
await new Promise(resolve => {
|
|
52
|
+
const readline = require('readline');
|
|
53
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
54
|
+
rl.question('', () => { rl.close(); resolve(); });
|
|
55
|
+
});
|
|
56
|
+
// Retry the credentials check
|
|
57
|
+
try {
|
|
58
|
+
const { execFileSync } = await import('node:child_process');
|
|
59
|
+
execFileSync('aws', ['sts', 'get-caller-identity'], {
|
|
60
|
+
encoding: 'utf-8', timeout: 8000, stdio: ['pipe', 'pipe', 'pipe'],
|
|
61
|
+
});
|
|
62
|
+
ui.success('AWS credentials refreshed successfully.');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
ui.warning('AWS credentials still invalid. You may need to re-run aws sso login.');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Determine refresh method
|
|
70
|
+
try {
|
|
71
|
+
// Check if SSO is configured
|
|
72
|
+
const { stdout: ssoCheck } = await execAsync('aws configure list-profiles 2>/dev/null || echo ""', { timeout: 5000 });
|
|
73
|
+
const profiles = ssoCheck.trim().split('\n').filter(Boolean);
|
|
74
|
+
if (profiles.length > 0) {
|
|
75
|
+
ui.info('Refreshing AWS SSO credentials...');
|
|
76
|
+
ui.info(`Run: aws sso login --profile ${profiles[0]}`);
|
|
77
|
+
ui.info('Or set a new profile: aws configure sso');
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
ui.info('To refresh AWS credentials:');
|
|
81
|
+
ui.info(' 1. aws configure (for long-term credentials)');
|
|
82
|
+
ui.info(' 2. aws sso configure (for SSO)');
|
|
83
|
+
ui.info(' 3. aws sts assume-role (for role assumption)');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
ui.info('To configure AWS credentials: aws configure');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/** Refresh GCP credentials */
|
|
91
|
+
async function refreshGCP(_options) {
|
|
92
|
+
ui.header('GCP Credentials');
|
|
93
|
+
try {
|
|
94
|
+
const { stdout } = await execAsync('gcloud auth print-access-token 2>/dev/null', {
|
|
95
|
+
timeout: 5000,
|
|
96
|
+
});
|
|
97
|
+
if (stdout.trim().length > 10) {
|
|
98
|
+
try {
|
|
99
|
+
const { stdout: proj } = await execAsync('gcloud config get-value project 2>/dev/null', {
|
|
100
|
+
timeout: 3000,
|
|
101
|
+
});
|
|
102
|
+
ui.success(`Credentials valid. Project: ${proj.trim() || '(not set)'}`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
ui.success('Credentials valid');
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// Not valid
|
|
113
|
+
}
|
|
114
|
+
ui.warning('GCP credentials expired or not configured');
|
|
115
|
+
ui.info('To refresh: gcloud auth application-default login');
|
|
116
|
+
ui.info('For service accounts: gcloud auth activate-service-account --key-file=SA_KEY.json');
|
|
117
|
+
}
|
|
118
|
+
/** Refresh Azure credentials */
|
|
119
|
+
async function refreshAzure(_options) {
|
|
120
|
+
ui.header('Azure Credentials');
|
|
121
|
+
try {
|
|
122
|
+
const { stdout } = await execAsync('az account show --output json 2>/dev/null', {
|
|
123
|
+
timeout: 10_000,
|
|
124
|
+
});
|
|
125
|
+
const account = JSON.parse(stdout);
|
|
126
|
+
ui.success(`Credentials valid. Subscription: ${account.name || account.id} (${account.state})`);
|
|
127
|
+
if (account.state !== 'Enabled') {
|
|
128
|
+
ui.warning('Subscription is not in Enabled state');
|
|
129
|
+
}
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
// Not valid
|
|
134
|
+
}
|
|
135
|
+
ui.warning('Azure credentials expired or not configured');
|
|
136
|
+
ui.info('To refresh: az login');
|
|
137
|
+
ui.info('For service principals: az login --service-principal -u CLIENT_ID -p CLIENT_SECRET --tenant TENANT_ID');
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Run the auth-refresh command
|
|
141
|
+
*/
|
|
142
|
+
export async function authRefreshCommand(options = {}) {
|
|
143
|
+
const provider = options.provider ?? 'all';
|
|
144
|
+
ui.header('Nimbus Auth Refresh');
|
|
145
|
+
ui.info('Checking and refreshing cloud provider credentials...');
|
|
146
|
+
ui.newLine();
|
|
147
|
+
if (provider === 'all' || provider === 'aws') {
|
|
148
|
+
await refreshAWS(options);
|
|
149
|
+
ui.newLine();
|
|
150
|
+
}
|
|
151
|
+
if (provider === 'all' || provider === 'gcp') {
|
|
152
|
+
await refreshGCP(options);
|
|
153
|
+
ui.newLine();
|
|
154
|
+
}
|
|
155
|
+
if (provider === 'all' || provider === 'azure') {
|
|
156
|
+
await refreshAzure(options);
|
|
157
|
+
ui.newLine();
|
|
158
|
+
}
|
|
159
|
+
ui.info('Tip: Run "nimbus doctor" for a full system check');
|
|
160
|
+
}
|
|
161
|
+
export default authRefreshCommand;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Status Command
|
|
3
|
+
*
|
|
4
|
+
* Display current authentication status
|
|
5
|
+
*
|
|
6
|
+
* Usage: nimbus auth status
|
|
7
|
+
*/
|
|
8
|
+
import { logger } from '../utils';
|
|
9
|
+
import { ui } from '../wizard';
|
|
10
|
+
import { authStore, AuthStore, getProviderInfo } from '../auth';
|
|
11
|
+
/**
|
|
12
|
+
* Run the auth status command
|
|
13
|
+
*/
|
|
14
|
+
export async function authStatusCommand(options = {}) {
|
|
15
|
+
logger.info('Checking auth status');
|
|
16
|
+
const status = authStore.getStatus();
|
|
17
|
+
// JSON output mode
|
|
18
|
+
if (options.json) {
|
|
19
|
+
// Build safe JSON output (no raw API keys)
|
|
20
|
+
const safeOutput = {
|
|
21
|
+
isConfigured: status.isConfigured,
|
|
22
|
+
identity: status.identity
|
|
23
|
+
? {
|
|
24
|
+
provider: status.identity.provider,
|
|
25
|
+
username: status.identity.username,
|
|
26
|
+
name: status.identity.name,
|
|
27
|
+
authenticatedAt: status.identity.authenticatedAt,
|
|
28
|
+
}
|
|
29
|
+
: null,
|
|
30
|
+
providers: status.providers.map(p => ({
|
|
31
|
+
name: p.name,
|
|
32
|
+
model: p.model,
|
|
33
|
+
isDefault: p.isDefault,
|
|
34
|
+
validatedAt: p.validatedAt,
|
|
35
|
+
})),
|
|
36
|
+
defaultProvider: status.defaultProvider,
|
|
37
|
+
};
|
|
38
|
+
// Output sanitized JSON (no sensitive data included)
|
|
39
|
+
ui.print(JSON.stringify(safeOutput, null, 2));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// Human-readable output
|
|
43
|
+
ui.newLine();
|
|
44
|
+
ui.section('Authentication Status');
|
|
45
|
+
// Overall status
|
|
46
|
+
if (status.isConfigured) {
|
|
47
|
+
ui.success('Nimbus is configured and ready to use');
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
ui.warning('Nimbus is not configured. Run `nimbus login` to get started.');
|
|
51
|
+
}
|
|
52
|
+
ui.newLine();
|
|
53
|
+
// Identity section
|
|
54
|
+
ui.print(ui.bold('Identity'));
|
|
55
|
+
if (status.identity) {
|
|
56
|
+
const identity = status.identity;
|
|
57
|
+
ui.print(` Provider: GitHub`);
|
|
58
|
+
ui.print(` Username: ${identity.username}`);
|
|
59
|
+
if (identity.name) {
|
|
60
|
+
ui.print(` Name: ${identity.name}`);
|
|
61
|
+
}
|
|
62
|
+
ui.print(` Signed in: ${formatDate(identity.authenticatedAt)}`);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
ui.print(ui.dim(' Not signed in'));
|
|
66
|
+
ui.print(ui.dim(' Run `nimbus login` to sign in with GitHub'));
|
|
67
|
+
}
|
|
68
|
+
ui.newLine();
|
|
69
|
+
// Providers section
|
|
70
|
+
ui.print(ui.bold('LLM Providers'));
|
|
71
|
+
if (status.providers.length > 0) {
|
|
72
|
+
for (const provider of status.providers) {
|
|
73
|
+
const info = getProviderInfo(provider.name);
|
|
74
|
+
const defaultMarker = provider.isDefault ? ui.color(' (default)', 'green') : '';
|
|
75
|
+
ui.print(` ${info.displayName}${defaultMarker}`);
|
|
76
|
+
ui.print(` Model: ${provider.model}`);
|
|
77
|
+
// Get the actual credential to show masked key
|
|
78
|
+
const credential = authStore.getProvider(provider.name);
|
|
79
|
+
if (credential?.apiKey) {
|
|
80
|
+
ui.print(` API Key: ${AuthStore.maskApiKey(credential.apiKey)}`);
|
|
81
|
+
}
|
|
82
|
+
else if (!info.requiresApiKey) {
|
|
83
|
+
ui.print(` API Key: ${ui.dim('(not required)')}`);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
ui.print(` API Key: ${ui.dim('(from environment)')}`);
|
|
87
|
+
}
|
|
88
|
+
if (credential?.baseUrl) {
|
|
89
|
+
ui.print(` Base URL: ${credential.baseUrl}`);
|
|
90
|
+
}
|
|
91
|
+
if (provider.validatedAt) {
|
|
92
|
+
ui.print(` Validated: ${formatDate(provider.validatedAt)}`);
|
|
93
|
+
}
|
|
94
|
+
ui.newLine();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
ui.print(ui.dim(' No providers configured'));
|
|
99
|
+
ui.print(ui.dim(' Run `nimbus login` to configure LLM providers'));
|
|
100
|
+
ui.newLine();
|
|
101
|
+
}
|
|
102
|
+
// Auth file location
|
|
103
|
+
ui.print(ui.dim(`Config: ${authStore.getAuthPath()}`));
|
|
104
|
+
ui.newLine();
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Format ISO date string for display
|
|
108
|
+
*/
|
|
109
|
+
function formatDate(isoString) {
|
|
110
|
+
try {
|
|
111
|
+
const date = new Date(isoString);
|
|
112
|
+
// Check if date is valid (NaN check)
|
|
113
|
+
if (isNaN(date.getTime())) {
|
|
114
|
+
return isoString;
|
|
115
|
+
}
|
|
116
|
+
return date.toLocaleString();
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return isoString;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
export default authStatusCommand;
|