@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
package/bin/nimbus
CHANGED
|
@@ -2,28 +2,44 @@
|
|
|
2
2
|
# Nimbus CLI launcher — prefers Bun, falls back to Node.js (>=18).
|
|
3
3
|
set -e
|
|
4
4
|
|
|
5
|
+
# Resolve the real script location, following symlinks so this works when npm
|
|
6
|
+
# installs the bin entry as a symlink (e.g. /opt/homebrew/bin/nimbus ->
|
|
7
|
+
# .../node_modules/@build-astron-co/nimbus/bin/nimbus).
|
|
5
8
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
6
|
-
|
|
9
|
+
REAL_SCRIPT="$SCRIPT_DIR/nimbus"
|
|
10
|
+
if [ -L "$REAL_SCRIPT" ]; then
|
|
11
|
+
LINK_TARGET="$(readlink "$REAL_SCRIPT")"
|
|
12
|
+
case "$LINK_TARGET" in
|
|
13
|
+
/*) REAL_SCRIPT="$LINK_TARGET" ;;
|
|
14
|
+
*) REAL_SCRIPT="$SCRIPT_DIR/$LINK_TARGET" ;;
|
|
15
|
+
esac
|
|
16
|
+
fi
|
|
17
|
+
PKG_ROOT="$(cd "$(dirname "$REAL_SCRIPT")/.." && pwd)"
|
|
18
|
+
ENTRY="$PKG_ROOT/src/nimbus.ts"
|
|
7
19
|
|
|
8
20
|
# Prefer Bun for best performance (native bun:sqlite, fast startup)
|
|
9
21
|
if command -v bun >/dev/null 2>&1; then
|
|
10
22
|
exec bun "$ENTRY" "$@"
|
|
11
23
|
fi
|
|
12
24
|
|
|
13
|
-
# Fallback: Node.js with tsx for TypeScript execution
|
|
25
|
+
# Fallback: Node.js with tsx for TypeScript execution.
|
|
26
|
+
# We use `node --loader tsx/esm` rather than `tsx` directly to ensure ESM
|
|
27
|
+
# output mode — required because yoga-layout (Ink dep) uses top-level await
|
|
28
|
+
# which is incompatible with tsx's default CJS output.
|
|
14
29
|
if command -v node >/dev/null 2>&1; then
|
|
15
30
|
NODE_VERSION=$(node -e "console.log(process.versions.node.split('.')[0])")
|
|
16
31
|
if [ "$NODE_VERSION" -ge 18 ] 2>/dev/null; then
|
|
17
|
-
#
|
|
18
|
-
|
|
19
|
-
if [ -
|
|
20
|
-
exec "$
|
|
32
|
+
# Prefer the tsx ESM loader bundled with this package
|
|
33
|
+
TSX_ESM="$PKG_ROOT/node_modules/tsx/dist/esm/index.mjs"
|
|
34
|
+
if [ -f "$TSX_ESM" ]; then
|
|
35
|
+
exec node --loader "$TSX_ESM" "$ENTRY" "$@"
|
|
21
36
|
fi
|
|
22
|
-
# Try global tsx
|
|
23
|
-
|
|
24
|
-
|
|
37
|
+
# Try global tsx ESM loader (npm global install)
|
|
38
|
+
TSX_GLOBAL_ESM="$(npm root -g 2>/dev/null)/tsx/dist/esm/index.mjs"
|
|
39
|
+
if [ -f "$TSX_GLOBAL_ESM" ]; then
|
|
40
|
+
exec node --loader "$TSX_GLOBAL_ESM" "$ENTRY" "$@"
|
|
25
41
|
fi
|
|
26
|
-
# Last resort:
|
|
42
|
+
# Last resort: node --import tsx (Node >= 18.19, tsx must be globally installed)
|
|
27
43
|
exec node --import tsx "$ENTRY" "$@"
|
|
28
44
|
fi
|
|
29
45
|
fi
|
package/bin/nimbus.cmd
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
:: Nimbus CLI launcher for Windows (CMD / PowerShell).
|
|
3
|
+
:: Resolves the package root relative to this script's location so it works
|
|
4
|
+
:: when npm installs the bin entry as a junction/shim in node_modules/.bin/.
|
|
5
|
+
|
|
6
|
+
setlocal enabledelayedexpansion
|
|
7
|
+
|
|
8
|
+
:: Locate the package root (one level up from this bin\ directory)
|
|
9
|
+
set "SCRIPT_DIR=%~dp0"
|
|
10
|
+
:: Remove trailing backslash
|
|
11
|
+
if "%SCRIPT_DIR:~-1%"=="\" set "SCRIPT_DIR=%SCRIPT_DIR:~0,-1%"
|
|
12
|
+
set "PKG_ROOT=%SCRIPT_DIR%\.."
|
|
13
|
+
set "ENTRY=%PKG_ROOT%\src\nimbus.ts"
|
|
14
|
+
|
|
15
|
+
:: Primary: Node.js >= 18 with tsx ESM loader (project is Node.js-native)
|
|
16
|
+
where node >nul 2>&1
|
|
17
|
+
if %errorlevel% equ 0 (
|
|
18
|
+
set "TSX_ESM=%PKG_ROOT%\node_modules\tsx\dist\esm\index.mjs"
|
|
19
|
+
if exist "!TSX_ESM!" (
|
|
20
|
+
node --loader "!TSX_ESM!" "%ENTRY%" %*
|
|
21
|
+
exit /b %errorlevel%
|
|
22
|
+
)
|
|
23
|
+
:: Try global tsx loader
|
|
24
|
+
for /f "delims=" %%i in ('npm root -g 2^>nul') do set "NPM_GLOBAL=%%i"
|
|
25
|
+
if defined NPM_GLOBAL (
|
|
26
|
+
set "TSX_GLOBAL=!NPM_GLOBAL!\tsx\dist\esm\index.mjs"
|
|
27
|
+
if exist "!TSX_GLOBAL!" (
|
|
28
|
+
node --loader "!TSX_GLOBAL!" "%ENTRY%" %*
|
|
29
|
+
exit /b %errorlevel%
|
|
30
|
+
)
|
|
31
|
+
)
|
|
32
|
+
:: Last resort: node --import tsx
|
|
33
|
+
node --import tsx "%ENTRY%" %*
|
|
34
|
+
exit /b %errorlevel%
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
echo Error: Nimbus requires Node.js ^>= 18. >&2
|
|
38
|
+
echo. >&2
|
|
39
|
+
echo Install Node.js: >&2
|
|
40
|
+
echo https://nodejs.org/ >&2
|
|
41
|
+
exit /b 1
|
package/bin/nimbus.mjs
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Nimbus CLI — cross-platform ESM launcher.
|
|
4
|
+
*
|
|
5
|
+
* This is the `bin` entry used by npm on all platforms (including Windows).
|
|
6
|
+
* It locates the package root (following symlinks so npm global installs work),
|
|
7
|
+
* then spawns Node.js with the tsx ESM loader to execute the TypeScript source.
|
|
8
|
+
*
|
|
9
|
+
* Why .mjs instead of a shell script?
|
|
10
|
+
* On Windows, npm's cmd-shim cannot wrap a POSIX sh script. A Node.js ESM
|
|
11
|
+
* bin entry (#!/usr/bin/env node + .mjs) works on all platforms.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { spawnSync, execSync } from 'node:child_process';
|
|
15
|
+
import { existsSync } from 'node:fs';
|
|
16
|
+
import { fileURLToPath } from 'node:url';
|
|
17
|
+
import { dirname, join, resolve } from 'node:path';
|
|
18
|
+
|
|
19
|
+
// L1: Enable ANSI color support on Windows terminals (Windows 10+ supports VT100).
|
|
20
|
+
// FORCE_COLOR=1 is the standard signal for chalk/ink/supports-color to emit ANSI codes.
|
|
21
|
+
// This must run before any child process is spawned so the env var is inherited.
|
|
22
|
+
if (process.platform === 'win32') {
|
|
23
|
+
process.env.FORCE_COLOR ??= '1';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Resolve the true package root, following symlinks (npm global installs symlink on POSIX).
|
|
27
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
28
|
+
const __dirname = dirname(__filename);
|
|
29
|
+
const PKG_ROOT = resolve(__dirname, '..');
|
|
30
|
+
const ENTRY = join(PKG_ROOT, 'src', 'nimbus.ts');
|
|
31
|
+
|
|
32
|
+
const passArgs = process.argv.slice(2);
|
|
33
|
+
|
|
34
|
+
function run(nodeArgs) {
|
|
35
|
+
const result = spawnSync(process.execPath, [...nodeArgs, ENTRY, ...passArgs], {
|
|
36
|
+
stdio: 'inherit',
|
|
37
|
+
env: process.env,
|
|
38
|
+
});
|
|
39
|
+
process.exit(result.status ?? (result.error ? 1 : 0));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 0. Pre-compiled dist (fastest — no tsx overhead)
|
|
43
|
+
const DIST_ENTRY = join(PKG_ROOT, 'dist', 'src', 'nimbus.js');
|
|
44
|
+
if (existsSync(DIST_ENTRY)) {
|
|
45
|
+
const result = spawnSync(process.execPath, [DIST_ENTRY, ...passArgs], {
|
|
46
|
+
stdio: 'inherit',
|
|
47
|
+
env: process.env,
|
|
48
|
+
});
|
|
49
|
+
process.exit(result.status ?? (result.error ? 1 : 0));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 1. tsx ESM loader bundled with this package (most reliable)
|
|
53
|
+
const TSX_BUNDLED = join(PKG_ROOT, 'node_modules', 'tsx', 'dist', 'esm', 'index.mjs');
|
|
54
|
+
if (existsSync(TSX_BUNDLED)) {
|
|
55
|
+
run(['--loader', TSX_BUNDLED]);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 2. tsx ESM loader from global npm
|
|
59
|
+
try {
|
|
60
|
+
const globalRoot = execSync('npm root -g', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
61
|
+
const TSX_GLOBAL = join(globalRoot, 'tsx', 'dist', 'esm', 'index.mjs');
|
|
62
|
+
if (existsSync(TSX_GLOBAL)) {
|
|
63
|
+
run(['--loader', TSX_GLOBAL]);
|
|
64
|
+
}
|
|
65
|
+
} catch {
|
|
66
|
+
// npm root -g failed — continue
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// 3. Last resort: node --import tsx (Node >= 18.19, tsx must be available)
|
|
70
|
+
run(['--import', 'tsx']);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# Dynamic completion helpers
|
|
4
|
+
_nimbus_kubectl_contexts() {
|
|
5
|
+
kubectl config get-contexts -o name 2>/dev/null
|
|
6
|
+
}
|
|
7
|
+
_nimbus_namespaces() {
|
|
8
|
+
kubectl get namespaces -o name 2>/dev/null | sed 's|namespace/||'
|
|
9
|
+
}
|
|
10
|
+
_nimbus_tf_workspaces() {
|
|
11
|
+
terraform workspace list 2>/dev/null | sed 's/^[* ]*//'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
_nimbus_completions() {
|
|
15
|
+
local cur="${COMP_WORDS[COMP_CWORD]}"
|
|
16
|
+
local prev="${COMP_WORDS[COMP_CWORD-1]}"
|
|
17
|
+
local commands="chat run plan build deploy init login logout help version upgrade update doctor logs status alias pipeline rollback incident runbook schedule export"
|
|
18
|
+
# G20: Subcommand completions for terraform/kubectl/helm
|
|
19
|
+
case "${COMP_WORDS[1]}" in
|
|
20
|
+
tf|terraform) COMPREPLY=($(compgen -W "init plan apply destroy validate workspace output" -- "${cur}")); return ;;
|
|
21
|
+
k8s|kubectl) COMPREPLY=($(compgen -W "get apply delete logs scale rollout exec describe diff" -- "${cur}")); return ;;
|
|
22
|
+
helm) COMPREPLY=($(compgen -W "install upgrade rollback uninstall list show diff" -- "${cur}")); return ;;
|
|
23
|
+
runbook) COMPREPLY=($(compgen -W "list run create" -- "${cur}")); return ;;
|
|
24
|
+
schedule) COMPREPLY=($(compgen -W "list add remove run-now" -- "${cur}")); return ;;
|
|
25
|
+
export) COMPREPLY=($(compgen -W "--format --output" -- "${cur}")); return ;;
|
|
26
|
+
esac
|
|
27
|
+
case "$prev" in
|
|
28
|
+
--mode) COMPREPLY=($(compgen -W "plan build deploy" -- "$cur")); return ;;
|
|
29
|
+
--format) COMPREPLY=($(compgen -W "text json table md html" -- "$cur")); return ;;
|
|
30
|
+
--ui) COMPREPLY=($(compgen -W "ink readline" -- "$cur")); return ;;
|
|
31
|
+
--context) COMPREPLY=($(compgen -W "$(_nimbus_kubectl_contexts)" -- "$cur")); return ;;
|
|
32
|
+
--namespace|-n) COMPREPLY=($(compgen -W "$(_nimbus_namespaces)" -- "$cur")); return ;;
|
|
33
|
+
--workspace) COMPREPLY=($(compgen -W "$(_nimbus_tf_workspaces)" -- "$cur")); return ;;
|
|
34
|
+
nimbus) COMPREPLY=($(compgen -W "$commands" -- "$cur")); return ;;
|
|
35
|
+
esac
|
|
36
|
+
COMPREPLY=($(compgen -W "--mode --format --auto-approve --stdin --model --max-turns --help --version --context --namespace --workspace --quiet --budget" -- "$cur"))
|
|
37
|
+
}
|
|
38
|
+
complete -F _nimbus_completions nimbus
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
complete -c nimbus -f
|
|
2
|
+
|
|
3
|
+
# Subcommands
|
|
4
|
+
complete -c nimbus -n '__fish_use_subcommand' -a chat -d 'Interactive DevOps agent TUI'
|
|
5
|
+
complete -c nimbus -n '__fish_use_subcommand' -a run -d 'Run agent non-interactively'
|
|
6
|
+
complete -c nimbus -n '__fish_use_subcommand' -a plan -d 'Preview infrastructure changes'
|
|
7
|
+
complete -c nimbus -n '__fish_use_subcommand' -a init -d 'Generate NIMBUS.md'
|
|
8
|
+
complete -c nimbus -n '__fish_use_subcommand' -a login -d 'Configure LLM provider'
|
|
9
|
+
complete -c nimbus -n '__fish_use_subcommand' -a logout -d 'Remove credentials'
|
|
10
|
+
complete -c nimbus -n '__fish_use_subcommand' -a help -d 'Show help'
|
|
11
|
+
complete -c nimbus -n '__fish_use_subcommand' -a version -d 'Show version'
|
|
12
|
+
complete -c nimbus -n '__fish_use_subcommand' -a upgrade -d 'Upgrade to latest version'
|
|
13
|
+
complete -c nimbus -n '__fish_use_subcommand' -a update -d 'Alias for upgrade'
|
|
14
|
+
complete -c nimbus -n '__fish_use_subcommand' -a doctor -d 'Check environment'
|
|
15
|
+
complete -c nimbus -n '__fish_use_subcommand' -a logs -d 'Stream Kubernetes pod logs'
|
|
16
|
+
complete -c nimbus -n '__fish_use_subcommand' -a status -d 'Show current agent status'
|
|
17
|
+
complete -c nimbus -n '__fish_use_subcommand' -a alias -d 'Manage command aliases'
|
|
18
|
+
complete -c nimbus -n '__fish_use_subcommand' -a pipeline -d 'Run CI/CD pipeline'
|
|
19
|
+
complete -c nimbus -n '__fish_use_subcommand' -a rollback -d 'Rollback infrastructure changes'
|
|
20
|
+
complete -c nimbus -n '__fish_use_subcommand' -a incident -d 'Incident response session'
|
|
21
|
+
complete -c nimbus -n '__fish_use_subcommand' -a runbook -d 'Execute operational runbooks'
|
|
22
|
+
complete -c nimbus -n '__fish_use_subcommand' -a schedule -d 'Manage periodic automation'
|
|
23
|
+
complete -c nimbus -n '__fish_use_subcommand' -a export -d 'Export session to file'
|
|
24
|
+
|
|
25
|
+
# G20: Subcommand completions for tf/kubectl/helm
|
|
26
|
+
complete -c nimbus -n '__fish_seen_subcommand_from tf terraform' -a 'init plan apply destroy validate workspace output' -d 'terraform subcommand'
|
|
27
|
+
complete -c nimbus -n '__fish_seen_subcommand_from k8s kubectl' -a 'get apply delete logs scale rollout exec describe diff' -d 'kubectl subcommand'
|
|
28
|
+
complete -c nimbus -n '__fish_seen_subcommand_from helm' -a 'install upgrade rollback uninstall list show diff' -d 'helm subcommand'
|
|
29
|
+
complete -c nimbus -n '__fish_seen_subcommand_from runbook' -a 'list run create' -d 'runbook subcommand'
|
|
30
|
+
complete -c nimbus -n '__fish_seen_subcommand_from schedule' -a 'list add remove run-now' -d 'schedule subcommand'
|
|
31
|
+
|
|
32
|
+
# Flags
|
|
33
|
+
complete -c nimbus -l mode -a 'plan build deploy' -d 'Agent mode'
|
|
34
|
+
complete -c nimbus -l format -a 'text json table md html' -d 'Output format'
|
|
35
|
+
complete -c nimbus -l auto-approve -d 'Auto-approve permissions'
|
|
36
|
+
complete -c nimbus -l model -d 'LLM model override'
|
|
37
|
+
complete -c nimbus -l max-turns -d 'Maximum agent turns'
|
|
38
|
+
complete -c nimbus -l budget -d 'Cost budget in USD'
|
|
39
|
+
complete -c nimbus -l quiet -s q -d 'Suppress banners and decorative headers'
|
|
40
|
+
|
|
41
|
+
# Dynamic completions for --context (kubectl contexts)
|
|
42
|
+
complete -c nimbus -l context -d 'kubectl context' -a '(kubectl config get-contexts -o name 2>/dev/null)'
|
|
43
|
+
|
|
44
|
+
# Dynamic completions for --namespace (kubernetes namespaces)
|
|
45
|
+
complete -c nimbus -l namespace -s n -d 'Kubernetes namespace' -a '(kubectl get namespaces -o name 2>/dev/null | string replace "namespace/" "")'
|
|
46
|
+
|
|
47
|
+
# Dynamic completions for --workspace (terraform workspaces)
|
|
48
|
+
complete -c nimbus -l workspace -d 'Terraform workspace' -a '(terraform workspace list 2>/dev/null | string replace -r "^[* ]*" "")'
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#compdef nimbus
|
|
2
|
+
|
|
3
|
+
# Dynamic completion helpers
|
|
4
|
+
_nimbus_kubectl_contexts() {
|
|
5
|
+
local contexts
|
|
6
|
+
contexts=(${(f)"$(kubectl config get-contexts -o name 2>/dev/null)"})
|
|
7
|
+
_describe 'kubectl contexts' contexts
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
_nimbus_namespaces() {
|
|
11
|
+
local namespaces
|
|
12
|
+
namespaces=(${(f)"$(kubectl get namespaces -o name 2>/dev/null | sed 's|namespace/||')"})
|
|
13
|
+
_describe 'kubernetes namespaces' namespaces
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
_nimbus_tf_workspaces() {
|
|
17
|
+
local workspaces
|
|
18
|
+
workspaces=(${(f)"$(terraform workspace list 2>/dev/null | sed 's/^[* ]*//')"})
|
|
19
|
+
_describe 'terraform workspaces' workspaces
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
_nimbus() {
|
|
23
|
+
local -a commands
|
|
24
|
+
commands=(
|
|
25
|
+
'chat:Interactive DevOps agent TUI'
|
|
26
|
+
'run:Run agent non-interactively'
|
|
27
|
+
'plan:Preview infrastructure changes'
|
|
28
|
+
'init:Generate NIMBUS.md project context'
|
|
29
|
+
'login:Configure LLM provider'
|
|
30
|
+
'logout:Remove credentials'
|
|
31
|
+
'help:Show help'
|
|
32
|
+
'version:Show version'
|
|
33
|
+
'upgrade:Upgrade to latest version'
|
|
34
|
+
'update:Alias for upgrade'
|
|
35
|
+
'doctor:Check environment'
|
|
36
|
+
'logs:Stream Kubernetes pod logs'
|
|
37
|
+
'status:Show current agent status'
|
|
38
|
+
'alias:Manage command aliases'
|
|
39
|
+
'pipeline:Run CI/CD pipeline'
|
|
40
|
+
'rollback:Rollback infrastructure changes'
|
|
41
|
+
'incident:Incident response session'
|
|
42
|
+
'runbook:Execute operational runbooks'
|
|
43
|
+
'schedule:Manage periodic automation'
|
|
44
|
+
'export:Export session to file'
|
|
45
|
+
)
|
|
46
|
+
_arguments \
|
|
47
|
+
'1: :->command' \
|
|
48
|
+
'--mode[Agent mode]:mode:(plan build deploy)' \
|
|
49
|
+
'--format[Output format]:format:(text json table md html)' \
|
|
50
|
+
'--auto-approve[Auto-approve permissions]' \
|
|
51
|
+
'--model[LLM model]:model:' \
|
|
52
|
+
'--context[kubectl context]:context:_nimbus_kubectl_contexts' \
|
|
53
|
+
'--namespace[Kubernetes namespace]:namespace:_nimbus_namespaces' \
|
|
54
|
+
'--workspace[Terraform workspace]:workspace:_nimbus_tf_workspaces' \
|
|
55
|
+
'--budget[Cost budget in USD]:budget:' \
|
|
56
|
+
'--quiet[Suppress banners/headers]' \
|
|
57
|
+
'--version[Show version]' \
|
|
58
|
+
'--help[Show help]'
|
|
59
|
+
# G20: Subcommand completions
|
|
60
|
+
case ${words[2]} in
|
|
61
|
+
tf|terraform)
|
|
62
|
+
local -a tf_cmds; tf_cmds=('init' 'plan' 'apply' 'destroy' 'validate' 'workspace' 'output')
|
|
63
|
+
_describe 'terraform subcommands' tf_cmds; return ;;
|
|
64
|
+
k8s|kubectl)
|
|
65
|
+
local -a k8s_cmds; k8s_cmds=('get' 'apply' 'delete' 'logs' 'scale' 'rollout' 'exec' 'describe' 'diff')
|
|
66
|
+
_describe 'kubectl subcommands' k8s_cmds; return ;;
|
|
67
|
+
helm)
|
|
68
|
+
local -a helm_cmds; helm_cmds=('install' 'upgrade' 'rollback' 'uninstall' 'list' 'show' 'diff')
|
|
69
|
+
_describe 'helm subcommands' helm_cmds; return ;;
|
|
70
|
+
runbook)
|
|
71
|
+
local -a rb_cmds; rb_cmds=('list' 'run' 'create')
|
|
72
|
+
_describe 'runbook subcommands' rb_cmds; return ;;
|
|
73
|
+
schedule)
|
|
74
|
+
local -a sched_cmds; sched_cmds=('list' 'add' 'remove' 'run-now')
|
|
75
|
+
_describe 'schedule subcommands' sched_cmds; return ;;
|
|
76
|
+
esac
|
|
77
|
+
case $state in
|
|
78
|
+
command) _describe 'nimbus commands' commands ;;
|
|
79
|
+
esac
|
|
80
|
+
}
|
|
81
|
+
_nimbus "$@"
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compaction Agent
|
|
3
|
+
*
|
|
4
|
+
* Uses a fast LLM model (haiku) to summarize earlier conversation context
|
|
5
|
+
* while preserving key information needed for continuity.
|
|
6
|
+
*
|
|
7
|
+
* The compaction agent is invoked automatically by the context manager
|
|
8
|
+
* when the conversation exceeds the configured threshold, or manually
|
|
9
|
+
* by the user via a `/compact` command in the TUI.
|
|
10
|
+
*
|
|
11
|
+
* Key design decisions:
|
|
12
|
+
* - Uses the cheapest available model (haiku alias) to minimize cost.
|
|
13
|
+
* - Truncates very long tool outputs before sending to the summarizer.
|
|
14
|
+
* - Falls back to a simple extractive summary if the LLM call fails.
|
|
15
|
+
* - Preserves all technical details, file paths, and decisions.
|
|
16
|
+
*
|
|
17
|
+
* @module agent/compaction-agent
|
|
18
|
+
*/
|
|
19
|
+
import { getTextContent } from '../llm/types';
|
|
20
|
+
import { ContextManager, estimateTokens } from './context-manager';
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Constants
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
/** The system prompt given to the compaction model. */
|
|
25
|
+
const COMPACTION_SYSTEM_PROMPT = `You are a conversation summarizer for the Nimbus CLI agent. Your job is to create a concise summary of a conversation between a user and an AI assistant that helps with cloud infrastructure and DevOps tasks.
|
|
26
|
+
|
|
27
|
+
Rules:
|
|
28
|
+
1. Preserve ALL important technical details: file paths, resource names, configuration values, error messages, decisions made.
|
|
29
|
+
2. Preserve the user's original intent and any requirements they specified.
|
|
30
|
+
3. Preserve the current state of any ongoing work (what was done, what remains).
|
|
31
|
+
4. Remove conversational filler, repeated information, and verbose tool outputs.
|
|
32
|
+
5. Use bullet points for clarity.
|
|
33
|
+
6. Keep the summary under 2000 tokens.
|
|
34
|
+
7. Structure the summary as:
|
|
35
|
+
- **User's Goal**: What the user is trying to accomplish
|
|
36
|
+
- **Key Decisions**: Important choices that were made
|
|
37
|
+
- **Work Completed**: What actions were taken and their results
|
|
38
|
+
- **Current State**: Where things stand now
|
|
39
|
+
- **Pending Items**: What still needs to be done (if any)`;
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Public API
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
/**
|
|
44
|
+
* Run the compaction agent to summarize a set of messages.
|
|
45
|
+
*
|
|
46
|
+
* Splits the conversation into messages to preserve and messages to
|
|
47
|
+
* summarize (using the context manager's selection logic), sends the
|
|
48
|
+
* latter to a fast LLM for summarization, then reassembles a compacted
|
|
49
|
+
* message array.
|
|
50
|
+
*
|
|
51
|
+
* @param messages - The full conversation message array.
|
|
52
|
+
* @param contextManager - The context manager instance (provides selection logic).
|
|
53
|
+
* @param options - Compaction options (router, model, focus area).
|
|
54
|
+
* @returns The compacted messages and a result summary.
|
|
55
|
+
*/
|
|
56
|
+
export async function runCompaction(messages, contextManager, options) {
|
|
57
|
+
const { preserved, toSummarize } = contextManager.selectPreservedMessages(messages);
|
|
58
|
+
// Nothing to summarize -- return early
|
|
59
|
+
if (toSummarize.length === 0) {
|
|
60
|
+
const totalTokens = messages.reduce((sum, m) => sum + estimateTokens(getTextContent(m.content)), 0);
|
|
61
|
+
return {
|
|
62
|
+
messages,
|
|
63
|
+
result: {
|
|
64
|
+
originalTokens: totalTokens,
|
|
65
|
+
compactedTokens: totalTokens,
|
|
66
|
+
savedTokens: 0,
|
|
67
|
+
summaryPreserved: false,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// Format messages for the summarizer
|
|
72
|
+
const conversationText = formatMessagesForSummary(toSummarize);
|
|
73
|
+
const originalTokens = estimateTokens(conversationText);
|
|
74
|
+
// Build the user prompt for the summarizer
|
|
75
|
+
let userPrompt = `Please summarize the following conversation between a user and the Nimbus AI assistant:\n\n${conversationText}`;
|
|
76
|
+
if (options.focusArea) {
|
|
77
|
+
userPrompt += `\n\nPay special attention to: ${options.focusArea}`;
|
|
78
|
+
}
|
|
79
|
+
// H3: Inject current infraContext into compaction prompt so it's never omitted
|
|
80
|
+
if (options.infraContext) {
|
|
81
|
+
const ic = options.infraContext;
|
|
82
|
+
const infraLines = [];
|
|
83
|
+
if (ic.terraformWorkspace)
|
|
84
|
+
infraLines.push(`- Terraform workspace: ${ic.terraformWorkspace}`);
|
|
85
|
+
if (ic.kubectlContext)
|
|
86
|
+
infraLines.push(`- kubectl context: ${ic.kubectlContext}`);
|
|
87
|
+
if (ic.awsProfile)
|
|
88
|
+
infraLines.push(`- AWS profile: ${ic.awsProfile}`);
|
|
89
|
+
if (ic.awsRegion)
|
|
90
|
+
infraLines.push(`- AWS region: ${ic.awsRegion}`);
|
|
91
|
+
if (ic.gcpProject)
|
|
92
|
+
infraLines.push(`- GCP project: ${ic.gcpProject}`);
|
|
93
|
+
if (ic.azureSubscription)
|
|
94
|
+
infraLines.push(`- Azure subscription: ${ic.azureSubscription}`);
|
|
95
|
+
if (infraLines.length > 0) {
|
|
96
|
+
userPrompt += `\n\n## ALWAYS PRESERVE IN SUMMARY (do not omit):\n${infraLines.join('\n')}`;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Call the LLM for summarization using a fast, cheap model
|
|
100
|
+
const model = options.model ?? 'haiku';
|
|
101
|
+
let summary;
|
|
102
|
+
try {
|
|
103
|
+
const response = await options.router.route({
|
|
104
|
+
messages: [
|
|
105
|
+
{ role: 'system', content: COMPACTION_SYSTEM_PROMPT },
|
|
106
|
+
{ role: 'user', content: userPrompt },
|
|
107
|
+
],
|
|
108
|
+
model,
|
|
109
|
+
maxTokens: 2048,
|
|
110
|
+
});
|
|
111
|
+
summary = response.content;
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// If LLM call fails, fall back to a simple extractive summary
|
|
115
|
+
summary = fallbackSummary(toSummarize);
|
|
116
|
+
}
|
|
117
|
+
// H3: Prepend infraContext block to summary so it survives compaction
|
|
118
|
+
let finalSummary = summary;
|
|
119
|
+
if (options.infraContext) {
|
|
120
|
+
const ic = options.infraContext;
|
|
121
|
+
const infraLines = [];
|
|
122
|
+
if (ic.terraformWorkspace)
|
|
123
|
+
infraLines.push(`- Terraform workspace: ${ic.terraformWorkspace}`);
|
|
124
|
+
if (ic.kubectlContext)
|
|
125
|
+
infraLines.push(`- kubectl context: ${ic.kubectlContext}`);
|
|
126
|
+
if (ic.awsProfile)
|
|
127
|
+
infraLines.push(`- AWS profile: ${ic.awsProfile}`);
|
|
128
|
+
if (ic.awsRegion)
|
|
129
|
+
infraLines.push(`- AWS region: ${ic.awsRegion}`);
|
|
130
|
+
if (ic.gcpProject)
|
|
131
|
+
infraLines.push(`- GCP project: ${ic.gcpProject}`);
|
|
132
|
+
if (ic.azureSubscription)
|
|
133
|
+
infraLines.push(`- Azure subscription: ${ic.azureSubscription}`);
|
|
134
|
+
if (infraLines.length > 0) {
|
|
135
|
+
finalSummary = `## Infrastructure Context\n${infraLines.join('\n')}\n\n${summary}`;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Reassemble the compacted message array
|
|
139
|
+
const compactedMessages = contextManager.buildCompactedMessages(preserved, finalSummary);
|
|
140
|
+
const compactedTokens = compactedMessages.reduce((sum, m) => sum + estimateTokens(getTextContent(m.content)), 0);
|
|
141
|
+
return {
|
|
142
|
+
messages: compactedMessages,
|
|
143
|
+
result: {
|
|
144
|
+
originalTokens,
|
|
145
|
+
compactedTokens,
|
|
146
|
+
savedTokens: originalTokens - estimateTokens(summary),
|
|
147
|
+
summaryPreserved: true,
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Run manual compaction from a `/compact` command.
|
|
153
|
+
*
|
|
154
|
+
* Creates a temporary context manager with default settings and
|
|
155
|
+
* delegates to {@link runCompaction}.
|
|
156
|
+
*
|
|
157
|
+
* @param messages - The full conversation message array.
|
|
158
|
+
* @param options - Compaction options plus an optional max token override.
|
|
159
|
+
* @returns The compacted messages and a result summary.
|
|
160
|
+
*/
|
|
161
|
+
export async function runManualCompaction(messages, options) {
|
|
162
|
+
const contextManager = new ContextManager({
|
|
163
|
+
maxContextTokens: options.maxContextTokens,
|
|
164
|
+
preserveRecentMessages: 5,
|
|
165
|
+
});
|
|
166
|
+
return runCompaction(messages, contextManager, options);
|
|
167
|
+
}
|
|
168
|
+
// ---------------------------------------------------------------------------
|
|
169
|
+
// Internal Helpers
|
|
170
|
+
// ---------------------------------------------------------------------------
|
|
171
|
+
/**
|
|
172
|
+
* Format messages into a readable conversation transcript.
|
|
173
|
+
*
|
|
174
|
+
* Each message is labelled with its role. Very long tool outputs are
|
|
175
|
+
* truncated to avoid overwhelming the summarizer model. Tool call
|
|
176
|
+
* metadata is included inline for context.
|
|
177
|
+
*/
|
|
178
|
+
function formatMessagesForSummary(messages) {
|
|
179
|
+
const parts = [];
|
|
180
|
+
for (const msg of messages) {
|
|
181
|
+
const role = msg.role === 'user' ? 'User' : msg.role === 'assistant' ? 'Assistant' : 'Tool';
|
|
182
|
+
const content = getTextContent(msg.content);
|
|
183
|
+
// Truncate very long tool outputs to keep summarizer input manageable
|
|
184
|
+
const truncated = content.length > 2000 ? `${content.slice(0, 2000)}... [truncated]` : content;
|
|
185
|
+
parts.push(`[${role}]: ${truncated}`);
|
|
186
|
+
// Include tool call info if present
|
|
187
|
+
if (msg.toolCalls) {
|
|
188
|
+
for (const tc of msg.toolCalls) {
|
|
189
|
+
parts.push(` [Tool Call: ${tc.function.name}(${tc.function.arguments.slice(0, 200)})]`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return parts.join('\n\n');
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Fallback summary when the LLM is unavailable.
|
|
197
|
+
*
|
|
198
|
+
* Produces a simple extractive summary by listing message counts
|
|
199
|
+
* and the first few user messages. This is better than nothing when
|
|
200
|
+
* the compaction model cannot be reached.
|
|
201
|
+
*/
|
|
202
|
+
function fallbackSummary(messages) {
|
|
203
|
+
const userMessages = messages.filter(m => m.role === 'user');
|
|
204
|
+
const assistantMessages = messages.filter(m => m.role === 'assistant');
|
|
205
|
+
const parts = ['**Conversation Summary (auto-generated)**\n'];
|
|
206
|
+
parts.push(`- ${userMessages.length} user messages and ${assistantMessages.length} assistant responses`);
|
|
207
|
+
// Extract key topics from user messages
|
|
208
|
+
for (const msg of userMessages.slice(0, 5)) {
|
|
209
|
+
const content = getTextContent(msg.content);
|
|
210
|
+
if (content.length > 0) {
|
|
211
|
+
parts.push(`- User asked: "${content.slice(0, 150)}${content.length > 150 ? '...' : ''}"`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return parts.join('\n');
|
|
215
|
+
}
|