@castari/cli 0.3.0 → 0.3.2
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/README.md +1 -1
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +145 -2
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/buckets.d.ts +6 -0
- package/dist/commands/buckets.d.ts.map +1 -0
- package/dist/commands/buckets.js +359 -0
- package/dist/commands/buckets.js.map +1 -0
- package/dist/commands/files.d.ts +6 -0
- package/dist/commands/files.d.ts.map +1 -0
- package/dist/commands/files.js +369 -0
- package/dist/commands/files.js.map +1 -0
- package/dist/commands/mounts.d.ts +6 -0
- package/dist/commands/mounts.d.ts.map +1 -0
- package/dist/commands/mounts.js +252 -0
- package/dist/commands/mounts.js.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import Table from 'cli-table3';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { createWriteStream } from 'node:fs';
|
|
6
|
+
import { stat, readFile } from 'node:fs/promises';
|
|
7
|
+
import { basename } from 'node:path';
|
|
8
|
+
import { createHash } from 'node:crypto';
|
|
9
|
+
import { CastariClient } from '@castari/sdk';
|
|
10
|
+
import { info, hint, blank, keyValue, formatNumber } from '../utils/output.js';
|
|
11
|
+
import { handleError } from '../utils/errors.js';
|
|
12
|
+
// Threshold for using presigned upload (10MB)
|
|
13
|
+
const PRESIGNED_UPLOAD_THRESHOLD = 10 * 1024 * 1024;
|
|
14
|
+
/**
|
|
15
|
+
* Format file size in human-readable format
|
|
16
|
+
*/
|
|
17
|
+
function formatSize(bytes) {
|
|
18
|
+
if (bytes === 0)
|
|
19
|
+
return '0 B';
|
|
20
|
+
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
21
|
+
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
22
|
+
return `${(bytes / Math.pow(1024, i)).toFixed(i === 0 ? 0 : 1)} ${units[i]}`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Format date for file listing
|
|
26
|
+
*/
|
|
27
|
+
function formatFileDate(dateStr) {
|
|
28
|
+
const date = new Date(dateStr);
|
|
29
|
+
return date.toLocaleDateString('en-US', {
|
|
30
|
+
year: 'numeric',
|
|
31
|
+
month: 'short',
|
|
32
|
+
day: 'numeric',
|
|
33
|
+
hour: '2-digit',
|
|
34
|
+
minute: '2-digit',
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Format scope with color
|
|
39
|
+
*/
|
|
40
|
+
function formatScope(scope) {
|
|
41
|
+
switch (scope) {
|
|
42
|
+
case 'user':
|
|
43
|
+
return chalk.blue(scope);
|
|
44
|
+
case 'agent':
|
|
45
|
+
return chalk.green(scope);
|
|
46
|
+
case 'session':
|
|
47
|
+
return chalk.yellow(scope);
|
|
48
|
+
default:
|
|
49
|
+
return scope;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Format upload status with color
|
|
54
|
+
*/
|
|
55
|
+
function formatUploadStatus(status) {
|
|
56
|
+
switch (status) {
|
|
57
|
+
case 'confirmed':
|
|
58
|
+
return chalk.green(status);
|
|
59
|
+
case 'pending':
|
|
60
|
+
return chalk.yellow(status);
|
|
61
|
+
default:
|
|
62
|
+
return status;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Calculate SHA256 hash of a buffer
|
|
67
|
+
*/
|
|
68
|
+
function sha256(buffer) {
|
|
69
|
+
return createHash('sha256').update(buffer).digest('hex');
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* cast files list
|
|
73
|
+
*/
|
|
74
|
+
const listCommand = new Command('list')
|
|
75
|
+
.description('List files in managed storage')
|
|
76
|
+
.option('--limit <n>', 'Maximum number of files to return', '50')
|
|
77
|
+
.option('--offset <n>', 'Number of files to skip', '0')
|
|
78
|
+
.option('--scope <scope>', 'Filter by scope (user, agent, session)')
|
|
79
|
+
.option('--tags <tags>', 'Filter by tags (comma-separated)')
|
|
80
|
+
.option('--search <query>', 'Search in filename and description')
|
|
81
|
+
.action(async (options) => {
|
|
82
|
+
const spinner = ora('Listing files...').start();
|
|
83
|
+
try {
|
|
84
|
+
const client = new CastariClient();
|
|
85
|
+
await client.ensureAuthenticated();
|
|
86
|
+
const result = await client.files.list({
|
|
87
|
+
limit: parseInt(options.limit, 10),
|
|
88
|
+
offset: parseInt(options.offset, 10),
|
|
89
|
+
scope: options.scope,
|
|
90
|
+
tags: options.tags,
|
|
91
|
+
search: options.search,
|
|
92
|
+
});
|
|
93
|
+
spinner.stop();
|
|
94
|
+
if (result.files.length === 0) {
|
|
95
|
+
info('No files found');
|
|
96
|
+
hint("Upload a file with: cast files upload <path>");
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const table = new Table({
|
|
100
|
+
head: [
|
|
101
|
+
chalk.white('File ID'),
|
|
102
|
+
chalk.white('Filename'),
|
|
103
|
+
chalk.white('Size'),
|
|
104
|
+
chalk.white('Scope'),
|
|
105
|
+
chalk.white('Created'),
|
|
106
|
+
],
|
|
107
|
+
style: {
|
|
108
|
+
head: [],
|
|
109
|
+
border: [],
|
|
110
|
+
},
|
|
111
|
+
colWidths: [24, 30, 12, 10, 20],
|
|
112
|
+
});
|
|
113
|
+
for (const file of result.files) {
|
|
114
|
+
table.push([
|
|
115
|
+
file.file_id,
|
|
116
|
+
file.filename.length > 28
|
|
117
|
+
? file.filename.substring(0, 25) + '...'
|
|
118
|
+
: file.filename,
|
|
119
|
+
formatSize(file.size_bytes),
|
|
120
|
+
formatScope(file.scope),
|
|
121
|
+
formatFileDate(file.created_at),
|
|
122
|
+
]);
|
|
123
|
+
}
|
|
124
|
+
console.log(table.toString());
|
|
125
|
+
blank();
|
|
126
|
+
info(`Showing ${result.files.length} of ${formatNumber(result.meta.total)} file${result.meta.total === 1 ? '' : 's'}`);
|
|
127
|
+
if (result.meta.has_more) {
|
|
128
|
+
hint(`Use --offset ${result.meta.offset + result.meta.limit} to see more`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
spinner.fail('Failed to list files');
|
|
133
|
+
handleError(err);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
/**
|
|
137
|
+
* cast files upload <path>
|
|
138
|
+
*/
|
|
139
|
+
const uploadCommand = new Command('upload')
|
|
140
|
+
.description('Upload a file to managed storage')
|
|
141
|
+
.argument('<path>', 'Local file path')
|
|
142
|
+
.option('--description <desc>', 'File description')
|
|
143
|
+
.option('--tags <tags>', 'Comma-separated tags')
|
|
144
|
+
.action(async (localPath, options) => {
|
|
145
|
+
try {
|
|
146
|
+
const client = new CastariClient();
|
|
147
|
+
await client.ensureAuthenticated();
|
|
148
|
+
// Check if file exists and get size
|
|
149
|
+
let fileStats;
|
|
150
|
+
try {
|
|
151
|
+
fileStats = await stat(localPath);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
handleError(new Error(`File not found: ${localPath}`));
|
|
155
|
+
}
|
|
156
|
+
if (!fileStats.isFile()) {
|
|
157
|
+
handleError(new Error(`Not a file: ${localPath}`));
|
|
158
|
+
}
|
|
159
|
+
const filename = basename(localPath);
|
|
160
|
+
const fileSize = fileStats.size;
|
|
161
|
+
const tags = options.tags?.split(',').map((t) => t.trim()) || [];
|
|
162
|
+
const spinner = ora(`Uploading ${filename} (${formatSize(fileSize)})...`).start();
|
|
163
|
+
let result;
|
|
164
|
+
if (fileSize > PRESIGNED_UPLOAD_THRESHOLD) {
|
|
165
|
+
// Use presigned upload for large files
|
|
166
|
+
spinner.text = `Getting upload URL for ${filename}...`;
|
|
167
|
+
const presigned = await client.files.getUploadUrl(filename, fileSize, {
|
|
168
|
+
description: options.description,
|
|
169
|
+
tags,
|
|
170
|
+
});
|
|
171
|
+
spinner.text = `Uploading ${filename} (${formatSize(fileSize)})...`;
|
|
172
|
+
// Read file and calculate hash
|
|
173
|
+
const fileBuffer = await readFile(localPath);
|
|
174
|
+
const hash = sha256(fileBuffer);
|
|
175
|
+
// Upload to presigned URL
|
|
176
|
+
const uploadResponse = await fetch(presigned.upload_url, {
|
|
177
|
+
method: presigned.upload_method,
|
|
178
|
+
body: fileBuffer,
|
|
179
|
+
headers: presigned.upload_headers,
|
|
180
|
+
});
|
|
181
|
+
if (!uploadResponse.ok) {
|
|
182
|
+
throw new Error(`Upload failed: ${uploadResponse.statusText}`);
|
|
183
|
+
}
|
|
184
|
+
// Confirm upload
|
|
185
|
+
spinner.text = 'Confirming upload...';
|
|
186
|
+
const confirmed = await client.files.confirmUpload(presigned.file_id, hash);
|
|
187
|
+
result = {
|
|
188
|
+
file_id: confirmed.file_id,
|
|
189
|
+
filename: confirmed.filename,
|
|
190
|
+
size_bytes: confirmed.size_bytes,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
// Use direct multipart upload for small files
|
|
195
|
+
const fileBuffer = await readFile(localPath);
|
|
196
|
+
const blob = new Blob([fileBuffer]);
|
|
197
|
+
const uploadResult = await client.files.upload(blob, filename, {
|
|
198
|
+
description: options.description,
|
|
199
|
+
tags,
|
|
200
|
+
});
|
|
201
|
+
result = {
|
|
202
|
+
file_id: uploadResult.file_id,
|
|
203
|
+
filename: uploadResult.filename,
|
|
204
|
+
size_bytes: uploadResult.size_bytes,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
spinner.succeed(`Uploaded ${result.filename}`);
|
|
208
|
+
blank();
|
|
209
|
+
keyValue('File ID', result.file_id);
|
|
210
|
+
keyValue('Size', formatSize(result.size_bytes));
|
|
211
|
+
blank();
|
|
212
|
+
hint(`Attach to agent: cast agents files add <agent-slug> ${result.file_id}`);
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
handleError(err);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
/**
|
|
219
|
+
* cast files get <file_id>
|
|
220
|
+
*/
|
|
221
|
+
const getCommand = new Command('get')
|
|
222
|
+
.description('Get file details')
|
|
223
|
+
.argument('<file_id>', 'File ID')
|
|
224
|
+
.action(async (fileId) => {
|
|
225
|
+
const spinner = ora('Fetching file...').start();
|
|
226
|
+
try {
|
|
227
|
+
const client = new CastariClient();
|
|
228
|
+
await client.ensureAuthenticated();
|
|
229
|
+
const file = await client.files.get(fileId);
|
|
230
|
+
spinner.stop();
|
|
231
|
+
blank();
|
|
232
|
+
keyValue('File ID', file.file_id);
|
|
233
|
+
keyValue('Filename', file.filename);
|
|
234
|
+
keyValue('Size', formatSize(file.size_bytes));
|
|
235
|
+
keyValue('Content Type', file.content_type ?? 'unknown');
|
|
236
|
+
keyValue('Scope', formatScope(file.scope));
|
|
237
|
+
if (file.scope_id) {
|
|
238
|
+
keyValue('Scope ID', file.scope_id);
|
|
239
|
+
}
|
|
240
|
+
keyValue('Status', formatUploadStatus(file.upload_status));
|
|
241
|
+
if (file.description) {
|
|
242
|
+
keyValue('Description', file.description);
|
|
243
|
+
}
|
|
244
|
+
if (file.tags.length > 0) {
|
|
245
|
+
keyValue('Tags', file.tags.join(', '));
|
|
246
|
+
}
|
|
247
|
+
keyValue('SHA256', file.sha256_hash);
|
|
248
|
+
keyValue('Created', formatFileDate(file.created_at));
|
|
249
|
+
keyValue('Updated', formatFileDate(file.updated_at));
|
|
250
|
+
blank();
|
|
251
|
+
}
|
|
252
|
+
catch (err) {
|
|
253
|
+
spinner.fail('Failed to get file');
|
|
254
|
+
handleError(err);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
/**
|
|
258
|
+
* cast files delete <file_id>
|
|
259
|
+
*/
|
|
260
|
+
const deleteCommand = new Command('delete')
|
|
261
|
+
.description('Delete a file')
|
|
262
|
+
.argument('<file_id>', 'File ID')
|
|
263
|
+
.option('-f, --force', 'Skip confirmation')
|
|
264
|
+
.action(async (fileId, options) => {
|
|
265
|
+
try {
|
|
266
|
+
const client = new CastariClient();
|
|
267
|
+
await client.ensureAuthenticated();
|
|
268
|
+
// Confirm deletion unless --force is used
|
|
269
|
+
if (!options.force) {
|
|
270
|
+
const readline = await import('node:readline');
|
|
271
|
+
const rl = readline.createInterface({
|
|
272
|
+
input: process.stdin,
|
|
273
|
+
output: process.stdout,
|
|
274
|
+
});
|
|
275
|
+
const answer = await new Promise((resolve) => {
|
|
276
|
+
rl.question(chalk.yellow(`Are you sure you want to delete file '${fileId}'? [y/N] `), resolve);
|
|
277
|
+
});
|
|
278
|
+
rl.close();
|
|
279
|
+
if (answer.toLowerCase() !== 'y' && answer.toLowerCase() !== 'yes') {
|
|
280
|
+
info('Deletion cancelled');
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
const spinner = ora('Deleting file...').start();
|
|
285
|
+
await client.files.delete(fileId);
|
|
286
|
+
spinner.succeed(`File '${fileId}' deleted`);
|
|
287
|
+
}
|
|
288
|
+
catch (err) {
|
|
289
|
+
handleError(err);
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
/**
|
|
293
|
+
* cast files download <file_id>
|
|
294
|
+
*/
|
|
295
|
+
const downloadCommand = new Command('download')
|
|
296
|
+
.description('Download a file')
|
|
297
|
+
.argument('<file_id>', 'File ID')
|
|
298
|
+
.option('--output <path>', 'Output file path (default: original filename)')
|
|
299
|
+
.action(async (fileId, options) => {
|
|
300
|
+
try {
|
|
301
|
+
const client = new CastariClient();
|
|
302
|
+
await client.ensureAuthenticated();
|
|
303
|
+
// First get file metadata to know the filename
|
|
304
|
+
const spinner = ora('Fetching file info...').start();
|
|
305
|
+
const file = await client.files.get(fileId);
|
|
306
|
+
const outputPath = options.output || file.filename;
|
|
307
|
+
spinner.text = `Downloading ${file.filename}...`;
|
|
308
|
+
// Download file content via SDK (uses configured base URL and auth)
|
|
309
|
+
const response = await client.files.download(fileId);
|
|
310
|
+
// Write to file
|
|
311
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
312
|
+
const buffer = Buffer.from(arrayBuffer);
|
|
313
|
+
await new Promise((resolve, reject) => {
|
|
314
|
+
const writeStream = createWriteStream(outputPath);
|
|
315
|
+
writeStream.write(buffer);
|
|
316
|
+
writeStream.end();
|
|
317
|
+
writeStream.on('finish', resolve);
|
|
318
|
+
writeStream.on('error', reject);
|
|
319
|
+
});
|
|
320
|
+
spinner.succeed(`Downloaded to ${outputPath}`);
|
|
321
|
+
info(`Size: ${formatSize(buffer.length)}`);
|
|
322
|
+
}
|
|
323
|
+
catch (err) {
|
|
324
|
+
handleError(err);
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
/**
|
|
328
|
+
* cast files usage
|
|
329
|
+
*/
|
|
330
|
+
const usageCommand = new Command('usage')
|
|
331
|
+
.description('Show storage usage')
|
|
332
|
+
.action(async () => {
|
|
333
|
+
const spinner = ora('Fetching storage usage...').start();
|
|
334
|
+
try {
|
|
335
|
+
const client = new CastariClient();
|
|
336
|
+
await client.ensureAuthenticated();
|
|
337
|
+
const usage = await client.files.getUsage();
|
|
338
|
+
spinner.stop();
|
|
339
|
+
blank();
|
|
340
|
+
keyValue('Total Files', formatNumber(usage.total_files));
|
|
341
|
+
keyValue('Total Size', formatSize(usage.total_bytes));
|
|
342
|
+
keyValue('Quota Used', `${usage.usage_percent.toFixed(1)}%`);
|
|
343
|
+
keyValue('Quota Limit', `${usage.limit_mb} MB`);
|
|
344
|
+
blank();
|
|
345
|
+
// Show progress bar
|
|
346
|
+
const barWidth = 40;
|
|
347
|
+
const filled = Math.round((usage.usage_percent / 100) * barWidth);
|
|
348
|
+
const empty = barWidth - filled;
|
|
349
|
+
const bar = chalk.green('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));
|
|
350
|
+
console.log(` ${bar} ${usage.usage_percent.toFixed(1)}%`);
|
|
351
|
+
blank();
|
|
352
|
+
}
|
|
353
|
+
catch (err) {
|
|
354
|
+
spinner.fail('Failed to get storage usage');
|
|
355
|
+
handleError(err);
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
/**
|
|
359
|
+
* cast files
|
|
360
|
+
*/
|
|
361
|
+
export const filesCommand = new Command('files')
|
|
362
|
+
.description('Manage files in Castari storage')
|
|
363
|
+
.addCommand(listCommand)
|
|
364
|
+
.addCommand(uploadCommand)
|
|
365
|
+
.addCommand(getCommand)
|
|
366
|
+
.addCommand(deleteCommand)
|
|
367
|
+
.addCommand(downloadCommand)
|
|
368
|
+
.addCommand(usageCommand);
|
|
369
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/commands/files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mounts.d.ts","sourceRoot":"","sources":["../../src/commands/mounts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsSpC;;GAEG;AACH,eAAO,MAAM,aAAa,SAKE,CAAC"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import Table from 'cli-table3';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import prompts from 'prompts';
|
|
6
|
+
import { CastariClient } from '@castari/sdk';
|
|
7
|
+
import { info, hint, blank, keyValue } from '../utils/output.js';
|
|
8
|
+
import { handleError } from '../utils/errors.js';
|
|
9
|
+
/**
|
|
10
|
+
* Format enabled status with color
|
|
11
|
+
*/
|
|
12
|
+
function formatEnabled(enabled) {
|
|
13
|
+
return enabled ? chalk.green('Enabled') : chalk.gray('Disabled');
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Format permission rules
|
|
17
|
+
*/
|
|
18
|
+
function formatPermissions(rules) {
|
|
19
|
+
if (rules.length === 0) {
|
|
20
|
+
return chalk.gray('rw (default)');
|
|
21
|
+
}
|
|
22
|
+
return rules.map((r) => `${r.path}:${r.mode}`).join(', ');
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* cast mounts list <agent-slug>
|
|
26
|
+
*/
|
|
27
|
+
const listCommand = new Command('list')
|
|
28
|
+
.description('List mounts for an agent')
|
|
29
|
+
.argument('<agent-slug>', 'Agent slug')
|
|
30
|
+
.action(async (agentSlug) => {
|
|
31
|
+
const spinner = ora('Fetching mounts...').start();
|
|
32
|
+
try {
|
|
33
|
+
const client = new CastariClient();
|
|
34
|
+
await client.ensureAuthenticated();
|
|
35
|
+
const mounts = await client.mounts.getMounts(agentSlug);
|
|
36
|
+
spinner.stop();
|
|
37
|
+
if (mounts.length === 0) {
|
|
38
|
+
info(`No mounts configured for agent '${agentSlug}'`);
|
|
39
|
+
hint(`Add one with: cast mounts add ${agentSlug}`);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const table = new Table({
|
|
43
|
+
head: [
|
|
44
|
+
chalk.white('ID'),
|
|
45
|
+
chalk.white('Bucket'),
|
|
46
|
+
chalk.white('Mount Path'),
|
|
47
|
+
chalk.white('Prefix'),
|
|
48
|
+
chalk.white('Status'),
|
|
49
|
+
],
|
|
50
|
+
style: {
|
|
51
|
+
head: [],
|
|
52
|
+
border: [],
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
for (const mount of mounts) {
|
|
56
|
+
table.push([
|
|
57
|
+
mount.id.substring(0, 8),
|
|
58
|
+
mount.bucket.slug,
|
|
59
|
+
mount.mount_path,
|
|
60
|
+
mount.source_prefix || chalk.gray('-'),
|
|
61
|
+
formatEnabled(mount.enabled),
|
|
62
|
+
]);
|
|
63
|
+
}
|
|
64
|
+
console.log(table.toString());
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
spinner.fail('Failed to list mounts');
|
|
68
|
+
handleError(err);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
/**
|
|
72
|
+
* cast mounts add <agent-slug>
|
|
73
|
+
*/
|
|
74
|
+
const addCommand = new Command('add')
|
|
75
|
+
.description('Add a mount to an agent')
|
|
76
|
+
.argument('<agent-slug>', 'Agent slug')
|
|
77
|
+
.option('--bucket <bucket-slug>', 'Bucket to mount')
|
|
78
|
+
.option('--path <mount-path>', 'Mount path (e.g., /data)')
|
|
79
|
+
.option('--prefix <source-prefix>', 'Source prefix in bucket')
|
|
80
|
+
.option('--read-only', 'Make the mount read-only')
|
|
81
|
+
.action(async (agentSlug, options) => {
|
|
82
|
+
try {
|
|
83
|
+
const client = new CastariClient();
|
|
84
|
+
await client.ensureAuthenticated();
|
|
85
|
+
let bucketSlug = options.bucket;
|
|
86
|
+
let mountPath = options.path;
|
|
87
|
+
let sourcePrefix = options.prefix;
|
|
88
|
+
// Interactive mode if bucket or path not provided
|
|
89
|
+
if (!bucketSlug || !mountPath) {
|
|
90
|
+
// Fetch available buckets for selection
|
|
91
|
+
const buckets = await client.storage.getBuckets();
|
|
92
|
+
if (buckets.length === 0) {
|
|
93
|
+
info('No buckets available');
|
|
94
|
+
hint("Create one with: cast buckets create <name>");
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const responses = await prompts([
|
|
98
|
+
{
|
|
99
|
+
type: bucketSlug ? null : 'select',
|
|
100
|
+
name: 'bucket',
|
|
101
|
+
message: 'Select bucket to mount',
|
|
102
|
+
choices: buckets.map((b) => ({
|
|
103
|
+
title: `${b.name} (${b.slug})`,
|
|
104
|
+
value: b.slug,
|
|
105
|
+
})),
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
type: mountPath ? null : 'text',
|
|
109
|
+
name: 'path',
|
|
110
|
+
message: 'Mount path (e.g., /data)',
|
|
111
|
+
initial: '/data',
|
|
112
|
+
validate: (value) => value.startsWith('/') ? true : 'Mount path must start with /',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
type: sourcePrefix !== undefined ? null : 'text',
|
|
116
|
+
name: 'prefix',
|
|
117
|
+
message: 'Source prefix in bucket (optional)',
|
|
118
|
+
initial: '',
|
|
119
|
+
},
|
|
120
|
+
]);
|
|
121
|
+
if ((!responses.bucket && !bucketSlug) || (!responses.path && !mountPath)) {
|
|
122
|
+
info('Mount creation cancelled');
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
bucketSlug = bucketSlug || responses.bucket;
|
|
126
|
+
mountPath = mountPath || responses.path;
|
|
127
|
+
sourcePrefix = sourcePrefix !== undefined ? sourcePrefix : responses.prefix;
|
|
128
|
+
}
|
|
129
|
+
const spinner = ora('Adding mount...').start();
|
|
130
|
+
const mount = await client.mounts.addMount(agentSlug, {
|
|
131
|
+
bucketSlug: bucketSlug,
|
|
132
|
+
mountPath: mountPath,
|
|
133
|
+
sourcePrefix: sourcePrefix || undefined,
|
|
134
|
+
permissionRules: options.readOnly ? [{ path: '/', mode: 'ro' }] : undefined,
|
|
135
|
+
});
|
|
136
|
+
spinner.succeed(`Mount added to agent '${agentSlug}'`);
|
|
137
|
+
blank();
|
|
138
|
+
keyValue('Mount ID', mount.id.substring(0, 8));
|
|
139
|
+
keyValue('Bucket', mount.bucket.slug);
|
|
140
|
+
keyValue('Mount Path', mount.mount_path);
|
|
141
|
+
keyValue('Source Prefix', mount.source_prefix || '-');
|
|
142
|
+
keyValue('Permissions', formatPermissions(mount.permission_rules));
|
|
143
|
+
blank();
|
|
144
|
+
hint('Redeploy the agent to apply changes');
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
handleError(err);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
/**
|
|
151
|
+
* cast mounts remove <agent-slug> <mount-id>
|
|
152
|
+
*/
|
|
153
|
+
const removeCommand = new Command('remove')
|
|
154
|
+
.description('Remove a mount from an agent')
|
|
155
|
+
.argument('<agent-slug>', 'Agent slug')
|
|
156
|
+
.argument('<mount-id>', 'Mount ID (or prefix)')
|
|
157
|
+
.option('-f, --force', 'Skip confirmation')
|
|
158
|
+
.action(async (agentSlug, mountId, options) => {
|
|
159
|
+
try {
|
|
160
|
+
const client = new CastariClient();
|
|
161
|
+
await client.ensureAuthenticated();
|
|
162
|
+
// Find the full mount ID if a prefix was provided
|
|
163
|
+
const mounts = await client.mounts.getMounts(agentSlug);
|
|
164
|
+
const mount = mounts.find((m) => m.id.startsWith(mountId));
|
|
165
|
+
if (!mount) {
|
|
166
|
+
handleError(new Error(`Mount '${mountId}' not found for agent '${agentSlug}'`));
|
|
167
|
+
}
|
|
168
|
+
// Confirm deletion unless --force is used
|
|
169
|
+
if (!options.force) {
|
|
170
|
+
const response = await prompts({
|
|
171
|
+
type: 'confirm',
|
|
172
|
+
name: 'confirm',
|
|
173
|
+
message: `Remove mount at '${mount.mount_path}' from agent '${agentSlug}'?`,
|
|
174
|
+
initial: false,
|
|
175
|
+
});
|
|
176
|
+
if (!response.confirm) {
|
|
177
|
+
info('Removal cancelled');
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
const spinner = ora('Removing mount...').start();
|
|
182
|
+
await client.mounts.removeMount(agentSlug, mount.id);
|
|
183
|
+
spinner.succeed(`Mount removed from agent '${agentSlug}'`);
|
|
184
|
+
hint('Redeploy the agent to apply changes');
|
|
185
|
+
}
|
|
186
|
+
catch (err) {
|
|
187
|
+
handleError(err);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
/**
|
|
191
|
+
* cast mounts update <agent-slug> <mount-id>
|
|
192
|
+
*/
|
|
193
|
+
const updateCommand = new Command('update')
|
|
194
|
+
.description('Update a mount configuration')
|
|
195
|
+
.argument('<agent-slug>', 'Agent slug')
|
|
196
|
+
.argument('<mount-id>', 'Mount ID (or prefix)')
|
|
197
|
+
.option('--path <mount-path>', 'New mount path')
|
|
198
|
+
.option('--prefix <source-prefix>', 'New source prefix')
|
|
199
|
+
.option('--enable', 'Enable the mount')
|
|
200
|
+
.option('--disable', 'Disable the mount')
|
|
201
|
+
.action(async (agentSlug, mountId, options) => {
|
|
202
|
+
try {
|
|
203
|
+
const client = new CastariClient();
|
|
204
|
+
await client.ensureAuthenticated();
|
|
205
|
+
// Find the full mount ID if a prefix was provided
|
|
206
|
+
const mounts = await client.mounts.getMounts(agentSlug);
|
|
207
|
+
const mount = mounts.find((m) => m.id.startsWith(mountId));
|
|
208
|
+
if (!mount) {
|
|
209
|
+
handleError(new Error(`Mount '${mountId}' not found for agent '${agentSlug}'`));
|
|
210
|
+
}
|
|
211
|
+
// Determine enabled state
|
|
212
|
+
let enabled;
|
|
213
|
+
if (options.enable) {
|
|
214
|
+
enabled = true;
|
|
215
|
+
}
|
|
216
|
+
else if (options.disable) {
|
|
217
|
+
enabled = false;
|
|
218
|
+
}
|
|
219
|
+
// Check if any updates were specified
|
|
220
|
+
if (!options.path && options.prefix === undefined && enabled === undefined) {
|
|
221
|
+
info('No updates specified');
|
|
222
|
+
hint('Use --path, --prefix, --enable, or --disable to update the mount');
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const spinner = ora('Updating mount...').start();
|
|
226
|
+
const updated = await client.mounts.updateMount(agentSlug, mount.id, {
|
|
227
|
+
mountPath: options.path,
|
|
228
|
+
sourcePrefix: options.prefix,
|
|
229
|
+
enabled,
|
|
230
|
+
});
|
|
231
|
+
spinner.succeed(`Mount updated`);
|
|
232
|
+
blank();
|
|
233
|
+
keyValue('Mount Path', updated.mount_path);
|
|
234
|
+
keyValue('Source Prefix', updated.source_prefix || '-');
|
|
235
|
+
keyValue('Status', formatEnabled(updated.enabled));
|
|
236
|
+
blank();
|
|
237
|
+
hint('Redeploy the agent to apply changes');
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
handleError(err);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
/**
|
|
244
|
+
* cast mounts
|
|
245
|
+
*/
|
|
246
|
+
export const mountsCommand = new Command('mounts')
|
|
247
|
+
.description('Manage agent storage mounts')
|
|
248
|
+
.addCommand(listCommand)
|
|
249
|
+
.addCommand(addCommand)
|
|
250
|
+
.addCommand(removeCommand)
|
|
251
|
+
.addCommand(updateCommand);
|
|
252
|
+
//# sourceMappingURL=mounts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mounts.js","sourceRoot":"","sources":["../../src/commands/mounts.ts"],"names":[],"mappings":"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"}
|