@castari/cli 0.0.7 → 0.0.8

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.
@@ -26,7 +26,7 @@ export async function init(options = {}) {
26
26
  },
27
27
  dependencies: {
28
28
  '@castari/sdk': '^0.0.6',
29
- '@anthropic-ai/claude-agent-sdk': '^0.1.44',
29
+ '@anthropic-ai/claude-agent-sdk': '^0.1.50',
30
30
  },
31
31
  castari: {
32
32
  volume: 'default-data',
@@ -41,8 +41,7 @@ export async function init(options = {}) {
41
41
  skipLibCheck: true,
42
42
  },
43
43
  };
44
- const agentTs = `import { serve } from '@castari/sdk/server'
45
- import { tool } from '@castari/sdk'
44
+ const agentTs = `import { serve, tool } from '@castari/sdk'
46
45
 
47
46
  // Define your agent tools and logic here
48
47
  const myTool = tool({
@@ -65,7 +64,7 @@ serve({
65
64
  systemPrompt: 'You are a helpful Castari agent.',
66
65
  })
67
66
  `;
68
- const envExample = `ANTHROPIC_API_KEY=sk-ant-...\nCASTARI_CLIENT_ID=your-client-id\n# CASTARI_PLATFORM_URL=https://api.castari.com\n`;
67
+ const envExample = `ANTHROPIC_API_KEY=sk-ant-...\nCASTARI_CLIENT_ID=your-client-id\nCASTARI_API_KEY=castari_your-api-key\n# CASTARI_PLATFORM_URL=https://api.castari.com\n`;
69
68
  await writeFile('package.json', JSON.stringify(packageJson, null, 2));
70
69
  await writeFile('tsconfig.json', JSON.stringify(tsConfig, null, 2));
71
70
  await writeFile('.env.example', envExample);
@@ -111,7 +110,7 @@ async function initDemo() {
111
110
  },
112
111
  include: ['src'],
113
112
  });
114
- await writeFile(join(agentDir, '.env.example'), 'ANTHROPIC_API_KEY=sk-ant-...\nCASTARI_CLIENT_ID=your-client-id\n# CASTARI_PLATFORM_URL=http://localhost:3000\n');
113
+ await writeFile(join(agentDir, '.env.example'), 'ANTHROPIC_API_KEY=sk-ant-...\nCASTARI_CLIENT_ID=your-client-id\nCASTARI_API_KEY=castari_your-api-key\n# CASTARI_PLATFORM_URL=http://localhost:3000\n');
115
114
  await writeFile(join(agentDir, 'src', 'agent.ts'), `import { serve } from '@castari/sdk'
116
115
 
117
116
  serve({
@@ -126,6 +125,7 @@ serve({
126
125
  // Web scaffold
127
126
  await mkdir(join(webDir, 'app', 'api', 'chat'), { recursive: true });
128
127
  await mkdir(join(webDir, 'lib'), { recursive: true });
128
+ await mkdir(join(webDir, 'public'), { recursive: true });
129
129
  await writeJson(join(webDir, 'package.json'), {
130
130
  name: 'castari-demo-web',
131
131
  version: '0.1.0',
@@ -187,11 +187,16 @@ const nextConfig = {
187
187
 
188
188
  export default nextConfig
189
189
  `);
190
- await writeFile(join(webDir, '.env.example'), 'ANTHROPIC_API_KEY=sk-ant-...\nCASTARI_CLIENT_ID=your-client-id\n# CASTARI_PLATFORM_URL=http://localhost:3000\n# CASTARI_DEBUG=false\n');
190
+ await writeFile(join(webDir, '.env.example'), 'ANTHROPIC_API_KEY=sk-ant-...\nCASTARI_CLIENT_ID=your-client-id\nCASTARI_API_KEY=castari_your-api-key\n# CASTARI_PLATFORM_URL=http://localhost:3000\n# CASTARI_DEBUG=false\n');
191
191
  await writeFile(join(webDir, 'app', 'globals.css'), `:root {
192
- color-scheme: light;
193
- background: #f5f5f5;
194
- font-family: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
192
+ color-scheme: dark;
193
+ --bg: #131418;
194
+ --panel: #1c1d24;
195
+ --border: #2a2b36;
196
+ --muted: #888888;
197
+ --text: #ffffff;
198
+ --accent: #ffffff;
199
+ font-family: var(--font-inter), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
195
200
  }
196
201
 
197
202
  * {
@@ -200,9 +205,10 @@ export default nextConfig
200
205
 
201
206
  body {
202
207
  margin: 0;
203
- background: radial-gradient(circle at 20% 20%, #f7f0ff 0, #f5f5f5 35%), radial-gradient(circle at 80% 0%, #e0f4ff 0, #f5f5f5 30%);
204
- color: #0f172a;
208
+ background-color: var(--bg);
209
+ color: var(--text);
205
210
  min-height: 100vh;
211
+ font-weight: 300;
206
212
  }
207
213
 
208
214
  a {
@@ -210,139 +216,261 @@ a {
210
216
  text-decoration: none;
211
217
  }
212
218
 
213
- .chat-container {
214
- max-width: 760px;
215
- margin: 0 auto;
216
- padding: 32px 16px 64px;
219
+ .page-shell {
220
+ position: relative;
221
+ min-height: 100vh;
222
+ overflow: hidden;
223
+ display: flex;
224
+ justify-content: center;
225
+ padding: 36px 20px 72px;
226
+ }
227
+
228
+ .content {
229
+ position: relative;
230
+ width: min(1180px, 100%);
217
231
  display: flex;
218
232
  flex-direction: column;
219
- gap: 16px;
233
+ gap: 28px;
234
+ z-index: 1;
220
235
  }
221
236
 
222
- .card {
223
- background: rgba(255, 255, 255, 0.85);
224
- backdrop-filter: blur(6px);
225
- border: 1px solid rgba(15, 23, 42, 0.06);
226
- border-radius: 16px;
227
- box-shadow: 0 20px 60px rgba(15, 23, 42, 0.12);
228
- padding: 24px;
237
+ .topbar {
238
+ display: flex;
239
+ align-items: center;
240
+ justify-content: space-between;
241
+ gap: 12px;
242
+ flex-wrap: wrap;
243
+ padding-bottom: 12px;
244
+ border-bottom: 1px solid var(--border);
229
245
  }
230
246
 
231
- .heading {
247
+ .brand {
232
248
  display: flex;
233
249
  align-items: center;
250
+ gap: 14px;
251
+ }
252
+
253
+ .brand-logo {
254
+ width: 32px;
255
+ height: auto;
256
+ }
257
+
258
+ .brand-name {
259
+ font-family: var(--font-orbitron), 'Orbitron', sans-serif;
260
+ letter-spacing: 0.06em;
261
+ text-transform: uppercase;
262
+ font-size: 18px;
263
+ color: var(--text);
264
+ font-weight: 600;
265
+ }
266
+
267
+ .top-pills {
268
+ display: flex;
269
+ gap: 8px;
270
+ flex-wrap: wrap;
271
+ }
272
+
273
+ .hero {
274
+ display: flex;
275
+ flex-direction: column;
234
276
  gap: 12px;
235
- font-size: 22px;
236
- font-weight: 700;
277
+ padding: 40px 0 20px;
278
+ align-items: center;
279
+ text-align: center;
237
280
  }
238
281
 
239
- .badge {
240
- font-size: 12px;
282
+ .hero-title {
283
+ font-family: var(--font-orbitron), 'Orbitron', sans-serif;
284
+ font-size: clamp(30px, 4vw, 44px);
285
+ margin: 0;
286
+ letter-spacing: 0.02em;
241
287
  font-weight: 600;
242
- color: #0ea5e9;
243
- background: rgba(14, 165, 233, 0.1);
244
- padding: 6px 10px;
245
- border-radius: 999px;
246
- border: 1px solid rgba(14, 165, 233, 0.2);
288
+ }
289
+
290
+ .hero-copy {
291
+ color: var(--muted);
292
+ font-size: 18px;
293
+ line-height: 1.6;
294
+ max-width: 600px;
295
+ margin: 0;
296
+ }
297
+
298
+ .card {
299
+ position: relative;
300
+ background: var(--panel);
301
+ border: 1px solid var(--border);
302
+ border-radius: 20px;
303
+ padding: 22px;
304
+ }
305
+
306
+ .panel {
307
+ overflow: hidden;
308
+ }
309
+
310
+ .panel-header {
311
+ display: flex;
312
+ align-items: center;
313
+ justify-content: space-between;
314
+ gap: 14px;
315
+ flex-wrap: wrap;
316
+ margin-bottom: 20px;
317
+ }
318
+
319
+ .panel-title {
320
+ font-size: 18px;
321
+ font-weight: 500;
322
+ margin: 0;
323
+ }
324
+
325
+ .panel-copy {
326
+ color: var(--muted);
327
+ font-size: 14px;
328
+ margin: 4px 0 0;
329
+ }
330
+
331
+ .pill-row {
332
+ display: flex;
333
+ gap: 8px;
334
+ flex-wrap: wrap;
335
+ margin-bottom: 12px;
247
336
  }
248
337
 
249
338
  .messages {
250
339
  display: flex;
251
340
  flex-direction: column;
252
341
  gap: 12px;
342
+ background: #16171d;
343
+ border: 1px solid var(--border);
344
+ border-radius: 16px;
345
+ padding: 14px;
346
+ min-height: 300px;
253
347
  }
254
348
 
255
349
  .bubble {
256
350
  padding: 14px 16px;
257
351
  border-radius: 14px;
258
- max-width: 90%;
259
352
  line-height: 1.5;
260
353
  font-size: 15px;
354
+ max-width: 85%;
261
355
  }
262
356
 
263
357
  .bubble.assistant {
264
- background: #0f172a;
265
- color: white;
358
+ background: #1c1d24;
359
+ color: var(--text);
266
360
  align-self: flex-start;
267
- border-bottom-left-radius: 4px;
361
+ border: 1px solid var(--border);
268
362
  }
269
363
 
270
364
  .bubble.user {
271
- background: white;
272
- color: #0f172a;
273
- border: 1px solid rgba(15, 23, 42, 0.06);
365
+ background: #ffffff;
366
+ color: #000000;
274
367
  align-self: flex-end;
275
- border-bottom-right-radius: 4px;
276
368
  }
277
369
 
278
370
  .form {
279
371
  display: flex;
280
372
  gap: 12px;
281
- margin-top: 8px;
373
+ align-items: center;
374
+ margin-top: 16px;
375
+ background: #16171d;
376
+ border: 1px solid var(--border);
377
+ border-radius: 14px;
378
+ padding: 10px;
282
379
  }
283
380
 
284
381
  .input {
285
382
  flex: 1;
286
- padding: 14px 16px;
383
+ padding: 12px 14px;
287
384
  border-radius: 12px;
288
- border: 1px solid rgba(15, 23, 42, 0.08);
385
+ border: 1px solid transparent;
289
386
  font-size: 15px;
290
387
  outline: none;
291
- transition: border-color 0.15s ease;
388
+ background: transparent;
389
+ color: var(--text);
292
390
  }
293
391
 
294
- .input:focus {
295
- border-color: #0ea5e9;
296
- box-shadow: 0 0 0 3px rgba(14, 165, 233, 0.12);
392
+ .input::placeholder {
393
+ color: #666666;
297
394
  }
298
395
 
299
396
  .button {
300
- background: linear-gradient(135deg, #0ea5e9, #6366f1);
301
- color: white;
397
+ background: #ffffff;
398
+ color: #000000;
302
399
  border: none;
303
400
  border-radius: 12px;
304
- padding: 12px 18px;
305
- font-weight: 700;
401
+ padding: 12px 24px;
402
+ font-weight: 600;
306
403
  cursor: pointer;
307
- box-shadow: 0 12px 25px rgba(99, 102, 241, 0.35);
308
- min-width: 110px;
309
- transition: transform 0.12s ease, box-shadow 0.12s ease, opacity 0.12s ease;
404
+ transition: opacity 0.2s;
310
405
  }
311
406
 
312
407
  .button:disabled {
313
- opacity: 0.6;
408
+ opacity: 0.5;
314
409
  cursor: not-allowed;
315
- box-shadow: none;
316
410
  }
317
411
 
318
- .button:not(:disabled):hover {
319
- transform: translateY(-1px);
320
- box-shadow: 0 16px 30px rgba(99, 102, 241, 0.45);
412
+ .button:hover:not(:disabled) {
413
+ opacity: 0.9;
321
414
  }
322
415
 
323
416
  .status {
324
417
  font-size: 13px;
325
- color: #475569;
326
- margin-top: 6px;
327
- }
328
-
329
- .pill-row {
330
- display: flex;
331
- gap: 8px;
332
- flex-wrap: wrap;
418
+ color: var(--muted);
419
+ margin-top: 10px;
420
+ text-align: center;
333
421
  }
334
422
 
335
423
  .pill {
336
- padding: 6px 10px;
424
+ display: inline-flex;
425
+ align-items: center;
426
+ gap: 8px;
427
+ padding: 6px 12px;
337
428
  border-radius: 999px;
338
- background: rgba(15, 23, 42, 0.06);
429
+ border: 1px solid var(--border);
430
+ background: transparent;
431
+ color: var(--muted);
339
432
  font-size: 12px;
340
- color: #0f172a;
341
- border: 1px solid rgba(15, 23, 42, 0.08);
433
+ }
434
+
435
+ .pill-accent {
436
+ color: var(--text);
437
+ border-color: var(--text);
438
+ }
439
+
440
+ .pill-ghost {
441
+ border-color: var(--border);
442
+ color: var(--muted);
443
+ }
444
+
445
+ @media (max-width: 720px) {
446
+ .page-shell {
447
+ padding: 28px 16px 56px;
448
+ }
449
+
450
+ .form {
451
+ flex-direction: column;
452
+ }
453
+
454
+ .button {
455
+ width: 100%;
456
+ }
342
457
  }
343
458
  `);
344
459
  await writeFile(join(webDir, 'app', 'layout.tsx'), `import './globals.css'
345
460
  import { ReactNode } from 'react'
461
+ import { Inter, Orbitron } from 'next/font/google'
462
+
463
+ const inter = Inter({
464
+ subsets: ['latin'],
465
+ weight: ['300', '500', '700'],
466
+ variable: '--font-inter',
467
+ })
468
+
469
+ const orbitron = Orbitron({
470
+ subsets: ['latin'],
471
+ weight: ['600'],
472
+ variable: '--font-orbitron',
473
+ })
346
474
 
347
475
  export default function RootLayout({ children }: { children: ReactNode }) {
348
476
  return (
@@ -350,7 +478,7 @@ export default function RootLayout({ children }: { children: ReactNode }) {
350
478
  <head>
351
479
  <title>Castari Demo Chat</title>
352
480
  </head>
353
- <body>{children}</body>
481
+ <body className={\`\${inter.variable} \${orbitron.variable}\`}>{children}</body>
354
482
  </html>
355
483
  )
356
484
  }
@@ -358,6 +486,7 @@ export default function RootLayout({ children }: { children: ReactNode }) {
358
486
  await writeFile(join(webDir, 'app', 'page.tsx'), `"use client"
359
487
 
360
488
  import { FormEvent, useState } from 'react'
489
+ import Image from 'next/image'
361
490
 
362
491
  type ChatMessage = {
363
492
  role: 'assistant' | 'user'
@@ -437,43 +566,71 @@ export default function Home() {
437
566
  }
438
567
 
439
568
  return (
440
- <main className="chat-container">
441
- <div className="card">
442
- <div className="heading">
443
- <span>Castari Demo Chat</span>
444
- <span className="badge">Single sandbox</span>
445
- </div>
446
- <p style={{ margin: '8px 0 16px', color: '#475569' }}>
447
- This UI connects to a Castari agent running in a Daytona sandbox. Messages reuse the same
448
- sandbox (via labels) so the conversation stays warm while the sandbox is alive.
449
- </p>
450
-
451
- <div className="pill-row" style={{ marginBottom: 12 }}>
452
- <span className="pill">Snapshot: castari-demo-agent</span>
453
- <span className="pill">Volume: castari-demo-workspace</span>
454
- <span className="pill">Labels: app=castari-demo, env=local</span>
455
- </div>
456
-
457
- <div className="messages">
458
- {messages.map((m, idx) => (
459
- <div key={idx} className={\`bubble \${m.role}\`}>
460
- {m.content}
569
+ <main className="page-shell">
570
+ <div className="content">
571
+ <header className="topbar">
572
+ <div className="brand">
573
+ <Image
574
+ src="/logo.svg"
575
+ alt="Castari Logo"
576
+ width={32}
577
+ height={32}
578
+ className="brand-logo"
579
+ />
580
+ <div>
581
+ <div className="brand-name">Castari</div>
461
582
  </div>
462
- ))}
463
- </div>
464
-
465
- <form className="form" onSubmit={sendMessage}>
466
- <input
467
- className="input"
468
- placeholder="Ask the Castari agent anything..."
469
- value={input}
470
- onChange={e => setInput(e.target.value)}
471
- />
472
- <button className="button" type="submit" disabled={sending}>
473
- {sending ? 'Talking…' : 'Send'}
474
- </button>
475
- </form>
476
- {status && <div className="status">{status}</div>}
583
+ </div>
584
+
585
+ <div className="top-pills">
586
+ <span className="pill pill-ghost">Demo sandbox</span>
587
+ </div>
588
+ </header>
589
+
590
+ <section className="hero">
591
+ <h1 className="hero-title">Production-Ready Agents</h1>
592
+ <p className="hero-copy">
593
+ Secure, sandboxed AI agents for your infrastructure.
594
+ </p>
595
+ </section>
596
+
597
+ <section className="card panel">
598
+ <div className="panel-header">
599
+ <div>
600
+ <div className="panel-title">Chat with Castari</div>
601
+ <p className="panel-copy">
602
+ This agent runs in a live Daytona sandbox.
603
+ </p>
604
+ </div>
605
+ <span className="pill pill-accent">Live</span>
606
+ </div>
607
+
608
+ <div className="pill-row">
609
+ <span className="pill">Snapshot: castari-demo-agent</span>
610
+ <span className="pill">Volume: castari-demo-workspace</span>
611
+ </div>
612
+
613
+ <div className="messages">
614
+ {messages.map((m, idx) => (
615
+ <div key={idx} className={\`bubble \${m.role}\`}>
616
+ {m.content}
617
+ </div>
618
+ ))}
619
+ </div>
620
+
621
+ <form className="form" onSubmit={sendMessage}>
622
+ <input
623
+ className="input"
624
+ placeholder="Ask the Castari agent anything..."
625
+ value={input}
626
+ onChange={e => setInput(e.target.value)}
627
+ />
628
+ <button className="button" type="submit" disabled={sending}>
629
+ {sending ? 'Talking…' : 'Send'}
630
+ </button>
631
+ </form>
632
+ {status && <div className="status">{status}</div>}
633
+ </section>
477
634
  </div>
478
635
  </main>
479
636
  )
@@ -495,10 +652,11 @@ async function createClient() {
495
652
 
496
653
  const client = new CastariClient({
497
654
  snapshot: SNAPSHOT,
498
- volume: VOLUME,
655
+ // volume: VOLUME, // opt-in; omit to run ephemeral unless provided
499
656
  labels: LABELS,
500
657
  platformUrl: process.env.CASTARI_PLATFORM_URL,
501
658
  clientId: process.env.CASTARI_CLIENT_ID,
659
+ platformApiKey: process.env.CASTARI_API_KEY,
502
660
  anthropicApiKey,
503
661
  debug: process.env.CASTARI_DEBUG === 'true',
504
662
  })
@@ -652,6 +810,35 @@ export async function POST(request: Request) {
652
810
  },
653
811
  })
654
812
  }
813
+ `);
814
+ // Logo SVG
815
+ await writeFile(join(webDir, 'public', 'logo.svg'), `<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
816
+ <path d="M0 32L31.619 0L63.2381 32L31.619 64L0 32Z" fill="#A44A0C"/>
817
+ <path d="M31.527 31.8743H6.87042L24.3595 24.3417L31.527 7.24737V31.8743Z" fill="white"/>
818
+ <path d="M31.527 31.8743H6.87042L24.3595 24.3417L31.527 31.8743Z" fill="url(#paint0_linear_173_2089)"/>
819
+ <path d="M31.5268 31.872L31.5192 6.91829L24.0817 24.6204L31.5268 31.872Z" fill="url(#paint1_linear_173_2089)"/>
820
+ <path d="M31.7116 32.128L31.7192 57.0817L38.9973 39.3796L31.7116 32.128Z" fill="url(#paint2_linear_173_2089)"/>
821
+ <path d="M31.7117 32.1258H56.3683L38.8792 39.6584L31.7117 56.7527V32.1258Z" fill="white"/>
822
+ <path d="M31.7117 32.1258H56.3683L38.8792 39.6584L31.7117 32.1258Z" fill="url(#paint3_linear_173_2089)"/>
823
+ <defs>
824
+ <linearGradient id="paint0_linear_173_2089" x1="53.6475" y1="32.6825" x2="36.7362" y2="37.9872" gradientUnits="userSpaceOnUse">
825
+ <stop stop-color="#F8F8F8"/>
826
+ <stop offset="1" stop-color="#EACAB4"/>
827
+ </linearGradient>
828
+ <linearGradient id="paint1_linear_173_2089" x1="6.97479" y1="59.2675" x2="54.1923" y2="54.7965" gradientUnits="userSpaceOnUse">
829
+ <stop stop-color="white"/>
830
+ <stop offset="1" stop-color="#EDEDED"/>
831
+ </linearGradient>
832
+ <linearGradient id="paint2_linear_173_2089" x1="6.97479" y1="59.2675" x2="54.1923" y2="54.7965" gradientUnits="userSpaceOnUse">
833
+ <stop stop-color="white"/>
834
+ <stop offset="1" stop-color="#EDEDED"/>
835
+ </linearGradient>
836
+ <linearGradient id="paint3_linear_173_2089" x1="53.6475" y1="32.6825" x2="36.7362" y2="37.9872" gradientUnits="userSpaceOnUse">
837
+ <stop stop-color="#F8F8F8"/>
838
+ <stop offset="1" stop-color="#EACAB4"/>
839
+ </linearGradient>
840
+ </defs>
841
+ </svg>
655
842
  `);
656
843
  // Demo README
657
844
  await writeFile(join(demoRoot, 'README.md'), `# Castari Demo (Web + Agent)
@@ -666,12 +853,20 @@ Structure:
666
853
  - Bun (for the Castari CLI and scripts)
667
854
  - Node 18+ (for the Next.js app)
668
855
  - \`ANTHROPIC_API_KEY\`
856
+ - Castari credentials (\`CASTARI_CLIENT_ID\` and \`CASTARI_API_KEY\`)
669
857
  - Castari Platform running locally or reachable via \`CASTARI_PLATFORM_URL\`
670
858
 
859
+ ## Getting Castari Credentials
860
+ Generate your clientId and apiKey by running:
861
+ \`\`\`bash
862
+ castari generate-client-id
863
+ \`\`\`
864
+ Or via the Castari Platform Console if available.
865
+
671
866
  ## 1) Prepare and deploy the agent
672
867
  \`\`\`bash
673
868
  cd castari_demo/agent
674
- cp .env.example .env # add ANTHROPIC_API_KEY (and CASTARI_PLATFORM_URL if self-hosted)
869
+ cp .env.example .env # add ANTHROPIC_API_KEY, CASTARI_CLIENT_ID, CASTARI_API_KEY
675
870
  bun install # pulls @castari/sdk from npm
676
871
  castari deploy # builds snapshot castari-demo-agent (CLI must be installed)
677
872
  # Optional: bun run src/agent.ts # run locally without the CLI
@@ -680,7 +875,7 @@ castari deploy # builds snapshot castari-demo-agent (CLI must be installe
680
875
  ## 2) Run the web app
681
876
  \`\`\`bash
682
877
  cd ../web
683
- cp .env.example .env # add ANTHROPIC_API_KEY and CASTARI_PLATFORM_URL if needed
878
+ cp .env.example .env # add ANTHROPIC_API_KEY, CASTARI_CLIENT_ID, CASTARI_API_KEY
684
879
  npm install # or bun install
685
880
  npm run dev # opens http://localhost:3000
686
881
  \`\`\`
@@ -28,10 +28,13 @@ export async function start(options) {
28
28
  if (volumeName) {
29
29
  console.log(chalk.blue(`📦 Using volume: ${volumeName}`));
30
30
  }
31
+ else {
32
+ console.log(chalk.blue(`📦 No volume specified (sandbox will be ephemeral)`));
33
+ }
31
34
  const platformUrl = process.env.CASTARI_PLATFORM_URL;
32
35
  const clientOptions = {
33
36
  snapshot: snapshotName,
34
- volume: volumeName,
37
+ ...(volumeName ? { volume: volumeName } : {}),
35
38
  platformUrl,
36
39
  debug: true, // Enable debug logs for CLI
37
40
  anthropicApiKey: process.env.ANTHROPIC_API_KEY,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@castari/cli",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "castari": "./dist/index.js"