@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
package/dist/src/auth/store.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AuthStore - Credential Persistence Manager
|
|
3
3
|
* Manages storage and retrieval of authentication credentials at ~/.nimbus/auth.json
|
|
4
|
-
*
|
|
4
|
+
* Credentials are stored as plain JSON with 0600 file permissions (industry standard).
|
|
5
5
|
*/
|
|
6
6
|
import * as fs from 'fs';
|
|
7
7
|
import * as path from 'path';
|
|
8
8
|
import * as os from 'os';
|
|
9
9
|
import * as crypto from 'crypto';
|
|
10
10
|
const AUTH_FILE_VERSION = 1;
|
|
11
|
+
/** Legacy encryption prefix — used only for one-time migration of old files. */
|
|
12
|
+
const ENC_PREFIX = 'enc:';
|
|
11
13
|
/**
|
|
12
14
|
* Default empty auth file structure
|
|
13
15
|
*/
|
|
@@ -22,125 +24,78 @@ function createEmptyAuthFile() {
|
|
|
22
24
|
};
|
|
23
25
|
}
|
|
24
26
|
// ---------------------------------------------------------------------------
|
|
25
|
-
//
|
|
27
|
+
// Legacy decryption — used ONLY during one-time migration of enc:-prefixed values.
|
|
28
|
+
// This function is intentionally kept minimal; it is removed from the hot path.
|
|
26
29
|
// ---------------------------------------------------------------------------
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
* This is not cryptographically perfect, but it prevents casual copy-paste of
|
|
36
|
-
* the auth file between machines.
|
|
37
|
-
*/
|
|
38
|
-
function getMachineFingerprint() {
|
|
39
|
-
const hostname = os.hostname();
|
|
40
|
-
const homedir = os.homedir();
|
|
41
|
-
const username = os.userInfo().username;
|
|
42
|
-
return `${hostname}${homedir}${username}`;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Derive a 256-bit encryption key from the machine fingerprint using PBKDF2.
|
|
46
|
-
*/
|
|
47
|
-
function deriveKey() {
|
|
48
|
-
return crypto.pbkdf2Sync(getMachineFingerprint(), SALT, 100000, KEY_LENGTH, 'sha256');
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Encrypt a plaintext string with AES-256-GCM.
|
|
52
|
-
* Returns a base64-encoded blob containing iv + authTag + ciphertext.
|
|
53
|
-
*/
|
|
54
|
-
function encryptValue(plaintext) {
|
|
55
|
-
try {
|
|
56
|
-
const key = deriveKey();
|
|
57
|
-
const iv = crypto.randomBytes(IV_LENGTH);
|
|
58
|
-
const cipher = crypto.createCipheriv(ENCRYPTION_ALGORITHM, key, iv, {
|
|
59
|
-
authTagLength: AUTH_TAG_LENGTH,
|
|
60
|
-
});
|
|
61
|
-
const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
|
|
62
|
-
const authTag = cipher.getAuthTag();
|
|
63
|
-
// Layout: iv (16) + authTag (16) + ciphertext (variable)
|
|
64
|
-
const combined = Buffer.concat([iv, authTag, encrypted]);
|
|
65
|
-
return ENC_PREFIX + combined.toString('base64');
|
|
66
|
-
}
|
|
67
|
-
catch {
|
|
68
|
-
// On any encryption error, return the original value so the system
|
|
69
|
-
// can continue to operate.
|
|
70
|
-
return plaintext;
|
|
71
|
-
}
|
|
30
|
+
const _LEGACY_ALGORITHM = 'aes-256-gcm';
|
|
31
|
+
const _LEGACY_KEY_LENGTH = 32;
|
|
32
|
+
const _LEGACY_IV_LENGTH = 16;
|
|
33
|
+
const _LEGACY_AUTH_TAG_LENGTH = 16;
|
|
34
|
+
const _LEGACY_SALT = 'nimbus-auth-v1';
|
|
35
|
+
function _legacyDeriveKey() {
|
|
36
|
+
const fingerprint = `${os.hostname()}${os.homedir()}${os.userInfo().username}`;
|
|
37
|
+
return crypto.pbkdf2Sync(fingerprint, _LEGACY_SALT, 100000, _LEGACY_KEY_LENGTH, 'sha256');
|
|
72
38
|
}
|
|
73
39
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* never encrypted), the original string is returned for backward compatibility.
|
|
40
|
+
* Attempt to decrypt a value that was encrypted with the old AES-256-GCM scheme.
|
|
41
|
+
* Returns null if decryption fails (wrong machine, corrupted, etc.).
|
|
77
42
|
*/
|
|
78
|
-
function
|
|
43
|
+
function _legacyDecrypt(encrypted) {
|
|
79
44
|
try {
|
|
80
|
-
// Strip the enc: prefix
|
|
81
45
|
const payload = encrypted.slice(ENC_PREFIX.length);
|
|
82
46
|
const combined = Buffer.from(payload, 'base64');
|
|
83
|
-
if (combined.length <
|
|
84
|
-
|
|
85
|
-
return encrypted;
|
|
47
|
+
if (combined.length < _LEGACY_IV_LENGTH + _LEGACY_AUTH_TAG_LENGTH) {
|
|
48
|
+
return null;
|
|
86
49
|
}
|
|
87
|
-
const iv = combined.subarray(0,
|
|
88
|
-
const authTag = combined.subarray(
|
|
89
|
-
const ciphertext = combined.subarray(
|
|
90
|
-
const key =
|
|
91
|
-
const decipher = crypto.createDecipheriv(
|
|
92
|
-
authTagLength:
|
|
50
|
+
const iv = combined.subarray(0, _LEGACY_IV_LENGTH);
|
|
51
|
+
const authTag = combined.subarray(_LEGACY_IV_LENGTH, _LEGACY_IV_LENGTH + _LEGACY_AUTH_TAG_LENGTH);
|
|
52
|
+
const ciphertext = combined.subarray(_LEGACY_IV_LENGTH + _LEGACY_AUTH_TAG_LENGTH);
|
|
53
|
+
const key = _legacyDeriveKey();
|
|
54
|
+
const decipher = crypto.createDecipheriv(_LEGACY_ALGORITHM, key, iv, {
|
|
55
|
+
authTagLength: _LEGACY_AUTH_TAG_LENGTH,
|
|
93
56
|
});
|
|
94
57
|
decipher.setAuthTag(authTag);
|
|
95
|
-
|
|
96
|
-
return decrypted.toString('utf8');
|
|
58
|
+
return Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString('utf8');
|
|
97
59
|
}
|
|
98
60
|
catch {
|
|
99
|
-
|
|
100
|
-
// was introduced, or the file was moved between machines.
|
|
101
|
-
return encrypted;
|
|
61
|
+
return null;
|
|
102
62
|
}
|
|
103
63
|
}
|
|
104
|
-
// ---------------------------------------------------------------------------
|
|
105
|
-
// Encryption helpers for the AuthFile structure
|
|
106
|
-
// ---------------------------------------------------------------------------
|
|
107
|
-
/**
|
|
108
|
-
* Deep-clone the auth file and encrypt sensitive fields before persistence.
|
|
109
|
-
*/
|
|
110
|
-
function encryptAuthFile(authFile) {
|
|
111
|
-
const clone = JSON.parse(JSON.stringify(authFile));
|
|
112
|
-
// Encrypt provider API keys
|
|
113
|
-
for (const providerName of Object.keys(clone.providers)) {
|
|
114
|
-
const cred = clone.providers[providerName];
|
|
115
|
-
if (cred?.apiKey && cred.apiKey.length > 0 && !cred.apiKey.startsWith(ENC_PREFIX)) {
|
|
116
|
-
cred.apiKey = encryptValue(cred.apiKey);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
// Encrypt GitHub access token
|
|
120
|
-
if (clone.identity.github?.accessToken &&
|
|
121
|
-
clone.identity.github.accessToken.length > 0 &&
|
|
122
|
-
!clone.identity.github.accessToken.startsWith(ENC_PREFIX)) {
|
|
123
|
-
clone.identity.github.accessToken = encryptValue(clone.identity.github.accessToken);
|
|
124
|
-
}
|
|
125
|
-
return clone;
|
|
126
|
-
}
|
|
127
64
|
/**
|
|
128
|
-
*
|
|
129
|
-
*
|
|
65
|
+
* One-time migration: if any sensitive fields in the loaded auth file still carry
|
|
66
|
+
* the old `enc:` prefix, attempt to decrypt them. On success the plain-text value
|
|
67
|
+
* is kept in memory and will be written back as plain JSON on the next save().
|
|
68
|
+
* On failure the field is cleared and a warning is printed.
|
|
130
69
|
*/
|
|
131
|
-
function
|
|
132
|
-
//
|
|
70
|
+
function migrateEncryptedFields(authFile) {
|
|
71
|
+
// Provider API keys
|
|
133
72
|
for (const providerName of Object.keys(authFile.providers)) {
|
|
134
73
|
const cred = authFile.providers[providerName];
|
|
135
|
-
if (cred?.apiKey
|
|
136
|
-
|
|
74
|
+
if (cred?.apiKey?.startsWith(ENC_PREFIX)) {
|
|
75
|
+
const decrypted = _legacyDecrypt(cred.apiKey);
|
|
76
|
+
if (decrypted !== null) {
|
|
77
|
+
cred.apiKey = decrypted;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
process.stderr.write(`[nimbus] Warning: could not decrypt stored API key for provider "${providerName}". ` +
|
|
81
|
+
'The key has been cleared — please run `nimbus login` to re-enter it.\n');
|
|
82
|
+
delete cred.apiKey;
|
|
83
|
+
}
|
|
137
84
|
}
|
|
138
85
|
}
|
|
139
|
-
//
|
|
86
|
+
// GitHub access token
|
|
140
87
|
if (authFile.identity.github?.accessToken?.startsWith(ENC_PREFIX)) {
|
|
141
|
-
|
|
88
|
+
const decrypted = _legacyDecrypt(authFile.identity.github.accessToken);
|
|
89
|
+
if (decrypted !== null) {
|
|
90
|
+
authFile.identity.github.accessToken = decrypted;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
process.stderr.write('[nimbus] Warning: could not decrypt stored GitHub access token. ' +
|
|
94
|
+
'The token has been cleared — please run `nimbus connect github` to re-authenticate.\n');
|
|
95
|
+
// Clear the github identity since accessToken is required (not optional in the type)
|
|
96
|
+
delete authFile.identity.github;
|
|
97
|
+
}
|
|
142
98
|
}
|
|
143
|
-
return authFile;
|
|
144
99
|
}
|
|
145
100
|
/**
|
|
146
101
|
* AuthStore class for credential persistence
|
|
@@ -169,8 +124,8 @@ export class AuthStore {
|
|
|
169
124
|
}
|
|
170
125
|
/**
|
|
171
126
|
* Load auth file from disk, creating if necessary.
|
|
172
|
-
*
|
|
173
|
-
*
|
|
127
|
+
* Stored as plain JSON (industry standard: gh, terraform, AWS CLI all do this).
|
|
128
|
+
* Performs a one-time migration for legacy enc:-prefixed values from older versions.
|
|
174
129
|
*/
|
|
175
130
|
load() {
|
|
176
131
|
if (this.authFile) {
|
|
@@ -192,8 +147,19 @@ export class AuthStore {
|
|
|
192
147
|
// Ensure required fields exist
|
|
193
148
|
parsed.identity = parsed.identity || {};
|
|
194
149
|
parsed.providers = parsed.providers || {};
|
|
195
|
-
//
|
|
196
|
-
|
|
150
|
+
// One-time migration: decrypt any legacy enc:-prefixed fields and save back as plain text
|
|
151
|
+
const hasLegacyEncryption = Object.values(parsed.providers).some(c => c?.apiKey?.startsWith(ENC_PREFIX))
|
|
152
|
+
|| parsed.identity.github?.accessToken?.startsWith(ENC_PREFIX);
|
|
153
|
+
if (hasLegacyEncryption) {
|
|
154
|
+
migrateEncryptedFields(parsed);
|
|
155
|
+
// Persist the decrypted values immediately so migration only runs once
|
|
156
|
+
this.authFile = parsed;
|
|
157
|
+
try {
|
|
158
|
+
this.save(parsed);
|
|
159
|
+
}
|
|
160
|
+
catch { /* non-critical — in-memory values are still correct */ }
|
|
161
|
+
}
|
|
162
|
+
this.authFile = parsed;
|
|
197
163
|
return this.authFile;
|
|
198
164
|
}
|
|
199
165
|
catch {
|
|
@@ -204,8 +170,7 @@ export class AuthStore {
|
|
|
204
170
|
}
|
|
205
171
|
/**
|
|
206
172
|
* Save auth file to disk with secure permissions (0600).
|
|
207
|
-
*
|
|
208
|
-
* in plain text.
|
|
173
|
+
* Credentials are stored as plain JSON — file permissions provide the security boundary.
|
|
209
174
|
*/
|
|
210
175
|
save(authFile) {
|
|
211
176
|
this.ensureDirectory();
|
|
@@ -215,9 +180,7 @@ export class AuthStore {
|
|
|
215
180
|
}
|
|
216
181
|
fileToSave.updatedAt = new Date().toISOString();
|
|
217
182
|
this.authFile = fileToSave;
|
|
218
|
-
|
|
219
|
-
const encrypted = encryptAuthFile(fileToSave);
|
|
220
|
-
const content = JSON.stringify(encrypted, null, 2);
|
|
183
|
+
const content = JSON.stringify(fileToSave, null, 2);
|
|
221
184
|
fs.writeFileSync(this.authPath, content, { mode: 0o600 });
|
|
222
185
|
// Ensure permissions are set correctly even if file already existed
|
|
223
186
|
fs.chmodSync(this.authPath, 0o600);
|
package/dist/src/cli/init.js
CHANGED
|
@@ -299,8 +299,9 @@ export async function discoverInfraContext(dir) {
|
|
|
299
299
|
let match;
|
|
300
300
|
while ((match = profileRegex.exec(awsConfig)) !== null) {
|
|
301
301
|
const profileName = match[1];
|
|
302
|
-
if (profileName === 'default')
|
|
303
|
-
continue;
|
|
302
|
+
if (profileName === 'default') {
|
|
303
|
+
continue;
|
|
304
|
+
} // handled separately
|
|
304
305
|
// Extract region from the profile block
|
|
305
306
|
const blockStart = match.index + match[0].length;
|
|
306
307
|
const nextBlock = awsConfig.indexOf('\n[', blockStart);
|
|
@@ -308,8 +309,9 @@ export async function discoverInfraContext(dir) {
|
|
|
308
309
|
const regionMatch = block.match(/^\s*region\s*=\s*(.+)$/m);
|
|
309
310
|
profiles.push({ profile: profileName, region: regionMatch?.[1]?.trim() });
|
|
310
311
|
}
|
|
311
|
-
if (profiles.length > 0)
|
|
312
|
-
ctx.awsProfiles = profiles.slice(0, 10);
|
|
312
|
+
if (profiles.length > 0) {
|
|
313
|
+
ctx.awsProfiles = profiles.slice(0, 10);
|
|
314
|
+
} // max 10 profiles
|
|
313
315
|
}
|
|
314
316
|
}
|
|
315
317
|
catch { /* ignore */ }
|
|
@@ -318,8 +320,9 @@ export async function discoverInfraContext(dir) {
|
|
|
318
320
|
const proj = execFileSync('gcloud', ['config', 'get-value', 'project'], {
|
|
319
321
|
encoding: 'utf-8', timeout: 3000, stdio: ['pipe', 'pipe', 'pipe'],
|
|
320
322
|
}).trim();
|
|
321
|
-
if (proj && proj !== '(unset)')
|
|
323
|
+
if (proj && proj !== '(unset)') {
|
|
322
324
|
ctx.gcpProject = proj;
|
|
325
|
+
}
|
|
323
326
|
}
|
|
324
327
|
catch { /* ignore */ }
|
|
325
328
|
// G16: Count K8s namespaces and deployments
|
|
@@ -364,21 +367,27 @@ export async function discoverInfraContext(dir) {
|
|
|
364
367
|
*/
|
|
365
368
|
export function formatInfraContext(ctx) {
|
|
366
369
|
const parts = [];
|
|
367
|
-
if (ctx.terraformWorkspace)
|
|
370
|
+
if (ctx.terraformWorkspace) {
|
|
368
371
|
parts.push(`tf-workspace: ${ctx.terraformWorkspace}`);
|
|
369
|
-
|
|
372
|
+
}
|
|
373
|
+
if (ctx.kubectlContext) {
|
|
370
374
|
parts.push(`k8s-context: ${ctx.kubectlContext}`);
|
|
375
|
+
}
|
|
371
376
|
if (ctx.helmReleases && ctx.helmReleases.length > 0) {
|
|
372
377
|
parts.push(`helm-releases: ${ctx.helmReleases.slice(0, 3).join(', ')}${ctx.helmReleases.length > 3 ? ` +${ctx.helmReleases.length - 3} more` : ''}`);
|
|
373
378
|
}
|
|
374
|
-
if (ctx.awsAccount)
|
|
379
|
+
if (ctx.awsAccount) {
|
|
375
380
|
parts.push(`aws-account: ${ctx.awsAccount}`);
|
|
376
|
-
|
|
381
|
+
}
|
|
382
|
+
if (ctx.awsRegion) {
|
|
377
383
|
parts.push(`aws-region: ${ctx.awsRegion}`);
|
|
378
|
-
|
|
384
|
+
}
|
|
385
|
+
if (ctx.gcpProject) {
|
|
379
386
|
parts.push(`gcp-project: ${ctx.gcpProject}`);
|
|
380
|
-
|
|
387
|
+
}
|
|
388
|
+
if (ctx.cicdPipeline) {
|
|
381
389
|
parts.push(`cicd: ${ctx.cicdPipeline}`);
|
|
390
|
+
}
|
|
382
391
|
return parts.length > 0 ? parts.join(' | ') : 'no infra context detected';
|
|
383
392
|
}
|
|
384
393
|
/**
|
|
@@ -730,7 +739,7 @@ export function generateNimbusMd(detection, _dir, infraCtx) {
|
|
|
730
739
|
}
|
|
731
740
|
}
|
|
732
741
|
const runbookSection = foundRunbooks.length > 0
|
|
733
|
-
? foundRunbooks.join('\n')
|
|
742
|
+
? `${foundRunbooks.join('\n')}\n\nRefer to these runbooks for incident response and operational procedures.`
|
|
734
743
|
: '<!-- Add runbook references, e.g.:\n- docs/runbooks/cert-rotation.md -->';
|
|
735
744
|
lines.push('## Runbooks');
|
|
736
745
|
lines.push('');
|
|
@@ -884,10 +893,12 @@ export async function runInit(options) {
|
|
|
884
893
|
for (let idx = 0; idx < maxLen; idx++) {
|
|
885
894
|
const o = oldLines[idx];
|
|
886
895
|
const n = newLines[idx];
|
|
887
|
-
if (o === undefined)
|
|
896
|
+
if (o === undefined) {
|
|
888
897
|
diffLines.push(`+ ${n}`);
|
|
889
|
-
|
|
898
|
+
}
|
|
899
|
+
else if (n === undefined) {
|
|
890
900
|
diffLines.push(`- ${o}`);
|
|
901
|
+
}
|
|
891
902
|
else if (o !== n) {
|
|
892
903
|
diffLines.push(`- ${o}`);
|
|
893
904
|
diffLines.push(`+ ${n}`);
|
|
@@ -896,15 +907,19 @@ export async function runInit(options) {
|
|
|
896
907
|
if (diffLines.length > 0) {
|
|
897
908
|
log('\nNIMBUS.md changes:');
|
|
898
909
|
for (const dl of diffLines.slice(0, 50)) {
|
|
899
|
-
if (dl.startsWith('+'))
|
|
910
|
+
if (dl.startsWith('+')) {
|
|
900
911
|
log(` \x1b[32m${dl}\x1b[0m`);
|
|
901
|
-
|
|
912
|
+
}
|
|
913
|
+
else if (dl.startsWith('-')) {
|
|
902
914
|
log(` \x1b[31m${dl}\x1b[0m`);
|
|
903
|
-
|
|
915
|
+
}
|
|
916
|
+
else {
|
|
904
917
|
log(` ${dl}`);
|
|
918
|
+
}
|
|
905
919
|
}
|
|
906
|
-
if (diffLines.length > 50)
|
|
920
|
+
if (diffLines.length > 50) {
|
|
907
921
|
log(` ... and ${diffLines.length - 50} more changes`);
|
|
922
|
+
}
|
|
908
923
|
log('');
|
|
909
924
|
log('Apply these changes? [y/N]');
|
|
910
925
|
// Synchronous readline for non-quiet mode
|
|
@@ -1006,8 +1021,9 @@ export async function runInit(options) {
|
|
|
1006
1021
|
for (const sub of subdirs.slice(0, 20)) {
|
|
1007
1022
|
const subPath = path.join(dir, sub);
|
|
1008
1023
|
const hasTf = fs.readdirSync(subPath).some(f => f.endsWith('.tf'));
|
|
1009
|
-
if (hasTf)
|
|
1024
|
+
if (hasTf) {
|
|
1010
1025
|
tfRoots.push(sub);
|
|
1026
|
+
}
|
|
1011
1027
|
}
|
|
1012
1028
|
if (tfRoots.length > 1) {
|
|
1013
1029
|
monorepoSection = `\n## Terraform Modules (Monorepo)\n\nThis is a monorepo with multiple Terraform roots:\n${tfRoots.map(r => `- \`./${r}/\``).join('\n')}\n\nTo target a specific root, \`cd\` into the directory or specify the path.\n`;
|
package/dist/src/cli/run.js
CHANGED
|
@@ -153,7 +153,7 @@ export async function executeRun(router, options) {
|
|
|
153
153
|
},
|
|
154
154
|
required: ['success', 'output', 'cost', 'turns', 'toolCalls', 'errors'],
|
|
155
155
|
};
|
|
156
|
-
process.stdout.write(JSON.stringify(schema, null, 2)
|
|
156
|
+
process.stdout.write(`${JSON.stringify(schema, null, 2)}\n`);
|
|
157
157
|
return {
|
|
158
158
|
success: true,
|
|
159
159
|
output: '',
|
|
@@ -164,12 +164,15 @@ export async function executeRun(router, options) {
|
|
|
164
164
|
};
|
|
165
165
|
}
|
|
166
166
|
// H3: Inject context/workspace/namespace into environment before agent loop
|
|
167
|
-
if (options.context)
|
|
167
|
+
if (options.context) {
|
|
168
168
|
process.env.KUBECTL_CONTEXT = options.context;
|
|
169
|
-
|
|
169
|
+
}
|
|
170
|
+
if (options.workspace) {
|
|
170
171
|
process.env.TF_WORKSPACE = options.workspace;
|
|
171
|
-
|
|
172
|
+
}
|
|
173
|
+
if (options.namespace) {
|
|
172
174
|
process.env.K8S_NAMESPACE = options.namespace;
|
|
175
|
+
}
|
|
173
176
|
// Get prompt from stdin if requested
|
|
174
177
|
let prompt = options.prompt;
|
|
175
178
|
if (options.stdin && !prompt) {
|
|
@@ -178,17 +181,21 @@ export async function executeRun(router, options) {
|
|
|
178
181
|
if (options.stdinJson && stdinContent) {
|
|
179
182
|
try {
|
|
180
183
|
const config = JSON.parse(stdinContent);
|
|
181
|
-
if (typeof config.prompt === 'string')
|
|
184
|
+
if (typeof config.prompt === 'string') {
|
|
182
185
|
prompt = config.prompt;
|
|
186
|
+
}
|
|
183
187
|
if (config.mode === 'plan' || config.mode === 'build' || config.mode === 'deploy') {
|
|
184
188
|
options = { ...options, mode: config.mode };
|
|
185
189
|
}
|
|
186
|
-
if (typeof config.model === 'string')
|
|
190
|
+
if (typeof config.model === 'string') {
|
|
187
191
|
options = { ...options, model: config.model };
|
|
188
|
-
|
|
192
|
+
}
|
|
193
|
+
if (typeof config.autoApprove === 'boolean') {
|
|
189
194
|
options = { ...options, autoApprove: config.autoApprove };
|
|
190
|
-
|
|
195
|
+
}
|
|
196
|
+
if (typeof config.maxTurns === 'number') {
|
|
191
197
|
options = { ...options, maxTurns: config.maxTurns };
|
|
198
|
+
}
|
|
192
199
|
}
|
|
193
200
|
catch {
|
|
194
201
|
// If JSON parse fails, treat stdin as raw prompt text
|
|
@@ -406,8 +413,9 @@ export async function executeRun(router, options) {
|
|
|
406
413
|
console.log(divider);
|
|
407
414
|
console.log('');
|
|
408
415
|
// Also print final text output
|
|
409
|
-
if (output)
|
|
410
|
-
process.stdout.write(output
|
|
416
|
+
if (output) {
|
|
417
|
+
process.stdout.write(`${output}\n`);
|
|
418
|
+
}
|
|
411
419
|
}
|
|
412
420
|
const runResult = {
|
|
413
421
|
success: !result.interrupted,
|
package/dist/src/cli/serve.js
CHANGED
|
@@ -191,10 +191,12 @@ export async function serveCommand(options) {
|
|
|
191
191
|
const nimbusDir = join(homedir(), '.nimbus');
|
|
192
192
|
mkdirSync(nimbusDir, { recursive: true });
|
|
193
193
|
const childArgs = [process.argv[1], 'serve', '--port', String(port)];
|
|
194
|
-
if (options.host)
|
|
194
|
+
if (options.host) {
|
|
195
195
|
childArgs.push('--host', options.host);
|
|
196
|
-
|
|
196
|
+
}
|
|
197
|
+
if (options.auth) {
|
|
197
198
|
childArgs.push('--auth', options.auth);
|
|
199
|
+
}
|
|
198
200
|
const child = spawn(process.execPath, childArgs, {
|
|
199
201
|
detached: true,
|
|
200
202
|
stdio: 'ignore',
|
package/dist/src/cli.js
CHANGED
|
@@ -94,7 +94,7 @@ async function showSubcommandHelp(command, _args) {
|
|
|
94
94
|
};
|
|
95
95
|
const help = COMMAND_HELP[command];
|
|
96
96
|
if (help) {
|
|
97
|
-
process.stdout.write(help
|
|
97
|
+
process.stdout.write(`${help}\n`);
|
|
98
98
|
}
|
|
99
99
|
else {
|
|
100
100
|
await helpCommand({});
|
|
@@ -250,6 +250,16 @@ export async function runCommand(args) {
|
|
|
250
250
|
await onboardingCommand({});
|
|
251
251
|
return;
|
|
252
252
|
}
|
|
253
|
+
// nimbus connect <provider>
|
|
254
|
+
if (command === 'connect') {
|
|
255
|
+
if (subcommand === 'github') {
|
|
256
|
+
const { connectGitHubCommand } = await import('./commands/connect-github');
|
|
257
|
+
await connectGitHubCommand();
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
process.stderr.write(`Unknown connect target: ${subcommand || '(none)'}. Supported: nimbus connect github\n`);
|
|
261
|
+
process.exit(1);
|
|
262
|
+
}
|
|
253
263
|
// nimbus version
|
|
254
264
|
if (command === 'version' || command === '-v' || command === '--version') {
|
|
255
265
|
const options = {};
|
|
@@ -499,6 +509,27 @@ export async function runCommand(args) {
|
|
|
499
509
|
else if (arg === '--mock') {
|
|
500
510
|
options.mock = true;
|
|
501
511
|
}
|
|
512
|
+
else if (arg === '--yes' || arg === '-y') {
|
|
513
|
+
options.yes = true;
|
|
514
|
+
}
|
|
515
|
+
else if (arg === '--provider' && args[i + 1]) {
|
|
516
|
+
options.provider = args[++i];
|
|
517
|
+
}
|
|
518
|
+
else if (arg === '--gcp-project' && args[i + 1]) {
|
|
519
|
+
options.gcpProject = args[++i];
|
|
520
|
+
}
|
|
521
|
+
else if (arg === '--azure-subscription' && args[i + 1]) {
|
|
522
|
+
options.azureSubscription = args[++i];
|
|
523
|
+
}
|
|
524
|
+
else if (arg === '--json') {
|
|
525
|
+
options.jsonOutput = true;
|
|
526
|
+
}
|
|
527
|
+
else if (arg === '--questionnaire') {
|
|
528
|
+
options.questionnaire = true;
|
|
529
|
+
}
|
|
530
|
+
else if (arg === '--conversational') {
|
|
531
|
+
options.conversational = true;
|
|
532
|
+
}
|
|
502
533
|
}
|
|
503
534
|
await generateTerraformCommand(options);
|
|
504
535
|
return;
|
|
@@ -1393,8 +1424,9 @@ export async function runCommand(args) {
|
|
|
1393
1424
|
if (command === 'status') {
|
|
1394
1425
|
const statusOptions = {};
|
|
1395
1426
|
for (let i = 1; i < args.length; i++) {
|
|
1396
|
-
if (args[i] === '--json')
|
|
1427
|
+
if (args[i] === '--json') {
|
|
1397
1428
|
statusOptions.json = true;
|
|
1429
|
+
}
|
|
1398
1430
|
}
|
|
1399
1431
|
await statusCommand(statusOptions);
|
|
1400
1432
|
return;
|
|
@@ -1403,8 +1435,9 @@ export async function runCommand(args) {
|
|
|
1403
1435
|
if (command === 'context') {
|
|
1404
1436
|
const contextOptions = { verbose: true };
|
|
1405
1437
|
for (let i = 1; i < args.length; i++) {
|
|
1406
|
-
if (args[i] === '--json')
|
|
1438
|
+
if (args[i] === '--json') {
|
|
1407
1439
|
contextOptions.json = true;
|
|
1440
|
+
}
|
|
1408
1441
|
}
|
|
1409
1442
|
await statusCommand(contextOptions);
|
|
1410
1443
|
return;
|
|
@@ -1419,10 +1452,12 @@ export async function runCommand(args) {
|
|
|
1419
1452
|
const rolloutOptions = { deployment };
|
|
1420
1453
|
for (let i = 1; i < args.length; i++) {
|
|
1421
1454
|
const arg = args[i];
|
|
1422
|
-
if ((arg === '--namespace' || arg === '-n') && args[i + 1])
|
|
1455
|
+
if ((arg === '--namespace' || arg === '-n') && args[i + 1]) {
|
|
1423
1456
|
rolloutOptions.namespace = args[++i];
|
|
1424
|
-
|
|
1457
|
+
}
|
|
1458
|
+
else if (arg === '--timeout' && args[i + 1]) {
|
|
1425
1459
|
rolloutOptions.timeout = args[++i];
|
|
1460
|
+
}
|
|
1426
1461
|
}
|
|
1427
1462
|
await rolloutCommand(rolloutOptions);
|
|
1428
1463
|
return;
|
|
@@ -1432,18 +1467,24 @@ export async function runCommand(args) {
|
|
|
1432
1467
|
const rollbackOptions = {};
|
|
1433
1468
|
for (let i = 1; i < args.length; i++) {
|
|
1434
1469
|
const arg = args[i];
|
|
1435
|
-
if (arg === '--helm' && args[i + 1])
|
|
1470
|
+
if (arg === '--helm' && args[i + 1]) {
|
|
1436
1471
|
rollbackOptions.helm = args[++i];
|
|
1437
|
-
|
|
1472
|
+
}
|
|
1473
|
+
else if (arg === '--k8s' && args[i + 1]) {
|
|
1438
1474
|
rollbackOptions.k8s = args[++i];
|
|
1439
|
-
|
|
1475
|
+
}
|
|
1476
|
+
else if (arg === '--namespace' && args[i + 1]) {
|
|
1440
1477
|
rollbackOptions.namespace = args[++i];
|
|
1441
|
-
|
|
1478
|
+
}
|
|
1479
|
+
else if (arg === '--tf') {
|
|
1442
1480
|
rollbackOptions.tf = true;
|
|
1443
|
-
|
|
1481
|
+
}
|
|
1482
|
+
else if (arg === '--terraform') {
|
|
1444
1483
|
rollbackOptions.terraform = true;
|
|
1445
|
-
|
|
1484
|
+
}
|
|
1485
|
+
else if (arg === '--tf-dir' && args[i + 1]) {
|
|
1446
1486
|
rollbackOptions.tfDir = args[++i];
|
|
1487
|
+
}
|
|
1447
1488
|
}
|
|
1448
1489
|
await rollbackCommand(rollbackOptions);
|
|
1449
1490
|
return;
|
|
@@ -31,12 +31,14 @@ function saveAliases(aliases) {
|
|
|
31
31
|
* Returns the original args unchanged if no alias matches.
|
|
32
32
|
*/
|
|
33
33
|
export function resolveAlias(args) {
|
|
34
|
-
if (!args.length)
|
|
34
|
+
if (!args.length) {
|
|
35
35
|
return args;
|
|
36
|
+
}
|
|
36
37
|
const aliases = loadAliases();
|
|
37
38
|
const expanded = aliases[args[0]];
|
|
38
|
-
if (!expanded)
|
|
39
|
+
if (!expanded) {
|
|
39
40
|
return args;
|
|
41
|
+
}
|
|
40
42
|
// Split the alias value on spaces and prepend to remaining args
|
|
41
43
|
return [...expanded.split(' '), ...args.slice(1)];
|
|
42
44
|
}
|
|
@@ -73,7 +75,7 @@ export async function aliasCommand(subcommand, args) {
|
|
|
73
75
|
return;
|
|
74
76
|
}
|
|
75
77
|
// Create alias: subcommand is "<name>=<rest>" or subcommand is the name and args hold the expansion
|
|
76
|
-
const raw = subcommand + (args.length ?
|
|
78
|
+
const raw = subcommand + (args.length ? ` ${args.join(' ')}` : '');
|
|
77
79
|
const eqIdx = raw.indexOf('=');
|
|
78
80
|
if (eqIdx === -1) {
|
|
79
81
|
ui.error('Usage: nimbus alias <name>=<command> or nimbus alias list or nimbus alias remove <name>');
|
|
@@ -252,8 +252,9 @@ export async function auditScanCommand(options) {
|
|
|
252
252
|
? 'yellow'
|
|
253
253
|
: 'white';
|
|
254
254
|
ui.print(`[${ui.color(finding.severity, severityColor)}] ${finding.id}: ${finding.title}`);
|
|
255
|
-
if (finding.file)
|
|
255
|
+
if (finding.file) {
|
|
256
256
|
ui.dim(` File: ${finding.file}${finding.line ? `:${finding.line}` : ''}`);
|
|
257
|
+
}
|
|
257
258
|
ui.dim(` ${finding.recommendation}`);
|
|
258
259
|
ui.newLine();
|
|
259
260
|
}
|