@runtypelabs/cli 2.5.0 → 2.6.0

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 CHANGED
@@ -15376,8 +15376,8 @@ var require_provider_routing = __commonJS({
15376
15376
  });
15377
15377
 
15378
15378
  // src/index.ts
15379
- import { Command as Command20 } from "commander";
15380
- import chalk27 from "chalk";
15379
+ import { Command as Command21 } from "commander";
15380
+ import chalk28 from "chalk";
15381
15381
  import { config as loadEnv } from "dotenv";
15382
15382
 
15383
15383
  // src/commands/auth.ts
@@ -31682,14 +31682,538 @@ clientTokensCommand.command("regenerate <id>").description("Regenerate a client
31682
31682
  await waitUntilExit();
31683
31683
  });
31684
31684
 
31685
- // src/commands/analytics.ts
31685
+ // src/commands/persona.ts
31686
31686
  import { Command as Command17 } from "commander";
31687
31687
  import chalk23 from "chalk";
31688
+ import readline3 from "readline";
31689
+ import open5 from "open";
31690
+ import { execFile as execFileCallback } from "child_process";
31691
+ import { promisify } from "util";
31692
+
31693
+ // src/lib/persona-init.ts
31694
+ init_credential_store();
31695
+
31696
+ // src/lib/persona-snippets.ts
31697
+ function mapCliFormatToPersona(cli) {
31698
+ switch (cli) {
31699
+ case "script-installer":
31700
+ return "script-installer";
31701
+ case "script-manual":
31702
+ return "script-advanced";
31703
+ case "esm":
31704
+ case "react":
31705
+ return "react-component";
31706
+ default: {
31707
+ const _exhaustive = cli;
31708
+ return _exhaustive;
31709
+ }
31710
+ }
31711
+ }
31712
+ function parsePersonaInitFormat(raw) {
31713
+ const normalized = raw.trim().toLowerCase();
31714
+ if (normalized === "script-installer" || normalized === "script-manual" || normalized === "esm" || normalized === "react") {
31715
+ return normalized;
31716
+ }
31717
+ throw new Error(
31718
+ `Invalid --format "${raw}". Use: script-installer | script-manual | esm | react`
31719
+ );
31720
+ }
31721
+ var PERSONA_CDN_BASE = "https://cdn.jsdelivr.net/npm/@runtypelabs/persona@latest/dist";
31722
+ function mountIdFromSelector(sel) {
31723
+ const s = sel.trim();
31724
+ if (s.startsWith("#")) return s.slice(1);
31725
+ return s || "chat";
31726
+ }
31727
+ function escapeHtmlAttr(s) {
31728
+ return s.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/'/g, "&#39;").replace(/</g, "&lt;");
31729
+ }
31730
+ function buildScriptInstaller(input) {
31731
+ const targetSel = input.targetSelector?.trim() || void 0;
31732
+ if (!targetSel) {
31733
+ return `<script
31734
+ src="${PERSONA_CDN_BASE}/install.global.js"
31735
+ data-runtype-token="${escapeHtmlAttr(input.clientToken)}"
31736
+ ></script>`.trim();
31737
+ }
31738
+ const id = mountIdFromSelector(targetSel);
31739
+ const cfg = JSON.stringify({ target: targetSel, apiUrl: input.apiUrl });
31740
+ return `<div id="${escapeHtmlAttr(id)}"></div>
31741
+ <script
31742
+ src="${PERSONA_CDN_BASE}/install.global.js"
31743
+ data-runtype-token="${escapeHtmlAttr(input.clientToken)}"
31744
+ data-config='${cfg.replace(/'/g, "&#39;")}'
31745
+ ></script>`.trim();
31746
+ }
31747
+ function buildScriptAdvancedHtml(input) {
31748
+ const targetSel = input.targetSelector?.trim() || void 0;
31749
+ const apiUrl = JSON.stringify(input.apiUrl);
31750
+ const token = JSON.stringify(input.clientToken);
31751
+ const targetJson = JSON.stringify(targetSel || "body");
31752
+ const divLine = targetSel ? `<div id="${escapeHtmlAttr(mountIdFromSelector(targetSel))}"></div>
31753
+ ` : "";
31754
+ return `<link rel="stylesheet" href="${PERSONA_CDN_BASE}/widget.css" />
31755
+ ${divLine}<script type="module">
31756
+ import { initAgentWidget, markdownPostprocessor } from '${PERSONA_CDN_BASE}/index.js';
31757
+
31758
+ initAgentWidget({
31759
+ target: ${targetJson},
31760
+ config: {
31761
+ apiUrl: ${apiUrl},
31762
+ clientToken: ${token},
31763
+ parserType: 'json',
31764
+ postprocessMessage: ({ text }) => markdownPostprocessor(text),
31765
+ launcher: {
31766
+ enabled: true,
31767
+ title: 'Chat',
31768
+ subtitle: 'How can I help you today?',
31769
+ position: 'bottom-right',
31770
+ },
31771
+ },
31772
+ });
31773
+ </script>`.trim();
31774
+ }
31775
+ function buildReactComponentSnippet(input) {
31776
+ const targetSel = input.targetSelector?.trim() || void 0;
31777
+ const apiUrl = JSON.stringify(input.apiUrl);
31778
+ const token = JSON.stringify(input.clientToken);
31779
+ const targetStr = JSON.stringify(targetSel || "body");
31780
+ return `import "@runtypelabs/persona/widget.css";
31781
+ import { DEFAULT_WIDGET_CONFIG, initAgentWidget, markdownPostprocessor } from "@runtypelabs/persona";
31782
+
31783
+ initAgentWidget({
31784
+ target: ${targetStr},
31785
+ config: {
31786
+ ...DEFAULT_WIDGET_CONFIG,
31787
+ apiUrl: ${apiUrl},
31788
+ clientToken: ${token},
31789
+ parserType: "json",
31790
+ postprocessMessage: ({ text }) => markdownPostprocessor(text),
31791
+ },
31792
+ });`.trim();
31793
+ }
31794
+ function generatePersonaInitSnippet(input, personaFormat) {
31795
+ switch (personaFormat) {
31796
+ case "script-installer":
31797
+ return buildScriptInstaller(input);
31798
+ case "script-advanced":
31799
+ return buildScriptAdvancedHtml(input);
31800
+ case "react-component":
31801
+ return buildReactComponentSnippet(input);
31802
+ default: {
31803
+ const _exhaustive = personaFormat;
31804
+ return _exhaustive;
31805
+ }
31806
+ }
31807
+ }
31808
+
31809
+ // src/lib/persona-init.ts
31810
+ async function getPersonaInitApiKeyNonInteractive(apiUrl) {
31811
+ const envApiKey = getRuntimeApiKey();
31812
+ if (envApiKey) {
31813
+ try {
31814
+ const apiKeyManager = new ApiKeyManager();
31815
+ const isValid = await apiKeyManager.validateApiKey(envApiKey, apiUrl);
31816
+ if (isValid) {
31817
+ return envApiKey;
31818
+ }
31819
+ } catch {
31820
+ }
31821
+ }
31822
+ const store = new CredentialStore();
31823
+ return store.getApiKey();
31824
+ }
31825
+ async function runPersonaInit(options) {
31826
+ const client = new ApiClient(options.apiKey, options.apiUrl);
31827
+ const agent = await client.post("/agents", {
31828
+ name: options.agentName,
31829
+ description: options.agentDescription
31830
+ });
31831
+ const tokenBody = {
31832
+ name: options.tokenName,
31833
+ flowIds: [],
31834
+ agentIds: [agent.id],
31835
+ allowedOrigins: options.allowedOrigins,
31836
+ environment: options.environment,
31837
+ rateLimitPerMinute: 10,
31838
+ rateLimitPerHour: 100,
31839
+ maxMessagesPerSession: 100,
31840
+ sessionIdleTimeoutMinutes: 30
31841
+ };
31842
+ const tokenRes = await client.post("/client-tokens", tokenBody);
31843
+ const personaFormat = mapCliFormatToPersona(options.format);
31844
+ const code = generatePersonaInitSnippet(
31845
+ {
31846
+ clientToken: tokenRes.token,
31847
+ apiUrl: options.apiUrl,
31848
+ targetSelector: options.targetSelector
31849
+ },
31850
+ personaFormat
31851
+ );
31852
+ const dashboardBase = getDashboardUrl();
31853
+ const dashboardUrl = `${dashboardBase}/agents/${agent.id}`;
31854
+ return {
31855
+ status: "created",
31856
+ agent: { id: agent.id, name: agent.name },
31857
+ clientToken: {
31858
+ id: tokenRes.clientToken.id,
31859
+ name: tokenRes.clientToken.name,
31860
+ token: tokenRes.token,
31861
+ environment: options.environment
31862
+ },
31863
+ snippet: { format: options.format, code },
31864
+ dashboardUrl,
31865
+ warnings: tokenRes.warnings
31866
+ };
31867
+ }
31868
+
31869
+ // src/commands/persona.ts
31870
+ var execFile = promisify(execFileCallback);
31871
+ var FORMAT_CYCLE = [
31872
+ "script-installer",
31873
+ "react",
31874
+ "script-manual",
31875
+ "esm"
31876
+ ];
31877
+ function defaultTokenName(agentName) {
31878
+ return `${agentName} Widget`;
31879
+ }
31880
+ async function promptLine(rl, question, defaultValue) {
31881
+ const hint = defaultValue ? chalk23.dim(` (${defaultValue})`) : "";
31882
+ const answer = await new Promise((resolve8) => {
31883
+ rl.question(`${question}${hint}: `, resolve8);
31884
+ });
31885
+ const trimmed = answer.trim();
31886
+ if (!trimmed && defaultValue !== void 0) {
31887
+ return defaultValue;
31888
+ }
31889
+ return trimmed;
31890
+ }
31891
+ async function promptConfirm2(rl, message, defaultYes = false) {
31892
+ const hint = defaultYes ? chalk23.dim(" (Y/n)") : chalk23.dim(" (y/N)");
31893
+ const answer = await new Promise((resolve8) => {
31894
+ rl.question(`${message}${hint}: `, resolve8);
31895
+ });
31896
+ const t = answer.trim().toLowerCase();
31897
+ if (t === "") return defaultYes;
31898
+ return t === "y" || t === "yes";
31899
+ }
31900
+ async function copyToClipboard2(text) {
31901
+ if (process.platform === "darwin") {
31902
+ await execFile("pbcopy", [], { input: text });
31903
+ return;
31904
+ }
31905
+ if (process.platform === "win32") {
31906
+ await execFile("clip", [], { shell: true, input: text });
31907
+ return;
31908
+ }
31909
+ try {
31910
+ await execFile("xclip", ["-selection", "clipboard"], { input: text });
31911
+ } catch {
31912
+ await execFile("wl-copy", [], { input: text });
31913
+ }
31914
+ }
31915
+ function isProbablyLocalDev(origins) {
31916
+ return origins.some(
31917
+ (o) => o === "http://localhost:*" || o.startsWith("http://localhost:") || o.startsWith("http://127.0.0.1:")
31918
+ );
31919
+ }
31920
+ function snippetWithFormat(format, token, apiUrl, targetSelector) {
31921
+ const personaFmt = mapCliFormatToPersona(format);
31922
+ const code = generatePersonaInitSnippet(
31923
+ { clientToken: token, apiUrl, targetSelector },
31924
+ personaFmt
31925
+ );
31926
+ return { format, code };
31927
+ }
31928
+ async function runSuccessKeyLoop(initial, apiUrl, targetSelector) {
31929
+ if (!process.stdin.isTTY) {
31930
+ return;
31931
+ }
31932
+ let currentFormat = initial.snippet.format;
31933
+ let currentCode = initial.snippet.code;
31934
+ const token = initial.clientToken.token;
31935
+ console.log(chalk23.cyan("\nPersona setup complete\n"));
31936
+ console.log(`${chalk23.bold("Agent ID:")} ${initial.agent.id}`);
31937
+ console.log(`${chalk23.bold("Client Token ID:")} ${initial.clientToken.id}`);
31938
+ console.log(`${chalk23.bold("Client Token:")} ${chalk23.yellow(token)}`);
31939
+ console.log(`${chalk23.bold("Snippet format:")} ${currentFormat}`);
31940
+ console.log(chalk23.dim(`
31941
+ Dashboard: ${initial.dashboardUrl}`));
31942
+ if (initial.warnings?.length) {
31943
+ for (const w of initial.warnings) {
31944
+ console.log(chalk23.yellow(`\u26A0 ${w.message}`));
31945
+ }
31946
+ }
31947
+ console.log(chalk23.cyan("\nKeys:"));
31948
+ console.log(` ${chalk23.green("c")} Copy snippet to clipboard`);
31949
+ console.log(` ${chalk23.green("p")} Print snippet to the terminal`);
31950
+ console.log(` ${chalk23.green("f")} Switch snippet format`);
31951
+ console.log(` ${chalk23.green("o")} Open dashboard in browser`);
31952
+ console.log(` ${chalk23.green("q")} Quit`);
31953
+ readline3.emitKeypressEvents(process.stdin);
31954
+ if (process.stdin.isTTY) {
31955
+ process.stdin.setRawMode(true);
31956
+ }
31957
+ const cleanup = () => {
31958
+ process.stdin.setRawMode(false);
31959
+ process.stdin.removeAllListeners("keypress");
31960
+ };
31961
+ await new Promise((resolve8) => {
31962
+ const onKeypress = async (_str, key) => {
31963
+ if (!key) return;
31964
+ if (key.ctrl && key.name === "c") {
31965
+ cleanup();
31966
+ resolve8();
31967
+ process.exit(0);
31968
+ }
31969
+ const name = key.name;
31970
+ if (name === "q" || name === "escape") {
31971
+ cleanup();
31972
+ resolve8();
31973
+ return;
31974
+ }
31975
+ if (name === "c") {
31976
+ try {
31977
+ await copyToClipboard2(currentCode);
31978
+ console.log(chalk23.green("Snippet copied to clipboard."));
31979
+ } catch {
31980
+ console.log(chalk23.red("Could not copy (install xclip/wl-copy on Linux, or use p)."));
31981
+ }
31982
+ return;
31983
+ }
31984
+ if (name === "p") {
31985
+ console.log(chalk23.cyan("\n--- snippet ---\n"));
31986
+ console.log(currentCode);
31987
+ console.log(chalk23.cyan("\n--- end snippet ---\n"));
31988
+ return;
31989
+ }
31990
+ if (name === "f") {
31991
+ const idx = FORMAT_CYCLE.indexOf(currentFormat);
31992
+ const next = FORMAT_CYCLE[(idx + 1) % FORMAT_CYCLE.length] ?? "script-installer";
31993
+ const nextSnippet = snippetWithFormat(next, token, apiUrl, targetSelector);
31994
+ currentFormat = nextSnippet.format;
31995
+ currentCode = nextSnippet.code;
31996
+ console.log(chalk23.dim(`Format: ${currentFormat}`));
31997
+ return;
31998
+ }
31999
+ if (name === "o") {
32000
+ try {
32001
+ await open5(initial.dashboardUrl);
32002
+ } catch {
32003
+ console.log(chalk23.red("Could not open browser."));
32004
+ }
32005
+ }
32006
+ };
32007
+ process.stdin.on("keypress", onKeypress);
32008
+ });
32009
+ }
32010
+ var personaCommand = new Command17("persona").description(
32011
+ "Set up Persona: create an agent, client token, and embed snippet"
32012
+ );
32013
+ personaCommand.command("init").description("Create agent + client token and output a Persona embed snippet").option("--agent-name <name>", "Name for the new agent").option("--agent-description <text", "Optional agent description").option("--token-name <name>", "Name for the new client token").option("--environment <env>", "Token environment: test or live", "test").option("--origins <origins...>", "Allowed origins (default: * \u2014 broad; prefer explicit URLs in production)").option(
32014
+ "--format <fmt>",
32015
+ "Snippet format: script-installer | script-manual | esm | react",
32016
+ "script-installer"
32017
+ ).option("--print-snippet", "Print the generated snippet to stdout (non-interactive summary mode)").option("--target-selector <selector>", "CSS selector for widget mount target (omit to use body)").option("--api-url <url>", "Override API base URL").option("--json", "Structured JSON output (includes snippet body)").option("--yes", "Accept defaults in interactive prompts where sensible").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(
32018
+ async (options, cmd) => {
32019
+ const globals = cmd.optsWithGlobals();
32020
+ const jsonMode = !!(options.json ?? globals.json);
32021
+ const tty = isTTY(options);
32022
+ let formatCli;
32023
+ try {
32024
+ formatCli = parsePersonaInitFormat(options.format);
32025
+ } catch (e) {
32026
+ const msg = e instanceof Error ? e.message : String(e);
32027
+ if (jsonMode) {
32028
+ console.log(JSON.stringify({ status: "error", error: msg, code: "INVALID_FORMAT" }, null, 2));
32029
+ } else {
32030
+ console.error(chalk23.red(msg));
32031
+ }
32032
+ process.exit(1);
32033
+ }
32034
+ const apiUrl = options.apiUrl || globals.apiUrl || getApiUrl();
32035
+ const targetSelector = options.targetSelector || void 0;
32036
+ let env;
32037
+ if (options.environment === "test" || options.environment === "live") {
32038
+ env = options.environment;
32039
+ } else {
32040
+ const msg = 'Error: --environment must be "test" or "live"';
32041
+ if (jsonMode) {
32042
+ console.log(JSON.stringify({ status: "error", error: msg, code: "INVALID_ENV" }, null, 2));
32043
+ } else {
32044
+ console.error(chalk23.red(msg));
32045
+ }
32046
+ process.exit(1);
32047
+ }
32048
+ const interactive = tty && !jsonMode;
32049
+ let agentName = options.agentName?.trim();
32050
+ let tokenName = options.tokenName?.trim();
32051
+ let allowedOrigins = options.origins;
32052
+ let chosenEnv = env;
32053
+ const rl = interactive && process.stdin.isTTY && process.stdout.isTTY ? readline3.createInterface({ input: process.stdin, output: process.stdout }) : null;
32054
+ if (!interactive) {
32055
+ if (!agentName) {
32056
+ const msg = "Non-interactive mode requires --agent-name";
32057
+ if (jsonMode) {
32058
+ console.log(JSON.stringify({ status: "error", error: msg, code: "MISSING_AGENT_NAME" }, null, 2));
32059
+ } else {
32060
+ console.error(chalk23.red(msg));
32061
+ }
32062
+ process.exit(1);
32063
+ }
32064
+ if (!tokenName) {
32065
+ tokenName = defaultTokenName(agentName);
32066
+ }
32067
+ if (!allowedOrigins || allowedOrigins.length === 0) {
32068
+ allowedOrigins = ["*"];
32069
+ }
32070
+ } else {
32071
+ if (!agentName) {
32072
+ agentName = await promptLine(rl, "Agent name");
32073
+ if (!agentName) {
32074
+ console.error(chalk23.red("Agent name is required"));
32075
+ process.exit(1);
32076
+ }
32077
+ }
32078
+ if (!tokenName) {
32079
+ const def = options.yes ? defaultTokenName(agentName) : defaultTokenName(agentName);
32080
+ tokenName = await promptLine(rl, "Client token name", def);
32081
+ if (!tokenName) {
32082
+ tokenName = def;
32083
+ }
32084
+ }
32085
+ if (!allowedOrigins?.length) {
32086
+ if (options.yes) {
32087
+ allowedOrigins = ["*"];
32088
+ } else {
32089
+ const originsInput = await promptLine(
32090
+ rl,
32091
+ "Allowed origins (space-separated URLs, or * for any)",
32092
+ "*"
32093
+ );
32094
+ allowedOrigins = originsInput === "*" ? ["*"] : originsInput.split(/\s+/).filter(Boolean);
32095
+ }
32096
+ }
32097
+ if (chosenEnv === "live") {
32098
+ const ok = await promptConfirm2(rl, chalk23.yellow("Create a LIVE token? This is shown only once."), false);
32099
+ if (!ok) {
32100
+ console.log(chalk23.gray("Aborted."));
32101
+ rl.close();
32102
+ process.exit(0);
32103
+ }
32104
+ } else if (!options.yes) {
32105
+ const envAns = await promptLine(rl, "Environment (test/live)", "test");
32106
+ if (envAns === "live") {
32107
+ const ok = await promptConfirm2(rl, chalk23.yellow("Create a LIVE token?"), false);
32108
+ if (!ok) {
32109
+ chosenEnv = "test";
32110
+ } else {
32111
+ chosenEnv = "live";
32112
+ }
32113
+ }
32114
+ }
32115
+ }
32116
+ if (rl) {
32117
+ rl.close();
32118
+ }
32119
+ if (allowedOrigins.includes("*") && chosenEnv === "live" && !isProbablyLocalDev(allowedOrigins)) {
32120
+ console.log(
32121
+ chalk23.yellow(
32122
+ 'Warning: allowedOrigins is "*" for a live token. Prefer explicit https:// origins in production.'
32123
+ )
32124
+ );
32125
+ }
32126
+ let apiKey;
32127
+ if (jsonMode || !tty) {
32128
+ apiKey = await getPersonaInitApiKeyNonInteractive(apiUrl);
32129
+ if (!apiKey) {
32130
+ if (jsonMode) {
32131
+ console.log(
32132
+ JSON.stringify(
32133
+ {
32134
+ status: "unauthenticated",
32135
+ message: "Set RUNTYPE_API_KEY or run `runtype auth login` (uses saved credentials)"
32136
+ },
32137
+ null,
32138
+ 2
32139
+ )
32140
+ );
32141
+ } else {
32142
+ console.error(
32143
+ chalk23.red(
32144
+ "Authentication required: set RUNTYPE_API_KEY or run `runtype auth login` for stored credentials"
32145
+ )
32146
+ );
32147
+ }
32148
+ process.exit(1);
32149
+ }
32150
+ } else {
32151
+ apiKey = await ensureAuth({ apiUrl });
32152
+ if (!apiKey) {
32153
+ process.exit(1);
32154
+ }
32155
+ }
32156
+ let success;
32157
+ try {
32158
+ success = await runPersonaInit({
32159
+ apiKey,
32160
+ apiUrl,
32161
+ agentName,
32162
+ agentDescription: options.agentDescription,
32163
+ tokenName,
32164
+ environment: chosenEnv,
32165
+ allowedOrigins,
32166
+ format: formatCli,
32167
+ targetSelector
32168
+ });
32169
+ } catch (err) {
32170
+ const message = err instanceof Error ? err.message : String(err);
32171
+ if (jsonMode) {
32172
+ console.log(JSON.stringify({ status: "error", error: message, code: "API_ERROR" }, null, 2));
32173
+ } else {
32174
+ console.error(chalk23.red("Persona init failed"));
32175
+ console.error(chalk23.red(message));
32176
+ }
32177
+ process.exit(1);
32178
+ }
32179
+ if (jsonMode) {
32180
+ printJson(success);
32181
+ return;
32182
+ }
32183
+ if (!tty || options.printSnippet) {
32184
+ console.log(chalk23.green("\nPersona setup complete\n"));
32185
+ console.log(`${chalk23.bold("Agent ID:")} ${success.agent.id}`);
32186
+ console.log(`${chalk23.bold("Client Token ID:")} ${success.clientToken.id}`);
32187
+ console.log(`${chalk23.bold("Client Token:")} ${chalk23.yellow(success.clientToken.token)}`);
32188
+ console.log(`${chalk23.bold("Format:")} ${success.snippet.format}`);
32189
+ console.log(chalk23.dim(`
32190
+ Dashboard: ${success.dashboardUrl}`));
32191
+ if (success.warnings?.length) {
32192
+ for (const w of success.warnings) {
32193
+ console.log(chalk23.yellow(`\u26A0 ${w.message}`));
32194
+ }
32195
+ }
32196
+ console.log(chalk23.cyan("\nRecommended next step: npm install @runtypelabs/persona"));
32197
+ if (options.printSnippet) {
32198
+ console.log(chalk23.cyan("\n--- snippet ---\n"));
32199
+ console.log(success.snippet.code);
32200
+ } else {
32201
+ console.log(chalk23.dim("\nUse --print-snippet to print the embed code, or run interactively for copy shortcuts."));
32202
+ }
32203
+ return;
32204
+ }
32205
+ await runSuccessKeyLoop(success, apiUrl, targetSelector);
32206
+ }
32207
+ );
32208
+
32209
+ // src/commands/analytics.ts
32210
+ import { Command as Command18 } from "commander";
32211
+ import chalk24 from "chalk";
31688
32212
  import React16 from "react";
31689
32213
  import { render as render16 } from "ink";
31690
32214
  import { useState as useState30, useEffect as useEffect27 } from "react";
31691
32215
  import { Text as Text33 } from "ink";
31692
- var analyticsCommand = new Command17("analytics").description("View analytics and execution results");
32216
+ var analyticsCommand = new Command18("analytics").description("View analytics and execution results");
31693
32217
  analyticsCommand.command("stats").description("Show account statistics").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
31694
32218
  const apiKey = await ensureAuth();
31695
32219
  if (!apiKey) return;
@@ -31709,8 +32233,8 @@ analyticsCommand.command("stats").description("Show account statistics").option(
31709
32233
  }
31710
32234
  } catch (error) {
31711
32235
  const message = error instanceof Error ? error.message : "Unknown error";
31712
- console.error(chalk23.red("Failed to fetch stats"));
31713
- console.error(chalk23.red(message));
32236
+ console.error(chalk24.red("Failed to fetch stats"));
32237
+ console.error(chalk24.red(message));
31714
32238
  process.exit(1);
31715
32239
  }
31716
32240
  return;
@@ -31774,27 +32298,27 @@ analyticsCommand.command("results").description("List execution results").option
31774
32298
  } else {
31775
32299
  const results = data.data ?? [];
31776
32300
  if (results.length === 0) {
31777
- console.log(chalk23.gray("No results found"));
32301
+ console.log(chalk24.gray("No results found"));
31778
32302
  return;
31779
32303
  }
31780
- console.log(chalk23.cyan("Execution Results:"));
32304
+ console.log(chalk24.cyan("Execution Results:"));
31781
32305
  for (const result of results) {
31782
32306
  const statusColor = result.status === "completed" ? "green" : "red";
31783
- const date = result.createdAt ? chalk23.gray(` ${result.createdAt}`) : "";
32307
+ const date = result.createdAt ? chalk24.gray(` ${result.createdAt}`) : "";
31784
32308
  console.log(
31785
- ` ${chalk23.green(result.id)} ${chalk23[statusColor](`[${result.status}]`)} flow=${chalk23.gray(result.flowId)} record=${chalk23.gray(result.recordId)}${date}`
32309
+ ` ${chalk24.green(result.id)} ${chalk24[statusColor](`[${result.status}]`)} flow=${chalk24.gray(result.flowId)} record=${chalk24.gray(result.recordId)}${date}`
31786
32310
  );
31787
32311
  }
31788
32312
  const total = getTotalCount(data.pagination);
31789
32313
  if (total !== void 0) {
31790
- console.log(chalk23.dim(`
32314
+ console.log(chalk24.dim(`
31791
32315
  Total: ${total} results`));
31792
32316
  }
31793
32317
  }
31794
32318
  } catch (error) {
31795
32319
  const message = error instanceof Error ? error.message : "Unknown error";
31796
- console.error(chalk23.red("Failed to fetch results"));
31797
- console.error(chalk23.red(message));
32320
+ console.error(chalk24.red("Failed to fetch results"));
32321
+ console.error(chalk24.red(message));
31798
32322
  process.exit(1);
31799
32323
  }
31800
32324
  return;
@@ -31845,13 +32369,13 @@ analyticsCommand.command("results").description("List execution results").option
31845
32369
  );
31846
32370
 
31847
32371
  // src/commands/billing.ts
31848
- import { Command as Command18 } from "commander";
31849
- import chalk24 from "chalk";
32372
+ import { Command as Command19 } from "commander";
32373
+ import chalk25 from "chalk";
31850
32374
  import React17 from "react";
31851
32375
  import { render as render17 } from "ink";
31852
32376
  import { useState as useState31, useEffect as useEffect28 } from "react";
31853
- import open5 from "open";
31854
- var billingCommand = new Command18("billing").description("View billing and subscription info");
32377
+ import open6 from "open";
32378
+ var billingCommand = new Command19("billing").description("View billing and subscription info");
31855
32379
  billingCommand.command("status").description("Show current plan and usage").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
31856
32380
  const apiKey = await ensureAuth();
31857
32381
  if (!apiKey) return;
@@ -31888,8 +32412,8 @@ billingCommand.command("status").description("Show current plan and usage").opti
31888
32412
  }
31889
32413
  } catch (error) {
31890
32414
  const message = error instanceof Error ? error.message : "Unknown error";
31891
- console.error(chalk24.red("Failed to fetch billing status"));
31892
- console.error(chalk24.red(message));
32415
+ console.error(chalk25.red("Failed to fetch billing status"));
32416
+ console.error(chalk25.red(message));
31893
32417
  process.exit(1);
31894
32418
  }
31895
32419
  return;
@@ -31953,14 +32477,14 @@ billingCommand.command("portal").description("Open the billing portal in your br
31953
32477
  if (data.url) {
31954
32478
  console.log("Opening billing portal...");
31955
32479
  console.log(data.url);
31956
- await open5(data.url);
32480
+ await open6(data.url);
31957
32481
  } else {
31958
32482
  console.log("No portal URL returned. You may need to set up billing first.");
31959
32483
  }
31960
32484
  } catch (error) {
31961
32485
  const message = error instanceof Error ? error.message : "Unknown error";
31962
- console.error(chalk24.red("Failed to open billing portal"));
31963
- console.error(chalk24.red(message));
32486
+ console.error(chalk25.red("Failed to open billing portal"));
32487
+ console.error(chalk25.red(message));
31964
32488
  process.exit(1);
31965
32489
  }
31966
32490
  return;
@@ -31975,7 +32499,7 @@ billingCommand.command("portal").description("Open the billing portal in your br
31975
32499
  try {
31976
32500
  const data = await client.post("/billing/portal");
31977
32501
  if (data.url) {
31978
- await open5(data.url);
32502
+ await open6(data.url);
31979
32503
  setMsg("Billing portal opened in browser");
31980
32504
  setSuccess(true);
31981
32505
  } else {
@@ -32009,11 +32533,11 @@ billingCommand.command("refresh").description("Refresh plan data from billing pr
32009
32533
  if (!isTTY(options)) {
32010
32534
  try {
32011
32535
  await client.post("/billing/refresh");
32012
- console.log(chalk24.green("Plan data refreshed"));
32536
+ console.log(chalk25.green("Plan data refreshed"));
32013
32537
  } catch (error) {
32014
32538
  const message = error instanceof Error ? error.message : "Unknown error";
32015
- console.error(chalk24.red("Failed to refresh plan data"));
32016
- console.error(chalk24.red(message));
32539
+ console.error(chalk25.red("Failed to refresh plan data"));
32540
+ console.error(chalk25.red(message));
32017
32541
  process.exit(1);
32018
32542
  }
32019
32543
  return;
@@ -32049,13 +32573,13 @@ billingCommand.command("refresh").description("Refresh plan data from billing pr
32049
32573
  });
32050
32574
 
32051
32575
  // src/commands/flow-versions.ts
32052
- import { Command as Command19 } from "commander";
32053
- import chalk25 from "chalk";
32576
+ import { Command as Command20 } from "commander";
32577
+ import chalk26 from "chalk";
32054
32578
  import React18 from "react";
32055
32579
  import { render as render18 } from "ink";
32056
32580
  import { useState as useState32, useEffect as useEffect29 } from "react";
32057
32581
  import { Text as Text34 } from "ink";
32058
- var flowVersionsCommand = new Command19("flow-versions").description(
32582
+ var flowVersionsCommand = new Command20("flow-versions").description(
32059
32583
  "Manage flow versions"
32060
32584
  );
32061
32585
  flowVersionsCommand.command("list <flowId>").description("List all versions for a flow").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (flowId, options) => {
@@ -32070,21 +32594,21 @@ flowVersionsCommand.command("list <flowId>").description("List all versions for
32070
32594
  } else {
32071
32595
  const versions = data.data ?? [];
32072
32596
  if (versions.length === 0) {
32073
- console.log(chalk25.gray("No versions found"));
32597
+ console.log(chalk26.gray("No versions found"));
32074
32598
  return;
32075
32599
  }
32076
- console.log(chalk25.cyan(`Versions for flow ${flowId}:`));
32600
+ console.log(chalk26.cyan(`Versions for flow ${flowId}:`));
32077
32601
  for (const v of versions) {
32078
- const publishedTag = v.published ? chalk25.green(" [published]") : "";
32602
+ const publishedTag = v.published ? chalk26.green(" [published]") : "";
32079
32603
  const versionNum = v.version !== void 0 ? `v${v.version}` : v.id;
32080
- const date = v.createdAt ? chalk25.gray(` ${v.createdAt}`) : "";
32081
- console.log(` ${chalk25.green(v.id)} ${versionNum}${publishedTag}${date}`);
32604
+ const date = v.createdAt ? chalk26.gray(` ${v.createdAt}`) : "";
32605
+ console.log(` ${chalk26.green(v.id)} ${versionNum}${publishedTag}${date}`);
32082
32606
  }
32083
32607
  }
32084
32608
  } catch (error) {
32085
32609
  const message = error instanceof Error ? error.message : "Unknown error";
32086
- console.error(chalk25.red("Failed to fetch versions"));
32087
- console.error(chalk25.red(message));
32610
+ console.error(chalk26.red("Failed to fetch versions"));
32611
+ console.error(chalk26.red(message));
32088
32612
  process.exit(1);
32089
32613
  }
32090
32614
  return;
@@ -32144,8 +32668,8 @@ flowVersionsCommand.command("get <flowId> <versionId>").description("Get a speci
32144
32668
  }
32145
32669
  } catch (error) {
32146
32670
  const message = error instanceof Error ? error.message : "Unknown error";
32147
- console.error(chalk25.red("Failed to fetch version"));
32148
- console.error(chalk25.red(message));
32671
+ console.error(chalk26.red("Failed to fetch version"));
32672
+ console.error(chalk26.red(message));
32149
32673
  process.exit(1);
32150
32674
  }
32151
32675
  return;
@@ -32210,8 +32734,8 @@ flowVersionsCommand.command("published <flowId>").description("Get the published
32210
32734
  }
32211
32735
  } catch (error) {
32212
32736
  const message = error instanceof Error ? error.message : "Unknown error";
32213
- console.error(chalk25.red("Failed to fetch published version"));
32214
- console.error(chalk25.red(message));
32737
+ console.error(chalk26.red("Failed to fetch published version"));
32738
+ console.error(chalk26.red(message));
32215
32739
  process.exit(1);
32216
32740
  }
32217
32741
  return;
@@ -32264,11 +32788,11 @@ flowVersionsCommand.command("publish <flowId>").description("Publish a version")
32264
32788
  await client.post(`/flow-versions/${flowId}/publish`, {
32265
32789
  versionId: options.version
32266
32790
  });
32267
- console.log(chalk25.green("Version published"));
32791
+ console.log(chalk26.green("Version published"));
32268
32792
  } catch (error) {
32269
32793
  const message = error instanceof Error ? error.message : "Unknown error";
32270
- console.error(chalk25.red("Failed to publish version"));
32271
- console.error(chalk25.red(message));
32794
+ console.error(chalk26.red("Failed to publish version"));
32795
+ console.error(chalk26.red(message));
32272
32796
  process.exit(1);
32273
32797
  }
32274
32798
  return;
@@ -32309,7 +32833,7 @@ flowVersionsCommand.command("publish <flowId>").description("Publish a version")
32309
32833
  init_credential_store();
32310
32834
 
32311
32835
  // src/lib/update-check.ts
32312
- import chalk26 from "chalk";
32836
+ import chalk27 from "chalk";
32313
32837
  import Conf3 from "conf";
32314
32838
  var UPDATE_CHECK_INTERVAL_MS = 12 * 60 * 60 * 1e3;
32315
32839
  var UPDATE_NOTIFY_INTERVAL_MS = 24 * 60 * 60 * 1e3;
@@ -32403,7 +32927,7 @@ function notifyFromCachedCliUpdate(args, options = {}) {
32403
32927
  console.error(message);
32404
32928
  });
32405
32929
  notify(
32406
- `${chalk26.yellow("Update available:")} ${chalk26.red(currentVersion)} ${chalk26.gray("->")} ${chalk26.green(latestVersion)} ${chalk26.gray(`(${getUpgradeCommand()})`)}`
32930
+ `${chalk27.yellow("Update available:")} ${chalk27.red(currentVersion)} ${chalk27.gray("->")} ${chalk27.green(latestVersion)} ${chalk27.gray(`(${getUpgradeCommand()})`)}`
32407
32931
  );
32408
32932
  store.set("lastNotifiedAt", now.toISOString());
32409
32933
  store.set("lastNotifiedVersion", latestVersion);
@@ -32445,7 +32969,7 @@ function maybeNotifyAboutCliUpdate(args, options = {}) {
32445
32969
  // src/index.ts
32446
32970
  loadEnv();
32447
32971
  setCliTitle();
32448
- var program = new Command20();
32972
+ var program = new Command21();
32449
32973
  program.name("runtype").description("CLI for Runtype AI Platform").version(getCliVersion()).option("-v, --verbose", "Enable verbose output").option("--api-url <url>", "Override API URL").option("--json", "Output in JSON format");
32450
32974
  program.addCommand(initCommand);
32451
32975
  program.addCommand(loginCommand);
@@ -32463,6 +32987,7 @@ program.addCommand(schedulesCommand);
32463
32987
  program.addCommand(evalCommand);
32464
32988
  program.addCommand(apiKeysCommand);
32465
32989
  program.addCommand(clientTokensCommand);
32990
+ program.addCommand(personaCommand);
32466
32991
  program.addCommand(analyticsCommand);
32467
32992
  program.addCommand(billingCommand);
32468
32993
  program.addCommand(flowVersionsCommand);
@@ -32480,15 +33005,15 @@ try {
32480
33005
  } catch (error) {
32481
33006
  const commanderError = error;
32482
33007
  if (commanderError.code === "commander.missingArgument") {
32483
- console.error(chalk27.red(`Error: ${commanderError.message}`));
33008
+ console.error(chalk28.red(`Error: ${commanderError.message}`));
32484
33009
  process.exit(1);
32485
33010
  } else if (commanderError.code === "commander.unknownOption") {
32486
- console.error(chalk27.red(`Error: ${commanderError.message}`));
33011
+ console.error(chalk28.red(`Error: ${commanderError.message}`));
32487
33012
  process.exit(1);
32488
33013
  } else if (commanderError.code === "commander.help" || commanderError.code === "commander.version") {
32489
33014
  process.exit(0);
32490
33015
  } else {
32491
- console.error(chalk27.red("An unexpected error occurred:"));
33016
+ console.error(chalk28.red("An unexpected error occurred:"));
32492
33017
  console.error(error);
32493
33018
  process.exit(1);
32494
33019
  }
@@ -32497,12 +33022,12 @@ async function handleNoCommand() {
32497
33022
  const store = new CredentialStore();
32498
33023
  const hasCredentials = await store.hasCredentials();
32499
33024
  if (!hasCredentials) {
32500
- console.log(chalk27.cyan("\nWelcome to Runtype CLI!\n"));
33025
+ console.log(chalk28.cyan("\nWelcome to Runtype CLI!\n"));
32501
33026
  console.log("It looks like this is your first time. Run the setup wizard:");
32502
- console.log(` ${chalk27.green("runtype init")}
33027
+ console.log(` ${chalk28.green("runtype init")}
32503
33028
  `);
32504
33029
  console.log("Or see all available commands:");
32505
- console.log(` ${chalk27.green("runtype --help")}
33030
+ console.log(` ${chalk28.green("runtype --help")}
32506
33031
  `);
32507
33032
  } else {
32508
33033
  try {