@castari/cli 0.0.2 → 0.0.4
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 +20 -0
- package/dist/commands/deploy.js +35 -37
- package/dist/commands/init.js +2 -2
- package/dist/commands/start.js +3 -6
- package/dist/index.js +3 -3
- package/package.json +8 -5
package/README.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# @castari/cli
|
|
2
|
+
|
|
3
|
+
The Command Line Interface for Castari.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @castari/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
See the [CLI Reference](../../docs/cli-reference.md) for detailed documentation.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
castari init # Create a new agent
|
|
17
|
+
castari dev # Run locally
|
|
18
|
+
castari deploy # Deploy to Platform
|
|
19
|
+
castari start # Start sandbox
|
|
20
|
+
```
|
package/dist/commands/deploy.js
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
import { Daytona, Image } from '@daytonaio/sdk';
|
|
2
1
|
import { readFile } from 'fs/promises';
|
|
3
2
|
import chalk from 'chalk';
|
|
3
|
+
import AdmZip from 'adm-zip';
|
|
4
4
|
export async function deploy(options) {
|
|
5
|
-
const apiKey = process.env.DAYTONA_API_KEY;
|
|
6
|
-
if (!apiKey) {
|
|
7
|
-
console.error(chalk.red('Error: DAYTONA_API_KEY is required.'));
|
|
8
|
-
process.exit(1);
|
|
9
|
-
}
|
|
10
5
|
// Read package.json to get default snapshot name
|
|
11
6
|
let snapshotName = options.snapshot;
|
|
12
7
|
if (!snapshotName) {
|
|
@@ -23,42 +18,45 @@ export async function deploy(options) {
|
|
|
23
18
|
console.error(chalk.red('Error: Snapshot name is required (via --snapshot or package.json name).'));
|
|
24
19
|
process.exit(1);
|
|
25
20
|
}
|
|
26
|
-
console.log(chalk.blue(
|
|
27
|
-
const
|
|
28
|
-
apiKey,
|
|
29
|
-
apiUrl: process.env.DAYTONA_API_URL,
|
|
30
|
-
target: process.env.DAYTONA_TARGET,
|
|
31
|
-
});
|
|
21
|
+
console.log(chalk.blue(`📦 Packaging source code...`));
|
|
22
|
+
const zip = new AdmZip();
|
|
32
23
|
const projectRoot = process.cwd();
|
|
33
|
-
|
|
34
|
-
//
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
.
|
|
24
|
+
// Add local files, respecting a simple ignore list for now
|
|
25
|
+
// Ideally we'd parse .gitignore, but for MVP let's just ignore common heavy folders
|
|
26
|
+
const ignoreList = ['node_modules', '.git', 'dist', '.daytona', '.env'];
|
|
27
|
+
zip.addLocalFolder(projectRoot, undefined, (filename) => {
|
|
28
|
+
// Simple filter: return false to exclude
|
|
29
|
+
// filename is the relative path in the zip? No, it seems to be the absolute path or filename.
|
|
30
|
+
// AdmZip filter is a bit tricky. Let's assume it passes the name.
|
|
31
|
+
// Actually addLocalFolder filter takes a RegExp or function.
|
|
32
|
+
// If function: (filename: string) => boolean.
|
|
33
|
+
// Note: filename passed to filter is usually the relative path.
|
|
34
|
+
// Let's try to be safe and just add everything except node_modules at the root.
|
|
35
|
+
// Actually, addLocalFolder adds everything.
|
|
36
|
+
// We might want to use addLocalFile loop or similar if we want strict control.
|
|
37
|
+
// But let's try the filter.
|
|
38
|
+
return !ignoreList.some(ignore => filename.includes(ignore));
|
|
39
|
+
});
|
|
40
|
+
const zipBuffer = zip.toBuffer();
|
|
41
|
+
console.log(chalk.blue(`🚀 Uploading to Castari Platform...`));
|
|
42
|
+
const platformUrl = process.env.CASTARI_PLATFORM_URL || 'http://localhost:3000';
|
|
43
|
+
const formData = new FormData();
|
|
44
|
+
formData.append('file', new Blob([zipBuffer]), 'source.zip');
|
|
45
|
+
formData.append('snapshot', snapshotName);
|
|
40
46
|
try {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
console.log(chalk.yellow(`🗑️ Deleted existing snapshot "${snapshotName}"`));
|
|
45
|
-
}
|
|
46
|
-
catch (e) {
|
|
47
|
-
// Ignore delete error (e.g. not found)
|
|
48
|
-
}
|
|
49
|
-
await daytona.snapshot.create({
|
|
50
|
-
name: snapshotName,
|
|
51
|
-
image,
|
|
52
|
-
}, {
|
|
53
|
-
onLogs: log => {
|
|
54
|
-
if (log)
|
|
55
|
-
process.stdout.write(log);
|
|
56
|
-
},
|
|
47
|
+
const response = await fetch(`${platformUrl}/deploy`, {
|
|
48
|
+
method: 'POST',
|
|
49
|
+
body: formData,
|
|
57
50
|
});
|
|
58
|
-
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
const errorText = await response.text();
|
|
53
|
+
throw new Error(`Platform error (${response.status}): ${errorText}`);
|
|
54
|
+
}
|
|
55
|
+
const result = await response.json();
|
|
56
|
+
console.log(chalk.green(`✅ Snapshot "${result.snapshot}" created successfully!`));
|
|
59
57
|
}
|
|
60
58
|
catch (err) {
|
|
61
|
-
console.error(chalk.red('
|
|
59
|
+
console.error(chalk.red('Deploy failed:'), err.message || err);
|
|
62
60
|
process.exit(1);
|
|
63
61
|
}
|
|
64
62
|
}
|
package/dist/commands/init.js
CHANGED
|
@@ -22,7 +22,7 @@ export async function init() {
|
|
|
22
22
|
start: 'castari start',
|
|
23
23
|
},
|
|
24
24
|
dependencies: {
|
|
25
|
-
'@castari/sdk': '
|
|
25
|
+
'@castari/sdk': '^0.0.4',
|
|
26
26
|
'@anthropic-ai/claude-agent-sdk': '^0.1.44',
|
|
27
27
|
},
|
|
28
28
|
castari: {
|
|
@@ -62,7 +62,7 @@ serve({
|
|
|
62
62
|
systemPrompt: 'You are a helpful Castari agent.',
|
|
63
63
|
})
|
|
64
64
|
`;
|
|
65
|
-
const envExample = `ANTHROPIC_API_KEY=sk-ant-...\
|
|
65
|
+
const envExample = `ANTHROPIC_API_KEY=sk-ant-...\n# CASTARI_PLATFORM_URL=https://api.castari.com\n`;
|
|
66
66
|
await writeFile('package.json', JSON.stringify(packageJson, null, 2));
|
|
67
67
|
await writeFile('tsconfig.json', JSON.stringify(tsConfig, null, 2));
|
|
68
68
|
await writeFile('.env.example', envExample);
|
package/dist/commands/start.js
CHANGED
|
@@ -5,11 +5,6 @@ import dotenv from 'dotenv';
|
|
|
5
5
|
export async function start(options) {
|
|
6
6
|
// Load .env from current directory
|
|
7
7
|
dotenv.config();
|
|
8
|
-
const apiKey = process.env.DAYTONA_API_KEY;
|
|
9
|
-
if (!apiKey) {
|
|
10
|
-
console.error(chalk.red('Error: DAYTONA_API_KEY is required.'));
|
|
11
|
-
process.exit(1);
|
|
12
|
-
}
|
|
13
8
|
// Read package.json for defaults
|
|
14
9
|
let snapshotName = options.snapshot;
|
|
15
10
|
let volumeName = options.volume;
|
|
@@ -31,11 +26,13 @@ export async function start(options) {
|
|
|
31
26
|
if (volumeName) {
|
|
32
27
|
console.log(chalk.blue(`📦 Using volume: ${volumeName}`));
|
|
33
28
|
}
|
|
29
|
+
const platformUrl = process.env.CASTARI_PLATFORM_URL;
|
|
34
30
|
const client = new CastariClient({
|
|
35
31
|
snapshot: snapshotName,
|
|
36
32
|
volume: volumeName,
|
|
37
|
-
|
|
33
|
+
platformUrl,
|
|
38
34
|
debug: true, // Enable debug logs for CLI
|
|
35
|
+
anthropicApiKey: process.env.ANTHROPIC_API_KEY
|
|
39
36
|
});
|
|
40
37
|
try {
|
|
41
38
|
await client.start();
|
package/dist/index.js
CHANGED
|
@@ -9,11 +9,11 @@ cli
|
|
|
9
9
|
.command('init', 'Initialize a new Castari agent project')
|
|
10
10
|
.action(init);
|
|
11
11
|
cli
|
|
12
|
-
.command('deploy', '
|
|
12
|
+
.command('deploy', 'Deploy the agent to the Castari Platform')
|
|
13
13
|
.option('--snapshot <name>', 'Snapshot name (overrides package.json)')
|
|
14
14
|
.action(deploy);
|
|
15
15
|
cli
|
|
16
|
-
.command('start', 'Start a
|
|
16
|
+
.command('start', 'Start a sandbox for the agent')
|
|
17
17
|
.option('--snapshot <name>', 'Snapshot name')
|
|
18
18
|
.option('--volume <name>', 'Volume name for persistence')
|
|
19
19
|
.option('--id <id>', 'Custom sandbox ID')
|
|
@@ -22,5 +22,5 @@ cli
|
|
|
22
22
|
.command('dev', 'Run the agent locally for development')
|
|
23
23
|
.action(dev);
|
|
24
24
|
cli.help();
|
|
25
|
-
cli.version('0.0.
|
|
25
|
+
cli.version('0.0.4');
|
|
26
26
|
cli.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@castari/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"castari": "./dist/index.js"
|
|
@@ -17,15 +17,18 @@
|
|
|
17
17
|
"dev": "bun run src/index.ts"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
+
"@anthropic-ai/claude-agent-sdk": "^0.1.44",
|
|
21
|
+
"@castari/sdk": "^0.0.4",
|
|
22
|
+
"adm-zip": "^0.5.16",
|
|
20
23
|
"cac": "^6.7.14",
|
|
21
|
-
"inquirer": "^9.2.12",
|
|
22
24
|
"chalk": "^5.3.0",
|
|
23
25
|
"dotenv": "^16.3.1",
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"@anthropic-ai/claude-agent-sdk": "^0.1.44"
|
|
26
|
+
"form-data": "^4.0.5",
|
|
27
|
+
"inquirer": "^9.2.12"
|
|
27
28
|
},
|
|
28
29
|
"devDependencies": {
|
|
30
|
+
"@types/adm-zip": "^0.5.7",
|
|
31
|
+
"@types/form-data": "^2.5.2",
|
|
29
32
|
"@types/inquirer": "^9.0.7",
|
|
30
33
|
"@types/node": "^20.10.0",
|
|
31
34
|
"typescript": "^5.6.3"
|