cassian-cli 0.3.4 → 0.3.6
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/dist/commands/init.d.ts +0 -4
- package/dist/commands/init.js +19 -63
- package/dist/commands/up.js +16 -8
- package/dist/index.js +2 -10
- package/dist/types.d.ts +2 -0
- package/package.json +1 -1
package/dist/commands/init.d.ts
CHANGED
|
@@ -2,11 +2,7 @@ export interface InitOptions {
|
|
|
2
2
|
name?: string;
|
|
3
3
|
gpu?: string;
|
|
4
4
|
gpuCount?: string;
|
|
5
|
-
memory?: string;
|
|
6
|
-
shm?: string;
|
|
7
5
|
disk?: string;
|
|
8
|
-
setup?: string;
|
|
9
|
-
syncignore?: string;
|
|
10
6
|
yes?: boolean;
|
|
11
7
|
}
|
|
12
8
|
export declare function init(options?: InitOptions): Promise<void>;
|
package/dist/commands/init.js
CHANGED
|
@@ -64,33 +64,17 @@ function promptChoice(rl, question, choices, fallback) {
|
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
66
|
function buildYaml(opts) {
|
|
67
|
-
const
|
|
68
|
-
const setupLine = opts.setup ? ` setup: ${opts.setup}\n` : "";
|
|
69
|
-
const noSyncLines = opts.noSync.length
|
|
70
|
-
? ` no_sync:\n${opts.noSync.map(p => ` - "${p}"`).join("\n")}\n` : "";
|
|
71
|
-
const storageLines = opts.storage.length
|
|
72
|
-
? ` storage:\n${opts.storage.map(p => ` - "${p}"`).join("\n")}\n` : "";
|
|
67
|
+
const storageLine = opts.storage ? "\nstorage: true\n" : "";
|
|
73
68
|
const excludeLines = opts.exclude.length
|
|
74
|
-
?
|
|
69
|
+
? `\nworkspace:\n exclude:\n${opts.exclude.map(p => ` - "${p}"`).join("\n")}\n` : "";
|
|
75
70
|
return `name: ${opts.name}
|
|
76
71
|
|
|
77
72
|
gpu:
|
|
78
73
|
count: ${opts.gpuCount}
|
|
79
74
|
type: ${opts.gpuType}
|
|
80
75
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
volumes:
|
|
84
|
-
- name: ${volName}
|
|
85
|
-
size: ${opts.diskSize}
|
|
86
|
-
mount: /workspace
|
|
87
|
-
|
|
88
|
-
resources:
|
|
89
|
-
memory: ${opts.memory}
|
|
90
|
-
shm_size: ${opts.shmSize}
|
|
91
|
-
|
|
92
|
-
workspace:
|
|
93
|
-
${setupLine}${noSyncLines}${storageLines}${excludeLines}`;
|
|
76
|
+
disk: ${opts.diskSize}
|
|
77
|
+
${storageLine}${excludeLines}`;
|
|
94
78
|
}
|
|
95
79
|
export async function init(options = {}) {
|
|
96
80
|
if (existsSync("cassian.yaml")) {
|
|
@@ -98,19 +82,13 @@ export async function init(options = {}) {
|
|
|
98
82
|
}
|
|
99
83
|
const dirName = process.cwd().split("/").pop().toLowerCase().replace(/[^a-z0-9-]/g, "-");
|
|
100
84
|
const skipPrompts = options.yes ?? false;
|
|
101
|
-
|
|
102
|
-
const allFlagsProvided = !!(options.name && options.gpu && options.gpuCount && options.memory && options.disk);
|
|
103
|
-
if (allFlagsProvided || skipPrompts) {
|
|
85
|
+
if (skipPrompts) {
|
|
104
86
|
const yaml = buildYaml({
|
|
105
87
|
name: options.name || dirName,
|
|
106
88
|
gpuType: options.gpu || "rtx3090",
|
|
107
89
|
gpuCount: parseInt(options.gpuCount || "1"),
|
|
108
|
-
memory: options.memory || "32G",
|
|
109
|
-
shmSize: options.shm || "16G",
|
|
110
90
|
diskSize: options.disk || "50G",
|
|
111
|
-
|
|
112
|
-
noSync: ["checkpoints/", "outputs/"],
|
|
113
|
-
storage: [],
|
|
91
|
+
storage: true,
|
|
114
92
|
exclude: ["node_modules/", ".venv/", "__pycache__/", "*.pyc", "wandb/"],
|
|
115
93
|
});
|
|
116
94
|
writeFileSync("cassian.yaml", yaml);
|
|
@@ -125,7 +103,7 @@ export async function init(options = {}) {
|
|
|
125
103
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
126
104
|
console.log();
|
|
127
105
|
console.log(bold(" Let's set up your Cassian project."));
|
|
128
|
-
console.log(dim(" Press enter to accept defaults
|
|
106
|
+
console.log(dim(" Press enter to accept defaults.\n"));
|
|
129
107
|
const name = options.name || await prompt(rl, ` Instance name ${dim(`[${dirName}]`)}: `, dirName);
|
|
130
108
|
console.log();
|
|
131
109
|
const availability = await fetchAvailability();
|
|
@@ -140,48 +118,26 @@ export async function init(options = {}) {
|
|
|
140
118
|
], "1");
|
|
141
119
|
const gpuCount = parseInt(gpuCountStr);
|
|
142
120
|
console.log();
|
|
143
|
-
const
|
|
144
|
-
{ label: "
|
|
145
|
-
{ label: "
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
{ label: "4 GB", value: "4G" }, { label: "8 GB", value: "8G" },
|
|
150
|
-
{ label: "16 GB", value: "16G", hint: "recommended" }, { label: "32 GB", value: "32G" },
|
|
151
|
-
], "16G");
|
|
152
|
-
console.log();
|
|
153
|
-
const diskSize = options.disk || await promptChoice(rl, " Workspace disk size:", [
|
|
154
|
-
{ label: "20 GB", value: "20G" }, { label: "50 GB", value: "50G", hint: "recommended" },
|
|
155
|
-
{ label: "100 GB", value: "100G" }, { label: "200 GB", value: "200G" },
|
|
156
|
-
{ label: "500 GB", value: "500G", hint: "for large datasets / checkpoints" }, { label: "1 TB", value: "1T" },
|
|
121
|
+
const diskSize = options.disk || await promptChoice(rl, " Disk size (fast storage for code + training):", [
|
|
122
|
+
{ label: "20 GB", value: "20G" },
|
|
123
|
+
{ label: "50 GB", value: "50G", hint: "recommended" },
|
|
124
|
+
{ label: "100 GB", value: "100G" },
|
|
125
|
+
{ label: "200 GB", value: "200G" },
|
|
126
|
+
{ label: "500 GB", value: "500G" },
|
|
157
127
|
], "50G");
|
|
158
128
|
console.log();
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const
|
|
162
|
-
const
|
|
163
|
-
console.log();
|
|
164
|
-
console.log(dim(" Folders that stay on the GPU instance but don't sync to your machine"));
|
|
165
|
-
console.log(dim(" (large files like checkpoints, training outputs — still persists across sessions)"));
|
|
166
|
-
const noSyncRaw = options.syncignore ?? await prompt(rl, ` No-sync folders ${dim("[checkpoints/, outputs/]")}: `, "");
|
|
167
|
-
const noSync = noSyncRaw
|
|
168
|
-
? noSyncRaw.split(",").map(s => s.trim()).filter(Boolean)
|
|
169
|
-
: ["checkpoints/", "outputs/"];
|
|
170
|
-
console.log();
|
|
171
|
-
console.log(dim(" Folders streamed from cloud storage (huge datasets, pretrained models)"));
|
|
172
|
-
console.log(dim(" (doesn't use instance disk — reads directly from cloud)"));
|
|
173
|
-
const storageRaw = await prompt(rl, ` Cloud storage folders ${dim("[none]")}: `, "");
|
|
174
|
-
const storage = storageRaw
|
|
175
|
-
? storageRaw.split(",").map(s => s.trim()).filter(Boolean)
|
|
176
|
-
: [];
|
|
129
|
+
console.log(dim(" Cloud storage gives you unlimited persistent space at /workspace/storage"));
|
|
130
|
+
console.log(dim(" Great for datasets, model weights, and large files"));
|
|
131
|
+
const storageAnswer = await prompt(rl, ` Enable cloud storage? ${dim("[Y/n]")}: `, "Y");
|
|
132
|
+
const storage = storageAnswer.toLowerCase() !== "n";
|
|
177
133
|
console.log();
|
|
178
|
-
console.log(dim(" Folders to exclude
|
|
134
|
+
console.log(dim(" Folders to exclude (build artifacts, can be recreated)"));
|
|
179
135
|
const excludeRaw = await prompt(rl, ` Exclude ${dim("[node_modules/, .venv/, __pycache__/, *.pyc, wandb/]")}: `, "");
|
|
180
136
|
const exclude = excludeRaw
|
|
181
137
|
? excludeRaw.split(",").map(s => s.trim()).filter(Boolean)
|
|
182
138
|
: ["node_modules/", ".venv/", "__pycache__/", "*.pyc", "wandb/"];
|
|
183
139
|
rl.close();
|
|
184
|
-
const yaml = buildYaml({ name, gpuType, gpuCount,
|
|
140
|
+
const yaml = buildYaml({ name, gpuType, gpuCount, diskSize, storage, exclude });
|
|
185
141
|
writeFileSync("cassian.yaml", yaml);
|
|
186
142
|
console.log();
|
|
187
143
|
console.log(` ${green("✓")} Created cassian.yaml`);
|
package/dist/commands/up.js
CHANGED
|
@@ -54,8 +54,14 @@ export async function up() {
|
|
|
54
54
|
console.log();
|
|
55
55
|
info("Instance", config.name);
|
|
56
56
|
info("GPUs", `${config.gpu.count}x ${config.gpu.type || "any"}`);
|
|
57
|
-
if (config.
|
|
58
|
-
info("
|
|
57
|
+
if (config.disk) {
|
|
58
|
+
info("Disk", config.disk);
|
|
59
|
+
}
|
|
60
|
+
else if (config.volumes?.length) {
|
|
61
|
+
info("Disk", config.volumes.map((v) => `${v.size} at ${v.mount}`).join(", "));
|
|
62
|
+
}
|
|
63
|
+
if (config.storage) {
|
|
64
|
+
info("Storage", "enabled (/workspace/storage)");
|
|
59
65
|
}
|
|
60
66
|
console.log();
|
|
61
67
|
const vm = dev.vm;
|
|
@@ -99,17 +105,19 @@ export async function up() {
|
|
|
99
105
|
await new Promise((r) => setTimeout(r, 1000));
|
|
100
106
|
spinner.text = "Starting instance...";
|
|
101
107
|
}
|
|
108
|
+
// Build volumes: use new `disk` field or legacy `volumes` array
|
|
109
|
+
const volumes = config.volumes
|
|
110
|
+
? config.volumes.map((v) => ({ name: v.name, size_gb: parseSizeToGb(v.size), mount: v.mount }))
|
|
111
|
+
: config.disk
|
|
112
|
+
? [{ name: config.name, size_gb: parseSizeToGb(config.disk), mount: "/workspace" }]
|
|
113
|
+
: [];
|
|
102
114
|
const instance = await client.post("/v1/instances", {
|
|
103
115
|
name: config.name,
|
|
104
116
|
gpu_count: config.gpu.count,
|
|
105
117
|
gpu_type: config.gpu.type || null,
|
|
106
118
|
image: config.image || "default",
|
|
107
119
|
ssh_public_key: sshPubKey,
|
|
108
|
-
volumes
|
|
109
|
-
name: v.name,
|
|
110
|
-
size_gb: parseSizeToGb(v.size),
|
|
111
|
-
mount: v.mount,
|
|
112
|
-
})),
|
|
120
|
+
volumes,
|
|
113
121
|
resources: {
|
|
114
122
|
memory: config.resources?.memory || null,
|
|
115
123
|
shm_size: config.resources?.shm_size || null,
|
|
@@ -117,7 +125,7 @@ export async function up() {
|
|
|
117
125
|
},
|
|
118
126
|
workspace: {
|
|
119
127
|
no_sync: config.workspace?.no_sync || [],
|
|
120
|
-
storage: config.workspace?.storage || [],
|
|
128
|
+
storage: config.storage === true ? ["storage"] : (Array.isArray(config.storage) ? config.storage : config.workspace?.storage || []),
|
|
121
129
|
exclude: config.workspace?.exclude || config.workspace?.syncignore || [],
|
|
122
130
|
},
|
|
123
131
|
});
|
package/dist/index.js
CHANGED
|
@@ -87,21 +87,13 @@ program
|
|
|
87
87
|
.option("--name <name>", "Instance name")
|
|
88
88
|
.option("--gpu <type>", "GPU type (e.g. h100-sxm, a100-sxm, rtx3090)")
|
|
89
89
|
.option("--gpu-count <n>", "Number of GPUs")
|
|
90
|
-
.option("--
|
|
91
|
-
.option("--
|
|
92
|
-
.option("--disk <size>", "Workspace disk size (e.g. 50G, 1T)")
|
|
93
|
-
.option("--setup <cmd>", "Setup command to run after sync")
|
|
94
|
-
.option("--syncignore <list>", "Comma-separated patterns to exclude from sync")
|
|
95
|
-
.option("-y, --yes", "Skip all prompts, use defaults or provided flags")
|
|
90
|
+
.option("--disk <size>", "Disk size (e.g. 50G, 200G)")
|
|
91
|
+
.option("-y, --yes", "Skip all prompts, use defaults")
|
|
96
92
|
.action((opts) => init({
|
|
97
93
|
name: opts.name,
|
|
98
94
|
gpu: opts.gpu,
|
|
99
95
|
gpuCount: opts.gpuCount,
|
|
100
|
-
memory: opts.memory,
|
|
101
|
-
shm: opts.shm,
|
|
102
96
|
disk: opts.disk,
|
|
103
|
-
setup: opts.setup,
|
|
104
|
-
syncignore: opts.syncignore,
|
|
105
97
|
yes: opts.yes,
|
|
106
98
|
}));
|
|
107
99
|
program.parse();
|
package/dist/types.d.ts
CHANGED