omnara 1.0.1 → 1.0.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 (2) hide show
  1. package/dist/bin.js +390 -53
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -210,7 +210,7 @@ function createSseClient({
210
210
  ...options
211
211
  }) {
212
212
  let lastEventId;
213
- const sleep2 = sseSleepFn ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms)));
213
+ const sleep2 = sseSleepFn ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms)));
214
214
  const createStream = async function* () {
215
215
  let retryDelay = sseDefaultRetryDelay ?? 3e3;
216
216
  let attempt = 0;
@@ -2547,7 +2547,13 @@ var zCreateMachineRequest = z.object({
2547
2547
  });
2548
2548
  var zConnectByoMachineRequest = z.object({
2549
2549
  display_name: zResourceName,
2550
- project_ids: z.array(zProjectId).max(100)
2550
+ description: z.string().optional(),
2551
+ cwd: z.string().optional(),
2552
+ env: z.record(z.string(), z.string()).optional(),
2553
+ secret_env: z.record(z.string(), zSecretId).optional(),
2554
+ metadata: zMachineMetadata.optional(),
2555
+ project_ids: z.array(zProjectId).max(100).optional(),
2556
+ token_name: zResourceName.optional()
2551
2557
  });
2552
2558
  var zUpdateMachineRequest = z.object({
2553
2559
  cwd: z.string().optional(),
@@ -3672,7 +3678,6 @@ var zListVisibleMachinesQuery = z.object({
3672
3678
  cursor: z.string().max(1024).optional()
3673
3679
  });
3674
3680
  var zListVisibleMachinesResponse2 = zListVisibleMachinesResponse;
3675
- var zCreateMachineBody = zCreateMachineRequest;
3676
3681
  var zCreateMachineHeaders = z.object({
3677
3682
  "Idempotency-Key": z.string().min(1).max(255).optional()
3678
3683
  });
@@ -3680,6 +3685,7 @@ var zCreateMachinePath = z.object({
3680
3685
  orgID: z.string().regex(/^org_[a-z2-7]{26}$/)
3681
3686
  });
3682
3687
  var zCreateMachineResponse = zMachine;
3688
+ var zConnectByoMachineBody = zConnectByoMachineRequest;
3683
3689
  var zConnectByoMachinePath = z.object({
3684
3690
  orgID: zOrganizationId
3685
3691
  });
@@ -5693,11 +5699,19 @@ var createMachine = (options) => (options.client ?? client).post({
5693
5699
  });
5694
5700
  var connectByoMachine = (options) => (options.client ?? client).post({
5695
5701
  responseValidator: async (data) => await validateResponse(zConnectByoMachineResponse2, data),
5696
- security: [{
5697
- in: "cookie",
5698
- name: "__Host-omnara_session",
5699
- type: "apiKey"
5700
- }, { name: "X-Omnara-Csrf", type: "apiKey" }],
5702
+ security: [
5703
+ {
5704
+ key: "bearerAuth",
5705
+ scheme: "bearer",
5706
+ type: "http"
5707
+ },
5708
+ {
5709
+ in: "cookie",
5710
+ name: "__Host-omnara_session",
5711
+ type: "apiKey"
5712
+ },
5713
+ { name: "X-Omnara-Csrf", type: "apiKey" }
5714
+ ],
5701
5715
  url: "/api/v1/orgs/{orgID}/machines/connect",
5702
5716
  ...options,
5703
5717
  headers: {
@@ -6305,10 +6319,10 @@ var getDaemonSkillArchive = (options) => (options.client ?? client).get({
6305
6319
 
6306
6320
  // ../sdk/src/auth.ts
6307
6321
  function bearerToken(token) {
6308
- const resolve2 = typeof token === "function" ? token : () => token;
6322
+ const resolve3 = typeof token === "function" ? token : () => token;
6309
6323
  return {
6310
6324
  async authenticate(request) {
6311
- const value = await resolve2();
6325
+ const value = await resolve3();
6312
6326
  if (value) request.headers.set("Authorization", `Bearer ${value}`);
6313
6327
  }
6314
6328
  };
@@ -6456,7 +6470,7 @@ async function startDeviceAuth(options) {
6456
6470
  };
6457
6471
  }
6458
6472
  function defaultSleep(seconds) {
6459
- return new Promise((resolve2) => setTimeout(resolve2, seconds * 1e3));
6473
+ return new Promise((resolve3) => setTimeout(resolve3, seconds * 1e3));
6460
6474
  }
6461
6475
  async function pollDeviceAuthToken(options) {
6462
6476
  const fetchImpl = options.fetch ?? fetch;
@@ -7052,6 +7066,7 @@ function flowOp(spec) {
7052
7066
  type: "flow",
7053
7067
  execute: (input) => run({
7054
7068
  client: input.client,
7069
+ baseUrl: input.baseUrl,
7055
7070
  path: parseWithSchema(spec.path, input.path, "arguments"),
7056
7071
  body: parseWithSchema(spec.body, input.body, "flags"),
7057
7072
  report: createFlowReporter(spec.summary)
@@ -7261,7 +7276,7 @@ function registerOperation(parent, config2, spec) {
7261
7276
  renderResult(data, true);
7262
7277
  return;
7263
7278
  }
7264
- const formatted = spec.format(data);
7279
+ const formatted = spec.format(data, { baseUrl: config2.baseUrl });
7265
7280
  renderResult(formatted.value, false, { columns: formatted.columns });
7266
7281
  });
7267
7282
  });
@@ -7277,6 +7292,7 @@ function registerFlow(parent, config2, spec) {
7277
7292
  const options = command.opts();
7278
7293
  await spec.execute({
7279
7294
  client: config2.client,
7295
+ baseUrl: config2.baseUrl,
7280
7296
  path: await resolvePathValues(plan, args, options, config2),
7281
7297
  body: collectFlagValues(bodyFlags, options)
7282
7298
  });
@@ -7479,7 +7495,7 @@ function registerLoginCommand(program2, cli) {
7479
7495
  }
7480
7496
 
7481
7497
  // src/manifest.ts
7482
- import * as z13 from "zod";
7498
+ import * as z14 from "zod";
7483
7499
 
7484
7500
  // src/config-attachment.ts
7485
7501
  import { readFileSync as readFileSync2 } from "node:fs";
@@ -7574,18 +7590,332 @@ function formatVoid(message = "ok") {
7574
7590
  return () => ({ value: message });
7575
7591
  }
7576
7592
 
7593
+ // src/machine-setup.ts
7594
+ import { spawn as spawn2, spawnSync } from "node:child_process";
7595
+ import { accessSync, constants, existsSync as existsSync2, readdirSync, readFileSync as readFileSync3 } from "node:fs";
7596
+ import { homedir as homedir2 } from "node:os";
7597
+ import { basename, dirname as dirname2, isAbsolute, join as join2, resolve } from "node:path";
7598
+ import * as z9 from "zod";
7599
+ var zMachineSetupBody = zConnectByoMachineRequest;
7600
+ async function connectMachine(context) {
7601
+ const { client: client2, path, body, report } = context;
7602
+ report.start("Creating machine with a daemon token");
7603
+ try {
7604
+ const { data } = await sdk_gen_exports.connectByoMachine({ client: client2, path, body });
7605
+ report.stop(`Machine created: ${data.machine.id}`);
7606
+ if (data.project_grants.length > 0) {
7607
+ report.info(`Granted to ${data.project_grants.length} project(s)`);
7608
+ }
7609
+ return data;
7610
+ } catch (error) {
7611
+ report.fail("Machine could not be created");
7612
+ throw error;
7613
+ }
7614
+ }
7615
+ function shellQuote(value) {
7616
+ return `'${value.replaceAll("'", `'\\''`)}'`;
7617
+ }
7618
+ function installCommand(baseUrl) {
7619
+ return `curl -fsSL ${shellQuote(`${baseUrl}/install/omnarad.sh`)} | sh`;
7620
+ }
7621
+ var formatMachineSetup = (response, { baseUrl }) => ({
7622
+ value: {
7623
+ ...response,
7624
+ install_command: installCommand(baseUrl),
7625
+ install_note: "Run install_command on the target machine and paste the token when prompted."
7626
+ }
7627
+ });
7628
+ var daemonConfigFileName = "daemon.json";
7629
+ var installLockFileName = "install.lock";
7630
+ var daemonLockFileName = "daemon.lock";
7631
+ var daemonLockPollMs = 250;
7632
+ var zDaemonConfigFile = z9.looseObject({
7633
+ machine_id: z9.string().optional(),
7634
+ api_url: z9.string().optional()
7635
+ });
7636
+ function daemonHome() {
7637
+ const override = process.env.OMNARA_HOME;
7638
+ if (override !== void 0 && override !== "") {
7639
+ if (!isAbsolute(override) || resolve(override) !== override) {
7640
+ throw new CliInputError("OMNARA_HOME must be an absolute clean path");
7641
+ }
7642
+ if (dirname2(override) === override) {
7643
+ throw new CliInputError("OMNARA_HOME cannot be a filesystem root");
7644
+ }
7645
+ return override;
7646
+ }
7647
+ const userHome = homedir2();
7648
+ if (userHome === "" || !isAbsolute(userHome) || userHome.trim() !== userHome) {
7649
+ throw new CliInputError("HOME must be an absolute path so omnarad can install under ~/.omnarad");
7650
+ }
7651
+ return join2(userHome, ".omnarad");
7652
+ }
7653
+ var supportedPlatforms = /* @__PURE__ */ new Set(["darwin", "linux"]);
7654
+ var supportedArchitectures = /* @__PURE__ */ new Set(["x64", "arm64"]);
7655
+ function ensureSupportedPlatform(platform, architecture) {
7656
+ if (!supportedPlatforms.has(platform)) {
7657
+ throw new CliInputError(`omnarad supports macOS and Linux; this machine reports ${platform}`);
7658
+ }
7659
+ if (!supportedArchitectures.has(architecture)) {
7660
+ throw new CliInputError(
7661
+ `omnarad supports amd64 and arm64; this machine reports ${architecture}`
7662
+ );
7663
+ }
7664
+ }
7665
+ function isLoopbackHost(hostname2) {
7666
+ if (hostname2 === "localhost" || hostname2 === "[::1]" || hostname2 === "::1") return true;
7667
+ const octets = hostname2.split(".");
7668
+ return octets.length === 4 && octets[0] === "127" && octets.every((octet) => /^\d{1,3}$/.test(octet));
7669
+ }
7670
+ function ensureDaemonApiUrl(raw) {
7671
+ const trimmed = raw.trim();
7672
+ let parsed;
7673
+ try {
7674
+ parsed = new URL(trimmed);
7675
+ } catch {
7676
+ throw new CliInputError(`omnarad rejects the API URL ${raw}: it must be an absolute URL`);
7677
+ }
7678
+ const reject = (reason) => {
7679
+ throw new CliInputError(`omnarad rejects the API URL ${raw}: ${reason}`);
7680
+ };
7681
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
7682
+ reject("the scheme must be https or loopback http");
7683
+ }
7684
+ if (parsed.hostname === "") reject("a host is required");
7685
+ if (parsed.username !== "" || parsed.password !== "") reject("it must not contain user info");
7686
+ if (trimmed.includes("?") || trimmed.includes("#")) {
7687
+ reject("it must not contain a query or fragment");
7688
+ }
7689
+ const hostname2 = parsed.hostname.toLowerCase();
7690
+ if (parsed.protocol === "http:" && hostname2 !== "host.docker.internal" && !isLoopbackHost(hostname2)) {
7691
+ reject("it must use https unless the host is local");
7692
+ }
7693
+ }
7694
+ function describeDaemonConfig(configPath) {
7695
+ try {
7696
+ const config2 = zDaemonConfigFile.parse(JSON.parse(readFileSync3(configPath, "utf8")));
7697
+ const details = [
7698
+ ...config2.machine_id === void 0 ? [] : [`machine ${config2.machine_id}`],
7699
+ ...config2.api_url === void 0 ? [] : [`API ${config2.api_url}`]
7700
+ ];
7701
+ return details.length === 0 ? configPath : `${configPath} (${details.join(", ")})`;
7702
+ } catch {
7703
+ return configPath;
7704
+ }
7705
+ }
7706
+ function describeExistingInstallation(home) {
7707
+ const configPath = join2(home, daemonConfigFileName);
7708
+ if (existsSync2(configPath)) return describeDaemonConfig(configPath);
7709
+ if (!existsSync2(home)) return void 0;
7710
+ const leftovers = readdirSync(home).filter((name) => name !== installLockFileName);
7711
+ return leftovers.length === 0 ? void 0 : `${home} already contains ${leftovers.join(", ")}`;
7712
+ }
7713
+ function nearestExistingAncestor(path) {
7714
+ const parent = dirname2(path);
7715
+ return existsSync2(path) || parent === path ? path : nearestExistingAncestor(parent);
7716
+ }
7717
+ function ensureDaemonHomeWritable(home) {
7718
+ const target = nearestExistingAncestor(home);
7719
+ try {
7720
+ accessSync(target, constants.W_OK);
7721
+ } catch {
7722
+ throw new CliInputError(`omnarad cannot be installed because ${target} is not writable`);
7723
+ }
7724
+ }
7725
+ var DaemonExitError = class extends Error {
7726
+ };
7727
+ async function runMachineCreateLocal(context) {
7728
+ const { report, baseUrl } = context;
7729
+ ensureSupportedPlatform(process.platform, process.arch);
7730
+ ensureDaemonApiUrl(baseUrl);
7731
+ const home = daemonHome();
7732
+ const existing = describeExistingInstallation(home);
7733
+ if (existing !== void 0) {
7734
+ report.warn(`omnarad is already installed on this computer: ${existing}`);
7735
+ report.info(
7736
+ [
7737
+ "Nothing was created. Check the daemon with: omnarad status, or start it with: omnarad restart",
7738
+ "To connect this computer as a new machine, run: omnarad uninstall, then re-run this command"
7739
+ ].join("\n")
7740
+ );
7741
+ throw new CliInputError("omnarad is already installed on this machine");
7742
+ }
7743
+ ensureDaemonHomeWritable(home);
7744
+ const { machine, token } = await connectMachine(context);
7745
+ report.info(`Machine ID: ${machine.id}`);
7746
+ report.start("Installing omnarad on this machine");
7747
+ try {
7748
+ await runInstaller(report, baseUrl, token, machine.id, home);
7749
+ } catch (error) {
7750
+ if (error instanceof DaemonExitError) {
7751
+ report.fail("omnarad exited after it was installed");
7752
+ report.info(
7753
+ [
7754
+ `omnarad is installed and registered as machine ${machine.id}; nothing needs to be reinstalled.`,
7755
+ "Check the daemon with: omnarad status, or launch it again with: omnarad start"
7756
+ ].join("\n")
7757
+ );
7758
+ throw error;
7759
+ }
7760
+ report.fail("omnarad installation failed");
7761
+ report.info(`Machine daemon token (shown only once):
7762
+ ${token}`);
7763
+ report.url(
7764
+ "Finish setup by running this, then paste the machine token when prompted",
7765
+ installCommand(baseUrl)
7766
+ );
7767
+ throw error;
7768
+ }
7769
+ report.done();
7770
+ }
7771
+ function daemonGuidance(machineId) {
7772
+ return [
7773
+ "omnarad is connected to Omnara as this machine.",
7774
+ "Manage the daemon with: omnarad status | stop | restart | uninstall",
7775
+ `Let agents in a project use this machine with: omnara grant machines add --machine-id ${machineId}`,
7776
+ "Learn more: https://docs.omnara.com/machines/connect"
7777
+ ].join("\n");
7778
+ }
7779
+ var foregroundGuidance = [
7780
+ "No launchd/systemd user service manager is available, so omnarad is running in the foreground.",
7781
+ "Its logs stream below; press Ctrl-C to stop the daemon, and run omnarad start to launch it again."
7782
+ ].join("\n");
7783
+ var serviceManagerCommands = /* @__PURE__ */ new Set(["launchd", "systemd"]);
7784
+ function parentProcess(pid) {
7785
+ if (process.platform === "linux") {
7786
+ try {
7787
+ const stat = readFileSync3(`/proc/${pid}/stat`, "utf8");
7788
+ const fields = stat.slice(stat.lastIndexOf(")") + 2).split(" ");
7789
+ const ppid2 = Number(fields[1]);
7790
+ const parentStat = readFileSync3(`/proc/${ppid2}/stat`, "utf8");
7791
+ const command = parentStat.slice(parentStat.indexOf("(") + 1, parentStat.lastIndexOf(")"));
7792
+ return Number.isInteger(ppid2) && ppid2 > 0 ? { pid: ppid2, command } : void 0;
7793
+ } catch {
7794
+ return void 0;
7795
+ }
7796
+ }
7797
+ const result = spawnSync("ps", ["-o", "ppid=", "-p", String(pid)], { encoding: "utf8" });
7798
+ const ppid = Number(result.stdout.trim());
7799
+ if (result.status !== 0 || !Number.isInteger(ppid) || ppid <= 0) return void 0;
7800
+ const parent = spawnSync("ps", ["-o", "comm=", "-p", String(ppid)], { encoding: "utf8" });
7801
+ return { pid: ppid, command: basename(parent.stdout.trim()) };
7802
+ }
7803
+ function classifyDaemonSupervision(daemonPid, installerPid, lookupParent) {
7804
+ let current = daemonPid;
7805
+ for (let depth = 0; depth < 16; depth += 1) {
7806
+ const parent = lookupParent(current);
7807
+ if (parent === void 0) return void 0;
7808
+ if (parent.pid === installerPid) return "foreground";
7809
+ if (parent.pid === 1 || serviceManagerCommands.has(parent.command)) return "service";
7810
+ current = parent.pid;
7811
+ }
7812
+ return void 0;
7813
+ }
7814
+ function readDaemonLockPid(home) {
7815
+ try {
7816
+ const pid = Number(readFileSync3(join2(home, daemonLockFileName), "utf8").trim());
7817
+ return Number.isInteger(pid) && pid > 0 ? pid : void 0;
7818
+ } catch {
7819
+ return void 0;
7820
+ }
7821
+ }
7822
+ function installerScript(baseUrl) {
7823
+ return [
7824
+ "installer=$(mktemp)",
7825
+ `trap 'rm -f "$installer"' EXIT`,
7826
+ `curl -qfsSL --connect-timeout 10 -m 60 --max-redirs 5 --max-filesize 1048576 --proto '=http,https' --proto-redir '=https' -o "$installer" ${shellQuote(`${baseUrl}/install/omnarad.sh`)}`,
7827
+ 'sh "$installer"'
7828
+ ].join(" && ");
7829
+ }
7830
+ function installerFailure(code, signal, log3) {
7831
+ const reason = signal === null ? `exit code ${code}` : `signal ${signal}`;
7832
+ return new Error(`omnarad installer failed (${reason})${log3 === "" ? "" : `
7833
+ ${log3}`}`);
7834
+ }
7835
+ function runInstaller(report, baseUrl, token, machineId, home) {
7836
+ return new Promise((resolve3, reject) => {
7837
+ const child = spawn2("/bin/sh", ["-c", installerScript(baseUrl)], {
7838
+ stdio: ["ignore", "pipe", "pipe"],
7839
+ env: { ...process.env, OMNARA_API_URL: baseUrl, OMNARA_MACHINE_TOKEN: token }
7840
+ });
7841
+ const relay = (signal) => {
7842
+ child.kill(signal);
7843
+ };
7844
+ process.on("SIGINT", relay);
7845
+ process.on("SIGTERM", relay);
7846
+ const buffered = [];
7847
+ let transcript = "";
7848
+ let supervision;
7849
+ const enterForeground = () => {
7850
+ supervision = "foreground";
7851
+ report.stop("omnarad installed");
7852
+ report.info(daemonGuidance(machineId));
7853
+ report.info(foregroundGuidance);
7854
+ for (const [target, data] of buffered) target.write(data);
7855
+ };
7856
+ const lockWatch = setInterval(() => {
7857
+ if (supervision !== void 0 || child.pid === void 0) return;
7858
+ const daemonPid = readDaemonLockPid(home);
7859
+ if (daemonPid === void 0) return;
7860
+ const detected = classifyDaemonSupervision(daemonPid, child.pid, parentProcess);
7861
+ if (detected === "foreground") enterForeground();
7862
+ else if (detected === "service") supervision = "service";
7863
+ }, daemonLockPollMs);
7864
+ const settle = (outcome) => {
7865
+ clearInterval(lockWatch);
7866
+ process.off("SIGINT", relay);
7867
+ process.off("SIGTERM", relay);
7868
+ outcome();
7869
+ };
7870
+ const consume = (stream) => (chunk) => {
7871
+ if (supervision === "foreground") {
7872
+ stream.write(chunk);
7873
+ return;
7874
+ }
7875
+ buffered.push([stream, chunk]);
7876
+ transcript += chunk.toString();
7877
+ };
7878
+ child.stdout.on("data", consume(process.stdout));
7879
+ child.stderr.on("data", consume(process.stderr));
7880
+ child.on("error", (error) => {
7881
+ settle(() => {
7882
+ reject(new Error(`could not run the omnarad installer: ${error.message}`));
7883
+ });
7884
+ });
7885
+ child.on("close", (code, signal) => {
7886
+ settle(() => {
7887
+ const foreground = supervision === "foreground";
7888
+ if (foreground && (code === 0 || signal === "SIGINT")) {
7889
+ report.info("omnarad stopped");
7890
+ resolve3();
7891
+ } else if (foreground) {
7892
+ const reason = signal === null ? `exit code ${code}` : `signal ${signal}`;
7893
+ reject(new DaemonExitError(`omnarad exited while running in the foreground (${reason})`));
7894
+ } else if (code === 0) {
7895
+ report.stop("omnarad installed and started as a background service");
7896
+ for (const [target, data] of buffered) target.write(data);
7897
+ report.info(daemonGuidance(machineId));
7898
+ resolve3();
7899
+ } else {
7900
+ reject(installerFailure(code, signal, transcript.trim()));
7901
+ }
7902
+ });
7903
+ });
7904
+ });
7905
+ }
7906
+
7577
7907
  // src/mcp-add.ts
7578
7908
  import { isMap, isScalar as isScalar2, parseDocument } from "yaml";
7579
- import * as z10 from "zod";
7909
+ import * as z11 from "zod";
7580
7910
 
7581
7911
  // src/mcp-oauth.ts
7582
- import * as z9 from "zod";
7912
+ import * as z10 from "zod";
7583
7913
 
7584
7914
  // src/poll.ts
7585
7915
  var POLL_INTERVAL_SECONDS = 2;
7586
7916
  var MAX_CONSECUTIVE_POLL_FAILURES = 3;
7587
7917
  function sleep(seconds) {
7588
- return new Promise((resolve2) => setTimeout(resolve2, seconds * 1e3));
7918
+ return new Promise((resolve3) => setTimeout(resolve3, seconds * 1e3));
7589
7919
  }
7590
7920
  async function pollUntilDeadline(options) {
7591
7921
  const deadline = Date.parse(options.expiresAt);
@@ -7627,7 +7957,7 @@ async function authorizeMcpOAuthSecret(options) {
7627
7957
  }
7628
7958
  });
7629
7959
  }
7630
- var zBrowserFlag = z9.boolean().default(true).describe("open the authorization URL in a browser");
7960
+ var zBrowserFlag = z10.boolean().default(true).describe("open the authorization URL in a browser");
7631
7961
  function openAuthorizationUrl(report, title, url3, browser) {
7632
7962
  report.url(title, url3);
7633
7963
  if (browser) {
@@ -7663,7 +7993,7 @@ async function runMcpOAuth(context) {
7663
7993
  // src/mcp-add.ts
7664
7994
  var SERVER_KEY_PATTERN = /^[a-zA-Z][a-zA-Z0-9-]{0,31}$/;
7665
7995
  var zMcpAddBody = zMcpoAuthStartRequest.omit({ owner: true, name: true }).extend({
7666
- server_name: z10.string().regex(
7996
+ server_name: z11.string().regex(
7667
7997
  SERVER_KEY_PATTERN,
7668
7998
  "must start with a letter and contain at most 32 letters, digits, or hyphens"
7669
7999
  ).describe("MCP server key used in the agent config"),
@@ -7676,7 +8006,7 @@ function targetLabel(target) {
7676
8006
  function serverEntry(url3, secretId) {
7677
8007
  return { url: url3, auth: { type: "oauth", secret_id: secretId } };
7678
8008
  }
7679
- var zJsonRecord = z10.record(z10.string(), z10.json());
8009
+ var zJsonRecord = z11.record(z11.string(), z11.json());
7680
8010
  function prepareJsonConfig(config2, serverName, mcpUrl) {
7681
8011
  let parsedJson;
7682
8012
  try {
@@ -7840,18 +8170,18 @@ function runProfileMcpAdd(context) {
7840
8170
  }
7841
8171
 
7842
8172
  // src/skill-archive.ts
7843
- import { readdirSync, readFileSync as readFileSync3, statSync } from "node:fs";
7844
- import { basename, dirname as dirname2, join as join2, resolve } from "node:path";
8173
+ import { readdirSync as readdirSync2, readFileSync as readFileSync4, statSync } from "node:fs";
8174
+ import { basename as basename2, dirname as dirname3, join as join3, resolve as resolve2 } from "node:path";
7845
8175
  import * as tar from "tar";
7846
- import * as z11 from "zod";
7847
- var zCreateSkillCliBody = z11.object({
8176
+ import * as z12 from "zod";
8177
+ var zCreateSkillCliBody = z12.object({
7848
8178
  owner: zSkillOwnerInput,
7849
- archive: z11.string().min(1).describe("path to a skill directory (packed automatically) or a .zip/.tar.gz archive")
8179
+ archive: z12.string().min(1).describe("path to a skill directory (packed automatically) or a .zip/.tar.gz archive")
7850
8180
  });
7851
8181
  var ARCHIVE_SUFFIXES = [".zip", ".tar.gz", ".tgz"];
7852
8182
  function assertPackable(dir) {
7853
- for (const entry of readdirSync(dir, { withFileTypes: true })) {
7854
- const fullPath = join2(dir, entry.name);
8183
+ for (const entry of readdirSync2(dir, { withFileTypes: true })) {
8184
+ const fullPath = join3(dir, entry.name);
7855
8185
  if (entry.isSymbolicLink()) {
7856
8186
  throw new CliInputError(`cannot pack ${fullPath}: symlinks are not allowed in skill archives`);
7857
8187
  }
@@ -7860,9 +8190,9 @@ function assertPackable(dir) {
7860
8190
  }
7861
8191
  }
7862
8192
  async function packDirectory(dir) {
7863
- const root = resolve(dir);
8193
+ const root = resolve2(dir);
7864
8194
  assertPackable(root);
7865
- const stream = tar.create({ cwd: dirname2(root), gzip: true, portable: true }, [basename(root)]);
8195
+ const stream = tar.create({ cwd: dirname3(root), gzip: true, portable: true }, [basename2(root)]);
7866
8196
  const chunks = [];
7867
8197
  for await (const chunk of stream) chunks.push(chunk);
7868
8198
  return Buffer.concat(chunks);
@@ -7876,28 +8206,28 @@ async function loadSkillArchive(archivePath) {
7876
8206
  }
7877
8207
  if (isDirectory) {
7878
8208
  const buffer = await packDirectory(archivePath);
7879
- return new File([new Uint8Array(buffer)], `${basename(resolve(archivePath))}.tar.gz`);
8209
+ return new File([new Uint8Array(buffer)], `${basename2(resolve2(archivePath))}.tar.gz`);
7880
8210
  }
7881
- const filename = basename(archivePath);
8211
+ const filename = basename2(archivePath);
7882
8212
  if (!ARCHIVE_SUFFIXES.some((suffix) => filename.toLowerCase().endsWith(suffix))) {
7883
8213
  throw new CliInputError(
7884
8214
  `archive must be a directory or a ${ARCHIVE_SUFFIXES.join("/")} file: ${archivePath}`
7885
8215
  );
7886
8216
  }
7887
- return new File([new Uint8Array(readFileSync3(archivePath))], filename);
8217
+ return new File([new Uint8Array(readFileSync4(archivePath))], filename);
7888
8218
  }
7889
8219
 
7890
8220
  // src/slack-integration.ts
7891
- import * as z12 from "zod";
7892
- var zSlackBody = z12.object({
7893
- app_name: z12.string().optional().describe("name for a new Slack app"),
7894
- app_configuration_token: z12.string().optional().describe("Slack app configuration token for a new app"),
7895
- icon_filename: z12.string().optional().describe("filename for the new Slack app icon"),
7896
- icon_data_base64: z12.string().optional().describe("base64-encoded Slack app icon"),
7897
- client_id: z12.string().optional().describe("existing Slack app client ID"),
7898
- client_secret: z12.string().optional().describe("existing Slack app client secret"),
7899
- signing_secret: z12.string().optional().describe("existing Slack app signing secret"),
7900
- return_to: z12.string().optional().describe("console-relative path opened after authorization"),
8221
+ import * as z13 from "zod";
8222
+ var zSlackBody = z13.object({
8223
+ app_name: z13.string().optional().describe("name for a new Slack app"),
8224
+ app_configuration_token: z13.string().optional().describe("Slack app configuration token for a new app"),
8225
+ icon_filename: z13.string().optional().describe("filename for the new Slack app icon"),
8226
+ icon_data_base64: z13.string().optional().describe("base64-encoded Slack app icon"),
8227
+ client_id: z13.string().optional().describe("existing Slack app client ID"),
8228
+ client_secret: z13.string().optional().describe("existing Slack app client secret"),
8229
+ signing_secret: z13.string().optional().describe("existing Slack app signing secret"),
8230
+ return_to: z13.string().optional().describe("console-relative path opened after authorization"),
7901
8231
  browser: zBrowserFlag
7902
8232
  });
7903
8233
  function parseRequest(body) {
@@ -7926,7 +8256,7 @@ function parseRequest(body) {
7926
8256
  if (!result2.success) {
7927
8257
  throw new CliInputError(
7928
8258
  `invalid existing Slack app parameters:
7929
- ${z12.prettifyError(result2.error)}`
8259
+ ${z13.prettifyError(result2.error)}`
7930
8260
  );
7931
8261
  }
7932
8262
  return { kind: "existing-app", body: result2.data };
@@ -7948,7 +8278,7 @@ ${z12.prettifyError(result2.error)}`
7948
8278
  if (!result.success) {
7949
8279
  throw new CliInputError(
7950
8280
  `invalid Slack app parameters:
7951
- ${z12.prettifyError(result.error)}
8281
+ ${z13.prettifyError(result.error)}
7952
8282
  Pass --app-name and --app-configuration-token, or existing app credentials.`
7953
8283
  );
7954
8284
  }
@@ -8043,7 +8373,7 @@ var commandGroups = [
8043
8373
  body: zConfigAttachment.extend({
8044
8374
  profile: zAgentProfileId.optional(),
8045
8375
  name: zAgentName.optional(),
8046
- message: z13.string().optional()
8376
+ message: z14.string().optional()
8047
8377
  }),
8048
8378
  transformBody: async ({ profile, name, message, ...attachment }, { client: client2, path }) => ({
8049
8379
  profile,
@@ -8084,7 +8414,7 @@ var commandGroups = [
8084
8414
  flowOp({
8085
8415
  verb: "mcp-add",
8086
8416
  summary: "Create an OAuth secret and add an MCP server to an agent",
8087
- path: z13.object({
8417
+ path: z14.object({
8088
8418
  orgID: zOrganizationId,
8089
8419
  projectID: zProjectId,
8090
8420
  agentID: zAgentId
@@ -8329,11 +8659,18 @@ var commandGroups = [
8329
8659
  }),
8330
8660
  op({
8331
8661
  verb: "create",
8332
- summary: "Create a machine",
8333
- fn: sdk_gen_exports.createMachine,
8334
- format: formatRecord(),
8335
- path: zCreateMachinePath,
8336
- body: zCreateMachineBody
8662
+ summary: "Create a machine with a daemon token and show how to install omnarad",
8663
+ fn: sdk_gen_exports.connectByoMachine,
8664
+ format: formatMachineSetup,
8665
+ path: zConnectByoMachinePath,
8666
+ body: zConnectByoMachineBody
8667
+ }),
8668
+ flowOp({
8669
+ verb: "create-local",
8670
+ summary: "Create a machine and install omnarad on this machine",
8671
+ path: zConnectByoMachinePath,
8672
+ body: zMachineSetupBody,
8673
+ run: runMachineCreateLocal
8337
8674
  }),
8338
8675
  op({
8339
8676
  verb: "update",
@@ -8546,7 +8883,7 @@ var commandGroups = [
8546
8883
  flowOp({
8547
8884
  verb: "mcp-oauth",
8548
8885
  summary: "Create a secret through an MCP server OAuth flow",
8549
- path: z13.object({ orgID: zOrganizationId }),
8886
+ path: z14.object({ orgID: zOrganizationId }),
8550
8887
  body: zMcpOAuthBody,
8551
8888
  run: runMcpOAuth
8552
8889
  })
@@ -8660,7 +8997,7 @@ var commandGroups = [
8660
8997
  flowOp({
8661
8998
  verb: "mcp-add",
8662
8999
  summary: "Create an OAuth secret and add an MCP server to an agent profile",
8663
- path: z13.object({
9000
+ path: z14.object({
8664
9001
  orgID: zOrganizationId,
8665
9002
  projectID: zProjectId,
8666
9003
  agentProfileID: zAgentProfileId
@@ -8672,7 +9009,7 @@ var commandGroups = [
8672
9009
  verb: "slack",
8673
9010
  aliases: ["slack-setup"],
8674
9011
  summary: "Connect Slack to an agent profile through OAuth",
8675
- path: z13.object({
9012
+ path: z14.object({
8676
9013
  orgID: zOrganizationId,
8677
9014
  projectID: zProjectId,
8678
9015
  agentProfileID: zAgentProfileId
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnara",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Command-line interface for Omnara: launch and manage agents, organizations, integrations, and MCP servers",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://omnara.com",