openxgen 0.5.1 → 0.6.1

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
@@ -12,23 +12,29 @@ var __export = (target, all) => {
12
12
  // src/config/store.ts
13
13
  var store_exports = {};
14
14
  __export(store_exports, {
15
+ addEnvironment: () => addEnvironment,
15
16
  addProvider: () => addProvider,
16
17
  clearAuth: () => clearAuth,
17
18
  getAccessToken: () => getAccessToken,
19
+ getActiveEnvironment: () => getActiveEnvironment,
18
20
  getAuth: () => getAuth,
19
21
  getConfig: () => getConfig,
20
22
  getDefaultProvider: () => getDefaultProvider,
23
+ getEnvStore: () => getEnvStore,
24
+ getEnvironments: () => getEnvironments,
21
25
  getProviders: () => getProviders,
22
26
  getProvidersStore: () => getProvidersStore,
23
27
  getRefreshToken: () => getRefreshToken,
24
28
  getServer: () => getServer,
29
+ removeEnvironment: () => removeEnvironment,
25
30
  removeProvider: () => removeProvider,
26
31
  requireAuth: () => requireAuth,
27
32
  requireServer: () => requireServer,
28
33
  setAuth: () => setAuth,
29
34
  setConfig: () => setConfig,
30
35
  setDefaultProvider: () => setDefaultProvider,
31
- setServer: () => setServer
36
+ setServer: () => setServer,
37
+ switchEnvironment: () => switchEnvironment
32
38
  });
33
39
  import { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync } from "fs";
34
40
  import { homedir } from "os";
@@ -121,6 +127,41 @@ function setDefaultProvider(id) {
121
127
  writeJson(PROVIDERS_FILE, store, true);
122
128
  return true;
123
129
  }
130
+ function getEnvStore() {
131
+ return { ...DEFAULT_ENV_STORE, ...readJson(ENVIRONMENTS_FILE, DEFAULT_ENV_STORE) };
132
+ }
133
+ function getEnvironments() {
134
+ return getEnvStore().environments;
135
+ }
136
+ function addEnvironment(env) {
137
+ const store = getEnvStore();
138
+ store.environments = store.environments.filter((e) => e.id !== env.id);
139
+ store.environments.push(env);
140
+ if (!store.activeId) store.activeId = env.id;
141
+ writeJson(ENVIRONMENTS_FILE, store);
142
+ }
143
+ function removeEnvironment(id) {
144
+ const store = getEnvStore();
145
+ const before = store.environments.length;
146
+ store.environments = store.environments.filter((e) => e.id !== id);
147
+ if (store.activeId === id) store.activeId = store.environments[0]?.id ?? null;
148
+ writeJson(ENVIRONMENTS_FILE, store);
149
+ return store.environments.length < before;
150
+ }
151
+ function switchEnvironment(id) {
152
+ const store = getEnvStore();
153
+ const env = store.environments.find((e) => e.id === id);
154
+ if (!env) return false;
155
+ store.activeId = id;
156
+ writeJson(ENVIRONMENTS_FILE, store);
157
+ setServer(env.url);
158
+ return true;
159
+ }
160
+ function getActiveEnvironment() {
161
+ const store = getEnvStore();
162
+ if (!store.activeId) return null;
163
+ return store.environments.find((e) => e.id === store.activeId) ?? null;
164
+ }
124
165
  function requireServer() {
125
166
  const server = getServer();
126
167
  if (!server) {
@@ -139,7 +180,7 @@ function requireAuth() {
139
180
  }
140
181
  return auth;
141
182
  }
142
- var XGEN_DIR, CONFIG_FILE, AUTH_FILE, PROVIDERS_FILE, DEFAULT_CONFIG, DEFAULT_PROVIDERS;
183
+ var XGEN_DIR, CONFIG_FILE, AUTH_FILE, PROVIDERS_FILE, DEFAULT_CONFIG, DEFAULT_PROVIDERS, ENVIRONMENTS_FILE, DEFAULT_ENV_STORE;
143
184
  var init_store = __esm({
144
185
  "src/config/store.ts"() {
145
186
  "use strict";
@@ -154,6 +195,8 @@ var init_store = __esm({
154
195
  streamLogs: false
155
196
  };
156
197
  DEFAULT_PROVIDERS = { providers: [], defaultId: null };
198
+ ENVIRONMENTS_FILE = join(XGEN_DIR, "environments.json");
199
+ DEFAULT_ENV_STORE = { environments: [], activeId: null };
157
200
  }
158
201
  });
159
202
 
@@ -357,6 +400,10 @@ async function executeWorkflowStream(request) {
357
400
  }
358
401
  async function executeWorkflow(request) {
359
402
  const client2 = getClient();
403
+ if (request.deploy_key) {
404
+ const res2 = await client2.post("/api/workflow/execute/deploy/result", request);
405
+ return res2.data;
406
+ }
360
407
  const res = await client2.post("/api/workflow/execute/based_id", request);
361
408
  return res.data;
362
409
  }
@@ -435,178 +482,6 @@ var init_sse = __esm({
435
482
  }
436
483
  });
437
484
 
438
- // src/utils/markdown.ts
439
- import chalk6 from "chalk";
440
- function renderMarkdown(text) {
441
- let result = text;
442
- result = result.replace(CODE_BLOCK_RE, (_match, lang, code) => {
443
- const trimmed = code.trimEnd();
444
- const header = lang ? chalk6.gray(` \u2500\u2500 ${lang} \u2500\u2500`) : chalk6.gray(" \u2500\u2500 code \u2500\u2500");
445
- const lines = trimmed.split("\n").map((l) => chalk6.white(` ${l}`)).join("\n");
446
- return `
447
- ${header}
448
- ${lines}
449
- ${chalk6.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")}
450
- `;
451
- });
452
- result = result.replace(INLINE_CODE_RE, (_m, code) => chalk6.cyan(`\`${code}\``));
453
- result = result.replace(BOLD_RE, (_m, text2) => chalk6.bold(text2));
454
- result = result.replace(HEADING_RE, (_m, hashes, text2) => {
455
- if (hashes.length === 1) return chalk6.bold.underline(text2);
456
- if (hashes.length === 2) return chalk6.bold(text2);
457
- return chalk6.bold.dim(text2);
458
- });
459
- result = result.replace(LIST_RE, (_m, indent, text2) => `${indent}${chalk6.cyan("\u2022")} ${text2}`);
460
- result = result.replace(LINK_RE, (_m, label, url) => `${chalk6.blue.underline(label)} ${chalk6.gray(`(${url})`)}`);
461
- return result;
462
- }
463
- var CODE_BLOCK_RE, INLINE_CODE_RE, BOLD_RE, HEADING_RE, LIST_RE, LINK_RE;
464
- var init_markdown = __esm({
465
- "src/utils/markdown.ts"() {
466
- "use strict";
467
- CODE_BLOCK_RE = /```(\w*)\n([\s\S]*?)```/g;
468
- INLINE_CODE_RE = /`([^`]+)`/g;
469
- BOLD_RE = /\*\*(.+?)\*\*/g;
470
- HEADING_RE = /^(#{1,3})\s+(.+)$/gm;
471
- LIST_RE = /^(\s*)[-*]\s+(.+)$/gm;
472
- LINK_RE = /\[([^\]]+)\]\(([^)]+)\)/g;
473
- }
474
- });
475
-
476
- // src/commands/workflow/run.ts
477
- var run_exports = {};
478
- __export(run_exports, {
479
- workflowRun: () => workflowRun
480
- });
481
- import chalk7 from "chalk";
482
- import { randomUUID } from "crypto";
483
- async function workflowRun(workflowId, input, opts) {
484
- const auth = requireAuth();
485
- let workflowName = workflowId;
486
- try {
487
- const detail = await getWorkflowDetail(workflowId);
488
- workflowName = detail.workflow_name ?? workflowId;
489
- } catch {
490
- }
491
- if (!input) {
492
- if (opts.interactive || !process.stdin.isTTY) {
493
- const { createInterface: createInterface7 } = await import("readline");
494
- const rl = createInterface7({ input: process.stdin, output: process.stdout });
495
- input = await new Promise((resolve) => {
496
- rl.question(chalk7.cyan("\uC785\uB825> "), (answer) => {
497
- rl.close();
498
- resolve(answer.trim());
499
- });
500
- });
501
- } else {
502
- printError("\uC785\uB825\uAC12\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \uC0AC\uC6A9\uBC95:");
503
- console.log(' xgen workflow run <id> "\uC785\uB825 \uD14D\uC2A4\uFFFD\uFFFD\uFFFD"');
504
- console.log(" xgen workflow run -i <id>");
505
- process.exit(1);
506
- }
507
- }
508
- if (!input) {
509
- printError("\uC785\uB825\uAC12\uC774 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4");
510
- process.exit(1);
511
- }
512
- const interactionId = `cli_${randomUUID().slice(0, 8)}`;
513
- printHeader(`\uC2E4\uD589: ${workflowName}`);
514
- printInfo(`\uC785\uB825: ${input}`);
515
- console.log();
516
- try {
517
- const stream = await executeWorkflowStream({
518
- workflow_id: workflowId,
519
- workflow_name: workflowName,
520
- input_data: input,
521
- interaction_id: interactionId
522
- });
523
- let hasOutput = false;
524
- let fullResponse = "";
525
- await parseSSEStream(
526
- stream,
527
- (event) => {
528
- switch (event.type) {
529
- case "token":
530
- if (event.content) {
531
- if (!hasOutput) {
532
- hasOutput = true;
533
- console.log();
534
- }
535
- process.stdout.write(event.content);
536
- fullResponse += event.content;
537
- }
538
- break;
539
- case "log":
540
- if (opts.logs && event.content) {
541
- process.stderr.write(chalk7.gray(`[LOG] ${event.content}
542
- `));
543
- }
544
- break;
545
- case "node_status":
546
- if (opts.logs) {
547
- const nodeName = event.node_name ?? event.node_id ?? "?";
548
- const status = event.status ?? "?";
549
- process.stderr.write(
550
- chalk7.gray(`[\uB178\uB4DC] ${nodeName}: ${status}
551
- `)
552
- );
553
- }
554
- break;
555
- case "tool":
556
- if (opts.logs) {
557
- process.stderr.write(chalk7.gray(`[\uB3C4\uAD6C] ${JSON.stringify(event.data)}
558
- `));
559
- }
560
- break;
561
- case "complete":
562
- break;
563
- case "error":
564
- console.log();
565
- printError(event.error ?? event.content ?? "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958");
566
- break;
567
- default:
568
- if (event.content) {
569
- if (!hasOutput) {
570
- process.stdout.write(chalk7.green("\uC751\uB2F5: "));
571
- hasOutput = true;
572
- }
573
- process.stdout.write(event.content);
574
- }
575
- }
576
- },
577
- () => {
578
- if (hasOutput) {
579
- console.log();
580
- if (fullResponse.includes("```") || fullResponse.includes("**")) {
581
- console.log(chalk7.gray("\u2500".repeat(40)));
582
- console.log(renderMarkdown(fullResponse));
583
- }
584
- }
585
- console.log();
586
- console.log(chalk7.gray(`\uC138\uC158: ${interactionId}`));
587
- },
588
- (err) => {
589
- console.log();
590
- printError(`\uC2A4\uD2B8\uB9AC\uBC0D \uC624\uB958: ${err.message}`);
591
- }
592
- );
593
- } catch (err) {
594
- const msg = err?.response?.data?.detail ?? err.message;
595
- printError(`\uC2E4\uD589 \uC2E4\uD328: ${msg}`);
596
- process.exit(1);
597
- }
598
- }
599
- var init_run = __esm({
600
- "src/commands/workflow/run.ts"() {
601
- "use strict";
602
- init_store();
603
- init_workflow();
604
- init_sse();
605
- init_format();
606
- init_markdown();
607
- }
608
- });
609
-
610
485
  // src/commands/chat.ts
611
486
  import chalk9 from "chalk";
612
487
  import { createInterface as createInterface2 } from "readline";
@@ -1920,10 +1795,17 @@ function showStatus() {
1920
1795
  const provider = getDefaultProvider();
1921
1796
  const server = getServer();
1922
1797
  const auth = getAuth();
1798
+ const activeEnv = getActiveEnvironment();
1799
+ const envs = getEnvironments();
1923
1800
  console.log(divider("\uC0C1\uD0DC"));
1924
1801
  console.log();
1925
1802
  console.log(provider ? statusDot(true, chalk12.bold("AI \uC5D0\uC774\uC804\uD2B8"), `${provider.name} \xB7 ${provider.model}`) : statusDot(false, "AI \uC5D0\uC774\uC804\uD2B8", "\uBBF8\uC124\uC815"));
1926
1803
  console.log(server && auth ? statusDot(true, chalk12.bold("XGEN \uC11C\uBC84"), `${auth.username} \xB7 ${server.replace("https://", "")}`) : server ? statusDot(false, "XGEN \uC11C\uBC84", `${server.replace("https://", "")} \xB7 \uB85C\uADF8\uC778 \uD544\uC694`) : statusDot(false, "XGEN \uC11C\uBC84", "\uBBF8\uC5F0\uACB0"));
1804
+ if (activeEnv) {
1805
+ console.log(statusDot(true, chalk12.bold("\uD658\uACBD"), `${activeEnv.name} (${envs.length}\uAC1C \uB4F1\uB85D)`));
1806
+ } else if (envs.length > 0) {
1807
+ console.log(statusDot(false, "\uD658\uACBD", `${envs.length}\uAC1C \uB4F1\uB85D`));
1808
+ }
1927
1809
  console.log();
1928
1810
  }
1929
1811
  async function homeMenu() {
@@ -1962,8 +1844,8 @@ async function homeMenu() {
1962
1844
  label: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uAD00\uB9AC",
1963
1845
  hint: "\uBAA9\uB85D \uC870\uD68C \u2192 \uC120\uD0DD \u2192 \uC2E4\uD589/\uC815\uBCF4",
1964
1846
  action: async () => {
1965
- const { listWorkflows: listWorkflows2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
1966
- const wfs = await listWorkflows2();
1847
+ const { getWorkflowListDetail: getWorkflowListDetail2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
1848
+ const wfs = await getWorkflowListDetail2();
1967
1849
  if (!wfs.length) {
1968
1850
  console.log(chalk12.yellow("\n \uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
1969
1851
  return;
@@ -1991,8 +1873,34 @@ async function homeMenu() {
1991
1873
  `));
1992
1874
  const input = await ask(chalk12.white(" \uBA54\uC2DC\uC9C0: "));
1993
1875
  if (!input) return;
1994
- const { workflowRun: workflowRun2 } = await Promise.resolve().then(() => (init_run(), run_exports));
1995
- await workflowRun2(wfId, input, { logs: false, interactive: false });
1876
+ const deployKey = selected2.deploy_key;
1877
+ const isDeployed = selected2.is_deployed;
1878
+ try {
1879
+ console.log(chalk12.gray("\n \uC2E4\uD589 \uC911...\n"));
1880
+ const { executeWorkflow: executeWorkflow2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
1881
+ const { randomUUID: randomUUID4 } = await import("crypto");
1882
+ const result = await executeWorkflow2({
1883
+ workflow_id: wfId,
1884
+ workflow_name: selected2.workflow_name,
1885
+ input_data: input,
1886
+ interaction_id: `cli_${randomUUID4().slice(0, 8)}`,
1887
+ deploy_key: isDeployed && deployKey ? deployKey : void 0
1888
+ });
1889
+ if (result.content) {
1890
+ console.log(chalk12.bold(" \uC751\uB2F5:"));
1891
+ console.log(` ${result.content}
1892
+ `);
1893
+ } else if (result.success === false) {
1894
+ console.log(chalk12.red(` \uC624\uB958: ${result.error ?? result.message}
1895
+ `));
1896
+ } else {
1897
+ console.log(chalk12.gray(JSON.stringify(result, null, 2).slice(0, 500)));
1898
+ console.log();
1899
+ }
1900
+ } catch (err) {
1901
+ console.log(chalk12.red(` \uC2E4\uD589 \uC2E4\uD328: ${err.message}
1902
+ `));
1903
+ }
1996
1904
  }
1997
1905
  });
1998
1906
  items.push({
@@ -2092,6 +2000,15 @@ async function homeMenu() {
2092
2000
  showStatus();
2093
2001
  }
2094
2002
  });
2003
+ items.push({
2004
+ key: "e",
2005
+ label: "\uD658\uACBD \uAD00\uB9AC",
2006
+ hint: `${getEnvironments().length}\uAC1C \uB4F1\uB85D \u2014 \uC11C\uBC84 \uC804\uD658`,
2007
+ action: async () => {
2008
+ await environmentMenu();
2009
+ showStatus();
2010
+ }
2011
+ });
2095
2012
  console.log(divider("\uBA54\uB274"));
2096
2013
  console.log();
2097
2014
  if (hasServer) {
@@ -2108,7 +2025,7 @@ async function homeMenu() {
2108
2025
  }
2109
2026
  console.log();
2110
2027
  console.log(chalk12.gray(" \uC124\uC815"));
2111
- for (const item of items.filter((i) => ["s", "p"].includes(i.key))) {
2028
+ for (const item of items.filter((i) => ["s", "p", "e"].includes(i.key))) {
2112
2029
  console.log(` ${chalk12.cyan.bold(item.key + ".")} ${item.label} ${chalk12.gray("\u2014 " + item.hint)}`);
2113
2030
  }
2114
2031
  console.log(` ${chalk12.gray("q. \uC885\uB8CC")}`);
@@ -2233,6 +2150,112 @@ async function providerMenu() {
2233
2150
  }
2234
2151
  }
2235
2152
  }
2153
+ async function environmentMenu() {
2154
+ const envs = getEnvironments();
2155
+ const active = getActiveEnvironment();
2156
+ console.log();
2157
+ console.log(box(["\uD658\uACBD \uAD00\uB9AC \u2014 XGEN \uC11C\uBC84 \uD504\uB85C\uD544"]));
2158
+ console.log();
2159
+ if (envs.length > 0) {
2160
+ for (const e of envs) {
2161
+ const mark = e.id === active?.id ? chalk12.green("\u25CF ") : chalk12.gray(" ");
2162
+ console.log(` ${mark}${chalk12.bold(e.name)} ${chalk12.gray(e.url)}`);
2163
+ if (e.description) console.log(` ${chalk12.gray(e.description)}`);
2164
+ }
2165
+ console.log();
2166
+ } else {
2167
+ console.log(chalk12.gray(" \uB4F1\uB85D\uB41C \uD658\uACBD \uC5C6\uC74C\n"));
2168
+ }
2169
+ const opts = ["\uC0C8 \uD658\uACBD \uCD94\uAC00", "\uAE30\uBCF8 \uD504\uB9AC\uC14B \uB4F1\uB85D (\uBCF8\uC0AC/\uC81C\uC8FC/\uB86F\uB370\uBAB0)"];
2170
+ if (envs.length > 0) opts.push("\uD658\uACBD \uC804\uD658 + \uB85C\uADF8\uC778");
2171
+ if (envs.length > 0) opts.push("\uC0AD\uC81C");
2172
+ opts.push("\uB3CC\uC544\uAC00\uAE30");
2173
+ opts.forEach((o, i) => console.log(` ${chalk12.cyan(`${i + 1}.`)} ${o}`));
2174
+ console.log();
2175
+ const c = await ask(chalk12.cyan(" \u276F "));
2176
+ const ci = parseInt(c);
2177
+ if (ci === 1) {
2178
+ const name = await ask(chalk12.white(" \uC774\uB984: "));
2179
+ const url = await ask(chalk12.white(" URL: "));
2180
+ const email = await ask(chalk12.white(" \uC774\uBA54\uC77C (\uC120\uD0DD): "));
2181
+ const desc = await ask(chalk12.white(" \uC124\uBA85 (\uC120\uD0DD): "));
2182
+ if (name && url) {
2183
+ const id = name.toLowerCase().replace(/[^a-z0-9]/g, "-");
2184
+ addEnvironment({ id, name, url: url.replace(/\/+$/, ""), email: email || void 0, description: desc || void 0 });
2185
+ console.log(chalk12.green(`
2186
+ \u2713 ${name} \uCD94\uAC00\uB428
2187
+ `));
2188
+ }
2189
+ } else if (ci === 2) {
2190
+ const presets = [
2191
+ { id: "hq", name: "\uBCF8\uC0AC (244)", url: "https://xgen.x2bee.com", email: "admin@plateer.com", description: "\uBCF8\uC0AC \uBC30\uD3EC \uD658\uACBD" },
2192
+ { id: "jeju", name: "\uC81C\uC8FC (243)", url: "https://jeju-xgen.x2bee.com", email: "admin@plateer.com", description: "\uC81C\uC8FC \uC11C\uBC84" },
2193
+ { id: "lotte", name: "\uB86F\uB370\uBAB0 (DGX)", url: "https://lotteimall-xgen.x2bee.com", description: "\uB86F\uB370\uBAB0 DGX Spark" }
2194
+ ];
2195
+ console.log(chalk12.bold("\n \uAE30\uBCF8 \uD658\uACBD \uD504\uB9AC\uC14B:\n"));
2196
+ presets.forEach((p, i) => {
2197
+ console.log(` ${chalk12.cyan(`${i + 1}.`)} ${p.name} ${chalk12.gray(p.url)}`);
2198
+ });
2199
+ console.log(` ${chalk12.cyan(`${presets.length + 1}.`)} \uC804\uBD80 \uB4F1\uB85D`);
2200
+ console.log();
2201
+ const pc = await ask(chalk12.cyan(" \u276F "));
2202
+ const pi = parseInt(pc);
2203
+ if (pi === presets.length + 1) {
2204
+ for (const p of presets) addEnvironment(p);
2205
+ console.log(chalk12.green(` \u2713 ${presets.length}\uAC1C \uD658\uACBD \uB4F1\uB85D\uB428
2206
+ `));
2207
+ } else if (pi >= 1 && pi <= presets.length) {
2208
+ addEnvironment(presets[pi - 1]);
2209
+ console.log(chalk12.green(` \u2713 ${presets[pi - 1].name} \uB4F1\uB85D\uB428
2210
+ `));
2211
+ }
2212
+ } else if (opts[ci - 1] === "\uD658\uACBD \uC804\uD658 + \uB85C\uADF8\uC778") {
2213
+ console.log();
2214
+ envs.forEach((e, i) => {
2215
+ const mark = e.id === active?.id ? chalk12.green("\u25CF ") : " ";
2216
+ console.log(` ${mark}${chalk12.cyan(`${i + 1}.`)} ${e.name} ${chalk12.gray(e.url)}`);
2217
+ });
2218
+ console.log();
2219
+ const ei = parseInt(await ask(chalk12.cyan(" \u276F "))) - 1;
2220
+ if (ei >= 0 && ei < envs.length) {
2221
+ switchEnvironment(envs[ei].id);
2222
+ console.log(chalk12.green(`
2223
+ \u2713 ${envs[ei].name} \uC804\uD658\uB428 \u2192 ${envs[ei].url}`));
2224
+ if (envs[ei].email) {
2225
+ const pw = await ask(chalk12.white(` \uBE44\uBC00\uBC88\uD638 (${envs[ei].email}): `));
2226
+ if (pw) {
2227
+ try {
2228
+ const { apiLogin: apiLogin2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
2229
+ const { setAuth: setAuth2 } = await Promise.resolve().then(() => (init_store(), store_exports));
2230
+ const result = await apiLogin2(envs[ei].email, pw);
2231
+ if (result.success && result.access_token) {
2232
+ setAuth2({ accessToken: result.access_token, refreshToken: result.refresh_token ?? "", userId: result.user_id ?? "", username: result.username ?? "", isAdmin: false, expiresAt: null });
2233
+ console.log(chalk12.green(` \u2713 \uB85C\uADF8\uC778: ${result.username}
2234
+ `));
2235
+ } else {
2236
+ console.log(chalk12.red(` \u2717 ${result.message}
2237
+ `));
2238
+ }
2239
+ } catch (err) {
2240
+ console.log(chalk12.red(` \u2717 ${err.message}
2241
+ `));
2242
+ }
2243
+ }
2244
+ }
2245
+ console.log();
2246
+ }
2247
+ } else if (opts[ci - 1] === "\uC0AD\uC81C") {
2248
+ console.log();
2249
+ envs.forEach((e, i) => console.log(` ${chalk12.cyan(`${i + 1}.`)} ${e.name}`));
2250
+ console.log();
2251
+ const di = parseInt(await ask(chalk12.white(" \uC0AD\uC81C \uBC88\uD638: "))) - 1;
2252
+ if (di >= 0 && di < envs.length) {
2253
+ removeEnvironment(envs[di].id);
2254
+ console.log(chalk12.green(` \u2713 \uC0AD\uC81C: ${envs[di].name}
2255
+ `));
2256
+ }
2257
+ }
2258
+ }
2236
2259
  var init_home = __esm({
2237
2260
  "src/commands/home.ts"() {
2238
2261
  "use strict";
@@ -2729,8 +2752,163 @@ async function workflowInfo(workflowId) {
2729
2752
  }
2730
2753
  }
2731
2754
 
2732
- // src/commands/workflow/index.ts
2733
- init_run();
2755
+ // src/commands/workflow/run.ts
2756
+ init_store();
2757
+ init_workflow();
2758
+ init_sse();
2759
+ init_format();
2760
+ import chalk7 from "chalk";
2761
+ import { randomUUID } from "crypto";
2762
+
2763
+ // src/utils/markdown.ts
2764
+ import chalk6 from "chalk";
2765
+ var CODE_BLOCK_RE = /```(\w*)\n([\s\S]*?)```/g;
2766
+ var INLINE_CODE_RE = /`([^`]+)`/g;
2767
+ var BOLD_RE = /\*\*(.+?)\*\*/g;
2768
+ var HEADING_RE = /^(#{1,3})\s+(.+)$/gm;
2769
+ var LIST_RE = /^(\s*)[-*]\s+(.+)$/gm;
2770
+ var LINK_RE = /\[([^\]]+)\]\(([^)]+)\)/g;
2771
+ function renderMarkdown(text) {
2772
+ let result = text;
2773
+ result = result.replace(CODE_BLOCK_RE, (_match, lang, code) => {
2774
+ const trimmed = code.trimEnd();
2775
+ const header = lang ? chalk6.gray(` \u2500\u2500 ${lang} \u2500\u2500`) : chalk6.gray(" \u2500\u2500 code \u2500\u2500");
2776
+ const lines = trimmed.split("\n").map((l) => chalk6.white(` ${l}`)).join("\n");
2777
+ return `
2778
+ ${header}
2779
+ ${lines}
2780
+ ${chalk6.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")}
2781
+ `;
2782
+ });
2783
+ result = result.replace(INLINE_CODE_RE, (_m, code) => chalk6.cyan(`\`${code}\``));
2784
+ result = result.replace(BOLD_RE, (_m, text2) => chalk6.bold(text2));
2785
+ result = result.replace(HEADING_RE, (_m, hashes, text2) => {
2786
+ if (hashes.length === 1) return chalk6.bold.underline(text2);
2787
+ if (hashes.length === 2) return chalk6.bold(text2);
2788
+ return chalk6.bold.dim(text2);
2789
+ });
2790
+ result = result.replace(LIST_RE, (_m, indent, text2) => `${indent}${chalk6.cyan("\u2022")} ${text2}`);
2791
+ result = result.replace(LINK_RE, (_m, label, url) => `${chalk6.blue.underline(label)} ${chalk6.gray(`(${url})`)}`);
2792
+ return result;
2793
+ }
2794
+
2795
+ // src/commands/workflow/run.ts
2796
+ async function workflowRun(workflowId, input, opts) {
2797
+ const auth = requireAuth();
2798
+ let workflowName = workflowId;
2799
+ try {
2800
+ const detail = await getWorkflowDetail(workflowId);
2801
+ workflowName = detail.workflow_name ?? workflowId;
2802
+ } catch {
2803
+ }
2804
+ if (!input) {
2805
+ if (opts.interactive || !process.stdin.isTTY) {
2806
+ const { createInterface: createInterface7 } = await import("readline");
2807
+ const rl = createInterface7({ input: process.stdin, output: process.stdout });
2808
+ input = await new Promise((resolve) => {
2809
+ rl.question(chalk7.cyan("\uC785\uB825> "), (answer) => {
2810
+ rl.close();
2811
+ resolve(answer.trim());
2812
+ });
2813
+ });
2814
+ } else {
2815
+ printError("\uC785\uB825\uAC12\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \uC0AC\uC6A9\uBC95:");
2816
+ console.log(' xgen workflow run <id> "\uC785\uB825 \uD14D\uC2A4\uFFFD\uFFFD\uFFFD"');
2817
+ console.log(" xgen workflow run -i <id>");
2818
+ process.exit(1);
2819
+ }
2820
+ }
2821
+ if (!input) {
2822
+ printError("\uC785\uB825\uAC12\uC774 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4");
2823
+ process.exit(1);
2824
+ }
2825
+ const interactionId = `cli_${randomUUID().slice(0, 8)}`;
2826
+ printHeader(`\uC2E4\uD589: ${workflowName}`);
2827
+ printInfo(`\uC785\uB825: ${input}`);
2828
+ console.log();
2829
+ try {
2830
+ const stream = await executeWorkflowStream({
2831
+ workflow_id: workflowId,
2832
+ workflow_name: workflowName,
2833
+ input_data: input,
2834
+ interaction_id: interactionId
2835
+ });
2836
+ let hasOutput = false;
2837
+ let fullResponse = "";
2838
+ await parseSSEStream(
2839
+ stream,
2840
+ (event) => {
2841
+ switch (event.type) {
2842
+ case "token":
2843
+ if (event.content) {
2844
+ if (!hasOutput) {
2845
+ hasOutput = true;
2846
+ console.log();
2847
+ }
2848
+ process.stdout.write(event.content);
2849
+ fullResponse += event.content;
2850
+ }
2851
+ break;
2852
+ case "log":
2853
+ if (opts.logs && event.content) {
2854
+ process.stderr.write(chalk7.gray(`[LOG] ${event.content}
2855
+ `));
2856
+ }
2857
+ break;
2858
+ case "node_status":
2859
+ if (opts.logs) {
2860
+ const nodeName = event.node_name ?? event.node_id ?? "?";
2861
+ const status = event.status ?? "?";
2862
+ process.stderr.write(
2863
+ chalk7.gray(`[\uB178\uB4DC] ${nodeName}: ${status}
2864
+ `)
2865
+ );
2866
+ }
2867
+ break;
2868
+ case "tool":
2869
+ if (opts.logs) {
2870
+ process.stderr.write(chalk7.gray(`[\uB3C4\uAD6C] ${JSON.stringify(event.data)}
2871
+ `));
2872
+ }
2873
+ break;
2874
+ case "complete":
2875
+ break;
2876
+ case "error":
2877
+ console.log();
2878
+ printError(event.error ?? event.content ?? "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958");
2879
+ break;
2880
+ default:
2881
+ if (event.content) {
2882
+ if (!hasOutput) {
2883
+ process.stdout.write(chalk7.green("\uC751\uB2F5: "));
2884
+ hasOutput = true;
2885
+ }
2886
+ process.stdout.write(event.content);
2887
+ }
2888
+ }
2889
+ },
2890
+ () => {
2891
+ if (hasOutput) {
2892
+ console.log();
2893
+ if (fullResponse.includes("```") || fullResponse.includes("**")) {
2894
+ console.log(chalk7.gray("\u2500".repeat(40)));
2895
+ console.log(renderMarkdown(fullResponse));
2896
+ }
2897
+ }
2898
+ console.log();
2899
+ console.log(chalk7.gray(`\uC138\uC158: ${interactionId}`));
2900
+ },
2901
+ (err) => {
2902
+ console.log();
2903
+ printError(`\uC2A4\uD2B8\uB9AC\uBC0D \uC624\uB958: ${err.message}`);
2904
+ }
2905
+ );
2906
+ } catch (err) {
2907
+ const msg = err?.response?.data?.detail ?? err.message;
2908
+ printError(`\uC2E4\uD589 \uC2E4\uD328: ${msg}`);
2909
+ process.exit(1);
2910
+ }
2911
+ }
2734
2912
 
2735
2913
  // src/commands/workflow/history.ts
2736
2914
  init_store();