@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,229 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for src/generator/intent-parser.ts – IntentParser
|
|
3
|
-
*
|
|
4
|
-
* The IntentParser is instantiated WITHOUT an LLM router so every test
|
|
5
|
-
* exercises the deterministic heuristic (regex + keyword) path only.
|
|
6
|
-
* LLM-based classification requires live API keys and is therefore
|
|
7
|
-
* intentionally excluded from unit tests.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { describe, it, expect } from 'vitest';
|
|
11
|
-
import { IntentParser, type ConversationalIntent } from '../generator/intent-parser';
|
|
12
|
-
|
|
13
|
-
// Helper: create a parser in pure-heuristic mode (no router)
|
|
14
|
-
function makeParser(): IntentParser {
|
|
15
|
-
return new IntentParser();
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Helper: extract entities of a given type from a parsed result
|
|
19
|
-
function entitiesOfType(intent: ConversationalIntent, type: string): string[] {
|
|
20
|
-
return intent.entities.filter(e => e.type === type).map(e => e.value);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// ---------------------------------------------------------------------------
|
|
24
|
-
// Intent type detection
|
|
25
|
-
// ---------------------------------------------------------------------------
|
|
26
|
-
|
|
27
|
-
describe('IntentParser – generate intents', () => {
|
|
28
|
-
it('parse("create a vpc on aws") returns type: generate', async () => {
|
|
29
|
-
const parser = makeParser();
|
|
30
|
-
const result = await parser.parse('create a vpc on aws');
|
|
31
|
-
expect(result.type).toBe('generate');
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('parse("generate a helm chart") returns type: generate', async () => {
|
|
35
|
-
const parser = makeParser();
|
|
36
|
-
const result = await parser.parse('generate a helm chart');
|
|
37
|
-
expect(result.type).toBe('generate');
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('parse("build an eks cluster on aws") returns type: generate', async () => {
|
|
41
|
-
const parser = makeParser();
|
|
42
|
-
const result = await parser.parse('build an eks cluster on aws');
|
|
43
|
-
expect(result.type).toBe('generate');
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('parse("create a deployment") returns type: generate', async () => {
|
|
47
|
-
const parser = makeParser();
|
|
48
|
-
const result = await parser.parse('create a deployment');
|
|
49
|
-
expect(result.type).toBe('generate');
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('parse("setup an s3 bucket") returns type: generate', async () => {
|
|
53
|
-
const parser = makeParser();
|
|
54
|
-
const result = await parser.parse('setup an s3 bucket');
|
|
55
|
-
expect(result.type).toBe('generate');
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
describe('IntentParser – explain intents', () => {
|
|
60
|
-
it('parse("explain kubernetes") returns type: explain', async () => {
|
|
61
|
-
const parser = makeParser();
|
|
62
|
-
const result = await parser.parse('explain kubernetes');
|
|
63
|
-
expect(result.type).toBe('explain');
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it('parse("what is terraform") returns type: explain', async () => {
|
|
67
|
-
const parser = makeParser();
|
|
68
|
-
const result = await parser.parse('what is terraform');
|
|
69
|
-
expect(result.type).toBe('explain');
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('parse("describe a vpc") returns type: explain', async () => {
|
|
73
|
-
const parser = makeParser();
|
|
74
|
-
const result = await parser.parse('describe a vpc');
|
|
75
|
-
expect(result.type).toBe('explain');
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('parse("why should I use helm") returns type: explain', async () => {
|
|
79
|
-
const parser = makeParser();
|
|
80
|
-
const result = await parser.parse('why should I use helm');
|
|
81
|
-
expect(result.type).toBe('explain');
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
describe('IntentParser – help intents', () => {
|
|
86
|
-
it('parse("help") returns type: help', async () => {
|
|
87
|
-
const parser = makeParser();
|
|
88
|
-
const result = await parser.parse('help');
|
|
89
|
-
expect(result.type).toBe('help');
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('parse("what can you do") returns type: help', async () => {
|
|
93
|
-
const parser = makeParser();
|
|
94
|
-
const result = await parser.parse('what can you do');
|
|
95
|
-
expect(result.type).toBe('help');
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('parse("guide me through the process") returns type: help', async () => {
|
|
99
|
-
const parser = makeParser();
|
|
100
|
-
const result = await parser.parse('guide me through the process');
|
|
101
|
-
expect(result.type).toBe('help');
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
describe('IntentParser – unknown intents', () => {
|
|
106
|
-
it('parse("random gibberish qwerty xyz") returns type: unknown', async () => {
|
|
107
|
-
const parser = makeParser();
|
|
108
|
-
const result = await parser.parse('random gibberish qwerty xyz');
|
|
109
|
-
expect(result.type).toBe('unknown');
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
it('parse("xyzzy plugh foo bar baz") returns type: unknown', async () => {
|
|
113
|
-
const parser = makeParser();
|
|
114
|
-
const result = await parser.parse('xyzzy plugh foo bar baz');
|
|
115
|
-
expect(result.type).toBe('unknown');
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
describe('IntentParser – modify intents', () => {
|
|
120
|
-
it('parse("change the vpc") returns type: modify', async () => {
|
|
121
|
-
const parser = makeParser();
|
|
122
|
-
const result = await parser.parse('change the vpc');
|
|
123
|
-
expect(result.type).toBe('modify');
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it('parse("update the rds instance") returns type: modify', async () => {
|
|
127
|
-
const parser = makeParser();
|
|
128
|
-
const result = await parser.parse('update the rds instance');
|
|
129
|
-
expect(result.type).toBe('modify');
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
// ---------------------------------------------------------------------------
|
|
134
|
-
// Entity extraction
|
|
135
|
-
// ---------------------------------------------------------------------------
|
|
136
|
-
|
|
137
|
-
describe('IntentParser – entity extraction', () => {
|
|
138
|
-
it('parse("create a vpc on aws") extracts provider: aws', async () => {
|
|
139
|
-
const parser = makeParser();
|
|
140
|
-
const result = await parser.parse('create a vpc on aws');
|
|
141
|
-
const providers = entitiesOfType(result, 'provider');
|
|
142
|
-
expect(providers).toContain('aws');
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it('parse("create a vpc on aws") extracts component: vpc', async () => {
|
|
146
|
-
const parser = makeParser();
|
|
147
|
-
const result = await parser.parse('create a vpc on aws');
|
|
148
|
-
const components = entitiesOfType(result, 'component');
|
|
149
|
-
expect(components).toContain('vpc');
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it('parse("generate a helm chart") extracts generation_type: helm', async () => {
|
|
153
|
-
const parser = makeParser();
|
|
154
|
-
const result = await parser.parse('generate a helm chart');
|
|
155
|
-
const genTypes = entitiesOfType(result, 'generation_type');
|
|
156
|
-
expect(genTypes).toContain('helm');
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it('parse("create a deployment") extracts generation_type: kubernetes', async () => {
|
|
160
|
-
const parser = makeParser();
|
|
161
|
-
const result = await parser.parse('create a deployment');
|
|
162
|
-
const genTypes = entitiesOfType(result, 'generation_type');
|
|
163
|
-
expect(genTypes).toContain('kubernetes');
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
it('parse("deploy something on gcp") extracts provider: gcp', async () => {
|
|
167
|
-
const parser = makeParser();
|
|
168
|
-
const result = await parser.parse('deploy something on gcp');
|
|
169
|
-
const providers = entitiesOfType(result, 'provider');
|
|
170
|
-
expect(providers).toContain('gcp');
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
it('parse("provision infrastructure in us-east-1") extracts region entity', async () => {
|
|
174
|
-
const parser = makeParser();
|
|
175
|
-
const result = await parser.parse('provision infrastructure in us-east-1');
|
|
176
|
-
const regions = entitiesOfType(result, 'region');
|
|
177
|
-
expect(regions).toContain('us-east-1');
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
it('parse("provision eks for the production environment") extracts environment entity', async () => {
|
|
181
|
-
const parser = makeParser();
|
|
182
|
-
const result = await parser.parse('provision eks for the production environment');
|
|
183
|
-
const envs = entitiesOfType(result, 'environment');
|
|
184
|
-
// The parser normalises "production" to "production"
|
|
185
|
-
expect(envs.some(e => e.includes('production'))).toBe(true);
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
// ---------------------------------------------------------------------------
|
|
190
|
-
// Confidence
|
|
191
|
-
// ---------------------------------------------------------------------------
|
|
192
|
-
|
|
193
|
-
describe('IntentParser – confidence', () => {
|
|
194
|
-
it('returns confidence between 0 and 1 for any input', async () => {
|
|
195
|
-
const parser = makeParser();
|
|
196
|
-
const inputs = ['create a vpc on aws', 'explain kubernetes', 'help', 'random gibberish xyz'];
|
|
197
|
-
|
|
198
|
-
for (const input of inputs) {
|
|
199
|
-
const result = await parser.parse(input);
|
|
200
|
-
expect(result.confidence).toBeGreaterThanOrEqual(0);
|
|
201
|
-
expect(result.confidence).toBeLessThanOrEqual(1);
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
it('unknown intent has confidence 0', async () => {
|
|
206
|
-
const parser = makeParser();
|
|
207
|
-
const result = await parser.parse('xyzzy plugh aaabbbccc');
|
|
208
|
-
expect(result.confidence).toBe(0);
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
it('matched intents have confidence greater than 0', async () => {
|
|
212
|
-
const parser = makeParser();
|
|
213
|
-
const result = await parser.parse('create a vpc on aws');
|
|
214
|
-
expect(result.confidence).toBeGreaterThan(0);
|
|
215
|
-
});
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
// ---------------------------------------------------------------------------
|
|
219
|
-
// setRouter
|
|
220
|
-
// ---------------------------------------------------------------------------
|
|
221
|
-
|
|
222
|
-
describe('IntentParser – setRouter', () => {
|
|
223
|
-
it('setRouter() accepts a router without throwing', () => {
|
|
224
|
-
const parser = makeParser();
|
|
225
|
-
// Pass a minimal mock object; we only test that the setter accepts it
|
|
226
|
-
const mockRouter = {} as any;
|
|
227
|
-
expect(() => parser.setRouter(mockRouter)).not.toThrow();
|
|
228
|
-
});
|
|
229
|
-
});
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for the LLM router support modules:
|
|
3
|
-
* - src/llm/model-aliases.ts – resolveModelAlias, getAliases
|
|
4
|
-
* - src/llm/provider-registry.ts – detectProvider
|
|
5
|
-
* - src/llm/cost-calculator.ts – calculateCost, getPricingData
|
|
6
|
-
*
|
|
7
|
-
* The LLMRouter constructor itself requires a fully populated config with valid
|
|
8
|
-
* API keys and is therefore NOT exercised here. All tested functions are pure
|
|
9
|
-
* (no I/O, no network) and execute synchronously.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { describe, it, expect } from 'vitest';
|
|
13
|
-
import { resolveModelAlias, getAliases } from '../llm/model-aliases';
|
|
14
|
-
import { detectProvider } from '../llm/provider-registry';
|
|
15
|
-
import { calculateCost, getPricingData, type CostResult } from '../llm/cost-calculator';
|
|
16
|
-
|
|
17
|
-
// ---------------------------------------------------------------------------
|
|
18
|
-
// resolveModelAlias
|
|
19
|
-
// ---------------------------------------------------------------------------
|
|
20
|
-
|
|
21
|
-
describe('resolveModelAlias', () => {
|
|
22
|
-
it('resolves "sonnet" alias to the full Claude Sonnet model ID', () => {
|
|
23
|
-
const resolved = resolveModelAlias('sonnet');
|
|
24
|
-
expect(resolved).toBe('claude-sonnet-4-20250514');
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('resolves "haiku" alias to the full Claude Haiku model ID', () => {
|
|
28
|
-
const resolved = resolveModelAlias('haiku');
|
|
29
|
-
expect(resolved).toBe('claude-haiku-4-20250514');
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('resolves "opus" alias to the full Claude Opus model ID', () => {
|
|
33
|
-
expect(resolveModelAlias('opus')).toBe('claude-opus-4-20250514');
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('resolves "gpt4o" alias to "gpt-4o"', () => {
|
|
37
|
-
expect(resolveModelAlias('gpt4o')).toBe('gpt-4o');
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('resolves "gemini" alias to the Gemini Flash model ID', () => {
|
|
41
|
-
expect(resolveModelAlias('gemini')).toBe('gemini-2.0-flash-exp');
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('returns the original string when no alias match is found', () => {
|
|
45
|
-
const unknown = 'some-unknown-model-id';
|
|
46
|
-
expect(resolveModelAlias(unknown)).toBe(unknown);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('resolves aliases case-insensitively', () => {
|
|
50
|
-
expect(resolveModelAlias('SONNET')).toBe('claude-sonnet-4-20250514');
|
|
51
|
-
expect(resolveModelAlias('Haiku')).toBe('claude-haiku-4-20250514');
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('resolves "claude" alias to the default Claude model', () => {
|
|
55
|
-
expect(resolveModelAlias('claude')).toBe('claude-sonnet-4-20250514');
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
// ---------------------------------------------------------------------------
|
|
60
|
-
// getAliases
|
|
61
|
-
// ---------------------------------------------------------------------------
|
|
62
|
-
|
|
63
|
-
describe('getAliases', () => {
|
|
64
|
-
it('returns an object', () => {
|
|
65
|
-
const aliases = getAliases();
|
|
66
|
-
expect(typeof aliases).toBe('object');
|
|
67
|
-
expect(aliases).not.toBeNull();
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('includes the expected shortcut keys', () => {
|
|
71
|
-
const aliases = getAliases();
|
|
72
|
-
expect('sonnet' in aliases).toBe(true);
|
|
73
|
-
expect('haiku' in aliases).toBe(true);
|
|
74
|
-
expect('opus' in aliases).toBe(true);
|
|
75
|
-
expect('gpt4o' in aliases).toBe(true);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('returns a copy so mutation does not affect subsequent calls', () => {
|
|
79
|
-
const aliases = getAliases();
|
|
80
|
-
(aliases as any)['__test__'] = 'should-not-persist';
|
|
81
|
-
const aliases2 = getAliases();
|
|
82
|
-
expect('__test__' in aliases2).toBe(false);
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
// ---------------------------------------------------------------------------
|
|
87
|
-
// detectProvider
|
|
88
|
-
// ---------------------------------------------------------------------------
|
|
89
|
-
|
|
90
|
-
describe('detectProvider', () => {
|
|
91
|
-
it('detects anthropic for "claude-sonnet-4-20250514"', () => {
|
|
92
|
-
expect(detectProvider('claude-sonnet-4-20250514')).toBe('anthropic');
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it('detects openai for "gpt-4o"', () => {
|
|
96
|
-
expect(detectProvider('gpt-4o')).toBe('openai');
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it('detects google for "gemini-2.0-flash-exp"', () => {
|
|
100
|
-
expect(detectProvider('gemini-2.0-flash-exp')).toBe('google');
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('detects ollama for "llama3.2"', () => {
|
|
104
|
-
expect(detectProvider('llama3.2')).toBe('ollama');
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it('detects ollama for "mistral"', () => {
|
|
108
|
-
expect(detectProvider('mistral')).toBe('ollama');
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it('resolves explicit provider prefix "groq/llama-3.1-70b"', () => {
|
|
112
|
-
expect(detectProvider('groq/llama-3.1-70b')).toBe('groq');
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
it('resolves explicit provider prefix "openai/gpt-4o"', () => {
|
|
116
|
-
expect(detectProvider('openai/gpt-4o')).toBe('openai');
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it('falls back to openrouter for unknown "provider/model" prefix', () => {
|
|
120
|
-
expect(detectProvider('unknown-provider/some-model')).toBe('openrouter');
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('defaults to anthropic for unrecognised bare model names', () => {
|
|
124
|
-
expect(detectProvider('totally-unknown-model')).toBe('anthropic');
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
// ---------------------------------------------------------------------------
|
|
129
|
-
// calculateCost
|
|
130
|
-
// ---------------------------------------------------------------------------
|
|
131
|
-
|
|
132
|
-
describe('calculateCost', () => {
|
|
133
|
-
it('returns a CostResult with costUSD and breakdown fields', () => {
|
|
134
|
-
const result: CostResult = calculateCost('anthropic', 'claude-sonnet-4-20250514', 1000, 1000);
|
|
135
|
-
expect(typeof result.costUSD).toBe('number');
|
|
136
|
-
expect(typeof result.breakdown.input).toBe('number');
|
|
137
|
-
expect(typeof result.breakdown.output).toBe('number');
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it('calculates correct cost for claude-sonnet-4-20250514 at 1K input + 1K output tokens', () => {
|
|
141
|
-
// Pricing: $0.003 / 1K input, $0.015 / 1K output
|
|
142
|
-
const result = calculateCost('anthropic', 'claude-sonnet-4-20250514', 1000, 1000);
|
|
143
|
-
expect(result.breakdown.input).toBeCloseTo(0.003, 6);
|
|
144
|
-
expect(result.breakdown.output).toBeCloseTo(0.015, 6);
|
|
145
|
-
expect(result.costUSD).toBeCloseTo(0.018, 6);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it('calculates correct cost for gpt-4o at 2K input + 500 output tokens', () => {
|
|
149
|
-
// Pricing: $0.005 / 1K input, $0.015 / 1K output
|
|
150
|
-
const result = calculateCost('openai', 'gpt-4o', 2000, 500);
|
|
151
|
-
expect(result.breakdown.input).toBeCloseTo(0.01, 6);
|
|
152
|
-
expect(result.breakdown.output).toBeCloseTo(0.0075, 6);
|
|
153
|
-
expect(result.costUSD).toBeCloseTo(0.0175, 6);
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it('returns zero cost for ollama (local model)', () => {
|
|
157
|
-
const result = calculateCost('ollama', 'llama3.2', 5000, 2000);
|
|
158
|
-
expect(result.costUSD).toBe(0);
|
|
159
|
-
expect(result.breakdown.input).toBe(0);
|
|
160
|
-
expect(result.breakdown.output).toBe(0);
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
it('returns zero cost for an unknown provider', () => {
|
|
164
|
-
const result = calculateCost('nonexistent-provider', 'some-model', 1000, 1000);
|
|
165
|
-
expect(result.costUSD).toBe(0);
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
it('returns zero cost for a known provider but unknown model', () => {
|
|
169
|
-
const result = calculateCost('openai', 'gpt-99-ultra-fake', 1000, 1000);
|
|
170
|
-
expect(result.costUSD).toBe(0);
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
it('costUSD equals breakdown.input + breakdown.output', () => {
|
|
174
|
-
const result = calculateCost('anthropic', 'claude-opus-4-20250514', 3000, 1500);
|
|
175
|
-
expect(result.costUSD).toBeCloseTo(result.breakdown.input + result.breakdown.output, 10);
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
it('returns zero cost for zero tokens', () => {
|
|
179
|
-
const result = calculateCost('anthropic', 'claude-sonnet-4-20250514', 0, 0);
|
|
180
|
-
expect(result.costUSD).toBe(0);
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
// ---------------------------------------------------------------------------
|
|
185
|
-
// getPricingData
|
|
186
|
-
// ---------------------------------------------------------------------------
|
|
187
|
-
|
|
188
|
-
describe('getPricingData', () => {
|
|
189
|
-
it('returns an object with anthropic pricing', () => {
|
|
190
|
-
const pricing = getPricingData();
|
|
191
|
-
expect(typeof pricing).toBe('object');
|
|
192
|
-
expect('anthropic' in pricing).toBe(true);
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
it('contains openai pricing', () => {
|
|
196
|
-
expect('openai' in getPricingData()).toBe(true);
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
it('contains google pricing', () => {
|
|
200
|
-
expect('google' in getPricingData()).toBe(true);
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
it('anthropic pricing for claude-sonnet-4-20250514 is a two-element array', () => {
|
|
204
|
-
const pricing = getPricingData();
|
|
205
|
-
const entry = pricing.anthropic['claude-sonnet-4-20250514'];
|
|
206
|
-
expect(Array.isArray(entry)).toBe(true);
|
|
207
|
-
expect(entry.length).toBe(2);
|
|
208
|
-
});
|
|
209
|
-
});
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Logs Command Tests — H1
|
|
3
|
-
*
|
|
4
|
-
* Validates argument building for the logsCommand helper.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { describe, test, it, expect } from 'vitest';
|
|
8
|
-
import { parseLogsArgs } from '../commands/logs';
|
|
9
|
-
|
|
10
|
-
describe('parseLogsArgs (H1)', () => {
|
|
11
|
-
test('parses pod name as first positional', () => {
|
|
12
|
-
const { pod, options } = parseLogsArgs(['my-pod']);
|
|
13
|
-
expect(pod).toBe('my-pod');
|
|
14
|
-
expect(options).toEqual({});
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
test('parses -n namespace', () => {
|
|
18
|
-
const { pod, options } = parseLogsArgs(['my-pod', '-n', 'kube-system']);
|
|
19
|
-
expect(pod).toBe('my-pod');
|
|
20
|
-
expect(options.namespace).toBe('kube-system');
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
test('parses --namespace', () => {
|
|
24
|
-
const { options } = parseLogsArgs(['pod', '--namespace', 'production']);
|
|
25
|
-
expect(options.namespace).toBe('production');
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
test('parses -f / --follow', () => {
|
|
29
|
-
const { options: o1 } = parseLogsArgs(['pod', '-f']);
|
|
30
|
-
expect(o1.follow).toBe(true);
|
|
31
|
-
|
|
32
|
-
const { options: o2 } = parseLogsArgs(['pod', '--follow']);
|
|
33
|
-
expect(o2.follow).toBe(true);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
test('parses -p / --previous', () => {
|
|
37
|
-
const { options: o1 } = parseLogsArgs(['pod', '-p']);
|
|
38
|
-
expect(o1.previous).toBe(true);
|
|
39
|
-
|
|
40
|
-
const { options: o2 } = parseLogsArgs(['pod', '--previous']);
|
|
41
|
-
expect(o2.previous).toBe(true);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
test('parses --tail N', () => {
|
|
45
|
-
const { options } = parseLogsArgs(['pod', '--tail', '100']);
|
|
46
|
-
expect(options.tail).toBe(100);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
test('parses --analyze', () => {
|
|
50
|
-
const { options } = parseLogsArgs(['pod', '--analyze']);
|
|
51
|
-
expect(options.analyze).toBe(true);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
test('parses -c container', () => {
|
|
55
|
-
const { options } = parseLogsArgs(['pod', '-c', 'sidecar']);
|
|
56
|
-
expect(options.container).toBe('sidecar');
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
test('parses --context', () => {
|
|
60
|
-
const { options } = parseLogsArgs(['pod', '--context', 'prod-cluster']);
|
|
61
|
-
expect(options.context).toBe('prod-cluster');
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
test('parses combined flags', () => {
|
|
65
|
-
const { pod, options } = parseLogsArgs([
|
|
66
|
-
'app-pod',
|
|
67
|
-
'-n', 'default',
|
|
68
|
-
'-f',
|
|
69
|
-
'--tail', '50',
|
|
70
|
-
'-c', 'app',
|
|
71
|
-
]);
|
|
72
|
-
expect(pod).toBe('app-pod');
|
|
73
|
-
expect(options.namespace).toBe('default');
|
|
74
|
-
expect(options.follow).toBe(true);
|
|
75
|
-
expect(options.tail).toBe(50);
|
|
76
|
-
expect(options.container).toBe('app');
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
// ---------------------------------------------------------------------------
|
|
81
|
-
// C1: logsTool follow mode (streaming)
|
|
82
|
-
// ---------------------------------------------------------------------------
|
|
83
|
-
|
|
84
|
-
describe('logsTool follow field (C1)', () => {
|
|
85
|
-
it('logsSchema has follow field', async () => {
|
|
86
|
-
const { readFileSync } = await import('node:fs');
|
|
87
|
-
const { join } = await import('node:path');
|
|
88
|
-
const src = readFileSync(join(process.cwd(), 'src/tools/schemas/devops.ts'), 'utf-8');
|
|
89
|
-
expect(src).toContain('follow: z.boolean()');
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('logsTool execute signature accepts ctx', async () => {
|
|
93
|
-
const { readFileSync } = await import('node:fs');
|
|
94
|
-
const { join } = await import('node:path');
|
|
95
|
-
const src = readFileSync(join(process.cwd(), 'src/tools/schemas/devops.ts'), 'utf-8');
|
|
96
|
-
// Check that logsTool execute accepts ctx parameter
|
|
97
|
-
expect(src).toMatch(/logsTool.*execute.*raw.*ctx\?/s);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it('follow mode uses spawnExec for kubernetes provider', async () => {
|
|
101
|
-
const { readFileSync } = await import('node:fs');
|
|
102
|
-
const { join } = await import('node:path');
|
|
103
|
-
const src = readFileSync(join(process.cwd(), 'src/tools/schemas/devops.ts'), 'utf-8');
|
|
104
|
-
// Verify the follow mode path calls spawnExec
|
|
105
|
-
expect(src).toContain('input.follow && ctx?.onProgress');
|
|
106
|
-
});
|
|
107
|
-
});
|