@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,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Manager — Token Tracking & Auto-Compact
|
|
3
|
+
*
|
|
4
|
+
* Tracks cumulative token usage across the agent loop and triggers
|
|
5
|
+
* automatic context compaction when usage exceeds a configurable
|
|
6
|
+
* threshold (default 85% of the model's context window).
|
|
7
|
+
*
|
|
8
|
+
* The manager provides:
|
|
9
|
+
* - Token estimation for messages, system prompts, and tool definitions.
|
|
10
|
+
* - A breakdown of how the context budget is being consumed.
|
|
11
|
+
* - Message selection logic for deciding what to preserve vs. summarize.
|
|
12
|
+
* - A builder for reassembling messages after compaction.
|
|
13
|
+
*
|
|
14
|
+
* Configuration can be supplied via constructor options or read from the
|
|
15
|
+
* Nimbus config database (keys: `context.auto_compact_threshold`,
|
|
16
|
+
* `context.max_file_injection`).
|
|
17
|
+
*
|
|
18
|
+
* @module agent/context-manager
|
|
19
|
+
*/
|
|
20
|
+
import { getTextContent } from '../llm/types';
|
|
21
|
+
import { getConfig } from '../state/config';
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Per-Model Context Window Sizes
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
/**
|
|
26
|
+
* Known context window sizes (in tokens) for popular models.
|
|
27
|
+
*
|
|
28
|
+
* When a model is not listed here, the manager falls back to the
|
|
29
|
+
* `maxContextTokens` option (default: 200 000).
|
|
30
|
+
*/
|
|
31
|
+
const MODEL_CONTEXT_WINDOWS = {
|
|
32
|
+
// Anthropic
|
|
33
|
+
'claude-opus-4-20250514': 200_000,
|
|
34
|
+
'claude-sonnet-4-20250514': 200_000,
|
|
35
|
+
'claude-haiku-4-20250514': 200_000,
|
|
36
|
+
'claude-3-5-sonnet-20241022': 200_000,
|
|
37
|
+
'claude-3-5-haiku-20241022': 200_000,
|
|
38
|
+
'claude-3-opus-20240229': 200_000,
|
|
39
|
+
'claude-3-sonnet-20240229': 200_000,
|
|
40
|
+
'claude-3-haiku-20240307': 200_000,
|
|
41
|
+
// OpenAI
|
|
42
|
+
'gpt-4o': 128_000,
|
|
43
|
+
'gpt-4o-mini': 128_000,
|
|
44
|
+
'gpt-4-turbo': 128_000,
|
|
45
|
+
'gpt-4': 8_192,
|
|
46
|
+
'gpt-3.5-turbo': 16_385,
|
|
47
|
+
o1: 200_000,
|
|
48
|
+
'o1-mini': 128_000,
|
|
49
|
+
'o1-preview': 128_000,
|
|
50
|
+
'o3-mini': 200_000,
|
|
51
|
+
// Google
|
|
52
|
+
'gemini-2.0-flash-exp': 1_048_576,
|
|
53
|
+
'gemini-1.5-pro': 2_097_152,
|
|
54
|
+
'gemini-1.5-flash': 1_048_576,
|
|
55
|
+
// Groq (Llama)
|
|
56
|
+
'llama-3.1-70b-versatile': 131_072,
|
|
57
|
+
'llama-3.1-8b-instant': 131_072,
|
|
58
|
+
'llama-3.3-70b-versatile': 131_072,
|
|
59
|
+
// DeepSeek
|
|
60
|
+
'deepseek-chat': 64_000,
|
|
61
|
+
'deepseek-coder': 64_000,
|
|
62
|
+
'deepseek-reasoner': 64_000,
|
|
63
|
+
// Local (Ollama defaults — dynamic lookup can override)
|
|
64
|
+
'llama3.2': 128_000,
|
|
65
|
+
mistral: 32_768,
|
|
66
|
+
codellama: 16_384,
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Look up the context window size for a model identifier.
|
|
70
|
+
*
|
|
71
|
+
* Tries exact match first, then prefix match (for versioned model IDs
|
|
72
|
+
* like `claude-sonnet-4-20250514`), then returns `null` if unknown.
|
|
73
|
+
*/
|
|
74
|
+
export function getModelContextWindow(model) {
|
|
75
|
+
// Exact match
|
|
76
|
+
if (MODEL_CONTEXT_WINDOWS[model] !== undefined) {
|
|
77
|
+
return MODEL_CONTEXT_WINDOWS[model];
|
|
78
|
+
}
|
|
79
|
+
// Prefix match: e.g., "gpt-4o-2024-08-06" should match "gpt-4o"
|
|
80
|
+
for (const [key, value] of Object.entries(MODEL_CONTEXT_WINDOWS)) {
|
|
81
|
+
if (model.startsWith(key)) {
|
|
82
|
+
return value;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// Token Estimation Utilities
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
/**
|
|
91
|
+
* Rough token estimate based on character count.
|
|
92
|
+
*
|
|
93
|
+
* Uses the common heuristic of ~4 characters per token, which is a
|
|
94
|
+
* reasonable average across English text and source code.
|
|
95
|
+
*
|
|
96
|
+
* @param text - The text to estimate.
|
|
97
|
+
* @returns Approximate token count (rounded up).
|
|
98
|
+
*/
|
|
99
|
+
export function estimateTokens(text) {
|
|
100
|
+
return Math.ceil(text.length / 4);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Estimate token count for a single LLM message.
|
|
104
|
+
*
|
|
105
|
+
* Accounts for the message content, structural overhead (role, framing),
|
|
106
|
+
* and any tool calls embedded in the message.
|
|
107
|
+
*
|
|
108
|
+
* @param message - The LLM message to estimate.
|
|
109
|
+
* @returns Approximate token count.
|
|
110
|
+
*/
|
|
111
|
+
export function estimateMessageTokens(message) {
|
|
112
|
+
let tokens = 0;
|
|
113
|
+
tokens += estimateTokens(getTextContent(message.content));
|
|
114
|
+
// Add overhead for role and message structure
|
|
115
|
+
tokens += 4;
|
|
116
|
+
// Tool calls add extra tokens for name, arguments, and JSON structure
|
|
117
|
+
if (message.toolCalls) {
|
|
118
|
+
for (const tc of message.toolCalls) {
|
|
119
|
+
tokens += estimateTokens(tc.function.name);
|
|
120
|
+
tokens += estimateTokens(tc.function.arguments);
|
|
121
|
+
tokens += 10; // structural overhead per tool call
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return tokens;
|
|
125
|
+
}
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
// H2: Terraform plan output detection
|
|
128
|
+
// ---------------------------------------------------------------------------
|
|
129
|
+
/**
|
|
130
|
+
* Patterns that indicate a message contains a terraform plan output.
|
|
131
|
+
* These messages are critical context that should survive compaction.
|
|
132
|
+
*/
|
|
133
|
+
const TERRAFORM_PLAN_INDICATORS = [
|
|
134
|
+
'Plan:',
|
|
135
|
+
'will be created',
|
|
136
|
+
'will be destroyed',
|
|
137
|
+
'to add,',
|
|
138
|
+
'to change,',
|
|
139
|
+
'to destroy',
|
|
140
|
+
];
|
|
141
|
+
/**
|
|
142
|
+
* Return true if the given text content contains terraform plan output.
|
|
143
|
+
* Used by selectPreservedMessages to protect plan results from compaction.
|
|
144
|
+
*
|
|
145
|
+
* @param text - The text content to inspect.
|
|
146
|
+
* @returns `true` if the text looks like terraform plan output.
|
|
147
|
+
*/
|
|
148
|
+
function containsTerraformPlanOutput(text) {
|
|
149
|
+
return TERRAFORM_PLAN_INDICATORS.some(indicator => text.includes(indicator));
|
|
150
|
+
}
|
|
151
|
+
// ---------------------------------------------------------------------------
|
|
152
|
+
// ContextManager Class
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
/**
|
|
155
|
+
* Manages context window budget and auto-compaction decisions.
|
|
156
|
+
*
|
|
157
|
+
* Create one instance per agent session. The manager does not hold
|
|
158
|
+
* conversation state itself -- it operates on message arrays passed in
|
|
159
|
+
* by the caller.
|
|
160
|
+
*/
|
|
161
|
+
export class ContextManager {
|
|
162
|
+
maxContextTokens;
|
|
163
|
+
autoCompactThreshold;
|
|
164
|
+
preserveRecentMessages;
|
|
165
|
+
alwaysInContext;
|
|
166
|
+
/** Per-message token count cache: key = `role:contentLen:toolCallCount:toolCallId`. */
|
|
167
|
+
_tokenCache = new Map();
|
|
168
|
+
constructor(options) {
|
|
169
|
+
// Try loading from config DB, fall back to options/defaults
|
|
170
|
+
const configThreshold = getConfigSafe('context.auto_compact_threshold');
|
|
171
|
+
// Auto-detect context window from model if provided, then options, then default
|
|
172
|
+
const modelWindow = options?.model ? getModelContextWindow(options.model) : null;
|
|
173
|
+
this.maxContextTokens = options?.maxContextTokens ?? modelWindow ?? 200_000;
|
|
174
|
+
this.autoCompactThreshold = configThreshold ?? options?.autoCompactThreshold ?? 0.85;
|
|
175
|
+
this.preserveRecentMessages = options?.preserveRecentMessages ?? 5;
|
|
176
|
+
this.alwaysInContext = options?.alwaysInContext ?? ['Infrastructure Context', 'Tool Timeouts'];
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Get cached token count for a message, computing + caching on miss.
|
|
180
|
+
* Key encodes role + content length + tool call count + tool call IDs so
|
|
181
|
+
* any meaningful change busts the cache entry.
|
|
182
|
+
*/
|
|
183
|
+
_getCachedTokens(msg) {
|
|
184
|
+
const contentLen = typeof msg.content === 'string'
|
|
185
|
+
? msg.content.length
|
|
186
|
+
: JSON.stringify(msg.content).length;
|
|
187
|
+
const tcCount = msg.toolCalls?.length ?? 0;
|
|
188
|
+
const tcIds = msg.toolCalls?.map(tc => tc.id).join(',') ?? '';
|
|
189
|
+
const key = `${msg.role}:${contentLen}:${tcCount}:${tcIds}`;
|
|
190
|
+
const cached = this._tokenCache.get(key);
|
|
191
|
+
if (cached !== undefined)
|
|
192
|
+
return cached;
|
|
193
|
+
const val = estimateMessageTokens(msg);
|
|
194
|
+
this._tokenCache.set(key, val);
|
|
195
|
+
return val;
|
|
196
|
+
}
|
|
197
|
+
/** Clear the token cache. Call after compaction when old messages are removed. */
|
|
198
|
+
clearTokenCache() {
|
|
199
|
+
this._tokenCache.clear();
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Check whether auto-compaction should be triggered.
|
|
203
|
+
*
|
|
204
|
+
* Returns `true` if the estimated token usage is at or above the
|
|
205
|
+
* configured threshold percentage of the context window.
|
|
206
|
+
*
|
|
207
|
+
* @param systemPrompt - The full system prompt string.
|
|
208
|
+
* @param messages - Current conversation messages.
|
|
209
|
+
* @param toolDefinitionsTokens - Pre-computed token count for tool schemas.
|
|
210
|
+
* @returns `true` if compaction should run.
|
|
211
|
+
*/
|
|
212
|
+
shouldCompact(systemPrompt, messages, toolDefinitionsTokens) {
|
|
213
|
+
const usage = this.calculateUsage(systemPrompt, messages, toolDefinitionsTokens);
|
|
214
|
+
return usage.usagePercent >= this.autoCompactThreshold * 100;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Calculate a detailed context usage breakdown.
|
|
218
|
+
*
|
|
219
|
+
* Separates the system prompt into base instructions and NIMBUS.md
|
|
220
|
+
* content (if present), and sums up messages and tool definitions
|
|
221
|
+
* to produce a full picture of context window consumption.
|
|
222
|
+
*
|
|
223
|
+
* @param systemPrompt - The full system prompt string.
|
|
224
|
+
* @param messages - Current conversation messages.
|
|
225
|
+
* @param toolDefinitionsTokens - Pre-computed token count for tool schemas.
|
|
226
|
+
* @returns A {@link ContextBreakdown} with per-category token counts.
|
|
227
|
+
*/
|
|
228
|
+
calculateUsage(systemPrompt, messages, toolDefinitionsTokens) {
|
|
229
|
+
const systemPromptTokens = estimateTokens(systemPrompt);
|
|
230
|
+
// Separate NIMBUS.md instructions if they appear in system prompt
|
|
231
|
+
const nimbusMarker = '# NIMBUS.md';
|
|
232
|
+
const nimbusIdx = systemPrompt.indexOf(nimbusMarker);
|
|
233
|
+
let nimbusInstructionsTokens = 0;
|
|
234
|
+
let baseSystemTokens = systemPromptTokens;
|
|
235
|
+
if (nimbusIdx >= 0) {
|
|
236
|
+
const nimbusContent = systemPrompt.slice(nimbusIdx);
|
|
237
|
+
nimbusInstructionsTokens = estimateTokens(nimbusContent);
|
|
238
|
+
baseSystemTokens = systemPromptTokens - nimbusInstructionsTokens;
|
|
239
|
+
}
|
|
240
|
+
const messagesTokens = messages.reduce((sum, msg) => sum + this._getCachedTokens(msg), 0);
|
|
241
|
+
const total = systemPromptTokens + messagesTokens + toolDefinitionsTokens;
|
|
242
|
+
const usagePercent = this.maxContextTokens > 0 ? Math.round((total / this.maxContextTokens) * 100) : 0;
|
|
243
|
+
return {
|
|
244
|
+
systemPrompt: baseSystemTokens,
|
|
245
|
+
nimbusInstructions: nimbusInstructionsTokens,
|
|
246
|
+
messages: messagesTokens,
|
|
247
|
+
toolDefinitions: toolDefinitionsTokens,
|
|
248
|
+
total,
|
|
249
|
+
budget: this.maxContextTokens,
|
|
250
|
+
usagePercent,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Select which messages to preserve during compaction.
|
|
255
|
+
*
|
|
256
|
+
* Preservation rules:
|
|
257
|
+
* - The first message is always kept (initial user context).
|
|
258
|
+
* - The last N messages are always kept (recent conversation).
|
|
259
|
+
* - Tool messages near the recent window are kept (active tool state).
|
|
260
|
+
* - Previous compaction summary blocks are always kept.
|
|
261
|
+
* - H2: Tool result messages containing terraform plan output are always
|
|
262
|
+
* kept so the agent retains critical plan context across compaction.
|
|
263
|
+
* - Everything else is marked for summarization.
|
|
264
|
+
*
|
|
265
|
+
* @param messages - The full conversation message array.
|
|
266
|
+
* @returns An object with `preserved` and `toSummarize` arrays.
|
|
267
|
+
*/
|
|
268
|
+
selectPreservedMessages(messages) {
|
|
269
|
+
if (messages.length <= this.preserveRecentMessages + 1) {
|
|
270
|
+
return { preserved: [...messages], toSummarize: [] };
|
|
271
|
+
}
|
|
272
|
+
const preserved = [];
|
|
273
|
+
const toSummarize = [];
|
|
274
|
+
for (let i = 0; i < messages.length; i++) {
|
|
275
|
+
const msg = messages[i];
|
|
276
|
+
const isFirst = i === 0;
|
|
277
|
+
const isRecent = i >= messages.length - this.preserveRecentMessages;
|
|
278
|
+
const hasActiveTools = msg.role === 'tool' && i >= messages.length - this.preserveRecentMessages - 2;
|
|
279
|
+
// Always preserve summary blocks (from previous compactions)
|
|
280
|
+
const isSummary = getTextContent(msg.content).startsWith('[Context Summary]');
|
|
281
|
+
// H2: Always preserve messages containing terraform plan output.
|
|
282
|
+
// These are typically `tool` role messages or `assistant` messages with
|
|
283
|
+
// tool_use content blocks whose text contains plan output markers.
|
|
284
|
+
const textContent = getTextContent(msg.content);
|
|
285
|
+
const isTerraformPlan = (msg.role === 'tool' || msg.role === 'assistant') &&
|
|
286
|
+
containsTerraformPlanOutput(textContent);
|
|
287
|
+
if (isFirst || isRecent || hasActiveTools || isSummary || isTerraformPlan) {
|
|
288
|
+
preserved.push(msg);
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
toSummarize.push(msg);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return { preserved, toSummarize };
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Build the compacted message array by inserting a summary.
|
|
298
|
+
*
|
|
299
|
+
* Places the summary as a user message immediately after the first
|
|
300
|
+
* preserved message, then appends all remaining preserved messages.
|
|
301
|
+
* The summary is wrapped with `[Context Summary]` markers so future
|
|
302
|
+
* compaction passes can identify and preserve it.
|
|
303
|
+
*
|
|
304
|
+
* @param preserved - Messages to keep verbatim.
|
|
305
|
+
* @param summary - The LLM-generated (or fallback) summary text.
|
|
306
|
+
* @returns A new message array ready to replace the original.
|
|
307
|
+
*/
|
|
308
|
+
buildCompactedMessages(preserved, summary) {
|
|
309
|
+
const result = [];
|
|
310
|
+
// Keep the first preserved message (typically the first user message)
|
|
311
|
+
if (preserved.length > 0) {
|
|
312
|
+
result.push(preserved[0]);
|
|
313
|
+
}
|
|
314
|
+
// Insert the summary as a user message with a clear marker
|
|
315
|
+
result.push({
|
|
316
|
+
role: 'user',
|
|
317
|
+
content: `[Context Summary] The following is a summary of the earlier conversation:\n\n${summary}\n\n---\nThe conversation continues below.`,
|
|
318
|
+
});
|
|
319
|
+
// Append remaining preserved messages
|
|
320
|
+
for (let i = 1; i < preserved.length; i++) {
|
|
321
|
+
result.push(preserved[i]);
|
|
322
|
+
}
|
|
323
|
+
return result;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Get the current configuration values.
|
|
327
|
+
*
|
|
328
|
+
* Useful for displaying context status in the TUI.
|
|
329
|
+
*/
|
|
330
|
+
getConfig() {
|
|
331
|
+
return {
|
|
332
|
+
maxContextTokens: this.maxContextTokens,
|
|
333
|
+
autoCompactThreshold: this.autoCompactThreshold,
|
|
334
|
+
preserveRecentMessages: this.preserveRecentMessages,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Update the max context tokens.
|
|
339
|
+
*
|
|
340
|
+
* Call this when the model changes mid-session so the compaction
|
|
341
|
+
* threshold adjusts to the new model's context window.
|
|
342
|
+
*
|
|
343
|
+
* @param tokens - The new maximum context window size.
|
|
344
|
+
*/
|
|
345
|
+
setMaxContextTokens(tokens) {
|
|
346
|
+
this.maxContextTokens = tokens;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Update the context window based on a model identifier.
|
|
350
|
+
*
|
|
351
|
+
* Looks up the model's known context window size. If the model is
|
|
352
|
+
* not in the built-in map, the current budget is left unchanged.
|
|
353
|
+
*
|
|
354
|
+
* @param model - The model identifier (e.g., "gpt-4o", "claude-sonnet-4-20250514").
|
|
355
|
+
* @returns `true` if the budget was updated, `false` if model is unknown.
|
|
356
|
+
*/
|
|
357
|
+
setModel(model) {
|
|
358
|
+
// Strip provider prefix (e.g., "openai/gpt-4o" → "gpt-4o")
|
|
359
|
+
const stripped = model.includes('/') ? model.split('/').slice(1).join('/') : model;
|
|
360
|
+
const window = getModelContextWindow(stripped);
|
|
361
|
+
if (window !== null) {
|
|
362
|
+
this.maxContextTokens = window;
|
|
363
|
+
return true;
|
|
364
|
+
}
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
// ---------------------------------------------------------------------------
|
|
369
|
+
// Internal Helpers
|
|
370
|
+
// ---------------------------------------------------------------------------
|
|
371
|
+
/**
|
|
372
|
+
* Safely read a config value without crashing if the DB is not ready.
|
|
373
|
+
*
|
|
374
|
+
* During early initialization the SQLite database may not yet be open.
|
|
375
|
+
* This wrapper catches any error and returns `null` so the constructor
|
|
376
|
+
* can fall back to provided options or built-in defaults.
|
|
377
|
+
*/
|
|
378
|
+
function getConfigSafe(key) {
|
|
379
|
+
try {
|
|
380
|
+
return getConfig(key);
|
|
381
|
+
}
|
|
382
|
+
catch {
|
|
383
|
+
return null;
|
|
384
|
+
}
|
|
385
|
+
}
|