@build-astron-co/nimbus 0.2.0 → 0.4.0
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/bin/nimbus +26 -10
- package/bin/nimbus.cmd +41 -0
- package/bin/nimbus.mjs +70 -0
- package/completions/nimbus.bash +38 -0
- package/completions/nimbus.fish +48 -0
- package/completions/nimbus.zsh +81 -0
- package/dist/src/agent/compaction-agent.js +215 -0
- package/dist/src/agent/context-manager.js +385 -0
- package/dist/src/agent/context.js +322 -0
- package/dist/src/agent/deploy-preview.js +395 -0
- package/dist/src/agent/expand-files.js +95 -0
- package/dist/src/agent/index.js +18 -0
- package/dist/src/agent/loop.js +1535 -0
- package/dist/src/agent/modes.js +347 -0
- package/dist/src/agent/permissions.js +396 -0
- package/dist/src/agent/subagents/base.js +67 -0
- package/dist/src/agent/subagents/cost.js +45 -0
- package/dist/src/agent/subagents/explore.js +36 -0
- package/dist/src/agent/subagents/general.js +41 -0
- package/dist/src/agent/subagents/index.js +88 -0
- package/dist/src/agent/subagents/infra.js +52 -0
- package/dist/src/agent/subagents/security.js +60 -0
- package/dist/src/agent/system-prompt.js +860 -0
- package/dist/src/app.js +152 -0
- package/dist/src/audit/activity-log.js +209 -0
- package/dist/src/audit/compliance-checker.js +419 -0
- package/dist/src/audit/cost-tracker.js +231 -0
- package/dist/src/audit/index.js +10 -0
- package/dist/src/audit/security-scanner.js +490 -0
- package/dist/src/auth/guard.js +64 -0
- package/dist/src/auth/index.js +19 -0
- package/dist/src/auth/keychain.js +79 -0
- package/dist/src/auth/oauth.js +389 -0
- package/dist/src/auth/providers.js +415 -0
- package/dist/src/auth/sso.js +87 -0
- package/dist/src/auth/store.js +424 -0
- package/dist/src/auth/types.js +5 -0
- package/dist/src/cli/index.js +8 -0
- package/dist/src/cli/init.js +1048 -0
- package/dist/src/cli/openapi-spec.js +346 -0
- package/dist/src/cli/run.js +505 -0
- package/dist/src/cli/serve-auth.js +56 -0
- package/dist/src/cli/serve.js +432 -0
- package/dist/src/cli/web.js +50 -0
- package/dist/src/cli.js +1574 -0
- package/dist/src/clients/core-engine-client.js +156 -0
- package/dist/src/clients/enterprise-client.js +246 -0
- package/dist/src/clients/generator-client.js +219 -0
- package/dist/src/clients/git-client.js +367 -0
- package/dist/src/clients/github-client.js +229 -0
- package/dist/src/clients/helm-client.js +299 -0
- package/dist/src/clients/index.js +18 -0
- package/dist/src/clients/k8s-client.js +270 -0
- package/dist/src/clients/llm-client.js +119 -0
- package/dist/src/clients/rest-client.js +104 -0
- package/dist/src/clients/service-discovery.js +35 -0
- package/dist/src/clients/terraform-client.js +302 -0
- package/dist/src/clients/tools-client.js +1227 -0
- package/dist/src/clients/ws-client.js +93 -0
- package/dist/src/commands/alias.js +91 -0
- package/dist/src/commands/analyze/index.js +313 -0
- package/dist/src/commands/apply/helm.js +375 -0
- package/dist/src/commands/apply/index.js +176 -0
- package/dist/src/commands/apply/k8s.js +350 -0
- package/dist/src/commands/apply/terraform.js +465 -0
- package/dist/src/commands/ask.js +137 -0
- package/dist/src/commands/audit/index.js +322 -0
- package/dist/src/commands/auth-cloud.js +345 -0
- package/dist/src/commands/auth-list.js +112 -0
- package/dist/src/commands/auth-profile.js +104 -0
- package/dist/src/commands/auth-refresh.js +161 -0
- package/dist/src/commands/auth-status.js +122 -0
- package/dist/src/commands/aws/ec2.js +402 -0
- package/dist/src/commands/aws/iam.js +304 -0
- package/dist/src/commands/aws/index.js +108 -0
- package/dist/src/commands/aws/lambda.js +317 -0
- package/dist/src/commands/aws/rds.js +345 -0
- package/dist/src/commands/aws/s3.js +346 -0
- package/dist/src/commands/aws/vpc.js +302 -0
- package/dist/src/commands/aws-discover.js +413 -0
- package/dist/src/commands/aws-terraform.js +618 -0
- package/dist/src/commands/azure/aks.js +305 -0
- package/dist/src/commands/azure/functions.js +200 -0
- package/dist/src/commands/azure/index.js +93 -0
- package/dist/src/commands/azure/storage.js +378 -0
- package/dist/src/commands/azure/vm.js +291 -0
- package/dist/src/commands/billing/index.js +224 -0
- package/dist/src/commands/chat.js +259 -0
- package/dist/src/commands/completions.js +255 -0
- package/dist/src/commands/config.js +291 -0
- package/dist/src/commands/cost/cloud-cost-estimator.js +211 -0
- package/dist/src/commands/cost/estimator.js +73 -0
- package/dist/src/commands/cost/index.js +625 -0
- package/dist/src/commands/cost/parsers/terraform.js +234 -0
- package/dist/src/commands/cost/parsers/types.js +4 -0
- package/dist/src/commands/cost/pricing/aws.js +501 -0
- package/dist/src/commands/cost/pricing/azure.js +462 -0
- package/dist/src/commands/cost/pricing/gcp.js +359 -0
- package/dist/src/commands/cost/pricing/index.js +24 -0
- package/dist/src/commands/demo.js +196 -0
- package/dist/src/commands/deploy.js +215 -0
- package/dist/src/commands/doctor.js +1291 -0
- package/dist/src/commands/drift/index.js +674 -0
- package/dist/src/commands/explain.js +235 -0
- package/dist/src/commands/export.js +120 -0
- package/dist/src/commands/feedback.js +319 -0
- package/dist/src/commands/fix.js +263 -0
- package/dist/src/commands/fs/index.js +338 -0
- package/dist/src/commands/gcp/compute.js +266 -0
- package/dist/src/commands/gcp/functions.js +221 -0
- package/dist/src/commands/gcp/gke.js +357 -0
- package/dist/src/commands/gcp/iam.js +295 -0
- package/dist/src/commands/gcp/index.js +105 -0
- package/dist/src/commands/gcp/storage.js +232 -0
- package/dist/src/commands/generate-helm.js +1026 -0
- package/dist/src/commands/generate-k8s.js +1263 -0
- package/dist/src/commands/generate-terraform.js +1058 -0
- package/dist/src/commands/gh/index.js +663 -0
- package/dist/src/commands/git/index.js +1208 -0
- package/dist/src/commands/helm/index.js +985 -0
- package/dist/src/commands/help.js +639 -0
- package/dist/src/commands/history.js +120 -0
- package/dist/src/commands/import.js +782 -0
- package/dist/src/commands/incident.js +144 -0
- package/dist/src/commands/index.js +109 -0
- package/dist/src/commands/init.js +955 -0
- package/dist/src/commands/k8s/index.js +979 -0
- package/dist/src/commands/login.js +588 -0
- package/dist/src/commands/logout.js +61 -0
- package/dist/src/commands/logs.js +160 -0
- package/dist/src/commands/onboarding.js +382 -0
- package/dist/src/commands/pipeline.js +153 -0
- package/dist/src/commands/plan/display.js +216 -0
- package/dist/src/commands/plan/index.js +525 -0
- package/dist/src/commands/plugin.js +325 -0
- package/dist/src/commands/preview.js +356 -0
- package/dist/src/commands/profile.js +297 -0
- package/dist/src/commands/questionnaire.js +1021 -0
- package/dist/src/commands/resume.js +35 -0
- package/dist/src/commands/rollback.js +259 -0
- package/dist/src/commands/rollout.js +74 -0
- package/dist/src/commands/runbook.js +307 -0
- package/dist/src/commands/schedule.js +202 -0
- package/dist/src/commands/status.js +213 -0
- package/dist/src/commands/team/index.js +309 -0
- package/dist/src/commands/team-context.js +200 -0
- package/dist/src/commands/template.js +204 -0
- package/dist/src/commands/tf/index.js +989 -0
- package/dist/src/commands/upgrade.js +515 -0
- package/dist/src/commands/usage/index.js +118 -0
- package/dist/src/commands/version.js +145 -0
- package/dist/src/commands/watch.js +127 -0
- package/dist/src/compat/index.js +2 -0
- package/dist/src/compat/runtime.js +10 -0
- package/dist/src/compat/sqlite.js +144 -0
- package/dist/src/config/index.js +6 -0
- package/dist/src/config/manager.js +469 -0
- package/dist/src/config/mode-store.js +57 -0
- package/dist/src/config/profiles.js +66 -0
- package/dist/src/config/safety-policy.js +251 -0
- package/dist/src/config/schema.js +107 -0
- package/dist/src/config/types.js +311 -0
- package/dist/src/config/workspace-state.js +38 -0
- package/dist/src/context/context-db.js +138 -0
- package/dist/src/demo/index.js +295 -0
- package/dist/src/demo/scenarios/full-journey.js +226 -0
- package/dist/src/demo/scenarios/getting-started.js +124 -0
- package/dist/src/demo/scenarios/helm-release.js +334 -0
- package/dist/src/demo/scenarios/k8s-deployment.js +190 -0
- package/dist/src/demo/scenarios/terraform-vpc.js +167 -0
- package/dist/src/demo/types.js +6 -0
- package/dist/src/engine/cost-estimator.js +334 -0
- package/dist/src/engine/diagram-generator.js +192 -0
- package/dist/src/engine/drift-detector.js +688 -0
- package/dist/src/engine/executor.js +832 -0
- package/dist/src/engine/index.js +39 -0
- package/dist/src/engine/orchestrator.js +436 -0
- package/dist/src/engine/planner.js +616 -0
- package/dist/src/engine/safety.js +609 -0
- package/dist/src/engine/verifier.js +664 -0
- package/dist/src/enterprise/audit.js +241 -0
- package/dist/src/enterprise/auth.js +189 -0
- package/dist/src/enterprise/billing.js +512 -0
- package/dist/src/enterprise/index.js +16 -0
- package/dist/src/enterprise/teams.js +315 -0
- package/dist/src/generator/best-practices.js +1375 -0
- package/dist/src/generator/helm.js +495 -0
- package/dist/src/generator/index.js +11 -0
- package/dist/src/generator/intent-parser.js +420 -0
- package/dist/src/generator/kubernetes.js +773 -0
- package/dist/src/generator/terraform.js +1472 -0
- package/dist/src/history/index.js +6 -0
- package/dist/src/history/manager.js +199 -0
- package/dist/src/history/types.js +6 -0
- package/dist/src/hooks/config.js +318 -0
- package/dist/src/hooks/engine.js +317 -0
- package/dist/src/hooks/index.js +2 -0
- package/dist/src/llm/auth-bridge.js +157 -0
- package/dist/src/llm/circuit-breaker.js +116 -0
- package/dist/src/llm/config-loader.js +172 -0
- package/dist/src/llm/cost-calculator.js +137 -0
- package/dist/src/llm/index.js +7 -0
- package/dist/src/llm/model-aliases.js +99 -0
- package/dist/src/llm/provider-registry.js +57 -0
- package/dist/src/llm/providers/anthropic.js +430 -0
- package/dist/src/llm/providers/bedrock.js +409 -0
- package/dist/src/llm/providers/google.js +344 -0
- package/dist/src/llm/providers/ollama.js +661 -0
- package/dist/src/llm/providers/openai-compatible.js +289 -0
- package/dist/src/llm/providers/openai.js +284 -0
- package/dist/src/llm/providers/openrouter.js +293 -0
- package/dist/src/llm/router.js +844 -0
- package/dist/src/llm/types.js +69 -0
- package/dist/src/lsp/client.js +239 -0
- package/dist/src/lsp/languages.js +95 -0
- package/dist/src/lsp/manager.js +243 -0
- package/dist/src/mcp/client.js +289 -0
- package/dist/src/mcp/index.js +5 -0
- package/dist/src/mcp/manager.js +113 -0
- package/dist/src/nimbus.js +212 -0
- package/dist/src/plugins/index.js +13 -0
- package/dist/src/plugins/loader.js +280 -0
- package/dist/src/plugins/manager.js +282 -0
- package/dist/src/plugins/types.js +23 -0
- package/dist/src/scanners/cicd-scanner.js +230 -0
- package/dist/src/scanners/cloud-scanner.js +415 -0
- package/dist/src/scanners/framework-scanner.js +430 -0
- package/dist/src/scanners/iac-scanner.js +350 -0
- package/dist/src/scanners/index.js +454 -0
- package/dist/src/scanners/language-scanner.js +258 -0
- package/dist/src/scanners/package-manager-scanner.js +252 -0
- package/dist/src/scanners/types.js +6 -0
- package/dist/src/sessions/manager.js +395 -0
- package/dist/src/sessions/types.js +4 -0
- package/dist/src/sharing/sync.js +238 -0
- package/dist/src/sharing/viewer.js +131 -0
- package/dist/src/snapshots/index.js +1 -0
- package/dist/src/snapshots/manager.js +432 -0
- package/dist/src/state/artifacts.js +94 -0
- package/dist/src/state/audit.js +73 -0
- package/dist/src/state/billing.js +126 -0
- package/dist/src/state/checkpoints.js +81 -0
- package/dist/src/state/config.js +58 -0
- package/dist/src/state/conversations.js +7 -0
- package/dist/src/state/credentials.js +96 -0
- package/dist/src/state/db.js +53 -0
- package/dist/src/state/index.js +23 -0
- package/dist/src/state/messages.js +76 -0
- package/dist/src/state/projects.js +92 -0
- package/dist/src/state/schema.js +233 -0
- package/dist/src/state/sessions.js +79 -0
- package/dist/src/state/teams.js +131 -0
- package/dist/src/telemetry.js +91 -0
- package/dist/src/tools/aws-ops.js +747 -0
- package/dist/src/tools/azure-ops.js +491 -0
- package/dist/src/tools/file-ops.js +451 -0
- package/dist/src/tools/gcp-ops.js +559 -0
- package/dist/src/tools/git-ops.js +557 -0
- package/dist/src/tools/github-ops.js +460 -0
- package/dist/src/tools/helm-ops.js +634 -0
- package/dist/src/tools/index.js +16 -0
- package/dist/src/tools/k8s-ops.js +579 -0
- package/dist/src/tools/schemas/converter.js +129 -0
- package/dist/src/tools/schemas/devops.js +3319 -0
- package/dist/src/tools/schemas/index.js +19 -0
- package/dist/src/tools/schemas/standard.js +966 -0
- package/dist/src/tools/schemas/types.js +409 -0
- package/dist/src/tools/spawn-exec.js +109 -0
- package/dist/src/tools/terraform-ops.js +627 -0
- package/dist/src/types/config.js +1 -0
- package/dist/src/types/drift.js +4 -0
- package/dist/src/types/enterprise.js +5 -0
- package/dist/src/types/index.js +14 -0
- package/dist/src/types/plan.js +1 -0
- package/dist/src/types/request.js +1 -0
- package/dist/src/types/response.js +1 -0
- package/dist/src/types/service.js +1 -0
- package/dist/src/ui/App.js +1672 -0
- package/dist/src/ui/DeployPreview.js +60 -0
- package/dist/src/ui/FileDiffModal.js +108 -0
- package/dist/src/ui/Header.js +46 -0
- package/dist/src/ui/HelpModal.js +9 -0
- package/dist/src/ui/InputBox.js +408 -0
- package/dist/src/ui/MessageList.js +795 -0
- package/dist/src/ui/PermissionPrompt.js +72 -0
- package/dist/src/ui/StatusBar.js +109 -0
- package/dist/src/ui/TerminalPane.js +31 -0
- package/dist/src/ui/ToolCallDisplay.js +303 -0
- package/dist/src/ui/TreePane.js +83 -0
- package/dist/src/ui/chat-ui.js +721 -0
- package/dist/src/ui/index.js +11 -0
- package/dist/src/ui/ink/index.js +1325 -0
- package/dist/src/ui/streaming.js +137 -0
- package/dist/src/ui/theme.js +78 -0
- package/dist/src/ui/types.js +7 -0
- package/dist/src/utils/analytics.js +61 -0
- package/dist/src/utils/cost-warning.js +25 -0
- package/dist/src/utils/env.js +42 -0
- package/dist/src/utils/errors.js +54 -0
- package/dist/src/utils/event-bus.js +22 -0
- package/dist/src/utils/index.js +16 -0
- package/dist/src/utils/logger.js +150 -0
- package/dist/src/utils/rate-limiter.js +90 -0
- package/dist/src/utils/service-auth.js +36 -0
- package/dist/src/utils/validation.js +39 -0
- package/dist/src/version.js +3 -0
- package/dist/src/watcher/index.js +192 -0
- package/dist/src/wizard/approval.js +275 -0
- package/dist/src/wizard/index.js +13 -0
- package/dist/src/wizard/prompts.js +273 -0
- package/dist/src/wizard/types.js +4 -0
- package/dist/src/wizard/ui.js +453 -0
- package/dist/src/wizard/wizard.js +227 -0
- package/package.json +31 -23
- package/src/__tests__/alias.test.ts +133 -0
- package/src/__tests__/app.test.ts +1 -1
- package/src/__tests__/audit.test.ts +1 -1
- package/src/__tests__/circuit-breaker.test.ts +1 -1
- package/src/__tests__/cli-run.test.ts +237 -1
- package/src/__tests__/compat-sqlite.test.ts +68 -0
- package/src/__tests__/context-manager.test.ts +131 -1
- package/src/__tests__/context.test.ts +1 -1
- package/src/__tests__/devops-terminal-gaps.test.ts +718 -0
- package/src/__tests__/doctor.test.ts +48 -0
- package/src/__tests__/enterprise.test.ts +1 -1
- package/src/__tests__/export.test.ts +236 -0
- package/src/__tests__/gap-11-18-20.test.ts +958 -0
- package/src/__tests__/generator.test.ts +1 -1
- package/src/__tests__/helm-streaming.test.ts +127 -0
- package/src/__tests__/hooks.test.ts +1 -1
- package/src/__tests__/incident.test.ts +179 -0
- package/src/__tests__/init.test.ts +55 -4
- package/src/__tests__/intent-parser.test.ts +1 -1
- package/src/__tests__/llm-router.test.ts +1 -1
- package/src/__tests__/logs.test.ts +107 -0
- package/src/__tests__/loop-errors.test.ts +244 -0
- package/src/__tests__/lsp.test.ts +1 -1
- package/src/__tests__/modes.test.ts +1 -1
- package/src/__tests__/perf-optimizations.test.ts +847 -0
- package/src/__tests__/permissions.test.ts +1 -1
- package/src/__tests__/pipeline.test.ts +50 -0
- package/src/__tests__/polish-phase3.test.ts +340 -0
- package/src/__tests__/profile.test.ts +237 -0
- package/src/__tests__/rollback.test.ts +83 -0
- package/src/__tests__/runbook.test.ts +219 -0
- package/src/__tests__/schedule.test.ts +206 -0
- package/src/__tests__/serve.test.ts +1 -1
- package/src/__tests__/sessions.test.ts +96 -1
- package/src/__tests__/sharing.test.ts +53 -1
- package/src/__tests__/snapshots.test.ts +1 -1
- package/src/__tests__/standalone-migration.test.ts +199 -0
- package/src/__tests__/state-db.test.ts +1 -1
- package/src/__tests__/status.test.ts +158 -0
- package/src/__tests__/stream-with-tools.test.ts +71 -25
- package/src/__tests__/subagents.test.ts +1 -1
- package/src/__tests__/system-prompt.test.ts +82 -3
- package/src/__tests__/terminal-gap-v2.test.ts +395 -0
- package/src/__tests__/terminal-parity.test.ts +393 -0
- package/src/__tests__/tf-apply.test.ts +187 -0
- package/src/__tests__/tool-converter.test.ts +1 -1
- package/src/__tests__/tool-schemas.test.ts +209 -4
- package/src/__tests__/tools.test.ts +4 -3
- package/src/__tests__/version-json.test.ts +184 -0
- package/src/__tests__/version.test.ts +1 -1
- package/src/__tests__/watch.test.ts +129 -0
- package/src/agent/compaction-agent.ts +40 -1
- package/src/agent/context-manager.ts +67 -3
- package/src/agent/deploy-preview.ts +62 -1
- package/src/agent/expand-files.ts +108 -0
- package/src/agent/loop.ts +1312 -31
- package/src/agent/permissions.ts +51 -4
- package/src/agent/system-prompt.ts +573 -19
- package/src/app.ts +58 -0
- package/src/audit/security-scanner.ts +45 -0
- package/src/auth/keychain.ts +82 -0
- package/src/auth/oauth.ts +15 -5
- package/src/cli/init.ts +378 -5
- package/src/cli/run.ts +407 -16
- package/src/cli/serve.ts +78 -1
- package/src/cli/web.ts +10 -6
- package/src/cli.ts +312 -1
- package/src/clients/service-discovery.ts +30 -25
- package/src/commands/alias.ts +100 -0
- package/src/commands/audit/index.ts +121 -2
- package/src/commands/auth-cloud.ts +113 -0
- package/src/commands/auth-refresh.ts +187 -0
- package/src/commands/aws-discover.ts +144 -251
- package/src/commands/aws-terraform.ts +68 -118
- package/src/commands/chat.ts +9 -3
- package/src/commands/completions.ts +268 -0
- package/src/commands/config.ts +26 -0
- package/src/commands/cost/index.ts +218 -2
- package/src/commands/deploy.ts +260 -0
- package/src/commands/doctor.ts +744 -152
- package/src/commands/drift/index.ts +371 -23
- package/src/commands/export.ts +146 -0
- package/src/commands/generate-k8s.ts +9 -61
- package/src/commands/generate-terraform.ts +191 -449
- package/src/commands/help.ts +212 -36
- package/src/commands/history.ts +8 -1
- package/src/commands/incident.ts +166 -0
- package/src/commands/init.ts +5 -0
- package/src/commands/login.ts +86 -1
- package/src/commands/logs.ts +167 -0
- package/src/commands/onboarding.ts +211 -34
- package/src/commands/pipeline.ts +186 -0
- package/src/commands/plugin.ts +398 -0
- package/src/commands/profile.ts +342 -0
- package/src/commands/questionnaire.ts +0 -98
- package/src/commands/resume.ts +26 -34
- package/src/commands/rollback.ts +315 -0
- package/src/commands/rollout.ts +88 -0
- package/src/commands/runbook.ts +346 -0
- package/src/commands/schedule.ts +236 -0
- package/src/commands/status.ts +252 -0
- package/src/commands/team-context.ts +220 -0
- package/src/commands/template.ts +58 -57
- package/src/commands/tf/index.ts +70 -11
- package/src/commands/upgrade.ts +57 -0
- package/src/commands/version.ts +54 -50
- package/src/commands/watch.ts +153 -0
- package/src/compat/runtime.ts +1 -1
- package/src/compat/sqlite.ts +75 -5
- package/src/config/mode-store.ts +62 -0
- package/src/config/profiles.ts +84 -0
- package/src/config/types.ts +83 -1
- package/src/config/workspace-state.ts +53 -0
- package/src/engine/cost-estimator.ts +52 -10
- package/src/engine/executor.ts +33 -2
- package/src/engine/planner.ts +68 -1
- package/src/generator/terraform.ts +8 -0
- package/src/history/manager.ts +2 -74
- package/src/hooks/engine.ts +5 -4
- package/src/llm/cost-calculator.ts +2 -2
- package/src/llm/providers/anthropic.ts +50 -21
- package/src/llm/router.ts +76 -7
- package/src/lsp/languages.ts +3 -0
- package/src/lsp/manager.ts +21 -5
- package/src/nimbus.ts +37 -18
- package/src/sessions/manager.ts +108 -1
- package/src/sharing/sync.ts +4 -0
- package/src/sharing/viewer.ts +66 -0
- package/src/tools/file-ops.ts +22 -0
- package/src/tools/schemas/devops.ts +3007 -117
- package/src/tools/schemas/standard.ts +5 -1
- package/src/tools/schemas/types.ts +31 -1
- package/src/tools/spawn-exec.ts +148 -0
- package/src/ui/App.tsx +1183 -66
- package/src/ui/DeployPreview.tsx +62 -57
- package/src/ui/FileDiffModal.tsx +162 -0
- package/src/ui/Header.tsx +87 -24
- package/src/ui/HelpModal.tsx +57 -0
- package/src/ui/InputBox.tsx +163 -10
- package/src/ui/MessageList.tsx +487 -40
- package/src/ui/PermissionPrompt.tsx +17 -5
- package/src/ui/StatusBar.tsx +122 -3
- package/src/ui/TerminalPane.tsx +84 -0
- package/src/ui/ToolCallDisplay.tsx +252 -18
- package/src/ui/TreePane.tsx +132 -0
- package/src/ui/chat-ui.ts +41 -44
- package/src/ui/ink/index.ts +771 -38
- package/src/ui/streaming.ts +1 -1
- package/src/ui/theme.ts +104 -0
- package/src/ui/types.ts +18 -0
- package/src/version.ts +1 -1
- package/src/watcher/index.ts +66 -15
- package/src/wizard/types.ts +1 -0
- package/src/wizard/ui.ts +1 -1
- package/tsconfig.json +2 -2
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enterprise Teams - Team CRUD and member management.
|
|
3
|
+
*
|
|
4
|
+
* Embedded replacement for services/team-service.
|
|
5
|
+
* All business logic is preserved verbatim from:
|
|
6
|
+
* - services/team-service/src/routes/teams.ts
|
|
7
|
+
* - services/team-service/src/routes/members.ts
|
|
8
|
+
*
|
|
9
|
+
* HTTP handlers, routes, and per-service SQLite are stripped.
|
|
10
|
+
* State is read/written through the unified database via ../state/teams.
|
|
11
|
+
*/
|
|
12
|
+
import { createTeam as stateCreateTeam, getTeam as stateGetTeam, addTeamMember as stateAddTeamMember, removeTeamMember as stateRemoveTeamMember, listTeamMembers as stateListTeamMembers, createUser as stateCreateUser, } from '../state/teams';
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Constants
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Valid roles for team members (owner is set during team creation only)
|
|
17
|
+
const VALID_MEMBER_ROLES = ['admin', 'member', 'viewer'];
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Private helpers
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
/**
|
|
22
|
+
* Map a state TeamRecord to the public Team shape.
|
|
23
|
+
*/
|
|
24
|
+
function recordToTeam(record) {
|
|
25
|
+
return {
|
|
26
|
+
id: record.id,
|
|
27
|
+
name: record.name,
|
|
28
|
+
ownerId: record.ownerId,
|
|
29
|
+
plan: record.plan,
|
|
30
|
+
createdAt: record.createdAt,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Retrieve the team_members row for a specific (teamId, userId) pair.
|
|
35
|
+
* The unified state module exposes listTeamMembers() but not a single-member
|
|
36
|
+
* getter, so we filter in-process here — consistent with the original
|
|
37
|
+
* team-service adapter's getTeamMember().
|
|
38
|
+
*/
|
|
39
|
+
function getTeamMember(teamId, userId) {
|
|
40
|
+
const members = stateListTeamMembers(teamId);
|
|
41
|
+
return members.find(m => m.userId === userId) ?? null;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Look up a user by email from the unified users table.
|
|
45
|
+
* If no user exists, create one with a generated id.
|
|
46
|
+
*/
|
|
47
|
+
async function getOrCreateUserByEmail(email) {
|
|
48
|
+
const { getDb } = await import('../state/db');
|
|
49
|
+
const db = getDb();
|
|
50
|
+
// Try to find by email first
|
|
51
|
+
const existing = db.prepare('SELECT * FROM users WHERE email = ?').get(email);
|
|
52
|
+
if (existing) {
|
|
53
|
+
return {
|
|
54
|
+
id: existing.id,
|
|
55
|
+
email: existing.email,
|
|
56
|
+
name: existing.name,
|
|
57
|
+
avatarUrl: existing.avatar_url,
|
|
58
|
+
createdAt: existing.created_at,
|
|
59
|
+
updatedAt: existing.updated_at,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// Create a new user record
|
|
63
|
+
const id = crypto.randomUUID();
|
|
64
|
+
stateCreateUser(id, email);
|
|
65
|
+
const created = db.prepare('SELECT * FROM users WHERE id = ?').get(id);
|
|
66
|
+
if (!created) {
|
|
67
|
+
throw new Error('Failed to create or load user');
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
id: created.id,
|
|
71
|
+
email: created.email,
|
|
72
|
+
name: created.name,
|
|
73
|
+
avatarUrl: created.avatar_url,
|
|
74
|
+
createdAt: created.created_at,
|
|
75
|
+
updatedAt: created.updated_at,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// Public API - Team CRUD
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
/**
|
|
82
|
+
* Create a new team.
|
|
83
|
+
*
|
|
84
|
+
* The owner is automatically added as a team member with the 'owner' role
|
|
85
|
+
* via the underlying state layer transaction.
|
|
86
|
+
*/
|
|
87
|
+
export async function createTeam(request) {
|
|
88
|
+
const { name, ownerId } = request;
|
|
89
|
+
if (!name || !ownerId) {
|
|
90
|
+
throw new Error('Team name and owner ID are required');
|
|
91
|
+
}
|
|
92
|
+
const id = crypto.randomUUID();
|
|
93
|
+
// stateCreateTeam(id, name, ownerId, plan?)
|
|
94
|
+
stateCreateTeam(id, name, ownerId);
|
|
95
|
+
// Add owner as a member with role 'owner' via the members table
|
|
96
|
+
const memberId = crypto.randomUUID();
|
|
97
|
+
stateAddTeamMember(memberId, id, ownerId, 'owner');
|
|
98
|
+
const record = stateGetTeam(id);
|
|
99
|
+
if (!record) {
|
|
100
|
+
throw new Error('Failed to create team');
|
|
101
|
+
}
|
|
102
|
+
return recordToTeam(record);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get a team by ID.
|
|
106
|
+
*
|
|
107
|
+
* Returns null if no team with the given ID exists.
|
|
108
|
+
*/
|
|
109
|
+
export async function getTeam(id) {
|
|
110
|
+
const record = stateGetTeam(id);
|
|
111
|
+
if (!record) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
return recordToTeam(record);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* List all teams visible to a given user (teams where userId is a member).
|
|
118
|
+
*/
|
|
119
|
+
export async function listUserTeams(userId) {
|
|
120
|
+
// The unified state module's listTeams() returns all teams; we filter by
|
|
121
|
+
// membership using the team_members table via a direct query to replicate
|
|
122
|
+
// the original listTeamsForUser(userId) JOIN behavior.
|
|
123
|
+
const { getDb } = await import('../state/db');
|
|
124
|
+
const db = getDb();
|
|
125
|
+
const rows = db
|
|
126
|
+
.prepare(`
|
|
127
|
+
SELECT t.* FROM teams t
|
|
128
|
+
JOIN team_members tm ON t.id = tm.team_id
|
|
129
|
+
WHERE tm.user_id = ?
|
|
130
|
+
ORDER BY t.created_at DESC
|
|
131
|
+
`)
|
|
132
|
+
.all(userId);
|
|
133
|
+
return rows.map(row => ({
|
|
134
|
+
id: row.id,
|
|
135
|
+
name: row.name,
|
|
136
|
+
ownerId: row.owner_id,
|
|
137
|
+
plan: (row.plan || 'free'),
|
|
138
|
+
createdAt: row.created_at,
|
|
139
|
+
}));
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Delete a team and all its member associations.
|
|
143
|
+
*
|
|
144
|
+
* If requesterId is provided, verifies the requester is the team owner before
|
|
145
|
+
* proceeding.
|
|
146
|
+
*/
|
|
147
|
+
export async function deleteTeam(id, requesterId) {
|
|
148
|
+
const record = stateGetTeam(id);
|
|
149
|
+
if (!record) {
|
|
150
|
+
throw new Error('Team not found');
|
|
151
|
+
}
|
|
152
|
+
if (requesterId) {
|
|
153
|
+
const member = getTeamMember(id, requesterId);
|
|
154
|
+
if (!member || member.role !== 'owner') {
|
|
155
|
+
throw new Error('Only the team owner can delete the team');
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const { getDb } = await import('../state/db');
|
|
159
|
+
const db = getDb();
|
|
160
|
+
// Delete members first (foreign-key safe), then the team row
|
|
161
|
+
db.prepare('DELETE FROM team_members WHERE team_id = ?').run(id);
|
|
162
|
+
db.prepare('DELETE FROM teams WHERE id = ?').run(id);
|
|
163
|
+
}
|
|
164
|
+
// ---------------------------------------------------------------------------
|
|
165
|
+
// Public API - Member management
|
|
166
|
+
// ---------------------------------------------------------------------------
|
|
167
|
+
/**
|
|
168
|
+
* Invite a member to a team by email address.
|
|
169
|
+
*
|
|
170
|
+
* Creates the user record if one does not yet exist. Validates role and
|
|
171
|
+
* requester authorization before inserting the membership row.
|
|
172
|
+
*/
|
|
173
|
+
export async function inviteMember(teamId, request, requesterId) {
|
|
174
|
+
const { email, role = 'member' } = request;
|
|
175
|
+
if (!email) {
|
|
176
|
+
throw new Error('Email is required');
|
|
177
|
+
}
|
|
178
|
+
// Validate role
|
|
179
|
+
if (!VALID_MEMBER_ROLES.includes(role)) {
|
|
180
|
+
throw new Error(`Invalid role: ${role}. Must be one of: ${VALID_MEMBER_ROLES.join(', ')}`);
|
|
181
|
+
}
|
|
182
|
+
if (role === 'owner') {
|
|
183
|
+
throw new Error('Cannot invite as owner. Use transfer ownership instead.');
|
|
184
|
+
}
|
|
185
|
+
// Verify requester authorization
|
|
186
|
+
if (requesterId) {
|
|
187
|
+
const requesterMember = getTeamMember(teamId, requesterId);
|
|
188
|
+
if (!requesterMember || !['owner', 'admin'].includes(requesterMember.role)) {
|
|
189
|
+
throw new Error('Only team owners and admins can invite members');
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// Verify team exists
|
|
193
|
+
const team = stateGetTeam(teamId);
|
|
194
|
+
if (!team) {
|
|
195
|
+
throw new Error('Team not found');
|
|
196
|
+
}
|
|
197
|
+
// Get or create user by email
|
|
198
|
+
const user = await getOrCreateUserByEmail(email);
|
|
199
|
+
// Check if already a member
|
|
200
|
+
const existingMember = getTeamMember(teamId, user.id);
|
|
201
|
+
if (existingMember) {
|
|
202
|
+
throw new Error('User is already a member of this team');
|
|
203
|
+
}
|
|
204
|
+
const memberId = crypto.randomUUID();
|
|
205
|
+
stateAddTeamMember(memberId, teamId, user.id, role);
|
|
206
|
+
return {
|
|
207
|
+
teamId,
|
|
208
|
+
userId: user.id,
|
|
209
|
+
role: role,
|
|
210
|
+
joinedAt: new Date().toISOString(),
|
|
211
|
+
user: {
|
|
212
|
+
id: user.id,
|
|
213
|
+
email: user.email,
|
|
214
|
+
name: user.name ?? undefined,
|
|
215
|
+
createdAt: user.createdAt,
|
|
216
|
+
updatedAt: user.updatedAt,
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* List all members of a team.
|
|
222
|
+
*/
|
|
223
|
+
export async function listMembers(teamId) {
|
|
224
|
+
// We need the joined user email/name alongside the member row.
|
|
225
|
+
// The unified state module's listTeamMembers() returns TeamMemberRecord
|
|
226
|
+
// (id, teamId, userId, role, joinedAt) without the user details, so we
|
|
227
|
+
// perform a JOIN directly to include the user's email.
|
|
228
|
+
const { getDb } = await import('../state/db');
|
|
229
|
+
const db = getDb();
|
|
230
|
+
const rows = db
|
|
231
|
+
.prepare(`
|
|
232
|
+
SELECT tm.id, tm.team_id, tm.user_id, tm.role, tm.joined_at,
|
|
233
|
+
u.email, u.name
|
|
234
|
+
FROM team_members tm
|
|
235
|
+
LEFT JOIN users u ON tm.user_id = u.id
|
|
236
|
+
WHERE tm.team_id = ?
|
|
237
|
+
ORDER BY tm.joined_at ASC
|
|
238
|
+
`)
|
|
239
|
+
.all(teamId);
|
|
240
|
+
return rows.map(row => ({
|
|
241
|
+
teamId: row.team_id,
|
|
242
|
+
userId: row.user_id,
|
|
243
|
+
role: row.role,
|
|
244
|
+
joinedAt: row.joined_at,
|
|
245
|
+
user: {
|
|
246
|
+
id: row.user_id,
|
|
247
|
+
email: row.email ?? null,
|
|
248
|
+
name: row.name ?? undefined,
|
|
249
|
+
createdAt: '',
|
|
250
|
+
updatedAt: '',
|
|
251
|
+
},
|
|
252
|
+
}));
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Update a team member's role.
|
|
256
|
+
*
|
|
257
|
+
* Owner role transitions are blocked; use a dedicated transfer-ownership flow
|
|
258
|
+
* instead.
|
|
259
|
+
*/
|
|
260
|
+
export async function updateMemberRole(teamId, userId, request, requesterId) {
|
|
261
|
+
const { role } = request;
|
|
262
|
+
if (!role) {
|
|
263
|
+
throw new Error('Role is required');
|
|
264
|
+
}
|
|
265
|
+
if (!VALID_MEMBER_ROLES.includes(role)) {
|
|
266
|
+
throw new Error(`Invalid role: ${role}. Must be one of: ${VALID_MEMBER_ROLES.join(', ')}`);
|
|
267
|
+
}
|
|
268
|
+
if (requesterId) {
|
|
269
|
+
const requesterMember = getTeamMember(teamId, requesterId);
|
|
270
|
+
if (!requesterMember || !['owner', 'admin'].includes(requesterMember.role)) {
|
|
271
|
+
throw new Error('Only team owners and admins can update member roles');
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
const member = getTeamMember(teamId, userId);
|
|
275
|
+
if (!member) {
|
|
276
|
+
throw new Error('Member not found');
|
|
277
|
+
}
|
|
278
|
+
if (member.role === 'owner') {
|
|
279
|
+
throw new Error('Cannot change owner role. Use transfer ownership instead.');
|
|
280
|
+
}
|
|
281
|
+
if (role === 'owner') {
|
|
282
|
+
throw new Error('Cannot promote to owner. Use transfer ownership instead.');
|
|
283
|
+
}
|
|
284
|
+
const { getDb } = await import('../state/db');
|
|
285
|
+
const db = getDb();
|
|
286
|
+
db.prepare('UPDATE team_members SET role = ? WHERE team_id = ? AND user_id = ?').run(role, teamId, userId);
|
|
287
|
+
return {
|
|
288
|
+
teamId,
|
|
289
|
+
userId,
|
|
290
|
+
role: role,
|
|
291
|
+
joinedAt: member.joinedAt,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Remove a member from a team.
|
|
296
|
+
*
|
|
297
|
+
* The team owner cannot be removed; use a dedicated transfer-ownership flow
|
|
298
|
+
* before deleting the team.
|
|
299
|
+
*/
|
|
300
|
+
export async function removeMember(teamId, userId, requesterId) {
|
|
301
|
+
if (requesterId) {
|
|
302
|
+
const requesterMember = getTeamMember(teamId, requesterId);
|
|
303
|
+
if (!requesterMember || !['owner', 'admin'].includes(requesterMember.role)) {
|
|
304
|
+
throw new Error('Only team owners and admins can remove members');
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
const member = getTeamMember(teamId, userId);
|
|
308
|
+
if (!member) {
|
|
309
|
+
throw new Error('Member not found');
|
|
310
|
+
}
|
|
311
|
+
if (member.role === 'owner') {
|
|
312
|
+
throw new Error('Cannot remove the team owner');
|
|
313
|
+
}
|
|
314
|
+
stateRemoveTeamMember(teamId, userId);
|
|
315
|
+
}
|