@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
|
@@ -190,6 +190,34 @@ export function estimateMessageTokens(message: LLMMessage): number {
|
|
|
190
190
|
return tokens;
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
+
// ---------------------------------------------------------------------------
|
|
194
|
+
// H2: Terraform plan output detection
|
|
195
|
+
// ---------------------------------------------------------------------------
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Patterns that indicate a message contains a terraform plan output.
|
|
199
|
+
* These messages are critical context that should survive compaction.
|
|
200
|
+
*/
|
|
201
|
+
const TERRAFORM_PLAN_INDICATORS = [
|
|
202
|
+
'Plan:',
|
|
203
|
+
'will be created',
|
|
204
|
+
'will be destroyed',
|
|
205
|
+
'to add,',
|
|
206
|
+
'to change,',
|
|
207
|
+
'to destroy',
|
|
208
|
+
] as const;
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Return true if the given text content contains terraform plan output.
|
|
212
|
+
* Used by selectPreservedMessages to protect plan results from compaction.
|
|
213
|
+
*
|
|
214
|
+
* @param text - The text content to inspect.
|
|
215
|
+
* @returns `true` if the text looks like terraform plan output.
|
|
216
|
+
*/
|
|
217
|
+
function containsTerraformPlanOutput(text: string): boolean {
|
|
218
|
+
return TERRAFORM_PLAN_INDICATORS.some(indicator => text.includes(indicator));
|
|
219
|
+
}
|
|
220
|
+
|
|
193
221
|
// ---------------------------------------------------------------------------
|
|
194
222
|
// ContextManager Class
|
|
195
223
|
// ---------------------------------------------------------------------------
|
|
@@ -206,6 +234,8 @@ export class ContextManager {
|
|
|
206
234
|
private autoCompactThreshold: number;
|
|
207
235
|
private preserveRecentMessages: number;
|
|
208
236
|
private alwaysInContext: string[];
|
|
237
|
+
/** Per-message token count cache: key = `role:contentLen:toolCallCount:toolCallId`. */
|
|
238
|
+
private _tokenCache: Map<string, number> = new Map();
|
|
209
239
|
|
|
210
240
|
constructor(options?: ContextManagerOptions) {
|
|
211
241
|
// Try loading from config DB, fall back to options/defaults
|
|
@@ -216,7 +246,31 @@ export class ContextManager {
|
|
|
216
246
|
this.maxContextTokens = options?.maxContextTokens ?? modelWindow ?? 200_000;
|
|
217
247
|
this.autoCompactThreshold = configThreshold ?? options?.autoCompactThreshold ?? 0.85;
|
|
218
248
|
this.preserveRecentMessages = options?.preserveRecentMessages ?? 5;
|
|
219
|
-
this.alwaysInContext = options?.alwaysInContext ?? [];
|
|
249
|
+
this.alwaysInContext = options?.alwaysInContext ?? ['Infrastructure Context', 'Tool Timeouts'];
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Get cached token count for a message, computing + caching on miss.
|
|
254
|
+
* Key encodes role + content length + tool call count + tool call IDs so
|
|
255
|
+
* any meaningful change busts the cache entry.
|
|
256
|
+
*/
|
|
257
|
+
private _getCachedTokens(msg: LLMMessage): number {
|
|
258
|
+
const contentLen = typeof msg.content === 'string'
|
|
259
|
+
? msg.content.length
|
|
260
|
+
: JSON.stringify(msg.content).length;
|
|
261
|
+
const tcCount = msg.toolCalls?.length ?? 0;
|
|
262
|
+
const tcIds = msg.toolCalls?.map(tc => tc.id).join(',') ?? '';
|
|
263
|
+
const key = `${msg.role}:${contentLen}:${tcCount}:${tcIds}`;
|
|
264
|
+
const cached = this._tokenCache.get(key);
|
|
265
|
+
if (cached !== undefined) return cached;
|
|
266
|
+
const val = estimateMessageTokens(msg);
|
|
267
|
+
this._tokenCache.set(key, val);
|
|
268
|
+
return val;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/** Clear the token cache. Call after compaction when old messages are removed. */
|
|
272
|
+
clearTokenCache(): void {
|
|
273
|
+
this._tokenCache.clear();
|
|
220
274
|
}
|
|
221
275
|
|
|
222
276
|
/**
|
|
@@ -270,7 +324,7 @@ export class ContextManager {
|
|
|
270
324
|
baseSystemTokens = systemPromptTokens - nimbusInstructionsTokens;
|
|
271
325
|
}
|
|
272
326
|
|
|
273
|
-
const messagesTokens = messages.reduce((sum, msg) => sum +
|
|
327
|
+
const messagesTokens = messages.reduce((sum, msg) => sum + this._getCachedTokens(msg), 0);
|
|
274
328
|
|
|
275
329
|
const total = systemPromptTokens + messagesTokens + toolDefinitionsTokens;
|
|
276
330
|
const usagePercent =
|
|
@@ -295,6 +349,8 @@ export class ContextManager {
|
|
|
295
349
|
* - The last N messages are always kept (recent conversation).
|
|
296
350
|
* - Tool messages near the recent window are kept (active tool state).
|
|
297
351
|
* - Previous compaction summary blocks are always kept.
|
|
352
|
+
* - H2: Tool result messages containing terraform plan output are always
|
|
353
|
+
* kept so the agent retains critical plan context across compaction.
|
|
298
354
|
* - Everything else is marked for summarization.
|
|
299
355
|
*
|
|
300
356
|
* @param messages - The full conversation message array.
|
|
@@ -321,7 +377,15 @@ export class ContextManager {
|
|
|
321
377
|
// Always preserve summary blocks (from previous compactions)
|
|
322
378
|
const isSummary = getTextContent(msg.content).startsWith('[Context Summary]');
|
|
323
379
|
|
|
324
|
-
|
|
380
|
+
// H2: Always preserve messages containing terraform plan output.
|
|
381
|
+
// These are typically `tool` role messages or `assistant` messages with
|
|
382
|
+
// tool_use content blocks whose text contains plan output markers.
|
|
383
|
+
const textContent = getTextContent(msg.content);
|
|
384
|
+
const isTerraformPlan =
|
|
385
|
+
(msg.role === 'tool' || msg.role === 'assistant') &&
|
|
386
|
+
containsTerraformPlanOutput(textContent);
|
|
387
|
+
|
|
388
|
+
if (isFirst || isRecent || hasActiveTools || isSummary || isTerraformPlan) {
|
|
325
389
|
preserved.push(msg);
|
|
326
390
|
} else {
|
|
327
391
|
toSummarize.push(msg);
|
|
@@ -180,11 +180,28 @@ async function generateTerraformPreview(workdir: string): Promise<DeployPreview>
|
|
|
180
180
|
const changes = parseTerraformPlanOutput(output);
|
|
181
181
|
const summary = summarizeChanges(changes);
|
|
182
182
|
|
|
183
|
+
// Try infracost for real cost delta (best-effort, non-blocking)
|
|
184
|
+
let costImpact: string | undefined;
|
|
185
|
+
try {
|
|
186
|
+
const { stdout: icOut } = await execAsync(
|
|
187
|
+
`infracost breakdown --path ${workdir} --format json`,
|
|
188
|
+
{ timeout: 60_000, maxBuffer: 5 * 1024 * 1024 }
|
|
189
|
+
);
|
|
190
|
+
const ic = JSON.parse(icOut);
|
|
191
|
+
const totalMonthly = parseFloat(ic.totalMonthlyCost ?? '0').toFixed(2);
|
|
192
|
+
const diff = parseFloat(ic.diffTotalMonthlyCost ?? '0');
|
|
193
|
+
const sign = diff > 0 ? '+' : '';
|
|
194
|
+
costImpact = `$${totalMonthly}/month${diff !== 0 ? ` (${sign}$${diff.toFixed(2)} change)` : ' (no change)'}`;
|
|
195
|
+
} catch {
|
|
196
|
+
// infracost not installed or failed — omit cost impact
|
|
197
|
+
}
|
|
198
|
+
|
|
183
199
|
return {
|
|
184
200
|
...base,
|
|
185
201
|
changes,
|
|
186
202
|
summary,
|
|
187
203
|
rawOutput: output,
|
|
204
|
+
costImpact,
|
|
188
205
|
success: true,
|
|
189
206
|
};
|
|
190
207
|
} catch (error: unknown) {
|
|
@@ -280,6 +297,50 @@ async function generateHelmPreview(action: string, workdir: string): Promise<Dep
|
|
|
280
297
|
}
|
|
281
298
|
}
|
|
282
299
|
|
|
300
|
+
// ---------------------------------------------------------------
|
|
301
|
+
// G9: Multi-file diff batch builder for Terraform plan output
|
|
302
|
+
// ---------------------------------------------------------------
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* G9: Build a FileDiffBatch from a Terraform plan preview.
|
|
306
|
+
*
|
|
307
|
+
* Parses the resource changes in the plan and represents each modified
|
|
308
|
+
* resource as a synthetic diff entry so they can be reviewed via the
|
|
309
|
+
* existing FileDiffModal batch flow.
|
|
310
|
+
*
|
|
311
|
+
* @param preview - DeployPreview from generateTerraformPreview
|
|
312
|
+
* @returns Array of file-diff entries suitable for FileDiffBatch.files
|
|
313
|
+
*/
|
|
314
|
+
export function buildFileDiffBatchFromPlan(
|
|
315
|
+
preview: DeployPreview
|
|
316
|
+
): Array<{ filePath: string; diff: string; toolName: string }> {
|
|
317
|
+
return preview.changes.map(change => {
|
|
318
|
+
const actionLine = getChangeSymbolStr(change.action);
|
|
319
|
+
const diff = [
|
|
320
|
+
`--- a/${change.resource}`,
|
|
321
|
+
`+++ b/${change.resource}`,
|
|
322
|
+
`@@ -0,0 +1,1 @@`,
|
|
323
|
+
`${actionLine} ${change.resource}${change.details ? ` # ${change.details}` : ''}`,
|
|
324
|
+
].join('\n');
|
|
325
|
+
|
|
326
|
+
return {
|
|
327
|
+
filePath: change.resource,
|
|
328
|
+
diff,
|
|
329
|
+
toolName: 'terraform',
|
|
330
|
+
};
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function getChangeSymbolStr(action: ResourceChange['action']): string {
|
|
335
|
+
switch (action) {
|
|
336
|
+
case 'create': return '+';
|
|
337
|
+
case 'update': return '~';
|
|
338
|
+
case 'destroy': return '-';
|
|
339
|
+
case 'replace': return '+/-';
|
|
340
|
+
default: return ' ';
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
283
344
|
// ---------------------------------------------------------------
|
|
284
345
|
// Output parsers
|
|
285
346
|
// ---------------------------------------------------------------
|
|
@@ -297,7 +358,7 @@ async function generateHelmPreview(action: string, workdir: string): Promise<Dep
|
|
|
297
358
|
* Falls back to the summary line (`Plan: X to add, Y to change, Z to destroy.`)
|
|
298
359
|
* when no individual resource lines are found.
|
|
299
360
|
*/
|
|
300
|
-
function parseTerraformPlanOutput(output: string): ResourceChange[] {
|
|
361
|
+
export function parseTerraformPlanOutput(output: string): ResourceChange[] {
|
|
301
362
|
const changes: ResourceChange[] = [];
|
|
302
363
|
const lines = output.split('\n');
|
|
303
364
|
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared @file reference expansion utility.
|
|
3
|
+
*
|
|
4
|
+
* Replaces @path/to/file references in a prompt with the file contents
|
|
5
|
+
* wrapped in <file> tags. Files larger than 10KB are truncated.
|
|
6
|
+
*
|
|
7
|
+
* Security: blocks path traversal (../../etc/passwd) and sensitive file patterns.
|
|
8
|
+
*
|
|
9
|
+
* Special tokens (G22):
|
|
10
|
+
* @workspace — concatenates all .tf files in cwd (up to 50KB)
|
|
11
|
+
* @cluster — instructs the agent to use the kubectl tool (async call not possible here)
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import * as fs from 'node:fs';
|
|
15
|
+
import * as path from 'node:path';
|
|
16
|
+
|
|
17
|
+
/** Sensitive file patterns that should never be expanded. */
|
|
18
|
+
const SENSITIVE_FILE_RE = /(\.env|\.pem|\.key|\.p12|\.pfx|id_rsa|id_ed25519|credentials|\.netrc)$/i;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Expand @file references in a prompt string.
|
|
22
|
+
* Replaces @path/to/file with the file contents wrapped in <file> tags.
|
|
23
|
+
* Files larger than 10KB are truncated.
|
|
24
|
+
*
|
|
25
|
+
* Security: blocks path traversal outside the project root and sensitive
|
|
26
|
+
* file patterns (.env, .pem, .key, credentials, etc.).
|
|
27
|
+
*/
|
|
28
|
+
export function expandFileReferences(text: string, cwd: string = process.cwd()): string {
|
|
29
|
+
const fileRefs = text.match(/@([\w./_-]+)/g);
|
|
30
|
+
if (!fileRefs) return text;
|
|
31
|
+
|
|
32
|
+
let expanded = text;
|
|
33
|
+
|
|
34
|
+
// G22: Handle @workspace special token — concatenate all .tf files
|
|
35
|
+
if (expanded.includes('@workspace')) {
|
|
36
|
+
try {
|
|
37
|
+
const tfFiles = fs.readdirSync(cwd).filter(f => f.endsWith('.tf'));
|
|
38
|
+
if (tfFiles.length > 0) {
|
|
39
|
+
const parts: string[] = [];
|
|
40
|
+
let totalSize = 0;
|
|
41
|
+
const MAX_SIZE = 50_000;
|
|
42
|
+
for (const file of tfFiles) {
|
|
43
|
+
if (totalSize >= MAX_SIZE) { parts.push('... [truncated — 50KB limit reached]'); break; }
|
|
44
|
+
try {
|
|
45
|
+
const content = fs.readFileSync(path.join(cwd, file), 'utf-8');
|
|
46
|
+
parts.push(`\n<file path="${file}">\n${content.slice(0, Math.min(content.length, MAX_SIZE - totalSize))}\n</file>`);
|
|
47
|
+
totalSize += content.length;
|
|
48
|
+
} catch { /* skip unreadable files */ }
|
|
49
|
+
}
|
|
50
|
+
expanded = expanded.replace('@workspace', parts.join('\n'));
|
|
51
|
+
} else {
|
|
52
|
+
expanded = expanded.replace('@workspace', '[No .tf files found in current directory]');
|
|
53
|
+
}
|
|
54
|
+
} catch {
|
|
55
|
+
expanded = expanded.replace('@workspace', '[Error reading workspace files]');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// G22: Handle @cluster special token — kubectl get all
|
|
60
|
+
// @cluster requires an async kubectl call — guide agent to use the kubectl tool instead
|
|
61
|
+
if (expanded.includes('@cluster')) {
|
|
62
|
+
expanded = expanded.replace(
|
|
63
|
+
'@cluster',
|
|
64
|
+
'[Use the kubectl tool with action=get and args="all -A" to retrieve cluster resources]'
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
for (const ref of fileRefs) {
|
|
69
|
+
// Skip special tokens already handled above
|
|
70
|
+
if (ref === '@workspace' || ref === '@cluster') {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const filePath = ref.slice(1);
|
|
75
|
+
try {
|
|
76
|
+
const resolved = path.resolve(cwd, filePath);
|
|
77
|
+
|
|
78
|
+
// Security: block path traversal outside project root
|
|
79
|
+
const rel = path.relative(cwd, resolved);
|
|
80
|
+
if (rel.startsWith('..') || path.isAbsolute(rel)) {
|
|
81
|
+
expanded = expanded.replace(
|
|
82
|
+
ref,
|
|
83
|
+
`[File blocked: path "${filePath}" is outside the project directory]`
|
|
84
|
+
);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Security: block sensitive file patterns
|
|
89
|
+
if (SENSITIVE_FILE_RE.test(resolved)) {
|
|
90
|
+
expanded = expanded.replace(
|
|
91
|
+
ref,
|
|
92
|
+
`[File blocked: "${filePath}" matches sensitive file pattern]`
|
|
93
|
+
);
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const content = fs.readFileSync(resolved, 'utf-8');
|
|
98
|
+
const truncated =
|
|
99
|
+
content.length > 10_000
|
|
100
|
+
? `${content.slice(0, 10_000)}\n... (truncated — showing 10,000 of ${content.length.toLocaleString()} chars)`
|
|
101
|
+
: content;
|
|
102
|
+
expanded = expanded.replace(ref, `\n<file path="${filePath}">\n${truncated}\n</file>`);
|
|
103
|
+
} catch {
|
|
104
|
+
// File not found — leave the @reference as-is
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return expanded;
|
|
108
|
+
}
|