@runtypelabs/cli 2.12.2 → 2.12.4

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/index.js +108 -66
  2. package/package.json +3 -4
package/dist/index.js CHANGED
@@ -133,7 +133,24 @@ var init_credential_store = __esm({
133
133
  // src/index.ts
134
134
  import { Command as Command23 } from "commander";
135
135
  import chalk30 from "chalk";
136
- import { config as loadEnv } from "dotenv";
136
+
137
+ // src/lib/load-env.ts
138
+ import { readFileSync } from "fs";
139
+ import { resolve } from "path";
140
+ function loadEnv(path14 = resolve(process.cwd(), ".env")) {
141
+ try {
142
+ const content = readFileSync(path14, "utf8").replace(/\r\n?/g, "\n");
143
+ for (const line of content.split("\n")) {
144
+ if (!line.trim() || line.trimStart().startsWith("#")) continue;
145
+ const match = line.match(/^\s*([\w.-]+)\s*=\s*(.*)?\s*$/);
146
+ if (match) {
147
+ const [, key, val = ""] = match;
148
+ process.env[key] ??= val.replace(/^(['"])(.*)\1$/, "$2");
149
+ }
150
+ }
151
+ } catch {
152
+ }
153
+ }
137
154
 
138
155
  // src/commands/auth.ts
139
156
  import { Command } from "commander";
@@ -157,8 +174,8 @@ var CallbackServer = class {
157
174
  expectedState;
158
175
  constructor() {
159
176
  this.app = express();
160
- this.codePromise = new Promise((resolve8, reject) => {
161
- this.codeResolve = resolve8;
177
+ this.codePromise = new Promise((resolve9, reject) => {
178
+ this.codeResolve = resolve9;
162
179
  this.codeReject = reject;
163
180
  });
164
181
  this.app.get("/callback", (req, res) => {
@@ -31542,6 +31559,28 @@ var MODEL_FAMILY_PROVIDER_IDS = {
31542
31559
  "vercel": "voyage/voyage-law-2"
31543
31560
  }
31544
31561
  };
31562
+ var PLATFORM_KEY_PROVIDER_MAP = {
31563
+ "mixlayer": true,
31564
+ "openai": true,
31565
+ "anthropic": true,
31566
+ "google": true,
31567
+ "xai": true,
31568
+ "vercel": true,
31569
+ "cloudflare": true,
31570
+ "azure": false,
31571
+ "openrouter": false,
31572
+ "togetherai": false,
31573
+ "bedrock": false,
31574
+ "vertex": false,
31575
+ "vertex-anthropic": false,
31576
+ "tinfoil": false,
31577
+ "generic-openai": false,
31578
+ "workers-ai": false,
31579
+ "mock": false
31580
+ };
31581
+ var PLATFORM_KEY_PROVIDERS = new Set(
31582
+ Object.entries(PLATFORM_KEY_PROVIDER_MAP).filter(([, v]) => v).map(([k]) => k)
31583
+ );
31545
31584
  var MANUAL_PROVIDER_MAP_OVERRIDES = {
31546
31585
  // Bedrock uses different model ID format
31547
31586
  "claude-sonnet-4-5": {
@@ -35196,6 +35235,15 @@ var RunPromptOptionsSchema = external_exports.object({
35196
35235
  variables: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
35197
35236
  responseFormat: external_exports.enum(["text", "json", "markdown"]).optional()
35198
35237
  });
35238
+ var SANDBOX_TTL_DEFAULT_SECONDS = 10 * 60;
35239
+ var SANDBOX_TTL_MAX_SECONDS = 2 * 60 * 60;
35240
+ var SANDBOX_TTL_OPTIONS = [
35241
+ { label: "10 min", value: 10 * 60 },
35242
+ { label: "30 min", value: 30 * 60 },
35243
+ { label: "1 hour", value: 60 * 60 },
35244
+ { label: "2 hours", value: 2 * 60 * 60 },
35245
+ { label: "Unlimited", value: null }
35246
+ ];
35199
35247
 
35200
35248
  // src/config/env.ts
35201
35249
  function getApiUrl() {
@@ -36024,7 +36072,7 @@ import chalk4 from "chalk";
36024
36072
  import React2 from "react";
36025
36073
  import { render as render2 } from "ink";
36026
36074
  import { useState as useState3, useEffect as useEffect4 } from "react";
36027
- import { readFileSync as readFileSync2 } from "fs";
36075
+ import { readFileSync as readFileSync3 } from "fs";
36028
36076
  import { processStream } from "@runtypelabs/sdk";
36029
36077
 
36030
36078
  // src/lib/ensure-auth.ts
@@ -36039,14 +36087,14 @@ async function promptConfirm(message, options) {
36039
36087
  output: process.stdout,
36040
36088
  terminal: true
36041
36089
  });
36042
- return new Promise((resolve8) => {
36090
+ return new Promise((resolve9) => {
36043
36091
  rl.question(chalk2.cyan(`${message} (${hint}): `), (answer) => {
36044
36092
  rl.close();
36045
36093
  const trimmed = answer.trim().toLowerCase();
36046
36094
  if (trimmed === "") {
36047
- resolve8(defaultYes);
36095
+ resolve9(defaultYes);
36048
36096
  } else {
36049
- resolve8(trimmed === "y" || trimmed === "yes");
36097
+ resolve9(trimmed === "y" || trimmed === "yes");
36050
36098
  }
36051
36099
  });
36052
36100
  });
@@ -36112,7 +36160,7 @@ async function handleBrowserLogin(store, apiUrl) {
36112
36160
  }
36113
36161
 
36114
36162
  // src/lib/cli-version.ts
36115
- import { readFileSync } from "fs";
36163
+ import { readFileSync as readFileSync2 } from "fs";
36116
36164
  import { dirname, join } from "path";
36117
36165
  import { fileURLToPath } from "url";
36118
36166
  var CLI_PACKAGE_NAME = "@runtypelabs/cli";
@@ -36130,7 +36178,7 @@ function getCliVersion() {
36130
36178
  ];
36131
36179
  for (const pkgPath of candidates) {
36132
36180
  try {
36133
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
36181
+ const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
36134
36182
  if (pkg.name === CLI_PACKAGE_NAME && pkg.version) {
36135
36183
  cachedCliVersion = pkg.version;
36136
36184
  return cachedCliVersion;
@@ -36487,7 +36535,7 @@ flowsCommand.command("create").description("Create a new flow").requiredOption("
36487
36535
  };
36488
36536
  if (options.fromFile) {
36489
36537
  try {
36490
- const fileContent = JSON.parse(readFileSync2(options.fromFile, "utf-8"));
36538
+ const fileContent = JSON.parse(readFileSync3(options.fromFile, "utf-8"));
36491
36539
  if (fileContent.flow) {
36492
36540
  body = { ...fileContent.flow, name: options.name || fileContent.flow.name };
36493
36541
  } else {
@@ -37116,14 +37164,14 @@ import chalk7 from "chalk";
37116
37164
  import React5 from "react";
37117
37165
  import { render as render5 } from "ink";
37118
37166
  import { useState as useState6, useEffect as useEffect7 } from "react";
37119
- import { readFileSync as readFileSync3 } from "fs";
37167
+ import { readFileSync as readFileSync4 } from "fs";
37120
37168
  var batchCommand = new Command5("batch").description("Manage batch operations");
37121
37169
  batchCommand.command("submit").description("Submit a batch job").requiredOption("-f, --flow <id>", "Flow ID to execute").requiredOption("-r, --records <file>", "JSON file with record IDs").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
37122
37170
  const apiKey = await ensureAuth();
37123
37171
  if (!apiKey) return;
37124
37172
  let recordIds;
37125
37173
  try {
37126
- const content = readFileSync3(options.records, "utf-8");
37174
+ const content = readFileSync4(options.records, "utf-8");
37127
37175
  const parsed = JSON.parse(content);
37128
37176
  recordIds = Array.isArray(parsed) ? parsed : parsed.recordIds || parsed.records || [];
37129
37177
  } catch (error51) {
@@ -38485,7 +38533,7 @@ import chalk10 from "chalk";
38485
38533
  import React8 from "react";
38486
38534
  import { render as render8 } from "ink";
38487
38535
  import { useState as useState9, useEffect as useEffect10 } from "react";
38488
- import { readFileSync as readFileSync4 } from "fs";
38536
+ import { readFileSync as readFileSync5 } from "fs";
38489
38537
  import { processStream as processStream3 } from "@runtypelabs/sdk";
38490
38538
  var dispatchCommand = new Command9("dispatch").description("Execute a flow or agent via the dispatch API").option("-f, --flow <id>", "Flow ID to execute").option("-a, --agent <id>", "Agent ID to execute").option("-r, --record <id>", "Existing record ID").option("--record-json <file>", "JSON file with record data").option("-m, --message <text>", "Message to send").option("-v, --variable <key=value>", "Set a variable (repeatable)", collectVariables, []).option("--stream", "Stream the response (default)", true).option("--no-stream", "Wait for complete response").option("--json", "Output as JSON").option("--debug", "Show step-level details").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
38491
38539
  if (!options.flow && !options.agent) {
@@ -38506,7 +38554,7 @@ var dispatchCommand = new Command9("dispatch").description("Execute a flow or ag
38506
38554
  payload.record = { id: options.record };
38507
38555
  } else if (options.recordJson) {
38508
38556
  try {
38509
- const data = JSON.parse(readFileSync4(options.recordJson, "utf-8"));
38557
+ const data = JSON.parse(readFileSync5(options.recordJson, "utf-8"));
38510
38558
  payload.record = { metadata: data };
38511
38559
  } catch (error51) {
38512
38560
  const message = error51 instanceof Error ? error51.message : "Unknown error";
@@ -43738,8 +43786,8 @@ function MarathonApp({
43738
43786
  setIsTerminalCheckpoint(true);
43739
43787
  isTerminalCheckpointRef.current = true;
43740
43788
  }
43741
- return new Promise((resolve8) => {
43742
- checkpointResolveRef.current = resolve8;
43789
+ return new Promise((resolve9) => {
43790
+ checkpointResolveRef.current = resolve9;
43743
43791
  });
43744
43792
  },
43745
43793
  updateMilestone: (milestone) => {
@@ -45066,16 +45114,16 @@ function MarathonStartupShell({
45066
45114
  latestAppPropsRef.current = marathonAppProps;
45067
45115
  useEffect20(() => {
45068
45116
  if (scene !== "app" || !appReadyResolverRef.current) return;
45069
- const resolve8 = appReadyResolverRef.current;
45117
+ const resolve9 = appReadyResolverRef.current;
45070
45118
  appReadyResolverRef.current = null;
45071
- resolve8();
45119
+ resolve9();
45072
45120
  }, [scene]);
45073
45121
  const beginTransition = (target) => {
45074
45122
  if (transitionPromiseRef.current) return transitionPromiseRef.current;
45075
45123
  if (target === "app" && !latestAppPropsRef.current) {
45076
45124
  throw new Error("Cannot complete startup before marathon app props are ready.");
45077
45125
  }
45078
- const promise2 = new Promise((resolve8) => {
45126
+ const promise2 = new Promise((resolve9) => {
45079
45127
  globalThis.setTimeout(() => {
45080
45128
  setPrompt(null);
45081
45129
  setModelChoices(null);
@@ -45096,12 +45144,12 @@ function MarathonStartupShell({
45096
45144
  if (target === "app") {
45097
45145
  appReadyResolverRef.current = () => {
45098
45146
  transitionPromiseRef.current = null;
45099
- resolve8();
45147
+ resolve9();
45100
45148
  };
45101
45149
  } else {
45102
45150
  dismissResolverRef.current = () => {
45103
45151
  transitionPromiseRef.current = null;
45104
- resolve8();
45152
+ resolve9();
45105
45153
  };
45106
45154
  }
45107
45155
  }, Math.max(0, MIN_HOLD_MS - (Date.now() - mountedAtRef.current)));
@@ -45118,8 +45166,8 @@ function MarathonStartupShell({
45118
45166
  setModelChoices(null);
45119
45167
  setPrompt(nextPrompt);
45120
45168
  setSelectedPromptIndex(0);
45121
- return new Promise((resolve8) => {
45122
- promptResolverRef.current = resolve8;
45169
+ return new Promise((resolve9) => {
45170
+ promptResolverRef.current = resolve9;
45123
45171
  });
45124
45172
  },
45125
45173
  requestModelChoice: async (nextCurrentModel, models) => {
@@ -45127,8 +45175,8 @@ function MarathonStartupShell({
45127
45175
  setPlaybookConfirm(null);
45128
45176
  setCurrentModel(nextCurrentModel);
45129
45177
  setModelChoices(models);
45130
- return new Promise((resolve8) => {
45131
- modelResolverRef.current = resolve8;
45178
+ return new Promise((resolve9) => {
45179
+ modelResolverRef.current = resolve9;
45132
45180
  });
45133
45181
  },
45134
45182
  requestPlaybookModelConfirm: async (playbookName, milestoneModels) => {
@@ -45143,8 +45191,8 @@ function MarathonStartupShell({
45143
45191
  // Default selection is the "Confirm" action (first item after milestones)
45144
45192
  selectedIndex: names.length
45145
45193
  });
45146
- return new Promise((resolve8) => {
45147
- playbookConfirmResolverRef.current = resolve8;
45194
+ return new Promise((resolve9) => {
45195
+ playbookConfirmResolverRef.current = resolve9;
45148
45196
  });
45149
45197
  },
45150
45198
  completeStartup: () => beginTransition("app"),
@@ -45642,7 +45690,7 @@ async function retryOnNetworkError(fn, opts = {}) {
45642
45690
  }
45643
45691
  const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);
45644
45692
  opts.onRetry?.(attempt + 1, delay, error51);
45645
- await new Promise((resolve8) => setTimeout(resolve8, delay));
45693
+ await new Promise((resolve9) => setTimeout(resolve9, delay));
45646
45694
  }
45647
45695
  }
45648
45696
  throw lastError;
@@ -45902,14 +45950,14 @@ async function promptNumericSelect(choices, promptLabel) {
45902
45950
  output: process.stdout,
45903
45951
  terminal: true
45904
45952
  });
45905
- return new Promise((resolve8) => {
45953
+ return new Promise((resolve9) => {
45906
45954
  const ask = () => {
45907
45955
  rl.question(chalk14.cyan(`
45908
45956
  ${promptLabel} (1-${choices.length}): `), (answer) => {
45909
45957
  const value = parseInt(answer.trim(), 10);
45910
45958
  if (value >= 1 && value <= choices.length) {
45911
45959
  rl.close();
45912
- resolve8(choices[value - 1].value);
45960
+ resolve9(choices[value - 1].value);
45913
45961
  return;
45914
45962
  }
45915
45963
  console.log(chalk14.red(`Please enter a number between 1 and ${choices.length}.`));
@@ -45937,7 +45985,7 @@ ${message}`));
45937
45985
  const previousRawMode = input.isRaw === true;
45938
45986
  let selectedIndex = 0;
45939
45987
  let renderedLineCount = 0;
45940
- return new Promise((resolve8) => {
45988
+ return new Promise((resolve9) => {
45941
45989
  const renderMenu = () => {
45942
45990
  if (renderedLineCount > 0) {
45943
45991
  clearRenderedLines(output, renderedLineCount);
@@ -45959,7 +46007,7 @@ ${message}`));
45959
46007
  };
45960
46008
  const finish = (value) => {
45961
46009
  cleanup();
45962
- resolve8(value);
46010
+ resolve9(value);
45963
46011
  };
45964
46012
  const onKeypress = (_, key) => {
45965
46013
  if (key.ctrl && key.name === "c") {
@@ -48169,7 +48217,7 @@ async function taskAction(agent, options) {
48169
48217
  waitForUiExit = renderedShell.waitUntilExit;
48170
48218
  rerenderUi = renderedShell.rerender;
48171
48219
  unmountUi = renderedShell.unmount;
48172
- await new Promise((resolve8) => setTimeout(resolve8, 0));
48220
+ await new Promise((resolve9) => setTimeout(resolve9, 0));
48173
48221
  if (!startupShellRef.current) {
48174
48222
  exitAltScreen();
48175
48223
  unmountUi?.();
@@ -48715,7 +48763,7 @@ Saving state... done. Session saved to ${filePath}`);
48715
48763
  waitForUiExit = renderedApp.waitUntilExit;
48716
48764
  unmountUi = renderedApp.unmount;
48717
48765
  }
48718
- await new Promise((resolve8) => setTimeout(resolve8, 0));
48766
+ await new Promise((resolve9) => setTimeout(resolve9, 0));
48719
48767
  const streamActions = streamRef.current;
48720
48768
  if (!streamActions) {
48721
48769
  exitAltScreen();
@@ -48840,7 +48888,7 @@ Saving state... done. Session saved to ${filePath}`);
48840
48888
  };
48841
48889
  if (event.phase === "start") {
48842
48890
  currentActions.startContextCompaction(absoluteEvent);
48843
- await new Promise((resolve8) => setTimeout(resolve8, 0));
48891
+ await new Promise((resolve9) => setTimeout(resolve9, 0));
48844
48892
  return;
48845
48893
  }
48846
48894
  currentActions.finishContextCompaction(absoluteEvent);
@@ -50058,24 +50106,23 @@ schedulesCommand.command("get <id>").description("Get schedule details").option(
50058
50106
  const { waitUntilExit } = render12(React12.createElement(App));
50059
50107
  await waitUntilExit();
50060
50108
  });
50061
- schedulesCommand.command("create").description("Create a new schedule").requiredOption("-f, --flow <id>", "Flow ID to schedule").requiredOption("-c, --cron <expression>", 'Cron expression (e.g. "0 9 * * *")').option("-n, --name <name>", "Schedule name").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
50109
+ schedulesCommand.command("create").description("Create a new recurring schedule for a flow").requiredOption("-f, --flow <id>", "Flow ID to schedule").requiredOption("-c, --cron <expression>", 'Cron expression (e.g. "0 9 * * *")').requiredOption("-z, --timezone <tz>", 'IANA timezone for the cron schedule (e.g. "America/Los_Angeles")').option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
50062
50110
  const apiKey = await ensureAuth();
50063
50111
  if (!apiKey) return;
50064
50112
  const client = new ApiClient(apiKey);
50113
+ const payload = {
50114
+ target: { flowId: options.flow },
50115
+ trigger: { type: "recurring", cron: options.cron, timezone: options.timezone }
50116
+ };
50065
50117
  if (!isTTY(options) || options.json) {
50066
50118
  try {
50067
- const data = await client.post("/schedules", {
50068
- flowId: options.flow,
50069
- cronExpression: options.cron,
50070
- name: options.name
50071
- });
50119
+ const data = await client.post("/schedules", payload);
50072
50120
  if (options.json) {
50073
50121
  printJson(data);
50074
50122
  return;
50075
50123
  }
50076
50124
  console.log(` ID: ${data.id}`);
50077
50125
  if (data.name) console.log(` Name: ${data.name}`);
50078
- console.log(` Cron: ${data.cronExpression}`);
50079
50126
  if (data.nextRunAt) console.log(` Next run: ${data.nextRunAt}`);
50080
50127
  } catch (error51) {
50081
50128
  const message = error51 instanceof Error ? error51.message : "Unknown error";
@@ -50090,11 +50137,7 @@ schedulesCommand.command("create").description("Create a new schedule").required
50090
50137
  const [error51, setError] = useState26(null);
50091
50138
  const [result, setResult] = useState26(null);
50092
50139
  useEffect23(() => {
50093
- client.post("/schedules", {
50094
- flowId: options.flow,
50095
- cronExpression: options.cron,
50096
- name: options.name
50097
- }).then((data) => {
50140
+ client.post("/schedules", payload).then((data) => {
50098
50141
  setResult(data);
50099
50142
  setSuccess(true);
50100
50143
  setLoading(false);
@@ -50114,7 +50157,6 @@ schedulesCommand.command("create").description("Create a new schedule").required
50114
50157
  fields: [
50115
50158
  { label: "ID", value: result.id, color: "green" },
50116
50159
  { label: "Name", value: result.name },
50117
- { label: "Cron", value: result.cronExpression },
50118
50160
  { label: "Next run", value: result.nextRunAt }
50119
50161
  ]
50120
50162
  }) : void 0
@@ -50252,14 +50294,14 @@ import React13 from "react";
50252
50294
  import { render as render13 } from "ink";
50253
50295
  import { useState as useState27, useEffect as useEffect24 } from "react";
50254
50296
  import { Text as Text30 } from "ink";
50255
- import { readFileSync as readFileSync13 } from "fs";
50297
+ import { readFileSync as readFileSync14 } from "fs";
50256
50298
  var evalCommand = new Command14("eval").description("Manage evaluations");
50257
50299
  evalCommand.command("submit").description("Submit an eval batch").requiredOption("-f, --flow <id>", "Flow ID to evaluate").requiredOption("-r, --records <file>", "JSON file with record IDs").option("-n, --name <name>", "Eval batch name").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
50258
50300
  const apiKey = await ensureAuth();
50259
50301
  if (!apiKey) return;
50260
50302
  let recordIds;
50261
50303
  try {
50262
- const content = readFileSync13(options.records, "utf-8");
50304
+ const content = readFileSync14(options.records, "utf-8");
50263
50305
  const parsed = JSON.parse(content);
50264
50306
  recordIds = Array.isArray(parsed) ? parsed : parsed.recordIds || parsed.records || [];
50265
50307
  } catch (error51) {
@@ -50817,13 +50859,13 @@ apiKeysCommand.command("delete <id>").description("Delete an API key").option("-
50817
50859
  await waitUntilExit2();
50818
50860
  return;
50819
50861
  }
50820
- const confirmed = await new Promise((resolve8) => {
50862
+ const confirmed = await new Promise((resolve9) => {
50821
50863
  const { unmount } = render14(
50822
50864
  React14.createElement(ConfirmPrompt, {
50823
50865
  message: `Delete API key ${id}?`,
50824
50866
  defaultValue: false,
50825
50867
  onConfirm: (result) => {
50826
- resolve8(result);
50868
+ resolve9(result);
50827
50869
  unmount();
50828
50870
  }
50829
50871
  })
@@ -51289,13 +51331,13 @@ clientTokensCommand.command("delete <id>").description("Delete a client token").
51289
51331
  await waitUntilExit2();
51290
51332
  return;
51291
51333
  }
51292
- const confirmed = await new Promise((resolve8) => {
51334
+ const confirmed = await new Promise((resolve9) => {
51293
51335
  const { unmount } = render15(
51294
51336
  React15.createElement(ConfirmPrompt, {
51295
51337
  message: `Delete client token ${id}?`,
51296
51338
  defaultValue: false,
51297
51339
  onConfirm: (result) => {
51298
- resolve8(result);
51340
+ resolve9(result);
51299
51341
  unmount();
51300
51342
  }
51301
51343
  })
@@ -51600,8 +51642,8 @@ function defaultTokenName(agentName) {
51600
51642
  }
51601
51643
  async function promptLine(rl, question, defaultValue) {
51602
51644
  const hint = defaultValue ? chalk23.dim(` (${defaultValue})`) : "";
51603
- const answer = await new Promise((resolve8) => {
51604
- rl.question(`${question}${hint}: `, resolve8);
51645
+ const answer = await new Promise((resolve9) => {
51646
+ rl.question(`${question}${hint}: `, resolve9);
51605
51647
  });
51606
51648
  const trimmed = answer.trim();
51607
51649
  if (!trimmed && defaultValue !== void 0) {
@@ -51611,8 +51653,8 @@ async function promptLine(rl, question, defaultValue) {
51611
51653
  }
51612
51654
  async function promptConfirm2(rl, message, defaultYes = false) {
51613
51655
  const hint = defaultYes ? chalk23.dim(" (Y/n)") : chalk23.dim(" (y/N)");
51614
- const answer = await new Promise((resolve8) => {
51615
- rl.question(`${message}${hint}: `, resolve8);
51656
+ const answer = await new Promise((resolve9) => {
51657
+ rl.question(`${message}${hint}: `, resolve9);
51616
51658
  });
51617
51659
  const t = answer.trim().toLowerCase();
51618
51660
  if (t === "") return defaultYes;
@@ -51681,18 +51723,18 @@ Dashboard: ${initial.dashboardUrl}`));
51681
51723
  process.stdin.removeAllListeners("keypress");
51682
51724
  process.stdin.pause();
51683
51725
  };
51684
- await new Promise((resolve8) => {
51726
+ await new Promise((resolve9) => {
51685
51727
  const onKeypress = async (_str, key) => {
51686
51728
  if (!key) return;
51687
51729
  if (key.ctrl && key.name === "c") {
51688
51730
  cleanup();
51689
- resolve8();
51731
+ resolve9();
51690
51732
  process.exit(0);
51691
51733
  }
51692
51734
  const name = key.name;
51693
51735
  if (name === "q" || name === "escape") {
51694
51736
  cleanup();
51695
- resolve8();
51737
+ resolve9();
51696
51738
  return;
51697
51739
  }
51698
51740
  if (name === "c") {
@@ -52778,11 +52820,11 @@ async function runTail(options) {
52778
52820
  process.stderr.write(
52779
52821
  (useColor ? chalk27.gray(`Retrying in ${delay / 1e3}s (attempt ${attempt}/${MAX_ATTEMPTS})...`) : `Retrying in ${delay / 1e3}s (attempt ${attempt}/${MAX_ATTEMPTS})...`) + "\n"
52780
52822
  );
52781
- await new Promise((resolve8) => {
52782
- const timer = setTimeout(resolve8, delay);
52823
+ await new Promise((resolve9) => {
52824
+ const timer = setTimeout(resolve9, delay);
52783
52825
  const onAbort = () => {
52784
52826
  clearTimeout(timer);
52785
- resolve8();
52827
+ resolve9();
52786
52828
  };
52787
52829
  controller.signal.addEventListener("abort", onAbort, { once: true });
52788
52830
  });
@@ -52798,7 +52840,7 @@ var tailCommand = new Command21("tail").description("Stream live execution logs
52798
52840
  // src/commands/validate-product.ts
52799
52841
  import { Command as Command22, Option } from "commander";
52800
52842
  import chalk28 from "chalk";
52801
- import { readFileSync as readFileSync14 } from "fs";
52843
+ import { readFileSync as readFileSync15 } from "fs";
52802
52844
  function createValidateProductCommand() {
52803
52845
  return new Command22("validate-product").description("Validate a product (FPO) or FPO template locally (no API call)").argument(
52804
52846
  "[input]",
@@ -52878,7 +52920,7 @@ async function readInput(input) {
52878
52920
  if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
52879
52921
  return trimmed;
52880
52922
  }
52881
- return readFileSync14(input, "utf-8");
52923
+ return readFileSync15(input, "utf-8");
52882
52924
  }
52883
52925
  async function readStdin() {
52884
52926
  if (process.stdin.isTTY) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runtypelabs/cli",
3
- "version": "2.12.2",
3
+ "version": "2.12.4",
4
4
  "description": "Command-line interface for Runtype AI platform",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,7 +11,6 @@
11
11
  "chalk": "^5.3.0",
12
12
  "commander": "^12.0.0",
13
13
  "conf": "^13.0.0",
14
- "dotenv": "^16.4.5",
15
14
  "express": "^5.2.1",
16
15
  "ink": "6.7.0",
17
16
  "ink-select-input": "^6.2.0",
@@ -22,7 +21,7 @@
22
21
  "micromatch": "^4.0.8",
23
22
  "yaml": "^2.8.3",
24
23
  "@runtypelabs/ink-components": "0.3.1",
25
- "@runtypelabs/sdk": "1.21.0",
24
+ "@runtypelabs/sdk": "1.21.1",
26
25
  "@runtypelabs/terminal-animations": "0.2.0"
27
26
  },
28
27
  "devDependencies": {
@@ -36,7 +35,7 @@
36
35
  "tsx": "^4.7.1",
37
36
  "typescript": "^5.3.3",
38
37
  "vitest": "^4.0.18",
39
- "@runtypelabs/shared": "1.6.0"
38
+ "@runtypelabs/shared": "1.6.1"
40
39
  },
41
40
  "engines": {
42
41
  "node": ">=18.0.0"