@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,315 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* nimbus rollback — Infrastructure Rollback Assistant
|
|
3
|
+
*
|
|
4
|
+
* Provides guided rollback for Helm releases and Kubernetes deployments.
|
|
5
|
+
* For Terraform, explains the rollback approach via state management.
|
|
6
|
+
*
|
|
7
|
+
* G20: New command added to the gap fix plan.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* nimbus rollback --helm <release>
|
|
11
|
+
* nimbus rollback --helm <release> --namespace <ns>
|
|
12
|
+
* nimbus rollback --k8s <deployment>
|
|
13
|
+
* nimbus rollback --k8s <deployment> --namespace <ns>
|
|
14
|
+
* nimbus rollback --tf
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { ui, confirm, select } from '../wizard';
|
|
18
|
+
|
|
19
|
+
/** Options for the rollback command. */
|
|
20
|
+
export interface RollbackOptions {
|
|
21
|
+
/** Helm release name to roll back. */
|
|
22
|
+
helm?: string;
|
|
23
|
+
/** Kubernetes deployment name to roll back. */
|
|
24
|
+
k8s?: string;
|
|
25
|
+
/** Kubernetes namespace (used for both Helm and kubectl). */
|
|
26
|
+
namespace?: string;
|
|
27
|
+
/** Terraform rollback guidance (no automated rollback). */
|
|
28
|
+
tf?: boolean;
|
|
29
|
+
/** Explicit terraform state rollback via --terraform flag. */
|
|
30
|
+
terraform?: boolean;
|
|
31
|
+
/** Directory containing terraform files (default: cwd). */
|
|
32
|
+
tfDir?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Run the nimbus rollback command.
|
|
37
|
+
*/
|
|
38
|
+
export async function rollbackCommand(options: RollbackOptions): Promise<void> {
|
|
39
|
+
const { execFileSync } = await import('node:child_process');
|
|
40
|
+
|
|
41
|
+
const run = (cmd: string, args: string[]): string => {
|
|
42
|
+
return execFileSync(cmd, args, {
|
|
43
|
+
encoding: 'utf-8',
|
|
44
|
+
timeout: 30000,
|
|
45
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// Helm rollback
|
|
50
|
+
if (options.helm) {
|
|
51
|
+
await rollbackHelm(options.helm, options.namespace, run);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Kubernetes deployment rollback
|
|
56
|
+
if (options.k8s) {
|
|
57
|
+
await rollbackK8s(options.k8s, options.namespace, run);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Terraform state rollback (--terraform flag)
|
|
62
|
+
if (options.terraform) {
|
|
63
|
+
await rollbackTerraformState(options.tfDir ?? process.cwd(), run);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Terraform guidance (--tf flag)
|
|
68
|
+
if (options.tf) {
|
|
69
|
+
rollbackTerraformGuidance();
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
ui.error('Specify a rollback target: --helm <release>, --k8s <deployment>, --tf, or --terraform');
|
|
74
|
+
ui.print('Usage:');
|
|
75
|
+
ui.print(' nimbus rollback --helm <release> [--namespace <ns>]');
|
|
76
|
+
ui.print(' nimbus rollback --k8s <deployment> [--namespace <ns>]');
|
|
77
|
+
ui.print(' nimbus rollback --tf');
|
|
78
|
+
ui.print(' nimbus rollback --terraform [--tf-dir <path>]');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function rollbackHelm(
|
|
82
|
+
release: string,
|
|
83
|
+
namespace: string | undefined,
|
|
84
|
+
run: (cmd: string, args: string[]) => string
|
|
85
|
+
): Promise<void> {
|
|
86
|
+
const nsArgs = namespace ? ['--namespace', namespace] : [];
|
|
87
|
+
|
|
88
|
+
ui.info(`Fetching history for Helm release: ${release}`);
|
|
89
|
+
|
|
90
|
+
let historyOutput: string;
|
|
91
|
+
try {
|
|
92
|
+
historyOutput = run('helm', ['history', release, '--output', 'table', ...nsArgs]);
|
|
93
|
+
} catch (e: unknown) {
|
|
94
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
95
|
+
ui.error(`Failed to fetch Helm history: ${msg}`);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
ui.newLine();
|
|
100
|
+
ui.print(historyOutput);
|
|
101
|
+
ui.newLine();
|
|
102
|
+
|
|
103
|
+
// Parse revision numbers from history output
|
|
104
|
+
const revisionLines = historyOutput
|
|
105
|
+
.split('\n')
|
|
106
|
+
.slice(1) // skip header
|
|
107
|
+
.filter(line => /^\d+/.test(line.trim()));
|
|
108
|
+
|
|
109
|
+
if (revisionLines.length === 0) {
|
|
110
|
+
ui.warning('No revision history found.');
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const revisionOptions = revisionLines.map(line => {
|
|
115
|
+
const parts = line.trim().split(/\s+/);
|
|
116
|
+
const rev = parts[0];
|
|
117
|
+
const status = parts[2] ?? '';
|
|
118
|
+
const description = parts.slice(4).join(' ') ?? '';
|
|
119
|
+
return {
|
|
120
|
+
value: rev,
|
|
121
|
+
label: `Revision ${rev} — ${status} ${description}`.trim(),
|
|
122
|
+
};
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const selectedRevision = await select<string>({
|
|
126
|
+
message: `Roll back ${release} to which revision?`,
|
|
127
|
+
options: revisionOptions,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
if (!selectedRevision) {
|
|
131
|
+
ui.info('Rollback cancelled.');
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const confirmed = await confirm({
|
|
136
|
+
message: `Roll back ${release} to revision ${selectedRevision}? This will update the release.`,
|
|
137
|
+
defaultValue: false,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
if (!confirmed) {
|
|
141
|
+
ui.info('Rollback cancelled.');
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
ui.startSpinner({ message: `Rolling back ${release} to revision ${selectedRevision}...` });
|
|
146
|
+
try {
|
|
147
|
+
run('helm', ['rollback', release, selectedRevision, ...nsArgs]);
|
|
148
|
+
ui.stopSpinnerSuccess(`${release} rolled back to revision ${selectedRevision}`);
|
|
149
|
+
} catch (e: unknown) {
|
|
150
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
151
|
+
ui.stopSpinnerFail(`Rollback failed: ${msg}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async function rollbackK8s(
|
|
156
|
+
deployment: string,
|
|
157
|
+
namespace: string | undefined,
|
|
158
|
+
run: (cmd: string, args: string[]) => string
|
|
159
|
+
): Promise<void> {
|
|
160
|
+
const nsArgs = namespace ? ['-n', namespace] : [];
|
|
161
|
+
const deployTarget = `deployment/${deployment}`;
|
|
162
|
+
|
|
163
|
+
ui.info(`Fetching rollout history for ${deployTarget}`);
|
|
164
|
+
|
|
165
|
+
let historyOutput: string;
|
|
166
|
+
try {
|
|
167
|
+
historyOutput = run('kubectl', ['rollout', 'history', deployTarget, ...nsArgs]);
|
|
168
|
+
} catch (e: unknown) {
|
|
169
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
170
|
+
ui.error(`Failed to fetch rollout history: ${msg}`);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
ui.newLine();
|
|
175
|
+
ui.print(historyOutput);
|
|
176
|
+
ui.newLine();
|
|
177
|
+
|
|
178
|
+
const confirmed = await confirm({
|
|
179
|
+
message: `Undo the last rollout for ${deployTarget}? This will revert to the previous revision.`,
|
|
180
|
+
defaultValue: false,
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
if (!confirmed) {
|
|
184
|
+
ui.info('Rollback cancelled.');
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
ui.startSpinner({ message: `Rolling back ${deployTarget}...` });
|
|
189
|
+
try {
|
|
190
|
+
run('kubectl', ['rollout', 'undo', deployTarget, ...nsArgs]);
|
|
191
|
+
ui.stopSpinnerSuccess(`${deployTarget} rolled back`);
|
|
192
|
+
// Show status
|
|
193
|
+
const status = run('kubectl', ['rollout', 'status', deployTarget, ...nsArgs]);
|
|
194
|
+
ui.print(status);
|
|
195
|
+
} catch (e: unknown) {
|
|
196
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
197
|
+
ui.stopSpinnerFail(`Rollback failed: ${msg}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async function rollbackTerraformState(
|
|
202
|
+
dir: string,
|
|
203
|
+
run: (cmd: string, args: string[]) => string
|
|
204
|
+
): Promise<void> {
|
|
205
|
+
const { existsSync, readdirSync } = await import('node:fs');
|
|
206
|
+
|
|
207
|
+
// Detect if terraform directory exists (look for *.tf files)
|
|
208
|
+
let hasTfFiles = false;
|
|
209
|
+
try {
|
|
210
|
+
hasTfFiles = existsSync(dir) && readdirSync(dir).some(f => f.endsWith('.tf'));
|
|
211
|
+
} catch {
|
|
212
|
+
/* ignore */
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (!hasTfFiles) {
|
|
216
|
+
ui.warning(`No *.tf files found in ${dir}. Is this a Terraform directory?`);
|
|
217
|
+
ui.dim('Use --tf-dir <path> to specify a different directory.');
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Show current workspace
|
|
222
|
+
let currentWorkspace = 'default';
|
|
223
|
+
try {
|
|
224
|
+
currentWorkspace = run('terraform', ['workspace', 'show']).trim();
|
|
225
|
+
ui.info(`Current Terraform workspace: ${currentWorkspace}`);
|
|
226
|
+
} catch {
|
|
227
|
+
ui.dim('Could not determine current workspace (terraform not in PATH?)');
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
ui.newLine();
|
|
231
|
+
|
|
232
|
+
// Show state list
|
|
233
|
+
let stateList = '';
|
|
234
|
+
try {
|
|
235
|
+
stateList = run('terraform', ['state', 'list']).trim();
|
|
236
|
+
} catch (e) {
|
|
237
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
238
|
+
ui.warning(`Could not list terraform state: ${msg}`);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (stateList) {
|
|
242
|
+
ui.info('Current state resources:');
|
|
243
|
+
for (const line of stateList.split('\n').slice(0, 20)) {
|
|
244
|
+
ui.print(` ${line}`);
|
|
245
|
+
}
|
|
246
|
+
const total = stateList.split('\n').length;
|
|
247
|
+
if (total > 20) ui.dim(` ... and ${total - 20} more`);
|
|
248
|
+
ui.newLine();
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Rollback guidance specific to state
|
|
252
|
+
ui.box({
|
|
253
|
+
title: `Terraform State Rollback — workspace: ${currentWorkspace}`,
|
|
254
|
+
content: [
|
|
255
|
+
'',
|
|
256
|
+
'To roll back Terraform state in workspace "' + currentWorkspace + '":',
|
|
257
|
+
'',
|
|
258
|
+
'1. Pull current state:',
|
|
259
|
+
' terraform state pull > state-backup.tfstate',
|
|
260
|
+
'',
|
|
261
|
+
'2. Push a previous state backup:',
|
|
262
|
+
' terraform state push <backup>.tfstate',
|
|
263
|
+
'',
|
|
264
|
+
'3. Or revert IaC code and re-apply:',
|
|
265
|
+
' git checkout <commit> -- *.tf',
|
|
266
|
+
' terraform plan && terraform apply',
|
|
267
|
+
'',
|
|
268
|
+
'4. For targeted resource rollback:',
|
|
269
|
+
' terraform apply -target=<resource>',
|
|
270
|
+
'',
|
|
271
|
+
'Run `nimbus chat` for AI-assisted rollback guidance.',
|
|
272
|
+
'',
|
|
273
|
+
],
|
|
274
|
+
style: 'rounded',
|
|
275
|
+
borderColor: 'yellow',
|
|
276
|
+
padding: 0,
|
|
277
|
+
});
|
|
278
|
+
ui.newLine();
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function rollbackTerraformGuidance(): void {
|
|
282
|
+
ui.newLine();
|
|
283
|
+
ui.box({
|
|
284
|
+
title: 'Terraform Rollback Guidance',
|
|
285
|
+
content: [
|
|
286
|
+
'',
|
|
287
|
+
'Terraform does not have a built-in rollback command.',
|
|
288
|
+
'To restore previous infrastructure state, use one of these approaches:',
|
|
289
|
+
'',
|
|
290
|
+
'1. Revert IaC code to a previous git commit:',
|
|
291
|
+
' git checkout <commit> -- *.tf',
|
|
292
|
+
' terraform plan && terraform apply',
|
|
293
|
+
'',
|
|
294
|
+
'2. Restore state from a backup:',
|
|
295
|
+
' terraform state pull > current.tfstate',
|
|
296
|
+
' terraform state push <backup>.tfstate',
|
|
297
|
+
'',
|
|
298
|
+
'3. Use workspace-specific state:',
|
|
299
|
+
' terraform workspace select <env>',
|
|
300
|
+
' terraform state list',
|
|
301
|
+
'',
|
|
302
|
+
'4. Target a specific resource for rollback:',
|
|
303
|
+
' terraform apply -target=<resource>',
|
|
304
|
+
'',
|
|
305
|
+
'Run `nimbus chat` to get AI-assisted rollback guidance.',
|
|
306
|
+
'',
|
|
307
|
+
],
|
|
308
|
+
style: 'rounded',
|
|
309
|
+
borderColor: 'yellow',
|
|
310
|
+
padding: 0,
|
|
311
|
+
});
|
|
312
|
+
ui.newLine();
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export default rollbackCommand;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* nimbus rollout — Watch Kubernetes Deployment Rollouts
|
|
3
|
+
*
|
|
4
|
+
* Streams real-time rollout status for a Kubernetes deployment.
|
|
5
|
+
* Wraps `kubectl rollout status deployment/<name> --watch`.
|
|
6
|
+
*
|
|
7
|
+
* L1: New command for DevOps parity.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* nimbus rollout <deployment>
|
|
11
|
+
* nimbus rollout <deployment> --namespace <ns>
|
|
12
|
+
* nimbus rollout <deployment> --timeout 10m
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { spawnExec } from '../tools/spawn-exec';
|
|
16
|
+
|
|
17
|
+
/** Options for the rollout command. */
|
|
18
|
+
export interface RolloutOptions {
|
|
19
|
+
/** Deployment name to watch. */
|
|
20
|
+
deployment: string;
|
|
21
|
+
/** Kubernetes namespace. */
|
|
22
|
+
namespace?: string;
|
|
23
|
+
/** Timeout for the rollout (default: 5m). */
|
|
24
|
+
timeout?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Run the nimbus rollout command.
|
|
29
|
+
* Streams kubectl rollout status with live output.
|
|
30
|
+
*/
|
|
31
|
+
export async function rolloutCommand(options: RolloutOptions): Promise<void> {
|
|
32
|
+
const { deployment, namespace, timeout = '5m' } = options;
|
|
33
|
+
|
|
34
|
+
const nsFlag = namespace ? `-n ${namespace}` : '';
|
|
35
|
+
const timeoutFlag = `--timeout=${timeout}`;
|
|
36
|
+
const command = `kubectl rollout status deployment/${deployment} ${nsFlag} ${timeoutFlag} --watch`.trim().replace(/\s+/g, ' ');
|
|
37
|
+
|
|
38
|
+
console.log(`Watching rollout: deployment/${deployment}${namespace ? ` (namespace: ${namespace})` : ''}`);
|
|
39
|
+
console.log(`Timeout: ${timeout}\n`);
|
|
40
|
+
|
|
41
|
+
const ac = new AbortController();
|
|
42
|
+
|
|
43
|
+
// Allow Ctrl+C to gracefully abort the rollout watch
|
|
44
|
+
process.on('SIGINT', () => {
|
|
45
|
+
console.log('\nRollout watch interrupted.');
|
|
46
|
+
ac.abort();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
const result = await spawnExec(command, {
|
|
51
|
+
onChunk: (chunk: string) => {
|
|
52
|
+
process.stdout.write(chunk);
|
|
53
|
+
},
|
|
54
|
+
timeout: parseTimeoutToMs(timeout),
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const combined = [result.stdout, result.stderr].filter(Boolean).join('\n');
|
|
58
|
+
if (result.exitCode !== 0) {
|
|
59
|
+
console.error(`\nRollout failed (exit code ${result.exitCode}):`);
|
|
60
|
+
if (combined) console.error(combined);
|
|
61
|
+
process.exitCode = 1;
|
|
62
|
+
} else {
|
|
63
|
+
console.log('\nRollout complete.');
|
|
64
|
+
}
|
|
65
|
+
} catch (err) {
|
|
66
|
+
if ((err as Error).message?.includes('aborted')) {
|
|
67
|
+
// Already printed abort message
|
|
68
|
+
} else {
|
|
69
|
+
console.error(`Rollout watch error: ${err instanceof Error ? err.message : String(err)}`);
|
|
70
|
+
process.exitCode = 1;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Parse a kubectl-style timeout string (e.g. "5m", "30s", "2h") to milliseconds.
|
|
77
|
+
*/
|
|
78
|
+
export function parseTimeoutToMs(timeout: string): number {
|
|
79
|
+
const match = timeout.match(/^(\d+)(s|m|h)$/);
|
|
80
|
+
if (!match) return 300_000; // default 5 min
|
|
81
|
+
const value = parseInt(match[1]);
|
|
82
|
+
switch (match[2]) {
|
|
83
|
+
case 's': return value * 1000;
|
|
84
|
+
case 'm': return value * 60 * 1000;
|
|
85
|
+
case 'h': return value * 3600 * 1000;
|
|
86
|
+
default: return 300_000;
|
|
87
|
+
}
|
|
88
|
+
}
|