runcastle 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/runcastle.js CHANGED
@@ -4897,7 +4897,7 @@ async function sandcastleImageProbe(exec, imageName) {
4897
4897
  tier: 2,
4898
4898
  status: "missing",
4899
4899
  detail: `image ${imageName} not found locally`,
4900
- fix: "Build it: sandcastle docker build-image (nothing builds it for you)."
4900
+ fix: 'Start runcastle and click "Build image" on the Enable AFK burns card \u2014 it builds this for you (one click). Only needed for AFK/sandboxed burns.'
4901
4901
  };
4902
4902
  }
4903
4903
  return {
@@ -4906,7 +4906,7 @@ async function sandcastleImageProbe(exec, imageName) {
4906
4906
  tier: 2,
4907
4907
  status: "missing",
4908
4908
  detail: "no container runtime available to inspect the image",
4909
- fix: "Install a container runtime first, then build: sandcastle docker build-image"
4909
+ fix: "Install a container runtime (Docker or Podman) first, then build the image from the Enable AFK burns card in the app."
4910
4910
  };
4911
4911
  }
4912
4912
  function afkTokenProbe(env) {
@@ -5055,10 +5055,38 @@ async function resolveRuntime(exec, preferred) {
5055
5055
  return other;
5056
5056
  return preferred;
5057
5057
  }
5058
+ function resolveSandcastleBin() {
5059
+ try {
5060
+ const mainUrl = import.meta.resolve("@ai-hero/sandcastle");
5061
+ let dir = dirname7(fileURLToPath6(mainUrl));
5062
+ for (let hops = 0;hops < 6; hops++) {
5063
+ const manifestPath = join14(dir, "package.json");
5064
+ if (existsSync16(manifestPath)) {
5065
+ const manifest = JSON.parse(readFileSync7(manifestPath, "utf8"));
5066
+ if (manifest.name === "@ai-hero/sandcastle" && manifest.bin?.sandcastle) {
5067
+ return join14(dir, manifest.bin.sandcastle);
5068
+ }
5069
+ }
5070
+ const parent = dirname7(dir);
5071
+ if (parent === dir)
5072
+ break;
5073
+ dir = parent;
5074
+ }
5075
+ return null;
5076
+ } catch {
5077
+ return null;
5078
+ }
5079
+ }
5058
5080
  function terminalSpec(kind, opts) {
5059
5081
  if (kind === "setup-token")
5060
5082
  return { cmd: "claude", args: ["setup-token"] };
5061
- return { cmd: "sandcastle", args: [opts.runtime, "build-image", "--image-name", opts.imageName] };
5083
+ if (!opts.sandcastleBin) {
5084
+ throw new NotFoundError("The bundled sandcastle CLI (@ai-hero/sandcastle) could not be located \u2014 reinstall runcastle.");
5085
+ }
5086
+ return {
5087
+ cmd: "node",
5088
+ args: [opts.sandcastleBin, opts.runtime, "build-image", "--image-name", opts.imageName]
5089
+ };
5062
5090
  }
5063
5091
  function sandcastleTemplateDir() {
5064
5092
  return resolveAsset(ASSET_ENV.sandcastleTemplate, fileURLToPath6(new URL("../assets/sandcastle", import.meta.url)));
@@ -5132,7 +5160,8 @@ var init_setup2 = __esm(() => {
5132
5160
  const preferred = ctx.config.sandbox === "podman" ? "podman" : "docker";
5133
5161
  const runtime = await resolveRuntime(exec, preferred);
5134
5162
  const imageName = ctx.config.sandboxImage ?? "sandcastle:runcastle";
5135
- const spec = terminalSpec(input.kind, { runtime, imageName });
5163
+ const sandcastleBin = input.kind === "build-image" ? resolveSandcastleBin() ?? undefined : undefined;
5164
+ const spec = terminalSpec(input.kind, { runtime, imageName, sandcastleBin });
5136
5165
  const sessionId = newId("setup");
5137
5166
  const cwd = input.kind === "build-image" ? prepareSandboxBuildContext() : process.cwd();
5138
5167
  const resolved = resolveExecutable(spec.cmd);
package/index.js CHANGED
@@ -4896,7 +4896,7 @@ async function sandcastleImageProbe(exec, imageName) {
4896
4896
  tier: 2,
4897
4897
  status: "missing",
4898
4898
  detail: `image ${imageName} not found locally`,
4899
- fix: "Build it: sandcastle docker build-image (nothing builds it for you)."
4899
+ fix: 'Start runcastle and click "Build image" on the Enable AFK burns card \u2014 it builds this for you (one click). Only needed for AFK/sandboxed burns.'
4900
4900
  };
4901
4901
  }
4902
4902
  return {
@@ -4905,7 +4905,7 @@ async function sandcastleImageProbe(exec, imageName) {
4905
4905
  tier: 2,
4906
4906
  status: "missing",
4907
4907
  detail: "no container runtime available to inspect the image",
4908
- fix: "Install a container runtime first, then build: sandcastle docker build-image"
4908
+ fix: "Install a container runtime (Docker or Podman) first, then build the image from the Enable AFK burns card in the app."
4909
4909
  };
4910
4910
  }
4911
4911
  function afkTokenProbe(env) {
@@ -5054,10 +5054,38 @@ async function resolveRuntime(exec, preferred) {
5054
5054
  return other;
5055
5055
  return preferred;
5056
5056
  }
5057
+ function resolveSandcastleBin() {
5058
+ try {
5059
+ const mainUrl = import.meta.resolve("@ai-hero/sandcastle");
5060
+ let dir = dirname7(fileURLToPath6(mainUrl));
5061
+ for (let hops = 0;hops < 6; hops++) {
5062
+ const manifestPath = join14(dir, "package.json");
5063
+ if (existsSync16(manifestPath)) {
5064
+ const manifest = JSON.parse(readFileSync7(manifestPath, "utf8"));
5065
+ if (manifest.name === "@ai-hero/sandcastle" && manifest.bin?.sandcastle) {
5066
+ return join14(dir, manifest.bin.sandcastle);
5067
+ }
5068
+ }
5069
+ const parent = dirname7(dir);
5070
+ if (parent === dir)
5071
+ break;
5072
+ dir = parent;
5073
+ }
5074
+ return null;
5075
+ } catch {
5076
+ return null;
5077
+ }
5078
+ }
5057
5079
  function terminalSpec(kind, opts) {
5058
5080
  if (kind === "setup-token")
5059
5081
  return { cmd: "claude", args: ["setup-token"] };
5060
- return { cmd: "sandcastle", args: [opts.runtime, "build-image", "--image-name", opts.imageName] };
5082
+ if (!opts.sandcastleBin) {
5083
+ throw new NotFoundError("The bundled sandcastle CLI (@ai-hero/sandcastle) could not be located \u2014 reinstall runcastle.");
5084
+ }
5085
+ return {
5086
+ cmd: "node",
5087
+ args: [opts.sandcastleBin, opts.runtime, "build-image", "--image-name", opts.imageName]
5088
+ };
5061
5089
  }
5062
5090
  function sandcastleTemplateDir() {
5063
5091
  return resolveAsset(ASSET_ENV.sandcastleTemplate, fileURLToPath6(new URL("../assets/sandcastle", import.meta.url)));
@@ -5131,7 +5159,8 @@ var init_setup2 = __esm(() => {
5131
5159
  const preferred = ctx.config.sandbox === "podman" ? "podman" : "docker";
5132
5160
  const runtime = await resolveRuntime(exec, preferred);
5133
5161
  const imageName = ctx.config.sandboxImage ?? "sandcastle:runcastle";
5134
- const spec = terminalSpec(input.kind, { runtime, imageName });
5162
+ const sandcastleBin = input.kind === "build-image" ? resolveSandcastleBin() ?? undefined : undefined;
5163
+ const spec = terminalSpec(input.kind, { runtime, imageName, sandcastleBin });
5135
5164
  const sessionId = newId("setup");
5136
5165
  const cwd = input.kind === "build-image" ? prepareSandboxBuildContext() : process.cwd();
5137
5166
  const resolved = resolveExecutable(spec.cmd);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runcastle",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "runcastle": "./bin/runcastle.js"