@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,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified schema with all 16 tables for the Nimbus persistence layer.
|
|
3
|
+
*
|
|
4
|
+
* Tables cover: operations, config, templates, conversations, artifacts,
|
|
5
|
+
* projects, audit_logs, safety_checks, checkpoints, device_codes, tokens,
|
|
6
|
+
* teams, team_members, users, subscriptions, and usage.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Run all CREATE TABLE / CREATE INDEX migrations against the given database.
|
|
10
|
+
* Every statement uses IF NOT EXISTS so the function is safe to call on an
|
|
11
|
+
* already-initialised database.
|
|
12
|
+
*/
|
|
13
|
+
export function runMigrations(db) {
|
|
14
|
+
db.exec(`
|
|
15
|
+
-- Operations / history
|
|
16
|
+
CREATE TABLE IF NOT EXISTS operations (
|
|
17
|
+
id TEXT PRIMARY KEY,
|
|
18
|
+
timestamp TEXT NOT NULL DEFAULT (datetime('now')),
|
|
19
|
+
type TEXT NOT NULL,
|
|
20
|
+
command TEXT NOT NULL,
|
|
21
|
+
input TEXT,
|
|
22
|
+
output TEXT,
|
|
23
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
24
|
+
duration_ms INTEGER,
|
|
25
|
+
model TEXT,
|
|
26
|
+
tokens_used INTEGER,
|
|
27
|
+
cost_usd REAL,
|
|
28
|
+
metadata TEXT
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
-- Config key-value store
|
|
32
|
+
CREATE TABLE IF NOT EXISTS config (
|
|
33
|
+
key TEXT PRIMARY KEY,
|
|
34
|
+
value TEXT NOT NULL,
|
|
35
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
-- Templates
|
|
39
|
+
CREATE TABLE IF NOT EXISTS templates (
|
|
40
|
+
id TEXT PRIMARY KEY,
|
|
41
|
+
name TEXT NOT NULL,
|
|
42
|
+
type TEXT NOT NULL,
|
|
43
|
+
content TEXT NOT NULL,
|
|
44
|
+
variables TEXT,
|
|
45
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
46
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
-- Conversations
|
|
50
|
+
CREATE TABLE IF NOT EXISTS conversations (
|
|
51
|
+
id TEXT PRIMARY KEY,
|
|
52
|
+
title TEXT NOT NULL,
|
|
53
|
+
messages TEXT NOT NULL,
|
|
54
|
+
model TEXT,
|
|
55
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
56
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
57
|
+
metadata TEXT
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
-- Artifacts
|
|
61
|
+
CREATE TABLE IF NOT EXISTS artifacts (
|
|
62
|
+
id TEXT PRIMARY KEY,
|
|
63
|
+
conversation_id TEXT,
|
|
64
|
+
name TEXT NOT NULL,
|
|
65
|
+
type TEXT NOT NULL,
|
|
66
|
+
content TEXT NOT NULL,
|
|
67
|
+
language TEXT,
|
|
68
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
69
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
70
|
+
metadata TEXT
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
-- Projects
|
|
74
|
+
CREATE TABLE IF NOT EXISTS projects (
|
|
75
|
+
id TEXT PRIMARY KEY,
|
|
76
|
+
name TEXT NOT NULL,
|
|
77
|
+
path TEXT NOT NULL UNIQUE,
|
|
78
|
+
config TEXT NOT NULL DEFAULT '{}',
|
|
79
|
+
last_scanned TEXT,
|
|
80
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
81
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
-- Audit logs
|
|
85
|
+
CREATE TABLE IF NOT EXISTS audit_logs (
|
|
86
|
+
id TEXT PRIMARY KEY,
|
|
87
|
+
timestamp TEXT NOT NULL DEFAULT (datetime('now')),
|
|
88
|
+
user_id TEXT,
|
|
89
|
+
action TEXT NOT NULL,
|
|
90
|
+
resource_type TEXT,
|
|
91
|
+
resource_id TEXT,
|
|
92
|
+
input TEXT,
|
|
93
|
+
output TEXT,
|
|
94
|
+
status TEXT NOT NULL,
|
|
95
|
+
duration_ms INTEGER,
|
|
96
|
+
metadata TEXT
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
-- Safety checks
|
|
100
|
+
CREATE TABLE IF NOT EXISTS safety_checks (
|
|
101
|
+
id TEXT PRIMARY KEY,
|
|
102
|
+
operation_id TEXT,
|
|
103
|
+
check_type TEXT NOT NULL,
|
|
104
|
+
check_name TEXT NOT NULL,
|
|
105
|
+
passed INTEGER NOT NULL DEFAULT 0,
|
|
106
|
+
severity TEXT,
|
|
107
|
+
message TEXT,
|
|
108
|
+
requires_approval INTEGER NOT NULL DEFAULT 0,
|
|
109
|
+
approved_by TEXT,
|
|
110
|
+
approved_at TEXT,
|
|
111
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
-- Checkpoints (resumable operations)
|
|
115
|
+
CREATE TABLE IF NOT EXISTS checkpoints (
|
|
116
|
+
id TEXT PRIMARY KEY,
|
|
117
|
+
operation_id TEXT NOT NULL,
|
|
118
|
+
step INTEGER NOT NULL,
|
|
119
|
+
state TEXT NOT NULL,
|
|
120
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
-- Device codes (auth)
|
|
124
|
+
CREATE TABLE IF NOT EXISTS device_codes (
|
|
125
|
+
device_code TEXT PRIMARY KEY,
|
|
126
|
+
user_code TEXT NOT NULL UNIQUE,
|
|
127
|
+
client_id TEXT,
|
|
128
|
+
scope TEXT,
|
|
129
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
130
|
+
token TEXT,
|
|
131
|
+
expires_at TEXT NOT NULL,
|
|
132
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
-- Auth tokens
|
|
136
|
+
CREATE TABLE IF NOT EXISTS tokens (
|
|
137
|
+
id TEXT PRIMARY KEY,
|
|
138
|
+
user_id TEXT,
|
|
139
|
+
token TEXT NOT NULL UNIQUE,
|
|
140
|
+
type TEXT NOT NULL DEFAULT 'access',
|
|
141
|
+
expires_at TEXT,
|
|
142
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
-- Teams
|
|
146
|
+
CREATE TABLE IF NOT EXISTS teams (
|
|
147
|
+
id TEXT PRIMARY KEY,
|
|
148
|
+
name TEXT NOT NULL,
|
|
149
|
+
owner_id TEXT NOT NULL,
|
|
150
|
+
plan TEXT NOT NULL DEFAULT 'free',
|
|
151
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
152
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
-- Team members
|
|
156
|
+
CREATE TABLE IF NOT EXISTS team_members (
|
|
157
|
+
id TEXT PRIMARY KEY,
|
|
158
|
+
team_id TEXT NOT NULL,
|
|
159
|
+
user_id TEXT NOT NULL,
|
|
160
|
+
role TEXT NOT NULL DEFAULT 'member',
|
|
161
|
+
joined_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
162
|
+
FOREIGN KEY (team_id) REFERENCES teams(id) ON DELETE CASCADE
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
-- Users
|
|
166
|
+
CREATE TABLE IF NOT EXISTS users (
|
|
167
|
+
id TEXT PRIMARY KEY,
|
|
168
|
+
email TEXT UNIQUE,
|
|
169
|
+
name TEXT,
|
|
170
|
+
avatar_url TEXT,
|
|
171
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
172
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
-- Subscriptions (billing)
|
|
176
|
+
CREATE TABLE IF NOT EXISTS subscriptions (
|
|
177
|
+
id TEXT PRIMARY KEY,
|
|
178
|
+
team_id TEXT NOT NULL,
|
|
179
|
+
plan TEXT NOT NULL DEFAULT 'free',
|
|
180
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
181
|
+
current_period_start TEXT,
|
|
182
|
+
current_period_end TEXT,
|
|
183
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
184
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
185
|
+
FOREIGN KEY (team_id) REFERENCES teams(id) ON DELETE CASCADE
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
-- Usage tracking (billing)
|
|
189
|
+
CREATE TABLE IF NOT EXISTS usage (
|
|
190
|
+
id TEXT PRIMARY KEY,
|
|
191
|
+
team_id TEXT,
|
|
192
|
+
user_id TEXT,
|
|
193
|
+
type TEXT NOT NULL,
|
|
194
|
+
quantity REAL NOT NULL DEFAULT 0,
|
|
195
|
+
unit TEXT NOT NULL DEFAULT 'tokens',
|
|
196
|
+
cost_usd REAL DEFAULT 0,
|
|
197
|
+
metadata TEXT,
|
|
198
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
-- Shared sessions
|
|
202
|
+
CREATE TABLE IF NOT EXISTS shares (
|
|
203
|
+
id TEXT PRIMARY KEY,
|
|
204
|
+
session_id TEXT NOT NULL,
|
|
205
|
+
name TEXT NOT NULL,
|
|
206
|
+
messages TEXT NOT NULL,
|
|
207
|
+
model TEXT,
|
|
208
|
+
mode TEXT,
|
|
209
|
+
cost_usd REAL DEFAULT 0,
|
|
210
|
+
token_count INTEGER DEFAULT 0,
|
|
211
|
+
is_live INTEGER NOT NULL DEFAULT 0,
|
|
212
|
+
write_token TEXT,
|
|
213
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
214
|
+
expires_at TEXT NOT NULL
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
-- Indexes
|
|
218
|
+
CREATE INDEX IF NOT EXISTS idx_operations_timestamp ON operations(timestamp);
|
|
219
|
+
CREATE INDEX IF NOT EXISTS idx_operations_type ON operations(type);
|
|
220
|
+
CREATE INDEX IF NOT EXISTS idx_conversations_updated ON conversations(updated_at);
|
|
221
|
+
CREATE INDEX IF NOT EXISTS idx_artifacts_type ON artifacts(type);
|
|
222
|
+
CREATE INDEX IF NOT EXISTS idx_artifacts_conversation ON artifacts(conversation_id);
|
|
223
|
+
CREATE INDEX IF NOT EXISTS idx_audit_logs_timestamp ON audit_logs(timestamp);
|
|
224
|
+
CREATE INDEX IF NOT EXISTS idx_audit_logs_user ON audit_logs(user_id);
|
|
225
|
+
CREATE INDEX IF NOT EXISTS idx_audit_logs_action ON audit_logs(action);
|
|
226
|
+
CREATE INDEX IF NOT EXISTS idx_checkpoints_operation ON checkpoints(operation_id);
|
|
227
|
+
CREATE INDEX IF NOT EXISTS idx_team_members_team ON team_members(team_id);
|
|
228
|
+
CREATE INDEX IF NOT EXISTS idx_usage_team ON usage(team_id);
|
|
229
|
+
CREATE INDEX IF NOT EXISTS idx_usage_created ON usage(created_at);
|
|
230
|
+
CREATE INDEX IF NOT EXISTS idx_shares_session ON shares(session_id);
|
|
231
|
+
CREATE INDEX IF NOT EXISTS idx_shares_expires ON shares(expires_at);
|
|
232
|
+
`);
|
|
233
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session / operation CRUD helpers.
|
|
3
|
+
*
|
|
4
|
+
* Refactored from SQLiteAdapter.saveOperation, getOperation, listOperations,
|
|
5
|
+
* and listOperationsByType.
|
|
6
|
+
*/
|
|
7
|
+
import { getDb } from './db';
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Internal helpers
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
function rowToOperation(row) {
|
|
12
|
+
return {
|
|
13
|
+
id: row.id,
|
|
14
|
+
timestamp: new Date(row.timestamp),
|
|
15
|
+
type: row.type,
|
|
16
|
+
command: row.command,
|
|
17
|
+
input: row.input,
|
|
18
|
+
output: row.output,
|
|
19
|
+
status: row.status,
|
|
20
|
+
durationMs: row.duration_ms,
|
|
21
|
+
model: row.model,
|
|
22
|
+
tokensUsed: row.tokens_used,
|
|
23
|
+
costUsd: row.cost_usd,
|
|
24
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : undefined,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Public API
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
/**
|
|
31
|
+
* Persist a single operation record.
|
|
32
|
+
*/
|
|
33
|
+
export function saveOperation(operation, db) {
|
|
34
|
+
const d = db || getDb();
|
|
35
|
+
const stmt = d.prepare(`
|
|
36
|
+
INSERT INTO operations (id, timestamp, type, command, input, output, status, duration_ms, model, tokens_used, cost_usd, metadata)
|
|
37
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
38
|
+
`);
|
|
39
|
+
stmt.run(operation.id, operation.timestamp.toISOString(), operation.type, operation.command, operation.input || null, operation.output || null, operation.status, operation.durationMs || null, operation.model || null, operation.tokensUsed || null, operation.costUsd || null, operation.metadata ? JSON.stringify(operation.metadata) : null);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Retrieve a single operation by id.
|
|
43
|
+
*/
|
|
44
|
+
export function getOperation(id, db) {
|
|
45
|
+
const d = db || getDb();
|
|
46
|
+
const stmt = d.prepare('SELECT * FROM operations WHERE id = ?');
|
|
47
|
+
const row = stmt.get(id);
|
|
48
|
+
if (!row) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
return rowToOperation(row);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* List operations ordered by timestamp descending.
|
|
55
|
+
*/
|
|
56
|
+
export function listOperations(limit = 50, offset = 0, db) {
|
|
57
|
+
const d = db || getDb();
|
|
58
|
+
const stmt = d.prepare(`
|
|
59
|
+
SELECT * FROM operations
|
|
60
|
+
ORDER BY timestamp DESC
|
|
61
|
+
LIMIT ? OFFSET ?
|
|
62
|
+
`);
|
|
63
|
+
const rows = stmt.all(limit, offset);
|
|
64
|
+
return rows.map(row => rowToOperation(row));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* List operations filtered by type, ordered by timestamp descending.
|
|
68
|
+
*/
|
|
69
|
+
export function listOperationsByType(type, limit = 50, offset = 0, db) {
|
|
70
|
+
const d = db || getDb();
|
|
71
|
+
const stmt = d.prepare(`
|
|
72
|
+
SELECT * FROM operations
|
|
73
|
+
WHERE type = ?
|
|
74
|
+
ORDER BY timestamp DESC
|
|
75
|
+
LIMIT ? OFFSET ?
|
|
76
|
+
`);
|
|
77
|
+
const rows = stmt.all(type, limit, offset);
|
|
78
|
+
return rows.map(row => rowToOperation(row));
|
|
79
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team and user CRUD helpers.
|
|
3
|
+
*
|
|
4
|
+
* Refactored from the team-service database adapter
|
|
5
|
+
* (services/team-service/src/db/adapter.ts) into standalone functions
|
|
6
|
+
* that operate against the unified Nimbus database.
|
|
7
|
+
*/
|
|
8
|
+
import { getDb } from './db';
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Team helpers
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
/**
|
|
13
|
+
* Create a new team.
|
|
14
|
+
*/
|
|
15
|
+
export function createTeam(id, name, ownerId, plan = 'free', db) {
|
|
16
|
+
const d = db || getDb();
|
|
17
|
+
const stmt = d.prepare(`
|
|
18
|
+
INSERT INTO teams (id, name, owner_id, plan, created_at, updated_at)
|
|
19
|
+
VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
|
20
|
+
`);
|
|
21
|
+
stmt.run(id, name, ownerId, plan);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Retrieve a team by id.
|
|
25
|
+
*/
|
|
26
|
+
export function getTeam(id, db) {
|
|
27
|
+
const d = db || getDb();
|
|
28
|
+
const stmt = d.prepare('SELECT * FROM teams WHERE id = ?');
|
|
29
|
+
const row = stmt.get(id);
|
|
30
|
+
if (!row) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
id: row.id,
|
|
35
|
+
name: row.name,
|
|
36
|
+
ownerId: row.owner_id,
|
|
37
|
+
plan: row.plan,
|
|
38
|
+
createdAt: row.created_at,
|
|
39
|
+
updatedAt: row.updated_at,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* List all teams, ordered by most-recently updated first.
|
|
44
|
+
*/
|
|
45
|
+
export function listTeams(db) {
|
|
46
|
+
const d = db || getDb();
|
|
47
|
+
const stmt = d.prepare('SELECT * FROM teams ORDER BY updated_at DESC');
|
|
48
|
+
const rows = stmt.all();
|
|
49
|
+
return rows.map(row => ({
|
|
50
|
+
id: row.id,
|
|
51
|
+
name: row.name,
|
|
52
|
+
ownerId: row.owner_id,
|
|
53
|
+
plan: row.plan,
|
|
54
|
+
createdAt: row.created_at,
|
|
55
|
+
updatedAt: row.updated_at,
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Team member helpers
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
/**
|
|
62
|
+
* Add a member to a team.
|
|
63
|
+
*/
|
|
64
|
+
export function addTeamMember(id, teamId, userId, role = 'member', db) {
|
|
65
|
+
const d = db || getDb();
|
|
66
|
+
const stmt = d.prepare(`
|
|
67
|
+
INSERT INTO team_members (id, team_id, user_id, role, joined_at)
|
|
68
|
+
VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP)
|
|
69
|
+
`);
|
|
70
|
+
stmt.run(id, teamId, userId, role);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Remove a member from a team by user id.
|
|
74
|
+
*/
|
|
75
|
+
export function removeTeamMember(teamId, userId, db) {
|
|
76
|
+
const d = db || getDb();
|
|
77
|
+
const stmt = d.prepare('DELETE FROM team_members WHERE team_id = ? AND user_id = ?');
|
|
78
|
+
stmt.run(teamId, userId);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* List all members of a team.
|
|
82
|
+
*/
|
|
83
|
+
export function listTeamMembers(teamId, db) {
|
|
84
|
+
const d = db || getDb();
|
|
85
|
+
const stmt = d.prepare(`
|
|
86
|
+
SELECT * FROM team_members
|
|
87
|
+
WHERE team_id = ?
|
|
88
|
+
ORDER BY joined_at ASC
|
|
89
|
+
`);
|
|
90
|
+
const rows = stmt.all(teamId);
|
|
91
|
+
return rows.map(row => ({
|
|
92
|
+
id: row.id,
|
|
93
|
+
teamId: row.team_id,
|
|
94
|
+
userId: row.user_id,
|
|
95
|
+
role: row.role,
|
|
96
|
+
joinedAt: row.joined_at,
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
// User helpers
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
/**
|
|
103
|
+
* Create a new user.
|
|
104
|
+
*/
|
|
105
|
+
export function createUser(id, email, name, avatarUrl, db) {
|
|
106
|
+
const d = db || getDb();
|
|
107
|
+
const stmt = d.prepare(`
|
|
108
|
+
INSERT INTO users (id, email, name, avatar_url, created_at, updated_at)
|
|
109
|
+
VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
|
110
|
+
`);
|
|
111
|
+
stmt.run(id, email || null, name || null, avatarUrl || null);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Retrieve a user by id.
|
|
115
|
+
*/
|
|
116
|
+
export function getUser(id, db) {
|
|
117
|
+
const d = db || getDb();
|
|
118
|
+
const stmt = d.prepare('SELECT * FROM users WHERE id = ?');
|
|
119
|
+
const row = stmt.get(id);
|
|
120
|
+
if (!row) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
id: row.id,
|
|
125
|
+
email: row.email,
|
|
126
|
+
name: row.name,
|
|
127
|
+
avatarUrl: row.avatar_url,
|
|
128
|
+
createdAt: row.created_at,
|
|
129
|
+
updatedAt: row.updated_at,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telemetry Module
|
|
3
|
+
*
|
|
4
|
+
* Thin wrapper around the PostHog analytics client (src/utils/analytics.ts).
|
|
5
|
+
* Reads the user's opt-in preference from ~/.nimbus/config.json and only
|
|
6
|
+
* forwards events when telemetry is explicitly enabled.
|
|
7
|
+
*
|
|
8
|
+
* Every exported function is guaranteed to never throw -- callers do not
|
|
9
|
+
* need try-catch around telemetry calls (though several already have it).
|
|
10
|
+
*/
|
|
11
|
+
import { analytics } from './utils/analytics';
|
|
12
|
+
/**
|
|
13
|
+
* Read the telemetry section from ~/.nimbus/config.json.
|
|
14
|
+
* Returns `{ enabled: false }` on any error so the default is always off.
|
|
15
|
+
*/
|
|
16
|
+
function readTelemetryConfig() {
|
|
17
|
+
try {
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
19
|
+
const fs = require('node:fs');
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
21
|
+
const path = require('node:path');
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
23
|
+
const { homedir } = require('os');
|
|
24
|
+
const configPath = path.join(homedir(), '.nimbus', 'config.json');
|
|
25
|
+
if (!fs.existsSync(configPath)) {
|
|
26
|
+
return { enabled: false };
|
|
27
|
+
}
|
|
28
|
+
const raw = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
29
|
+
return raw?.telemetry ?? { enabled: false };
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return { enabled: false };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Cache the config for the lifetime of the process so we only read the
|
|
36
|
+
// filesystem once. The user would need to restart nimbus after toggling
|
|
37
|
+
// telemetry anyway, so a stale value is acceptable.
|
|
38
|
+
let _cachedConfig = null;
|
|
39
|
+
function getConfig() {
|
|
40
|
+
if (_cachedConfig === null) {
|
|
41
|
+
_cachedConfig = readTelemetryConfig();
|
|
42
|
+
}
|
|
43
|
+
return _cachedConfig;
|
|
44
|
+
}
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Public API
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
/**
|
|
49
|
+
* Track an IaC generation event (terraform apply, k8s apply, helm install, etc.).
|
|
50
|
+
*
|
|
51
|
+
* @param type - A short identifier for the generation kind, e.g. "terraform-apply"
|
|
52
|
+
* @param tags - Freeform tags for categorisation, e.g. ["terraform"]
|
|
53
|
+
*/
|
|
54
|
+
export function trackGeneration(type, tags) {
|
|
55
|
+
try {
|
|
56
|
+
const config = getConfig();
|
|
57
|
+
if (!config.enabled) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// Fire-and-forget -- analytics.trackEvent already swallows errors.
|
|
61
|
+
analytics.trackEvent('generation', {
|
|
62
|
+
type,
|
|
63
|
+
tags,
|
|
64
|
+
userId: config.anonymousId,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// Absolutely never throw from telemetry.
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Track a generic named event with optional properties.
|
|
73
|
+
*
|
|
74
|
+
* @param name - The event name, e.g. "analysis_completed"
|
|
75
|
+
* @param properties - Arbitrary key/value metadata
|
|
76
|
+
*/
|
|
77
|
+
export function trackEvent(name, properties) {
|
|
78
|
+
try {
|
|
79
|
+
const config = getConfig();
|
|
80
|
+
if (!config.enabled) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
analytics.trackEvent(name, {
|
|
84
|
+
...properties,
|
|
85
|
+
userId: config.anonymousId,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// Absolutely never throw from telemetry.
|
|
90
|
+
}
|
|
91
|
+
}
|