@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
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PermissionPrompt Component
|
|
3
|
-
*
|
|
4
|
-
* Modal-style overlay that asks the user to approve or reject a tool
|
|
5
|
-
* invocation before it executes. Displays the tool name, its input
|
|
6
|
-
* parameters, and a risk-level indicator.
|
|
7
|
-
*
|
|
8
|
-
* Keyboard shortcuts:
|
|
9
|
-
* a - Approve this invocation
|
|
10
|
-
* r - Reject this invocation
|
|
11
|
-
* A - Approve all invocations for this tool
|
|
12
|
-
* s - Approve for the remainder of this session
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import React, { useState } from 'react';
|
|
16
|
-
import { Box, Text, useInput } from 'ink';
|
|
17
|
-
|
|
18
|
-
/** The four possible decisions the user can make. */
|
|
19
|
-
export type PermissionDecision = 'approve' | 'reject' | 'approve_all' | 'session';
|
|
20
|
-
|
|
21
|
-
/** Risk level categorisation for a tool invocation. */
|
|
22
|
-
export type RiskLevel = 'low' | 'medium' | 'high' | 'critical';
|
|
23
|
-
|
|
24
|
-
/** Props accepted by the PermissionPrompt component. */
|
|
25
|
-
export interface PermissionPromptProps {
|
|
26
|
-
/** Name of the tool requesting permission. */
|
|
27
|
-
toolName: string;
|
|
28
|
-
/** The parameters that will be passed to the tool. */
|
|
29
|
-
toolInput: Record<string, unknown>;
|
|
30
|
-
/** Risk assessment for this invocation. */
|
|
31
|
-
riskLevel: RiskLevel;
|
|
32
|
-
/** Called with the user's decision. */
|
|
33
|
-
onDecide: (decision: PermissionDecision) => void;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/** Map risk levels to display colours. */
|
|
37
|
-
const RISK_COLORS: Record<RiskLevel, string> = {
|
|
38
|
-
low: 'green',
|
|
39
|
-
medium: 'yellow',
|
|
40
|
-
high: 'red',
|
|
41
|
-
critical: 'magenta',
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
/** H4: Human-readable descriptions of each risk tier. */
|
|
45
|
-
const RISK_DESCRIPTIONS: Record<RiskLevel, string> = {
|
|
46
|
-
low: 'Read-only — safe to auto-approve',
|
|
47
|
-
medium: 'Modifies local files — review before approving',
|
|
48
|
-
high: 'System or cloud operation — approve with caution',
|
|
49
|
-
critical: 'Destructive or irreversible — explicit confirmation required',
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Format tool input into a list of truncated key=value lines.
|
|
54
|
-
*/
|
|
55
|
-
function formatInput(input: Record<string, unknown>, maxEntries = 6): string[] {
|
|
56
|
-
return Object.entries(input)
|
|
57
|
-
.slice(0, maxEntries)
|
|
58
|
-
.map(([key, value]) => {
|
|
59
|
-
const str = typeof value === 'string' ? value : JSON.stringify(value);
|
|
60
|
-
const truncated = str.length > 80 ? `${str.slice(0, 77)}...` : str;
|
|
61
|
-
return `${key}: ${truncated}`;
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* PermissionPrompt renders a bordered box with tool information and waits for
|
|
67
|
-
* a single keypress to determine the user's decision.
|
|
68
|
-
*/
|
|
69
|
-
export function PermissionPrompt({
|
|
70
|
-
toolName,
|
|
71
|
-
toolInput,
|
|
72
|
-
riskLevel,
|
|
73
|
-
onDecide,
|
|
74
|
-
}: PermissionPromptProps) {
|
|
75
|
-
const [pressed, setPressed] = useState<string | null>(null);
|
|
76
|
-
|
|
77
|
-
useInput(input => {
|
|
78
|
-
switch (input) {
|
|
79
|
-
case 'a':
|
|
80
|
-
setPressed('a');
|
|
81
|
-
onDecide('approve');
|
|
82
|
-
break;
|
|
83
|
-
case 'r':
|
|
84
|
-
setPressed('r');
|
|
85
|
-
onDecide('reject');
|
|
86
|
-
break;
|
|
87
|
-
case 'A':
|
|
88
|
-
setPressed('A');
|
|
89
|
-
onDecide('approve_all');
|
|
90
|
-
break;
|
|
91
|
-
case 's':
|
|
92
|
-
setPressed('s');
|
|
93
|
-
onDecide('session');
|
|
94
|
-
break;
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
const inputLines = formatInput(toolInput);
|
|
99
|
-
const riskColor = RISK_COLORS[riskLevel];
|
|
100
|
-
|
|
101
|
-
return (
|
|
102
|
-
<Box
|
|
103
|
-
flexDirection="column"
|
|
104
|
-
borderStyle="double"
|
|
105
|
-
borderColor={riskColor}
|
|
106
|
-
paddingX={1}
|
|
107
|
-
paddingY={1}
|
|
108
|
-
>
|
|
109
|
-
{/* Title bar */}
|
|
110
|
-
<Box marginBottom={1}>
|
|
111
|
-
<Text bold color="yellow">
|
|
112
|
-
Permission Required
|
|
113
|
-
</Text>
|
|
114
|
-
</Box>
|
|
115
|
-
|
|
116
|
-
{/* Tool name */}
|
|
117
|
-
<Box>
|
|
118
|
-
<Text dimColor>Tool: </Text>
|
|
119
|
-
<Text bold>{toolName}</Text>
|
|
120
|
-
</Box>
|
|
121
|
-
|
|
122
|
-
{/* Risk level */}
|
|
123
|
-
<Box>
|
|
124
|
-
<Text dimColor>Risk: </Text>
|
|
125
|
-
<Text bold color={riskColor}>
|
|
126
|
-
{riskLevel.toUpperCase()}
|
|
127
|
-
</Text>
|
|
128
|
-
</Box>
|
|
129
|
-
{/* H4: Risk description */}
|
|
130
|
-
<Box marginBottom={1}>
|
|
131
|
-
<Text dimColor>{RISK_DESCRIPTIONS[riskLevel]}</Text>
|
|
132
|
-
</Box>
|
|
133
|
-
|
|
134
|
-
{/* Parameters */}
|
|
135
|
-
<Box flexDirection="column" marginBottom={1}>
|
|
136
|
-
<Text dimColor>Parameters:</Text>
|
|
137
|
-
{inputLines.map((line, idx) => (
|
|
138
|
-
<Text key={idx}> {line}</Text>
|
|
139
|
-
))}
|
|
140
|
-
</Box>
|
|
141
|
-
|
|
142
|
-
{/* Action keys */}
|
|
143
|
-
<Box>
|
|
144
|
-
<Text color="green" bold inverse={pressed === 'a'}>
|
|
145
|
-
[a]
|
|
146
|
-
</Text>
|
|
147
|
-
<Text>=approve </Text>
|
|
148
|
-
<Text color="red" bold inverse={pressed === 'r'}>
|
|
149
|
-
[r]
|
|
150
|
-
</Text>
|
|
151
|
-
<Text>=reject </Text>
|
|
152
|
-
<Text color="cyan" bold inverse={pressed === 'A'}>
|
|
153
|
-
[A]
|
|
154
|
-
</Text>
|
|
155
|
-
<Text>=approve-all-session </Text>
|
|
156
|
-
<Text color="blue" bold inverse={pressed === 's'}>
|
|
157
|
-
[s]
|
|
158
|
-
</Text>
|
|
159
|
-
<Text>=approve-this-tool-session</Text>
|
|
160
|
-
</Box>
|
|
161
|
-
</Box>
|
|
162
|
-
);
|
|
163
|
-
}
|
package/src/ui/StatusBar.tsx
DELETED
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* StatusBar Component
|
|
3
|
-
*
|
|
4
|
-
* A single-line footer that shows the active agent mode, token usage with a
|
|
5
|
-
* percentage bar, estimated cost, snapshot count, and elapsed processing time.
|
|
6
|
-
*
|
|
7
|
-
* Layout:
|
|
8
|
-
* [Plan] [Build] [Deploy] | Tokens: 45.2k/200k (22%) | Cost: $0.03 | Snapshots: 3 (undo) | tf:default | k8s:prod-cluster | delta:+$1.20 | 12s
|
|
9
|
-
*
|
|
10
|
-
* Token percentage colour:
|
|
11
|
-
* green < 50%
|
|
12
|
-
* yellow 50-80%
|
|
13
|
-
* red > 80%
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import React, { useState, useEffect, useRef } from 'react';
|
|
17
|
-
import { Box, Text } from 'ink';
|
|
18
|
-
import type { SessionInfo, AgentMode } from './types';
|
|
19
|
-
|
|
20
|
-
/** Props accepted by the StatusBar component. */
|
|
21
|
-
export interface StatusBarProps {
|
|
22
|
-
session: SessionInfo;
|
|
23
|
-
/** Whether the agent is currently processing a request. */
|
|
24
|
-
isProcessing?: boolean;
|
|
25
|
-
/** Timestamp (Date.now()) when processing started. Null when idle. */
|
|
26
|
-
processingStartTime?: number | null;
|
|
27
|
-
/** Number of lines in the current input (Gap 9 — multi-line indicator). */
|
|
28
|
-
inputLineCount?: number;
|
|
29
|
-
/** C1: Show scroll hint when the user has scrolled away from the bottom. */
|
|
30
|
-
showScrollHint?: boolean;
|
|
31
|
-
/** H1: Toast message shown after copying a code block to clipboard. */
|
|
32
|
-
copyToast?: string;
|
|
33
|
-
/** Show "Esc to stop" hint when a log stream is active. */
|
|
34
|
-
showStreamingHint?: boolean;
|
|
35
|
-
/** H5: Mode change toast — shown for 2 seconds after Tab cycle. */
|
|
36
|
-
modeToast?: string;
|
|
37
|
-
/** M1: Active search query (shows "Search: N results" when set). */
|
|
38
|
-
searchQuery?: string;
|
|
39
|
-
/** M1: Number of messages matching the current search. */
|
|
40
|
-
searchResultCount?: number;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/** All modes in display order. */
|
|
44
|
-
const MODES: AgentMode[] = ['plan', 'build', 'deploy'];
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Format a token count into a human-readable string (e.g. 45200 -> "45.2k").
|
|
48
|
-
*/
|
|
49
|
-
function formatTokens(count: number): string {
|
|
50
|
-
if (count >= 1_000_000) {
|
|
51
|
-
return `${(count / 1_000_000).toFixed(1)}M`;
|
|
52
|
-
}
|
|
53
|
-
if (count >= 1_000) {
|
|
54
|
-
return `${(count / 1_000).toFixed(1)}k`;
|
|
55
|
-
}
|
|
56
|
-
return String(count);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Pick the colour for the token percentage indicator.
|
|
61
|
-
*/
|
|
62
|
-
function tokenColor(pct: number): string {
|
|
63
|
-
if (pct > 80) {
|
|
64
|
-
return 'red';
|
|
65
|
-
}
|
|
66
|
-
if (pct >= 50) {
|
|
67
|
-
return 'yellow';
|
|
68
|
-
}
|
|
69
|
-
return 'green';
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Determine if an environment name is production-like (G1).
|
|
74
|
-
*/
|
|
75
|
-
function isProdEnvironment(name: string): boolean {
|
|
76
|
-
return /prod|production|live/i.test(name);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* A single mode badge. The active mode is rendered with inverse styling.
|
|
81
|
-
*/
|
|
82
|
-
function ModeBadge({ mode, active }: { mode: AgentMode; active: boolean }) {
|
|
83
|
-
const label = ` ${mode.charAt(0).toUpperCase() + mode.slice(1)} `;
|
|
84
|
-
|
|
85
|
-
if (active) {
|
|
86
|
-
return (
|
|
87
|
-
<Text bold inverse>
|
|
88
|
-
{label}
|
|
89
|
-
</Text>
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return <Text dimColor>{label}</Text>;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* StatusBar renders the bottom status line of the TUI.
|
|
98
|
-
*/
|
|
99
|
-
export function StatusBar({
|
|
100
|
-
session,
|
|
101
|
-
isProcessing = false,
|
|
102
|
-
processingStartTime = null,
|
|
103
|
-
inputLineCount = 1,
|
|
104
|
-
showScrollHint = false,
|
|
105
|
-
copyToast = '',
|
|
106
|
-
showStreamingHint = false,
|
|
107
|
-
modeToast,
|
|
108
|
-
searchQuery,
|
|
109
|
-
searchResultCount,
|
|
110
|
-
}: StatusBarProps) {
|
|
111
|
-
const pct =
|
|
112
|
-
session.maxTokens > 0 ? Math.round((session.tokenCount / session.maxTokens) * 100) : 0;
|
|
113
|
-
const pctColor = tokenColor(pct);
|
|
114
|
-
const costStr =
|
|
115
|
-
session.costUSD < 0.01 && session.costUSD > 0
|
|
116
|
-
? `$${session.costUSD.toFixed(4)}`
|
|
117
|
-
: `$${session.costUSD.toFixed(2)}`;
|
|
118
|
-
|
|
119
|
-
// Elapsed time counter
|
|
120
|
-
const [elapsedSeconds, setElapsedSeconds] = useState(0);
|
|
121
|
-
const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
|
122
|
-
|
|
123
|
-
useEffect(() => {
|
|
124
|
-
if (isProcessing && processingStartTime) {
|
|
125
|
-
// Immediately calculate current elapsed
|
|
126
|
-
setElapsedSeconds(Math.floor((Date.now() - processingStartTime) / 1000));
|
|
127
|
-
|
|
128
|
-
intervalRef.current = setInterval(() => {
|
|
129
|
-
setElapsedSeconds(Math.floor((Date.now() - processingStartTime) / 1000));
|
|
130
|
-
}, 1000);
|
|
131
|
-
|
|
132
|
-
return () => {
|
|
133
|
-
if (intervalRef.current) {
|
|
134
|
-
clearInterval(intervalRef.current);
|
|
135
|
-
}
|
|
136
|
-
};
|
|
137
|
-
} else {
|
|
138
|
-
setElapsedSeconds(0);
|
|
139
|
-
if (intervalRef.current) {
|
|
140
|
-
clearInterval(intervalRef.current);
|
|
141
|
-
intervalRef.current = null;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}, [isProcessing, processingStartTime]);
|
|
145
|
-
|
|
146
|
-
// Snapshot display: show undo hint when snapshots exist (G19)
|
|
147
|
-
const snapshotDisplay = session.snapshotCount > 0
|
|
148
|
-
? `${session.snapshotCount} (↶ undo)`
|
|
149
|
-
: String(session.snapshotCount);
|
|
150
|
-
|
|
151
|
-
// Infra context colors (G1)
|
|
152
|
-
const tfColor = session.terraformWorkspace && isProdEnvironment(session.terraformWorkspace)
|
|
153
|
-
? 'yellow'
|
|
154
|
-
: 'green';
|
|
155
|
-
const k8sColor = session.kubectlContext && isProdEnvironment(session.kubectlContext)
|
|
156
|
-
? 'yellow'
|
|
157
|
-
: 'green';
|
|
158
|
-
|
|
159
|
-
// L5: Build a compact visual progress bar for context budget
|
|
160
|
-
const BAR_WIDTH = 8;
|
|
161
|
-
const filledBars = Math.round((pct / 100) * BAR_WIDTH);
|
|
162
|
-
const progressBar = '█'.repeat(filledBars) + '░'.repeat(BAR_WIDTH - filledBars);
|
|
163
|
-
|
|
164
|
-
return (
|
|
165
|
-
<Box
|
|
166
|
-
borderStyle="single"
|
|
167
|
-
borderColor="gray"
|
|
168
|
-
paddingX={1}
|
|
169
|
-
justifyContent="space-between"
|
|
170
|
-
width="100%"
|
|
171
|
-
>
|
|
172
|
-
{/* Mode badges */}
|
|
173
|
-
<Box>
|
|
174
|
-
{MODES.map(m => (
|
|
175
|
-
<ModeBadge key={m} mode={m} active={m === session.mode} />
|
|
176
|
-
))}
|
|
177
|
-
</Box>
|
|
178
|
-
|
|
179
|
-
{/* Metrics + keyboard hints */}
|
|
180
|
-
<Box>
|
|
181
|
-
<Text dimColor>Ctx: </Text>
|
|
182
|
-
<Text color={pctColor}>{progressBar}</Text>
|
|
183
|
-
<Text dimColor> </Text>
|
|
184
|
-
<Text color={pctColor}>
|
|
185
|
-
{formatTokens(session.tokenCount)}/{formatTokens(session.maxTokens)} ({pct}%)
|
|
186
|
-
</Text>
|
|
187
|
-
<Text dimColor> | Cost: </Text>
|
|
188
|
-
<Text>{costStr}</Text>
|
|
189
|
-
<Text dimColor> | Snapshots: </Text>
|
|
190
|
-
<Text>{snapshotDisplay}</Text>
|
|
191
|
-
{/* G1: Terraform workspace display */}
|
|
192
|
-
{session.terraformWorkspace && (
|
|
193
|
-
<>
|
|
194
|
-
<Text dimColor> | </Text>
|
|
195
|
-
<Text color={tfColor}>tf:{session.terraformWorkspace}</Text>
|
|
196
|
-
</>
|
|
197
|
-
)}
|
|
198
|
-
{/* G1: kubectl context display */}
|
|
199
|
-
{session.kubectlContext && (
|
|
200
|
-
<>
|
|
201
|
-
<Text dimColor> | </Text>
|
|
202
|
-
<Text color={k8sColor}>k8s:{session.kubectlContext}</Text>
|
|
203
|
-
</>
|
|
204
|
-
)}
|
|
205
|
-
{/* G15: Infra cost delta display */}
|
|
206
|
-
{session.infraCostDelta && (
|
|
207
|
-
<>
|
|
208
|
-
<Text dimColor> | </Text>
|
|
209
|
-
<Text color="green">delta:{session.infraCostDelta}</Text>
|
|
210
|
-
</>
|
|
211
|
-
)}
|
|
212
|
-
{isProcessing && elapsedSeconds > 0 && (
|
|
213
|
-
<>
|
|
214
|
-
<Text dimColor> | </Text>
|
|
215
|
-
<Text color="cyan">{elapsedSeconds}s</Text>
|
|
216
|
-
</>
|
|
217
|
-
)}
|
|
218
|
-
{inputLineCount > 1 && !isProcessing && (
|
|
219
|
-
<>
|
|
220
|
-
<Text dimColor> | </Text>
|
|
221
|
-
<Text color="cyan">{inputLineCount} lines</Text>
|
|
222
|
-
</>
|
|
223
|
-
)}
|
|
224
|
-
<Text dimColor> | Tab</Text>
|
|
225
|
-
<Text dimColor>:mode </Text>
|
|
226
|
-
<Text dimColor>Esc</Text>
|
|
227
|
-
<Text dimColor>:cancel </Text>
|
|
228
|
-
<Text dimColor>^C</Text>
|
|
229
|
-
<Text dimColor>:exit</Text>
|
|
230
|
-
{/* C3: Discoverability hints when idle */}
|
|
231
|
-
{!isProcessing && inputLineCount <= 1 && (
|
|
232
|
-
<>
|
|
233
|
-
<Text dimColor> | </Text>
|
|
234
|
-
<Text dimColor>F1:help /tree /terminal</Text>
|
|
235
|
-
<Text dimColor> </Text>
|
|
236
|
-
<Text dimColor>? help</Text>
|
|
237
|
-
</>
|
|
238
|
-
)}
|
|
239
|
-
{/* C1: Scroll hint when user has scrolled away from bottom */}
|
|
240
|
-
{showScrollHint && (
|
|
241
|
-
<>
|
|
242
|
-
<Text dimColor> | </Text>
|
|
243
|
-
<Text color="cyan">↑↓ scroll | G bottom</Text>
|
|
244
|
-
</>
|
|
245
|
-
)}
|
|
246
|
-
{/* H1: Streaming tool indicator — show "Esc to stop" when a log stream is active */}
|
|
247
|
-
{showStreamingHint && (
|
|
248
|
-
<>
|
|
249
|
-
<Text dimColor> | </Text>
|
|
250
|
-
<Text color="cyan">Esc:stop stream</Text>
|
|
251
|
-
</>
|
|
252
|
-
)}
|
|
253
|
-
{/* H1: Copy toast message after copying a code block */}
|
|
254
|
-
{copyToast && (
|
|
255
|
-
<>
|
|
256
|
-
<Text dimColor> | </Text>
|
|
257
|
-
<Text color="green">{copyToast}</Text>
|
|
258
|
-
</>
|
|
259
|
-
)}
|
|
260
|
-
{/* H5: Mode change toast */}
|
|
261
|
-
{modeToast && (
|
|
262
|
-
<>
|
|
263
|
-
<Text dimColor> | </Text>
|
|
264
|
-
<Text color="cyan" italic>{modeToast}</Text>
|
|
265
|
-
</>
|
|
266
|
-
)}
|
|
267
|
-
{/* M1: Search result count */}
|
|
268
|
-
{searchQuery && searchResultCount !== undefined && (
|
|
269
|
-
<>
|
|
270
|
-
<Text dimColor> | </Text>
|
|
271
|
-
<Text color="yellow">Search: "{searchQuery}" — {searchResultCount} results</Text>
|
|
272
|
-
</>
|
|
273
|
-
)}
|
|
274
|
-
</Box>
|
|
275
|
-
</Box>
|
|
276
|
-
);
|
|
277
|
-
}
|
package/src/ui/TerminalPane.tsx
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TerminalPane Component (M1)
|
|
3
|
-
*
|
|
4
|
-
* Read-only tool output observation pane showing the last N lines from
|
|
5
|
-
* completed tool calls. Rendered alongside MessageList in a side-by-side
|
|
6
|
-
* layout when active. Toggle via /terminal slash command.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import React from 'react';
|
|
10
|
-
import { Box, Text } from 'ink';
|
|
11
|
-
import type { UIToolCall } from './types';
|
|
12
|
-
|
|
13
|
-
export interface TerminalPaneProps {
|
|
14
|
-
/** Tool calls to display output from. */
|
|
15
|
-
toolCalls: UIToolCall[];
|
|
16
|
-
/** Maximum number of output lines to show (default: 20). */
|
|
17
|
-
maxLines?: number;
|
|
18
|
-
/** Width percentage hint for layout (unused — parent controls width). */
|
|
19
|
-
width?: number;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* A scrollable pane showing the last tool outputs as a rolling buffer.
|
|
24
|
-
*/
|
|
25
|
-
export function TerminalPane({ toolCalls, maxLines = 20 }: TerminalPaneProps) {
|
|
26
|
-
// Collect lines from all tool calls (completed + running with streaming output)
|
|
27
|
-
const outputLines: Array<{ text: string; isError: boolean; toolName: string; live?: boolean }> = [];
|
|
28
|
-
|
|
29
|
-
for (const tc of toolCalls) {
|
|
30
|
-
if (tc.status === 'running') {
|
|
31
|
-
// Show live streaming output for in-progress tool calls (Gap 1)
|
|
32
|
-
const liveOutput = tc.streamingOutput ?? '(waiting for output...)';
|
|
33
|
-
const lines = liveOutput.split('\n').filter(l => l.length > 0);
|
|
34
|
-
for (const line of lines) {
|
|
35
|
-
outputLines.push({ text: line, isError: false, toolName: tc.name, live: true });
|
|
36
|
-
}
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
if (tc.status !== 'completed' && tc.status !== 'failed') continue;
|
|
40
|
-
const output = tc.result?.output ?? '';
|
|
41
|
-
const isError = tc.result?.isError ?? false;
|
|
42
|
-
const lines = output.split('\n').filter(l => l.length > 0);
|
|
43
|
-
for (const line of lines) {
|
|
44
|
-
outputLines.push({ text: line, isError, toolName: tc.name });
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Show only the last maxLines lines
|
|
49
|
-
const visible = outputLines.slice(-maxLines);
|
|
50
|
-
|
|
51
|
-
return (
|
|
52
|
-
<Box
|
|
53
|
-
flexDirection="column"
|
|
54
|
-
borderStyle="single"
|
|
55
|
-
borderColor="gray"
|
|
56
|
-
paddingX={1}
|
|
57
|
-
flexGrow={1}
|
|
58
|
-
overflow="hidden"
|
|
59
|
-
>
|
|
60
|
-
{/* Header */}
|
|
61
|
-
<Box marginBottom={1}>
|
|
62
|
-
<Text bold color="cyan">
|
|
63
|
-
Terminal Output
|
|
64
|
-
</Text>
|
|
65
|
-
<Text dimColor> (read-only · /terminal to toggle)</Text>
|
|
66
|
-
</Box>
|
|
67
|
-
|
|
68
|
-
{visible.length === 0 ? (
|
|
69
|
-
<Text dimColor italic>No tool output yet.</Text>
|
|
70
|
-
) : (
|
|
71
|
-
visible.map((line, i) => (
|
|
72
|
-
<Text
|
|
73
|
-
key={i}
|
|
74
|
-
color={line.isError ? 'red' : line.live ? 'cyan' : undefined}
|
|
75
|
-
dimColor={!line.isError && !line.live}
|
|
76
|
-
wrap="truncate"
|
|
77
|
-
>
|
|
78
|
-
{line.live ? '[>] ' : ''}{line.text}
|
|
79
|
-
</Text>
|
|
80
|
-
))
|
|
81
|
-
)}
|
|
82
|
-
</Box>
|
|
83
|
-
);
|
|
84
|
-
}
|