@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,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GCP Cloud Storage CLI Commands
|
|
3
|
+
*
|
|
4
|
+
* Operations for Cloud Storage buckets and objects
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { execFile } from 'child_process';
|
|
8
|
+
import { promisify } from 'util';
|
|
9
|
+
import { logger } from '../../utils';
|
|
10
|
+
import { ui } from '../../wizard/ui';
|
|
11
|
+
import {
|
|
12
|
+
loadSafetyPolicy,
|
|
13
|
+
evaluateSafety,
|
|
14
|
+
type SafetyContext,
|
|
15
|
+
type SafetyCheckResult,
|
|
16
|
+
} from '../../config/safety-policy';
|
|
17
|
+
import { promptForApproval, displaySafetySummary } from '../../wizard/approval';
|
|
18
|
+
import type { GcpCommandOptions } from './index';
|
|
19
|
+
|
|
20
|
+
const execFileAsync = promisify(execFile);
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Run storage safety checks
|
|
24
|
+
*/
|
|
25
|
+
async function runStorageSafetyChecks(
|
|
26
|
+
action: string,
|
|
27
|
+
target: string,
|
|
28
|
+
options: GcpCommandOptions
|
|
29
|
+
): Promise<SafetyCheckResult> {
|
|
30
|
+
const safetyPolicy = loadSafetyPolicy();
|
|
31
|
+
|
|
32
|
+
const context: SafetyContext = {
|
|
33
|
+
operation: action,
|
|
34
|
+
type: 'gcp',
|
|
35
|
+
environment: options.project || 'default',
|
|
36
|
+
resources: [target],
|
|
37
|
+
metadata: {
|
|
38
|
+
resourceType: 'storage',
|
|
39
|
+
resourceId: target,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
return evaluateSafety(context, safetyPolicy);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Main Cloud Storage command router
|
|
48
|
+
*/
|
|
49
|
+
export async function storageCommand(
|
|
50
|
+
action: string,
|
|
51
|
+
args: string[],
|
|
52
|
+
options: GcpCommandOptions
|
|
53
|
+
): Promise<void> {
|
|
54
|
+
logger.info('Running GCP Storage command', { action, args, options });
|
|
55
|
+
|
|
56
|
+
switch (action) {
|
|
57
|
+
case 'ls':
|
|
58
|
+
await listBucketsOrObjects(args[0], options);
|
|
59
|
+
break;
|
|
60
|
+
|
|
61
|
+
case 'cp':
|
|
62
|
+
if (args.length < 2) {
|
|
63
|
+
ui.error('Source and destination required');
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
await copyObject(args[0], args[1], options);
|
|
67
|
+
break;
|
|
68
|
+
|
|
69
|
+
case 'rm':
|
|
70
|
+
if (!args[0]) {
|
|
71
|
+
ui.error('Object path required');
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
await removeObject(args[0], options);
|
|
75
|
+
break;
|
|
76
|
+
|
|
77
|
+
case 'mb':
|
|
78
|
+
if (!args[0]) {
|
|
79
|
+
ui.error('Bucket name required');
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
await makeBucket(args[0], options);
|
|
83
|
+
break;
|
|
84
|
+
|
|
85
|
+
case 'rb':
|
|
86
|
+
if (!args[0]) {
|
|
87
|
+
ui.error('Bucket name required');
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
await removeBucket(args[0], options);
|
|
91
|
+
break;
|
|
92
|
+
|
|
93
|
+
default:
|
|
94
|
+
showStorageHelp();
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* List buckets or objects
|
|
101
|
+
*/
|
|
102
|
+
async function listBucketsOrObjects(
|
|
103
|
+
path: string | undefined,
|
|
104
|
+
_options: GcpCommandOptions
|
|
105
|
+
): Promise<void> {
|
|
106
|
+
const gsutilArgs = ['ls'];
|
|
107
|
+
if (path) {
|
|
108
|
+
gsutilArgs.push(path);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
ui.startSpinner({ message: path ? `Listing objects in ${path}...` : 'Listing buckets...' });
|
|
113
|
+
const { stdout } = await execFileAsync('gsutil', gsutilArgs);
|
|
114
|
+
ui.stopSpinnerSuccess(path ? `Objects in ${path}` : 'Buckets listed');
|
|
115
|
+
|
|
116
|
+
const items = stdout.trim().split('\n').filter(Boolean);
|
|
117
|
+
|
|
118
|
+
if (items.length === 0) {
|
|
119
|
+
ui.info(path ? 'No objects found' : 'No buckets found');
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
ui.header(path ? `Objects in ${path}` : 'Cloud Storage Buckets');
|
|
124
|
+
ui.newLine();
|
|
125
|
+
|
|
126
|
+
ui.print(`Found ${items.length} item(s)\n`);
|
|
127
|
+
|
|
128
|
+
for (const item of items) {
|
|
129
|
+
if (item.startsWith('gs://')) {
|
|
130
|
+
// Bucket
|
|
131
|
+
ui.print(` ${ui.color(item, 'cyan')}`);
|
|
132
|
+
} else {
|
|
133
|
+
// Object
|
|
134
|
+
ui.print(` ${item}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
} catch (error: unknown) {
|
|
138
|
+
ui.stopSpinnerFail('Failed to list');
|
|
139
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
140
|
+
logger.error('Failed to list storage', { error: message });
|
|
141
|
+
ui.error(`Failed to list: ${message}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Copy objects
|
|
147
|
+
*/
|
|
148
|
+
async function copyObject(
|
|
149
|
+
source: string,
|
|
150
|
+
destination: string,
|
|
151
|
+
_options: GcpCommandOptions
|
|
152
|
+
): Promise<void> {
|
|
153
|
+
const gsutilArgs = ['cp', source, destination];
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
ui.startSpinner({ message: `Copying ${source} to ${destination}...` });
|
|
157
|
+
await execFileAsync('gsutil', gsutilArgs);
|
|
158
|
+
ui.stopSpinnerSuccess(`Copied ${source} to ${destination}`);
|
|
159
|
+
} catch (error: unknown) {
|
|
160
|
+
ui.stopSpinnerFail('Failed to copy');
|
|
161
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
162
|
+
logger.error('Failed to copy object', { error: message });
|
|
163
|
+
ui.error(`Failed to copy: ${message}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Remove an object (requires safety approval)
|
|
169
|
+
*/
|
|
170
|
+
async function removeObject(path: string, options: GcpCommandOptions): Promise<void> {
|
|
171
|
+
// Run safety checks
|
|
172
|
+
const safetyResult = await runStorageSafetyChecks('delete', path, options);
|
|
173
|
+
|
|
174
|
+
displaySafetySummary({
|
|
175
|
+
operation: `rm ${path}`,
|
|
176
|
+
risks: safetyResult.risks,
|
|
177
|
+
passed: safetyResult.passed,
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
if (safetyResult.requiresApproval) {
|
|
181
|
+
const result = await promptForApproval({
|
|
182
|
+
title: 'Remove Storage Object',
|
|
183
|
+
operation: `gsutil rm ${path}`,
|
|
184
|
+
risks: safetyResult.risks,
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
if (!result.approved) {
|
|
188
|
+
ui.warning('Operation cancelled');
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const gsutilArgs = ['rm', path];
|
|
194
|
+
|
|
195
|
+
try {
|
|
196
|
+
ui.startSpinner({ message: `Removing ${path}...` });
|
|
197
|
+
await execFileAsync('gsutil', gsutilArgs);
|
|
198
|
+
ui.stopSpinnerSuccess(`Removed ${path}`);
|
|
199
|
+
} catch (error: unknown) {
|
|
200
|
+
ui.stopSpinnerFail('Failed to remove');
|
|
201
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
202
|
+
logger.error('Failed to remove object', { error: message });
|
|
203
|
+
ui.error(`Failed to remove: ${message}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Create a bucket
|
|
209
|
+
*/
|
|
210
|
+
async function makeBucket(bucketName: string, options: GcpCommandOptions): Promise<void> {
|
|
211
|
+
const gsutilArgs = ['mb'];
|
|
212
|
+
if (options.project) {
|
|
213
|
+
gsutilArgs.push('-p', options.project);
|
|
214
|
+
}
|
|
215
|
+
if (options.region) {
|
|
216
|
+
gsutilArgs.push('-l', options.region);
|
|
217
|
+
}
|
|
218
|
+
gsutilArgs.push(bucketName.startsWith('gs://') ? bucketName : `gs://${bucketName}`);
|
|
219
|
+
|
|
220
|
+
try {
|
|
221
|
+
ui.startSpinner({ message: `Creating bucket ${bucketName}...` });
|
|
222
|
+
await execFileAsync('gsutil', gsutilArgs);
|
|
223
|
+
ui.stopSpinnerSuccess(`Bucket ${bucketName} created`);
|
|
224
|
+
} catch (error: unknown) {
|
|
225
|
+
ui.stopSpinnerFail('Failed to create bucket');
|
|
226
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
227
|
+
logger.error('Failed to create bucket', { error: message });
|
|
228
|
+
ui.error(`Failed to create bucket: ${message}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Remove a bucket (requires safety approval)
|
|
234
|
+
*/
|
|
235
|
+
async function removeBucket(bucketName: string, options: GcpCommandOptions): Promise<void> {
|
|
236
|
+
const bucket = bucketName.startsWith('gs://') ? bucketName : `gs://${bucketName}`;
|
|
237
|
+
|
|
238
|
+
// Run safety checks
|
|
239
|
+
const safetyResult = await runStorageSafetyChecks('delete', bucket, options);
|
|
240
|
+
|
|
241
|
+
displaySafetySummary({
|
|
242
|
+
operation: `rb ${bucket}`,
|
|
243
|
+
risks: safetyResult.risks,
|
|
244
|
+
passed: safetyResult.passed,
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
if (safetyResult.requiresApproval) {
|
|
248
|
+
const result = await promptForApproval({
|
|
249
|
+
title: 'Remove Storage Bucket',
|
|
250
|
+
operation: `gsutil rb ${bucket}`,
|
|
251
|
+
risks: safetyResult.risks,
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
if (!result.approved) {
|
|
255
|
+
ui.warning('Operation cancelled');
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const gsutilArgs = ['rb', bucket];
|
|
261
|
+
|
|
262
|
+
try {
|
|
263
|
+
ui.startSpinner({ message: `Removing bucket ${bucket}...` });
|
|
264
|
+
await execFileAsync('gsutil', gsutilArgs);
|
|
265
|
+
ui.stopSpinnerSuccess(`Bucket ${bucket} removed`);
|
|
266
|
+
} catch (error: unknown) {
|
|
267
|
+
ui.stopSpinnerFail('Failed to remove bucket');
|
|
268
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
269
|
+
logger.error('Failed to remove bucket', { error: message });
|
|
270
|
+
ui.error(`Failed to remove bucket: ${message}`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Show Storage help
|
|
276
|
+
*/
|
|
277
|
+
function showStorageHelp(): void {
|
|
278
|
+
ui.print(ui.bold('Cloud Storage Commands:'));
|
|
279
|
+
ui.print(' ls [gs://bucket] List buckets or objects');
|
|
280
|
+
ui.print(' cp <src> <dst> Copy objects');
|
|
281
|
+
ui.print(' rm <path> Remove object (requires approval)');
|
|
282
|
+
ui.print(' mb <bucket> Create bucket');
|
|
283
|
+
ui.print(' rb <bucket> Remove bucket (requires approval)');
|
|
284
|
+
}
|