@castlekit/castle 0.4.0 → 0.4.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.
Files changed (95) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +2 -2
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/server/app/_global-error.html +2 -2
  5. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  6. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  12. package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  15. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  16. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  17. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  19. package/.next/standalone/.next/server/app/api/avatars/[id]/route.js.nft.json +1 -1
  20. package/.next/standalone/.next/server/app/api/openclaw/agents/[id]/avatar/route.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/api/openclaw/agents/route.js.nft.json +1 -1
  22. package/.next/standalone/.next/server/app/api/openclaw/agents/status/route.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/api/openclaw/chat/attachments/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/openclaw/chat/channels/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/openclaw/chat/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/openclaw/chat/search/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/openclaw/chat/storage/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/openclaw/config/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/openclaw/events/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/openclaw/logs/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/openclaw/ping/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/openclaw/session/context/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/openclaw/session/status/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/openclaw/sessions/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/api/settings/avatar/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/chat.html +1 -1
  38. package/.next/standalone/.next/server/app/chat.rsc +1 -1
  39. package/.next/standalone/.next/server/app/chat.segments/_full.segment.rsc +1 -1
  40. package/.next/standalone/.next/server/app/chat.segments/_head.segment.rsc +1 -1
  41. package/.next/standalone/.next/server/app/chat.segments/_index.segment.rsc +1 -1
  42. package/.next/standalone/.next/server/app/chat.segments/_tree.segment.rsc +1 -1
  43. package/.next/standalone/.next/server/app/chat.segments/chat/__PAGE__.segment.rsc +1 -1
  44. package/.next/standalone/.next/server/app/chat.segments/chat.segment.rsc +1 -1
  45. package/.next/standalone/.next/server/app/index.html +1 -1
  46. package/.next/standalone/.next/server/app/index.rsc +2 -2
  47. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  48. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  49. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  50. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  51. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  52. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  53. package/.next/standalone/.next/server/app/settings.html +1 -1
  54. package/.next/standalone/.next/server/app/settings.rsc +1 -1
  55. package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +1 -1
  56. package/.next/standalone/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  57. package/.next/standalone/.next/server/app/settings.segments/_index.segment.rsc +1 -1
  58. package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  59. package/.next/standalone/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +1 -1
  60. package/.next/standalone/.next/server/app/settings.segments/settings.segment.rsc +1 -1
  61. package/.next/standalone/.next/server/app/ui-kit.html +1 -1
  62. package/.next/standalone/.next/server/app/ui-kit.rsc +1 -1
  63. package/.next/standalone/.next/server/app/ui-kit.segments/_full.segment.rsc +1 -1
  64. package/.next/standalone/.next/server/app/ui-kit.segments/_head.segment.rsc +1 -1
  65. package/.next/standalone/.next/server/app/ui-kit.segments/_index.segment.rsc +1 -1
  66. package/.next/standalone/.next/server/app/ui-kit.segments/_tree.segment.rsc +1 -1
  67. package/.next/standalone/.next/server/app/ui-kit.segments/ui-kit/__PAGE__.segment.rsc +1 -1
  68. package/.next/standalone/.next/server/app/ui-kit.segments/ui-kit.segment.rsc +1 -1
  69. package/.next/standalone/.next/server/chunks/ssr/_7a67de23._.js +1 -1
  70. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  71. package/.next/standalone/.next/server/pages/404.html +1 -1
  72. package/.next/standalone/.next/server/pages/500.html +2 -2
  73. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  74. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  75. package/.next/{static/chunks/2b48886a383c2e37.js → standalone/.next/static/chunks/8c691cfaccdbb9ee.js} +1 -1
  76. package/.next/standalone/CHANGELOG.md +28 -0
  77. package/.next/standalone/bin/castle.js +2 -2
  78. package/.next/standalone/install.ps1 +437 -0
  79. package/.next/standalone/install.sh +4 -0
  80. package/.next/standalone/package.json +2 -1
  81. package/.next/standalone/src/app/page.tsx +3 -3
  82. package/.next/standalone/src/cli/onboarding.ts +178 -102
  83. package/.next/{standalone/.next/static/chunks/2b48886a383c2e37.js → static/chunks/8c691cfaccdbb9ee.js} +1 -1
  84. package/bin/castle.js +2 -2
  85. package/install.ps1 +437 -0
  86. package/install.sh +4 -0
  87. package/package.json +2 -1
  88. package/src/app/page.tsx +3 -3
  89. package/src/cli/onboarding.ts +178 -102
  90. /package/.next/standalone/.next/static/{R01Vc6rRTS_XwAg0Y8ERm → -R3HvmmPKzJ9Jfjg7hRqd}/_buildManifest.js +0 -0
  91. /package/.next/standalone/.next/static/{R01Vc6rRTS_XwAg0Y8ERm → -R3HvmmPKzJ9Jfjg7hRqd}/_clientMiddlewareManifest.json +0 -0
  92. /package/.next/standalone/.next/static/{R01Vc6rRTS_XwAg0Y8ERm → -R3HvmmPKzJ9Jfjg7hRqd}/_ssgManifest.js +0 -0
  93. /package/.next/static/{R01Vc6rRTS_XwAg0Y8ERm → -R3HvmmPKzJ9Jfjg7hRqd}/_buildManifest.js +0 -0
  94. /package/.next/static/{R01Vc6rRTS_XwAg0Y8ERm → -R3HvmmPKzJ9Jfjg7hRqd}/_clientMiddlewareManifest.json +0 -0
  95. /package/.next/static/{R01Vc6rRTS_XwAg0Y8ERm → -R3HvmmPKzJ9Jfjg7hRqd}/_ssgManifest.js +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@castlekit/castle",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "The multi-agent workspace",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,6 +14,7 @@
14
14
  "public/",
15
15
  "index.js",
16
16
  "install.sh",
17
+ "install.ps1",
17
18
  "next.config.ts",
18
19
  "postcss.config.mjs",
19
20
  "tsconfig.json",
@@ -206,7 +206,7 @@ function ConnectionCard({
206
206
  }) {
207
207
  const getSubtitle = () => {
208
208
  if (isLoading) return "Connecting to Gateway...";
209
- if (!isConfigured) return "Run 'castle setup' to configure";
209
+ if (!isConfigured) return "OpenClaw not installed visit openclaw.ai";
210
210
  if (isConnected) {
211
211
  const parts = ["Connected"];
212
212
  if (serverVersion) parts[0] = `Connected to OpenClaw ${serverVersion}`;
@@ -247,8 +247,8 @@ function ConnectionCard({
247
247
  {isLoading ? (
248
248
  <Badge variant="outline">Connecting...</Badge>
249
249
  ) : (
250
- <Badge variant={isConnected ? "success" : "error"}>
251
- {isConnected ? "Connected" : "Disconnected"}
250
+ <Badge variant={isConnected ? "success" : isConfigured ? "error" : "outline"}>
251
+ {isConnected ? "Connected" : isConfigured ? "Disconnected" : "Not Installed"}
252
252
  </Badge>
253
253
  )}
254
254
  </div>
@@ -329,6 +329,7 @@ export async function runOnboarding(): Promise<void> {
329
329
  }
330
330
 
331
331
  // Step 1: Check for OpenClaw
332
+ let openclawSkipped = false;
332
333
  const openclawSpinner = p.spinner();
333
334
  openclawSpinner.start("Checking for OpenClaw...");
334
335
 
@@ -355,32 +356,30 @@ export async function runOnboarding(): Promise<void> {
355
356
  const installSpinner = p.spinner();
356
357
  installSpinner.start("Installing OpenClaw...");
357
358
 
359
+ const installCmd = process.platform === "win32"
360
+ ? 'powershell -NoProfile -ExecutionPolicy Bypass -Command "iwr -useb https://openclaw.ai/install.ps1 -OutFile $env:TEMP\\openclaw-install.ps1; & $env:TEMP\\openclaw-install.ps1 -NoOnboard"'
361
+ : 'curl -fsSL --proto "=https" --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --no-onboard --no-prompt';
362
+
358
363
  try {
359
- execSync(
360
- 'curl -fsSL --proto "=https" --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --no-onboard --no-prompt',
361
- { stdio: "pipe", timeout: 120000 }
362
- );
364
+ execSync(installCmd, { stdio: "inherit", timeout: 300000 });
363
365
  installSpinner.stop(BLUE("✔ OpenClaw installed"));
364
366
  } catch (error) {
367
+ openclawSkipped = true;
365
368
  installSpinner.stop(pc.red("OpenClaw installation failed"));
366
- p.note(
367
- `Install OpenClaw manually:\n${BLUE_LIGHT(
368
- "curl -fsSL https://openclaw.ai/install.sh | bash"
369
- )}\n\nThen run: ${BLUE_LIGHT("castle setup")}`,
370
- BLUE_BOLD("Manual Install")
369
+ const manualCmd = process.platform === "win32"
370
+ ? "iwr -useb https://openclaw.ai/install.ps1 | iex"
371
+ : "curl -fsSL https://openclaw.ai/install.sh | bash";
372
+ p.log.warn(
373
+ `You can install OpenClaw later:\n${BLUE_LIGHT(manualCmd)}`
371
374
  );
372
- p.outro("Come back when OpenClaw is installed!");
373
- process.exit(1);
374
375
  }
375
376
  } else {
376
- p.note(
377
- `Install OpenClaw:\n${BLUE_LIGHT(
378
- "curl -fsSL https://openclaw.ai/install.sh | bash"
379
- )}\n\nThen come back and run:\n${BLUE_LIGHT("castle setup")}`,
380
- BLUE_BOLD("Install OpenClaw First")
381
- );
382
- p.outro("See you soon!");
383
- process.exit(0);
377
+ openclawSkipped = true;
378
+ }
379
+
380
+ if (openclawSkipped && !isOpenClawInstalled()) {
381
+ // Skip Gateway config — use defaults and continue to build/start Castle
382
+ p.log.message(pc.dim("Using default settings — you can reconfigure later with castle setup"));
384
383
  }
385
384
  } else {
386
385
  // Auto-detect token and agents in one go
@@ -413,34 +412,49 @@ export async function runOnboarding(): Promise<void> {
413
412
  let token = readOpenClawToken();
414
413
  let gatewayUrl: string | undefined;
415
414
  let isRemote = false;
415
+ let primaryAgent = "assistant";
416
+ let agents: DiscoveredAgent[] = [];
417
+
418
+ if (!openclawSkipped) {
419
+ // If we have auto-detected config, offer a choice
420
+ const hasLocalConfig = !!readOpenClawPort() || isOpenClawInstalled();
421
+
422
+ if (hasLocalConfig && token) {
423
+ // Both auto-detect and manual are available
424
+ const connectionMode = await p.select({
425
+ message: "How would you like to connect?",
426
+ options: [
427
+ {
428
+ value: "auto",
429
+ label: `Auto-detected local Gateway ${pc.dim(`(port ${port})`)}`,
430
+ hint: "Recommended for local setups",
431
+ },
432
+ {
433
+ value: "manual",
434
+ label: "Enter Gateway details manually",
435
+ hint: "For remote, Tailscale, or custom setups",
436
+ },
437
+ ],
438
+ });
416
439
 
417
- // If we have auto-detected config, offer a choice
418
- const hasLocalConfig = !!readOpenClawPort() || isOpenClawInstalled();
419
-
420
- if (hasLocalConfig && token) {
421
- // Both auto-detect and manual are available
422
- const connectionMode = await p.select({
423
- message: "How would you like to connect?",
424
- options: [
425
- {
426
- value: "auto",
427
- label: `Auto-detected local Gateway ${pc.dim(`(port ${port})`)}`,
428
- hint: "Recommended for local setups",
429
- },
430
- {
431
- value: "manual",
432
- label: "Enter Gateway details manually",
433
- hint: "For remote, Tailscale, or custom setups",
434
- },
435
- ],
436
- });
437
-
438
- if (p.isCancel(connectionMode)) {
439
- p.cancel("Setup cancelled.");
440
- process.exit(0);
441
- }
440
+ if (p.isCancel(connectionMode)) {
441
+ p.cancel("Setup cancelled.");
442
+ process.exit(0);
443
+ }
442
444
 
443
- if (connectionMode === "manual") {
445
+ if (connectionMode === "manual") {
446
+ const manualResult = await promptManualGateway();
447
+ if (!manualResult) {
448
+ p.cancel("Setup cancelled.");
449
+ process.exit(0);
450
+ }
451
+ port = manualResult.port;
452
+ token = manualResult.token;
453
+ gatewayUrl = manualResult.gatewayUrl;
454
+ isRemote = manualResult.isRemote;
455
+ }
456
+ } else if (!token) {
457
+ // No auto-detected token — fall through to manual entry
444
458
  const manualResult = await promptManualGateway();
445
459
  if (!manualResult) {
446
460
  p.cancel("Setup cancelled.");
@@ -451,57 +465,44 @@ export async function runOnboarding(): Promise<void> {
451
465
  gatewayUrl = manualResult.gatewayUrl;
452
466
  isRemote = manualResult.isRemote;
453
467
  }
454
- } else if (!token) {
455
- // No auto-detected token — fall through to manual entry
456
- const manualResult = await promptManualGateway();
457
- if (!manualResult) {
458
- p.cancel("Setup cancelled.");
459
- process.exit(0);
460
- }
461
- port = manualResult.port;
462
- token = manualResult.token;
463
- gatewayUrl = manualResult.gatewayUrl;
464
- isRemote = manualResult.isRemote;
465
- }
466
468
 
467
- // Step 3: Agent Discovery (use URL if remote, port if local)
468
- const agentTarget = gatewayUrl || port;
469
- const agents = await discoverAgents(agentTarget, token);
469
+ // Step 3: Agent Discovery (use URL if remote, port if local)
470
+ const agentTarget = gatewayUrl || port;
471
+ agents = await discoverAgents(agentTarget, token);
470
472
 
471
- let primaryAgent: string;
473
+ if (agents.length > 0) {
472
474
 
473
- if (agents.length > 0) {
475
+ const selectedAgent = await p.select({
476
+ message: "Choose your primary agent",
477
+ options: agents.map((a) => ({
478
+ value: a.id,
479
+ label: `${a.name} ${pc.dim(`<${a.id}>`)}`,
480
+ hint: a.description || undefined,
481
+ })),
482
+ });
474
483
 
475
- const selectedAgent = await p.select({
476
- message: "Choose your primary agent",
477
- options: agents.map((a) => ({
478
- value: a.id,
479
- label: `${a.name} ${pc.dim(`<${a.id}>`)}`,
480
- hint: a.description || undefined,
481
- })),
482
- });
484
+ if (p.isCancel(selectedAgent)) {
485
+ p.cancel("Setup cancelled.");
486
+ process.exit(0);
487
+ }
483
488
 
484
- if (p.isCancel(selectedAgent)) {
485
- p.cancel("Setup cancelled.");
486
- process.exit(0);
487
- }
489
+ primaryAgent = selectedAgent as string;
490
+ } else {
491
+ const setPrimary = await p.text({
492
+ message: "Enter the name of your primary agent",
493
+ initialValue: "assistant",
494
+ validate(value: string | undefined) {
495
+ if (!value?.trim()) return "Agent name is required";
496
+ },
497
+ });
488
498
 
489
- primaryAgent = selectedAgent as string;
490
- } else {
491
- const setPrimary = await p.text({
492
- message: "Enter the name of your primary agent",
493
- initialValue: "assistant",
494
- validate(value: string | undefined) {
495
- if (!value?.trim()) return "Agent name is required";
496
- },
497
- });
499
+ if (p.isCancel(setPrimary)) {
500
+ p.cancel("Setup cancelled.");
501
+ process.exit(0);
502
+ }
498
503
 
499
- if (p.isCancel(setPrimary)) {
500
- p.cancel("Setup cancelled.");
501
- process.exit(0);
504
+ primaryAgent = setPrimary as string;
502
505
  }
503
-
504
- primaryAgent = setPrimary as string;
505
506
  }
506
507
 
507
508
  // Step 5: Create Castle config
@@ -619,12 +620,37 @@ export async function runOnboarding(): Promise<void> {
619
620
 
620
621
  // Write PID file helper
621
622
  const pidFile = join(castleDir, "server.pid");
623
+ const isWin = process.platform === "win32";
624
+
625
+ // Stop existing service FIRST — otherwise the service manager respawns
626
+ // the old server immediately after we kill it, stealing the port.
627
+ if (process.platform === "darwin") {
628
+ const plistPath = join(home(), "Library", "LaunchAgents", "com.castlekit.castle.plist");
629
+ try {
630
+ execSyncChild(`launchctl unload "${plistPath}" 2>/dev/null`, { stdio: "ignore", timeout: 10000 });
631
+ } catch { /* no existing service */ }
632
+ } else if (process.platform === "linux") {
633
+ try {
634
+ execSyncChild("systemctl --user stop castle.service 2>/dev/null", { stdio: "ignore", timeout: 10000 });
635
+ } catch { /* no existing service */ }
636
+ } else if (isWin) {
637
+ try {
638
+ execSyncChild('schtasks /End /TN "CastleServer" 2>nul', { stdio: "ignore", timeout: 10000 });
639
+ } catch { /* no existing task */ }
640
+ try {
641
+ execSyncChild('schtasks /Delete /TN "CastleServer" /F 2>nul', { stdio: "ignore", timeout: 10000 });
642
+ } catch { /* no existing task */ }
643
+ }
622
644
 
623
645
  // Kill any existing Castle server (by PID file)
624
646
  try {
625
647
  const existingPid = parseInt(readF(pidFile, "utf-8").trim(), 10);
626
648
  if (Number.isInteger(existingPid) && existingPid > 0) {
627
- process.kill(existingPid);
649
+ if (isWin) {
650
+ try { execSyncChild(`taskkill /PID ${existingPid} /F 2>nul`, { stdio: "ignore", timeout: 5000 }); } catch { /* ignore */ }
651
+ } else {
652
+ process.kill(existingPid);
653
+ }
628
654
  for (let i = 0; i < 30; i++) {
629
655
  try {
630
656
  process.kill(existingPid, 0);
@@ -639,14 +665,35 @@ export async function runOnboarding(): Promise<void> {
639
665
  }
640
666
 
641
667
  // Kill anything else on the target port
642
- try {
643
- execSyncChild(`lsof -ti:${castlePort} | xargs kill -9 2>/dev/null`, {
644
- stdio: "ignore",
645
- timeout: 5000,
646
- });
647
- await new Promise((r) => setTimeout(r, 500));
648
- } catch {
649
- // Nothing on port or lsof not available
668
+ if (isWin) {
669
+ try {
670
+ const netstatOut = execSyncChild(
671
+ `netstat -ano | findstr ":${castlePort} " | findstr "LISTENING"`,
672
+ { encoding: "utf-8", timeout: 5000 }
673
+ ).toString();
674
+ const pids = new Set<string>();
675
+ for (const line of netstatOut.split("\n")) {
676
+ const parts = line.trim().split(/\s+/);
677
+ const pid = parts[parts.length - 1];
678
+ if (pid && /^\d+$/.test(pid) && pid !== "0") pids.add(pid);
679
+ }
680
+ for (const pid of pids) {
681
+ try { execSyncChild(`taskkill /PID ${pid} /F 2>nul`, { stdio: "ignore", timeout: 5000 }); } catch { /* ignore */ }
682
+ }
683
+ if (pids.size > 0) await new Promise((r) => setTimeout(r, 500));
684
+ } catch {
685
+ // Nothing on port or netstat not available
686
+ }
687
+ } else {
688
+ try {
689
+ execSyncChild(`lsof -ti:${castlePort} | xargs kill -9 2>/dev/null`, {
690
+ stdio: "ignore",
691
+ timeout: 5000,
692
+ });
693
+ await new Promise((r) => setTimeout(r, 500));
694
+ } catch {
695
+ // Nothing on port or lsof not available
696
+ }
650
697
  }
651
698
 
652
699
  // Escape XML special characters for plist values
@@ -693,9 +740,7 @@ ${plistEnvEntries}
693
740
  </dict>
694
741
  </dict>
695
742
  </plist>`;
696
- try {
697
- execSyncChild(`launchctl unload "${plistPath}" 2>/dev/null`, { stdio: "ignore", timeout: 10000 });
698
- } catch { /* ignore */ }
743
+ // Service was already unloaded above — just write new plist and load
699
744
  writeFile(plistPath, plist);
700
745
  try {
701
746
  execSyncChild(`launchctl load "${plistPath}"`, { stdio: "ignore", timeout: 10000 });
@@ -730,6 +775,32 @@ WantedBy=default.target
730
775
  } catch {
731
776
  // Non-fatal
732
777
  }
778
+ } else if (isWin) {
779
+ // Windows: use Task Scheduler to run Castle at logon
780
+ // Build a batch wrapper that sets environment variables and starts the server
781
+ const batPath = join(castleDir, "start-server.bat");
782
+ const envLines = Object.entries(serverEnv)
783
+ .map(([k, v]) => `set "${k}=${v}"`)
784
+ .join("\r\n");
785
+ const batContent = `@echo off\r\n${envLines}\r\ncd /d "${PROJECT_ROOT}"\r\n"${nodePath}" ${serverArgs.map((a) => `"${a}"`).join(" ")}\r\n`;
786
+ writeFile(batPath, batContent);
787
+
788
+ // Task was already deleted above — create fresh
789
+ try {
790
+ execSyncChild(
791
+ `schtasks /Create /TN "CastleServer" /TR "\\"${batPath}\\"" /SC ONLOGON /RL HIGHEST /F 2>nul`,
792
+ { stdio: "ignore", timeout: 10000 }
793
+ );
794
+ } catch {
795
+ // Non-fatal — fall back to spawning directly
796
+ }
797
+
798
+ // Also start the task now
799
+ try {
800
+ execSyncChild('schtasks /Run /TN "CastleServer" 2>nul', { stdio: "ignore", timeout: 10000 });
801
+ } catch {
802
+ // Non-fatal
803
+ }
733
804
  }
734
805
 
735
806
  // If no service manager started it, spawn directly
@@ -805,6 +876,11 @@ WantedBy=default.target
805
876
  }
806
877
 
807
878
  p.outro(pc.dim(`Opening ${BLUE(`http://localhost:${castlePort}`)}...`));
808
- const open = (await import("open")).default;
809
- await open(`http://localhost:${castlePort}`);
879
+ const url = `http://localhost:${castlePort}`;
880
+ if (process.platform === "win32") {
881
+ execSync(`start "" "${url}"`, { stdio: "ignore" });
882
+ } else {
883
+ const open = (await import("open")).default;
884
+ await open(url);
885
+ }
810
886
  }
@@ -1 +1 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,41613,e=>{"use strict";var t=e.i(18050),a=e.i(75157);function r({title:e,subtitle:r,className:s}){return(0,t.jsxs)("div",{className:(0,a.cn)("space-y-2",s),children:[(0,t.jsx)("h1",{className:"text-2xl font-semibold text-foreground",children:e}),r?(0,t.jsx)("p",{className:"text-sm text-foreground-secondary",children:r}):null]})}e.s(["PageHeader",()=>r])},15288,87486,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(75157);let s=(0,a.forwardRef)(({className:e,variant:a="default",...s},n)=>(0,t.jsx)("div",{className:(0,r.cn)("rounded-[var(--radius-md)] bg-surface p-6",{"":"default"===a,"border border-border":"bordered"===a,"shadow-lg shadow-black/5 dark:shadow-black/20":"elevated"===a},e),ref:n,...s}));s.displayName="Card";let n=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("div",{className:(0,r.cn)("flex flex-col space-y-1.5 pb-4",e),ref:s,...a}));n.displayName="CardHeader";let i=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("h3",{className:(0,r.cn)("text-lg font-semibold leading-none tracking-tight text-foreground",e),ref:s,...a}));i.displayName="CardTitle";let l=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("p",{className:(0,r.cn)("text-sm text-foreground-secondary",e),ref:s,...a}));l.displayName="CardDescription";let o=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("div",{className:(0,r.cn)("",e),ref:s,...a}));o.displayName="CardContent";let c=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("div",{className:(0,r.cn)("flex items-center pt-4",e),ref:s,...a}));function d({className:e,variant:a="default",size:s="md",...n}){return(0,t.jsx)("span",{className:(0,r.cn)("inline-flex items-center font-medium rounded-[var(--radius-full)] transition-colors",{"bg-surface text-foreground-secondary":"default"===a,"bg-success/10 text-success":"success"===a,"bg-warning/10 text-warning":"warning"===a,"bg-error/10 text-error":"error"===a,"bg-info/10 text-info":"info"===a,"bg-transparent text-foreground-secondary border border-border":"outline"===a},{"px-2 py-0.5 text-xs":"sm"===s,"px-2.5 py-0.5 text-sm":"md"===s},e),...n})}c.displayName="CardFooter",e.s(["Card",()=>s,"CardContent",()=>o,"CardDescription",()=>l,"CardFooter",()=>c,"CardHeader",()=>n,"CardTitle",()=>i],15288),e.s(["Badge",()=>d],87486)},29143,18809,e=>{"use strict";var t=e.i(71645),a=e.i(83599);let r=null,s=0,n=-1,i=Date.now(),l=new Map,o=new Set;function c(e,t){return l.has(e)||l.set(e,new Set),l.get(e).add(t),1==++s&&(r||(console.log("[SSE Client] Opening connection (subscribers:",s+")"),r=new EventSource("/api/openclaw/events"),i=Date.now(),r.onopen=()=>{console.log("[SSE Client] Connected")},r.onmessage=e=>{try{let t=JSON.parse(e.data);!function(e){if(i=Date.now(),"number"==typeof e.seq){if(e.seq<=n)return console.debug("[SSE Client] Dropped duplicate event seq:",e.seq,"event:",e.event);n=e.seq}let t=e.event;for(let[a,r]of l)if("*"===a||(a.endsWith(".*")?t.startsWith(a.slice(0,-1)):t===a))for(let t of r)try{t(e)}catch(e){console.error("[SSE] Handler error:",e)}}(t)}catch(t){console.warn("[SSE Client] Failed to parse event:",t.message,"data:",e.data?.slice(0,100))}},r.onerror=e=>{for(let e of(console.warn("[SSE Client] Connection error (readyState:",r?.readyState+")"),o))try{e()}catch{}})),()=>{let a=l.get(e);a&&(a.delete(t),0===a.size&&l.delete(e)),--s<=0&&(s=0,r&&(console.log("[SSE Client] Closing connection"),r.close(),r=null),n=-1)}}function d(e){return o.add(e),()=>{o.delete(e)}}function u(){return i}e.s(["getLastEventTimestamp",()=>u,"onError",()=>d,"subscribe",()=>c],18809);let h=async e=>{let t=await fetch(e,{method:"POST"});return t.ok||console.warn(`[useOpenClaw] Status fetch returned ${t.status}`),t.json()},x=async e=>{let t=await fetch(e);return t.ok?(await t.json()).agents||[]:(console.warn(`[useOpenClaw] Agents fetch failed: ${t.status}`),[])};function f(){let{data:e,error:r,isLoading:s,mutate:n}=(0,a.default)("/api/openclaw/ping",h,{refreshInterval:6e4,revalidateOnFocus:!0,dedupingInterval:1e4,errorRetryCount:2}),i=e?.ok??!1,{data:l,isLoading:o,mutate:u}=(0,a.default)(i?"/api/openclaw/agents":null,x,{refreshInterval:3e5,revalidateOnFocus:!1,dedupingInterval:3e4}),f=(0,t.useCallback)(async()=>{await n(),i&&await u()},[n,u,i]),m=(0,t.useCallback)(()=>u(),[u]);return(0,t.useEffect)(()=>{let e=e=>{u()},t=c("castle.state",e=>{let t=e.payload;n(e=>({ok:t.isConnected,configured:e?.configured??!0,state:t.state,server:t.server}),{revalidate:!1}),t.isConnected&&u()}),a=c("agent.*",e),r=c("agentAvatarUpdated",e),s=d(()=>{console.warn("[useOpenClaw] SSE error — marking as disconnected"),n(e=>e?{...e,ok:!1,state:"disconnected"}:e,{revalidate:!1})});return()=>{t(),a(),r(),s()}},[n,u]),{status:e,isLoading:s,isError:!!r,isConnected:i,isConfigured:e?.configured??!1,latency:e?.latency_ms,serverVersion:e?.server?.version,agents:l??[],agentsLoading:o,refresh:f,refreshAgents:m}}e.s(["useOpenClaw",()=>f],29143)},63209,e=>{"use strict";let t=(0,e.i(75254).default)("circle-alert",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]]);e.s(["AlertCircle",()=>t],63209)},31245,e=>{"use strict";let t=(0,e.i(75254).default)("bot",[["path",{d:"M12 8V4H8",key:"hb8ula"}],["rect",{width:"16",height:"12",x:"4",y:"8",rx:"2",key:"enze0r"}],["path",{d:"M2 14h2",key:"vft8re"}],["path",{d:"M20 14h2",key:"4cs60a"}],["path",{d:"M15 13v2",key:"1xurst"}],["path",{d:"M9 13v2",key:"rq6x2g"}]]);e.s(["Bot",()=>t],31245)},57212,e=>{"use strict";let t=(0,e.i(75254).default)("wifi-off",[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}],["path",{d:"M5 12.859a10 10 0 0 1 5.17-2.69",key:"1dl1wf"}],["path",{d:"M19 12.859a10 10 0 0 0-2.007-1.523",key:"4k23kn"}],["path",{d:"M2 8.82a15 15 0 0 1 4.177-2.643",key:"1grhjp"}],["path",{d:"M22 8.82a15 15 0 0 0-11.288-3.764",key:"z3jwby"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]]);e.s(["WifiOff",()=>t],57212)},16715,e=>{"use strict";let t=(0,e.i(75254).default)("refresh-cw",[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]]);e.s(["RefreshCw",()=>t],16715)},31278,e=>{"use strict";let t=(0,e.i(75254).default)("loader-circle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);e.s(["Loader2",()=>t],31278)},94983,e=>{"use strict";let t=(0,e.i(75254).default)("message-circle",[["path",{d:"M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719",key:"1sd12s"}]]);e.s(["MessageCircle",()=>t],94983)},84614,e=>{"use strict";let t=(0,e.i(75254).default)("user",[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]]);e.s(["User",()=>t],84614)},46798,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(74080),s=e.i(75157);function n({children:e,content:n,side:i="right",className:l,delay:o=0}){let[c,d]=(0,a.useState)(!1),[u,h]=(0,a.useState)(!1),x=(0,a.useRef)(null),[f,m]=(0,a.useState)({x:0,y:0}),[p,g]=(0,a.useState)(!1),v=(0,a.useRef)(null),b=(0,a.useRef)(null);(0,a.useEffect)(()=>(h(!0),()=>{x.current&&clearTimeout(x.current)}),[]);let y=(0,a.useCallback)(()=>{if(v.current&&b.current){let e=v.current.getBoundingClientRect(),t=b.current.getBoundingClientRect(),a=0,r=0;switch(i){case"top":a=e.left+e.width/2-t.width/2,r=e.top-t.height-10;break;case"bottom":a=e.left+e.width/2-t.width/2,r=e.bottom+10;break;case"left":a=e.left-t.width-10,r=e.top+e.height/2-t.height/2;break;default:a=e.right+10,r=e.top+e.height/2-t.height/2}m({x:a,y:r}),g(!0)}},[i]);return(0,a.useLayoutEffect)(()=>{if(!c)return void g(!1);y();let e=()=>y();return window.addEventListener("resize",e),window.addEventListener("scroll",e,!0),()=>{window.removeEventListener("resize",e),window.removeEventListener("scroll",e,!0)}},[c,y]),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("div",{ref:v,onMouseEnter:()=>{o>0?x.current=setTimeout(()=>d(!0),o):d(!0)},onMouseLeave:()=>{x.current&&(clearTimeout(x.current),x.current=null),d(!1)},className:l,children:e}),c&&u?(0,r.createPortal)((0,t.jsx)("div",{ref:b,className:"fixed z-[9999] pointer-events-none",style:{left:f.x,top:f.y,visibility:p?"visible":"hidden"},children:(0,t.jsx)("div",{className:(0,s.cn)("transition-all duration-150 ease-out",p?"opacity-100 scale-100":"opacity-0 scale-95","right"===i&&(p?"translate-x-0":"-translate-x-2"),"left"===i&&(p?"translate-x-0":"translate-x-2"),"top"===i&&(p?"translate-y-0":"translate-y-2"),"bottom"===i&&(p?"translate-y-0":"-translate-y-2")),children:(0,t.jsxs)("div",{className:"relative bg-[#1a1a1a] text-white text-sm font-medium px-3 py-1.5 rounded-[4px] whitespace-nowrap shadow-xl shadow-black/25",children:[n,"right"===i&&(0,t.jsx)("div",{className:"absolute -left-[7px] top-1/2 -translate-y-1/2",children:(0,t.jsx)("div",{className:"w-0 h-0 border-t-[8px] border-t-transparent border-b-[8px] border-b-transparent border-r-[8px] border-r-[#1a1a1a]"})}),"left"===i&&(0,t.jsx)("div",{className:"absolute -right-[7px] top-1/2 -translate-y-1/2",children:(0,t.jsx)("div",{className:"w-0 h-0 border-t-[8px] border-t-transparent border-b-[8px] border-b-transparent border-l-[8px] border-l-[#1a1a1a]"})}),"top"===i&&(0,t.jsx)("div",{className:"absolute -bottom-[7px] left-1/2 -translate-x-1/2",children:(0,t.jsx)("div",{className:"w-0 h-0 border-l-[8px] border-l-transparent border-r-[8px] border-r-transparent border-t-[8px] border-t-[#1a1a1a]"})}),"bottom"===i&&(0,t.jsx)("div",{className:"absolute -top-[7px] left-1/2 -translate-x-1/2",children:(0,t.jsx)("div",{className:"w-0 h-0 border-l-[8px] border-l-transparent border-r-[8px] border-r-transparent border-b-[8px] border-b-[#1a1a1a]"})})]})})}),document.body):null]})}e.s(["Tooltip",()=>n])},19009,e=>{"use strict";var t=e.i(83599);let a=e=>fetch(e).then(e=>e.json());function r(){let{data:e,mutate:r,isLoading:s}=(0,t.default)("/api/settings",a,{revalidateOnFocus:!0,dedupingInterval:5e3}),n=e?.displayName||"";return{displayName:n,avatarUrl:e?.avatarPath?`/api/settings/avatar?v=${encodeURIComponent(e.avatarPath)}`:null,tooltips:e?.tooltips!=="false",isLoading:s,refresh:()=>r()}}e.s(["useUserSettings",()=>r])},99676,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(75157);let s=(0,a.forwardRef)(({className:e,size:a="md",status:s,statusPulse:n,children:i,...l},o)=>(0,t.jsxs)("div",{className:"relative inline-block shrink-0",children:[(0,t.jsx)("div",{className:(0,r.cn)("relative flex shrink-0 overflow-hidden rounded-[4px] bg-surface border border-border",{"h-9 w-9":"sm"===a,"h-10 w-10":"md"===a,"h-12 w-12":"lg"===a},e),ref:o,...l,children:i}),s&&(0,t.jsx)("span",{className:(0,r.cn)("absolute block rounded-full ring-2 ring-background",{"h-2.5 w-2.5 -bottom-0.5 -right-0.5":"sm"===a,"h-3 w-3 -bottom-0.5 -right-0.5":"md"===a,"h-3.5 w-3.5 -bottom-0.5 -right-0.5":"lg"===a},{"bg-success":"online"===s,"bg-foreground-muted":"offline"===s,"bg-error":"busy"===s,"bg-warning":"away"===s},n&&"animate-pulse")})]}));s.displayName="Avatar";let n=(0,a.forwardRef)(({className:e,alt:a,...s},n)=>(0,t.jsx)("img",{className:(0,r.cn)("aspect-square h-full w-full object-cover",e),alt:a,ref:n,...s}));n.displayName="AvatarImage";let i=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("span",{className:(0,r.cn)("flex h-full w-full items-center justify-center bg-surface text-foreground-secondary font-medium text-sm",e),ref:s,...a}));i.displayName="AvatarFallback",e.s(["Avatar",()=>s,"AvatarFallback",()=>i,"AvatarImage",()=>n])},94037,60289,97250,91799,39616,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(63178),s=e.i(75254);let n=(0,s.default)("layout-dashboard",[["rect",{width:"7",height:"9",x:"3",y:"3",rx:"1",key:"10lvy0"}],["rect",{width:"7",height:"5",x:"14",y:"3",rx:"1",key:"16une8"}],["rect",{width:"7",height:"9",x:"14",y:"12",rx:"1",key:"1hutg5"}],["rect",{width:"7",height:"5",x:"3",y:"16",rx:"1",key:"ldoo1y"}]]);e.s(["LayoutDashboard",()=>n],60289);var i=e.i(94983),l=e.i(84614);let o=(0,s.default)("sun",[["circle",{cx:"12",cy:"12",r:"4",key:"4exip2"}],["path",{d:"M12 2v2",key:"tus03m"}],["path",{d:"M12 20v2",key:"1lh1kg"}],["path",{d:"m4.93 4.93 1.41 1.41",key:"149t6j"}],["path",{d:"m17.66 17.66 1.41 1.41",key:"ptbguv"}],["path",{d:"M2 12h2",key:"1t8f8n"}],["path",{d:"M20 12h2",key:"1q8mjw"}],["path",{d:"m6.34 17.66-1.41 1.41",key:"1m8zz5"}],["path",{d:"m19.07 4.93-1.41 1.41",key:"1shlcs"}]]);e.s(["Sun",()=>o],97250);let c=(0,s.default)("moon",[["path",{d:"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",key:"kfwtm"}]]);e.s(["Moon",()=>c],91799);let d=(0,s.default)("settings",[["path",{d:"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915",key:"1i5ecw"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);e.s(["Settings",()=>d],39616);var u=e.i(75157);function h({className:e}){return(0,t.jsx)("svg",{viewBox:"0 0 512 512",xmlns:"http://www.w3.org/2000/svg",className:(0,u.cn)("fill-current",e),children:(0,t.jsxs)("g",{children:[(0,t.jsx)("path",{d:"m124.809 408.11h262.382v103.89h-262.382z"}),(0,t.jsx)("path",{d:"m273.162 123.55h134.646l-34.459-44.772 33.515-46.459h-133.702v-32.319h-29.985v196.446h29.985z"}),(0,t.jsx)("path",{d:"m347.45 281.985h-50.335v-56.54h-79.107v56.54h-53.643v-56.54h-91.962v111.141c0 23.448 19.075 42.523 42.523 42.523h282.147c23.448 0 42.524-19.075 42.524-42.523v-111.14h-92.147z"})]})})}var x=e.i(46798),f=e.i(18566),m=e.i(19009),p=e.i(57401),g=e.i(99676);let v=[{id:"dashboard",label:"Dashboard",icon:n,href:"/"},{id:"chat",label:"Chat",icon:i.MessageCircle,href:"/chat"}];function b({activeItem:e="dashboard",onNavigate:a,className:r,variant:s="solid"}){let n=(0,f.usePathname)(),i=(0,f.useRouter)(),l=!a,{tooltips:o}=(0,m.useUserSettings)(),c=n&&"/"!==n&&n.startsWith("/chat")?"chat":"dashboard",d=l?c:e;return(0,t.jsxs)("aside",{className:(0,u.cn)("fixed top-[20px] left-[24px] bottom-[20px] flex flex-col z-40 rounded-[var(--radius-md)] w-14","glass"===s?"glass":"bg-surface border border-border",r),children:[(0,t.jsx)("div",{className:"flex items-center justify-center pt-5 pb-[60px]",children:(0,t.jsx)("button",{type:"button","aria-label":"Go to Dashboard",onClick:()=>l?i.push("/"):a?.("dashboard"),className:"flex items-center justify-center transition-opacity hover:opacity-85 cursor-pointer",children:(0,t.jsx)(h,{className:"h-[36px] w-[36px] min-h-[36px] min-w-[36px] shrink-0 text-[var(--logo-color)] -mt-[3px]"})})}),(0,t.jsx)("nav",{className:"flex-1 space-y-1 px-2",children:v.map(e=>{let r=d===e.id,s=(0,t.jsx)("button",{onClick:()=>l?i.push(e.href):a?.(e.id),className:(0,u.cn)("flex items-center justify-center w-full rounded-[4px] p-2.5 cursor-pointer",r?"bg-accent/10 text-accent":"text-foreground-secondary hover:text-foreground hover:bg-surface-hover"),children:(0,t.jsx)(e.icon,{className:"h-5 w-5 shrink-0"})});return o?(0,t.jsx)(x.Tooltip,{content:e.label,side:"right",children:s},e.id):(0,t.jsx)("div",{children:s},e.id)})}),(0,t.jsx)(y,{})]})}function y(){let[e,s]=(0,a.useState)(!1),{theme:n,setTheme:i}=(0,r.useTheme)(),[u,h]=(0,a.useState)(!1),x=(0,f.useRouter)(),{avatarUrl:v,isLoading:b}=(0,m.useUserSettings)(),{getStatus:y}=(0,p.useAgentStatus)(),j=y(p.USER_STATUS_ID),w=(0,a.useRef)(null);(0,a.useEffect)(()=>{h(!0)},[]),(0,a.useEffect)(()=>{function e(e){w.current&&!w.current.contains(e.target)&&s(!1)}return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[]);let k="dark"===n;return(0,t.jsxs)("div",{ref:w,className:"relative flex justify-center pb-[8px]",children:[(0,t.jsx)("button",{onClick:()=>s(!e),className:"group flex items-center justify-center rounded-[4px] cursor-pointer transition-opacity",children:(0,t.jsx)(g.Avatar,{size:"sm",status:"active"===j?"online":"offline",children:b?(0,t.jsx)(g.AvatarFallback,{className:"skeleton"}):v?(0,t.jsx)(g.AvatarImage,{src:v,alt:"You",className:"grayscale group-hover:grayscale-0 transition-all duration-200"}):(0,t.jsx)(g.AvatarFallback,{className:"text-foreground-secondary",children:(0,t.jsx)(l.User,{className:"h-5 w-5"})})})}),e&&(0,t.jsxs)("div",{className:"absolute left-[calc(100%+8px)] bottom-0 w-48 rounded-[var(--radius-md)] bg-surface border border-border shadow-xl py-1 z-50",children:[(0,t.jsxs)("button",{onClick:()=>{s(!1),x.push("/settings")},className:"flex items-center gap-3 w-full px-4 py-2.5 text-sm text-foreground-secondary hover:text-foreground hover:bg-surface-hover cursor-pointer",children:[(0,t.jsx)(d,{className:"h-4 w-4"}),"Settings"]}),u&&(0,t.jsxs)("button",{onClick:()=>{i(k?"light":"dark"),s(!1)},className:"flex items-center gap-3 w-full px-4 py-2.5 text-sm text-foreground-secondary hover:text-foreground hover:bg-surface-hover cursor-pointer",children:[k?(0,t.jsx)(o,{className:"h-4 w-4"}):(0,t.jsx)(c,{className:"h-4 w-4"}),k?"Light mode":"Dark mode"]})]})]})}e.s(["Sidebar",()=>b],94037)},68553,e=>{"use strict";let t=(0,e.i(75254).default)("camera",[["path",{d:"M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z",key:"18u6gg"}],["circle",{cx:"12",cy:"13",r:"3",key:"1vg3eu"}]]);e.s(["Camera",()=>t],68553)},52683,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(31245),s=e.i(75254);let n=(0,s.default)("wifi",[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M2 8.82a15 15 0 0 1 20 0",key:"dnpr2z"}],["path",{d:"M5 12.859a10 10 0 0 1 14 0",key:"1x1e6c"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}]]);var i=e.i(57212);let l=(0,s.default)("crown",[["path",{d:"M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z",key:"1vdc57"}],["path",{d:"M5 21h14",key:"11awu3"}]]);var o=e.i(16715),c=e.i(31278),d=e.i(63209),u=e.i(68553),h=e.i(94037),x=e.i(41613),f=e.i(15288),m=e.i(87486),p=e.i(99676),g=e.i(75157),v=e.i(29143),b=e.i(57401),y=e.i(40871);function j({agent:e,isPrimary:r,isConnected:s,onAvatarUpdated:n}){let i=(0,a.useRef)(null),[o,d]=(0,a.useState)(!1),{getStatus:h}=(0,b.useAgentStatus)(),x=h(e.id),v=(0,a.useCallback)(()=>{s&&i.current?.click()},[s]),y=(0,a.useCallback)(async t=>{let a=t.target.files?.[0];if(a){if(t.target.value="",a.size>5242880)return void alert("Image too large (max 5MB)");d(!0);try{let t=new FormData;t.append("avatar",a);let r=await fetch(`/api/openclaw/agents/${e.id}/avatar`,{method:"POST",body:t}),s=await r.json();if(!r.ok)return void alert(s.error||"Failed to update avatar");n()}catch{alert("Failed to upload avatar")}finally{d(!1)}}},[e.id,n]);return(0,t.jsx)(f.Card,{variant:"bordered",className:(0,g.cn)("py-4 pl-5 pr-4 transition-colors min-h-[80px] flex items-center",s?"hover:border-border-hover":"opacity-60"),children:(0,t.jsxs)("div",{className:"flex items-center justify-between flex-1",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsxs)("button",{type:"button",onClick:v,disabled:!s||o,className:"relative group rounded-[4px] focus:outline-none focus-visible:ring-2 focus-visible:ring-accent leading-[0]",title:s?"Click to change avatar":void 0,children:[(0,t.jsx)(p.Avatar,{size:"md",status:function(e,t){if(!t)return"offline";switch(e){case"thinking":return"away";case"active":return"online";default:return"offline"}}(x,s),statusPulse:"thinking"===x,children:e.avatar?(0,t.jsx)(p.AvatarImage,{src:e.avatar,alt:e.name,className:(0,g.cn)(!s&&"grayscale")}):(0,t.jsx)(p.AvatarFallback,{children:e.emoji||e.name.slice(0,2).toUpperCase()})}),s&&!o&&(0,t.jsx)("div",{className:"absolute inset-0 rounded-[4px] bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center",children:(0,t.jsx)(u.Camera,{className:"h-4 w-4 text-white"})}),o&&(0,t.jsx)("div",{className:"absolute inset-0 rounded-[4px] bg-black/50 flex items-center justify-center",children:(0,t.jsx)(c.Loader2,{className:"h-4 w-4 text-white animate-spin"})})]}),(0,t.jsx)("input",{ref:i,type:"file",accept:"image/png,image/jpeg,image/webp,image/gif",className:"hidden",onChange:y}),(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:e.name}),r&&(0,t.jsxs)("span",{className:"flex items-center gap-1 text-xs text-accent",children:[(0,t.jsx)(l,{className:"h-3 w-3"}),"Primary"]})]}),(0,t.jsx)("p",{className:"text-xs text-foreground-muted",children:s?e.description||"OpenClaw Agent":"Unreachable"})]})]}),(0,t.jsx)(m.Badge,{variant:function(e,t){if(!t)return"outline";switch(e){case"thinking":return"warning";case"active":return"success";default:return"outline"}}(x,s),size:"sm",children:function(e,t){if(!t)return"Offline";switch(e){case"thinking":return"Thinking";case"active":return"Active";default:return"Idle"}}(x,s)})]})})}function w({isConnected:e,isLoading:a,isConfigured:r,serverVersion:s,latency:l,error:d,onRefresh:u}){return(0,t.jsx)(f.Card,{variant:"bordered",className:"mb-8",children:(0,t.jsxs)(f.CardContent,{className:"flex items-center justify-between",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[a?(0,t.jsx)(c.Loader2,{className:"h-5 w-5 text-foreground-muted animate-spin"}):e?(0,t.jsx)(n,{className:"h-5 w-5 text-success"}):(0,t.jsx)(i.WifiOff,{className:"h-5 w-5 text-error"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:"OpenClaw Gateway"}),(0,t.jsx)("p",{className:"text-xs text-foreground-muted",children:(()=>{if(a)return"Connecting to Gateway...";if(!r)return"Run 'castle setup' to configure";if(e){let e=["Connected"];return s&&(e[0]=`Connected to OpenClaw ${s}`),l&&e.push(`${l}ms`),e.join(" · ")}return d||"Not connected"})()})]})]}),(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("button",{onClick:u,className:"p-1.5 rounded-md text-foreground-muted hover:text-foreground hover:bg-surface-hover transition-colors",title:"Refresh connection",children:(0,t.jsx)(o.RefreshCw,{className:"h-4 w-4"})}),a?(0,t.jsx)(m.Badge,{variant:"outline",children:"Connecting..."}):(0,t.jsx)(m.Badge,{variant:e?"success":"error",children:e?"Connected":"Disconnected"})]})]})})}function k(){return(0,t.jsx)("div",{className:"grid gap-3",children:[1,2,3].map(e=>(0,t.jsx)(f.Card,{variant:"bordered",className:"p-4 min-h-[80px] flex items-center",children:(0,t.jsxs)("div",{className:"flex items-center justify-between flex-1",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)("div",{className:"skeleton h-10 w-10 rounded-full"}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("div",{className:"skeleton h-4 w-24 rounded"}),(0,t.jsx)("div",{className:"skeleton h-3 w-32 rounded"})]})]}),(0,t.jsx)("div",{className:"skeleton h-5 w-14 rounded-full"})]})},e))})}function N({isConfigured:e}){return(0,t.jsx)(f.Card,{variant:"bordered",className:"p-8",children:(0,t.jsx)("div",{className:"flex flex-col items-center text-center gap-3",children:e?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(d.AlertCircle,{className:"h-8 w-8 text-foreground-muted"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:"No agents discovered"}),(0,t.jsx)("p",{className:"text-xs text-foreground-muted mt-1",children:"Make sure OpenClaw Gateway is running and agents are configured."})]})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.Bot,{className:"h-8 w-8 text-foreground-muted"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:"Welcome to Castle"}),(0,t.jsxs)("p",{className:"text-xs text-foreground-muted mt-1",children:["Run ",(0,t.jsx)("code",{className:"px-1 py-0.5 bg-surface-hover rounded text-xs",children:"castle setup"})," to connect to your OpenClaw Gateway."]})]})]})})})}function C(){let{status:e,isLoading:a,isConnected:s,isConfigured:n,latency:i,serverVersion:l,agents:o,agentsLoading:c,refresh:d}=(0,v.useOpenClaw)();return(0,t.jsxs)("div",{className:"min-h-screen bg-background",children:[(0,t.jsx)(h.Sidebar,{variant:"solid"}),(0,t.jsxs)("main",{className:"min-h-screen ml-[80px]",children:[(0,t.jsxs)("div",{className:"px-8 py-5 flex items-center justify-between gap-4 border-b border-border",children:[(0,t.jsx)(x.PageHeader,{title:"Castle",subtitle:"The multi-agent workspace"}),(0,t.jsx)(y.SearchTrigger,{})]}),(0,t.jsxs)("div",{className:"p-8 max-w-4xl",children:[(0,t.jsx)(w,{isConnected:s,isLoading:a,isConfigured:n,serverVersion:l,latency:i,error:e?.error,onRefresh:d}),(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between",children:[(0,t.jsxs)("h2",{className:"text-lg font-semibold text-foreground flex items-center gap-2",children:[(0,t.jsx)(r.Bot,{className:"h-5 w-5 text-foreground-secondary"}),"Agents"]}),!a&&o.length>0&&(0,t.jsxs)("span",{className:"text-sm text-foreground-muted",children:[o.length," agent",1!==o.length?"s":""," discovered"]})]}),c||a&&0===o.length?(0,t.jsx)(k,{}):o.length>0?(0,t.jsx)("div",{className:"grid gap-3",children:o.map((e,a)=>(0,t.jsx)(j,{agent:e,isPrimary:0===a,isConnected:s,onAvatarUpdated:d},e.id))}):(0,t.jsx)(N,{isConfigured:n})]})]})]})]})}e.s(["default",()=>C],52683)}]);
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,41613,e=>{"use strict";var t=e.i(18050),a=e.i(75157);function r({title:e,subtitle:r,className:s}){return(0,t.jsxs)("div",{className:(0,a.cn)("space-y-2",s),children:[(0,t.jsx)("h1",{className:"text-2xl font-semibold text-foreground",children:e}),r?(0,t.jsx)("p",{className:"text-sm text-foreground-secondary",children:r}):null]})}e.s(["PageHeader",()=>r])},15288,87486,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(75157);let s=(0,a.forwardRef)(({className:e,variant:a="default",...s},n)=>(0,t.jsx)("div",{className:(0,r.cn)("rounded-[var(--radius-md)] bg-surface p-6",{"":"default"===a,"border border-border":"bordered"===a,"shadow-lg shadow-black/5 dark:shadow-black/20":"elevated"===a},e),ref:n,...s}));s.displayName="Card";let n=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("div",{className:(0,r.cn)("flex flex-col space-y-1.5 pb-4",e),ref:s,...a}));n.displayName="CardHeader";let i=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("h3",{className:(0,r.cn)("text-lg font-semibold leading-none tracking-tight text-foreground",e),ref:s,...a}));i.displayName="CardTitle";let l=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("p",{className:(0,r.cn)("text-sm text-foreground-secondary",e),ref:s,...a}));l.displayName="CardDescription";let o=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("div",{className:(0,r.cn)("",e),ref:s,...a}));o.displayName="CardContent";let c=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("div",{className:(0,r.cn)("flex items-center pt-4",e),ref:s,...a}));function d({className:e,variant:a="default",size:s="md",...n}){return(0,t.jsx)("span",{className:(0,r.cn)("inline-flex items-center font-medium rounded-[var(--radius-full)] transition-colors",{"bg-surface text-foreground-secondary":"default"===a,"bg-success/10 text-success":"success"===a,"bg-warning/10 text-warning":"warning"===a,"bg-error/10 text-error":"error"===a,"bg-info/10 text-info":"info"===a,"bg-transparent text-foreground-secondary border border-border":"outline"===a},{"px-2 py-0.5 text-xs":"sm"===s,"px-2.5 py-0.5 text-sm":"md"===s},e),...n})}c.displayName="CardFooter",e.s(["Card",()=>s,"CardContent",()=>o,"CardDescription",()=>l,"CardFooter",()=>c,"CardHeader",()=>n,"CardTitle",()=>i],15288),e.s(["Badge",()=>d],87486)},29143,18809,e=>{"use strict";var t=e.i(71645),a=e.i(83599);let r=null,s=0,n=-1,i=Date.now(),l=new Map,o=new Set;function c(e,t){return l.has(e)||l.set(e,new Set),l.get(e).add(t),1==++s&&(r||(console.log("[SSE Client] Opening connection (subscribers:",s+")"),r=new EventSource("/api/openclaw/events"),i=Date.now(),r.onopen=()=>{console.log("[SSE Client] Connected")},r.onmessage=e=>{try{let t=JSON.parse(e.data);!function(e){if(i=Date.now(),"number"==typeof e.seq){if(e.seq<=n)return console.debug("[SSE Client] Dropped duplicate event seq:",e.seq,"event:",e.event);n=e.seq}let t=e.event;for(let[a,r]of l)if("*"===a||(a.endsWith(".*")?t.startsWith(a.slice(0,-1)):t===a))for(let t of r)try{t(e)}catch(e){console.error("[SSE] Handler error:",e)}}(t)}catch(t){console.warn("[SSE Client] Failed to parse event:",t.message,"data:",e.data?.slice(0,100))}},r.onerror=e=>{for(let e of(console.warn("[SSE Client] Connection error (readyState:",r?.readyState+")"),o))try{e()}catch{}})),()=>{let a=l.get(e);a&&(a.delete(t),0===a.size&&l.delete(e)),--s<=0&&(s=0,r&&(console.log("[SSE Client] Closing connection"),r.close(),r=null),n=-1)}}function d(e){return o.add(e),()=>{o.delete(e)}}function u(){return i}e.s(["getLastEventTimestamp",()=>u,"onError",()=>d,"subscribe",()=>c],18809);let h=async e=>{let t=await fetch(e,{method:"POST"});return t.ok||console.warn(`[useOpenClaw] Status fetch returned ${t.status}`),t.json()},x=async e=>{let t=await fetch(e);return t.ok?(await t.json()).agents||[]:(console.warn(`[useOpenClaw] Agents fetch failed: ${t.status}`),[])};function f(){let{data:e,error:r,isLoading:s,mutate:n}=(0,a.default)("/api/openclaw/ping",h,{refreshInterval:6e4,revalidateOnFocus:!0,dedupingInterval:1e4,errorRetryCount:2}),i=e?.ok??!1,{data:l,isLoading:o,mutate:u}=(0,a.default)(i?"/api/openclaw/agents":null,x,{refreshInterval:3e5,revalidateOnFocus:!1,dedupingInterval:3e4}),f=(0,t.useCallback)(async()=>{await n(),i&&await u()},[n,u,i]),m=(0,t.useCallback)(()=>u(),[u]);return(0,t.useEffect)(()=>{let e=e=>{u()},t=c("castle.state",e=>{let t=e.payload;n(e=>({ok:t.isConnected,configured:e?.configured??!0,state:t.state,server:t.server}),{revalidate:!1}),t.isConnected&&u()}),a=c("agent.*",e),r=c("agentAvatarUpdated",e),s=d(()=>{console.warn("[useOpenClaw] SSE error — marking as disconnected"),n(e=>e?{...e,ok:!1,state:"disconnected"}:e,{revalidate:!1})});return()=>{t(),a(),r(),s()}},[n,u]),{status:e,isLoading:s,isError:!!r,isConnected:i,isConfigured:e?.configured??!1,latency:e?.latency_ms,serverVersion:e?.server?.version,agents:l??[],agentsLoading:o,refresh:f,refreshAgents:m}}e.s(["useOpenClaw",()=>f],29143)},63209,e=>{"use strict";let t=(0,e.i(75254).default)("circle-alert",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]]);e.s(["AlertCircle",()=>t],63209)},31245,e=>{"use strict";let t=(0,e.i(75254).default)("bot",[["path",{d:"M12 8V4H8",key:"hb8ula"}],["rect",{width:"16",height:"12",x:"4",y:"8",rx:"2",key:"enze0r"}],["path",{d:"M2 14h2",key:"vft8re"}],["path",{d:"M20 14h2",key:"4cs60a"}],["path",{d:"M15 13v2",key:"1xurst"}],["path",{d:"M9 13v2",key:"rq6x2g"}]]);e.s(["Bot",()=>t],31245)},57212,e=>{"use strict";let t=(0,e.i(75254).default)("wifi-off",[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}],["path",{d:"M5 12.859a10 10 0 0 1 5.17-2.69",key:"1dl1wf"}],["path",{d:"M19 12.859a10 10 0 0 0-2.007-1.523",key:"4k23kn"}],["path",{d:"M2 8.82a15 15 0 0 1 4.177-2.643",key:"1grhjp"}],["path",{d:"M22 8.82a15 15 0 0 0-11.288-3.764",key:"z3jwby"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]]);e.s(["WifiOff",()=>t],57212)},16715,e=>{"use strict";let t=(0,e.i(75254).default)("refresh-cw",[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]]);e.s(["RefreshCw",()=>t],16715)},31278,e=>{"use strict";let t=(0,e.i(75254).default)("loader-circle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);e.s(["Loader2",()=>t],31278)},94983,e=>{"use strict";let t=(0,e.i(75254).default)("message-circle",[["path",{d:"M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719",key:"1sd12s"}]]);e.s(["MessageCircle",()=>t],94983)},84614,e=>{"use strict";let t=(0,e.i(75254).default)("user",[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]]);e.s(["User",()=>t],84614)},46798,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(74080),s=e.i(75157);function n({children:e,content:n,side:i="right",className:l,delay:o=0}){let[c,d]=(0,a.useState)(!1),[u,h]=(0,a.useState)(!1),x=(0,a.useRef)(null),[f,m]=(0,a.useState)({x:0,y:0}),[p,g]=(0,a.useState)(!1),v=(0,a.useRef)(null),b=(0,a.useRef)(null);(0,a.useEffect)(()=>(h(!0),()=>{x.current&&clearTimeout(x.current)}),[]);let y=(0,a.useCallback)(()=>{if(v.current&&b.current){let e=v.current.getBoundingClientRect(),t=b.current.getBoundingClientRect(),a=0,r=0;switch(i){case"top":a=e.left+e.width/2-t.width/2,r=e.top-t.height-10;break;case"bottom":a=e.left+e.width/2-t.width/2,r=e.bottom+10;break;case"left":a=e.left-t.width-10,r=e.top+e.height/2-t.height/2;break;default:a=e.right+10,r=e.top+e.height/2-t.height/2}m({x:a,y:r}),g(!0)}},[i]);return(0,a.useLayoutEffect)(()=>{if(!c)return void g(!1);y();let e=()=>y();return window.addEventListener("resize",e),window.addEventListener("scroll",e,!0),()=>{window.removeEventListener("resize",e),window.removeEventListener("scroll",e,!0)}},[c,y]),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("div",{ref:v,onMouseEnter:()=>{o>0?x.current=setTimeout(()=>d(!0),o):d(!0)},onMouseLeave:()=>{x.current&&(clearTimeout(x.current),x.current=null),d(!1)},className:l,children:e}),c&&u?(0,r.createPortal)((0,t.jsx)("div",{ref:b,className:"fixed z-[9999] pointer-events-none",style:{left:f.x,top:f.y,visibility:p?"visible":"hidden"},children:(0,t.jsx)("div",{className:(0,s.cn)("transition-all duration-150 ease-out",p?"opacity-100 scale-100":"opacity-0 scale-95","right"===i&&(p?"translate-x-0":"-translate-x-2"),"left"===i&&(p?"translate-x-0":"translate-x-2"),"top"===i&&(p?"translate-y-0":"translate-y-2"),"bottom"===i&&(p?"translate-y-0":"-translate-y-2")),children:(0,t.jsxs)("div",{className:"relative bg-[#1a1a1a] text-white text-sm font-medium px-3 py-1.5 rounded-[4px] whitespace-nowrap shadow-xl shadow-black/25",children:[n,"right"===i&&(0,t.jsx)("div",{className:"absolute -left-[7px] top-1/2 -translate-y-1/2",children:(0,t.jsx)("div",{className:"w-0 h-0 border-t-[8px] border-t-transparent border-b-[8px] border-b-transparent border-r-[8px] border-r-[#1a1a1a]"})}),"left"===i&&(0,t.jsx)("div",{className:"absolute -right-[7px] top-1/2 -translate-y-1/2",children:(0,t.jsx)("div",{className:"w-0 h-0 border-t-[8px] border-t-transparent border-b-[8px] border-b-transparent border-l-[8px] border-l-[#1a1a1a]"})}),"top"===i&&(0,t.jsx)("div",{className:"absolute -bottom-[7px] left-1/2 -translate-x-1/2",children:(0,t.jsx)("div",{className:"w-0 h-0 border-l-[8px] border-l-transparent border-r-[8px] border-r-transparent border-t-[8px] border-t-[#1a1a1a]"})}),"bottom"===i&&(0,t.jsx)("div",{className:"absolute -top-[7px] left-1/2 -translate-x-1/2",children:(0,t.jsx)("div",{className:"w-0 h-0 border-l-[8px] border-l-transparent border-r-[8px] border-r-transparent border-b-[8px] border-b-[#1a1a1a]"})})]})})}),document.body):null]})}e.s(["Tooltip",()=>n])},19009,e=>{"use strict";var t=e.i(83599);let a=e=>fetch(e).then(e=>e.json());function r(){let{data:e,mutate:r,isLoading:s}=(0,t.default)("/api/settings",a,{revalidateOnFocus:!0,dedupingInterval:5e3}),n=e?.displayName||"";return{displayName:n,avatarUrl:e?.avatarPath?`/api/settings/avatar?v=${encodeURIComponent(e.avatarPath)}`:null,tooltips:e?.tooltips!=="false",isLoading:s,refresh:()=>r()}}e.s(["useUserSettings",()=>r])},99676,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(75157);let s=(0,a.forwardRef)(({className:e,size:a="md",status:s,statusPulse:n,children:i,...l},o)=>(0,t.jsxs)("div",{className:"relative inline-block shrink-0",children:[(0,t.jsx)("div",{className:(0,r.cn)("relative flex shrink-0 overflow-hidden rounded-[4px] bg-surface border border-border",{"h-9 w-9":"sm"===a,"h-10 w-10":"md"===a,"h-12 w-12":"lg"===a},e),ref:o,...l,children:i}),s&&(0,t.jsx)("span",{className:(0,r.cn)("absolute block rounded-full ring-2 ring-background",{"h-2.5 w-2.5 -bottom-0.5 -right-0.5":"sm"===a,"h-3 w-3 -bottom-0.5 -right-0.5":"md"===a,"h-3.5 w-3.5 -bottom-0.5 -right-0.5":"lg"===a},{"bg-success":"online"===s,"bg-foreground-muted":"offline"===s,"bg-error":"busy"===s,"bg-warning":"away"===s},n&&"animate-pulse")})]}));s.displayName="Avatar";let n=(0,a.forwardRef)(({className:e,alt:a,...s},n)=>(0,t.jsx)("img",{className:(0,r.cn)("aspect-square h-full w-full object-cover",e),alt:a,ref:n,...s}));n.displayName="AvatarImage";let i=(0,a.forwardRef)(({className:e,...a},s)=>(0,t.jsx)("span",{className:(0,r.cn)("flex h-full w-full items-center justify-center bg-surface text-foreground-secondary font-medium text-sm",e),ref:s,...a}));i.displayName="AvatarFallback",e.s(["Avatar",()=>s,"AvatarFallback",()=>i,"AvatarImage",()=>n])},94037,60289,97250,91799,39616,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(63178),s=e.i(75254);let n=(0,s.default)("layout-dashboard",[["rect",{width:"7",height:"9",x:"3",y:"3",rx:"1",key:"10lvy0"}],["rect",{width:"7",height:"5",x:"14",y:"3",rx:"1",key:"16une8"}],["rect",{width:"7",height:"9",x:"14",y:"12",rx:"1",key:"1hutg5"}],["rect",{width:"7",height:"5",x:"3",y:"16",rx:"1",key:"ldoo1y"}]]);e.s(["LayoutDashboard",()=>n],60289);var i=e.i(94983),l=e.i(84614);let o=(0,s.default)("sun",[["circle",{cx:"12",cy:"12",r:"4",key:"4exip2"}],["path",{d:"M12 2v2",key:"tus03m"}],["path",{d:"M12 20v2",key:"1lh1kg"}],["path",{d:"m4.93 4.93 1.41 1.41",key:"149t6j"}],["path",{d:"m17.66 17.66 1.41 1.41",key:"ptbguv"}],["path",{d:"M2 12h2",key:"1t8f8n"}],["path",{d:"M20 12h2",key:"1q8mjw"}],["path",{d:"m6.34 17.66-1.41 1.41",key:"1m8zz5"}],["path",{d:"m19.07 4.93-1.41 1.41",key:"1shlcs"}]]);e.s(["Sun",()=>o],97250);let c=(0,s.default)("moon",[["path",{d:"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",key:"kfwtm"}]]);e.s(["Moon",()=>c],91799);let d=(0,s.default)("settings",[["path",{d:"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915",key:"1i5ecw"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);e.s(["Settings",()=>d],39616);var u=e.i(75157);function h({className:e}){return(0,t.jsx)("svg",{viewBox:"0 0 512 512",xmlns:"http://www.w3.org/2000/svg",className:(0,u.cn)("fill-current",e),children:(0,t.jsxs)("g",{children:[(0,t.jsx)("path",{d:"m124.809 408.11h262.382v103.89h-262.382z"}),(0,t.jsx)("path",{d:"m273.162 123.55h134.646l-34.459-44.772 33.515-46.459h-133.702v-32.319h-29.985v196.446h29.985z"}),(0,t.jsx)("path",{d:"m347.45 281.985h-50.335v-56.54h-79.107v56.54h-53.643v-56.54h-91.962v111.141c0 23.448 19.075 42.523 42.523 42.523h282.147c23.448 0 42.524-19.075 42.524-42.523v-111.14h-92.147z"})]})})}var x=e.i(46798),f=e.i(18566),m=e.i(19009),p=e.i(57401),g=e.i(99676);let v=[{id:"dashboard",label:"Dashboard",icon:n,href:"/"},{id:"chat",label:"Chat",icon:i.MessageCircle,href:"/chat"}];function b({activeItem:e="dashboard",onNavigate:a,className:r,variant:s="solid"}){let n=(0,f.usePathname)(),i=(0,f.useRouter)(),l=!a,{tooltips:o}=(0,m.useUserSettings)(),c=n&&"/"!==n&&n.startsWith("/chat")?"chat":"dashboard",d=l?c:e;return(0,t.jsxs)("aside",{className:(0,u.cn)("fixed top-[20px] left-[24px] bottom-[20px] flex flex-col z-40 rounded-[var(--radius-md)] w-14","glass"===s?"glass":"bg-surface border border-border",r),children:[(0,t.jsx)("div",{className:"flex items-center justify-center pt-5 pb-[60px]",children:(0,t.jsx)("button",{type:"button","aria-label":"Go to Dashboard",onClick:()=>l?i.push("/"):a?.("dashboard"),className:"flex items-center justify-center transition-opacity hover:opacity-85 cursor-pointer",children:(0,t.jsx)(h,{className:"h-[36px] w-[36px] min-h-[36px] min-w-[36px] shrink-0 text-[var(--logo-color)] -mt-[3px]"})})}),(0,t.jsx)("nav",{className:"flex-1 space-y-1 px-2",children:v.map(e=>{let r=d===e.id,s=(0,t.jsx)("button",{onClick:()=>l?i.push(e.href):a?.(e.id),className:(0,u.cn)("flex items-center justify-center w-full rounded-[4px] p-2.5 cursor-pointer",r?"bg-accent/10 text-accent":"text-foreground-secondary hover:text-foreground hover:bg-surface-hover"),children:(0,t.jsx)(e.icon,{className:"h-5 w-5 shrink-0"})});return o?(0,t.jsx)(x.Tooltip,{content:e.label,side:"right",children:s},e.id):(0,t.jsx)("div",{children:s},e.id)})}),(0,t.jsx)(y,{})]})}function y(){let[e,s]=(0,a.useState)(!1),{theme:n,setTheme:i}=(0,r.useTheme)(),[u,h]=(0,a.useState)(!1),x=(0,f.useRouter)(),{avatarUrl:v,isLoading:b}=(0,m.useUserSettings)(),{getStatus:y}=(0,p.useAgentStatus)(),w=y(p.USER_STATUS_ID),j=(0,a.useRef)(null);(0,a.useEffect)(()=>{h(!0)},[]),(0,a.useEffect)(()=>{function e(e){j.current&&!j.current.contains(e.target)&&s(!1)}return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[]);let k="dark"===n;return(0,t.jsxs)("div",{ref:j,className:"relative flex justify-center pb-[8px]",children:[(0,t.jsx)("button",{onClick:()=>s(!e),className:"group flex items-center justify-center rounded-[4px] cursor-pointer transition-opacity",children:(0,t.jsx)(g.Avatar,{size:"sm",status:"active"===w?"online":"offline",children:b?(0,t.jsx)(g.AvatarFallback,{className:"skeleton"}):v?(0,t.jsx)(g.AvatarImage,{src:v,alt:"You",className:"grayscale group-hover:grayscale-0 transition-all duration-200"}):(0,t.jsx)(g.AvatarFallback,{className:"text-foreground-secondary",children:(0,t.jsx)(l.User,{className:"h-5 w-5"})})})}),e&&(0,t.jsxs)("div",{className:"absolute left-[calc(100%+8px)] bottom-0 w-48 rounded-[var(--radius-md)] bg-surface border border-border shadow-xl py-1 z-50",children:[(0,t.jsxs)("button",{onClick:()=>{s(!1),x.push("/settings")},className:"flex items-center gap-3 w-full px-4 py-2.5 text-sm text-foreground-secondary hover:text-foreground hover:bg-surface-hover cursor-pointer",children:[(0,t.jsx)(d,{className:"h-4 w-4"}),"Settings"]}),u&&(0,t.jsxs)("button",{onClick:()=>{i(k?"light":"dark"),s(!1)},className:"flex items-center gap-3 w-full px-4 py-2.5 text-sm text-foreground-secondary hover:text-foreground hover:bg-surface-hover cursor-pointer",children:[k?(0,t.jsx)(o,{className:"h-4 w-4"}):(0,t.jsx)(c,{className:"h-4 w-4"}),k?"Light mode":"Dark mode"]})]})]})}e.s(["Sidebar",()=>b],94037)},68553,e=>{"use strict";let t=(0,e.i(75254).default)("camera",[["path",{d:"M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z",key:"18u6gg"}],["circle",{cx:"12",cy:"13",r:"3",key:"1vg3eu"}]]);e.s(["Camera",()=>t],68553)},52683,e=>{"use strict";var t=e.i(18050),a=e.i(71645),r=e.i(31245),s=e.i(75254);let n=(0,s.default)("wifi",[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M2 8.82a15 15 0 0 1 20 0",key:"dnpr2z"}],["path",{d:"M5 12.859a10 10 0 0 1 14 0",key:"1x1e6c"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}]]);var i=e.i(57212);let l=(0,s.default)("crown",[["path",{d:"M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z",key:"1vdc57"}],["path",{d:"M5 21h14",key:"11awu3"}]]);var o=e.i(16715),c=e.i(31278),d=e.i(63209),u=e.i(68553),h=e.i(94037),x=e.i(41613),f=e.i(15288),m=e.i(87486),p=e.i(99676),g=e.i(75157),v=e.i(29143),b=e.i(57401),y=e.i(40871);function w({agent:e,isPrimary:r,isConnected:s,onAvatarUpdated:n}){let i=(0,a.useRef)(null),[o,d]=(0,a.useState)(!1),{getStatus:h}=(0,b.useAgentStatus)(),x=h(e.id),v=(0,a.useCallback)(()=>{s&&i.current?.click()},[s]),y=(0,a.useCallback)(async t=>{let a=t.target.files?.[0];if(a){if(t.target.value="",a.size>5242880)return void alert("Image too large (max 5MB)");d(!0);try{let t=new FormData;t.append("avatar",a);let r=await fetch(`/api/openclaw/agents/${e.id}/avatar`,{method:"POST",body:t}),s=await r.json();if(!r.ok)return void alert(s.error||"Failed to update avatar");n()}catch{alert("Failed to upload avatar")}finally{d(!1)}}},[e.id,n]);return(0,t.jsx)(f.Card,{variant:"bordered",className:(0,g.cn)("py-4 pl-5 pr-4 transition-colors min-h-[80px] flex items-center",s?"hover:border-border-hover":"opacity-60"),children:(0,t.jsxs)("div",{className:"flex items-center justify-between flex-1",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsxs)("button",{type:"button",onClick:v,disabled:!s||o,className:"relative group rounded-[4px] focus:outline-none focus-visible:ring-2 focus-visible:ring-accent leading-[0]",title:s?"Click to change avatar":void 0,children:[(0,t.jsx)(p.Avatar,{size:"md",status:function(e,t){if(!t)return"offline";switch(e){case"thinking":return"away";case"active":return"online";default:return"offline"}}(x,s),statusPulse:"thinking"===x,children:e.avatar?(0,t.jsx)(p.AvatarImage,{src:e.avatar,alt:e.name,className:(0,g.cn)(!s&&"grayscale")}):(0,t.jsx)(p.AvatarFallback,{children:e.emoji||e.name.slice(0,2).toUpperCase()})}),s&&!o&&(0,t.jsx)("div",{className:"absolute inset-0 rounded-[4px] bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center",children:(0,t.jsx)(u.Camera,{className:"h-4 w-4 text-white"})}),o&&(0,t.jsx)("div",{className:"absolute inset-0 rounded-[4px] bg-black/50 flex items-center justify-center",children:(0,t.jsx)(c.Loader2,{className:"h-4 w-4 text-white animate-spin"})})]}),(0,t.jsx)("input",{ref:i,type:"file",accept:"image/png,image/jpeg,image/webp,image/gif",className:"hidden",onChange:y}),(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:e.name}),r&&(0,t.jsxs)("span",{className:"flex items-center gap-1 text-xs text-accent",children:[(0,t.jsx)(l,{className:"h-3 w-3"}),"Primary"]})]}),(0,t.jsx)("p",{className:"text-xs text-foreground-muted",children:s?e.description||"OpenClaw Agent":"Unreachable"})]})]}),(0,t.jsx)(m.Badge,{variant:function(e,t){if(!t)return"outline";switch(e){case"thinking":return"warning";case"active":return"success";default:return"outline"}}(x,s),size:"sm",children:function(e,t){if(!t)return"Offline";switch(e){case"thinking":return"Thinking";case"active":return"Active";default:return"Idle"}}(x,s)})]})})}function j({isConnected:e,isLoading:a,isConfigured:r,serverVersion:s,latency:l,error:d,onRefresh:u}){return(0,t.jsx)(f.Card,{variant:"bordered",className:"mb-8",children:(0,t.jsxs)(f.CardContent,{className:"flex items-center justify-between",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[a?(0,t.jsx)(c.Loader2,{className:"h-5 w-5 text-foreground-muted animate-spin"}):e?(0,t.jsx)(n,{className:"h-5 w-5 text-success"}):(0,t.jsx)(i.WifiOff,{className:"h-5 w-5 text-error"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:"OpenClaw Gateway"}),(0,t.jsx)("p",{className:"text-xs text-foreground-muted",children:(()=>{if(a)return"Connecting to Gateway...";if(!r)return"OpenClaw not installed — visit openclaw.ai";if(e){let e=["Connected"];return s&&(e[0]=`Connected to OpenClaw ${s}`),l&&e.push(`${l}ms`),e.join(" · ")}return d||"Not connected"})()})]})]}),(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("button",{onClick:u,className:"p-1.5 rounded-md text-foreground-muted hover:text-foreground hover:bg-surface-hover transition-colors",title:"Refresh connection",children:(0,t.jsx)(o.RefreshCw,{className:"h-4 w-4"})}),a?(0,t.jsx)(m.Badge,{variant:"outline",children:"Connecting..."}):(0,t.jsx)(m.Badge,{variant:e?"success":r?"error":"outline",children:e?"Connected":r?"Disconnected":"Not Installed"})]})]})})}function k(){return(0,t.jsx)("div",{className:"grid gap-3",children:[1,2,3].map(e=>(0,t.jsx)(f.Card,{variant:"bordered",className:"p-4 min-h-[80px] flex items-center",children:(0,t.jsxs)("div",{className:"flex items-center justify-between flex-1",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)("div",{className:"skeleton h-10 w-10 rounded-full"}),(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsx)("div",{className:"skeleton h-4 w-24 rounded"}),(0,t.jsx)("div",{className:"skeleton h-3 w-32 rounded"})]})]}),(0,t.jsx)("div",{className:"skeleton h-5 w-14 rounded-full"})]})},e))})}function N({isConfigured:e}){return(0,t.jsx)(f.Card,{variant:"bordered",className:"p-8",children:(0,t.jsx)("div",{className:"flex flex-col items-center text-center gap-3",children:e?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(d.AlertCircle,{className:"h-8 w-8 text-foreground-muted"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:"No agents discovered"}),(0,t.jsx)("p",{className:"text-xs text-foreground-muted mt-1",children:"Make sure OpenClaw Gateway is running and agents are configured."})]})]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.Bot,{className:"h-8 w-8 text-foreground-muted"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:"Welcome to Castle"}),(0,t.jsxs)("p",{className:"text-xs text-foreground-muted mt-1",children:["Run ",(0,t.jsx)("code",{className:"px-1 py-0.5 bg-surface-hover rounded text-xs",children:"castle setup"})," to connect to your OpenClaw Gateway."]})]})]})})})}function C(){let{status:e,isLoading:a,isConnected:s,isConfigured:n,latency:i,serverVersion:l,agents:o,agentsLoading:c,refresh:d}=(0,v.useOpenClaw)();return(0,t.jsxs)("div",{className:"min-h-screen bg-background",children:[(0,t.jsx)(h.Sidebar,{variant:"solid"}),(0,t.jsxs)("main",{className:"min-h-screen ml-[80px]",children:[(0,t.jsxs)("div",{className:"px-8 py-5 flex items-center justify-between gap-4 border-b border-border",children:[(0,t.jsx)(x.PageHeader,{title:"Castle",subtitle:"The multi-agent workspace"}),(0,t.jsx)(y.SearchTrigger,{})]}),(0,t.jsxs)("div",{className:"p-8 max-w-4xl",children:[(0,t.jsx)(j,{isConnected:s,isLoading:a,isConfigured:n,serverVersion:l,latency:i,error:e?.error,onRefresh:d}),(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between",children:[(0,t.jsxs)("h2",{className:"text-lg font-semibold text-foreground flex items-center gap-2",children:[(0,t.jsx)(r.Bot,{className:"h-5 w-5 text-foreground-secondary"}),"Agents"]}),!a&&o.length>0&&(0,t.jsxs)("span",{className:"text-sm text-foreground-muted",children:[o.length," agent",1!==o.length?"s":""," discovered"]})]}),c||a&&0===o.length?(0,t.jsx)(k,{}):o.length>0?(0,t.jsx)("div",{className:"grid gap-3",children:o.map((e,a)=>(0,t.jsx)(w,{agent:e,isPrimary:0===a,isConnected:s,onAvatarUpdated:d},e.id))}):(0,t.jsx)(N,{isConfigured:n})]})]})]})]})}e.s(["default",()=>C],52683)}]);
package/bin/castle.js CHANGED
@@ -12,13 +12,13 @@ if (module.enableCompileCache && !process.env.NODE_DISABLE_COMPILE_CACHE) {
12
12
  // Bootstrap tsx from the package's own node_modules so it works
13
13
  // regardless of the user's current working directory.
14
14
  import { dirname, resolve } from "path";
15
- import { fileURLToPath } from "url";
15
+ import { fileURLToPath, pathToFileURL } from "url";
16
16
 
17
17
  const __dirname = dirname(fileURLToPath(import.meta.url));
18
18
 
19
19
  if (!process.env._CASTLE_CLI) {
20
20
  const { execFileSync } = await import("child_process");
21
- const tsxImport = resolve(__dirname, "..", "node_modules", "tsx", "dist", "esm", "index.mjs");
21
+ const tsxImport = pathToFileURL(resolve(__dirname, "..", "node_modules", "tsx", "dist", "esm", "index.mjs")).href;
22
22
  try {
23
23
  execFileSync(process.execPath, ["--import", tsxImport, ...process.argv.slice(1)], {
24
24
  stdio: "inherit",