@runtypelabs/cli 2.12.2 → 2.12.3

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 +70 -53
  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) => {
@@ -36024,7 +36041,7 @@ import chalk4 from "chalk";
36024
36041
  import React2 from "react";
36025
36042
  import { render as render2 } from "ink";
36026
36043
  import { useState as useState3, useEffect as useEffect4 } from "react";
36027
- import { readFileSync as readFileSync2 } from "fs";
36044
+ import { readFileSync as readFileSync3 } from "fs";
36028
36045
  import { processStream } from "@runtypelabs/sdk";
36029
36046
 
36030
36047
  // src/lib/ensure-auth.ts
@@ -36039,14 +36056,14 @@ async function promptConfirm(message, options) {
36039
36056
  output: process.stdout,
36040
36057
  terminal: true
36041
36058
  });
36042
- return new Promise((resolve8) => {
36059
+ return new Promise((resolve9) => {
36043
36060
  rl.question(chalk2.cyan(`${message} (${hint}): `), (answer) => {
36044
36061
  rl.close();
36045
36062
  const trimmed = answer.trim().toLowerCase();
36046
36063
  if (trimmed === "") {
36047
- resolve8(defaultYes);
36064
+ resolve9(defaultYes);
36048
36065
  } else {
36049
- resolve8(trimmed === "y" || trimmed === "yes");
36066
+ resolve9(trimmed === "y" || trimmed === "yes");
36050
36067
  }
36051
36068
  });
36052
36069
  });
@@ -36112,7 +36129,7 @@ async function handleBrowserLogin(store, apiUrl) {
36112
36129
  }
36113
36130
 
36114
36131
  // src/lib/cli-version.ts
36115
- import { readFileSync } from "fs";
36132
+ import { readFileSync as readFileSync2 } from "fs";
36116
36133
  import { dirname, join } from "path";
36117
36134
  import { fileURLToPath } from "url";
36118
36135
  var CLI_PACKAGE_NAME = "@runtypelabs/cli";
@@ -36130,7 +36147,7 @@ function getCliVersion() {
36130
36147
  ];
36131
36148
  for (const pkgPath of candidates) {
36132
36149
  try {
36133
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
36150
+ const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
36134
36151
  if (pkg.name === CLI_PACKAGE_NAME && pkg.version) {
36135
36152
  cachedCliVersion = pkg.version;
36136
36153
  return cachedCliVersion;
@@ -36487,7 +36504,7 @@ flowsCommand.command("create").description("Create a new flow").requiredOption("
36487
36504
  };
36488
36505
  if (options.fromFile) {
36489
36506
  try {
36490
- const fileContent = JSON.parse(readFileSync2(options.fromFile, "utf-8"));
36507
+ const fileContent = JSON.parse(readFileSync3(options.fromFile, "utf-8"));
36491
36508
  if (fileContent.flow) {
36492
36509
  body = { ...fileContent.flow, name: options.name || fileContent.flow.name };
36493
36510
  } else {
@@ -37116,14 +37133,14 @@ import chalk7 from "chalk";
37116
37133
  import React5 from "react";
37117
37134
  import { render as render5 } from "ink";
37118
37135
  import { useState as useState6, useEffect as useEffect7 } from "react";
37119
- import { readFileSync as readFileSync3 } from "fs";
37136
+ import { readFileSync as readFileSync4 } from "fs";
37120
37137
  var batchCommand = new Command5("batch").description("Manage batch operations");
37121
37138
  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
37139
  const apiKey = await ensureAuth();
37123
37140
  if (!apiKey) return;
37124
37141
  let recordIds;
37125
37142
  try {
37126
- const content = readFileSync3(options.records, "utf-8");
37143
+ const content = readFileSync4(options.records, "utf-8");
37127
37144
  const parsed = JSON.parse(content);
37128
37145
  recordIds = Array.isArray(parsed) ? parsed : parsed.recordIds || parsed.records || [];
37129
37146
  } catch (error51) {
@@ -38485,7 +38502,7 @@ import chalk10 from "chalk";
38485
38502
  import React8 from "react";
38486
38503
  import { render as render8 } from "ink";
38487
38504
  import { useState as useState9, useEffect as useEffect10 } from "react";
38488
- import { readFileSync as readFileSync4 } from "fs";
38505
+ import { readFileSync as readFileSync5 } from "fs";
38489
38506
  import { processStream as processStream3 } from "@runtypelabs/sdk";
38490
38507
  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
38508
  if (!options.flow && !options.agent) {
@@ -38506,7 +38523,7 @@ var dispatchCommand = new Command9("dispatch").description("Execute a flow or ag
38506
38523
  payload.record = { id: options.record };
38507
38524
  } else if (options.recordJson) {
38508
38525
  try {
38509
- const data = JSON.parse(readFileSync4(options.recordJson, "utf-8"));
38526
+ const data = JSON.parse(readFileSync5(options.recordJson, "utf-8"));
38510
38527
  payload.record = { metadata: data };
38511
38528
  } catch (error51) {
38512
38529
  const message = error51 instanceof Error ? error51.message : "Unknown error";
@@ -43738,8 +43755,8 @@ function MarathonApp({
43738
43755
  setIsTerminalCheckpoint(true);
43739
43756
  isTerminalCheckpointRef.current = true;
43740
43757
  }
43741
- return new Promise((resolve8) => {
43742
- checkpointResolveRef.current = resolve8;
43758
+ return new Promise((resolve9) => {
43759
+ checkpointResolveRef.current = resolve9;
43743
43760
  });
43744
43761
  },
43745
43762
  updateMilestone: (milestone) => {
@@ -45066,16 +45083,16 @@ function MarathonStartupShell({
45066
45083
  latestAppPropsRef.current = marathonAppProps;
45067
45084
  useEffect20(() => {
45068
45085
  if (scene !== "app" || !appReadyResolverRef.current) return;
45069
- const resolve8 = appReadyResolverRef.current;
45086
+ const resolve9 = appReadyResolverRef.current;
45070
45087
  appReadyResolverRef.current = null;
45071
- resolve8();
45088
+ resolve9();
45072
45089
  }, [scene]);
45073
45090
  const beginTransition = (target) => {
45074
45091
  if (transitionPromiseRef.current) return transitionPromiseRef.current;
45075
45092
  if (target === "app" && !latestAppPropsRef.current) {
45076
45093
  throw new Error("Cannot complete startup before marathon app props are ready.");
45077
45094
  }
45078
- const promise2 = new Promise((resolve8) => {
45095
+ const promise2 = new Promise((resolve9) => {
45079
45096
  globalThis.setTimeout(() => {
45080
45097
  setPrompt(null);
45081
45098
  setModelChoices(null);
@@ -45096,12 +45113,12 @@ function MarathonStartupShell({
45096
45113
  if (target === "app") {
45097
45114
  appReadyResolverRef.current = () => {
45098
45115
  transitionPromiseRef.current = null;
45099
- resolve8();
45116
+ resolve9();
45100
45117
  };
45101
45118
  } else {
45102
45119
  dismissResolverRef.current = () => {
45103
45120
  transitionPromiseRef.current = null;
45104
- resolve8();
45121
+ resolve9();
45105
45122
  };
45106
45123
  }
45107
45124
  }, Math.max(0, MIN_HOLD_MS - (Date.now() - mountedAtRef.current)));
@@ -45118,8 +45135,8 @@ function MarathonStartupShell({
45118
45135
  setModelChoices(null);
45119
45136
  setPrompt(nextPrompt);
45120
45137
  setSelectedPromptIndex(0);
45121
- return new Promise((resolve8) => {
45122
- promptResolverRef.current = resolve8;
45138
+ return new Promise((resolve9) => {
45139
+ promptResolverRef.current = resolve9;
45123
45140
  });
45124
45141
  },
45125
45142
  requestModelChoice: async (nextCurrentModel, models) => {
@@ -45127,8 +45144,8 @@ function MarathonStartupShell({
45127
45144
  setPlaybookConfirm(null);
45128
45145
  setCurrentModel(nextCurrentModel);
45129
45146
  setModelChoices(models);
45130
- return new Promise((resolve8) => {
45131
- modelResolverRef.current = resolve8;
45147
+ return new Promise((resolve9) => {
45148
+ modelResolverRef.current = resolve9;
45132
45149
  });
45133
45150
  },
45134
45151
  requestPlaybookModelConfirm: async (playbookName, milestoneModels) => {
@@ -45143,8 +45160,8 @@ function MarathonStartupShell({
45143
45160
  // Default selection is the "Confirm" action (first item after milestones)
45144
45161
  selectedIndex: names.length
45145
45162
  });
45146
- return new Promise((resolve8) => {
45147
- playbookConfirmResolverRef.current = resolve8;
45163
+ return new Promise((resolve9) => {
45164
+ playbookConfirmResolverRef.current = resolve9;
45148
45165
  });
45149
45166
  },
45150
45167
  completeStartup: () => beginTransition("app"),
@@ -45642,7 +45659,7 @@ async function retryOnNetworkError(fn, opts = {}) {
45642
45659
  }
45643
45660
  const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);
45644
45661
  opts.onRetry?.(attempt + 1, delay, error51);
45645
- await new Promise((resolve8) => setTimeout(resolve8, delay));
45662
+ await new Promise((resolve9) => setTimeout(resolve9, delay));
45646
45663
  }
45647
45664
  }
45648
45665
  throw lastError;
@@ -45902,14 +45919,14 @@ async function promptNumericSelect(choices, promptLabel) {
45902
45919
  output: process.stdout,
45903
45920
  terminal: true
45904
45921
  });
45905
- return new Promise((resolve8) => {
45922
+ return new Promise((resolve9) => {
45906
45923
  const ask = () => {
45907
45924
  rl.question(chalk14.cyan(`
45908
45925
  ${promptLabel} (1-${choices.length}): `), (answer) => {
45909
45926
  const value = parseInt(answer.trim(), 10);
45910
45927
  if (value >= 1 && value <= choices.length) {
45911
45928
  rl.close();
45912
- resolve8(choices[value - 1].value);
45929
+ resolve9(choices[value - 1].value);
45913
45930
  return;
45914
45931
  }
45915
45932
  console.log(chalk14.red(`Please enter a number between 1 and ${choices.length}.`));
@@ -45937,7 +45954,7 @@ ${message}`));
45937
45954
  const previousRawMode = input.isRaw === true;
45938
45955
  let selectedIndex = 0;
45939
45956
  let renderedLineCount = 0;
45940
- return new Promise((resolve8) => {
45957
+ return new Promise((resolve9) => {
45941
45958
  const renderMenu = () => {
45942
45959
  if (renderedLineCount > 0) {
45943
45960
  clearRenderedLines(output, renderedLineCount);
@@ -45959,7 +45976,7 @@ ${message}`));
45959
45976
  };
45960
45977
  const finish = (value) => {
45961
45978
  cleanup();
45962
- resolve8(value);
45979
+ resolve9(value);
45963
45980
  };
45964
45981
  const onKeypress = (_, key) => {
45965
45982
  if (key.ctrl && key.name === "c") {
@@ -48169,7 +48186,7 @@ async function taskAction(agent, options) {
48169
48186
  waitForUiExit = renderedShell.waitUntilExit;
48170
48187
  rerenderUi = renderedShell.rerender;
48171
48188
  unmountUi = renderedShell.unmount;
48172
- await new Promise((resolve8) => setTimeout(resolve8, 0));
48189
+ await new Promise((resolve9) => setTimeout(resolve9, 0));
48173
48190
  if (!startupShellRef.current) {
48174
48191
  exitAltScreen();
48175
48192
  unmountUi?.();
@@ -48715,7 +48732,7 @@ Saving state... done. Session saved to ${filePath}`);
48715
48732
  waitForUiExit = renderedApp.waitUntilExit;
48716
48733
  unmountUi = renderedApp.unmount;
48717
48734
  }
48718
- await new Promise((resolve8) => setTimeout(resolve8, 0));
48735
+ await new Promise((resolve9) => setTimeout(resolve9, 0));
48719
48736
  const streamActions = streamRef.current;
48720
48737
  if (!streamActions) {
48721
48738
  exitAltScreen();
@@ -48840,7 +48857,7 @@ Saving state... done. Session saved to ${filePath}`);
48840
48857
  };
48841
48858
  if (event.phase === "start") {
48842
48859
  currentActions.startContextCompaction(absoluteEvent);
48843
- await new Promise((resolve8) => setTimeout(resolve8, 0));
48860
+ await new Promise((resolve9) => setTimeout(resolve9, 0));
48844
48861
  return;
48845
48862
  }
48846
48863
  currentActions.finishContextCompaction(absoluteEvent);
@@ -50252,14 +50269,14 @@ import React13 from "react";
50252
50269
  import { render as render13 } from "ink";
50253
50270
  import { useState as useState27, useEffect as useEffect24 } from "react";
50254
50271
  import { Text as Text30 } from "ink";
50255
- import { readFileSync as readFileSync13 } from "fs";
50272
+ import { readFileSync as readFileSync14 } from "fs";
50256
50273
  var evalCommand = new Command14("eval").description("Manage evaluations");
50257
50274
  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
50275
  const apiKey = await ensureAuth();
50259
50276
  if (!apiKey) return;
50260
50277
  let recordIds;
50261
50278
  try {
50262
- const content = readFileSync13(options.records, "utf-8");
50279
+ const content = readFileSync14(options.records, "utf-8");
50263
50280
  const parsed = JSON.parse(content);
50264
50281
  recordIds = Array.isArray(parsed) ? parsed : parsed.recordIds || parsed.records || [];
50265
50282
  } catch (error51) {
@@ -50817,13 +50834,13 @@ apiKeysCommand.command("delete <id>").description("Delete an API key").option("-
50817
50834
  await waitUntilExit2();
50818
50835
  return;
50819
50836
  }
50820
- const confirmed = await new Promise((resolve8) => {
50837
+ const confirmed = await new Promise((resolve9) => {
50821
50838
  const { unmount } = render14(
50822
50839
  React14.createElement(ConfirmPrompt, {
50823
50840
  message: `Delete API key ${id}?`,
50824
50841
  defaultValue: false,
50825
50842
  onConfirm: (result) => {
50826
- resolve8(result);
50843
+ resolve9(result);
50827
50844
  unmount();
50828
50845
  }
50829
50846
  })
@@ -51289,13 +51306,13 @@ clientTokensCommand.command("delete <id>").description("Delete a client token").
51289
51306
  await waitUntilExit2();
51290
51307
  return;
51291
51308
  }
51292
- const confirmed = await new Promise((resolve8) => {
51309
+ const confirmed = await new Promise((resolve9) => {
51293
51310
  const { unmount } = render15(
51294
51311
  React15.createElement(ConfirmPrompt, {
51295
51312
  message: `Delete client token ${id}?`,
51296
51313
  defaultValue: false,
51297
51314
  onConfirm: (result) => {
51298
- resolve8(result);
51315
+ resolve9(result);
51299
51316
  unmount();
51300
51317
  }
51301
51318
  })
@@ -51600,8 +51617,8 @@ function defaultTokenName(agentName) {
51600
51617
  }
51601
51618
  async function promptLine(rl, question, defaultValue) {
51602
51619
  const hint = defaultValue ? chalk23.dim(` (${defaultValue})`) : "";
51603
- const answer = await new Promise((resolve8) => {
51604
- rl.question(`${question}${hint}: `, resolve8);
51620
+ const answer = await new Promise((resolve9) => {
51621
+ rl.question(`${question}${hint}: `, resolve9);
51605
51622
  });
51606
51623
  const trimmed = answer.trim();
51607
51624
  if (!trimmed && defaultValue !== void 0) {
@@ -51611,8 +51628,8 @@ async function promptLine(rl, question, defaultValue) {
51611
51628
  }
51612
51629
  async function promptConfirm2(rl, message, defaultYes = false) {
51613
51630
  const hint = defaultYes ? chalk23.dim(" (Y/n)") : chalk23.dim(" (y/N)");
51614
- const answer = await new Promise((resolve8) => {
51615
- rl.question(`${message}${hint}: `, resolve8);
51631
+ const answer = await new Promise((resolve9) => {
51632
+ rl.question(`${message}${hint}: `, resolve9);
51616
51633
  });
51617
51634
  const t = answer.trim().toLowerCase();
51618
51635
  if (t === "") return defaultYes;
@@ -51681,18 +51698,18 @@ Dashboard: ${initial.dashboardUrl}`));
51681
51698
  process.stdin.removeAllListeners("keypress");
51682
51699
  process.stdin.pause();
51683
51700
  };
51684
- await new Promise((resolve8) => {
51701
+ await new Promise((resolve9) => {
51685
51702
  const onKeypress = async (_str, key) => {
51686
51703
  if (!key) return;
51687
51704
  if (key.ctrl && key.name === "c") {
51688
51705
  cleanup();
51689
- resolve8();
51706
+ resolve9();
51690
51707
  process.exit(0);
51691
51708
  }
51692
51709
  const name = key.name;
51693
51710
  if (name === "q" || name === "escape") {
51694
51711
  cleanup();
51695
- resolve8();
51712
+ resolve9();
51696
51713
  return;
51697
51714
  }
51698
51715
  if (name === "c") {
@@ -52778,11 +52795,11 @@ async function runTail(options) {
52778
52795
  process.stderr.write(
52779
52796
  (useColor ? chalk27.gray(`Retrying in ${delay / 1e3}s (attempt ${attempt}/${MAX_ATTEMPTS})...`) : `Retrying in ${delay / 1e3}s (attempt ${attempt}/${MAX_ATTEMPTS})...`) + "\n"
52780
52797
  );
52781
- await new Promise((resolve8) => {
52782
- const timer = setTimeout(resolve8, delay);
52798
+ await new Promise((resolve9) => {
52799
+ const timer = setTimeout(resolve9, delay);
52783
52800
  const onAbort = () => {
52784
52801
  clearTimeout(timer);
52785
- resolve8();
52802
+ resolve9();
52786
52803
  };
52787
52804
  controller.signal.addEventListener("abort", onAbort, { once: true });
52788
52805
  });
@@ -52798,7 +52815,7 @@ var tailCommand = new Command21("tail").description("Stream live execution logs
52798
52815
  // src/commands/validate-product.ts
52799
52816
  import { Command as Command22, Option } from "commander";
52800
52817
  import chalk28 from "chalk";
52801
- import { readFileSync as readFileSync14 } from "fs";
52818
+ import { readFileSync as readFileSync15 } from "fs";
52802
52819
  function createValidateProductCommand() {
52803
52820
  return new Command22("validate-product").description("Validate a product (FPO) or FPO template locally (no API call)").argument(
52804
52821
  "[input]",
@@ -52878,7 +52895,7 @@ async function readInput(input) {
52878
52895
  if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
52879
52896
  return trimmed;
52880
52897
  }
52881
- return readFileSync14(input, "utf-8");
52898
+ return readFileSync15(input, "utf-8");
52882
52899
  }
52883
52900
  async function readStdin() {
52884
52901
  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.3",
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,8 +21,8 @@
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",
26
- "@runtypelabs/terminal-animations": "0.2.0"
24
+ "@runtypelabs/terminal-animations": "0.2.0",
25
+ "@runtypelabs/sdk": "1.21.0"
27
26
  },
28
27
  "devDependencies": {
29
28
  "@types/micromatch": "^4.0.9",