@build-astron-co/nimbus 0.4.2 → 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/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 +6 -3
- 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/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/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/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 -609
- 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 -234
- 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
|
@@ -247,18 +247,24 @@ async function generateStep(ctx) {
|
|
|
247
247
|
// Derive components from discovered resources
|
|
248
248
|
const resourceTypes = (ctx.resources ?? []).map(r => r.type);
|
|
249
249
|
const components = [];
|
|
250
|
-
if (resourceTypes.some(t => t.includes('VPC') || t.includes('Subnet')))
|
|
250
|
+
if (resourceTypes.some(t => t.includes('VPC') || t.includes('Subnet'))) {
|
|
251
251
|
components.push('vpc');
|
|
252
|
-
|
|
252
|
+
}
|
|
253
|
+
if (resourceTypes.some(t => t.includes('EC2') || t.includes('Instance'))) {
|
|
253
254
|
components.push('ec2');
|
|
254
|
-
|
|
255
|
+
}
|
|
256
|
+
if (resourceTypes.some(t => t.includes('S3'))) {
|
|
255
257
|
components.push('s3');
|
|
256
|
-
|
|
258
|
+
}
|
|
259
|
+
if (resourceTypes.some(t => t.includes('RDS'))) {
|
|
257
260
|
components.push('rds');
|
|
258
|
-
|
|
261
|
+
}
|
|
262
|
+
if (resourceTypes.some(t => t.includes('EKS'))) {
|
|
259
263
|
components.push('eks');
|
|
260
|
-
|
|
264
|
+
}
|
|
265
|
+
if (components.length === 0) {
|
|
261
266
|
components.push('vpc', 's3');
|
|
267
|
+
}
|
|
262
268
|
const generatedProject = await generateTerraformProject({
|
|
263
269
|
projectName: 'infrastructure',
|
|
264
270
|
provider: 'aws',
|
|
@@ -279,12 +285,15 @@ async function generateStep(ctx) {
|
|
|
279
285
|
};
|
|
280
286
|
ui.stopSpinnerSuccess(`Generated ${Object.keys(fileMap).length} file(s)`);
|
|
281
287
|
// Add starter kit files if requested
|
|
282
|
-
if (ctx.includeReadme)
|
|
288
|
+
if (ctx.includeReadme) {
|
|
283
289
|
fileMap['README.md'] = generateReadme(summary);
|
|
284
|
-
|
|
290
|
+
}
|
|
291
|
+
if (ctx.includeGitignore) {
|
|
285
292
|
fileMap['.gitignore'] = generateGitignore();
|
|
286
|
-
|
|
293
|
+
}
|
|
294
|
+
if (ctx.includeMakefile) {
|
|
287
295
|
fileMap['Makefile'] = generateMakefile();
|
|
296
|
+
}
|
|
288
297
|
return {
|
|
289
298
|
success: true,
|
|
290
299
|
data: {
|
|
@@ -557,18 +566,24 @@ async function runNonInteractive(options) {
|
|
|
557
566
|
try {
|
|
558
567
|
const resourceTypes = (resources ?? []).map(r => r.type);
|
|
559
568
|
const components = [];
|
|
560
|
-
if (resourceTypes.some(t => t.includes('VPC') || t.includes('Subnet')))
|
|
569
|
+
if (resourceTypes.some(t => t.includes('VPC') || t.includes('Subnet'))) {
|
|
561
570
|
components.push('vpc');
|
|
562
|
-
|
|
571
|
+
}
|
|
572
|
+
if (resourceTypes.some(t => t.includes('EC2') || t.includes('Instance'))) {
|
|
563
573
|
components.push('ec2');
|
|
564
|
-
|
|
574
|
+
}
|
|
575
|
+
if (resourceTypes.some(t => t.includes('S3'))) {
|
|
565
576
|
components.push('s3');
|
|
566
|
-
|
|
577
|
+
}
|
|
578
|
+
if (resourceTypes.some(t => t.includes('RDS'))) {
|
|
567
579
|
components.push('rds');
|
|
568
|
-
|
|
580
|
+
}
|
|
581
|
+
if (resourceTypes.some(t => t.includes('EKS'))) {
|
|
569
582
|
components.push('eks');
|
|
570
|
-
|
|
583
|
+
}
|
|
584
|
+
if (components.length === 0) {
|
|
571
585
|
components.push('vpc', 's3');
|
|
586
|
+
}
|
|
572
587
|
const generatedProject = await generateTerraformProject({
|
|
573
588
|
projectName: 'infrastructure',
|
|
574
589
|
provider: 'aws',
|
|
@@ -594,12 +609,15 @@ async function runNonInteractive(options) {
|
|
|
594
609
|
if (!fs.existsSync(outputPath)) {
|
|
595
610
|
fs.mkdirSync(outputPath, { recursive: true });
|
|
596
611
|
}
|
|
597
|
-
if (options.includeStarterKit || options.includeReadme)
|
|
612
|
+
if (options.includeStarterKit || options.includeReadme) {
|
|
598
613
|
files['README.md'] = generateReadme(summary);
|
|
599
|
-
|
|
614
|
+
}
|
|
615
|
+
if (options.includeStarterKit || options.includeGitignore) {
|
|
600
616
|
files['.gitignore'] = generateGitignore();
|
|
601
|
-
|
|
617
|
+
}
|
|
618
|
+
if (options.includeStarterKit || options.includeMakefile) {
|
|
602
619
|
files['Makefile'] = generateMakefile();
|
|
620
|
+
}
|
|
603
621
|
for (const [fileName, content] of Object.entries(files)) {
|
|
604
622
|
const filePath = path.join(outputPath, fileName);
|
|
605
623
|
await writeFile(filePath, content, 'utf-8');
|
|
@@ -83,7 +83,7 @@ export function dynamicComplete(prevWord, _currWord) {
|
|
|
83
83
|
suggestions = getHelmReleases();
|
|
84
84
|
}
|
|
85
85
|
if (suggestions.length > 0) {
|
|
86
|
-
process.stdout.write(suggestions.join('\n')
|
|
86
|
+
process.stdout.write(`${suggestions.join('\n')}\n`);
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
const FLAGS = [
|
|
@@ -91,12 +91,13 @@ export async function configSetCommand(options) {
|
|
|
91
91
|
];
|
|
92
92
|
if (!knownModels.includes(value)) {
|
|
93
93
|
ui.warning(`"${value}" is not a recognized Nimbus model ID.`);
|
|
94
|
-
ui.info(
|
|
94
|
+
ui.info(`Known models: ${knownModels.slice(0, 6).join(', ')}`);
|
|
95
95
|
if (!options.nonInteractive) {
|
|
96
96
|
const { confirm: confirmPrompt } = await import('../wizard/prompts');
|
|
97
97
|
const proceed = await confirmPrompt({ message: 'Set this model anyway?', defaultValue: false });
|
|
98
|
-
if (!proceed)
|
|
98
|
+
if (!proceed) {
|
|
99
99
|
return;
|
|
100
|
+
}
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
103
|
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connect GitHub Command
|
|
3
|
+
*
|
|
4
|
+
* Runs the GitHub Device Flow OAuth independently of the main login wizard.
|
|
5
|
+
* This allows users to link their GitHub identity at any time without
|
|
6
|
+
* reconfiguring their LLM provider.
|
|
7
|
+
*
|
|
8
|
+
* Usage: nimbus connect github
|
|
9
|
+
*/
|
|
10
|
+
import { ui } from '../wizard';
|
|
11
|
+
import { authStore, GitHubDeviceFlow, completeGitHubAuth, } from '../auth';
|
|
12
|
+
/**
|
|
13
|
+
* Run the GitHub Device Flow and save the identity to authStore on success.
|
|
14
|
+
* Exits cleanly on failure without asking the user to continue — callers can
|
|
15
|
+
* retry by running `nimbus connect github` again.
|
|
16
|
+
*/
|
|
17
|
+
export async function connectGitHubCommand() {
|
|
18
|
+
ui.newLine();
|
|
19
|
+
ui.section('Connect GitHub Identity');
|
|
20
|
+
// Check if already authenticated
|
|
21
|
+
const existing = authStore.getIdentity();
|
|
22
|
+
if (existing) {
|
|
23
|
+
ui.info(`Already connected as: ${existing.username}`);
|
|
24
|
+
const { confirm } = await import('../wizard');
|
|
25
|
+
const reauth = await confirm({
|
|
26
|
+
message: 'Reconnect with a different GitHub account?',
|
|
27
|
+
defaultValue: false,
|
|
28
|
+
});
|
|
29
|
+
if (!reauth) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
ui.newLine();
|
|
34
|
+
ui.info('Starting GitHub Device Flow authentication...');
|
|
35
|
+
ui.newLine();
|
|
36
|
+
try {
|
|
37
|
+
const deviceFlow = new GitHubDeviceFlow();
|
|
38
|
+
// Request device code
|
|
39
|
+
ui.startSpinner({ message: 'Requesting authorization code...' });
|
|
40
|
+
const deviceCode = await deviceFlow.requestDeviceCode();
|
|
41
|
+
ui.stopSpinnerSuccess('Authorization code received');
|
|
42
|
+
// Display the code for the user to enter in their browser
|
|
43
|
+
ui.newLine();
|
|
44
|
+
ui.box({
|
|
45
|
+
title: 'GitHub Authorization',
|
|
46
|
+
content: [
|
|
47
|
+
`Open ${deviceCode.verification_uri} in your browser`,
|
|
48
|
+
'and enter this code:',
|
|
49
|
+
'',
|
|
50
|
+
` ${deviceCode.user_code}`,
|
|
51
|
+
'',
|
|
52
|
+
'Waiting for authorization...',
|
|
53
|
+
],
|
|
54
|
+
style: 'rounded',
|
|
55
|
+
borderColor: 'yellow',
|
|
56
|
+
padding: 1,
|
|
57
|
+
});
|
|
58
|
+
ui.newLine();
|
|
59
|
+
// Poll for the access token
|
|
60
|
+
ui.startSpinner({ message: 'Waiting for authorization...' });
|
|
61
|
+
const accessToken = await deviceFlow.waitForAuthorization(() => {
|
|
62
|
+
// Called on each poll — no-op here
|
|
63
|
+
});
|
|
64
|
+
ui.stopSpinnerSuccess('Authorization successful');
|
|
65
|
+
// Fetch the user profile
|
|
66
|
+
ui.startSpinner({ message: 'Fetching user profile...' });
|
|
67
|
+
const identity = await completeGitHubAuth(accessToken);
|
|
68
|
+
ui.stopSpinnerSuccess(`Connected as ${identity.username}${identity.name ? ` (${identity.name})` : ''}`);
|
|
69
|
+
// Persist the identity
|
|
70
|
+
authStore.setIdentity(identity);
|
|
71
|
+
ui.newLine();
|
|
72
|
+
ui.success('GitHub identity linked successfully.');
|
|
73
|
+
ui.newLine();
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
78
|
+
ui.stopSpinnerFail(`GitHub authentication failed: ${message}`);
|
|
79
|
+
ui.newLine();
|
|
80
|
+
ui.error(`Could not complete GitHub Device Flow: ${message}`);
|
|
81
|
+
ui.print('');
|
|
82
|
+
ui.print('Possible causes:');
|
|
83
|
+
ui.print(' • The OAuth app may not have Device Flow enabled.');
|
|
84
|
+
ui.print(' Visit github.com/settings/developers to check your OAuth App settings.');
|
|
85
|
+
ui.print(' • The authorization timed out (codes expire after ~15 minutes).');
|
|
86
|
+
ui.print('');
|
|
87
|
+
ui.print('Run `nimbus connect github` again to retry.');
|
|
88
|
+
ui.newLine();
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
export default connectGitHubCommand;
|
|
@@ -92,7 +92,7 @@ function runInfracostBreakdown(directory) {
|
|
|
92
92
|
});
|
|
93
93
|
return JSON.parse(result);
|
|
94
94
|
}
|
|
95
|
-
catch (
|
|
95
|
+
catch (_error) {
|
|
96
96
|
return null;
|
|
97
97
|
}
|
|
98
98
|
}
|
|
@@ -523,8 +523,9 @@ export async function costDiffCommand(path1, path2, opts = {}) {
|
|
|
523
523
|
ui.newLine();
|
|
524
524
|
// Per-project breakdown
|
|
525
525
|
for (const project of data.projects ?? []) {
|
|
526
|
-
if ((project.diffTotalMonthlyCost ?? 0) === 0)
|
|
526
|
+
if ((project.diffTotalMonthlyCost ?? 0) === 0) {
|
|
527
527
|
continue;
|
|
528
|
+
}
|
|
528
529
|
ui.print(` ${ui.bold(project.name)}: ${formatChange(project.diffTotalMonthlyCost, data.currency)}/mo`);
|
|
529
530
|
for (const resource of (project.resources ?? []).slice(0, 10)) {
|
|
530
531
|
ui.print(` ${resource.name.slice(0, 50).padEnd(50)} ${formatCurrency(resource.monthlyCost, data.currency)}/mo`);
|
|
@@ -114,10 +114,12 @@ export async function deployCommand(args) {
|
|
|
114
114
|
else {
|
|
115
115
|
const planResult = run('terraform', ['plan', '-out=nimbus-deploy.tfplan', '-no-color'], { cwd });
|
|
116
116
|
// Always print plan output so the user can review it
|
|
117
|
-
if (planResult.stdout)
|
|
118
|
-
process.stdout.write(planResult.stdout
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
if (planResult.stdout) {
|
|
118
|
+
process.stdout.write(`${planResult.stdout}\n`);
|
|
119
|
+
}
|
|
120
|
+
if (planResult.stderr) {
|
|
121
|
+
process.stderr.write(`${planResult.stderr}\n`);
|
|
122
|
+
}
|
|
121
123
|
if (planResult.status !== 0) {
|
|
122
124
|
fail('terraform plan failed. Fix the errors above before deploying.');
|
|
123
125
|
process.exit(1);
|
|
@@ -149,10 +151,12 @@ export async function deployCommand(args) {
|
|
|
149
151
|
// ------------------------------------------------------------------
|
|
150
152
|
banner(String(step++), totalSteps, 'Applying infrastructure changes...');
|
|
151
153
|
const applyResult = run('terraform', ['apply', '-auto-approve', '-no-color', 'nimbus-deploy.tfplan'], { cwd });
|
|
152
|
-
if (applyResult.stdout)
|
|
153
|
-
process.stdout.write(applyResult.stdout
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
if (applyResult.stdout) {
|
|
155
|
+
process.stdout.write(`${applyResult.stdout}\n`);
|
|
156
|
+
}
|
|
157
|
+
if (applyResult.stderr) {
|
|
158
|
+
process.stderr.write(`${applyResult.stderr}\n`);
|
|
159
|
+
}
|
|
156
160
|
// Clean up plan file regardless of success/failure
|
|
157
161
|
try {
|
|
158
162
|
const { unlinkSync } = await import('node:fs');
|
|
@@ -188,8 +192,9 @@ export async function deployCommand(args) {
|
|
|
188
192
|
for (const deployment of deployments) {
|
|
189
193
|
// deployment looks like "deployment.apps/my-app"
|
|
190
194
|
const rolloutResult = run('kubectl', ['rollout', 'status', deployment, '--timeout=120s', ...nsArgs], { cwd });
|
|
191
|
-
if (rolloutResult.stdout)
|
|
192
|
-
process.stdout.write(rolloutResult.stdout
|
|
195
|
+
if (rolloutResult.stdout) {
|
|
196
|
+
process.stdout.write(`${rolloutResult.stdout}\n`);
|
|
197
|
+
}
|
|
193
198
|
if (rolloutResult.status !== 0) {
|
|
194
199
|
warn(`Rollout timeout or error for ${deployment}: ${rolloutResult.stderr.trim()}`);
|
|
195
200
|
warn('Pods may still be coming up. Check with: kubectl get pods');
|
|
@@ -419,8 +419,9 @@ async function checkToolServices(options) {
|
|
|
419
419
|
}
|
|
420
420
|
catch {
|
|
421
421
|
const match = output.match(/[\d]+\.[\d]+\.[\d]+/);
|
|
422
|
-
if (match)
|
|
422
|
+
if (match) {
|
|
423
423
|
version = match[0];
|
|
424
|
+
}
|
|
424
425
|
}
|
|
425
426
|
results.push({ name: tool.name, version, available: true });
|
|
426
427
|
}
|
|
@@ -906,8 +907,9 @@ async function checkKubeConfig() {
|
|
|
906
907
|
try {
|
|
907
908
|
const { stdout: ctx } = await execAsync2('kubectl config current-context', { timeout: 5_000 });
|
|
908
909
|
const context = ctx.trim();
|
|
909
|
-
if (!context)
|
|
910
|
+
if (!context) {
|
|
910
911
|
return { name: 'Kubernetes Reachability', passed: true, message: 'kubectl: no active context' };
|
|
912
|
+
}
|
|
911
913
|
try {
|
|
912
914
|
await execAsync2('kubectl cluster-info --request-timeout=3s', { timeout: 8_000 });
|
|
913
915
|
try {
|
|
@@ -1245,8 +1247,9 @@ export async function doctorCommand(options = {}) {
|
|
|
1245
1247
|
details: r.details,
|
|
1246
1248
|
})),
|
|
1247
1249
|
}, null, 2));
|
|
1248
|
-
if (!allPassed)
|
|
1250
|
+
if (!allPassed) {
|
|
1249
1251
|
process.exit(1);
|
|
1252
|
+
}
|
|
1250
1253
|
return;
|
|
1251
1254
|
}
|
|
1252
1255
|
// Summary
|
|
@@ -305,8 +305,9 @@ export async function driftScanCommand(opts = {}) {
|
|
|
305
305
|
// Find terraform directories up to depth 3
|
|
306
306
|
const tfDirs = [];
|
|
307
307
|
function walk(dir, depth) {
|
|
308
|
-
if (depth > 3)
|
|
308
|
+
if (depth > 3) {
|
|
309
309
|
return;
|
|
310
|
+
}
|
|
310
311
|
try {
|
|
311
312
|
if (fsSync.existsSync(pathMod.join(dir, '.terraform')) || fsSync.readdirSync(dir).some(f => f.endsWith('.tf'))) {
|
|
312
313
|
tfDirs.push(dir);
|
|
@@ -31,7 +31,7 @@ export async function exportCommand(options = {}) {
|
|
|
31
31
|
const sm = SessionManager.getInstance();
|
|
32
32
|
const sessions = sm.list();
|
|
33
33
|
// Find the target session
|
|
34
|
-
|
|
34
|
+
const targetSession = sessions.find(s => options.sessionId && (s.id === options.sessionId || s.id.startsWith(options.sessionId))) ?? sessions[0];
|
|
35
35
|
if (!targetSession) {
|
|
36
36
|
console.error('No sessions found. Run "nimbus chat" first to create a session.');
|
|
37
37
|
process.exit(1);
|
|
@@ -50,10 +50,12 @@ export async function exportCommand(options = {}) {
|
|
|
50
50
|
role: m.role,
|
|
51
51
|
content: Array.isArray(m.content)
|
|
52
52
|
? m.content.map((b) => {
|
|
53
|
-
if (typeof b === 'string')
|
|
53
|
+
if (typeof b === 'string') {
|
|
54
54
|
return b;
|
|
55
|
-
|
|
55
|
+
}
|
|
56
|
+
if (b && typeof b === 'object' && 'text' in b) {
|
|
56
57
|
return b.text;
|
|
58
|
+
}
|
|
57
59
|
return '';
|
|
58
60
|
}).join('')
|
|
59
61
|
: String(m.content ?? ''),
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
* Usage: nimbus generate terraform [options]
|
|
7
7
|
*/
|
|
8
8
|
import { logger } from '../utils';
|
|
9
|
+
import * as fs from 'node:fs';
|
|
10
|
+
import * as path from 'node:path';
|
|
11
|
+
import * as os from 'node:os';
|
|
9
12
|
import { createWizard, ui, select, multiSelect, confirm, input, pathInput, } from '../wizard';
|
|
10
13
|
import { generateTerraformProject } from '../generator/terraform';
|
|
11
14
|
// ---- Cloud CLI helpers (replace microservice REST calls) ----
|
|
@@ -58,6 +61,65 @@ function validateAzureSubscription(subscriptionId) {
|
|
|
58
61
|
return { valid: false, error: e.message?.slice(0, 100) };
|
|
59
62
|
}
|
|
60
63
|
}
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// Cloud provider auto-detection helpers
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
/**
|
|
68
|
+
* Detect cloud providers from environment variables and credential files.
|
|
69
|
+
* Returns a list of detected provider names (aws | gcp | azure).
|
|
70
|
+
*/
|
|
71
|
+
async function detectCloudProviders() {
|
|
72
|
+
const detected = [];
|
|
73
|
+
// AWS
|
|
74
|
+
if (process.env.AWS_ACCESS_KEY_ID ||
|
|
75
|
+
process.env.AWS_PROFILE ||
|
|
76
|
+
fs.existsSync(path.join(os.homedir(), '.aws', 'credentials'))) {
|
|
77
|
+
detected.push('aws');
|
|
78
|
+
}
|
|
79
|
+
// GCP
|
|
80
|
+
if (process.env.GOOGLE_APPLICATION_CREDENTIALS ||
|
|
81
|
+
process.env.GCLOUD_PROJECT ||
|
|
82
|
+
fs.existsSync(path.join(os.homedir(), '.config', 'gcloud', 'application_default_credentials.json'))) {
|
|
83
|
+
detected.push('gcp');
|
|
84
|
+
}
|
|
85
|
+
// Azure
|
|
86
|
+
if (process.env.AZURE_SUBSCRIPTION_ID ||
|
|
87
|
+
process.env.ARM_CLIENT_ID ||
|
|
88
|
+
fs.existsSync(path.join(os.homedir(), '.azure', 'accessTokens.json'))) {
|
|
89
|
+
detected.push('azure');
|
|
90
|
+
}
|
|
91
|
+
return detected;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Scan .tf files in the current directory for provider declarations.
|
|
95
|
+
* Looks for: provider "google" {, provider "aws" {, provider "azurerm" {
|
|
96
|
+
*/
|
|
97
|
+
function scanTfFilesForProviders() {
|
|
98
|
+
const detected = new Set();
|
|
99
|
+
try {
|
|
100
|
+
const tfFiles = fs
|
|
101
|
+
.readdirSync(process.cwd(), { recursive: true, withFileTypes: true })
|
|
102
|
+
.filter(e => e.isFile() && e.name.endsWith('.tf'))
|
|
103
|
+
.map(e => path.join(e.parentPath ?? e.path ?? process.cwd(), e.name));
|
|
104
|
+
for (const file of tfFiles.slice(0, 50)) {
|
|
105
|
+
try {
|
|
106
|
+
const content = fs.readFileSync(file, 'utf-8');
|
|
107
|
+
if (/provider\s+["']aws["']/i.test(content)) {
|
|
108
|
+
detected.add('aws');
|
|
109
|
+
}
|
|
110
|
+
if (/provider\s+["']google["']/i.test(content)) {
|
|
111
|
+
detected.add('gcp');
|
|
112
|
+
}
|
|
113
|
+
if (/provider\s+["']azurerm["']/i.test(content)) {
|
|
114
|
+
detected.add('azure');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch { /* skip unreadable files */ }
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch { /* non-critical */ }
|
|
121
|
+
return [...detected];
|
|
122
|
+
}
|
|
61
123
|
/**
|
|
62
124
|
* Run the generate terraform command
|
|
63
125
|
*/
|
|
@@ -82,17 +144,38 @@ export async function generateTerraformCommand(options = {}) {
|
|
|
82
144
|
await runConversational(options);
|
|
83
145
|
return;
|
|
84
146
|
}
|
|
147
|
+
// Auto-detect cloud provider from environment + local .tf files
|
|
148
|
+
let autoDetectedProvider = options.provider;
|
|
149
|
+
if (!autoDetectedProvider) {
|
|
150
|
+
const [envDetected, tfDetected] = await Promise.all([
|
|
151
|
+
detectCloudProviders(),
|
|
152
|
+
Promise.resolve(scanTfFilesForProviders()),
|
|
153
|
+
]);
|
|
154
|
+
// Merge and deduplicate (tf file declarations take priority)
|
|
155
|
+
const allDetected = [...new Set([...tfDetected, ...envDetected])];
|
|
156
|
+
if (allDetected.length === 1) {
|
|
157
|
+
autoDetectedProvider = allDetected[0];
|
|
158
|
+
ui.info(`Detected: ${autoDetectedProvider} from environment — continuing...`);
|
|
159
|
+
}
|
|
160
|
+
else if (allDetected.length > 1) {
|
|
161
|
+
// Show list with detected ones pre-marked; user selects one
|
|
162
|
+
ui.info(`Detected multiple providers: ${allDetected.join(', ')}`);
|
|
163
|
+
// Will fall through to the wizard's provider selection step with a pre-populated default
|
|
164
|
+
autoDetectedProvider = allDetected[0];
|
|
165
|
+
}
|
|
166
|
+
}
|
|
85
167
|
// Interactive wizard mode
|
|
86
168
|
const steps = createWizardSteps();
|
|
87
169
|
const wizard = createWizard({
|
|
88
170
|
title: 'nimbus generate terraform',
|
|
89
171
|
description: 'Generate Terraform from your cloud infrastructure',
|
|
90
172
|
initialContext: {
|
|
91
|
-
provider: 'aws',
|
|
173
|
+
provider: autoDetectedProvider ?? 'aws',
|
|
92
174
|
awsProfile: options.profile,
|
|
93
175
|
awsRegions: options.regions,
|
|
94
176
|
servicesToScan: options.services,
|
|
95
177
|
outputPath: options.output,
|
|
178
|
+
yes: options.yes,
|
|
96
179
|
},
|
|
97
180
|
steps,
|
|
98
181
|
onEvent: event => {
|
|
@@ -234,6 +317,11 @@ function createWizardSteps() {
|
|
|
234
317
|
* Step 1: Provider Selection
|
|
235
318
|
*/
|
|
236
319
|
async function providerSelectionStep(ctx) {
|
|
320
|
+
// --yes: accept the detected/default provider without prompting
|
|
321
|
+
if (ctx.yes && ctx.provider) {
|
|
322
|
+
ui.info(`Provider: ${ctx.provider} (--yes)`);
|
|
323
|
+
return { success: true, data: { provider: ctx.provider } };
|
|
324
|
+
}
|
|
237
325
|
const provider = await select({
|
|
238
326
|
message: 'Select cloud provider:',
|
|
239
327
|
options: [
|
|
@@ -708,7 +796,21 @@ async function discoveryStep(ctx) {
|
|
|
708
796
|
/**
|
|
709
797
|
* Step 5: Generation Options
|
|
710
798
|
*/
|
|
711
|
-
async function generationOptionsStep(
|
|
799
|
+
async function generationOptionsStep(ctx) {
|
|
800
|
+
// --yes: use defaults without prompting
|
|
801
|
+
if (ctx.yes) {
|
|
802
|
+
ui.info('Generation options: defaults accepted (--yes)');
|
|
803
|
+
return {
|
|
804
|
+
success: true,
|
|
805
|
+
data: {
|
|
806
|
+
importMethod: 'both',
|
|
807
|
+
includeReadme: true,
|
|
808
|
+
includeGitignore: true,
|
|
809
|
+
includeMakefile: true,
|
|
810
|
+
includeGithubActions: true,
|
|
811
|
+
},
|
|
812
|
+
};
|
|
813
|
+
}
|
|
712
814
|
// Import method
|
|
713
815
|
const importMethod = await select({
|
|
714
816
|
message: 'How should imports be generated?',
|
|
@@ -752,6 +854,12 @@ async function generationOptionsStep(_ctx) {
|
|
|
752
854
|
* Step 6: Output Location
|
|
753
855
|
*/
|
|
754
856
|
async function outputLocationStep(ctx) {
|
|
857
|
+
// --yes: accept the default output path without prompting
|
|
858
|
+
if (ctx.yes) {
|
|
859
|
+
const outputPath = ctx.outputPath || './terraform-infrastructure';
|
|
860
|
+
ui.info(`Output path: ${outputPath} (--yes)`);
|
|
861
|
+
return { success: true, data: { outputPath, savePreferences: false } };
|
|
862
|
+
}
|
|
755
863
|
const outputPath = await pathInput('Where should the Terraform files be saved?', ctx.outputPath || './terraform-infrastructure');
|
|
756
864
|
if (!outputPath) {
|
|
757
865
|
return { success: false, error: 'Output path is required' };
|
|
@@ -267,7 +267,7 @@ function discoverAwsResources(resourceType, region) {
|
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
269
|
}
|
|
270
|
-
catch (
|
|
270
|
+
catch (_error) {
|
|
271
271
|
// AWS CLI not available or not authenticated
|
|
272
272
|
}
|
|
273
273
|
return resources;
|
|
@@ -348,7 +348,7 @@ function discoverGcpResources(resourceType, project) {
|
|
|
348
348
|
}
|
|
349
349
|
}
|
|
350
350
|
}
|
|
351
|
-
catch (
|
|
351
|
+
catch (_error) {
|
|
352
352
|
// gcloud CLI not available or not authenticated
|
|
353
353
|
}
|
|
354
354
|
return resources;
|
|
@@ -427,7 +427,7 @@ function discoverAzureResources(resourceType, subscription) {
|
|
|
427
427
|
}
|
|
428
428
|
}
|
|
429
429
|
}
|
|
430
|
-
catch (
|
|
430
|
+
catch (_error) {
|
|
431
431
|
// az CLI not available or not authenticated
|
|
432
432
|
}
|
|
433
433
|
return resources;
|
|
@@ -29,8 +29,9 @@ function parseIncidentInput(input) {
|
|
|
29
29
|
*/
|
|
30
30
|
async function fetchPagerDutyDetails(incidentId) {
|
|
31
31
|
const token = process.env.PD_API_TOKEN;
|
|
32
|
-
if (!token)
|
|
32
|
+
if (!token) {
|
|
33
33
|
return null;
|
|
34
|
+
}
|
|
34
35
|
try {
|
|
35
36
|
const curlCmd = `curl -sf -H "Authorization: Token token=${token}" -H "Accept: application/vnd.pagerduty+json;version=2" "https://api.pagerduty.com/incidents/${incidentId}"`;
|
|
36
37
|
const output = execSync(curlCmd, { encoding: 'utf-8', timeout: 10_000 });
|
|
@@ -68,8 +69,9 @@ function getRecentHelmHistory(serviceName) {
|
|
|
68
69
|
encoding: 'utf-8', timeout: 10_000,
|
|
69
70
|
});
|
|
70
71
|
const history = JSON.parse(out);
|
|
71
|
-
if (history.length === 0)
|
|
72
|
+
if (history.length === 0) {
|
|
72
73
|
return '';
|
|
74
|
+
}
|
|
73
75
|
const lines = history.map(h => ` Rev ${h.revision}: ${h.chart} [${h.status}] ${h.updated} — ${h.description}`);
|
|
74
76
|
return `\nRecent Helm releases for ${serviceName}:\n${lines.join('\n')}`;
|
|
75
77
|
}
|
|
@@ -83,8 +85,9 @@ function getRecentHelmHistory(serviceName) {
|
|
|
83
85
|
function getRecentPodLogs(serviceName) {
|
|
84
86
|
try {
|
|
85
87
|
const out = execSync(`kubectl logs -l app=${serviceName} --tail=50 --since=30m --all-containers 2>/dev/null | head -c 4096`, { encoding: 'utf-8', timeout: 15_000 });
|
|
86
|
-
if (!out.trim())
|
|
88
|
+
if (!out.trim()) {
|
|
87
89
|
return '';
|
|
90
|
+
}
|
|
88
91
|
return `\nRecent pod logs (last 30m, ${serviceName}):\n${out.trim()}`;
|
|
89
92
|
}
|
|
90
93
|
catch {
|
|
@@ -130,11 +133,13 @@ export async function incidentCommand(incidentInput, options = {}) {
|
|
|
130
133
|
if (serviceName) {
|
|
131
134
|
contextParts.push(`\n## Detected Service: ${serviceName}`);
|
|
132
135
|
const helmHistory = getRecentHelmHistory(serviceName);
|
|
133
|
-
if (helmHistory)
|
|
136
|
+
if (helmHistory) {
|
|
134
137
|
contextParts.push(helmHistory);
|
|
138
|
+
}
|
|
135
139
|
const podLogs = getRecentPodLogs(serviceName);
|
|
136
|
-
if (podLogs)
|
|
140
|
+
if (podLogs) {
|
|
137
141
|
contextParts.push(podLogs);
|
|
142
|
+
}
|
|
138
143
|
}
|
|
139
144
|
contextParts.push('\n## Your Task\nHelp resolve this incident. Start by diagnosing root cause from the context above, then suggest and (with permission) execute remediation steps.');
|
|
140
145
|
const initialPrompt = contextParts.join('\n');
|