@pleri/olam-cli 0.1.101 → 0.1.102

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -21871,7 +21871,7 @@ var WorldRegistry = class {
21871
21871
  this.db.pragma("foreign_keys = ON");
21872
21872
  this.db.exec(CREATE_TABLE);
21873
21873
  this.db.exec(CREATE_META);
21874
- for (const col of ["readiness_chain TEXT", "expected_services TEXT", "app_port_urls TEXT"]) {
21874
+ for (const col of ["readiness_chain TEXT", "expected_services TEXT", "app_port_urls TEXT", "tailscale_paths TEXT"]) {
21875
21875
  try {
21876
21876
  this.db.exec(`ALTER TABLE worlds ADD COLUMN ${col}`);
21877
21877
  } catch {
@@ -21989,6 +21989,27 @@ var WorldRegistry = class {
21989
21989
  const max = rows.length > 0 ? rows[rows.length - 1].port_offset : -100;
21990
21990
  return max + 100;
21991
21991
  }
21992
+ /**
21993
+ * Persist tailscale serve paths registered for a world.
21994
+ * Paths are stored as a JSON array in the tailscale_paths column.
21995
+ */
21996
+ storeTailscalePaths(worldId, paths) {
21997
+ this.db.prepare("UPDATE worlds SET tailscale_paths = ?, updated_at = ? WHERE id = ?").run(JSON.stringify(paths), (/* @__PURE__ */ new Date()).toISOString(), worldId);
21998
+ }
21999
+ /**
22000
+ * Load tailscale serve paths for a world. Returns [] when none stored or
22001
+ * column absent (pre-migration rows).
22002
+ */
22003
+ loadTailscalePaths(worldId) {
22004
+ const row = this.db.prepare("SELECT tailscale_paths FROM worlds WHERE id = ?").get(worldId);
22005
+ if (!row?.tailscale_paths)
22006
+ return [];
22007
+ try {
22008
+ return JSON.parse(row.tailscale_paths);
22009
+ } catch {
22010
+ return [];
22011
+ }
22012
+ }
21992
22013
  close() {
21993
22014
  this.db.close();
21994
22015
  }
@@ -23074,7 +23095,7 @@ var createServiceContainer = async (docker, worldId, worldName, service, portOff
23074
23095
  await container.start();
23075
23096
  return container;
23076
23097
  };
23077
- var DEFAULT_IMAGE2 = "olam-devbox:latest";
23098
+ var DEFAULT_IMAGE2 = "olam-devbox:base";
23078
23099
  var CONTROL_PLANE_PORT = 8080;
23079
23100
  var HOST_CONTROL_PLANE_BASE2 = 19080;
23080
23101
  var HOST_APP_PORT_BASE_DELTA = 1e4;
@@ -23299,6 +23320,46 @@ var execInContainer = async (container, cmd, opts) => {
23299
23320
  };
23300
23321
  };
23301
23322
 
23323
+ // ../adapters/dist/docker/host.js
23324
+ import { spawnSync as spawnSync2 } from "node:child_process";
23325
+ function resolveDockerHostOptions(spawnImpl = spawnSync2) {
23326
+ if (process.env.DOCKER_HOST && process.env.DOCKER_HOST.length > 0) {
23327
+ return {};
23328
+ }
23329
+ try {
23330
+ const result = spawnImpl("docker", ["context", "inspect", "--format", "{{.Endpoints.docker.Host}}"], { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
23331
+ if (result.status === 0) {
23332
+ const host = (result.stdout ?? "").trim();
23333
+ if (host.startsWith("unix://")) {
23334
+ return { socketPath: host.slice("unix://".length) };
23335
+ }
23336
+ if (host.startsWith("npipe://")) {
23337
+ return { socketPath: host.slice("npipe://".length) };
23338
+ }
23339
+ if (host.startsWith("tcp://") || host.startsWith("http://") || host.startsWith("https://")) {
23340
+ const url = new URL(host.startsWith("tcp://") ? host.replace("tcp://", "http://") : host);
23341
+ const protocol = host.startsWith("https://") ? "https" : "http";
23342
+ const port = url.port ? parseInt(url.port, 10) : protocol === "https" ? 2376 : 2375;
23343
+ return { host: url.hostname, port, protocol };
23344
+ }
23345
+ }
23346
+ } catch {
23347
+ }
23348
+ return { socketPath: "/var/run/docker.sock" };
23349
+ }
23350
+ function describeDockerEndpoint(opts) {
23351
+ if (!opts || Object.keys(opts).length === 0) {
23352
+ return process.env.DOCKER_HOST ? `DOCKER_HOST=${process.env.DOCKER_HOST}` : "/var/run/docker.sock (default)";
23353
+ }
23354
+ if (opts.socketPath) {
23355
+ return `socketPath=${opts.socketPath}`;
23356
+ }
23357
+ if (opts.host) {
23358
+ return `${opts.protocol ?? "http"}://${opts.host}:${opts.port ?? "?"}`;
23359
+ }
23360
+ return JSON.stringify(opts);
23361
+ }
23362
+
23302
23363
  // ../adapters/dist/docker/provider.js
23303
23364
  var DockerWorld = class {
23304
23365
  id;
@@ -23351,9 +23412,11 @@ var DockerProvider = class extends ComputeProvider {
23351
23412
  maxLifetimeMinutes: null
23352
23413
  };
23353
23414
  docker;
23415
+ dockerOptions;
23354
23416
  constructor(dockerOptions) {
23355
23417
  super();
23356
23418
  this.docker = new Dockerode(dockerOptions);
23419
+ this.dockerOptions = dockerOptions;
23357
23420
  }
23358
23421
  // -----------------------------------------------------------------------
23359
23422
  // createWorld
@@ -23362,8 +23425,10 @@ var DockerProvider = class extends ComputeProvider {
23362
23425
  const { id, name, services = [], portOffset = 0 } = config2;
23363
23426
  try {
23364
23427
  await this.docker.ping();
23365
- } catch {
23366
- throw new Error("Docker daemon is not available. Ensure Docker is running and accessible.");
23428
+ } catch (err) {
23429
+ const where = describeDockerEndpoint(this.dockerOptions);
23430
+ const cause = err instanceof Error ? err.message : String(err);
23431
+ throw new Error(`Docker daemon is not available at ${where}. Ensure Docker is running and the resolved endpoint is correct. (underlying: ${cause})`);
23367
23432
  }
23368
23433
  await createNetwork(this.docker, id, name);
23369
23434
  for (const svc of services) {
@@ -24300,7 +24365,7 @@ function selectComputeProvider(config2, env) {
24300
24365
  "Compute provider 'e2b' is not implemented. Use 'docker', 'ssh', or 'cloudflare'."
24301
24366
  );
24302
24367
  case "docker":
24303
- return new DockerProvider();
24368
+ return new DockerProvider(resolveDockerHostOptions());
24304
24369
  default: {
24305
24370
  const exhaustive = kind;
24306
24371
  throw new Error(`Unknown compute provider: ${String(exhaustive)}`);
@@ -27906,7 +27971,7 @@ function decideWorkspaceMatch(input) {
27906
27971
  }
27907
27972
 
27908
27973
  // ../core/dist/util/open-url.js
27909
- import { spawnSync as spawnSync2 } from "node:child_process";
27974
+ import { spawnSync as spawnSync3 } from "node:child_process";
27910
27975
  function openUrl(url) {
27911
27976
  if (process.env.CI === "true") {
27912
27977
  return { opened: false, reason: "CI environment detected" };
@@ -27930,7 +27995,7 @@ function openUrl(url) {
27930
27995
  args = [url];
27931
27996
  }
27932
27997
  try {
27933
- const result = spawnSync2(cmd, args, { stdio: "ignore", timeout: 5e3 });
27998
+ const result = spawnSync3(cmd, args, { stdio: "ignore", timeout: 5e3 });
27934
27999
  if (result.error) {
27935
28000
  return { opened: false, reason: `spawn ${cmd}: ${result.error.message}` };
27936
28001
  }
@@ -31462,7 +31527,7 @@ ${stderr.split("\n").slice(0, 3).join(" ")}`);
31462
31527
  Likely cause: corrupt local image, a custom devbox image without
31463
31528
  the olam user (line 10 of devbox.Dockerfile), or NSS resolver
31464
31529
  failure under cross-arch QEMU emulation.
31465
- Remedy: docker rmi olam-devbox:latest && olam upgrade -y
31530
+ Remedy: docker rmi olam-devbox:base && olam upgrade -y
31466
31531
  (or set OLAM_DEVBOX_IMAGE to a known-good ref before \`olam create\`).
31467
31532
  PR push from inside the world will not work until this is resolved.`);
31468
31533
  return;
@@ -31716,6 +31781,71 @@ function buildManifestRuntime(worldId, repos) {
31716
31781
  }
31717
31782
  return { worldId, repos: runtimeRepos };
31718
31783
  }
31784
+ function exposeWorldOverTailscale(appPortUrls, worldId, registry2, _exec = execSync5) {
31785
+ if (process.env["OLAM_TAILSCALE_SERVE"] !== "true")
31786
+ return;
31787
+ if (appPortUrls.length === 0)
31788
+ return;
31789
+ const bin = resolveTailscaleBin(_exec);
31790
+ if (!bin) {
31791
+ console.warn("[tailscale] WARN: OLAM_TAILSCALE_SERVE=true but no tailscale binary found. Set TAILSCALE_BIN or install tailscale. Skipping serve mapping.");
31792
+ return;
31793
+ }
31794
+ const registeredPaths = [];
31795
+ for (const { repoName, hostPort } of appPortUrls) {
31796
+ const servePath = `/world/${worldId}/${repoName}`;
31797
+ try {
31798
+ _exec(`"${bin}" serve --bg --set-path=${servePath} http://localhost:${hostPort}`, {
31799
+ timeout: 1e4
31800
+ });
31801
+ console.log(`[tailscale] exposed ${worldId}/${repoName} at https://<machine>.<tailnet>/world/${worldId}/${repoName}`);
31802
+ registeredPaths.push(servePath);
31803
+ } catch (err) {
31804
+ const msg = err instanceof Error ? err.message : String(err);
31805
+ console.warn(`[tailscale] WARN: serve failed for ${repoName} (port ${hostPort}): ${msg}`);
31806
+ }
31807
+ }
31808
+ if (registeredPaths.length > 0) {
31809
+ registry2.storeTailscalePaths(worldId, registeredPaths);
31810
+ }
31811
+ }
31812
+ function cleanupWorldTailscale(worldId, registry2, _exec = execSync5) {
31813
+ const paths = registry2.loadTailscalePaths(worldId);
31814
+ if (paths.length === 0)
31815
+ return;
31816
+ const bin = resolveTailscaleBin(_exec);
31817
+ if (!bin) {
31818
+ console.warn("[tailscale] WARN: Cannot cleanup tailscale serve paths \u2014 binary not found.");
31819
+ return;
31820
+ }
31821
+ for (const servePath of paths) {
31822
+ try {
31823
+ _exec(`"${bin}" serve --bg --set-path=${servePath} off`, { timeout: 1e4 });
31824
+ console.log(`[tailscale] cleaned up serve path ${servePath}`);
31825
+ } catch (err) {
31826
+ const msg = err instanceof Error ? err.message : String(err);
31827
+ console.warn(`[tailscale] WARN: cleanup failed for ${servePath}: ${msg}`);
31828
+ }
31829
+ }
31830
+ }
31831
+ function resolveTailscaleBin(_exec = execSync5) {
31832
+ const candidates = [
31833
+ process.env["TAILSCALE_BIN"],
31834
+ "/Applications/Tailscale.app/Contents/MacOS/Tailscale",
31835
+ "/usr/local/bin/tailscale",
31836
+ "/opt/homebrew/bin/tailscale"
31837
+ ];
31838
+ for (const c of candidates) {
31839
+ if (!c)
31840
+ continue;
31841
+ try {
31842
+ _exec(`test -x "${c}"`, { timeout: 2e3 });
31843
+ return c;
31844
+ } catch {
31845
+ }
31846
+ }
31847
+ return void 0;
31848
+ }
31719
31849
  var WorldManager = class {
31720
31850
  config;
31721
31851
  provider;
@@ -32394,6 +32524,10 @@ ${opts.task}`;
32394
32524
  }
32395
32525
  } catch {
32396
32526
  }
32527
+ try {
32528
+ exposeWorldOverTailscale(appPortUrls, worldId, this.registry);
32529
+ } catch {
32530
+ }
32397
32531
  return {
32398
32532
  ...metadata,
32399
32533
  status: "running",
@@ -32441,6 +32575,10 @@ ${opts.task}`;
32441
32575
  } catch {
32442
32576
  }
32443
32577
  }
32578
+ try {
32579
+ cleanupWorldTailscale(worldId, this.registry);
32580
+ } catch {
32581
+ }
32444
32582
  try {
32445
32583
  await this.provider.destroyWorld(worldId);
32446
32584
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pleri/olam-cli",
3
- "version": "0.1.101",
3
+ "version": "0.1.102",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "olam": "./bin/olam.cjs"