@build-astron-co/nimbus 0.4.1 → 0.4.3
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/CHANGELOG.md +268 -89
- package/README.md +26 -567
- package/dist/src/agent/compaction-agent.js +24 -12
- package/dist/src/agent/context-manager.js +2 -1
- package/dist/src/agent/expand-files.js +2 -1
- package/dist/src/agent/loop.js +71 -33
- package/dist/src/agent/permissions.js +4 -2
- package/dist/src/agent/system-prompt.js +34 -17
- package/dist/src/app.js +1 -1
- package/dist/src/auth/keychain.js +8 -4
- package/dist/src/auth/store.js +70 -107
- package/dist/src/cli/init.js +35 -19
- package/dist/src/cli/run.js +18 -10
- package/dist/src/cli/serve.js +4 -2
- package/dist/src/cli.js +52 -11
- package/dist/src/commands/alias.js +5 -3
- package/dist/src/commands/audit/index.js +2 -1
- package/dist/src/commands/aws-terraform.js +36 -18
- package/dist/src/commands/completions.js +1 -1
- package/dist/src/commands/config.js +3 -2
- package/dist/src/commands/connect-github.js +92 -0
- package/dist/src/commands/cost/index.js +3 -2
- package/dist/src/commands/deploy.js +15 -10
- package/dist/src/commands/doctor.js +9 -6
- package/dist/src/commands/drift/index.js +2 -1
- package/dist/src/commands/export.js +5 -3
- package/dist/src/commands/generate-terraform.js +110 -2
- package/dist/src/commands/import.js +3 -3
- package/dist/src/commands/incident.js +10 -5
- package/dist/src/commands/login.js +8 -93
- package/dist/src/commands/logs.js +16 -8
- package/dist/src/commands/onboarding.js +6 -4
- package/dist/src/commands/pipeline.js +6 -3
- package/dist/src/commands/plugin.js +3 -2
- package/dist/src/commands/profile.js +27 -14
- package/dist/src/commands/questionnaire.js +1 -1
- package/dist/src/commands/rollback.js +3 -2
- package/dist/src/commands/rollout.js +5 -3
- package/dist/src/commands/runbook.js +17 -10
- package/dist/src/commands/schedule.js +10 -5
- package/dist/src/commands/status.js +2 -1
- package/dist/src/commands/team-context.js +12 -7
- package/dist/src/commands/template.js +1 -1
- package/dist/src/commands/tf/index.js +6 -3
- package/dist/src/commands/upgrade.js +5 -3
- package/dist/src/commands/version.js +6 -3
- package/dist/src/commands/watch.js +6 -3
- package/dist/src/compat/sqlite.js +5 -3
- package/dist/src/config/mode-store.js +2 -1
- package/dist/src/config/profiles.js +4 -2
- package/dist/src/config/types.js +2 -1
- package/dist/src/engine/executor.js +8 -4
- package/dist/src/engine/planner.js +9 -5
- package/dist/src/llm/providers/anthropic.js +6 -3
- package/dist/src/llm/providers/ollama.js +1 -1
- package/dist/src/llm/router.js +22 -7
- package/dist/src/nimbus.js +1 -0
- package/dist/src/sessions/manager.js +6 -3
- package/dist/src/sharing/viewer.js +2 -1
- package/dist/src/tools/file-ops.js +1 -2
- package/dist/src/tools/schemas/devops.js +197 -108
- package/dist/src/tools/schemas/standard.js +1 -1
- package/dist/src/ui/App.js +25 -13
- package/dist/src/ui/FileDiffModal.js +22 -11
- package/dist/src/ui/HelpModal.js +2 -1
- package/dist/src/ui/InputBox.js +6 -3
- package/dist/src/ui/MessageList.js +40 -20
- package/dist/src/ui/TerminalPane.js +2 -1
- package/dist/src/ui/ToolCallDisplay.js +12 -6
- package/dist/src/ui/TreePane.js +2 -1
- package/dist/src/ui/ink/index.js +37 -21
- package/dist/src/version.js +1 -1
- package/dist/src/watcher/index.js +8 -4
- package/package.json +3 -5
- package/src/__tests__/alias.test.ts +0 -133
- package/src/__tests__/app.test.ts +0 -76
- package/src/__tests__/audit.test.ts +0 -877
- package/src/__tests__/circuit-breaker.test.ts +0 -116
- package/src/__tests__/cli-run.test.ts +0 -351
- package/src/__tests__/compat-sqlite.test.ts +0 -68
- package/src/__tests__/context-manager.test.ts +0 -632
- package/src/__tests__/context.test.ts +0 -242
- package/src/__tests__/devops-terminal-gaps.test.ts +0 -718
- package/src/__tests__/doctor.test.ts +0 -48
- package/src/__tests__/enterprise.test.ts +0 -401
- package/src/__tests__/export.test.ts +0 -236
- package/src/__tests__/gap-11-18-20.test.ts +0 -958
- package/src/__tests__/generator.test.ts +0 -433
- package/src/__tests__/helm-streaming.test.ts +0 -127
- package/src/__tests__/hooks.test.ts +0 -582
- package/src/__tests__/incident.test.ts +0 -179
- package/src/__tests__/init.test.ts +0 -487
- package/src/__tests__/intent-parser.test.ts +0 -229
- package/src/__tests__/llm-router.test.ts +0 -209
- package/src/__tests__/logs.test.ts +0 -107
- package/src/__tests__/loop-errors.test.ts +0 -244
- package/src/__tests__/lsp.test.ts +0 -293
- package/src/__tests__/modes.test.ts +0 -336
- package/src/__tests__/perf-optimizations.test.ts +0 -847
- package/src/__tests__/permissions.test.ts +0 -338
- package/src/__tests__/pipeline.test.ts +0 -50
- package/src/__tests__/polish-phase3.test.ts +0 -340
- package/src/__tests__/profile.test.ts +0 -237
- package/src/__tests__/rollback.test.ts +0 -83
- package/src/__tests__/runbook.test.ts +0 -219
- package/src/__tests__/schedule.test.ts +0 -206
- package/src/__tests__/serve.test.ts +0 -275
- package/src/__tests__/sessions.test.ts +0 -322
- package/src/__tests__/sharing.test.ts +0 -340
- package/src/__tests__/snapshots.test.ts +0 -581
- package/src/__tests__/standalone-migration.test.ts +0 -199
- package/src/__tests__/state-db.test.ts +0 -334
- package/src/__tests__/status.test.ts +0 -158
- package/src/__tests__/stream-with-tools.test.ts +0 -778
- package/src/__tests__/subagents.test.ts +0 -176
- package/src/__tests__/system-prompt.test.ts +0 -248
- package/src/__tests__/terminal-gap-v2.test.ts +0 -395
- package/src/__tests__/terminal-parity.test.ts +0 -393
- package/src/__tests__/tf-apply.test.ts +0 -187
- package/src/__tests__/tool-converter.test.ts +0 -256
- package/src/__tests__/tool-schemas.test.ts +0 -602
- package/src/__tests__/tools.test.ts +0 -144
- package/src/__tests__/version-json.test.ts +0 -184
- package/src/__tests__/version.test.ts +0 -49
- package/src/__tests__/watch.test.ts +0 -129
- package/src/agent/compaction-agent.ts +0 -266
- package/src/agent/context-manager.ts +0 -499
- package/src/agent/context.ts +0 -427
- package/src/agent/deploy-preview.ts +0 -487
- package/src/agent/expand-files.ts +0 -108
- package/src/agent/index.ts +0 -68
- package/src/agent/loop.ts +0 -1998
- package/src/agent/modes.ts +0 -429
- package/src/agent/permissions.ts +0 -513
- package/src/agent/subagents/base.ts +0 -116
- package/src/agent/subagents/cost.ts +0 -51
- package/src/agent/subagents/explore.ts +0 -42
- package/src/agent/subagents/general.ts +0 -54
- package/src/agent/subagents/index.ts +0 -102
- package/src/agent/subagents/infra.ts +0 -59
- package/src/agent/subagents/security.ts +0 -69
- package/src/agent/system-prompt.ts +0 -990
- package/src/app.ts +0 -180
- package/src/audit/activity-log.ts +0 -290
- package/src/audit/compliance-checker.ts +0 -540
- package/src/audit/cost-tracker.ts +0 -318
- package/src/audit/index.ts +0 -23
- package/src/audit/security-scanner.ts +0 -641
- package/src/auth/guard.ts +0 -75
- package/src/auth/index.ts +0 -56
- package/src/auth/keychain.ts +0 -82
- package/src/auth/oauth.ts +0 -465
- package/src/auth/providers.ts +0 -470
- package/src/auth/sso.ts +0 -113
- package/src/auth/store.ts +0 -505
- package/src/auth/types.ts +0 -187
- package/src/build.ts +0 -141
- package/src/cli/index.ts +0 -16
- package/src/cli/init.ts +0 -1227
- package/src/cli/openapi-spec.ts +0 -356
- package/src/cli/run.ts +0 -628
- package/src/cli/serve-auth.ts +0 -80
- package/src/cli/serve.ts +0 -539
- package/src/cli/web.ts +0 -71
- package/src/cli.ts +0 -1728
- package/src/clients/core-engine-client.ts +0 -227
- package/src/clients/enterprise-client.ts +0 -334
- package/src/clients/generator-client.ts +0 -351
- package/src/clients/git-client.ts +0 -627
- package/src/clients/github-client.ts +0 -410
- package/src/clients/helm-client.ts +0 -504
- package/src/clients/index.ts +0 -80
- package/src/clients/k8s-client.ts +0 -497
- package/src/clients/llm-client.ts +0 -161
- package/src/clients/rest-client.ts +0 -130
- package/src/clients/service-discovery.ts +0 -38
- package/src/clients/terraform-client.ts +0 -482
- package/src/clients/tools-client.ts +0 -1843
- package/src/clients/ws-client.ts +0 -115
- package/src/commands/alias.ts +0 -100
- package/src/commands/analyze/index.ts +0 -352
- package/src/commands/apply/helm.ts +0 -473
- package/src/commands/apply/index.ts +0 -213
- package/src/commands/apply/k8s.ts +0 -454
- package/src/commands/apply/terraform.ts +0 -582
- package/src/commands/ask.ts +0 -167
- package/src/commands/audit/index.ts +0 -357
- package/src/commands/auth-cloud.ts +0 -407
- package/src/commands/auth-list.ts +0 -134
- package/src/commands/auth-profile.ts +0 -121
- package/src/commands/auth-refresh.ts +0 -187
- package/src/commands/auth-status.ts +0 -141
- package/src/commands/aws/ec2.ts +0 -501
- package/src/commands/aws/iam.ts +0 -397
- package/src/commands/aws/index.ts +0 -133
- package/src/commands/aws/lambda.ts +0 -396
- package/src/commands/aws/rds.ts +0 -439
- package/src/commands/aws/s3.ts +0 -439
- package/src/commands/aws/vpc.ts +0 -393
- package/src/commands/aws-discover.ts +0 -542
- package/src/commands/aws-terraform.ts +0 -755
- package/src/commands/azure/aks.ts +0 -376
- package/src/commands/azure/functions.ts +0 -253
- package/src/commands/azure/index.ts +0 -116
- package/src/commands/azure/storage.ts +0 -478
- package/src/commands/azure/vm.ts +0 -355
- package/src/commands/billing/index.ts +0 -256
- package/src/commands/chat.ts +0 -320
- package/src/commands/completions.ts +0 -268
- package/src/commands/config.ts +0 -372
- package/src/commands/cost/cloud-cost-estimator.ts +0 -266
- package/src/commands/cost/estimator.ts +0 -79
- package/src/commands/cost/index.ts +0 -810
- package/src/commands/cost/parsers/terraform.ts +0 -273
- package/src/commands/cost/parsers/types.ts +0 -25
- package/src/commands/cost/pricing/aws.ts +0 -544
- package/src/commands/cost/pricing/azure.ts +0 -499
- package/src/commands/cost/pricing/gcp.ts +0 -396
- package/src/commands/cost/pricing/index.ts +0 -40
- package/src/commands/demo.ts +0 -250
- package/src/commands/deploy.ts +0 -260
- package/src/commands/doctor.ts +0 -1386
- package/src/commands/drift/index.ts +0 -787
- package/src/commands/explain.ts +0 -277
- package/src/commands/export.ts +0 -146
- package/src/commands/feedback.ts +0 -389
- package/src/commands/fix.ts +0 -324
- package/src/commands/fs/index.ts +0 -402
- package/src/commands/gcp/compute.ts +0 -325
- package/src/commands/gcp/functions.ts +0 -271
- package/src/commands/gcp/gke.ts +0 -438
- package/src/commands/gcp/iam.ts +0 -344
- package/src/commands/gcp/index.ts +0 -129
- package/src/commands/gcp/storage.ts +0 -284
- package/src/commands/generate-helm.ts +0 -1249
- package/src/commands/generate-k8s.ts +0 -1508
- package/src/commands/generate-terraform.ts +0 -1202
- package/src/commands/gh/index.ts +0 -863
- package/src/commands/git/index.ts +0 -1343
- package/src/commands/helm/index.ts +0 -1126
- package/src/commands/help.ts +0 -715
- package/src/commands/history.ts +0 -149
- package/src/commands/import.ts +0 -868
- package/src/commands/incident.ts +0 -166
- package/src/commands/index.ts +0 -367
- package/src/commands/init.ts +0 -1051
- package/src/commands/k8s/index.ts +0 -1137
- package/src/commands/login.ts +0 -716
- package/src/commands/logout.ts +0 -83
- package/src/commands/logs.ts +0 -167
- package/src/commands/onboarding.ts +0 -405
- package/src/commands/pipeline.ts +0 -186
- package/src/commands/plan/display.ts +0 -279
- package/src/commands/plan/index.ts +0 -599
- package/src/commands/plugin.ts +0 -398
- package/src/commands/preview.ts +0 -452
- package/src/commands/profile.ts +0 -342
- package/src/commands/questionnaire.ts +0 -1172
- package/src/commands/resume.ts +0 -47
- package/src/commands/rollback.ts +0 -315
- package/src/commands/rollout.ts +0 -88
- package/src/commands/runbook.ts +0 -346
- package/src/commands/schedule.ts +0 -236
- package/src/commands/status.ts +0 -252
- package/src/commands/team/index.ts +0 -346
- package/src/commands/team-context.ts +0 -220
- package/src/commands/template.ts +0 -233
- package/src/commands/tf/index.ts +0 -1093
- package/src/commands/upgrade.ts +0 -607
- package/src/commands/usage/index.ts +0 -134
- package/src/commands/version.ts +0 -174
- package/src/commands/watch.ts +0 -153
- package/src/compat/index.ts +0 -2
- package/src/compat/runtime.ts +0 -12
- package/src/compat/sqlite.ts +0 -177
- package/src/config/index.ts +0 -17
- package/src/config/manager.ts +0 -530
- package/src/config/mode-store.ts +0 -62
- package/src/config/profiles.ts +0 -84
- package/src/config/safety-policy.ts +0 -358
- package/src/config/schema.ts +0 -125
- package/src/config/types.ts +0 -609
- package/src/config/workspace-state.ts +0 -53
- package/src/context/context-db.ts +0 -199
- package/src/demo/index.ts +0 -349
- package/src/demo/scenarios/full-journey.ts +0 -229
- package/src/demo/scenarios/getting-started.ts +0 -127
- package/src/demo/scenarios/helm-release.ts +0 -341
- package/src/demo/scenarios/k8s-deployment.ts +0 -194
- package/src/demo/scenarios/terraform-vpc.ts +0 -170
- package/src/demo/types.ts +0 -92
- package/src/engine/cost-estimator.ts +0 -480
- package/src/engine/diagram-generator.ts +0 -256
- package/src/engine/drift-detector.ts +0 -902
- package/src/engine/executor.ts +0 -1066
- package/src/engine/index.ts +0 -76
- package/src/engine/orchestrator.ts +0 -636
- package/src/engine/planner.ts +0 -787
- package/src/engine/safety.ts +0 -743
- package/src/engine/verifier.ts +0 -770
- package/src/enterprise/audit.ts +0 -348
- package/src/enterprise/auth.ts +0 -270
- package/src/enterprise/billing.ts +0 -822
- package/src/enterprise/index.ts +0 -17
- package/src/enterprise/teams.ts +0 -443
- package/src/generator/best-practices.ts +0 -1608
- package/src/generator/helm.ts +0 -630
- package/src/generator/index.ts +0 -37
- package/src/generator/intent-parser.ts +0 -514
- package/src/generator/kubernetes.ts +0 -976
- package/src/generator/terraform.ts +0 -1875
- package/src/history/index.ts +0 -8
- package/src/history/manager.ts +0 -250
- package/src/history/types.ts +0 -34
- package/src/hooks/config.ts +0 -432
- package/src/hooks/engine.ts +0 -392
- package/src/hooks/index.ts +0 -4
- package/src/llm/auth-bridge.ts +0 -198
- package/src/llm/circuit-breaker.ts +0 -140
- package/src/llm/config-loader.ts +0 -201
- package/src/llm/cost-calculator.ts +0 -171
- package/src/llm/index.ts +0 -8
- package/src/llm/model-aliases.ts +0 -115
- package/src/llm/provider-registry.ts +0 -63
- package/src/llm/providers/anthropic.ts +0 -462
- package/src/llm/providers/bedrock.ts +0 -477
- package/src/llm/providers/google.ts +0 -405
- package/src/llm/providers/ollama.ts +0 -767
- package/src/llm/providers/openai-compatible.ts +0 -340
- package/src/llm/providers/openai.ts +0 -328
- package/src/llm/providers/openrouter.ts +0 -338
- package/src/llm/router.ts +0 -1104
- package/src/llm/types.ts +0 -232
- package/src/lsp/client.ts +0 -298
- package/src/lsp/languages.ts +0 -119
- package/src/lsp/manager.ts +0 -294
- package/src/mcp/client.ts +0 -402
- package/src/mcp/index.ts +0 -5
- package/src/mcp/manager.ts +0 -133
- package/src/nimbus.ts +0 -233
- package/src/plugins/index.ts +0 -27
- package/src/plugins/loader.ts +0 -334
- package/src/plugins/manager.ts +0 -376
- package/src/plugins/types.ts +0 -284
- package/src/scanners/cicd-scanner.ts +0 -258
- package/src/scanners/cloud-scanner.ts +0 -466
- package/src/scanners/framework-scanner.ts +0 -469
- package/src/scanners/iac-scanner.ts +0 -388
- package/src/scanners/index.ts +0 -539
- package/src/scanners/language-scanner.ts +0 -276
- package/src/scanners/package-manager-scanner.ts +0 -277
- package/src/scanners/types.ts +0 -172
- package/src/sessions/manager.ts +0 -472
- package/src/sessions/types.ts +0 -44
- package/src/sharing/sync.ts +0 -300
- package/src/sharing/viewer.ts +0 -163
- package/src/snapshots/index.ts +0 -2
- package/src/snapshots/manager.ts +0 -530
- package/src/state/artifacts.ts +0 -147
- package/src/state/audit.ts +0 -137
- package/src/state/billing.ts +0 -240
- package/src/state/checkpoints.ts +0 -117
- package/src/state/config.ts +0 -67
- package/src/state/conversations.ts +0 -14
- package/src/state/credentials.ts +0 -154
- package/src/state/db.ts +0 -58
- package/src/state/index.ts +0 -26
- package/src/state/messages.ts +0 -115
- package/src/state/projects.ts +0 -123
- package/src/state/schema.ts +0 -236
- package/src/state/sessions.ts +0 -147
- package/src/state/teams.ts +0 -200
- package/src/telemetry.ts +0 -108
- package/src/tools/aws-ops.ts +0 -952
- package/src/tools/azure-ops.ts +0 -579
- package/src/tools/file-ops.ts +0 -615
- package/src/tools/gcp-ops.ts +0 -625
- package/src/tools/git-ops.ts +0 -773
- package/src/tools/github-ops.ts +0 -799
- package/src/tools/helm-ops.ts +0 -943
- package/src/tools/index.ts +0 -17
- package/src/tools/k8s-ops.ts +0 -819
- package/src/tools/schemas/converter.ts +0 -184
- package/src/tools/schemas/devops.ts +0 -3502
- package/src/tools/schemas/index.ts +0 -73
- package/src/tools/schemas/standard.ts +0 -1148
- package/src/tools/schemas/types.ts +0 -735
- package/src/tools/spawn-exec.ts +0 -148
- package/src/tools/terraform-ops.ts +0 -862
- package/src/types/ambient.d.ts +0 -193
- package/src/types/config.ts +0 -83
- package/src/types/drift.ts +0 -116
- package/src/types/enterprise.ts +0 -335
- package/src/types/index.ts +0 -20
- package/src/types/plan.ts +0 -44
- package/src/types/request.ts +0 -65
- package/src/types/response.ts +0 -54
- package/src/types/service.ts +0 -51
- package/src/ui/App.tsx +0 -2114
- package/src/ui/DeployPreview.tsx +0 -174
- package/src/ui/FileDiffModal.tsx +0 -162
- package/src/ui/Header.tsx +0 -131
- package/src/ui/HelpModal.tsx +0 -57
- package/src/ui/InputBox.tsx +0 -503
- package/src/ui/MessageList.tsx +0 -1032
- package/src/ui/PermissionPrompt.tsx +0 -163
- package/src/ui/StatusBar.tsx +0 -277
- package/src/ui/TerminalPane.tsx +0 -84
- package/src/ui/ToolCallDisplay.tsx +0 -643
- package/src/ui/TreePane.tsx +0 -132
- package/src/ui/chat-ui.ts +0 -850
- package/src/ui/index.ts +0 -33
- package/src/ui/ink/index.ts +0 -1444
- package/src/ui/streaming.ts +0 -176
- package/src/ui/theme.ts +0 -104
- package/src/ui/types.ts +0 -75
- package/src/utils/analytics.ts +0 -72
- package/src/utils/cost-warning.ts +0 -27
- package/src/utils/env.ts +0 -46
- package/src/utils/errors.ts +0 -69
- package/src/utils/event-bus.ts +0 -38
- package/src/utils/index.ts +0 -24
- package/src/utils/logger.ts +0 -171
- package/src/utils/rate-limiter.ts +0 -121
- package/src/utils/service-auth.ts +0 -49
- package/src/utils/validation.ts +0 -53
- package/src/version.ts +0 -4
- package/src/watcher/index.ts +0 -214
- package/src/wizard/approval.ts +0 -383
- package/src/wizard/index.ts +0 -25
- package/src/wizard/prompts.ts +0 -338
- package/src/wizard/types.ts +0 -172
- package/src/wizard/ui.ts +0 -556
- package/src/wizard/wizard.ts +0 -304
- package/tsconfig.json +0 -24
package/src/commands/config.ts
DELETED
|
@@ -1,372 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Config Command
|
|
3
|
-
*
|
|
4
|
-
* Manage Nimbus configuration
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { ui } from '../wizard/ui';
|
|
8
|
-
import { select, input, confirm } from '../wizard/prompts';
|
|
9
|
-
import { ConfigManager, CONFIG_KEYS } from '../config';
|
|
10
|
-
|
|
11
|
-
export interface ConfigOptions {
|
|
12
|
-
/** Non-interactive mode */
|
|
13
|
-
nonInteractive?: boolean;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface ConfigSetOptions extends ConfigOptions {
|
|
17
|
-
/** Key to set */
|
|
18
|
-
key?: string;
|
|
19
|
-
/** Value to set */
|
|
20
|
-
value?: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface ConfigGetOptions extends ConfigOptions {
|
|
24
|
-
/** Key to get */
|
|
25
|
-
key?: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface ConfigListOptions extends ConfigOptions {
|
|
29
|
-
/** Output as JSON */
|
|
30
|
-
json?: boolean;
|
|
31
|
-
/** Show only keys with non-default values */
|
|
32
|
-
changed?: boolean;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface ConfigInitOptions extends ConfigOptions {
|
|
36
|
-
/** Force overwrite existing config */
|
|
37
|
-
force?: boolean;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Config set command
|
|
42
|
-
*/
|
|
43
|
-
export async function configSetCommand(options: ConfigSetOptions): Promise<void> {
|
|
44
|
-
const configManager = new ConfigManager();
|
|
45
|
-
|
|
46
|
-
let key = options.key;
|
|
47
|
-
let value = options.value;
|
|
48
|
-
|
|
49
|
-
// Interactive mode - select key if not provided
|
|
50
|
-
if (!key && !options.nonInteractive) {
|
|
51
|
-
const keyOptions = CONFIG_KEYS.map(k => ({
|
|
52
|
-
label: k.key,
|
|
53
|
-
value: k.key,
|
|
54
|
-
description: k.description,
|
|
55
|
-
}));
|
|
56
|
-
|
|
57
|
-
key = (await select({
|
|
58
|
-
message: 'Select configuration key to set:',
|
|
59
|
-
options: keyOptions,
|
|
60
|
-
})) as string;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (!key) {
|
|
64
|
-
ui.error('Configuration key is required.');
|
|
65
|
-
process.exit(1);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Validate key
|
|
69
|
-
const keyInfo = configManager.getKeyInfo(key);
|
|
70
|
-
if (!keyInfo) {
|
|
71
|
-
ui.warning(`Unknown configuration key: ${key}`);
|
|
72
|
-
ui.info('Use "nimbus config list" to see available keys.');
|
|
73
|
-
|
|
74
|
-
if (!options.nonInteractive) {
|
|
75
|
-
const proceed = await confirm({
|
|
76
|
-
message: 'Set this key anyway?',
|
|
77
|
-
defaultValue: false,
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
if (!proceed) {
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Get value if not provided
|
|
87
|
-
if (value === undefined && !options.nonInteractive) {
|
|
88
|
-
const currentValue = configManager.get(key);
|
|
89
|
-
const defaultValue = keyInfo?.defaultValue;
|
|
90
|
-
|
|
91
|
-
let placeholder = '';
|
|
92
|
-
if (currentValue !== undefined) {
|
|
93
|
-
placeholder = String(currentValue);
|
|
94
|
-
} else if (defaultValue !== undefined) {
|
|
95
|
-
placeholder = `default: ${defaultValue}`;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (keyInfo?.type === 'boolean') {
|
|
99
|
-
const boolValue = await confirm({
|
|
100
|
-
message: `Set ${key}:`,
|
|
101
|
-
defaultValue: currentValue ?? defaultValue ?? false,
|
|
102
|
-
});
|
|
103
|
-
value = String(boolValue);
|
|
104
|
-
} else {
|
|
105
|
-
value = await input({
|
|
106
|
-
message: `Enter value for ${key}:`,
|
|
107
|
-
defaultValue: currentValue !== undefined ? String(currentValue) : undefined,
|
|
108
|
-
placeholder,
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (value === undefined) {
|
|
114
|
-
ui.error('Configuration value is required.');
|
|
115
|
-
process.exit(1);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// M4: Validate model key against known model IDs
|
|
119
|
-
if (key === 'model' || key === 'llm.defaultModel') {
|
|
120
|
-
const knownModels = [
|
|
121
|
-
'claude-opus-4-6',
|
|
122
|
-
'claude-sonnet-4-6',
|
|
123
|
-
'claude-haiku-4-5-20251001',
|
|
124
|
-
'claude-opus-4-20250514',
|
|
125
|
-
'claude-sonnet-4-20250514',
|
|
126
|
-
'claude-haiku-4-5',
|
|
127
|
-
'anthropic/claude-opus-4-6',
|
|
128
|
-
'anthropic/claude-sonnet-4-6',
|
|
129
|
-
'anthropic/claude-haiku-4-5-20251001',
|
|
130
|
-
'anthropic/claude-opus-4-20250514',
|
|
131
|
-
'anthropic/claude-sonnet-4-20250514',
|
|
132
|
-
];
|
|
133
|
-
if (!knownModels.includes(value)) {
|
|
134
|
-
ui.warning(`"${value}" is not a recognized Nimbus model ID.`);
|
|
135
|
-
ui.info('Known models: ' + knownModels.slice(0, 6).join(', '));
|
|
136
|
-
if (!options.nonInteractive) {
|
|
137
|
-
const { confirm: confirmPrompt } = await import('../wizard/prompts');
|
|
138
|
-
const proceed = await confirmPrompt({ message: 'Set this model anyway?', defaultValue: false });
|
|
139
|
-
if (!proceed) return;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Parse and set value
|
|
145
|
-
const parsedValue = configManager.parseValue(key, value);
|
|
146
|
-
configManager.set(key, parsedValue);
|
|
147
|
-
|
|
148
|
-
ui.success(`Configuration updated: ${key} = ${parsedValue}`);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Config get command
|
|
153
|
-
*/
|
|
154
|
-
export async function configGetCommand(options: ConfigGetOptions): Promise<void> {
|
|
155
|
-
const configManager = new ConfigManager();
|
|
156
|
-
|
|
157
|
-
let key = options.key;
|
|
158
|
-
|
|
159
|
-
// Interactive mode - select key if not provided
|
|
160
|
-
if (!key && !options.nonInteractive) {
|
|
161
|
-
const keyOptions = CONFIG_KEYS.map(k => ({
|
|
162
|
-
label: k.key,
|
|
163
|
-
value: k.key,
|
|
164
|
-
description: k.description,
|
|
165
|
-
}));
|
|
166
|
-
|
|
167
|
-
key = (await select({
|
|
168
|
-
message: 'Select configuration key to view:',
|
|
169
|
-
options: keyOptions,
|
|
170
|
-
})) as string;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
if (!key) {
|
|
174
|
-
ui.error('Configuration key is required.');
|
|
175
|
-
process.exit(1);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const value = configManager.get(key);
|
|
179
|
-
|
|
180
|
-
if (value === undefined) {
|
|
181
|
-
const keyInfo = configManager.getKeyInfo(key);
|
|
182
|
-
if (keyInfo?.defaultValue !== undefined) {
|
|
183
|
-
ui.print(`${ui.color(key, 'cyan')}: ${keyInfo.defaultValue} ${ui.dim('(default)')}`);
|
|
184
|
-
} else {
|
|
185
|
-
ui.print(`${ui.color(key, 'cyan')}: ${ui.dim('(not set)')}`);
|
|
186
|
-
}
|
|
187
|
-
} else {
|
|
188
|
-
ui.print(`${ui.color(key, 'cyan')}: ${value}`);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Config list command
|
|
194
|
-
*/
|
|
195
|
-
export async function configListCommand(options: ConfigListOptions): Promise<void> {
|
|
196
|
-
const configManager = new ConfigManager();
|
|
197
|
-
const allConfig = configManager.getAllFlat();
|
|
198
|
-
|
|
199
|
-
if (options.json) {
|
|
200
|
-
console.log(JSON.stringify(allConfig, null, 2));
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
ui.newLine();
|
|
205
|
-
ui.header('Nimbus Configuration', configManager.getConfigPath());
|
|
206
|
-
|
|
207
|
-
// Group by section
|
|
208
|
-
const sections: Record<
|
|
209
|
-
string,
|
|
210
|
-
Array<{ key: string; value: any; info?: (typeof CONFIG_KEYS)[number] }>
|
|
211
|
-
> = {};
|
|
212
|
-
|
|
213
|
-
for (const keyInfo of CONFIG_KEYS) {
|
|
214
|
-
const [section] = keyInfo.key.split('.');
|
|
215
|
-
if (!sections[section]) {
|
|
216
|
-
sections[section] = [];
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const value = allConfig[keyInfo.key];
|
|
220
|
-
const isDefault = value === undefined || value === keyInfo.defaultValue;
|
|
221
|
-
|
|
222
|
-
if (options.changed && isDefault) {
|
|
223
|
-
continue;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
sections[section].push({
|
|
227
|
-
key: keyInfo.key,
|
|
228
|
-
value: value !== undefined ? value : keyInfo.defaultValue,
|
|
229
|
-
info: keyInfo,
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
for (const [section, items] of Object.entries(sections)) {
|
|
234
|
-
if (items.length === 0) {
|
|
235
|
-
continue;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
ui.section(section.charAt(0).toUpperCase() + section.slice(1));
|
|
239
|
-
|
|
240
|
-
for (const item of items) {
|
|
241
|
-
const isDefault = item.value === item.info?.defaultValue;
|
|
242
|
-
const valueStr = item.value !== undefined ? String(item.value) : ui.dim('(not set)');
|
|
243
|
-
const defaultMarker = isDefault ? ui.dim(' (default)') : '';
|
|
244
|
-
|
|
245
|
-
ui.print(` ${ui.color(item.key, 'cyan')}: ${valueStr}${defaultMarker}`);
|
|
246
|
-
|
|
247
|
-
if (item.info?.description) {
|
|
248
|
-
ui.print(` ${ui.dim(item.info.description)}`);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
ui.newLine();
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* Config init command
|
|
258
|
-
*/
|
|
259
|
-
export async function configInitCommand(options: ConfigInitOptions): Promise<void> {
|
|
260
|
-
const configManager = new ConfigManager();
|
|
261
|
-
|
|
262
|
-
if (configManager.exists() && !options.force) {
|
|
263
|
-
ui.warning(`Configuration file already exists at: ${configManager.getConfigPath()}`);
|
|
264
|
-
|
|
265
|
-
if (!options.nonInteractive) {
|
|
266
|
-
const overwrite = await confirm({
|
|
267
|
-
message: 'Overwrite existing configuration?',
|
|
268
|
-
defaultValue: false,
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
if (!overwrite) {
|
|
272
|
-
ui.info('Configuration unchanged.');
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
} else {
|
|
276
|
-
ui.info('Use --force to overwrite.');
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// Interactive configuration setup
|
|
282
|
-
if (!options.nonInteractive) {
|
|
283
|
-
ui.newLine();
|
|
284
|
-
ui.header('Nimbus Configuration Setup', "Let's configure your Nimbus CLI");
|
|
285
|
-
|
|
286
|
-
// Workspace settings
|
|
287
|
-
ui.section('Workspace');
|
|
288
|
-
|
|
289
|
-
const defaultProvider = await select({
|
|
290
|
-
message: 'Default cloud provider:',
|
|
291
|
-
options: [
|
|
292
|
-
{ label: 'AWS', value: 'aws', description: 'Amazon Web Services' },
|
|
293
|
-
{ label: 'GCP', value: 'gcp', description: 'Google Cloud Platform' },
|
|
294
|
-
{ label: 'Azure', value: 'azure', description: 'Microsoft Azure' },
|
|
295
|
-
],
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
const outputDir = await input({
|
|
299
|
-
message: 'Default output directory for generated code:',
|
|
300
|
-
defaultValue: './infrastructure',
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
// LLM settings
|
|
304
|
-
ui.section('LLM');
|
|
305
|
-
|
|
306
|
-
const temperature = await input({
|
|
307
|
-
message: 'LLM temperature (0-1):',
|
|
308
|
-
defaultValue: '0.7',
|
|
309
|
-
validate: val => {
|
|
310
|
-
const num = Number(val);
|
|
311
|
-
if (isNaN(num) || num < 0 || num > 1) {
|
|
312
|
-
return 'Temperature must be a number between 0 and 1';
|
|
313
|
-
}
|
|
314
|
-
return true;
|
|
315
|
-
},
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
// Safety settings
|
|
319
|
-
ui.section('Safety');
|
|
320
|
-
|
|
321
|
-
const requireConfirmation = await confirm({
|
|
322
|
-
message: 'Require confirmation for destructive operations?',
|
|
323
|
-
defaultValue: true,
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
// Save configuration
|
|
327
|
-
configManager.set('workspace.defaultProvider', defaultProvider);
|
|
328
|
-
configManager.set('workspace.outputDirectory', outputDir);
|
|
329
|
-
configManager.set('llm.temperature', Number(temperature));
|
|
330
|
-
configManager.set('safety.requireConfirmation', requireConfirmation);
|
|
331
|
-
|
|
332
|
-
ui.newLine();
|
|
333
|
-
ui.success(`Configuration saved to: ${configManager.getConfigPath()}`);
|
|
334
|
-
} else {
|
|
335
|
-
// Non-interactive - just create default config
|
|
336
|
-
configManager.reset();
|
|
337
|
-
ui.success(`Default configuration created at: ${configManager.getConfigPath()}`);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
/**
|
|
342
|
-
* Config reset command
|
|
343
|
-
*/
|
|
344
|
-
export async function configResetCommand(options: ConfigOptions): Promise<void> {
|
|
345
|
-
const configManager = new ConfigManager();
|
|
346
|
-
|
|
347
|
-
if (!options.nonInteractive) {
|
|
348
|
-
const confirm_reset = await confirm({
|
|
349
|
-
message: 'Reset all configuration to defaults?',
|
|
350
|
-
defaultValue: false,
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
if (!confirm_reset) {
|
|
354
|
-
ui.info('Configuration unchanged.');
|
|
355
|
-
return;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
configManager.reset();
|
|
360
|
-
ui.success('Configuration reset to defaults.');
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* Main config command dispatcher
|
|
365
|
-
*/
|
|
366
|
-
export const configCommand = {
|
|
367
|
-
set: configSetCommand,
|
|
368
|
-
get: configGetCommand,
|
|
369
|
-
list: configListCommand,
|
|
370
|
-
init: configInitCommand,
|
|
371
|
-
reset: configResetCommand,
|
|
372
|
-
};
|
|
@@ -1,266 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cloud Cost Estimator
|
|
3
|
-
*
|
|
4
|
-
* Provides cost estimates for live cloud operations (EC2 start, RDS create,
|
|
5
|
-
* EKS create, etc.) so users see a cost warning before committing to
|
|
6
|
-
* billable actions.
|
|
7
|
-
*
|
|
8
|
-
* Pricing data is a simple static lookup table based on on-demand, us-east-1
|
|
9
|
-
* list prices. Monthly = hourly * 730. The goal is user awareness, not
|
|
10
|
-
* exact billing.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
// Hours in a standard AWS billing month
|
|
14
|
-
const HOURS_PER_MONTH = 730;
|
|
15
|
-
|
|
16
|
-
// ------------------------------------------------------------------
|
|
17
|
-
// EC2 instance hourly pricing (on-demand, us-east-1, Linux)
|
|
18
|
-
// ------------------------------------------------------------------
|
|
19
|
-
const EC2_HOURLY: Record<string, number> = {
|
|
20
|
-
// T3 burstable
|
|
21
|
-
't3.nano': 0.0052,
|
|
22
|
-
't3.micro': 0.0104,
|
|
23
|
-
't3.small': 0.0208,
|
|
24
|
-
't3.medium': 0.0416,
|
|
25
|
-
't3.large': 0.0832,
|
|
26
|
-
't3.xlarge': 0.1664,
|
|
27
|
-
't3.2xlarge': 0.3328,
|
|
28
|
-
// T3a (AMD)
|
|
29
|
-
't3a.nano': 0.0047,
|
|
30
|
-
't3a.micro': 0.0094,
|
|
31
|
-
't3a.small': 0.0188,
|
|
32
|
-
't3a.medium': 0.0376,
|
|
33
|
-
't3a.large': 0.0752,
|
|
34
|
-
't3a.xlarge': 0.1504,
|
|
35
|
-
// T2 burstable
|
|
36
|
-
't2.nano': 0.0058,
|
|
37
|
-
't2.micro': 0.0116,
|
|
38
|
-
't2.small': 0.023,
|
|
39
|
-
't2.medium': 0.0464,
|
|
40
|
-
't2.large': 0.0928,
|
|
41
|
-
't2.xlarge': 0.1856,
|
|
42
|
-
't2.2xlarge': 0.3712,
|
|
43
|
-
// M5 general purpose
|
|
44
|
-
'm5.large': 0.096,
|
|
45
|
-
'm5.xlarge': 0.192,
|
|
46
|
-
'm5.2xlarge': 0.384,
|
|
47
|
-
'm5.4xlarge': 0.768,
|
|
48
|
-
// M6i general purpose
|
|
49
|
-
'm6i.large': 0.096,
|
|
50
|
-
'm6i.xlarge': 0.192,
|
|
51
|
-
'm6i.2xlarge': 0.384,
|
|
52
|
-
// C5 compute optimized
|
|
53
|
-
'c5.large': 0.085,
|
|
54
|
-
'c5.xlarge': 0.17,
|
|
55
|
-
'c5.2xlarge': 0.34,
|
|
56
|
-
'c5.4xlarge': 0.68,
|
|
57
|
-
// R5 memory optimized
|
|
58
|
-
'r5.large': 0.126,
|
|
59
|
-
'r5.xlarge': 0.252,
|
|
60
|
-
'r5.2xlarge': 0.504,
|
|
61
|
-
// GPU
|
|
62
|
-
'p3.2xlarge': 3.06,
|
|
63
|
-
'g4dn.xlarge': 0.526,
|
|
64
|
-
'g4dn.2xlarge': 0.752,
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
// ------------------------------------------------------------------
|
|
68
|
-
// RDS instance hourly pricing (on-demand, us-east-1, Single-AZ)
|
|
69
|
-
// ------------------------------------------------------------------
|
|
70
|
-
const RDS_HOURLY: Record<string, number> = {
|
|
71
|
-
'db.t3.micro': 0.017,
|
|
72
|
-
'db.t3.small': 0.034,
|
|
73
|
-
'db.t3.medium': 0.068,
|
|
74
|
-
'db.t3.large': 0.136,
|
|
75
|
-
'db.t3.xlarge': 0.272,
|
|
76
|
-
'db.t4g.micro': 0.016,
|
|
77
|
-
'db.t4g.small': 0.032,
|
|
78
|
-
'db.t4g.medium': 0.065,
|
|
79
|
-
'db.m5.large': 0.171,
|
|
80
|
-
'db.m5.xlarge': 0.342,
|
|
81
|
-
'db.m5.2xlarge': 0.684,
|
|
82
|
-
'db.m6i.large': 0.171,
|
|
83
|
-
'db.m6i.xlarge': 0.342,
|
|
84
|
-
'db.r5.large': 0.24,
|
|
85
|
-
'db.r5.xlarge': 0.48,
|
|
86
|
-
'db.r5.2xlarge': 0.96,
|
|
87
|
-
'db.r6i.large': 0.24,
|
|
88
|
-
'db.r6i.xlarge': 0.48,
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
// ------------------------------------------------------------------
|
|
92
|
-
// Fixed hourly rates for managed services
|
|
93
|
-
// ------------------------------------------------------------------
|
|
94
|
-
const MANAGED_SERVICE_HOURLY: Record<string, number> = {
|
|
95
|
-
'eks-cluster': 0.1,
|
|
96
|
-
'nat-gateway': 0.045,
|
|
97
|
-
alb: 0.0225,
|
|
98
|
-
nlb: 0.0225,
|
|
99
|
-
'vpn-gateway': 0.05,
|
|
100
|
-
'elasticache-t3-medium': 0.068,
|
|
101
|
-
'redshift-dc2-large': 0.25,
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
// ------------------------------------------------------------------
|
|
105
|
-
// Types
|
|
106
|
-
// ------------------------------------------------------------------
|
|
107
|
-
|
|
108
|
-
export type CloudOperation =
|
|
109
|
-
| 'ec2:StartInstances'
|
|
110
|
-
| 'ec2:RunInstances'
|
|
111
|
-
| 'rds:StartDBInstance'
|
|
112
|
-
| 'rds:CreateDBInstance'
|
|
113
|
-
| 'eks:CreateCluster'
|
|
114
|
-
| 'natgateway:Create'
|
|
115
|
-
| 'alb:Create'
|
|
116
|
-
| 'nlb:Create';
|
|
117
|
-
|
|
118
|
-
export interface CloudCostEstimate {
|
|
119
|
-
/** Estimated hourly cost in USD */
|
|
120
|
-
hourly: number;
|
|
121
|
-
/** Estimated monthly cost in USD (hourly * 730) */
|
|
122
|
-
monthly: number;
|
|
123
|
-
/** Human-readable description of the cost estimate */
|
|
124
|
-
description: string;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export interface CloudCostParams {
|
|
128
|
-
/** EC2 instance type (e.g. t3.micro) */
|
|
129
|
-
instanceType?: string;
|
|
130
|
-
/** RDS instance class (e.g. db.t3.micro) */
|
|
131
|
-
instanceClass?: string;
|
|
132
|
-
/** Number of instances / resources */
|
|
133
|
-
count?: number;
|
|
134
|
-
/** Whether RDS Multi-AZ is enabled (doubles compute cost) */
|
|
135
|
-
multiAz?: boolean;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// ------------------------------------------------------------------
|
|
139
|
-
// Main estimation function
|
|
140
|
-
// ------------------------------------------------------------------
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Estimate the cost of a cloud operation.
|
|
144
|
-
*
|
|
145
|
-
* Returns null if the operation or resource type is not recognized.
|
|
146
|
-
*/
|
|
147
|
-
export function estimateCloudCost(
|
|
148
|
-
operation: CloudOperation,
|
|
149
|
-
params: CloudCostParams = {}
|
|
150
|
-
): CloudCostEstimate | null {
|
|
151
|
-
const count = params.count ?? 1;
|
|
152
|
-
|
|
153
|
-
switch (operation) {
|
|
154
|
-
case 'ec2:StartInstances':
|
|
155
|
-
case 'ec2:RunInstances': {
|
|
156
|
-
const type = params.instanceType || 't3.medium';
|
|
157
|
-
const hourlyPerUnit = EC2_HOURLY[type];
|
|
158
|
-
if (hourlyPerUnit === undefined) {
|
|
159
|
-
// Unknown type -- provide a generic estimate with a caveat
|
|
160
|
-
return {
|
|
161
|
-
hourly: 0.0416 * count,
|
|
162
|
-
monthly: 0.0416 * HOURS_PER_MONTH * count,
|
|
163
|
-
description: `EC2 ${type} x${count} (pricing unavailable, using t3.medium estimate)`,
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
const hourly = hourlyPerUnit * count;
|
|
167
|
-
return {
|
|
168
|
-
hourly,
|
|
169
|
-
monthly: hourly * HOURS_PER_MONTH,
|
|
170
|
-
description: `EC2 ${type}${count > 1 ? ` x${count}` : ''} on-demand`,
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
case 'rds:StartDBInstance':
|
|
175
|
-
case 'rds:CreateDBInstance': {
|
|
176
|
-
const cls = params.instanceClass || 'db.t3.medium';
|
|
177
|
-
const hourlyPerUnit = RDS_HOURLY[cls];
|
|
178
|
-
const multiAzMultiplier = params.multiAz ? 2 : 1;
|
|
179
|
-
if (hourlyPerUnit === undefined) {
|
|
180
|
-
const fallback = 0.068; // db.t3.medium default
|
|
181
|
-
const hourly = fallback * multiAzMultiplier * count;
|
|
182
|
-
return {
|
|
183
|
-
hourly,
|
|
184
|
-
monthly: hourly * HOURS_PER_MONTH,
|
|
185
|
-
description: `RDS ${cls}${params.multiAz ? ' Multi-AZ' : ''}${count > 1 ? ` x${count}` : ''} (pricing unavailable, using db.t3.medium estimate)`,
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
const hourly = hourlyPerUnit * multiAzMultiplier * count;
|
|
189
|
-
return {
|
|
190
|
-
hourly,
|
|
191
|
-
monthly: hourly * HOURS_PER_MONTH,
|
|
192
|
-
description: `RDS ${cls}${params.multiAz ? ' Multi-AZ' : ''}${count > 1 ? ` x${count}` : ''} on-demand`,
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
case 'eks:CreateCluster': {
|
|
197
|
-
const hourly = MANAGED_SERVICE_HOURLY['eks-cluster'] * count;
|
|
198
|
-
return {
|
|
199
|
-
hourly,
|
|
200
|
-
monthly: hourly * HOURS_PER_MONTH,
|
|
201
|
-
description: `EKS cluster control plane${count > 1 ? ` x${count}` : ''} ($0.10/hr fixed)`,
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
case 'natgateway:Create': {
|
|
206
|
-
const hourly = MANAGED_SERVICE_HOURLY['nat-gateway'] * count;
|
|
207
|
-
return {
|
|
208
|
-
hourly,
|
|
209
|
-
monthly: hourly * HOURS_PER_MONTH,
|
|
210
|
-
description: `NAT Gateway${count > 1 ? ` x${count}` : ''} ($0.045/hr + data processing charges)`,
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
case 'alb:Create': {
|
|
215
|
-
const hourly = MANAGED_SERVICE_HOURLY['alb'] * count;
|
|
216
|
-
return {
|
|
217
|
-
hourly,
|
|
218
|
-
monthly: hourly * HOURS_PER_MONTH,
|
|
219
|
-
description: `Application Load Balancer${count > 1 ? ` x${count}` : ''} ($0.0225/hr + LCU charges)`,
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
case 'nlb:Create': {
|
|
224
|
-
const hourly = MANAGED_SERVICE_HOURLY['nlb'] * count;
|
|
225
|
-
return {
|
|
226
|
-
hourly,
|
|
227
|
-
monthly: hourly * HOURS_PER_MONTH,
|
|
228
|
-
description: `Network Load Balancer${count > 1 ? ` x${count}` : ''} ($0.0225/hr + LCU charges)`,
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
default:
|
|
233
|
-
return null;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// ------------------------------------------------------------------
|
|
238
|
-
// Display helpers
|
|
239
|
-
// ------------------------------------------------------------------
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Format a cost estimate into a human-readable warning string.
|
|
243
|
-
*
|
|
244
|
-
* Example output:
|
|
245
|
-
* "Estimated cost: ~$0.04/hour ($30.37/month) - EC2 t3.medium on-demand"
|
|
246
|
-
*/
|
|
247
|
-
export function formatCostWarning(estimate: CloudCostEstimate): string {
|
|
248
|
-
const hourly =
|
|
249
|
-
estimate.hourly < 0.01 ? `$${estimate.hourly.toFixed(4)}` : `$${estimate.hourly.toFixed(2)}`;
|
|
250
|
-
const monthly = `$${estimate.monthly.toFixed(2)}`;
|
|
251
|
-
return `Estimated cost: ~${hourly}/hour (${monthly}/month) - ${estimate.description}`;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Resolve an EC2 instance type to its hourly cost, or undefined if unknown.
|
|
256
|
-
*/
|
|
257
|
-
export function getEC2HourlyCost(instanceType: string): number | undefined {
|
|
258
|
-
return EC2_HOURLY[instanceType];
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Resolve an RDS instance class to its hourly cost, or undefined if unknown.
|
|
263
|
-
*/
|
|
264
|
-
export function getRDSHourlyCost(instanceClass: string): number | undefined {
|
|
265
|
-
return RDS_HOURLY[instanceClass];
|
|
266
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Built-in Cost Estimator
|
|
3
|
-
*
|
|
4
|
-
* Parses Terraform .tf files and estimates costs using a static pricing
|
|
5
|
-
* lookup table. This provides quick, offline cost estimates without
|
|
6
|
-
* requiring external tools like Infracost.
|
|
7
|
-
*
|
|
8
|
-
* For more accurate, real-time pricing, install Infracost.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { TerraformParser } from './parsers/terraform';
|
|
12
|
-
import { getResourcePrice } from './pricing';
|
|
13
|
-
import type { CostEstimate, CostResource } from './index';
|
|
14
|
-
|
|
15
|
-
export class CostEstimator {
|
|
16
|
-
/**
|
|
17
|
-
* Estimate costs for a directory containing Terraform files.
|
|
18
|
-
*
|
|
19
|
-
* Reads all .tf files in the given directory, parses resource blocks,
|
|
20
|
-
* and looks up estimated pricing for each recognized resource type.
|
|
21
|
-
*/
|
|
22
|
-
static async estimateDirectory(directory: string): Promise<CostEstimate> {
|
|
23
|
-
const parser = new TerraformParser();
|
|
24
|
-
const resources = await parser.parseDirectory(directory);
|
|
25
|
-
|
|
26
|
-
const costResources: CostResource[] = [];
|
|
27
|
-
const unsupportedTypes: Record<string, number> = {};
|
|
28
|
-
|
|
29
|
-
for (const resource of resources) {
|
|
30
|
-
const pricing = getResourcePrice(resource);
|
|
31
|
-
if (pricing) {
|
|
32
|
-
costResources.push({
|
|
33
|
-
name: `${resource.type}.${resource.name}`,
|
|
34
|
-
resourceType: resource.type,
|
|
35
|
-
monthlyCost: pricing.monthlyCost,
|
|
36
|
-
hourlyCost: pricing.hourlyCost,
|
|
37
|
-
monthlyQuantity: pricing.quantity,
|
|
38
|
-
unit: pricing.unit,
|
|
39
|
-
});
|
|
40
|
-
} else {
|
|
41
|
-
unsupportedTypes[resource.type] = (unsupportedTypes[resource.type] || 0) + 1;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const totalMonthlyCost = costResources.reduce((sum, r) => sum + r.monthlyCost, 0);
|
|
46
|
-
const totalHourlyCost = costResources.reduce((sum, r) => sum + (r.hourlyCost || 0), 0);
|
|
47
|
-
|
|
48
|
-
return {
|
|
49
|
-
version: '0.2',
|
|
50
|
-
currency: 'USD',
|
|
51
|
-
projects: [
|
|
52
|
-
{
|
|
53
|
-
name: directory.split('/').pop() || 'project',
|
|
54
|
-
metadata: { source: 'nimbus-builtin' },
|
|
55
|
-
pastTotalMonthlyCost: 0,
|
|
56
|
-
pastTotalHourlyCost: 0,
|
|
57
|
-
diffTotalMonthlyCost: 0,
|
|
58
|
-
diffTotalHourlyCost: 0,
|
|
59
|
-
totalMonthlyCost,
|
|
60
|
-
totalHourlyCost,
|
|
61
|
-
resources: costResources,
|
|
62
|
-
},
|
|
63
|
-
],
|
|
64
|
-
totalMonthlyCost,
|
|
65
|
-
totalHourlyCost,
|
|
66
|
-
diffTotalMonthlyCost: 0,
|
|
67
|
-
timeGenerated: new Date().toISOString(),
|
|
68
|
-
summary: {
|
|
69
|
-
totalDetectedResources: resources.length,
|
|
70
|
-
totalSupportedResources: costResources.length,
|
|
71
|
-
totalUnsupportedResources: Object.values(unsupportedTypes).reduce((s, c) => s + c, 0),
|
|
72
|
-
totalUsageBasedResources: 0,
|
|
73
|
-
totalNoPriceResources: 0,
|
|
74
|
-
unsupportedResourceCounts: unsupportedTypes,
|
|
75
|
-
noPriceResourceCounts: {},
|
|
76
|
-
},
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
}
|