@castari/cli 0.0.7 → 0.0.9

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,68 @@ 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
+ </div>
602
+ <span className="pill pill-accent">Live</span>
603
+ </div>
604
+
605
+ <div className="pill-row">
606
+ <span className="pill">Snapshot: castari-demo-agent</span>
607
+ <span className="pill">Volume: castari-demo-workspace</span>
608
+ </div>
609
+
610
+ <div className="messages">
611
+ {messages.map((m, idx) => (
612
+ <div key={idx} className={\`bubble \${m.role}\`}>
613
+ {m.content}
614
+ </div>
615
+ ))}
616
+ </div>
617
+
618
+ <form className="form" onSubmit={sendMessage}>
619
+ <input
620
+ className="input"
621
+ placeholder="Ask the Castari agent anything..."
622
+ value={input}
623
+ onChange={e => setInput(e.target.value)}
624
+ />
625
+ <button className="button" type="submit" disabled={sending}>
626
+ {sending ? 'Talking…' : 'Send'}
627
+ </button>
628
+ </form>
629
+ {status && <div className="status">{status}</div>}
630
+ </section>
477
631
  </div>
478
632
  </main>
479
633
  )
@@ -495,10 +649,11 @@ async function createClient() {
495
649
 
496
650
  const client = new CastariClient({
497
651
  snapshot: SNAPSHOT,
498
- volume: VOLUME,
652
+ // volume: VOLUME, // opt-in; omit to run ephemeral unless provided
499
653
  labels: LABELS,
500
654
  platformUrl: process.env.CASTARI_PLATFORM_URL,
501
655
  clientId: process.env.CASTARI_CLIENT_ID,
656
+ platformApiKey: process.env.CASTARI_API_KEY,
502
657
  anthropicApiKey,
503
658
  debug: process.env.CASTARI_DEBUG === 'true',
504
659
  })
@@ -652,6 +807,35 @@ export async function POST(request: Request) {
652
807
  },
653
808
  })
654
809
  }
810
+ `);
811
+ // Logo SVG
812
+ 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">
813
+ <path d="M0 32L31.619 0L63.2381 32L31.619 64L0 32Z" fill="#A44A0C"/>
814
+ <path d="M31.527 31.8743H6.87042L24.3595 24.3417L31.527 7.24737V31.8743Z" fill="white"/>
815
+ <path d="M31.527 31.8743H6.87042L24.3595 24.3417L31.527 31.8743Z" fill="url(#paint0_linear_173_2089)"/>
816
+ <path d="M31.5268 31.872L31.5192 6.91829L24.0817 24.6204L31.5268 31.872Z" fill="url(#paint1_linear_173_2089)"/>
817
+ <path d="M31.7116 32.128L31.7192 57.0817L38.9973 39.3796L31.7116 32.128Z" fill="url(#paint2_linear_173_2089)"/>
818
+ <path d="M31.7117 32.1258H56.3683L38.8792 39.6584L31.7117 56.7527V32.1258Z" fill="white"/>
819
+ <path d="M31.7117 32.1258H56.3683L38.8792 39.6584L31.7117 32.1258Z" fill="url(#paint3_linear_173_2089)"/>
820
+ <defs>
821
+ <linearGradient id="paint0_linear_173_2089" x1="53.6475" y1="32.6825" x2="36.7362" y2="37.9872" gradientUnits="userSpaceOnUse">
822
+ <stop stop-color="#F8F8F8"/>
823
+ <stop offset="1" stop-color="#EACAB4"/>
824
+ </linearGradient>
825
+ <linearGradient id="paint1_linear_173_2089" x1="6.97479" y1="59.2675" x2="54.1923" y2="54.7965" gradientUnits="userSpaceOnUse">
826
+ <stop stop-color="white"/>
827
+ <stop offset="1" stop-color="#EDEDED"/>
828
+ </linearGradient>
829
+ <linearGradient id="paint2_linear_173_2089" x1="6.97479" y1="59.2675" x2="54.1923" y2="54.7965" gradientUnits="userSpaceOnUse">
830
+ <stop stop-color="white"/>
831
+ <stop offset="1" stop-color="#EDEDED"/>
832
+ </linearGradient>
833
+ <linearGradient id="paint3_linear_173_2089" x1="53.6475" y1="32.6825" x2="36.7362" y2="37.9872" gradientUnits="userSpaceOnUse">
834
+ <stop stop-color="#F8F8F8"/>
835
+ <stop offset="1" stop-color="#EACAB4"/>
836
+ </linearGradient>
837
+ </defs>
838
+ </svg>
655
839
  `);
656
840
  // Demo README
657
841
  await writeFile(join(demoRoot, 'README.md'), `# Castari Demo (Web + Agent)
@@ -666,12 +850,20 @@ Structure:
666
850
  - Bun (for the Castari CLI and scripts)
667
851
  - Node 18+ (for the Next.js app)
668
852
  - \`ANTHROPIC_API_KEY\`
853
+ - Castari credentials (\`CASTARI_CLIENT_ID\` and \`CASTARI_API_KEY\`)
669
854
  - Castari Platform running locally or reachable via \`CASTARI_PLATFORM_URL\`
670
855
 
856
+ ## Getting Castari Credentials
857
+ Generate your clientId and apiKey by running:
858
+ \`\`\`bash
859
+ castari generate-client-id
860
+ \`\`\`
861
+ Or via the Castari Platform Console if available.
862
+
671
863
  ## 1) Prepare and deploy the agent
672
864
  \`\`\`bash
673
865
  cd castari_demo/agent
674
- cp .env.example .env # add ANTHROPIC_API_KEY (and CASTARI_PLATFORM_URL if self-hosted)
866
+ cp .env.example .env # add ANTHROPIC_API_KEY, CASTARI_CLIENT_ID, CASTARI_API_KEY
675
867
  bun install # pulls @castari/sdk from npm
676
868
  castari deploy # builds snapshot castari-demo-agent (CLI must be installed)
677
869
  # Optional: bun run src/agent.ts # run locally without the CLI
@@ -680,7 +872,7 @@ castari deploy # builds snapshot castari-demo-agent (CLI must be installe
680
872
  ## 2) Run the web app
681
873
  \`\`\`bash
682
874
  cd ../web
683
- cp .env.example .env # add ANTHROPIC_API_KEY and CASTARI_PLATFORM_URL if needed
875
+ cp .env.example .env # add ANTHROPIC_API_KEY, CASTARI_CLIENT_ID, CASTARI_API_KEY
684
876
  npm install # or bun install
685
877
  npm run dev # opens http://localhost:3000
686
878
  \`\`\`
@@ -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.9",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "castari": "./dist/index.js"
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@anthropic-ai/claude-agent-sdk": "^0.1.44",
21
- "@castari/sdk": "^0.0.6",
21
+ "@castari/sdk": "^0.0.7",
22
22
  "adm-zip": "^0.5.16",
23
23
  "cac": "^6.7.14",
24
24
  "chalk": "^5.3.0",