@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/ask.ts
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Ask Command
|
|
3
|
-
*
|
|
4
|
-
* Quick question and answer with AI
|
|
5
|
-
*
|
|
6
|
-
* Usage: nimbus ask "<question>" [options]
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { logger } from '../utils';
|
|
10
|
-
import { ui } from '../wizard';
|
|
11
|
-
import { llmClient } from '../clients';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Command options
|
|
15
|
-
*/
|
|
16
|
-
export interface AskOptions {
|
|
17
|
-
context?: string;
|
|
18
|
-
contextFile?: string;
|
|
19
|
-
model?: string;
|
|
20
|
-
json?: boolean;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Run the ask command
|
|
25
|
-
*/
|
|
26
|
-
export async function askCommand(question: string, options: AskOptions = {}): Promise<void> {
|
|
27
|
-
logger.info('Running ask command', { question, options });
|
|
28
|
-
|
|
29
|
-
// Validate question
|
|
30
|
-
if (!question || question.trim() === '') {
|
|
31
|
-
ui.error('Please provide a question');
|
|
32
|
-
ui.newLine();
|
|
33
|
-
ui.print('Usage: nimbus ask "your question here"');
|
|
34
|
-
ui.newLine();
|
|
35
|
-
ui.print('Examples:');
|
|
36
|
-
ui.print(' nimbus ask "How do I create an S3 bucket with Terraform?"');
|
|
37
|
-
ui.print(' nimbus ask "What is the best practice for IAM roles?"');
|
|
38
|
-
ui.print(' nimbus ask "Explain kubernetes deployments" --context ./k8s/');
|
|
39
|
-
process.exit(1);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Build context
|
|
43
|
-
let context = '';
|
|
44
|
-
|
|
45
|
-
// Add file context if provided
|
|
46
|
-
if (options.contextFile) {
|
|
47
|
-
try {
|
|
48
|
-
const fs = await import('fs/promises');
|
|
49
|
-
const fileContent = await fs.readFile(options.contextFile, 'utf-8');
|
|
50
|
-
context += `File: ${options.contextFile}\n\`\`\`\n${fileContent}\n\`\`\`\n\n`;
|
|
51
|
-
ui.info(`Including context from: ${options.contextFile}`);
|
|
52
|
-
} catch (error: any) {
|
|
53
|
-
ui.warning(`Could not read context file: ${error.message}`);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Add directory context if provided
|
|
58
|
-
if (options.context) {
|
|
59
|
-
try {
|
|
60
|
-
const fs = await import('fs/promises');
|
|
61
|
-
const path = await import('path');
|
|
62
|
-
const stat = await fs.stat(options.context);
|
|
63
|
-
|
|
64
|
-
if (stat.isDirectory()) {
|
|
65
|
-
// Read relevant files from directory
|
|
66
|
-
const files = await fs.readdir(options.context);
|
|
67
|
-
const relevantExtensions = ['.tf', '.yaml', '.yml', '.json', '.ts', '.js', '.py', '.go'];
|
|
68
|
-
const relevantFiles = files
|
|
69
|
-
.filter(f => relevantExtensions.some(ext => f.endsWith(ext)))
|
|
70
|
-
.slice(0, 5); // Limit to 5 files
|
|
71
|
-
|
|
72
|
-
for (const file of relevantFiles) {
|
|
73
|
-
try {
|
|
74
|
-
const filePath = path.join(options.context, file);
|
|
75
|
-
const content = await fs.readFile(filePath, 'utf-8');
|
|
76
|
-
// Limit content size
|
|
77
|
-
const truncated =
|
|
78
|
-
content.length > 2000 ? `${content.slice(0, 2000)}\n... (truncated)` : content;
|
|
79
|
-
context += `File: ${file}\n\`\`\`\n${truncated}\n\`\`\`\n\n`;
|
|
80
|
-
} catch {
|
|
81
|
-
// Skip unreadable files
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (relevantFiles.length > 0) {
|
|
86
|
-
ui.info(`Including context from ${relevantFiles.length} file(s) in: ${options.context}`);
|
|
87
|
-
}
|
|
88
|
-
} else {
|
|
89
|
-
// Single file
|
|
90
|
-
const fileContent = await fs.readFile(options.context, 'utf-8');
|
|
91
|
-
context += `File: ${options.context}\n\`\`\`\n${fileContent}\n\`\`\`\n\n`;
|
|
92
|
-
ui.info(`Including context from: ${options.context}`);
|
|
93
|
-
}
|
|
94
|
-
} catch (error: any) {
|
|
95
|
-
ui.warning(`Could not read context: ${error.message}`);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Build the full question with context
|
|
100
|
-
let fullQuestion = question;
|
|
101
|
-
if (context) {
|
|
102
|
-
fullQuestion = `Context:\n${context}\n\nQuestion: ${question}`;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Check if LLM is available
|
|
106
|
-
const llmAvailable = await llmClient.isAvailable();
|
|
107
|
-
|
|
108
|
-
if (!llmAvailable) {
|
|
109
|
-
ui.error('LLM service is not available');
|
|
110
|
-
ui.info('Make sure you have configured an LLM provider with "nimbus login"');
|
|
111
|
-
ui.info('Or set the ANTHROPIC_API_KEY or OPENAI_API_KEY environment variable');
|
|
112
|
-
process.exit(1);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
ui.newLine();
|
|
116
|
-
ui.startSpinner({ message: 'Thinking...' });
|
|
117
|
-
|
|
118
|
-
try {
|
|
119
|
-
// Stream the response
|
|
120
|
-
let response = '';
|
|
121
|
-
let firstChunk = true;
|
|
122
|
-
|
|
123
|
-
for await (const chunk of llmClient.chat(fullQuestion, [], { model: options.model })) {
|
|
124
|
-
if (chunk.type === 'content' && chunk.content) {
|
|
125
|
-
if (firstChunk) {
|
|
126
|
-
ui.stopSpinnerSuccess('');
|
|
127
|
-
ui.newLine();
|
|
128
|
-
firstChunk = false;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
response += chunk.content;
|
|
132
|
-
process.stdout.write(chunk.content);
|
|
133
|
-
} else if (chunk.type === 'error') {
|
|
134
|
-
ui.stopSpinnerFail('Error');
|
|
135
|
-
ui.error(chunk.message || chunk.error || 'Unknown error');
|
|
136
|
-
process.exit(1);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Ensure newline at end
|
|
141
|
-
if (!response.endsWith('\n')) {
|
|
142
|
-
ui.newLine();
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// JSON output mode
|
|
146
|
-
if (options.json) {
|
|
147
|
-
console.log(
|
|
148
|
-
JSON.stringify(
|
|
149
|
-
{
|
|
150
|
-
question,
|
|
151
|
-
answer: response,
|
|
152
|
-
context: context ? true : false,
|
|
153
|
-
},
|
|
154
|
-
null,
|
|
155
|
-
2
|
|
156
|
-
)
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
} catch (error: any) {
|
|
160
|
-
ui.stopSpinnerFail('Failed');
|
|
161
|
-
ui.error(error.message);
|
|
162
|
-
process.exit(1);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Export as default
|
|
167
|
-
export default askCommand;
|
|
@@ -1,357 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Audit Commands
|
|
3
|
-
* Audit log viewer and export CLI commands
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { ui } from '../../wizard/ui';
|
|
7
|
-
import { auditClient } from '../../clients/enterprise-client';
|
|
8
|
-
import * as fs from 'node:fs';
|
|
9
|
-
import type { AuditListOptions, AuditExportCommandOptions } from '../../types';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Get current team ID from config or environment
|
|
13
|
-
*/
|
|
14
|
-
function getCurrentTeamId(): string | null {
|
|
15
|
-
return process.env.NIMBUS_TEAM_ID || null;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Parse relative time string (e.g., "7d", "24h") to ISO date
|
|
20
|
-
*/
|
|
21
|
-
function parseRelativeTime(timeStr: string): string {
|
|
22
|
-
const now = Date.now();
|
|
23
|
-
const match = timeStr.match(/^(\d+)([dhwm])$/);
|
|
24
|
-
|
|
25
|
-
if (!match) {
|
|
26
|
-
return timeStr; // Assume it's already a valid date string
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const value = parseInt(match[1], 10);
|
|
30
|
-
const unit = match[2];
|
|
31
|
-
|
|
32
|
-
let ms: number;
|
|
33
|
-
switch (unit) {
|
|
34
|
-
case 'h':
|
|
35
|
-
ms = value * 60 * 60 * 1000;
|
|
36
|
-
break;
|
|
37
|
-
case 'd':
|
|
38
|
-
ms = value * 24 * 60 * 60 * 1000;
|
|
39
|
-
break;
|
|
40
|
-
case 'w':
|
|
41
|
-
ms = value * 7 * 24 * 60 * 60 * 1000;
|
|
42
|
-
break;
|
|
43
|
-
case 'm':
|
|
44
|
-
ms = value * 30 * 24 * 60 * 60 * 1000;
|
|
45
|
-
break;
|
|
46
|
-
default:
|
|
47
|
-
return timeStr;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return new Date(now - ms).toISOString();
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Parse audit list options
|
|
55
|
-
*/
|
|
56
|
-
export function parseAuditListOptions(args: string[]): AuditListOptions {
|
|
57
|
-
const options: AuditListOptions = {};
|
|
58
|
-
|
|
59
|
-
for (let i = 0; i < args.length; i++) {
|
|
60
|
-
const arg = args[i];
|
|
61
|
-
if (arg === '--since' && args[i + 1]) {
|
|
62
|
-
options.since = parseRelativeTime(args[++i]);
|
|
63
|
-
} else if (arg === '--until' && args[i + 1]) {
|
|
64
|
-
options.until = parseRelativeTime(args[++i]);
|
|
65
|
-
} else if (arg === '--action' && args[i + 1]) {
|
|
66
|
-
options.action = args[++i];
|
|
67
|
-
} else if (arg === '--user' && args[i + 1]) {
|
|
68
|
-
options.userId = args[++i];
|
|
69
|
-
} else if ((arg === '--limit' || arg === '-n') && args[i + 1]) {
|
|
70
|
-
options.limit = parseInt(args[++i], 10);
|
|
71
|
-
} else if (arg === '--json') {
|
|
72
|
-
options.json = true;
|
|
73
|
-
} else if (arg === '--non-interactive') {
|
|
74
|
-
options.nonInteractive = true;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return options;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Parse audit export options
|
|
83
|
-
*/
|
|
84
|
-
export function parseAuditExportOptions(args: string[]): AuditExportCommandOptions {
|
|
85
|
-
const options: AuditExportCommandOptions = {};
|
|
86
|
-
|
|
87
|
-
for (let i = 0; i < args.length; i++) {
|
|
88
|
-
const arg = args[i];
|
|
89
|
-
if (arg === '--format' && args[i + 1]) {
|
|
90
|
-
options.format = args[++i] as 'csv' | 'json';
|
|
91
|
-
} else if ((arg === '--output' || arg === '-o') && args[i + 1]) {
|
|
92
|
-
options.output = args[++i];
|
|
93
|
-
} else if (arg === '--since' && args[i + 1]) {
|
|
94
|
-
options.since = parseRelativeTime(args[++i]);
|
|
95
|
-
} else if (arg === '--until' && args[i + 1]) {
|
|
96
|
-
options.until = parseRelativeTime(args[++i]);
|
|
97
|
-
} else if (arg === '--non-interactive') {
|
|
98
|
-
options.nonInteractive = true;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return options;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Format timestamp for display
|
|
107
|
-
*/
|
|
108
|
-
function formatTimestamp(ts: string): string {
|
|
109
|
-
const date = new Date(ts);
|
|
110
|
-
return `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Audit list command
|
|
115
|
-
*/
|
|
116
|
-
export async function auditListCommand(options: AuditListOptions): Promise<void> {
|
|
117
|
-
try {
|
|
118
|
-
const teamId = getCurrentTeamId();
|
|
119
|
-
if (!teamId) {
|
|
120
|
-
ui.error('No team selected. Run `nimbus team switch <team-id>` first.');
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
ui.startSpinner({ message: 'Fetching audit logs...' });
|
|
125
|
-
const result = await auditClient.queryLogs({
|
|
126
|
-
teamId,
|
|
127
|
-
userId: options.userId,
|
|
128
|
-
action: options.action as any,
|
|
129
|
-
since: options.since,
|
|
130
|
-
until: options.until,
|
|
131
|
-
limit: options.limit || 50,
|
|
132
|
-
});
|
|
133
|
-
ui.stopSpinnerSuccess(`Found ${result.total} logs (showing ${result.logs.length})`);
|
|
134
|
-
|
|
135
|
-
if (options.json) {
|
|
136
|
-
console.log(JSON.stringify(result, null, 2));
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (result.logs.length === 0) {
|
|
141
|
-
ui.info('No audit logs found');
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
ui.newLine();
|
|
146
|
-
ui.table({
|
|
147
|
-
columns: [
|
|
148
|
-
{ key: 'timestamp', header: 'Time', width: 20 },
|
|
149
|
-
{ key: 'action', header: 'Action', width: 20 },
|
|
150
|
-
{ key: 'user', header: 'User', width: 15 },
|
|
151
|
-
{ key: 'status', header: 'Status', width: 10 },
|
|
152
|
-
{ key: 'resource', header: 'Resource' },
|
|
153
|
-
],
|
|
154
|
-
data: result.logs.map(log => ({
|
|
155
|
-
timestamp: formatTimestamp(log.timestamp),
|
|
156
|
-
action: log.action,
|
|
157
|
-
user: log.userId || '-',
|
|
158
|
-
status: log.status,
|
|
159
|
-
resource: log.resourceType ? `${log.resourceType}/${log.resourceId || ''}` : '-',
|
|
160
|
-
})),
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
if (result.total > result.logs.length) {
|
|
164
|
-
ui.newLine();
|
|
165
|
-
ui.dim(`Showing ${result.logs.length} of ${result.total} logs. Use --limit to show more.`);
|
|
166
|
-
}
|
|
167
|
-
} catch (error: any) {
|
|
168
|
-
ui.stopSpinnerFail('Failed to fetch audit logs');
|
|
169
|
-
ui.error(error.message);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Audit export command
|
|
175
|
-
*/
|
|
176
|
-
export async function auditExportCommand(options: AuditExportCommandOptions): Promise<void> {
|
|
177
|
-
try {
|
|
178
|
-
const teamId = getCurrentTeamId();
|
|
179
|
-
if (!teamId) {
|
|
180
|
-
ui.error('No team selected. Run `nimbus team switch <team-id>` first.');
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const format = options.format || 'json';
|
|
185
|
-
const output =
|
|
186
|
-
options.output || `audit-logs-${new Date().toISOString().split('T')[0]}.${format}`;
|
|
187
|
-
|
|
188
|
-
ui.startSpinner({ message: `Exporting audit logs to ${output}...` });
|
|
189
|
-
const content = await auditClient.exportLogs(format, {
|
|
190
|
-
teamId,
|
|
191
|
-
since: options.since,
|
|
192
|
-
until: options.until,
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
fs.writeFileSync(output, content);
|
|
196
|
-
ui.stopSpinnerSuccess(`Exported to ${output}`);
|
|
197
|
-
|
|
198
|
-
const stats = fs.statSync(output);
|
|
199
|
-
ui.info(`File size: ${(stats.size / 1024).toFixed(1)} KB`);
|
|
200
|
-
} catch (error: any) {
|
|
201
|
-
ui.stopSpinnerFail('Failed to export audit logs');
|
|
202
|
-
ui.error(error.message);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/** Options for the audit scan subcommand */
|
|
207
|
-
export interface AuditScanOptions {
|
|
208
|
-
/** Compliance framework filter */
|
|
209
|
-
framework?: 'soc2' | 'hipaa' | 'pci' | 'iso27001';
|
|
210
|
-
/** Write JSON report to this file */
|
|
211
|
-
output?: string;
|
|
212
|
-
/** Directory to scan (default: cwd) */
|
|
213
|
-
dir?: string;
|
|
214
|
-
/** Exit code 1 if findings exceed this count */
|
|
215
|
-
threshold?: number;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Parse audit scan options from CLI args
|
|
220
|
-
*/
|
|
221
|
-
export function parseAuditScanOptions(args: string[]): AuditScanOptions {
|
|
222
|
-
const options: AuditScanOptions = {};
|
|
223
|
-
|
|
224
|
-
for (let i = 0; i < args.length; i++) {
|
|
225
|
-
const arg = args[i];
|
|
226
|
-
if (arg === '--framework' && args[i + 1]) {
|
|
227
|
-
options.framework = args[++i] as AuditScanOptions['framework'];
|
|
228
|
-
} else if ((arg === '--output' || arg === '-o') && args[i + 1]) {
|
|
229
|
-
options.output = args[++i];
|
|
230
|
-
} else if ((arg === '--dir' || arg === '-d') && args[i + 1]) {
|
|
231
|
-
options.dir = args[++i];
|
|
232
|
-
} else if (arg === '--threshold' && args[i + 1]) {
|
|
233
|
-
options.threshold = parseInt(args[++i], 10);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
return options;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Audit scan subcommand — runs the local security scanner
|
|
242
|
-
*/
|
|
243
|
-
export async function auditScanCommand(options: AuditScanOptions): Promise<void> {
|
|
244
|
-
const { scanSecurity } = await import('../../audit/security-scanner');
|
|
245
|
-
const dir = options.dir ?? process.cwd();
|
|
246
|
-
|
|
247
|
-
ui.startSpinner({ message: `Scanning ${dir} for security issues...` });
|
|
248
|
-
|
|
249
|
-
let result;
|
|
250
|
-
try {
|
|
251
|
-
result = await scanSecurity({ dir });
|
|
252
|
-
} catch (e: any) {
|
|
253
|
-
ui.stopSpinnerFail('Scan failed');
|
|
254
|
-
ui.error(e.message);
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
ui.stopSpinnerSuccess(
|
|
259
|
-
`Scan complete: ${result.findings.length} finding(s) in ${result.scannedFiles} file(s)`
|
|
260
|
-
);
|
|
261
|
-
|
|
262
|
-
// Filter by framework if provided (maps framework to relevant finding IDs)
|
|
263
|
-
let findings = result.findings;
|
|
264
|
-
if (options.framework) {
|
|
265
|
-
// Each framework maps loosely to severity thresholds
|
|
266
|
-
const frameworkSeverityMap: Record<string, string[]> = {
|
|
267
|
-
soc2: ['CRITICAL', 'HIGH', 'MEDIUM'],
|
|
268
|
-
hipaa: ['CRITICAL', 'HIGH', 'MEDIUM'],
|
|
269
|
-
pci: ['CRITICAL', 'HIGH'],
|
|
270
|
-
iso27001: ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'],
|
|
271
|
-
};
|
|
272
|
-
const allowedSeverities = frameworkSeverityMap[options.framework] ?? [];
|
|
273
|
-
findings = findings.filter((f: { severity: string }) => allowedSeverities.includes(f.severity));
|
|
274
|
-
ui.dim(`Framework filter (${options.framework}): showing ${findings.length} relevant finding(s)`);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
if (findings.length === 0) {
|
|
278
|
-
ui.info('No findings. Scan clean.');
|
|
279
|
-
} else {
|
|
280
|
-
ui.newLine();
|
|
281
|
-
for (const finding of findings) {
|
|
282
|
-
const severityColor = finding.severity === 'CRITICAL' || finding.severity === 'HIGH'
|
|
283
|
-
? 'red'
|
|
284
|
-
: finding.severity === 'MEDIUM'
|
|
285
|
-
? 'yellow'
|
|
286
|
-
: 'white';
|
|
287
|
-
ui.print(`[${ui.color(finding.severity, severityColor)}] ${finding.id}: ${finding.title}`);
|
|
288
|
-
if (finding.file) ui.dim(` File: ${finding.file}${finding.line ? `:${finding.line}` : ''}`);
|
|
289
|
-
ui.dim(` ${finding.recommendation}`);
|
|
290
|
-
ui.newLine();
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
// Write JSON report to file if requested
|
|
295
|
-
if (options.output) {
|
|
296
|
-
const report = {
|
|
297
|
-
timestamp: result.timestamp.toISOString(),
|
|
298
|
-
scannedFiles: result.scannedFiles,
|
|
299
|
-
scanDuration: result.scanDuration,
|
|
300
|
-
framework: options.framework ?? null,
|
|
301
|
-
findingsCount: findings.length,
|
|
302
|
-
findings,
|
|
303
|
-
};
|
|
304
|
-
fs.writeFileSync(options.output, JSON.stringify(report, null, 2), 'utf-8');
|
|
305
|
-
ui.print(`Report written to ${options.output}`);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
// Threshold check — exit code 1 if too many findings
|
|
309
|
-
if (options.threshold !== undefined && findings.length > options.threshold) {
|
|
310
|
-
ui.error(`Findings (${findings.length}) exceeded threshold (${options.threshold}). Exiting with code 1.`);
|
|
311
|
-
process.exit(1);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Main audit command dispatcher
|
|
317
|
-
*/
|
|
318
|
-
export async function auditCommand(subcommand: string, args: string[]): Promise<void> {
|
|
319
|
-
switch (subcommand) {
|
|
320
|
-
case 'list':
|
|
321
|
-
case '':
|
|
322
|
-
await auditListCommand(parseAuditListOptions(args));
|
|
323
|
-
break;
|
|
324
|
-
case 'export':
|
|
325
|
-
await auditExportCommand(parseAuditExportOptions(args));
|
|
326
|
-
break;
|
|
327
|
-
case 'scan':
|
|
328
|
-
await auditScanCommand(parseAuditScanOptions(args));
|
|
329
|
-
break;
|
|
330
|
-
default:
|
|
331
|
-
ui.error(`Unknown audit command: ${subcommand}`);
|
|
332
|
-
ui.newLine();
|
|
333
|
-
ui.info('Available audit commands:');
|
|
334
|
-
ui.print(' nimbus audit - List audit logs');
|
|
335
|
-
ui.print(' nimbus audit list - List audit logs');
|
|
336
|
-
ui.print(' nimbus audit export - Export audit logs');
|
|
337
|
-
ui.print(' nimbus audit scan - Scan directory for security issues');
|
|
338
|
-
ui.newLine();
|
|
339
|
-
ui.info('Options (list):');
|
|
340
|
-
ui.print(' --since <time> Filter logs since (e.g., 7d, 24h, 2024-01-01)');
|
|
341
|
-
ui.print(' --until <time> Filter logs until');
|
|
342
|
-
ui.print(' --action <type> Filter by action type');
|
|
343
|
-
ui.print(' --user <id> Filter by user');
|
|
344
|
-
ui.print(' --limit <n> Number of logs to show');
|
|
345
|
-
ui.print(' --json Output as JSON');
|
|
346
|
-
ui.newLine();
|
|
347
|
-
ui.info('Options (scan):');
|
|
348
|
-
ui.print(' --framework <f> Compliance framework: soc2|hipaa|pci|iso27001');
|
|
349
|
-
ui.print(' --output <file> Write JSON report to file');
|
|
350
|
-
ui.print(' --dir <path> Directory to scan (default: cwd)');
|
|
351
|
-
ui.print(' --threshold <n> Exit code 1 if findings exceed this count');
|
|
352
|
-
ui.newLine();
|
|
353
|
-
ui.info('Export options:');
|
|
354
|
-
ui.print(' --format <type> Export format (csv|json)');
|
|
355
|
-
ui.print(' --output <file> Output file path');
|
|
356
|
-
}
|
|
357
|
-
}
|