@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,396 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS Lambda Commands
|
|
3
|
+
*
|
|
4
|
+
* Lambda function operations
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* nimbus aws lambda list
|
|
8
|
+
* nimbus aws lambda invoke <function-name>
|
|
9
|
+
* nimbus aws lambda logs <function-name>
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { logger } from '../../utils';
|
|
13
|
+
import { ui } from '../../wizard/ui';
|
|
14
|
+
import { confirm, input } from '../../wizard/prompts';
|
|
15
|
+
import type { AwsCommandOptions } from './index';
|
|
16
|
+
|
|
17
|
+
interface LambdaFunction {
|
|
18
|
+
FunctionName: string;
|
|
19
|
+
Runtime: string;
|
|
20
|
+
Handler: string;
|
|
21
|
+
CodeSize: number;
|
|
22
|
+
MemorySize: number;
|
|
23
|
+
Timeout: number;
|
|
24
|
+
LastModified: string;
|
|
25
|
+
State?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Lambda command router
|
|
30
|
+
*/
|
|
31
|
+
export async function lambdaCommand(
|
|
32
|
+
action: string,
|
|
33
|
+
args: string[],
|
|
34
|
+
options: AwsCommandOptions
|
|
35
|
+
): Promise<void> {
|
|
36
|
+
logger.info('Running Lambda command', { action, args, options });
|
|
37
|
+
|
|
38
|
+
switch (action) {
|
|
39
|
+
case 'list':
|
|
40
|
+
case 'ls':
|
|
41
|
+
await listFunctions(options);
|
|
42
|
+
break;
|
|
43
|
+
|
|
44
|
+
case 'invoke':
|
|
45
|
+
if (!args[0]) {
|
|
46
|
+
ui.error('Function name is required');
|
|
47
|
+
ui.print('Usage: nimbus aws lambda invoke <function-name>');
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
await invokeFunction(args[0], args[1], options);
|
|
51
|
+
break;
|
|
52
|
+
|
|
53
|
+
case 'logs':
|
|
54
|
+
if (!args[0]) {
|
|
55
|
+
ui.error('Function name is required');
|
|
56
|
+
ui.print('Usage: nimbus aws lambda logs <function-name>');
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
await getFunctionLogs(args[0], options);
|
|
60
|
+
break;
|
|
61
|
+
|
|
62
|
+
default:
|
|
63
|
+
showLambdaHelp();
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* List all Lambda functions
|
|
70
|
+
*/
|
|
71
|
+
async function listFunctions(options: AwsCommandOptions): Promise<void> {
|
|
72
|
+
ui.header('Lambda Functions');
|
|
73
|
+
|
|
74
|
+
ui.startSpinner({ message: 'Fetching Lambda functions...' });
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
const result = await runAwsCommand<{ Functions: LambdaFunction[] }>(
|
|
78
|
+
'lambda list-functions',
|
|
79
|
+
options
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const functions = result.Functions || [];
|
|
83
|
+
|
|
84
|
+
ui.stopSpinnerSuccess(`Found ${functions.length} function(s)`);
|
|
85
|
+
ui.newLine();
|
|
86
|
+
|
|
87
|
+
if (functions.length === 0) {
|
|
88
|
+
ui.info('No Lambda functions found');
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Display table
|
|
93
|
+
displayFunctionTable(functions);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
ui.stopSpinnerFail('Failed to list functions');
|
|
96
|
+
ui.error((error as Error).message);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Invoke a Lambda function
|
|
102
|
+
*/
|
|
103
|
+
async function invokeFunction(
|
|
104
|
+
functionName: string,
|
|
105
|
+
payload: string | undefined,
|
|
106
|
+
options: AwsCommandOptions
|
|
107
|
+
): Promise<void> {
|
|
108
|
+
ui.header(`Invoke Lambda: ${functionName}`);
|
|
109
|
+
|
|
110
|
+
// Get payload if not provided
|
|
111
|
+
let invokePayload = payload;
|
|
112
|
+
if (!invokePayload) {
|
|
113
|
+
invokePayload = await input({
|
|
114
|
+
message: 'Enter payload (JSON):',
|
|
115
|
+
defaultValue: '{}',
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Validate JSON
|
|
120
|
+
try {
|
|
121
|
+
JSON.parse(invokePayload);
|
|
122
|
+
} catch {
|
|
123
|
+
ui.error('Invalid JSON payload');
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const proceed = await confirm({
|
|
128
|
+
message: `Invoke function ${functionName}?`,
|
|
129
|
+
defaultValue: true,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
if (!proceed) {
|
|
133
|
+
ui.info('Operation cancelled');
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
ui.startSpinner({ message: 'Invoking function...' });
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
const { execFile } = await import('child_process');
|
|
141
|
+
const { promisify } = await import('util');
|
|
142
|
+
const fs = await import('fs/promises');
|
|
143
|
+
const os = await import('os');
|
|
144
|
+
const path = await import('path');
|
|
145
|
+
const execFileAsync = promisify(execFile);
|
|
146
|
+
|
|
147
|
+
// Write payload to temp file
|
|
148
|
+
const tempFile = path.join(os.tmpdir(), `lambda-payload-${Date.now()}.json`);
|
|
149
|
+
await fs.writeFile(tempFile, invokePayload);
|
|
150
|
+
|
|
151
|
+
// Invoke Lambda
|
|
152
|
+
const args = [
|
|
153
|
+
'lambda',
|
|
154
|
+
'invoke',
|
|
155
|
+
'--function-name',
|
|
156
|
+
functionName,
|
|
157
|
+
'--payload',
|
|
158
|
+
`file://${tempFile}`,
|
|
159
|
+
'--cli-binary-format',
|
|
160
|
+
'raw-in-base64-out',
|
|
161
|
+
];
|
|
162
|
+
|
|
163
|
+
if (options.profile) {
|
|
164
|
+
args.push('--profile', options.profile);
|
|
165
|
+
}
|
|
166
|
+
if (options.region) {
|
|
167
|
+
args.push('--region', options.region);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const outputFile = path.join(os.tmpdir(), `lambda-response-${Date.now()}.json`);
|
|
171
|
+
args.push(outputFile);
|
|
172
|
+
|
|
173
|
+
const { stdout } = await execFileAsync('aws', args);
|
|
174
|
+
|
|
175
|
+
ui.stopSpinnerSuccess('Function invoked');
|
|
176
|
+
ui.newLine();
|
|
177
|
+
|
|
178
|
+
// Parse invocation result
|
|
179
|
+
const result = JSON.parse(stdout);
|
|
180
|
+
ui.print(ui.bold('Invocation Result:'));
|
|
181
|
+
ui.print(` Status Code: ${result.StatusCode}`);
|
|
182
|
+
if (result.FunctionError) {
|
|
183
|
+
ui.print(` Error: ${ui.color(result.FunctionError, 'red')}`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Read response
|
|
187
|
+
try {
|
|
188
|
+
const response = await fs.readFile(outputFile, 'utf-8');
|
|
189
|
+
ui.newLine();
|
|
190
|
+
ui.print(ui.bold('Response:'));
|
|
191
|
+
ui.print(response);
|
|
192
|
+
} catch {
|
|
193
|
+
// No response file
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Cleanup
|
|
197
|
+
await fs.unlink(tempFile).catch(() => {});
|
|
198
|
+
await fs.unlink(outputFile).catch(() => {});
|
|
199
|
+
} catch (error) {
|
|
200
|
+
ui.stopSpinnerFail('Invocation failed');
|
|
201
|
+
ui.error((error as Error).message);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Get Lambda function logs
|
|
207
|
+
*/
|
|
208
|
+
async function getFunctionLogs(functionName: string, options: AwsCommandOptions): Promise<void> {
|
|
209
|
+
ui.header(`Lambda Logs: ${functionName}`);
|
|
210
|
+
|
|
211
|
+
ui.startSpinner({ message: 'Fetching logs...' });
|
|
212
|
+
|
|
213
|
+
try {
|
|
214
|
+
const { execFile } = await import('child_process');
|
|
215
|
+
const { promisify } = await import('util');
|
|
216
|
+
const execFileAsync = promisify(execFile);
|
|
217
|
+
|
|
218
|
+
// Get log group name
|
|
219
|
+
const logGroupName = `/aws/lambda/${functionName}`;
|
|
220
|
+
|
|
221
|
+
// Fetch recent log streams
|
|
222
|
+
const args = [
|
|
223
|
+
'logs',
|
|
224
|
+
'describe-log-streams',
|
|
225
|
+
'--log-group-name',
|
|
226
|
+
logGroupName,
|
|
227
|
+
'--order-by',
|
|
228
|
+
'LastEventTime',
|
|
229
|
+
'--descending',
|
|
230
|
+
'--limit',
|
|
231
|
+
'1',
|
|
232
|
+
'--output',
|
|
233
|
+
'json',
|
|
234
|
+
];
|
|
235
|
+
|
|
236
|
+
if (options.profile) {
|
|
237
|
+
args.push('--profile', options.profile);
|
|
238
|
+
}
|
|
239
|
+
if (options.region) {
|
|
240
|
+
args.push('--region', options.region);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const { stdout: streamsOutput } = await execFileAsync('aws', args);
|
|
244
|
+
const streams = JSON.parse(streamsOutput);
|
|
245
|
+
|
|
246
|
+
if (!streams.logStreams || streams.logStreams.length === 0) {
|
|
247
|
+
ui.stopSpinnerSuccess('');
|
|
248
|
+
ui.info('No log streams found');
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const latestStream = streams.logStreams[0].logStreamName;
|
|
253
|
+
|
|
254
|
+
// Fetch log events
|
|
255
|
+
const logArgs = [
|
|
256
|
+
'logs',
|
|
257
|
+
'get-log-events',
|
|
258
|
+
'--log-group-name',
|
|
259
|
+
logGroupName,
|
|
260
|
+
'--log-stream-name',
|
|
261
|
+
latestStream,
|
|
262
|
+
'--limit',
|
|
263
|
+
'50',
|
|
264
|
+
'--output',
|
|
265
|
+
'json',
|
|
266
|
+
];
|
|
267
|
+
|
|
268
|
+
if (options.profile) {
|
|
269
|
+
logArgs.push('--profile', options.profile);
|
|
270
|
+
}
|
|
271
|
+
if (options.region) {
|
|
272
|
+
logArgs.push('--region', options.region);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const { stdout: logsOutput } = await execFileAsync('aws', logArgs);
|
|
276
|
+
const logs = JSON.parse(logsOutput);
|
|
277
|
+
|
|
278
|
+
ui.stopSpinnerSuccess('Logs retrieved');
|
|
279
|
+
ui.newLine();
|
|
280
|
+
|
|
281
|
+
if (!logs.events || logs.events.length === 0) {
|
|
282
|
+
ui.info('No log events found');
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
ui.print(ui.bold(`Recent logs from: ${latestStream}`));
|
|
287
|
+
ui.newLine();
|
|
288
|
+
|
|
289
|
+
for (const event of logs.events) {
|
|
290
|
+
const timestamp = new Date(event.timestamp).toISOString();
|
|
291
|
+
ui.print(`${ui.dim(timestamp)} ${event.message.trim()}`);
|
|
292
|
+
}
|
|
293
|
+
} catch (error) {
|
|
294
|
+
ui.stopSpinnerFail('Failed to fetch logs');
|
|
295
|
+
ui.error((error as Error).message);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Run AWS CLI command and parse JSON output
|
|
301
|
+
*/
|
|
302
|
+
async function runAwsCommand<T>(command: string, options: AwsCommandOptions): Promise<T> {
|
|
303
|
+
const { execFile } = await import('child_process');
|
|
304
|
+
const { promisify } = await import('util');
|
|
305
|
+
const execFileAsync = promisify(execFile);
|
|
306
|
+
|
|
307
|
+
const args = command.split(' ');
|
|
308
|
+
const baseCommand = args[0];
|
|
309
|
+
const commandArgs = args.slice(1);
|
|
310
|
+
|
|
311
|
+
// Add common options
|
|
312
|
+
if (options.profile) {
|
|
313
|
+
commandArgs.push('--profile', options.profile);
|
|
314
|
+
}
|
|
315
|
+
if (options.region) {
|
|
316
|
+
commandArgs.push('--region', options.region);
|
|
317
|
+
}
|
|
318
|
+
commandArgs.push('--output', 'json');
|
|
319
|
+
|
|
320
|
+
const { stdout } = await execFileAsync('aws', [baseCommand, ...commandArgs]);
|
|
321
|
+
return JSON.parse(stdout) as T;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Display functions in a table format
|
|
326
|
+
*/
|
|
327
|
+
function displayFunctionTable(functions: LambdaFunction[]): void {
|
|
328
|
+
const headers = ['Name', 'Runtime', 'Memory', 'Timeout', 'Code Size', 'Modified'];
|
|
329
|
+
const rows = functions.map(fn => [
|
|
330
|
+
fn.FunctionName,
|
|
331
|
+
fn.Runtime || 'N/A',
|
|
332
|
+
`${fn.MemorySize} MB`,
|
|
333
|
+
`${fn.Timeout}s`,
|
|
334
|
+
formatBytes(fn.CodeSize),
|
|
335
|
+
new Date(fn.LastModified).toLocaleDateString(),
|
|
336
|
+
]);
|
|
337
|
+
|
|
338
|
+
// Print header
|
|
339
|
+
const headerRow = headers
|
|
340
|
+
.map((h, i) => {
|
|
341
|
+
const maxWidth = Math.max(h.length, ...rows.map(r => r[i].length));
|
|
342
|
+
return h.padEnd(maxWidth);
|
|
343
|
+
})
|
|
344
|
+
.join(' ');
|
|
345
|
+
|
|
346
|
+
ui.print(ui.bold(headerRow));
|
|
347
|
+
ui.print('-'.repeat(headerRow.length));
|
|
348
|
+
|
|
349
|
+
// Print rows
|
|
350
|
+
for (const row of rows) {
|
|
351
|
+
const formattedRow = row
|
|
352
|
+
.map((cell, i) => {
|
|
353
|
+
const maxWidth = Math.max(headers[i].length, ...rows.map(r => r[i].length));
|
|
354
|
+
return cell.padEnd(maxWidth);
|
|
355
|
+
})
|
|
356
|
+
.join(' ');
|
|
357
|
+
|
|
358
|
+
ui.print(formattedRow);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Format bytes to human readable
|
|
364
|
+
*/
|
|
365
|
+
function formatBytes(bytes: number): string {
|
|
366
|
+
if (bytes === 0) {
|
|
367
|
+
return '0 B';
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const k = 1024;
|
|
371
|
+
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
372
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
373
|
+
|
|
374
|
+
return `${(bytes / Math.pow(k, i)).toFixed(1)} ${sizes[i]}`;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Show Lambda command help
|
|
379
|
+
*/
|
|
380
|
+
function showLambdaHelp(): void {
|
|
381
|
+
ui.print('Usage: nimbus aws lambda <action> [args]');
|
|
382
|
+
ui.newLine();
|
|
383
|
+
|
|
384
|
+
ui.print(ui.bold('Actions:'));
|
|
385
|
+
ui.print(' list List all Lambda functions');
|
|
386
|
+
ui.print(' invoke <name> Invoke a function');
|
|
387
|
+
ui.print(' logs <name> View function logs');
|
|
388
|
+
ui.newLine();
|
|
389
|
+
|
|
390
|
+
ui.print(ui.bold('Examples:'));
|
|
391
|
+
ui.print(' nimbus aws lambda list');
|
|
392
|
+
ui.print(' nimbus aws lambda invoke my-function \'{"key": "value"}\'');
|
|
393
|
+
ui.print(' nimbus aws lambda logs my-function');
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
export default lambdaCommand;
|