@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/src/ui/InputBox.tsx
DELETED
|
@@ -1,503 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* InputBox Component
|
|
3
|
-
*
|
|
4
|
-
* A text input area with a "> " prompt character. Uses ink-text-input for
|
|
5
|
-
* editing and submits on Enter. The parent component receives the submitted
|
|
6
|
-
* text via the `onSubmit` callback.
|
|
7
|
-
*
|
|
8
|
-
* Features:
|
|
9
|
-
* - Input history (Up/Down arrows)
|
|
10
|
-
* - Multi-line paste detection with line count indicator
|
|
11
|
-
* - Slash command autocomplete (Tab to cycle)
|
|
12
|
-
* - @file mention with Tab completion (type @ then Tab to cycle files)
|
|
13
|
-
* - Reverse search (Ctrl+R) through history
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import React, { useState, useCallback, useRef, useEffect } from 'react';
|
|
17
|
-
import { Box, Text, useInput } from 'ink';
|
|
18
|
-
import TextInput from 'ink-text-input';
|
|
19
|
-
import { spawnSync } from 'node:child_process';
|
|
20
|
-
import { writeFileSync, readFileSync, unlinkSync, existsSync, mkdirSync } from 'node:fs';
|
|
21
|
-
import { join } from 'node:path';
|
|
22
|
-
import { homedir } from 'node:os';
|
|
23
|
-
|
|
24
|
-
/** Maximum number of history entries to keep. */
|
|
25
|
-
const MAX_HISTORY = 100;
|
|
26
|
-
|
|
27
|
-
/** Path to the persistent input history file. */
|
|
28
|
-
const HISTORY_FILE = join(homedir(), '.nimbus', 'input-history.json');
|
|
29
|
-
|
|
30
|
-
/** Load persisted input history from disk (returns [] on any error). */
|
|
31
|
-
function loadHistory(): string[] {
|
|
32
|
-
try {
|
|
33
|
-
if (!existsSync(HISTORY_FILE)) return [];
|
|
34
|
-
const raw = readFileSync(HISTORY_FILE, 'utf-8');
|
|
35
|
-
const parsed = JSON.parse(raw);
|
|
36
|
-
if (Array.isArray(parsed)) return parsed.slice(-MAX_HISTORY) as string[];
|
|
37
|
-
} catch { /* ignore */ }
|
|
38
|
-
return [];
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/** Save input history to disk (fire-and-forget, ignores errors). */
|
|
42
|
-
function saveHistory(entries: string[]): void {
|
|
43
|
-
try {
|
|
44
|
-
const dir = join(homedir(), '.nimbus');
|
|
45
|
-
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
46
|
-
writeFileSync(HISTORY_FILE, JSON.stringify(entries.slice(-MAX_HISTORY)), 'utf-8');
|
|
47
|
-
} catch { /* non-critical */ }
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/** All recognized slash commands for autocomplete. */
|
|
51
|
-
const SLASH_COMMANDS = [
|
|
52
|
-
'/alias',
|
|
53
|
-
'/apply',
|
|
54
|
-
'/branch',
|
|
55
|
-
'/auth-refresh',
|
|
56
|
-
'/clear',
|
|
57
|
-
'/compact',
|
|
58
|
-
'/context',
|
|
59
|
-
'/cost',
|
|
60
|
-
'/diff',
|
|
61
|
-
'/drift',
|
|
62
|
-
'/explain',
|
|
63
|
-
'/export',
|
|
64
|
-
'/help',
|
|
65
|
-
'/init',
|
|
66
|
-
'/k8s-ctx',
|
|
67
|
-
'/model',
|
|
68
|
-
'/models',
|
|
69
|
-
'/mode',
|
|
70
|
-
'/new',
|
|
71
|
-
'/plan',
|
|
72
|
-
'/profile',
|
|
73
|
-
'/redo',
|
|
74
|
-
'/rollback',
|
|
75
|
-
'/search',
|
|
76
|
-
'/sessions',
|
|
77
|
-
'/switch',
|
|
78
|
-
'/terminal',
|
|
79
|
-
'/tf-ws',
|
|
80
|
-
'/theme',
|
|
81
|
-
'/tools',
|
|
82
|
-
'/tree',
|
|
83
|
-
'/undo',
|
|
84
|
-
'/watch',
|
|
85
|
-
'/workspace',
|
|
86
|
-
];
|
|
87
|
-
|
|
88
|
-
/** L1: Known subagent names for @agent completions. */
|
|
89
|
-
const AGENT_NAMES = ['explore', 'infra', 'security', 'cost', 'general'];
|
|
90
|
-
|
|
91
|
-
/** Props accepted by the InputBox component. */
|
|
92
|
-
export interface InputBoxProps {
|
|
93
|
-
/** Called when the user presses Enter with non-empty input. */
|
|
94
|
-
onSubmit: (text: string) => void;
|
|
95
|
-
/** Called when the user presses Escape to abort the current operation. */
|
|
96
|
-
onAbort?: () => void;
|
|
97
|
-
/** Placeholder text shown when the input is empty. */
|
|
98
|
-
placeholder?: string;
|
|
99
|
-
/** Whether the input is disabled (e.g. while the agent is processing). */
|
|
100
|
-
disabled?: boolean;
|
|
101
|
-
/** Current agent mode — controls prompt character and color (Gap 11). */
|
|
102
|
-
mode?: 'plan' | 'build' | 'deploy';
|
|
103
|
-
/** Called when the input line count changes (for StatusBar multi-line indicator). */
|
|
104
|
-
onLineCountChange?: (count: number) => void;
|
|
105
|
-
/** GAP-21: Pre-fill the input with this text (e.g. @filepath from TreePane). */
|
|
106
|
-
prefill?: string;
|
|
107
|
-
/** H3: Fetch dynamic completions for slash command arguments (e.g. /k8s-ctx, /tf-ws). */
|
|
108
|
-
onFetchCompletions?: (prefix: string) => Promise<string[]>;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* InputBox renders a ">" prompt followed by an editable text field.
|
|
113
|
-
* Pressing Enter submits the value and clears the field. Pressing Escape
|
|
114
|
-
* fires the optional onAbort callback. Up/Down arrows navigate history.
|
|
115
|
-
* Tab autocompletes slash commands. Ctrl+R opens reverse search.
|
|
116
|
-
*/
|
|
117
|
-
export function InputBox({ onSubmit, onAbort, placeholder, disabled = false, mode = 'build', onLineCountChange, prefill, onFetchCompletions }: InputBoxProps) {
|
|
118
|
-
const [value, setValue] = useState(prefill ?? '') as [string, React.Dispatch<React.SetStateAction<string>>];
|
|
119
|
-
// GAP-21: When prefill changes externally, update the input value
|
|
120
|
-
const prevPrefill = useRef(prefill);
|
|
121
|
-
if (prefill !== prevPrefill.current) {
|
|
122
|
-
prevPrefill.current = prefill;
|
|
123
|
-
if (prefill !== undefined) {
|
|
124
|
-
setValue(prefill);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// History: most recent entry is at the end (C1: loaded from disk)
|
|
129
|
-
const history = useRef<string[]>(loadHistory());
|
|
130
|
-
// -1 means "not browsing history" (showing current draft)
|
|
131
|
-
const historyIndex = useRef(-1);
|
|
132
|
-
// Stores the in-progress text before the user started browsing history
|
|
133
|
-
const draft = useRef('');
|
|
134
|
-
|
|
135
|
-
// C1: Persist history to disk on unmount
|
|
136
|
-
useEffect(() => {
|
|
137
|
-
return () => {
|
|
138
|
-
saveHistory(history.current);
|
|
139
|
-
};
|
|
140
|
-
}, []);
|
|
141
|
-
|
|
142
|
-
// Slash command autocomplete state
|
|
143
|
-
const [slashHint, setSlashHint] = useState('');
|
|
144
|
-
const suggestionIndex = useRef(0);
|
|
145
|
-
const lastSuggestions = useRef<string[]>([]);
|
|
146
|
-
|
|
147
|
-
// @file completion state
|
|
148
|
-
const [fileSuggestions, setFileSuggestions] = useState<string[]>([]);
|
|
149
|
-
const [fileHint, setFileHint] = useState('');
|
|
150
|
-
const fileSuggestionIndex = useRef(0);
|
|
151
|
-
|
|
152
|
-
// H3: Dynamic completions for slash command arguments
|
|
153
|
-
const [dynamicSuggestions, setDynamicSuggestions] = useState<string[]>([]);
|
|
154
|
-
const [dynamicHint, setDynamicHint] = useState('');
|
|
155
|
-
const dynamicSuggestionIndex = useRef(0);
|
|
156
|
-
// Cache: prefix → {items, ts}
|
|
157
|
-
const dynamicCache = useRef<Map<string, { items: string[]; ts: number }>>(new Map());
|
|
158
|
-
|
|
159
|
-
// Ctrl+R search mode
|
|
160
|
-
const [searchMode, setSearchMode] = useState(false);
|
|
161
|
-
const [searchQuery, setSearchQuery] = useState('');
|
|
162
|
-
const [searchResults, setSearchResults] = useState<string[]>([]);
|
|
163
|
-
|
|
164
|
-
const handleSubmit = useCallback(
|
|
165
|
-
(submitted: string) => {
|
|
166
|
-
const trimmed = submitted.trim();
|
|
167
|
-
if (trimmed.length === 0) {
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
onSubmit(trimmed);
|
|
171
|
-
|
|
172
|
-
// Add to history (avoid consecutive duplicates)
|
|
173
|
-
const h = history.current;
|
|
174
|
-
if (h.length === 0 || h[h.length - 1] !== trimmed) {
|
|
175
|
-
h.push(trimmed);
|
|
176
|
-
if (h.length > MAX_HISTORY) {
|
|
177
|
-
h.shift();
|
|
178
|
-
}
|
|
179
|
-
// C1: Persist to disk on every new entry
|
|
180
|
-
saveHistory(h);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Reset history navigation
|
|
184
|
-
historyIndex.current = -1;
|
|
185
|
-
draft.current = '';
|
|
186
|
-
setValue('');
|
|
187
|
-
setSlashHint('');
|
|
188
|
-
},
|
|
189
|
-
[onSubmit]
|
|
190
|
-
);
|
|
191
|
-
|
|
192
|
-
// Handle Escape, Up/Down arrows, Tab autocomplete, Ctrl+R
|
|
193
|
-
useInput(
|
|
194
|
-
(input, key) => {
|
|
195
|
-
// --- Ctrl+E: open $EDITOR for multi-line input composition (Gap 3) ---
|
|
196
|
-
if (input === 'e' && key.ctrl) {
|
|
197
|
-
const editor = process.env.EDITOR ?? process.env.VISUAL ?? 'nano';
|
|
198
|
-
const tmpFile = `/tmp/nimbus-input-${Date.now()}.md`;
|
|
199
|
-
try {
|
|
200
|
-
writeFileSync(tmpFile, value, 'utf-8');
|
|
201
|
-
spawnSync(editor, [tmpFile], { stdio: 'inherit' });
|
|
202
|
-
const edited = readFileSync(tmpFile, 'utf-8');
|
|
203
|
-
try { unlinkSync(tmpFile); } catch { /* ignore */ }
|
|
204
|
-
setValue(edited);
|
|
205
|
-
} catch {
|
|
206
|
-
/* editor not available — ignore */
|
|
207
|
-
}
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// --- Ctrl+R: toggle search mode ---
|
|
212
|
-
if (input === 'r' && key.ctrl) {
|
|
213
|
-
if (!searchMode) {
|
|
214
|
-
setSearchMode(true);
|
|
215
|
-
setSearchQuery('');
|
|
216
|
-
setSearchResults([]);
|
|
217
|
-
} else {
|
|
218
|
-
setSearchMode(false);
|
|
219
|
-
}
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// --- Search mode key handling ---
|
|
224
|
-
if (searchMode) {
|
|
225
|
-
if (key.escape) {
|
|
226
|
-
setSearchMode(false);
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
if (key.return) {
|
|
230
|
-
// Select top result
|
|
231
|
-
if (searchResults.length > 0) {
|
|
232
|
-
setValue(searchResults[0]);
|
|
233
|
-
}
|
|
234
|
-
setSearchMode(false);
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
// Let the search TextInput handle other keys
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (key.escape && onAbort) {
|
|
242
|
-
onAbort();
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// --- Tab: autocomplete ---
|
|
247
|
-
if (key.tab) {
|
|
248
|
-
// @file completion
|
|
249
|
-
const atMatch = value.match(/@(\S*)$/);
|
|
250
|
-
if (atMatch && fileSuggestions.length > 0) {
|
|
251
|
-
const idx = fileSuggestionIndex.current % fileSuggestions.length;
|
|
252
|
-
const replacement = `${value.slice(0, value.length - atMatch[0].length)}@${fileSuggestions[idx]}`;
|
|
253
|
-
setValue(replacement);
|
|
254
|
-
fileSuggestionIndex.current = idx + 1;
|
|
255
|
-
setFileHint(`[${fileSuggestions.length} files, Tab to cycle]`);
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// Slash command completion
|
|
260
|
-
if (value.startsWith('/')) {
|
|
261
|
-
// H3: Dynamic argument completions for /k8s-ctx, /tf-ws, /model, /profile
|
|
262
|
-
const dynamicPrefixes = ['/k8s-ctx ', '/tf-ws ', '/model ', '/profile '];
|
|
263
|
-
const dynMatch = dynamicPrefixes.find(p => value.startsWith(p));
|
|
264
|
-
if (dynMatch && onFetchCompletions) {
|
|
265
|
-
const partial = value.slice(dynMatch.length);
|
|
266
|
-
// Cycle through already-fetched suggestions
|
|
267
|
-
if (dynamicSuggestions.length > 0) {
|
|
268
|
-
const filtered = partial ? dynamicSuggestions.filter(s => s.startsWith(partial)) : dynamicSuggestions;
|
|
269
|
-
if (filtered.length > 0) {
|
|
270
|
-
const idx = dynamicSuggestionIndex.current % filtered.length;
|
|
271
|
-
setValue(`${dynMatch}${filtered[idx]}`);
|
|
272
|
-
dynamicSuggestionIndex.current = idx + 1;
|
|
273
|
-
setDynamicHint(`[${filtered.length} options, Tab to cycle]`);
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
// Fetch completions (non-blocking, cache 30s)
|
|
278
|
-
const cacheKey = dynMatch;
|
|
279
|
-
const cached = dynamicCache.current.get(cacheKey);
|
|
280
|
-
const CACHE_TTL = 30_000;
|
|
281
|
-
if (!cached || Date.now() - cached.ts > CACHE_TTL) {
|
|
282
|
-
onFetchCompletions(value).then(items => {
|
|
283
|
-
dynamicCache.current.set(cacheKey, { items, ts: Date.now() });
|
|
284
|
-
setDynamicSuggestions(items);
|
|
285
|
-
dynamicSuggestionIndex.current = 0;
|
|
286
|
-
if (items.length > 0) {
|
|
287
|
-
setValue(`${dynMatch}${items[0]}`);
|
|
288
|
-
setDynamicHint(`[${items.length} options, Tab to cycle]`);
|
|
289
|
-
}
|
|
290
|
-
}).catch(() => { /* ignore */ });
|
|
291
|
-
} else {
|
|
292
|
-
setDynamicSuggestions(cached.items);
|
|
293
|
-
dynamicSuggestionIndex.current = 0;
|
|
294
|
-
}
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
const prefix = value.toLowerCase();
|
|
299
|
-
const matches = SLASH_COMMANDS.filter(cmd => cmd.startsWith(prefix));
|
|
300
|
-
if (matches.length === 0) {
|
|
301
|
-
setSlashHint('');
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
if (matches.length === 1) {
|
|
305
|
-
setValue(`${matches[0]} `);
|
|
306
|
-
setSlashHint('');
|
|
307
|
-
lastSuggestions.current = [];
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
// Multiple matches: cycle through them
|
|
311
|
-
if (
|
|
312
|
-
lastSuggestions.current.length === matches.length &&
|
|
313
|
-
lastSuggestions.current.every((s, i) => s === matches[i])
|
|
314
|
-
) {
|
|
315
|
-
suggestionIndex.current = (suggestionIndex.current + 1) % matches.length;
|
|
316
|
-
} else {
|
|
317
|
-
lastSuggestions.current = matches;
|
|
318
|
-
suggestionIndex.current = 0;
|
|
319
|
-
}
|
|
320
|
-
setValue(matches[suggestionIndex.current]);
|
|
321
|
-
setSlashHint(`[${matches.length} matches, Tab to cycle]`);
|
|
322
|
-
}
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
const h = history.current;
|
|
327
|
-
if (h.length === 0) {
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
if (key.upArrow) {
|
|
332
|
-
if (historyIndex.current === -1) {
|
|
333
|
-
// Starting to browse: save current draft
|
|
334
|
-
draft.current = value;
|
|
335
|
-
historyIndex.current = h.length - 1;
|
|
336
|
-
} else if (historyIndex.current > 0) {
|
|
337
|
-
historyIndex.current--;
|
|
338
|
-
}
|
|
339
|
-
setValue(h[historyIndex.current]);
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
if (key.downArrow) {
|
|
344
|
-
if (historyIndex.current === -1) {
|
|
345
|
-
return;
|
|
346
|
-
} // not browsing
|
|
347
|
-
|
|
348
|
-
if (historyIndex.current < h.length - 1) {
|
|
349
|
-
historyIndex.current++;
|
|
350
|
-
setValue(h[historyIndex.current]);
|
|
351
|
-
} else {
|
|
352
|
-
// Past the end of history: restore draft
|
|
353
|
-
historyIndex.current = -1;
|
|
354
|
-
setValue(draft.current);
|
|
355
|
-
}
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
},
|
|
359
|
-
{ isActive: !disabled }
|
|
360
|
-
);
|
|
361
|
-
|
|
362
|
-
// Count lines for multi-line paste indicator
|
|
363
|
-
const lineCount = value.split('\n').length;
|
|
364
|
-
const isMultiLine = lineCount > 1;
|
|
365
|
-
|
|
366
|
-
if (disabled) {
|
|
367
|
-
return (
|
|
368
|
-
<Box paddingX={1}>
|
|
369
|
-
<Text dimColor>{'> '}</Text>
|
|
370
|
-
<Text dimColor italic>
|
|
371
|
-
{placeholder ?? 'waiting...'}
|
|
372
|
-
</Text>
|
|
373
|
-
</Box>
|
|
374
|
-
);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
// --- Search mode UI ---
|
|
378
|
-
if (searchMode) {
|
|
379
|
-
return (
|
|
380
|
-
<Box flexDirection="column" paddingX={1}>
|
|
381
|
-
<Box>
|
|
382
|
-
<Text color="yellow">{'(reverse-search): '}</Text>
|
|
383
|
-
<TextInput
|
|
384
|
-
value={searchQuery}
|
|
385
|
-
onChange={q => {
|
|
386
|
-
setSearchQuery(q);
|
|
387
|
-
if (q.length > 0) {
|
|
388
|
-
const results = history.current
|
|
389
|
-
.filter(entry => entry.toLowerCase().includes(q.toLowerCase()))
|
|
390
|
-
.reverse()
|
|
391
|
-
.slice(0, 10);
|
|
392
|
-
setSearchResults(results);
|
|
393
|
-
} else {
|
|
394
|
-
setSearchResults([]);
|
|
395
|
-
}
|
|
396
|
-
}}
|
|
397
|
-
onSubmit={() => {
|
|
398
|
-
if (searchResults.length > 0) {
|
|
399
|
-
setValue(searchResults[0]);
|
|
400
|
-
}
|
|
401
|
-
setSearchMode(false);
|
|
402
|
-
}}
|
|
403
|
-
placeholder="type to search history..."
|
|
404
|
-
/>
|
|
405
|
-
</Box>
|
|
406
|
-
{searchResults.length > 0 && (
|
|
407
|
-
<Box flexDirection="column" marginLeft={2}>
|
|
408
|
-
{searchResults.slice(0, 5).map((result, i) => (
|
|
409
|
-
<Text key={i} dimColor={i > 0}>
|
|
410
|
-
{i === 0 ? '> ' : ' '}
|
|
411
|
-
{result.length > 80 ? `${result.slice(0, 77)}...` : result}
|
|
412
|
-
</Text>
|
|
413
|
-
))}
|
|
414
|
-
{searchResults.length > 5 && (
|
|
415
|
-
<Text dimColor italic>
|
|
416
|
-
{' '}
|
|
417
|
-
... {searchResults.length - 5} more
|
|
418
|
-
</Text>
|
|
419
|
-
)}
|
|
420
|
-
</Box>
|
|
421
|
-
)}
|
|
422
|
-
</Box>
|
|
423
|
-
);
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
// Gap 11: mode-specific prompt character and color
|
|
427
|
-
const promptLabel = mode === 'plan' ? '[plan]> ' : mode === 'deploy' ? '[DEPLOY]> ' : '[build]> ';
|
|
428
|
-
const promptColor = mode === 'plan' ? 'blue' : mode === 'deploy' ? 'red' : 'green';
|
|
429
|
-
|
|
430
|
-
// --- Normal input UI ---
|
|
431
|
-
return (
|
|
432
|
-
<Box paddingX={1}>
|
|
433
|
-
<Text bold color={promptColor}>
|
|
434
|
-
{promptLabel}
|
|
435
|
-
</Text>
|
|
436
|
-
<TextInput
|
|
437
|
-
value={value}
|
|
438
|
-
onChange={v => {
|
|
439
|
-
// L2: Guard against large paste (>10KB) which would freeze the Ink UI
|
|
440
|
-
const safeV = v.length > 10_000 ? v.slice(0, 10_000) : v;
|
|
441
|
-
setValue(safeV);
|
|
442
|
-
onLineCountChange?.(safeV.split('\n').length);
|
|
443
|
-
// If user types while browsing history, exit history mode
|
|
444
|
-
if (historyIndex.current !== -1) {
|
|
445
|
-
historyIndex.current = -1;
|
|
446
|
-
}
|
|
447
|
-
// Reset slash autocomplete on any change
|
|
448
|
-
if (!v.startsWith('/')) {
|
|
449
|
-
setSlashHint('');
|
|
450
|
-
lastSuggestions.current = [];
|
|
451
|
-
}
|
|
452
|
-
// @file / @agent mention detection
|
|
453
|
-
const atMatch = v.match(/@(\S*)$/);
|
|
454
|
-
if (atMatch) {
|
|
455
|
-
const partial = atMatch[1];
|
|
456
|
-
// L1: Try agent names first
|
|
457
|
-
const agentMatches = AGENT_NAMES.filter(a => a.startsWith(partial.toLowerCase()));
|
|
458
|
-
if (agentMatches.length > 0 && partial.length > 0) {
|
|
459
|
-
setFileSuggestions(agentMatches.map(a => `@${a} `));
|
|
460
|
-
fileSuggestionIndex.current = 0;
|
|
461
|
-
setFileHint(`[${agentMatches.length} agent${agentMatches.length > 1 ? 's' : ''}, Tab to complete]`);
|
|
462
|
-
} else {
|
|
463
|
-
try {
|
|
464
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
465
|
-
const fs = require('node:fs');
|
|
466
|
-
const cwd = process.cwd();
|
|
467
|
-
const entries = fs.readdirSync(cwd, { withFileTypes: true });
|
|
468
|
-
const matches = (entries as Array<{ name: string; isDirectory(): boolean }>)
|
|
469
|
-
.filter(
|
|
470
|
-
e =>
|
|
471
|
-
!e.name.startsWith('.') && e.name.toLowerCase().includes(partial.toLowerCase())
|
|
472
|
-
)
|
|
473
|
-
.map(e => (e.isDirectory() ? `${e.name}/` : e.name))
|
|
474
|
-
.slice(0, 10);
|
|
475
|
-
setFileSuggestions(matches);
|
|
476
|
-
fileSuggestionIndex.current = 0;
|
|
477
|
-
if (matches.length > 0) {
|
|
478
|
-
setFileHint(`[${matches.length} files, Tab to complete]`);
|
|
479
|
-
} else {
|
|
480
|
-
setFileHint('');
|
|
481
|
-
}
|
|
482
|
-
} catch {
|
|
483
|
-
setFileSuggestions([]);
|
|
484
|
-
setFileHint('');
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
} else {
|
|
488
|
-
if (fileSuggestions.length > 0) {
|
|
489
|
-
setFileSuggestions([]);
|
|
490
|
-
setFileHint('');
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
}}
|
|
494
|
-
onSubmit={handleSubmit}
|
|
495
|
-
placeholder={placeholder ?? 'Type a DevOps command... (e.g. "terraform plan", "check pods", "list releases")'}
|
|
496
|
-
/>
|
|
497
|
-
{isMultiLine && <Text color="cyan">{` [${lineCount} lines]`}</Text>}
|
|
498
|
-
{slashHint && <Text dimColor>{` ${slashHint}`}</Text>}
|
|
499
|
-
{fileHint && <Text dimColor>{` ${fileHint}`}</Text>}
|
|
500
|
-
{dynamicHint && <Text dimColor>{` ${dynamicHint}`}</Text>}
|
|
501
|
-
</Box>
|
|
502
|
-
);
|
|
503
|
-
}
|