@build-astron-co/nimbus 0.2.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/LICENSE +21 -0
- package/README.md +628 -0
- package/bin/nimbus +38 -0
- package/package.json +80 -0
- package/src/__tests__/app.test.ts +76 -0
- package/src/__tests__/audit.test.ts +877 -0
- package/src/__tests__/circuit-breaker.test.ts +116 -0
- package/src/__tests__/cli-run.test.ts +115 -0
- package/src/__tests__/context-manager.test.ts +502 -0
- package/src/__tests__/context.test.ts +242 -0
- package/src/__tests__/enterprise.test.ts +401 -0
- package/src/__tests__/generator.test.ts +433 -0
- package/src/__tests__/hooks.test.ts +582 -0
- package/src/__tests__/init.test.ts +436 -0
- package/src/__tests__/intent-parser.test.ts +229 -0
- package/src/__tests__/llm-router.test.ts +209 -0
- package/src/__tests__/lsp.test.ts +293 -0
- package/src/__tests__/modes.test.ts +336 -0
- package/src/__tests__/permissions.test.ts +338 -0
- package/src/__tests__/serve.test.ts +275 -0
- package/src/__tests__/sessions.test.ts +227 -0
- package/src/__tests__/sharing.test.ts +288 -0
- package/src/__tests__/snapshots.test.ts +581 -0
- package/src/__tests__/state-db.test.ts +334 -0
- package/src/__tests__/stream-with-tools.test.ts +732 -0
- package/src/__tests__/subagents.test.ts +176 -0
- package/src/__tests__/system-prompt.test.ts +169 -0
- package/src/__tests__/tool-converter.test.ts +256 -0
- package/src/__tests__/tool-schemas.test.ts +397 -0
- package/src/__tests__/tools.test.ts +143 -0
- package/src/__tests__/version.test.ts +49 -0
- package/src/agent/compaction-agent.ts +227 -0
- package/src/agent/context-manager.ts +435 -0
- package/src/agent/context.ts +427 -0
- package/src/agent/deploy-preview.ts +426 -0
- package/src/agent/index.ts +68 -0
- package/src/agent/loop.ts +717 -0
- package/src/agent/modes.ts +429 -0
- package/src/agent/permissions.ts +466 -0
- package/src/agent/subagents/base.ts +116 -0
- package/src/agent/subagents/cost.ts +51 -0
- package/src/agent/subagents/explore.ts +42 -0
- package/src/agent/subagents/general.ts +54 -0
- package/src/agent/subagents/index.ts +102 -0
- package/src/agent/subagents/infra.ts +59 -0
- package/src/agent/subagents/security.ts +69 -0
- package/src/agent/system-prompt.ts +436 -0
- package/src/app.ts +122 -0
- package/src/audit/activity-log.ts +290 -0
- package/src/audit/compliance-checker.ts +540 -0
- package/src/audit/cost-tracker.ts +318 -0
- package/src/audit/index.ts +23 -0
- package/src/audit/security-scanner.ts +596 -0
- package/src/auth/guard.ts +75 -0
- package/src/auth/index.ts +56 -0
- package/src/auth/oauth.ts +455 -0
- package/src/auth/providers.ts +470 -0
- package/src/auth/sso.ts +113 -0
- package/src/auth/store.ts +505 -0
- package/src/auth/types.ts +187 -0
- package/src/build.ts +141 -0
- package/src/cli/index.ts +16 -0
- package/src/cli/init.ts +854 -0
- package/src/cli/openapi-spec.ts +356 -0
- package/src/cli/run.ts +237 -0
- package/src/cli/serve-auth.ts +80 -0
- package/src/cli/serve.ts +462 -0
- package/src/cli/web.ts +67 -0
- package/src/cli.ts +1417 -0
- package/src/clients/core-engine-client.ts +227 -0
- package/src/clients/enterprise-client.ts +334 -0
- package/src/clients/generator-client.ts +351 -0
- package/src/clients/git-client.ts +627 -0
- package/src/clients/github-client.ts +410 -0
- package/src/clients/helm-client.ts +504 -0
- package/src/clients/index.ts +80 -0
- package/src/clients/k8s-client.ts +497 -0
- package/src/clients/llm-client.ts +161 -0
- package/src/clients/rest-client.ts +130 -0
- package/src/clients/service-discovery.ts +33 -0
- package/src/clients/terraform-client.ts +482 -0
- package/src/clients/tools-client.ts +1843 -0
- package/src/clients/ws-client.ts +115 -0
- package/src/commands/analyze/index.ts +352 -0
- package/src/commands/apply/helm.ts +473 -0
- package/src/commands/apply/index.ts +213 -0
- package/src/commands/apply/k8s.ts +454 -0
- package/src/commands/apply/terraform.ts +582 -0
- package/src/commands/ask.ts +167 -0
- package/src/commands/audit/index.ts +238 -0
- package/src/commands/auth-cloud.ts +294 -0
- package/src/commands/auth-list.ts +134 -0
- package/src/commands/auth-profile.ts +121 -0
- package/src/commands/auth-status.ts +141 -0
- package/src/commands/aws/ec2.ts +501 -0
- package/src/commands/aws/iam.ts +397 -0
- package/src/commands/aws/index.ts +133 -0
- package/src/commands/aws/lambda.ts +396 -0
- package/src/commands/aws/rds.ts +439 -0
- package/src/commands/aws/s3.ts +439 -0
- package/src/commands/aws/vpc.ts +393 -0
- package/src/commands/aws-discover.ts +649 -0
- package/src/commands/aws-terraform.ts +805 -0
- package/src/commands/azure/aks.ts +376 -0
- package/src/commands/azure/functions.ts +253 -0
- package/src/commands/azure/index.ts +116 -0
- package/src/commands/azure/storage.ts +478 -0
- package/src/commands/azure/vm.ts +355 -0
- package/src/commands/billing/index.ts +256 -0
- package/src/commands/chat.ts +314 -0
- package/src/commands/config.ts +346 -0
- package/src/commands/cost/cloud-cost-estimator.ts +266 -0
- package/src/commands/cost/estimator.ts +79 -0
- package/src/commands/cost/index.ts +594 -0
- package/src/commands/cost/parsers/terraform.ts +273 -0
- package/src/commands/cost/parsers/types.ts +25 -0
- package/src/commands/cost/pricing/aws.ts +544 -0
- package/src/commands/cost/pricing/azure.ts +499 -0
- package/src/commands/cost/pricing/gcp.ts +396 -0
- package/src/commands/cost/pricing/index.ts +40 -0
- package/src/commands/demo.ts +250 -0
- package/src/commands/doctor.ts +794 -0
- package/src/commands/drift/index.ts +439 -0
- package/src/commands/explain.ts +277 -0
- package/src/commands/feedback.ts +389 -0
- package/src/commands/fix.ts +324 -0
- package/src/commands/fs/index.ts +402 -0
- package/src/commands/gcp/compute.ts +325 -0
- package/src/commands/gcp/functions.ts +271 -0
- package/src/commands/gcp/gke.ts +438 -0
- package/src/commands/gcp/iam.ts +344 -0
- package/src/commands/gcp/index.ts +129 -0
- package/src/commands/gcp/storage.ts +284 -0
- package/src/commands/generate-helm.ts +1249 -0
- package/src/commands/generate-k8s.ts +1560 -0
- package/src/commands/generate-terraform.ts +1460 -0
- package/src/commands/gh/index.ts +863 -0
- package/src/commands/git/index.ts +1343 -0
- package/src/commands/helm/index.ts +1126 -0
- package/src/commands/help.ts +539 -0
- package/src/commands/history.ts +142 -0
- package/src/commands/import.ts +868 -0
- package/src/commands/index.ts +367 -0
- package/src/commands/init.ts +1046 -0
- package/src/commands/k8s/index.ts +1137 -0
- package/src/commands/login.ts +631 -0
- package/src/commands/logout.ts +83 -0
- package/src/commands/onboarding.ts +228 -0
- package/src/commands/plan/display.ts +279 -0
- package/src/commands/plan/index.ts +599 -0
- package/src/commands/preview.ts +452 -0
- package/src/commands/questionnaire.ts +1270 -0
- package/src/commands/resume.ts +55 -0
- package/src/commands/team/index.ts +346 -0
- package/src/commands/template.ts +232 -0
- package/src/commands/tf/index.ts +1034 -0
- package/src/commands/upgrade.ts +550 -0
- package/src/commands/usage/index.ts +134 -0
- package/src/commands/version.ts +170 -0
- package/src/compat/index.ts +2 -0
- package/src/compat/runtime.ts +12 -0
- package/src/compat/sqlite.ts +107 -0
- package/src/config/index.ts +17 -0
- package/src/config/manager.ts +530 -0
- package/src/config/safety-policy.ts +358 -0
- package/src/config/schema.ts +125 -0
- package/src/config/types.ts +527 -0
- package/src/context/context-db.ts +199 -0
- package/src/demo/index.ts +349 -0
- package/src/demo/scenarios/full-journey.ts +229 -0
- package/src/demo/scenarios/getting-started.ts +127 -0
- package/src/demo/scenarios/helm-release.ts +341 -0
- package/src/demo/scenarios/k8s-deployment.ts +194 -0
- package/src/demo/scenarios/terraform-vpc.ts +170 -0
- package/src/demo/types.ts +92 -0
- package/src/engine/cost-estimator.ts +438 -0
- package/src/engine/diagram-generator.ts +256 -0
- package/src/engine/drift-detector.ts +902 -0
- package/src/engine/executor.ts +1035 -0
- package/src/engine/index.ts +76 -0
- package/src/engine/orchestrator.ts +636 -0
- package/src/engine/planner.ts +720 -0
- package/src/engine/safety.ts +743 -0
- package/src/engine/verifier.ts +770 -0
- package/src/enterprise/audit.ts +348 -0
- package/src/enterprise/auth.ts +270 -0
- package/src/enterprise/billing.ts +822 -0
- package/src/enterprise/index.ts +17 -0
- package/src/enterprise/teams.ts +443 -0
- package/src/generator/best-practices.ts +1608 -0
- package/src/generator/helm.ts +630 -0
- package/src/generator/index.ts +37 -0
- package/src/generator/intent-parser.ts +514 -0
- package/src/generator/kubernetes.ts +976 -0
- package/src/generator/terraform.ts +1867 -0
- package/src/history/index.ts +8 -0
- package/src/history/manager.ts +322 -0
- package/src/history/types.ts +34 -0
- package/src/hooks/config.ts +432 -0
- package/src/hooks/engine.ts +391 -0
- package/src/hooks/index.ts +4 -0
- package/src/llm/auth-bridge.ts +198 -0
- package/src/llm/circuit-breaker.ts +140 -0
- package/src/llm/config-loader.ts +201 -0
- package/src/llm/cost-calculator.ts +171 -0
- package/src/llm/index.ts +8 -0
- package/src/llm/model-aliases.ts +115 -0
- package/src/llm/provider-registry.ts +63 -0
- package/src/llm/providers/anthropic.ts +433 -0
- package/src/llm/providers/bedrock.ts +477 -0
- package/src/llm/providers/google.ts +405 -0
- package/src/llm/providers/ollama.ts +767 -0
- package/src/llm/providers/openai-compatible.ts +340 -0
- package/src/llm/providers/openai.ts +328 -0
- package/src/llm/providers/openrouter.ts +338 -0
- package/src/llm/router.ts +1035 -0
- package/src/llm/types.ts +232 -0
- package/src/lsp/client.ts +298 -0
- package/src/lsp/languages.ts +116 -0
- package/src/lsp/manager.ts +278 -0
- package/src/mcp/client.ts +402 -0
- package/src/mcp/index.ts +5 -0
- package/src/mcp/manager.ts +133 -0
- package/src/nimbus.ts +214 -0
- package/src/plugins/index.ts +27 -0
- package/src/plugins/loader.ts +334 -0
- package/src/plugins/manager.ts +376 -0
- package/src/plugins/types.ts +284 -0
- package/src/scanners/cicd-scanner.ts +258 -0
- package/src/scanners/cloud-scanner.ts +466 -0
- package/src/scanners/framework-scanner.ts +469 -0
- package/src/scanners/iac-scanner.ts +388 -0
- package/src/scanners/index.ts +539 -0
- package/src/scanners/language-scanner.ts +276 -0
- package/src/scanners/package-manager-scanner.ts +277 -0
- package/src/scanners/types.ts +172 -0
- package/src/sessions/manager.ts +365 -0
- package/src/sessions/types.ts +44 -0
- package/src/sharing/sync.ts +296 -0
- package/src/sharing/viewer.ts +97 -0
- package/src/snapshots/index.ts +2 -0
- package/src/snapshots/manager.ts +530 -0
- package/src/state/artifacts.ts +147 -0
- package/src/state/audit.ts +137 -0
- package/src/state/billing.ts +240 -0
- package/src/state/checkpoints.ts +117 -0
- package/src/state/config.ts +67 -0
- package/src/state/conversations.ts +14 -0
- package/src/state/credentials.ts +154 -0
- package/src/state/db.ts +58 -0
- package/src/state/index.ts +26 -0
- package/src/state/messages.ts +115 -0
- package/src/state/projects.ts +123 -0
- package/src/state/schema.ts +236 -0
- package/src/state/sessions.ts +147 -0
- package/src/state/teams.ts +200 -0
- package/src/telemetry.ts +108 -0
- package/src/tools/aws-ops.ts +952 -0
- package/src/tools/azure-ops.ts +579 -0
- package/src/tools/file-ops.ts +593 -0
- package/src/tools/gcp-ops.ts +625 -0
- package/src/tools/git-ops.ts +773 -0
- package/src/tools/github-ops.ts +799 -0
- package/src/tools/helm-ops.ts +943 -0
- package/src/tools/index.ts +17 -0
- package/src/tools/k8s-ops.ts +819 -0
- package/src/tools/schemas/converter.ts +184 -0
- package/src/tools/schemas/devops.ts +612 -0
- package/src/tools/schemas/index.ts +73 -0
- package/src/tools/schemas/standard.ts +1144 -0
- package/src/tools/schemas/types.ts +705 -0
- package/src/tools/terraform-ops.ts +862 -0
- package/src/types/ambient.d.ts +193 -0
- package/src/types/config.ts +83 -0
- package/src/types/drift.ts +116 -0
- package/src/types/enterprise.ts +335 -0
- package/src/types/index.ts +20 -0
- package/src/types/plan.ts +44 -0
- package/src/types/request.ts +65 -0
- package/src/types/response.ts +54 -0
- package/src/types/service.ts +51 -0
- package/src/ui/App.tsx +997 -0
- package/src/ui/DeployPreview.tsx +169 -0
- package/src/ui/Header.tsx +68 -0
- package/src/ui/InputBox.tsx +350 -0
- package/src/ui/MessageList.tsx +585 -0
- package/src/ui/PermissionPrompt.tsx +151 -0
- package/src/ui/StatusBar.tsx +158 -0
- package/src/ui/ToolCallDisplay.tsx +409 -0
- package/src/ui/chat-ui.ts +853 -0
- package/src/ui/index.ts +33 -0
- package/src/ui/ink/index.ts +711 -0
- package/src/ui/streaming.ts +176 -0
- package/src/ui/types.ts +57 -0
- package/src/utils/analytics.ts +72 -0
- package/src/utils/cost-warning.ts +27 -0
- package/src/utils/env.ts +46 -0
- package/src/utils/errors.ts +69 -0
- package/src/utils/event-bus.ts +38 -0
- package/src/utils/index.ts +24 -0
- package/src/utils/logger.ts +171 -0
- package/src/utils/rate-limiter.ts +121 -0
- package/src/utils/service-auth.ts +49 -0
- package/src/utils/validation.ts +53 -0
- package/src/version.ts +4 -0
- package/src/watcher/index.ts +163 -0
- package/src/wizard/approval.ts +383 -0
- package/src/wizard/index.ts +25 -0
- package/src/wizard/prompts.ts +338 -0
- package/src/wizard/types.ts +171 -0
- package/src/wizard/ui.ts +556 -0
- package/src/wizard/wizard.ts +304 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth List Command
|
|
3
|
+
*
|
|
4
|
+
* Display all available providers and their configuration status
|
|
5
|
+
*
|
|
6
|
+
* Usage: nimbus auth list
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { logger } from '../utils';
|
|
10
|
+
import { ui } from '../wizard';
|
|
11
|
+
import { authStore, AuthStore, getProviderNames, getProviderInfo } from '../auth';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Command options
|
|
15
|
+
*/
|
|
16
|
+
export interface AuthListOptions {
|
|
17
|
+
json?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Run the auth list command
|
|
22
|
+
*/
|
|
23
|
+
export async function authListCommand(options: AuthListOptions = {}): Promise<void> {
|
|
24
|
+
logger.info('Listing auth providers');
|
|
25
|
+
|
|
26
|
+
const providerNames = getProviderNames();
|
|
27
|
+
const status = authStore.getStatus();
|
|
28
|
+
const configuredProviders = new Set(status.providers.map(p => p.name));
|
|
29
|
+
|
|
30
|
+
// Build provider data
|
|
31
|
+
const providerData = providerNames.map(name => {
|
|
32
|
+
const info = getProviderInfo(name);
|
|
33
|
+
const credential = authStore.getProvider(name);
|
|
34
|
+
const isConfigured = configuredProviders.has(name);
|
|
35
|
+
const isDefault = status.defaultProvider === name;
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
name,
|
|
39
|
+
displayName: info.displayName,
|
|
40
|
+
description: info.description,
|
|
41
|
+
isConfigured,
|
|
42
|
+
isDefault,
|
|
43
|
+
model: credential?.model || info.models.find(m => m.isDefault)?.id || info.models[0].id,
|
|
44
|
+
apiKey: credential?.apiKey,
|
|
45
|
+
baseUrl: credential?.baseUrl,
|
|
46
|
+
requiresApiKey: info.requiresApiKey,
|
|
47
|
+
apiKeyUrl: info.apiKeyUrl,
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// JSON output mode
|
|
52
|
+
if (options.json) {
|
|
53
|
+
const safeOutput = providerData.map(p => ({
|
|
54
|
+
name: p.name,
|
|
55
|
+
displayName: p.displayName,
|
|
56
|
+
description: p.description,
|
|
57
|
+
isConfigured: p.isConfigured,
|
|
58
|
+
isDefault: p.isDefault,
|
|
59
|
+
model: p.model,
|
|
60
|
+
apiKey: p.apiKey ? AuthStore.maskApiKey(p.apiKey) : null,
|
|
61
|
+
baseUrl: p.baseUrl,
|
|
62
|
+
requiresApiKey: p.requiresApiKey,
|
|
63
|
+
}));
|
|
64
|
+
|
|
65
|
+
// Output sanitized JSON (API keys are already masked above)
|
|
66
|
+
ui.print(JSON.stringify(safeOutput, null, 2));
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Human-readable table output
|
|
71
|
+
ui.newLine();
|
|
72
|
+
ui.section('LLM Providers');
|
|
73
|
+
|
|
74
|
+
// Build table data
|
|
75
|
+
const tableData: Array<Record<string, string>> = [];
|
|
76
|
+
|
|
77
|
+
for (const provider of providerData) {
|
|
78
|
+
const statusIcon = provider.isConfigured ? ui.color('✓', 'green') : ui.dim('—');
|
|
79
|
+
const statusText = provider.isConfigured ? 'Configured' : 'Not configured';
|
|
80
|
+
|
|
81
|
+
let apiKeyDisplay: string;
|
|
82
|
+
if (provider.isConfigured && provider.apiKey) {
|
|
83
|
+
apiKeyDisplay = AuthStore.maskApiKey(provider.apiKey);
|
|
84
|
+
} else if (!provider.requiresApiKey) {
|
|
85
|
+
apiKeyDisplay = ui.dim('(not needed)');
|
|
86
|
+
} else if (provider.isConfigured) {
|
|
87
|
+
apiKeyDisplay = ui.dim('(from env)');
|
|
88
|
+
} else {
|
|
89
|
+
apiKeyDisplay = ui.dim('—');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const modelDisplay = provider.isConfigured ? provider.model : ui.dim(provider.model);
|
|
93
|
+
const defaultDisplay = provider.isDefault ? ui.color('★', 'yellow') : '';
|
|
94
|
+
|
|
95
|
+
tableData.push({
|
|
96
|
+
provider: `${statusIcon} ${provider.displayName}`,
|
|
97
|
+
status: statusText,
|
|
98
|
+
apiKey: apiKeyDisplay,
|
|
99
|
+
model: modelDisplay,
|
|
100
|
+
default: defaultDisplay,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Display table
|
|
105
|
+
ui.table({
|
|
106
|
+
columns: [
|
|
107
|
+
{ key: 'provider', header: 'Provider', width: 25 },
|
|
108
|
+
{ key: 'status', header: 'Status', width: 15 },
|
|
109
|
+
{ key: 'apiKey', header: 'API Key', width: 20 },
|
|
110
|
+
{ key: 'model', header: 'Model', width: 30 },
|
|
111
|
+
{ key: 'default', header: 'Default', width: 8 },
|
|
112
|
+
],
|
|
113
|
+
data: tableData,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
ui.newLine();
|
|
117
|
+
|
|
118
|
+
// Show hints for unconfigured providers
|
|
119
|
+
const unconfigured = providerData.filter(p => !p.isConfigured);
|
|
120
|
+
if (unconfigured.length > 0) {
|
|
121
|
+
ui.print(ui.dim('To configure a provider, run `nimbus login`'));
|
|
122
|
+
ui.newLine();
|
|
123
|
+
|
|
124
|
+
ui.print(ui.dim('API key URLs:'));
|
|
125
|
+
for (const provider of unconfigured) {
|
|
126
|
+
if (provider.apiKeyUrl) {
|
|
127
|
+
ui.print(ui.dim(` ${provider.displayName}: ${provider.apiKeyUrl}`));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
ui.newLine();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export default authListCommand;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Profile Commands
|
|
3
|
+
*
|
|
4
|
+
* CLI commands for managing authentication profiles and switching providers
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { AuthStore } from '../auth/store';
|
|
8
|
+
import { ui } from '../wizard/ui';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* List all configured providers
|
|
12
|
+
*/
|
|
13
|
+
async function authProfileListCommand(): Promise<void> {
|
|
14
|
+
ui.header('Auth Profiles');
|
|
15
|
+
|
|
16
|
+
const authStore = new AuthStore();
|
|
17
|
+
const status = authStore.getStatus();
|
|
18
|
+
|
|
19
|
+
if (!status.hasProviders) {
|
|
20
|
+
ui.warning('No providers configured. Run "nimbus login" to set up authentication.');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
ui.table({
|
|
25
|
+
columns: [
|
|
26
|
+
{ key: 'name', header: 'Provider' },
|
|
27
|
+
{ key: 'model', header: 'Model' },
|
|
28
|
+
{ key: 'default', header: 'Default' },
|
|
29
|
+
{ key: 'validatedAt', header: 'Validated' },
|
|
30
|
+
],
|
|
31
|
+
data: status.providers.map(p => ({
|
|
32
|
+
name: p.name,
|
|
33
|
+
model: p.model || '-',
|
|
34
|
+
default: p.isDefault ? 'Yes' : '',
|
|
35
|
+
validatedAt: p.validatedAt ? new Date(p.validatedAt).toLocaleDateString() : '-',
|
|
36
|
+
})),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Show the current default provider
|
|
42
|
+
*/
|
|
43
|
+
async function authProfileShowCommand(): Promise<void> {
|
|
44
|
+
ui.header('Current Auth Profile');
|
|
45
|
+
|
|
46
|
+
const authStore = new AuthStore();
|
|
47
|
+
const defaultProvider = authStore.getDefaultProvider();
|
|
48
|
+
|
|
49
|
+
if (!defaultProvider) {
|
|
50
|
+
ui.warning('No default provider set. Run "nimbus login" to configure.');
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const status = authStore.getStatus();
|
|
55
|
+
const providerInfo = status.providers.find(p => p.name === defaultProvider);
|
|
56
|
+
|
|
57
|
+
ui.print(` ${ui.color('Provider:', 'cyan')} ${defaultProvider}`);
|
|
58
|
+
if (providerInfo) {
|
|
59
|
+
ui.print(` ${ui.color('Model:', 'cyan')} ${providerInfo.model || '-'}`);
|
|
60
|
+
ui.print(
|
|
61
|
+
` ${ui.color('Validated:', 'cyan')} ${providerInfo.validatedAt ? new Date(providerInfo.validatedAt).toLocaleDateString() : '-'}`
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Switch the default provider
|
|
68
|
+
*/
|
|
69
|
+
async function authProfileSwitchCommand(provider: string): Promise<void> {
|
|
70
|
+
ui.header(`Switch Auth Profile`);
|
|
71
|
+
|
|
72
|
+
const authStore = new AuthStore();
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
authStore.setDefaultProvider(provider as any);
|
|
76
|
+
ui.success(`Default provider switched to "${provider}"`);
|
|
77
|
+
ui.info(`Persisted to ${authStore.getAuthPath()}`);
|
|
78
|
+
} catch (error: any) {
|
|
79
|
+
ui.error(error.message);
|
|
80
|
+
ui.info('Available providers:');
|
|
81
|
+
const status = authStore.getStatus();
|
|
82
|
+
status.providers.forEach(p => {
|
|
83
|
+
ui.print(` - ${p.name}${p.isDefault ? ' (current default)' : ''}`);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Main auth-profile command router
|
|
90
|
+
*/
|
|
91
|
+
export async function authProfileCommand(subcommand: string, args: string[]): Promise<void> {
|
|
92
|
+
const positionalArgs: string[] = [];
|
|
93
|
+
|
|
94
|
+
for (let i = 0; i < args.length; i++) {
|
|
95
|
+
const arg = args[i];
|
|
96
|
+
if (!arg.startsWith('-')) {
|
|
97
|
+
positionalArgs.push(arg);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
switch (subcommand) {
|
|
102
|
+
case 'list':
|
|
103
|
+
case 'ls':
|
|
104
|
+
await authProfileListCommand();
|
|
105
|
+
break;
|
|
106
|
+
case 'show':
|
|
107
|
+
await authProfileShowCommand();
|
|
108
|
+
break;
|
|
109
|
+
case 'switch':
|
|
110
|
+
if (positionalArgs.length < 1) {
|
|
111
|
+
ui.error('Usage: nimbus auth-profile switch <provider>');
|
|
112
|
+
ui.info('Example: nimbus auth-profile switch openai');
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
await authProfileSwitchCommand(positionalArgs[0]);
|
|
116
|
+
break;
|
|
117
|
+
default:
|
|
118
|
+
ui.error(`Unknown auth-profile subcommand: ${subcommand || '(none)'}`);
|
|
119
|
+
ui.info('Available commands: list, show, switch <provider>');
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Status Command
|
|
3
|
+
*
|
|
4
|
+
* Display current authentication status
|
|
5
|
+
*
|
|
6
|
+
* Usage: nimbus auth status
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { logger } from '../utils';
|
|
10
|
+
import { ui } from '../wizard';
|
|
11
|
+
import { authStore, AuthStore, getProviderInfo } from '../auth';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Command options
|
|
15
|
+
*/
|
|
16
|
+
export interface AuthStatusOptions {
|
|
17
|
+
json?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Run the auth status command
|
|
22
|
+
*/
|
|
23
|
+
export async function authStatusCommand(options: AuthStatusOptions = {}): Promise<void> {
|
|
24
|
+
logger.info('Checking auth status');
|
|
25
|
+
|
|
26
|
+
const status = authStore.getStatus();
|
|
27
|
+
|
|
28
|
+
// JSON output mode
|
|
29
|
+
if (options.json) {
|
|
30
|
+
// Build safe JSON output (no raw API keys)
|
|
31
|
+
const safeOutput = {
|
|
32
|
+
isConfigured: status.isConfigured,
|
|
33
|
+
identity: status.identity
|
|
34
|
+
? {
|
|
35
|
+
provider: status.identity.provider,
|
|
36
|
+
username: status.identity.username,
|
|
37
|
+
name: status.identity.name,
|
|
38
|
+
authenticatedAt: status.identity.authenticatedAt,
|
|
39
|
+
}
|
|
40
|
+
: null,
|
|
41
|
+
providers: status.providers.map(p => ({
|
|
42
|
+
name: p.name,
|
|
43
|
+
model: p.model,
|
|
44
|
+
isDefault: p.isDefault,
|
|
45
|
+
validatedAt: p.validatedAt,
|
|
46
|
+
})),
|
|
47
|
+
defaultProvider: status.defaultProvider,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// Output sanitized JSON (no sensitive data included)
|
|
51
|
+
ui.print(JSON.stringify(safeOutput, null, 2));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Human-readable output
|
|
56
|
+
ui.newLine();
|
|
57
|
+
ui.section('Authentication Status');
|
|
58
|
+
|
|
59
|
+
// Overall status
|
|
60
|
+
if (status.isConfigured) {
|
|
61
|
+
ui.success('Nimbus is configured and ready to use');
|
|
62
|
+
} else {
|
|
63
|
+
ui.warning('Nimbus is not configured. Run `nimbus login` to get started.');
|
|
64
|
+
}
|
|
65
|
+
ui.newLine();
|
|
66
|
+
|
|
67
|
+
// Identity section
|
|
68
|
+
ui.print(ui.bold('Identity'));
|
|
69
|
+
|
|
70
|
+
if (status.identity) {
|
|
71
|
+
const identity = status.identity;
|
|
72
|
+
ui.print(` Provider: GitHub`);
|
|
73
|
+
ui.print(` Username: ${identity.username}`);
|
|
74
|
+
if (identity.name) {
|
|
75
|
+
ui.print(` Name: ${identity.name}`);
|
|
76
|
+
}
|
|
77
|
+
ui.print(` Signed in: ${formatDate(identity.authenticatedAt)}`);
|
|
78
|
+
} else {
|
|
79
|
+
ui.print(ui.dim(' Not signed in'));
|
|
80
|
+
ui.print(ui.dim(' Run `nimbus login` to sign in with GitHub'));
|
|
81
|
+
}
|
|
82
|
+
ui.newLine();
|
|
83
|
+
|
|
84
|
+
// Providers section
|
|
85
|
+
ui.print(ui.bold('LLM Providers'));
|
|
86
|
+
|
|
87
|
+
if (status.providers.length > 0) {
|
|
88
|
+
for (const provider of status.providers) {
|
|
89
|
+
const info = getProviderInfo(provider.name);
|
|
90
|
+
const defaultMarker = provider.isDefault ? ui.color(' (default)', 'green') : '';
|
|
91
|
+
|
|
92
|
+
ui.print(` ${info.displayName}${defaultMarker}`);
|
|
93
|
+
ui.print(` Model: ${provider.model}`);
|
|
94
|
+
|
|
95
|
+
// Get the actual credential to show masked key
|
|
96
|
+
const credential = authStore.getProvider(provider.name);
|
|
97
|
+
if (credential?.apiKey) {
|
|
98
|
+
ui.print(` API Key: ${AuthStore.maskApiKey(credential.apiKey)}`);
|
|
99
|
+
} else if (!info.requiresApiKey) {
|
|
100
|
+
ui.print(` API Key: ${ui.dim('(not required)')}`);
|
|
101
|
+
} else {
|
|
102
|
+
ui.print(` API Key: ${ui.dim('(from environment)')}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (credential?.baseUrl) {
|
|
106
|
+
ui.print(` Base URL: ${credential.baseUrl}`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (provider.validatedAt) {
|
|
110
|
+
ui.print(` Validated: ${formatDate(provider.validatedAt)}`);
|
|
111
|
+
}
|
|
112
|
+
ui.newLine();
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
ui.print(ui.dim(' No providers configured'));
|
|
116
|
+
ui.print(ui.dim(' Run `nimbus login` to configure LLM providers'));
|
|
117
|
+
ui.newLine();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Auth file location
|
|
121
|
+
ui.print(ui.dim(`Config: ${authStore.getAuthPath()}`));
|
|
122
|
+
ui.newLine();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Format ISO date string for display
|
|
127
|
+
*/
|
|
128
|
+
function formatDate(isoString: string): string {
|
|
129
|
+
try {
|
|
130
|
+
const date = new Date(isoString);
|
|
131
|
+
// Check if date is valid (NaN check)
|
|
132
|
+
if (isNaN(date.getTime())) {
|
|
133
|
+
return isoString;
|
|
134
|
+
}
|
|
135
|
+
return date.toLocaleString();
|
|
136
|
+
} catch {
|
|
137
|
+
return isoString;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export default authStatusCommand;
|