@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,349 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Demo Framework
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates demo scenarios for presentations and tutorials
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { logger } from '../utils';
|
|
8
|
+
import { ui } from '../wizard/ui';
|
|
9
|
+
import { confirm } from '../wizard/prompts';
|
|
10
|
+
import type { DemoScenario, DemoStep, DemoOptions, StepResult, ScenarioResult } from './types';
|
|
11
|
+
import { terraformVpcScenario } from './scenarios/terraform-vpc';
|
|
12
|
+
import { fullJourneyScenario } from './scenarios/full-journey';
|
|
13
|
+
import { gettingStartedScenario } from './scenarios/getting-started';
|
|
14
|
+
import { k8sDeploymentScenario } from './scenarios/k8s-deployment';
|
|
15
|
+
import { helmReleaseScenario } from './scenarios/helm-release';
|
|
16
|
+
|
|
17
|
+
// All available scenarios
|
|
18
|
+
const scenarios: DemoScenario[] = [
|
|
19
|
+
gettingStartedScenario,
|
|
20
|
+
terraformVpcScenario,
|
|
21
|
+
k8sDeploymentScenario,
|
|
22
|
+
helmReleaseScenario,
|
|
23
|
+
fullJourneyScenario,
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Get all available demo scenarios
|
|
28
|
+
*/
|
|
29
|
+
export function getScenarios(): DemoScenario[] {
|
|
30
|
+
return scenarios;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Get a scenario by ID
|
|
35
|
+
*/
|
|
36
|
+
export function getScenario(id: string): DemoScenario | undefined {
|
|
37
|
+
return scenarios.find(s => s.id === id);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Run a demo scenario
|
|
42
|
+
*/
|
|
43
|
+
export async function runScenario(
|
|
44
|
+
scenario: DemoScenario,
|
|
45
|
+
options: DemoOptions = {}
|
|
46
|
+
): Promise<ScenarioResult> {
|
|
47
|
+
logger.info(`Running demo scenario: ${scenario.name}`);
|
|
48
|
+
|
|
49
|
+
const startedAt = new Date();
|
|
50
|
+
const stepResults: StepResult[] = [];
|
|
51
|
+
let totalDuration = 0;
|
|
52
|
+
let success = true;
|
|
53
|
+
|
|
54
|
+
// Show scenario header
|
|
55
|
+
displayScenarioHeader(scenario);
|
|
56
|
+
|
|
57
|
+
// Check prerequisites
|
|
58
|
+
if (scenario.prerequisites && scenario.prerequisites.length > 0) {
|
|
59
|
+
ui.newLine();
|
|
60
|
+
ui.print(ui.bold('Prerequisites:'));
|
|
61
|
+
for (const prereq of scenario.prerequisites) {
|
|
62
|
+
ui.print(` - ${prereq}`);
|
|
63
|
+
}
|
|
64
|
+
ui.newLine();
|
|
65
|
+
|
|
66
|
+
if (options.interactive) {
|
|
67
|
+
const proceed = await confirm({
|
|
68
|
+
message: 'Have you met all prerequisites?',
|
|
69
|
+
defaultValue: true,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (!proceed) {
|
|
73
|
+
ui.warning('Demo cancelled - prerequisites not met');
|
|
74
|
+
return {
|
|
75
|
+
scenario,
|
|
76
|
+
steps: [],
|
|
77
|
+
success: false,
|
|
78
|
+
totalDuration: 0,
|
|
79
|
+
startedAt,
|
|
80
|
+
completedAt: new Date(),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Run each step
|
|
87
|
+
for (let i = 0; i < scenario.steps.length; i++) {
|
|
88
|
+
const step = scenario.steps[i];
|
|
89
|
+
|
|
90
|
+
// Wait before step if interactive
|
|
91
|
+
if (options.interactive && i > 0) {
|
|
92
|
+
const proceed = await confirm({
|
|
93
|
+
message: 'Continue to next step?',
|
|
94
|
+
defaultValue: true,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
if (!proceed) {
|
|
98
|
+
ui.info('Demo paused');
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const result = await runStep(step, options, i + 1, scenario.steps.length);
|
|
104
|
+
stepResults.push(result);
|
|
105
|
+
totalDuration += result.duration;
|
|
106
|
+
|
|
107
|
+
if (!result.success) {
|
|
108
|
+
success = false;
|
|
109
|
+
if (!options.interactive) {
|
|
110
|
+
ui.error('Step failed, stopping demo');
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Add delay based on speed
|
|
116
|
+
const delay = getDelay(options.speed, step.delay);
|
|
117
|
+
if (delay > 0) {
|
|
118
|
+
await sleep(delay);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const completedAt = new Date();
|
|
123
|
+
|
|
124
|
+
// Show summary
|
|
125
|
+
displaySummary(scenario, stepResults, success, totalDuration);
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
scenario,
|
|
129
|
+
steps: stepResults,
|
|
130
|
+
success,
|
|
131
|
+
totalDuration,
|
|
132
|
+
startedAt,
|
|
133
|
+
completedAt,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Run a single demo step
|
|
139
|
+
*/
|
|
140
|
+
async function runStep(
|
|
141
|
+
step: DemoStep,
|
|
142
|
+
options: DemoOptions,
|
|
143
|
+
current: number,
|
|
144
|
+
total: number
|
|
145
|
+
): Promise<StepResult> {
|
|
146
|
+
const startTime = Date.now();
|
|
147
|
+
|
|
148
|
+
// Display step header
|
|
149
|
+
ui.newLine();
|
|
150
|
+
ui.print(ui.color(`Step ${current}/${total}`, 'cyan'));
|
|
151
|
+
ui.print(ui.bold(step.title));
|
|
152
|
+
if (step.description) {
|
|
153
|
+
ui.print(ui.dim(step.description));
|
|
154
|
+
}
|
|
155
|
+
ui.newLine();
|
|
156
|
+
|
|
157
|
+
// Show command
|
|
158
|
+
ui.print(` ${ui.color('$', 'green')} ${ui.color(step.command, 'yellow')}`);
|
|
159
|
+
ui.newLine();
|
|
160
|
+
|
|
161
|
+
// Execute or mock
|
|
162
|
+
let output = '';
|
|
163
|
+
let error = '';
|
|
164
|
+
let success = true;
|
|
165
|
+
|
|
166
|
+
if (options.dryRun) {
|
|
167
|
+
// Use mock response in dry run mode
|
|
168
|
+
if (step.mockResponse) {
|
|
169
|
+
output = step.mockResponse;
|
|
170
|
+
if (step.showOutput !== false) {
|
|
171
|
+
displayOutput(output);
|
|
172
|
+
}
|
|
173
|
+
} else {
|
|
174
|
+
ui.dim(' [Dry run - command not executed]');
|
|
175
|
+
}
|
|
176
|
+
} else {
|
|
177
|
+
// Actually execute the command
|
|
178
|
+
try {
|
|
179
|
+
const result = await executeCommand(step.command);
|
|
180
|
+
output = result.stdout;
|
|
181
|
+
error = result.stderr;
|
|
182
|
+
success = result.exitCode === 0;
|
|
183
|
+
|
|
184
|
+
if (step.showOutput !== false && output) {
|
|
185
|
+
displayOutput(output);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (error && options.verbose) {
|
|
189
|
+
ui.print(ui.color(error, 'red'));
|
|
190
|
+
}
|
|
191
|
+
} catch (e: any) {
|
|
192
|
+
success = false;
|
|
193
|
+
error = e.message;
|
|
194
|
+
ui.error(`Failed: ${error}`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Verify expected output
|
|
199
|
+
if (success && step.expectedOutput) {
|
|
200
|
+
const regex = new RegExp(step.expectedOutput);
|
|
201
|
+
if (!regex.test(output)) {
|
|
202
|
+
success = false;
|
|
203
|
+
error = 'Output did not match expected pattern';
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const duration = Date.now() - startTime;
|
|
208
|
+
|
|
209
|
+
// Show result
|
|
210
|
+
if (success) {
|
|
211
|
+
ui.success('Step completed');
|
|
212
|
+
} else {
|
|
213
|
+
ui.error('Step failed');
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return {
|
|
217
|
+
step,
|
|
218
|
+
success,
|
|
219
|
+
output,
|
|
220
|
+
error: error || undefined,
|
|
221
|
+
duration,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Execute a command and return result
|
|
227
|
+
*/
|
|
228
|
+
async function executeCommand(command: string): Promise<{
|
|
229
|
+
stdout: string;
|
|
230
|
+
stderr: string;
|
|
231
|
+
exitCode: number;
|
|
232
|
+
}> {
|
|
233
|
+
const { exec } = await import('child_process');
|
|
234
|
+
const { promisify } = await import('util');
|
|
235
|
+
const execAsync = promisify(exec);
|
|
236
|
+
|
|
237
|
+
try {
|
|
238
|
+
const { stdout, stderr } = await execAsync(command, {
|
|
239
|
+
maxBuffer: 10 * 1024 * 1024, // 10MB
|
|
240
|
+
});
|
|
241
|
+
return { stdout, stderr, exitCode: 0 };
|
|
242
|
+
} catch (error: any) {
|
|
243
|
+
return {
|
|
244
|
+
stdout: error.stdout || '',
|
|
245
|
+
stderr: error.stderr || error.message,
|
|
246
|
+
exitCode: error.code || 1,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Display scenario header
|
|
253
|
+
*/
|
|
254
|
+
function displayScenarioHeader(scenario: DemoScenario): void {
|
|
255
|
+
ui.newLine();
|
|
256
|
+
ui.print(`╔${'═'.repeat(58)}╗`);
|
|
257
|
+
ui.print(`║${' '.repeat(58)}║`);
|
|
258
|
+
ui.print(`║${centerText(scenario.name, 58)}║`);
|
|
259
|
+
ui.print(`║${centerText(scenario.description, 58)}║`);
|
|
260
|
+
ui.print(`║${' '.repeat(58)}║`);
|
|
261
|
+
ui.print(`║${centerText(`${scenario.steps.length} steps`, 58)}║`);
|
|
262
|
+
ui.print(`╚${'═'.repeat(58)}╝`);
|
|
263
|
+
ui.newLine();
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Display execution summary
|
|
268
|
+
*/
|
|
269
|
+
function displaySummary(
|
|
270
|
+
scenario: DemoScenario,
|
|
271
|
+
results: StepResult[],
|
|
272
|
+
success: boolean,
|
|
273
|
+
duration: number
|
|
274
|
+
): void {
|
|
275
|
+
ui.newLine();
|
|
276
|
+
ui.print('─'.repeat(60));
|
|
277
|
+
ui.print(ui.bold('Demo Summary'));
|
|
278
|
+
ui.newLine();
|
|
279
|
+
|
|
280
|
+
const passed = results.filter(r => r.success).length;
|
|
281
|
+
const failed = results.filter(r => !r.success).length;
|
|
282
|
+
|
|
283
|
+
ui.print(` Scenario: ${scenario.name}`);
|
|
284
|
+
ui.print(
|
|
285
|
+
` Steps: ${ui.color(`${passed} passed`, 'green')}, ${failed > 0 ? ui.color(`${failed} failed`, 'red') : '0 failed'}`
|
|
286
|
+
);
|
|
287
|
+
ui.print(` Duration: ${(duration / 1000).toFixed(1)}s`);
|
|
288
|
+
|
|
289
|
+
ui.newLine();
|
|
290
|
+
if (success) {
|
|
291
|
+
ui.success('Demo completed successfully!');
|
|
292
|
+
} else {
|
|
293
|
+
ui.error('Demo completed with errors');
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Display command output with formatting
|
|
299
|
+
*/
|
|
300
|
+
function displayOutput(output: string): void {
|
|
301
|
+
const lines = output.split('\n');
|
|
302
|
+
for (const line of lines) {
|
|
303
|
+
// Color terraform output
|
|
304
|
+
if (line.startsWith('+')) {
|
|
305
|
+
ui.print(` ${ui.color(line, 'green')}`);
|
|
306
|
+
} else if (line.startsWith('-')) {
|
|
307
|
+
ui.print(` ${ui.color(line, 'red')}`);
|
|
308
|
+
} else if (line.startsWith('~')) {
|
|
309
|
+
ui.print(` ${ui.color(line, 'yellow')}`);
|
|
310
|
+
} else {
|
|
311
|
+
ui.print(` ${line}`);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Get delay based on speed setting
|
|
318
|
+
*/
|
|
319
|
+
function getDelay(speed: string | undefined, stepDelay: number | undefined): number {
|
|
320
|
+
const baseDelay = stepDelay || 500;
|
|
321
|
+
|
|
322
|
+
switch (speed) {
|
|
323
|
+
case 'slow':
|
|
324
|
+
return baseDelay * 2;
|
|
325
|
+
case 'fast':
|
|
326
|
+
return baseDelay / 2;
|
|
327
|
+
default:
|
|
328
|
+
return baseDelay;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Center text in a given width
|
|
334
|
+
*/
|
|
335
|
+
function centerText(text: string, width: number): string {
|
|
336
|
+
const leftPadding = Math.max(0, Math.floor((width - text.length) / 2));
|
|
337
|
+
const rightPadding = Math.max(0, width - leftPadding - text.length);
|
|
338
|
+
return ' '.repeat(leftPadding) + text + ' '.repeat(rightPadding);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Sleep for specified milliseconds
|
|
343
|
+
*/
|
|
344
|
+
function sleep(ms: number): Promise<void> {
|
|
345
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Re-export types
|
|
349
|
+
export * from './types';
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Full Journey Demo Scenario
|
|
3
|
+
*
|
|
4
|
+
* End-to-end demo from discovery to deployment
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { DemoScenario } from '../types';
|
|
8
|
+
|
|
9
|
+
export const fullJourneyScenario: DemoScenario = {
|
|
10
|
+
id: 'full-journey',
|
|
11
|
+
name: 'Full Infrastructure Journey',
|
|
12
|
+
description: 'Complete workflow: Discovery → Generation → Preview → Deploy',
|
|
13
|
+
category: 'full-journey',
|
|
14
|
+
duration: 15,
|
|
15
|
+
prerequisites: [
|
|
16
|
+
'AWS CLI configured with credentials',
|
|
17
|
+
'Terraform installed (v1.0+)',
|
|
18
|
+
'kubectl configured (for K8s steps)',
|
|
19
|
+
'Nimbus CLI installed',
|
|
20
|
+
],
|
|
21
|
+
tags: ['full-demo', 'aws', 'terraform', 'kubernetes'],
|
|
22
|
+
steps: [
|
|
23
|
+
{
|
|
24
|
+
id: 'init',
|
|
25
|
+
title: 'Initialize Nimbus Project',
|
|
26
|
+
description: 'Set up Nimbus in the current project',
|
|
27
|
+
command: 'nimbus init',
|
|
28
|
+
showOutput: true,
|
|
29
|
+
waitForInput: true,
|
|
30
|
+
mockResponse: `
|
|
31
|
+
Nimbus Initialization
|
|
32
|
+
|
|
33
|
+
Scanning project...
|
|
34
|
+
|
|
35
|
+
Detected:
|
|
36
|
+
✓ Languages: TypeScript, Python
|
|
37
|
+
✓ Frameworks: Next.js, FastAPI
|
|
38
|
+
✓ Package Managers: npm, pip
|
|
39
|
+
✓ IaC: Terraform
|
|
40
|
+
✓ CI/CD: GitHub Actions
|
|
41
|
+
✓ Cloud: AWS
|
|
42
|
+
|
|
43
|
+
Created .nimbus/project.yaml
|
|
44
|
+
|
|
45
|
+
Project initialized successfully!
|
|
46
|
+
`.trim(),
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 'discover-aws',
|
|
50
|
+
title: 'Discover AWS Resources',
|
|
51
|
+
description: 'Scan your AWS account for existing infrastructure',
|
|
52
|
+
command: 'nimbus aws discover --regions us-east-1',
|
|
53
|
+
showOutput: true,
|
|
54
|
+
waitForInput: true,
|
|
55
|
+
mockResponse: `
|
|
56
|
+
AWS Discovery
|
|
57
|
+
|
|
58
|
+
Scanning AWS account...
|
|
59
|
+
Region: us-east-1
|
|
60
|
+
|
|
61
|
+
Discovery Summary:
|
|
62
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
63
|
+
EC2 Instances: 3
|
|
64
|
+
VPCs: 2
|
|
65
|
+
S3 Buckets: 5
|
|
66
|
+
RDS Instances: 1
|
|
67
|
+
Lambda Functions: 8
|
|
68
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
69
|
+
|
|
70
|
+
Resources discovered and saved to .nimbus/inventory.yaml
|
|
71
|
+
`.trim(),
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: 'generate-terraform',
|
|
75
|
+
title: 'Generate Terraform from Inventory',
|
|
76
|
+
description: 'Create Terraform code from discovered resources',
|
|
77
|
+
command: 'nimbus generate terraform --from-inventory',
|
|
78
|
+
showOutput: true,
|
|
79
|
+
waitForInput: true,
|
|
80
|
+
mockResponse: `
|
|
81
|
+
Generate Terraform
|
|
82
|
+
|
|
83
|
+
Generating from .nimbus/inventory.yaml...
|
|
84
|
+
|
|
85
|
+
Generated files:
|
|
86
|
+
● terraform/main.tf
|
|
87
|
+
● terraform/vpc.tf
|
|
88
|
+
● terraform/ec2.tf
|
|
89
|
+
● terraform/rds.tf
|
|
90
|
+
● terraform/s3.tf
|
|
91
|
+
● terraform/variables.tf
|
|
92
|
+
● terraform/outputs.tf
|
|
93
|
+
|
|
94
|
+
Output directory: ./terraform
|
|
95
|
+
|
|
96
|
+
Generation complete!
|
|
97
|
+
Run 'nimbus preview terraform' to see the plan.
|
|
98
|
+
`.trim(),
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
id: 'preview',
|
|
102
|
+
title: 'Preview Infrastructure Changes',
|
|
103
|
+
description: 'Review what will be created/modified',
|
|
104
|
+
command: 'nimbus preview terraform ./terraform',
|
|
105
|
+
showOutput: true,
|
|
106
|
+
waitForInput: true,
|
|
107
|
+
mockResponse: `
|
|
108
|
+
Preview Terraform Changes
|
|
109
|
+
|
|
110
|
+
Directory: ./terraform
|
|
111
|
+
|
|
112
|
+
Creating execution plan...
|
|
113
|
+
Plan created
|
|
114
|
+
|
|
115
|
+
Plan Summary:
|
|
116
|
+
|
|
117
|
+
+ 12 to add
|
|
118
|
+
~ 0 to change
|
|
119
|
+
- 0 to destroy
|
|
120
|
+
|
|
121
|
+
Resources to be created:
|
|
122
|
+
+ aws_vpc.main
|
|
123
|
+
+ aws_subnet.private[0-2]
|
|
124
|
+
+ aws_subnet.public[0-2]
|
|
125
|
+
+ aws_security_group.main
|
|
126
|
+
+ aws_instance.app
|
|
127
|
+
+ aws_db_instance.main
|
|
128
|
+
+ aws_s3_bucket.assets
|
|
129
|
+
|
|
130
|
+
Safety Check Summary:
|
|
131
|
+
|
|
132
|
+
🟡 [MEDIUM] This operation will modify infrastructure
|
|
133
|
+
|
|
134
|
+
All safety checks passed
|
|
135
|
+
`.trim(),
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
id: 'apply',
|
|
139
|
+
title: 'Apply Infrastructure',
|
|
140
|
+
description: 'Deploy the infrastructure with safety approval',
|
|
141
|
+
command: 'nimbus apply terraform ./terraform',
|
|
142
|
+
showOutput: true,
|
|
143
|
+
waitForInput: true,
|
|
144
|
+
mockResponse: `
|
|
145
|
+
Terraform Apply
|
|
146
|
+
|
|
147
|
+
Creating execution plan...
|
|
148
|
+
Plan created
|
|
149
|
+
|
|
150
|
+
╔══════════════════════════════════════════════════════════╗
|
|
151
|
+
║ APPROVAL REQUIRED ║
|
|
152
|
+
╠══════════════════════════════════════════════════════════╣
|
|
153
|
+
║ Operation: terraform apply ║
|
|
154
|
+
╚══════════════════════════════════════════════════════════╝
|
|
155
|
+
|
|
156
|
+
Identified Risks:
|
|
157
|
+
🟡 [MEDIUM] This operation will modify infrastructure
|
|
158
|
+
|
|
159
|
+
Do you want to proceed? Yes
|
|
160
|
+
|
|
161
|
+
Applying changes...
|
|
162
|
+
|
|
163
|
+
Apply complete! Resources: 12 added, 0 changed, 0 destroyed.
|
|
164
|
+
`.trim(),
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
id: 'generate-k8s',
|
|
168
|
+
title: 'Generate Kubernetes Manifests',
|
|
169
|
+
description: 'Create K8s deployment for the application',
|
|
170
|
+
command: 'nimbus questionnaire kubernetes',
|
|
171
|
+
showOutput: true,
|
|
172
|
+
waitForInput: true,
|
|
173
|
+
mockResponse: `
|
|
174
|
+
Kubernetes Configuration Wizard
|
|
175
|
+
|
|
176
|
+
Step 1/4: Application Info
|
|
177
|
+
Name: my-app
|
|
178
|
+
Image: my-registry/my-app:latest
|
|
179
|
+
|
|
180
|
+
Step 2/4: Deployment Settings
|
|
181
|
+
Replicas: 3
|
|
182
|
+
Port: 8080
|
|
183
|
+
|
|
184
|
+
Step 3/4: Resource Limits
|
|
185
|
+
CPU Request: 100m
|
|
186
|
+
Memory Request: 128Mi
|
|
187
|
+
|
|
188
|
+
Step 4/4: Service Configuration
|
|
189
|
+
Type: ClusterIP
|
|
190
|
+
Port: 80
|
|
191
|
+
|
|
192
|
+
Generated files:
|
|
193
|
+
● k8s/deployment.yaml
|
|
194
|
+
● k8s/service.yaml
|
|
195
|
+
|
|
196
|
+
Output directory: ./k8s
|
|
197
|
+
`.trim(),
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
id: 'deploy-k8s',
|
|
201
|
+
title: 'Deploy to Kubernetes',
|
|
202
|
+
description: 'Apply K8s manifests to the cluster',
|
|
203
|
+
command: 'nimbus apply k8s ./k8s',
|
|
204
|
+
showOutput: true,
|
|
205
|
+
waitForInput: false,
|
|
206
|
+
mockResponse: `
|
|
207
|
+
Kubernetes Apply
|
|
208
|
+
|
|
209
|
+
Manifests: ./k8s
|
|
210
|
+
Namespace: default
|
|
211
|
+
|
|
212
|
+
Found 2 manifest file(s)
|
|
213
|
+
|
|
214
|
+
Resources to apply:
|
|
215
|
+
- Deployment/my-app
|
|
216
|
+
- Service/my-app
|
|
217
|
+
|
|
218
|
+
Apply 2 resource(s)? Yes
|
|
219
|
+
|
|
220
|
+
Applying manifests...
|
|
221
|
+
Apply complete!
|
|
222
|
+
|
|
223
|
+
Created:
|
|
224
|
+
+ Deployment/my-app
|
|
225
|
+
+ Service/my-app
|
|
226
|
+
`.trim(),
|
|
227
|
+
},
|
|
228
|
+
],
|
|
229
|
+
};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Getting Started Tutorial
|
|
3
|
+
*
|
|
4
|
+
* Interactive tutorial for new Nimbus users
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { DemoScenario } from '../types';
|
|
8
|
+
|
|
9
|
+
export const gettingStartedScenario: DemoScenario = {
|
|
10
|
+
id: 'getting-started',
|
|
11
|
+
name: 'Getting Started with Nimbus',
|
|
12
|
+
description: 'Learn the basics of Nimbus CLI in this interactive tutorial',
|
|
13
|
+
category: 'tutorial',
|
|
14
|
+
duration: 5,
|
|
15
|
+
prerequisites: ['Nimbus CLI installed'],
|
|
16
|
+
tags: ['tutorial', 'beginner', 'basics'],
|
|
17
|
+
steps: [
|
|
18
|
+
{
|
|
19
|
+
id: 'check-version',
|
|
20
|
+
title: 'Check Nimbus Version',
|
|
21
|
+
description: "First, let's make sure Nimbus is installed correctly",
|
|
22
|
+
command: 'nimbus --version',
|
|
23
|
+
showOutput: true,
|
|
24
|
+
waitForInput: true,
|
|
25
|
+
mockResponse: 'nimbus version 1.0.0',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: 'help',
|
|
29
|
+
title: 'View Available Commands',
|
|
30
|
+
description: "Nimbus has many commands - let's see what's available",
|
|
31
|
+
command: 'nimbus --help',
|
|
32
|
+
showOutput: true,
|
|
33
|
+
waitForInput: true,
|
|
34
|
+
mockResponse: `
|
|
35
|
+
Nimbus CLI - AI-powered infrastructure assistant
|
|
36
|
+
|
|
37
|
+
USAGE:
|
|
38
|
+
nimbus <command> [options]
|
|
39
|
+
|
|
40
|
+
COMMANDS:
|
|
41
|
+
init Initialize Nimbus in the current project
|
|
42
|
+
chat Start an interactive chat session
|
|
43
|
+
generate Generate infrastructure code
|
|
44
|
+
apply Apply infrastructure changes
|
|
45
|
+
preview Preview changes without applying
|
|
46
|
+
aws AWS CLI commands
|
|
47
|
+
tf Terraform commands
|
|
48
|
+
k8s Kubernetes commands
|
|
49
|
+
helm Helm commands
|
|
50
|
+
|
|
51
|
+
FLAGS:
|
|
52
|
+
--version Show version
|
|
53
|
+
--help Show help
|
|
54
|
+
`.trim(),
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: 'doctor',
|
|
58
|
+
title: 'Run System Check',
|
|
59
|
+
description: 'Check that all required tools are installed',
|
|
60
|
+
command: 'nimbus doctor',
|
|
61
|
+
showOutput: true,
|
|
62
|
+
waitForInput: true,
|
|
63
|
+
mockResponse: `
|
|
64
|
+
Nimbus Doctor
|
|
65
|
+
|
|
66
|
+
Checking system requirements...
|
|
67
|
+
|
|
68
|
+
✓ Node.js 18.0.0
|
|
69
|
+
✓ Bun 1.0.0
|
|
70
|
+
✓ Git 2.40.0
|
|
71
|
+
✓ Terraform 1.5.0
|
|
72
|
+
✓ kubectl 1.28.0
|
|
73
|
+
✓ Helm 3.12.0
|
|
74
|
+
✓ AWS CLI 2.13.0
|
|
75
|
+
|
|
76
|
+
All checks passed!
|
|
77
|
+
`.trim(),
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
id: 'init-demo',
|
|
81
|
+
title: 'Initialize a Project',
|
|
82
|
+
description: 'Set up Nimbus in any directory to get started',
|
|
83
|
+
command: 'nimbus init --scan-depth quick',
|
|
84
|
+
showOutput: true,
|
|
85
|
+
waitForInput: true,
|
|
86
|
+
mockResponse: `
|
|
87
|
+
Nimbus Initialization
|
|
88
|
+
|
|
89
|
+
Scanning project (quick mode)...
|
|
90
|
+
|
|
91
|
+
Project Summary:
|
|
92
|
+
Type: unknown
|
|
93
|
+
Languages: none detected
|
|
94
|
+
|
|
95
|
+
Created .nimbus/project.yaml
|
|
96
|
+
Created .nimbus/config.yaml
|
|
97
|
+
|
|
98
|
+
Project initialized!
|
|
99
|
+
|
|
100
|
+
Next steps:
|
|
101
|
+
1. Run 'nimbus chat' to get AI assistance
|
|
102
|
+
2. Run 'nimbus generate terraform' to create infrastructure
|
|
103
|
+
3. Run 'nimbus aws discover' to scan your AWS account
|
|
104
|
+
`.trim(),
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
id: 'config-list',
|
|
108
|
+
title: 'View Configuration',
|
|
109
|
+
description: 'See your current Nimbus configuration',
|
|
110
|
+
command: 'nimbus config list',
|
|
111
|
+
showOutput: true,
|
|
112
|
+
waitForInput: false,
|
|
113
|
+
mockResponse: `
|
|
114
|
+
Nimbus Configuration
|
|
115
|
+
|
|
116
|
+
Key Value
|
|
117
|
+
─────────────────────────────────────────
|
|
118
|
+
llm.provider anthropic
|
|
119
|
+
llm.model claude-3-sonnet
|
|
120
|
+
safety.enabled true
|
|
121
|
+
safety.costThreshold 500
|
|
122
|
+
output.format table
|
|
123
|
+
output.colors true
|
|
124
|
+
`.trim(),
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
};
|