@coze-arch/cli 0.0.6-alpha.dd6b66 → 0.0.7

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/lib/cli.js CHANGED
@@ -15,7 +15,6 @@ var fs$1 = require('fs/promises');
15
15
  var os = require('os');
16
16
  var jsYaml = require('js-yaml');
17
17
  var toml = require('@iarna/toml');
18
- var fastGlob = require('fast-glob');
19
18
  var child_process = require('child_process');
20
19
  var addFormats = require('ajv-formats');
21
20
  var Ajv = require('ajv');
@@ -1491,7 +1490,7 @@ var browserClient = createBaseClient();
1491
1490
 
1492
1491
 
1493
1492
 
1494
- const log$7 = debug('slardar:transport');
1493
+ const log$2 = debug('slardar:transport');
1495
1494
  // eslint-disable-next-line @typescript-eslint/no-empty-function
1496
1495
  const noop = () => {};
1497
1496
 
@@ -1511,22 +1510,22 @@ const noop = () => {};
1511
1510
  function makeRequest(options) {
1512
1511
  const { url, method, data, success = noop, fail = noop, getResponseText = noop } = options;
1513
1512
 
1514
- log$7('Making %s request to %s', method, url);
1513
+ log$2('Making %s request to %s', method, url);
1515
1514
  if (data) {
1516
- log$7('Request data: %s', data.slice(0, 200));
1515
+ log$2('Request data: %s', data.slice(0, 200));
1517
1516
  }
1518
1517
 
1519
1518
  // 检查 URL 是否有效
1520
1519
  if (!url || typeof url !== 'string') {
1521
1520
  const error = new Error(`Invalid URL: ${url}`);
1522
- log$7('Invalid URL provided: %o', url);
1521
+ log$2('Invalid URL provided: %o', url);
1523
1522
  fail(error);
1524
1523
  return;
1525
1524
  }
1526
1525
 
1527
1526
  try {
1528
1527
  const urlObj = new URL(url);
1529
- log$7('Parsed URL - protocol: %s, hostname: %s, port: %s, path: %s',
1528
+ log$2('Parsed URL - protocol: %s, hostname: %s, port: %s, path: %s',
1530
1529
  urlObj.protocol, urlObj.hostname, urlObj.port, urlObj.pathname);
1531
1530
 
1532
1531
  const isHttps = urlObj.protocol === 'https:';
@@ -1544,34 +1543,34 @@ function makeRequest(options) {
1544
1543
  },
1545
1544
  },
1546
1545
  res => {
1547
- log$7('Response callback triggered: status=%s', res.statusCode);
1546
+ log$2('Response callback triggered: status=%s', res.statusCode);
1548
1547
  let responseText = '';
1549
1548
 
1550
1549
  res.on('data', chunk => {
1551
- log$7('Response data chunk received: %s bytes', chunk.length);
1550
+ log$2('Response data chunk received: %s bytes', chunk.length);
1552
1551
  responseText += chunk.toString();
1553
1552
  });
1554
1553
 
1555
1554
  res.on('end', () => {
1556
- log$7('Response end event fired');
1557
- log$7('Response received: status=%s, body=%s', res.statusCode, responseText.slice(0, 200));
1555
+ log$2('Response end event fired');
1556
+ log$2('Response received: status=%s, body=%s', res.statusCode, responseText.slice(0, 200));
1558
1557
  getResponseText(responseText);
1559
1558
 
1560
1559
  try {
1561
1560
  if (res.statusCode && res.statusCode >= 400) {
1562
- log$7('Request failed with status %s: %s', res.statusCode, responseText);
1561
+ log$2('Request failed with status %s: %s', res.statusCode, responseText);
1563
1562
  fail(new Error(responseText || res.statusMessage || 'Request failed'));
1564
1563
  } else if (responseText) {
1565
1564
  // eslint-disable-next-line no-restricted-syntax -- Parsing trusted Slardar API responses
1566
1565
  const result = JSON.parse(responseText);
1567
- log$7('Request succeeded');
1566
+ log$2('Request succeeded');
1568
1567
  success(result);
1569
1568
  } else {
1570
- log$7('Request succeeded with empty response');
1569
+ log$2('Request succeeded with empty response');
1571
1570
  success({});
1572
1571
  }
1573
1572
  } catch (e) {
1574
- log$7('Failed to parse response: %s', (e ).message);
1573
+ log$2('Failed to parse response: %s', (e ).message);
1575
1574
  fail(e );
1576
1575
  }
1577
1576
  });
@@ -1579,12 +1578,12 @@ function makeRequest(options) {
1579
1578
  );
1580
1579
 
1581
1580
  req.on('error', err => {
1582
- log$7('Request error: %s', err.message);
1581
+ log$2('Request error: %s', err.message);
1583
1582
  fail(err);
1584
1583
  });
1585
1584
 
1586
1585
  req.on('timeout', () => {
1587
- log$7('Request timeout');
1586
+ log$2('Request timeout');
1588
1587
  req.destroy();
1589
1588
  fail(new Error('Request timeout'));
1590
1589
  });
@@ -1595,7 +1594,7 @@ function makeRequest(options) {
1595
1594
 
1596
1595
  req.end();
1597
1596
  } catch (e) {
1598
- log$7('Exception during request: %s', (e ).message);
1597
+ log$2('Exception during request: %s', (e ).message);
1599
1598
  fail(e );
1600
1599
  }
1601
1600
  }
@@ -1606,14 +1605,14 @@ function makeRequest(options) {
1606
1605
  function createNodeTransport() {
1607
1606
  return {
1608
1607
  get(options) {
1609
- log$7('Transport GET called: %s', options.url);
1608
+ log$2('Transport GET called: %s', options.url);
1610
1609
  makeRequest({
1611
1610
  method: 'GET',
1612
1611
  ...options,
1613
1612
  });
1614
1613
  },
1615
1614
  post({ url, data }) {
1616
- log$7('Transport POST called: %s', url);
1615
+ log$2('Transport POST called: %s', url);
1617
1616
  makeRequest({
1618
1617
  method: 'POST',
1619
1618
  url,
@@ -1627,14 +1626,14 @@ function createNodeTransport() {
1627
1626
  };
1628
1627
  }
1629
1628
 
1630
- function _nullishCoalesce$3(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain$7(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }/**
1629
+ function _nullishCoalesce$3(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain$6(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }/**
1631
1630
  * Slardar CLI Reporter 主类
1632
1631
  * 封装 @slardar/base 的初始化和上报逻辑
1633
1632
  */
1634
1633
 
1635
1634
  // 创建 debug 实例
1636
1635
  // 使用方式: DEBUG=slardar:* your-cli-command
1637
- const log$6 = debug('slardar:reporter');
1636
+ const log$1 = debug('slardar:reporter');
1638
1637
 
1639
1638
  /**
1640
1639
  * Slardar CLI Reporter
@@ -1659,12 +1658,12 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
1659
1658
  */
1660
1659
  setup(config) {
1661
1660
  if (this.initialized) {
1662
- log$6('Already initialized, skipping setup');
1661
+ log$1('Already initialized, skipping setup');
1663
1662
  return;
1664
1663
  }
1665
1664
 
1666
1665
  try {
1667
- log$6('Initializing Slardar with config:', {
1666
+ log$1('Initializing Slardar with config:', {
1668
1667
  bid: config.bid,
1669
1668
  release: config.release,
1670
1669
  env: config.env,
@@ -1697,17 +1696,17 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
1697
1696
 
1698
1697
  // 添加 send 钩子来追踪事件上报
1699
1698
  this.client.on('send', (ev) => {
1700
- log$6(
1699
+ log$1(
1701
1700
  'send hook called for event: %s',
1702
- (_optionalChain$7([ev, 'optionalAccess', _ => _.ev_type]) ) || 'unknown',
1701
+ (_optionalChain$6([ev, 'optionalAccess', _ => _.ev_type]) ) || 'unknown',
1703
1702
  );
1704
1703
  });
1705
1704
 
1706
1705
  this.client.start();
1707
1706
  this.initialized = true;
1708
- log$6('Slardar initialized successfully');
1707
+ log$1('Slardar initialized successfully');
1709
1708
  } catch (error) {
1710
- log$6('Failed to initialize:', error);
1709
+ log$1('Failed to initialize:', error);
1711
1710
  }
1712
1711
  }
1713
1712
 
@@ -1716,7 +1715,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
1716
1715
  */
1717
1716
  ensureInitialized() {
1718
1717
  if (!this.initialized) {
1719
- log$6('Not initialized, call setup() first');
1718
+ log$1('Not initialized, call setup() first');
1720
1719
  return false;
1721
1720
  }
1722
1721
  return true;
@@ -1738,7 +1737,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
1738
1737
  }
1739
1738
 
1740
1739
  try {
1741
- log$6('Sending event:', { name, metrics, categories });
1740
+ log$1('Sending event:', { name, metrics, categories });
1742
1741
 
1743
1742
  // 过滤掉 undefined 值以满足 Slardar 类型要求
1744
1743
  const cleanMetrics = metrics
@@ -1757,13 +1756,13 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
1757
1756
  )
1758
1757
  : undefined;
1759
1758
 
1760
- _optionalChain$7([this, 'access', _2 => _2.client, 'access', _3 => _3.sendEvent, 'optionalCall', _4 => _4({
1759
+ _optionalChain$6([this, 'access', _2 => _2.client, 'access', _3 => _3.sendEvent, 'optionalCall', _4 => _4({
1761
1760
  name,
1762
1761
  metrics: cleanMetrics ,
1763
1762
  categories: cleanCategories ,
1764
1763
  })]);
1765
1764
  } catch (error) {
1766
- log$6('Failed to send event:', error);
1765
+ log$1('Failed to send event:', error);
1767
1766
  }
1768
1767
  }
1769
1768
 
@@ -1783,7 +1782,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
1783
1782
  }
1784
1783
 
1785
1784
  try {
1786
- log$6('Sending log:', { level, message, extra });
1785
+ log$1('Sending log:', { level, message, extra });
1787
1786
  // 使用 sendEvent 发送日志事件
1788
1787
  this.sendEvent('cli_log', undefined, {
1789
1788
  level,
@@ -1791,7 +1790,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
1791
1790
  ...extra,
1792
1791
  });
1793
1792
  } catch (error) {
1794
- log$6('Failed to send log:', error);
1793
+ log$1('Failed to send log:', error);
1795
1794
  }
1796
1795
  }
1797
1796
 
@@ -1825,19 +1824,19 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
1825
1824
  },
1826
1825
  };
1827
1826
 
1828
- log$6('Reporting JS error:', {
1827
+ log$1('Reporting JS error:', {
1829
1828
  name: error.name,
1830
1829
  message: error.message.slice(0, 100),
1831
- stack: _optionalChain$7([error, 'access', _5 => _5.stack, 'optionalAccess', _6 => _6.slice, 'call', _7 => _7(0, 200)]),
1830
+ stack: _optionalChain$6([error, 'access', _5 => _5.stack, 'optionalAccess', _6 => _6.slice, 'call', _7 => _7(0, 200)]),
1832
1831
  extra,
1833
1832
  source,
1834
1833
  });
1835
1834
 
1836
1835
  // 使用 Slardar 的 js_error 事件类型,这样会显示在 JS 错误总览页面
1837
1836
  this.client.report(errorEvent);
1838
- log$6('JS error reported successfully');
1837
+ log$1('JS error reported successfully');
1839
1838
  } catch (err) {
1840
- log$6('Failed to report error:', err);
1839
+ log$1('Failed to report error:', err);
1841
1840
  }
1842
1841
  }
1843
1842
 
@@ -1848,7 +1847,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
1848
1847
  if (!this.ensureInitialized()) {
1849
1848
  return;
1850
1849
  }
1851
- _optionalChain$7([this, 'access', _8 => _8.client, 'access', _9 => _9.context, 'optionalAccess', _10 => _10.set, 'call', _11 => _11(key, value)]);
1850
+ _optionalChain$6([this, 'access', _8 => _8.client, 'access', _9 => _9.context, 'optionalAccess', _10 => _10.set, 'call', _11 => _11(key, value)]);
1852
1851
  }
1853
1852
 
1854
1853
  /**
@@ -1858,8 +1857,8 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
1858
1857
  if (!this.ensureInitialized()) {
1859
1858
  return;
1860
1859
  }
1861
- log$6('Merging context:', context);
1862
- _optionalChain$7([this, 'access', _12 => _12.client, 'access', _13 => _13.context, 'optionalAccess', _14 => _14.merge, 'call', _15 => _15(context)]);
1860
+ log$1('Merging context:', context);
1861
+ _optionalChain$6([this, 'access', _12 => _12.client, 'access', _13 => _13.context, 'optionalAccess', _14 => _14.merge, 'call', _15 => _15(context)]);
1863
1862
  }
1864
1863
 
1865
1864
  /**
@@ -1869,7 +1868,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
1869
1868
  if (!this.ensureInitialized()) {
1870
1869
  return;
1871
1870
  }
1872
- _optionalChain$7([this, 'access', _16 => _16.client, 'access', _17 => _17.context, 'optionalAccess', _18 => _18.delete, 'call', _19 => _19(key)]);
1871
+ _optionalChain$6([this, 'access', _16 => _16.client, 'access', _17 => _17.context, 'optionalAccess', _18 => _18.delete, 'call', _19 => _19(key)]);
1873
1872
  }
1874
1873
 
1875
1874
  /**
@@ -1879,7 +1878,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
1879
1878
  if (!this.ensureInitialized()) {
1880
1879
  return;
1881
1880
  }
1882
- _optionalChain$7([this, 'access', _20 => _20.client, 'access', _21 => _21.context, 'optionalAccess', _22 => _22.clear, 'call', _23 => _23()]);
1881
+ _optionalChain$6([this, 'access', _20 => _20.client, 'access', _21 => _21.context, 'optionalAccess', _22 => _22.clear, 'call', _23 => _23()]);
1883
1882
  }
1884
1883
 
1885
1884
  /**
@@ -1895,7 +1894,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
1895
1894
  }
1896
1895
 
1897
1896
  try {
1898
- log$6('Updating config:', config);
1897
+ log$1('Updating config:', config);
1899
1898
  this.client.config({
1900
1899
  userId: config.userId,
1901
1900
  release: config.release,
@@ -1903,7 +1902,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
1903
1902
  env: config.env,
1904
1903
  });
1905
1904
  } catch (error) {
1906
- log$6('Failed to update config:', error);
1905
+ log$1('Failed to update config:', error);
1907
1906
  }
1908
1907
  }
1909
1908
 
@@ -1915,11 +1914,11 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
1915
1914
  if (!this.ensureInitialized()) {
1916
1915
  return;
1917
1916
  }
1918
- log$6('Flushing Slardar data...');
1919
- _optionalChain$7([this, 'access', _24 => _24.client, 'access', _25 => _25.getSender, 'optionalCall', _26 => _26(), 'optionalAccess', _27 => _27.flush, 'call', _28 => _28()]);
1920
- log$6('Waiting %dms for events to be sent...', waitMs);
1917
+ log$1('Flushing Slardar data...');
1918
+ _optionalChain$6([this, 'access', _24 => _24.client, 'access', _25 => _25.getSender, 'optionalCall', _26 => _26(), 'optionalAccess', _27 => _27.flush, 'call', _28 => _28()]);
1919
+ log$1('Waiting %dms for events to be sent...', waitMs);
1921
1920
  await new Promise(resolve => setTimeout(resolve, waitMs));
1922
- log$6('Slardar data flushed');
1921
+ log$1('Slardar data flushed');
1923
1922
  }
1924
1923
 
1925
1924
  /**
@@ -1935,7 +1934,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
1935
1934
  */
1936
1935
  const reporter = new SlardarCLIReporter();
1937
1936
 
1938
- function _optionalChain$6(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
1937
+ function _optionalChain$5(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
1939
1938
 
1940
1939
 
1941
1940
 
@@ -1995,11 +1994,11 @@ const EventBuilder = {
1995
1994
  name: CLI_EVENTS.CLI_COMMAND,
1996
1995
  categories: {
1997
1996
  command,
1998
- args: _optionalChain$6([options, 'optionalAccess', _ => _.args]),
1997
+ args: _optionalChain$5([options, 'optionalAccess', _ => _.args]),
1999
1998
  status: 'running' ,
2000
- ..._optionalChain$6([options, 'optionalAccess', _2 => _2.categories]),
1999
+ ..._optionalChain$5([options, 'optionalAccess', _2 => _2.categories]),
2001
2000
  },
2002
- metrics: _optionalChain$6([options, 'optionalAccess', _3 => _3.metrics]),
2001
+ metrics: _optionalChain$5([options, 'optionalAccess', _3 => _3.metrics]),
2003
2002
  };
2004
2003
  },
2005
2004
 
@@ -2020,13 +2019,13 @@ const EventBuilder = {
2020
2019
  name: CLI_EVENTS.CLI_COMMAND_COMPLETE,
2021
2020
  categories: {
2022
2021
  command,
2023
- args: _optionalChain$6([options, 'optionalAccess', _4 => _4.args]),
2022
+ args: _optionalChain$5([options, 'optionalAccess', _4 => _4.args]),
2024
2023
  status: success ? ('success' ) : ('fail' ),
2025
- ..._optionalChain$6([options, 'optionalAccess', _5 => _5.categories]),
2024
+ ..._optionalChain$5([options, 'optionalAccess', _5 => _5.categories]),
2026
2025
  },
2027
2026
  metrics: {
2028
2027
  duration,
2029
- ...(_optionalChain$6([options, 'optionalAccess', _6 => _6.errorCode]) && { errorCode: options.errorCode }),
2028
+ ...(_optionalChain$5([options, 'optionalAccess', _6 => _6.errorCode]) && { errorCode: options.errorCode }),
2030
2029
  },
2031
2030
  };
2032
2031
  },
@@ -2047,12 +2046,12 @@ const EventBuilder = {
2047
2046
  name: CLI_EVENTS.NETWORK_REQUEST,
2048
2047
  categories: {
2049
2048
  url,
2050
- method: _optionalChain$6([options, 'optionalAccess', _7 => _7.method]) || 'GET',
2051
- statusCode: _optionalChain$6([options, 'optionalAccess', _8 => _8.statusCode, 'optionalAccess', _9 => _9.toString, 'call', _10 => _10()]),
2052
- status: _optionalChain$6([options, 'optionalAccess', _11 => _11.success]) ? ('success' ) : ('fail' ),
2049
+ method: _optionalChain$5([options, 'optionalAccess', _7 => _7.method]) || 'GET',
2050
+ statusCode: _optionalChain$5([options, 'optionalAccess', _8 => _8.statusCode, 'optionalAccess', _9 => _9.toString, 'call', _10 => _10()]),
2051
+ status: _optionalChain$5([options, 'optionalAccess', _11 => _11.success]) ? ('success' ) : ('fail' ),
2053
2052
  },
2054
2053
  metrics: {
2055
- duration: _optionalChain$6([options, 'optionalAccess', _12 => _12.duration]),
2054
+ duration: _optionalChain$5([options, 'optionalAccess', _12 => _12.duration]),
2056
2055
  },
2057
2056
  };
2058
2057
  },
@@ -2074,11 +2073,11 @@ const EventBuilder = {
2074
2073
  categories: {
2075
2074
  operation,
2076
2075
  filePath,
2077
- status: _optionalChain$6([options, 'optionalAccess', _13 => _13.success]) ? ('success' ) : ('fail' ),
2076
+ status: _optionalChain$5([options, 'optionalAccess', _13 => _13.success]) ? ('success' ) : ('fail' ),
2078
2077
  },
2079
2078
  metrics: {
2080
- duration: _optionalChain$6([options, 'optionalAccess', _14 => _14.duration]),
2081
- fileSize: _optionalChain$6([options, 'optionalAccess', _15 => _15.fileSize]),
2079
+ duration: _optionalChain$5([options, 'optionalAccess', _14 => _14.duration]),
2080
+ fileSize: _optionalChain$5([options, 'optionalAccess', _15 => _15.fileSize]),
2082
2081
  },
2083
2082
  };
2084
2083
  },
@@ -2106,7 +2105,7 @@ const EventBuilder = {
2106
2105
  };
2107
2106
 
2108
2107
  var name = "@coze-arch/cli";
2109
- var version = "0.0.6-alpha.dd6b66";
2108
+ var version = "0.0.7";
2110
2109
  var description = "coze coding devtools cli";
2111
2110
  var license = "MIT";
2112
2111
  var author = "fanwenjie.fe@bytedance.com";
@@ -2146,7 +2145,6 @@ var dependencies = {
2146
2145
  commander: "~12.1.0",
2147
2146
  debug: "^4.3.7",
2148
2147
  ejs: "^3.1.10",
2149
- "fast-glob": "^3.3.3",
2150
2148
  "js-yaml": "^4.1.0",
2151
2149
  minimist: "^1.2.5",
2152
2150
  shelljs: "^0.10.0"
@@ -2207,11 +2205,11 @@ var packageJson = {
2207
2205
  cozePublishConfig: cozePublishConfig
2208
2206
  };
2209
2207
 
2210
- function _optionalChain$5(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }/**
2208
+ function _optionalChain$4(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }/**
2211
2209
  * Slardar 监控初始化和上报
2212
2210
  */
2213
2211
 
2214
- const log$5 = debug('slardar:cli');
2212
+ const log = debug('slardar:cli');
2215
2213
 
2216
2214
  /**
2217
2215
  * 安全执行函数包装器
@@ -2224,18 +2222,18 @@ function safeRun(
2224
2222
  ) {
2225
2223
  return ((...args) => {
2226
2224
  try {
2227
- log$5('Calling Slardar function: %s', name);
2225
+ log('Calling Slardar function: %s', name);
2228
2226
  const result = fn(...args);
2229
2227
 
2230
2228
  // 如果是 Promise,处理异步错误
2231
2229
  if (result instanceof Promise) {
2232
2230
  return result
2233
2231
  .then(res => {
2234
- log$5('Slardar function %s completed', name);
2232
+ log('Slardar function %s completed', name);
2235
2233
  return res;
2236
2234
  })
2237
2235
  .catch(error => {
2238
- log$5(
2236
+ log(
2239
2237
  'Slardar function %s failed: %s',
2240
2238
  name,
2241
2239
  (error ).message,
@@ -2244,11 +2242,11 @@ function safeRun(
2244
2242
  });
2245
2243
  }
2246
2244
 
2247
- log$5('Slardar function %s completed', name);
2245
+ log('Slardar function %s completed', name);
2248
2246
  return result;
2249
2247
  } catch (error) {
2250
2248
  // Slardar 上报失败不应影响 CLI 正常运行,但要记录错误
2251
- log$5('Slardar function %s failed: %s', name, (error ).message);
2249
+ log('Slardar function %s failed: %s', name, (error ).message);
2252
2250
  }
2253
2251
  }) ;
2254
2252
  }
@@ -2310,11 +2308,11 @@ const reportCommandComplete = safeRun(
2310
2308
  ,
2311
2309
  ) => {
2312
2310
  const event = EventBuilder.cliCommandComplete(command, success, duration, {
2313
- args: _optionalChain$5([options, 'optionalAccess', _ => _.args]),
2314
- errorCode: _optionalChain$5([options, 'optionalAccess', _2 => _2.errorCode]),
2311
+ args: _optionalChain$4([options, 'optionalAccess', _ => _.args]),
2312
+ errorCode: _optionalChain$4([options, 'optionalAccess', _2 => _2.errorCode]),
2315
2313
  categories: {
2316
- ...(_optionalChain$5([options, 'optionalAccess', _3 => _3.errorMessage]) && { errorMessage: options.errorMessage }),
2317
- ..._optionalChain$5([options, 'optionalAccess', _4 => _4.categories]),
2314
+ ...(_optionalChain$4([options, 'optionalAccess', _3 => _3.errorMessage]) && { errorMessage: options.errorMessage }),
2315
+ ..._optionalChain$4([options, 'optionalAccess', _4 => _4.categories]),
2318
2316
  },
2319
2317
  });
2320
2318
  reporter.sendEvent(event.name, event.metrics, event.categories);
@@ -2342,7 +2340,7 @@ const flushSlardar = safeRun('flushSlardar', async () => {
2342
2340
  await reporter.flush();
2343
2341
  });
2344
2342
 
2345
- function _nullishCoalesce$2(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain$4(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var LogLevel; (function (LogLevel) {
2343
+ function _nullishCoalesce$2(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain$3(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var LogLevel; (function (LogLevel) {
2346
2344
  const ERROR = 0; LogLevel[LogLevel["ERROR"] = ERROR] = "ERROR";
2347
2345
  const WARN = 1; LogLevel[LogLevel["WARN"] = WARN] = "WARN";
2348
2346
  const SUCCESS = 2; LogLevel[LogLevel["SUCCESS"] = SUCCESS] = "SUCCESS";
@@ -2389,7 +2387,7 @@ class Logger {
2389
2387
  return level;
2390
2388
  }
2391
2389
 
2392
- const envLevel = _optionalChain$4([process, 'access', _ => _.env, 'access', _2 => _2.LOG_LEVEL, 'optionalAccess', _3 => _3.toLowerCase, 'call', _4 => _4()]);
2390
+ const envLevel = _optionalChain$3([process, 'access', _ => _.env, 'access', _2 => _2.LOG_LEVEL, 'optionalAccess', _3 => _3.toLowerCase, 'call', _4 => _4()]);
2393
2391
  if (envLevel && envLevel in LOG_LEVEL_MAP) {
2394
2392
  return LOG_LEVEL_MAP[envLevel];
2395
2393
  }
@@ -2401,7 +2399,7 @@ class Logger {
2401
2399
  // 简单检测:Node.js 环境且支持 TTY
2402
2400
  return (
2403
2401
  typeof process !== 'undefined' &&
2404
- _optionalChain$4([process, 'access', _5 => _5.stdout, 'optionalAccess', _6 => _6.isTTY]) === true &&
2402
+ _optionalChain$3([process, 'access', _5 => _5.stdout, 'optionalAccess', _6 => _6.isTTY]) === true &&
2405
2403
  process.env.NO_COLOR === undefined
2406
2404
  );
2407
2405
  }
@@ -2802,7 +2800,7 @@ const executeWarmup = async (options) => {
2802
2800
  /**
2803
2801
  * 注册 warmup 命令到 program
2804
2802
  */
2805
- const registerCommand$5 = program => {
2803
+ const registerCommand$4 = program => {
2806
2804
  program
2807
2805
  .command('warmup')
2808
2806
  .description('Pre-install dependencies for templates to speed up init')
@@ -2812,76 +2810,6 @@ const registerCommand$5 = program => {
2812
2810
  });
2813
2811
  };
2814
2812
 
2815
- // ABOUTME: Temporary paths utility for Coze CLI
2816
- // ABOUTME: Provides centralized management of temporary directories and files
2817
-
2818
-
2819
- /**
2820
- * Base Coze directory in user's home
2821
- * Used for storing CLI-related temporary files, logs, and cache
2822
- * Default: ~/.coze
2823
- */
2824
- const COZE_HOME_DIR = '.coze';
2825
-
2826
- /**
2827
- * Logs directory name
2828
- * Default: .coze-logs
2829
- */
2830
- const LOGS_DIR = '.coze-logs';
2831
-
2832
- /**
2833
- * Get the Coze home directory path
2834
- * Can be customized via COZE_HOME environment variable
2835
- *
2836
- * @returns Absolute path to Coze home directory (default: ~/.coze)
2837
- */
2838
- const getCozeHome = () =>
2839
- process.env.COZE_HOME || path.join(os.homedir(), COZE_HOME_DIR);
2840
-
2841
- /**
2842
- * Get the logs directory path
2843
- * Can be customized via COZE_LOG_DIR environment variable
2844
- *
2845
- * @returns Absolute path to logs directory (default: ~/.coze-logs)
2846
- */
2847
- const getCozeLogsDir = () =>
2848
- process.env.COZE_LOG_DIR || path.join(os.homedir(), LOGS_DIR);
2849
-
2850
- /**
2851
- * Get path for a specific file/directory within Coze home
2852
- *
2853
- * @param relativePath - Relative path within Coze home directory
2854
- * @returns Absolute path to the file/directory
2855
- *
2856
- * @example
2857
- * ```ts
2858
- * // Get routes file path
2859
- * const routesPath = getCozeFilePath('routes.json');
2860
- * // Returns: ~/.coze/routes.json
2861
- *
2862
- * // Get cache directory
2863
- * const cacheDir = getCozeFilePath('cache');
2864
- * // Returns: ~/.coze/cache
2865
- * ```
2866
- */
2867
- const getCozeFilePath = (relativePath) =>
2868
- path.join(getCozeHome(), relativePath);
2869
-
2870
- /**
2871
- * Get path for a log file
2872
- *
2873
- * @param filename - Log file name
2874
- * @returns Absolute path to the log file
2875
- *
2876
- * @example
2877
- * ```ts
2878
- * const devLog = getCozeLogPath('dev.log');
2879
- * // Returns: ~/.coze-logs/dev.log
2880
- * ```
2881
- */
2882
- const getCozeLogPath = (filename) =>
2883
- path.join(getCozeLogsDir(), filename);
2884
-
2885
2813
  // ABOUTME: This file implements the update command for coze CLI
2886
2814
  // ABOUTME: It wraps pnpm update/install to update package dependencies with logging support
2887
2815
 
@@ -2892,22 +2820,29 @@ const getCozeLogPath = (filename) =>
2892
2820
  */
2893
2821
  const LOG_FILE_NAME$1 = 'update.log';
2894
2822
 
2823
+ /**
2824
+ * 获取日志目录
2825
+ * 优先使用环境变量 COZE_LOG_DIR,否则使用 ~/.coze-logs
2826
+ */
2827
+ const getLogDir$1 = () =>
2828
+ process.env.COZE_LOG_DIR || path.join(os.homedir(), '.coze-logs');
2829
+
2895
2830
  /**
2896
2831
  * 解析日志文件路径
2897
2832
  * - 如果是绝对路径,直接使用
2898
- * - 如果是相对路径,基于 logs 目录 + 相对路径
2899
- * - 如果为空,使用默认日志文件路径
2833
+ * - 如果是相对路径,基于 getLogDir() + 相对路径
2834
+ * - 如果为空,使用 getLogDir() + LOG_FILE_NAME
2900
2835
  */
2901
2836
  const resolveLogFilePath$1 = (logFile) => {
2902
2837
  if (!logFile) {
2903
- return getCozeLogPath(LOG_FILE_NAME$1);
2838
+ return path.join(getLogDir$1(), LOG_FILE_NAME$1);
2904
2839
  }
2905
2840
 
2906
2841
  if (path.isAbsolute(logFile)) {
2907
2842
  return logFile;
2908
2843
  }
2909
2844
 
2910
- return getCozeLogPath(logFile);
2845
+ return path.join(getLogDir$1(), logFile);
2911
2846
  };
2912
2847
 
2913
2848
  /**
@@ -3081,7 +3016,6 @@ const handleUpdateError = (
3081
3016
  /**
3082
3017
  * 执行 update 命令的内部实现
3083
3018
  */
3084
- // eslint-disable-next-line max-lines-per-function
3085
3019
  const executeUpdate = (
3086
3020
  packageName,
3087
3021
  options
@@ -3214,7 +3148,7 @@ const executeUpdate = (
3214
3148
  /**
3215
3149
  * 注册 update 命令到 program
3216
3150
  */
3217
- const registerCommand$4 = program => {
3151
+ const registerCommand$3 = program => {
3218
3152
  program
3219
3153
  .command('update <package>')
3220
3154
  .description('Update a package dependency')
@@ -3240,7 +3174,7 @@ const registerCommand$4 = program => {
3240
3174
  });
3241
3175
  };
3242
3176
 
3243
- function _optionalChain$3(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }/* eslint-disable @typescript-eslint/no-explicit-any */
3177
+ function _optionalChain$2(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }/* eslint-disable @typescript-eslint/no-explicit-any */
3244
3178
  // Safe JSON parsing utilities with type safety and error handling
3245
3179
  // Provides fallback values, validation, and error monitoring capabilities
3246
3180
 
@@ -3312,16 +3246,7 @@ function safeJsonParse(
3312
3246
 
3313
3247
  if (arguments.length === 2) {
3314
3248
  // safeJsonParse(input, options) or safeJsonParse(input, defaultValue)
3315
- if (
3316
- defaultValueOrOptions &&
3317
- typeof defaultValueOrOptions === 'object' &&
3318
- ('onError' in defaultValueOrOptions ||
3319
- 'validate' in defaultValueOrOptions ||
3320
- 'throwOnValidationError' in defaultValueOrOptions)
3321
- ) {
3322
- options = defaultValueOrOptions ;
3323
- defaultValue = undefined;
3324
- } else {
3249
+ {
3325
3250
  defaultValue = defaultValueOrOptions ;
3326
3251
  options = undefined;
3327
3252
  }
@@ -3340,12 +3265,12 @@ function safeJsonParse(
3340
3265
  const parsed = JSON.parse(String(input));
3341
3266
 
3342
3267
  // Optional validation
3343
- if (_optionalChain$3([options, 'optionalAccess', _ => _.validate])) {
3268
+ if (_optionalChain$2([options, 'optionalAccess', _ => _.validate])) {
3344
3269
  if (options.validate(parsed)) {
3345
3270
  return parsed;
3346
3271
  } else {
3347
3272
  const validationError = new Error('JSON validation failed');
3348
- _optionalChain$3([options, 'access', _2 => _2.onError, 'optionalCall', _3 => _3(validationError, input)]);
3273
+ _optionalChain$2([options, 'access', _2 => _2.onError, 'optionalCall', _3 => _3(validationError, input)]);
3349
3274
 
3350
3275
  if (options.throwOnValidationError) {
3351
3276
  throw validationError;
@@ -3357,15 +3282,15 @@ function safeJsonParse(
3357
3282
  return parsed;
3358
3283
  } catch (error) {
3359
3284
  // Re-throw validation errors when throwOnValidationError is true
3360
- if (error instanceof Error && error.message === 'JSON validation failed' && _optionalChain$3([options, 'optionalAccess', _4 => _4.throwOnValidationError])) {
3285
+ if (error instanceof Error && error.message === 'JSON validation failed' && _optionalChain$2([options, 'optionalAccess', _4 => _4.throwOnValidationError])) {
3361
3286
  throw error;
3362
3287
  }
3363
- _optionalChain$3([options, 'optionalAccess', _5 => _5.onError, 'optionalCall', _6 => _6(error , input)]);
3288
+ _optionalChain$2([options, 'optionalAccess', _5 => _5.onError, 'optionalCall', _6 => _6(error , input)]);
3364
3289
  return defaultValue;
3365
3290
  }
3366
3291
  }
3367
3292
 
3368
- function _optionalChain$2(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
3293
+ function _optionalChain$1(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
3369
3294
 
3370
3295
 
3371
3296
  /**
@@ -3455,13 +3380,13 @@ const getCommandConfig = (
3455
3380
  // 根据命令名称映射到配置路径
3456
3381
  switch (commandName) {
3457
3382
  case 'dev':
3458
- commandConfig = _optionalChain$2([config, 'access', _ => _.dev, 'optionalAccess', _2 => _2.run]);
3383
+ commandConfig = _optionalChain$1([config, 'access', _ => _.dev, 'optionalAccess', _2 => _2.run]);
3459
3384
  break;
3460
3385
  case 'build':
3461
- commandConfig = _optionalChain$2([config, 'access', _3 => _3.deploy, 'optionalAccess', _4 => _4.build]);
3386
+ commandConfig = _optionalChain$1([config, 'access', _3 => _3.deploy, 'optionalAccess', _4 => _4.build]);
3462
3387
  break;
3463
3388
  case 'start':
3464
- commandConfig = _optionalChain$2([config, 'access', _5 => _5.deploy, 'optionalAccess', _6 => _6.run]);
3389
+ commandConfig = _optionalChain$1([config, 'access', _5 => _5.deploy, 'optionalAccess', _6 => _6.run]);
3465
3390
  break;
3466
3391
  default:
3467
3392
  throw new Error(`Unknown command: ${commandName}`);
@@ -3689,7 +3614,7 @@ const executeFix = async (
3689
3614
  /**
3690
3615
  * 注册 fix 命令到 program
3691
3616
  */
3692
- const registerCommand$3 = program => {
3617
+ const registerCommand$2 = program => {
3693
3618
  program
3694
3619
  .command('fix')
3695
3620
  .description(
@@ -3704,28 +3629,35 @@ const registerCommand$3 = program => {
3704
3629
  });
3705
3630
  };
3706
3631
 
3707
- function _nullishCoalesce$1(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain$1(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
3632
+ function _nullishCoalesce$1(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
3708
3633
  /**
3709
3634
  * 日志文件名常量
3710
3635
  */
3711
3636
  const LOG_FILE_NAME = 'dev.log';
3712
3637
 
3638
+ /**
3639
+ * 获取日志目录
3640
+ * 优先使用环境变量 COZE_LOG_DIR,否则使用 ~/.coze-logs
3641
+ */
3642
+ const getLogDir = () =>
3643
+ process.env.COZE_LOG_DIR || path.join(os.homedir(), '.coze-logs');
3644
+
3713
3645
  /**
3714
3646
  * 解析日志文件路径
3715
3647
  * - 如果是绝对路径,直接使用
3716
- * - 如果是相对路径,基于 logs 目录 + 相对路径
3717
- * - 如果为空,使用默认日志文件路径
3648
+ * - 如果是相对路径,基于 getLogDir() + 相对路径
3649
+ * - 如果为空,使用 getLogDir() + LOG_FILE_NAME
3718
3650
  */
3719
3651
  const resolveLogFilePath = (logFile) => {
3720
3652
  if (!logFile) {
3721
- return getCozeLogPath(LOG_FILE_NAME);
3653
+ return path.join(getLogDir(), LOG_FILE_NAME);
3722
3654
  }
3723
3655
 
3724
3656
  if (path.isAbsolute(logFile)) {
3725
3657
  return logFile;
3726
3658
  }
3727
3659
 
3728
- return getCozeLogPath(logFile);
3660
+ return path.join(getLogDir(), logFile);
3729
3661
  };
3730
3662
 
3731
3663
  /**
@@ -3796,86 +3728,82 @@ const executeRun = async (
3796
3728
  }
3797
3729
 
3798
3730
  // 将输出同时写入控制台和日志文件
3799
- _optionalChain$1([childProcess, 'access', _ => _.stdout, 'optionalAccess', _2 => _2.on, 'call', _3 => _3('data', (data) => {
3731
+ _optionalChain([childProcess, 'access', _ => _.stdout, 'optionalAccess', _2 => _2.on, 'call', _3 => _3('data', (data) => {
3800
3732
  process.stdout.write(data);
3801
3733
  logStream.write(data);
3802
3734
  })]);
3803
3735
 
3804
- _optionalChain$1([childProcess, 'access', _4 => _4.stderr, 'optionalAccess', _5 => _5.on, 'call', _6 => _6('data', (data) => {
3736
+ _optionalChain([childProcess, 'access', _4 => _4.stderr, 'optionalAccess', _5 => _5.on, 'call', _6 => _6('data', (data) => {
3805
3737
  process.stderr.write(data);
3806
3738
  logStream.write(data);
3807
3739
  })]);
3808
3740
 
3809
- // Wait for child process to complete
3810
- await new Promise((resolve, reject) => {
3811
- childProcess.on('close', (code, signal) => {
3812
- logStream.end();
3813
-
3814
- if (code !== 0) {
3815
- const errorMessage = `Command exited with code ${_nullishCoalesce$1(code, () => ( 'unknown'))}${signal ? ` and signal ${signal}` : ''}`;
3816
- logger.error(errorMessage);
3817
- logger.error(`Check log file for details: ${logFilePath}`);
3818
-
3819
- // 上报命令失败
3820
- reportError(new Error(errorMessage), {
3821
- command: commandName,
3822
- exitCode: String(_nullishCoalesce$1(code, () => ( 'unknown'))),
3823
- signal: _nullishCoalesce$1(signal, () => ( 'none')),
3824
- logFile: logFilePath,
3825
- });
3826
- reportCommandComplete(commandName, false, Date.now() - cmdStartTime, {
3827
- args: JSON.stringify(options),
3828
- errorCode: _nullishCoalesce$1(code, () => ( 1)),
3829
- errorMessage,
3830
- });
3831
- flushSlardar()
3832
- .then(() => {
3833
- process.exit(code || 1);
3834
- })
3835
- .catch(() => {
3836
- // Catch any errors in the promise chain to prevent unhandled rejections
3837
- process.exit(code || 1);
3838
- });
3839
- } else {
3840
- logger.success('Command completed successfully');
3841
- logger.info(`Log file: ${logFilePath}`);
3842
-
3843
- // 上报命令成功
3844
- reportCommandComplete(commandName, true, Date.now() - cmdStartTime, {
3845
- args: JSON.stringify(options),
3846
- });
3847
- // flush 由 main 函数统一处理
3848
- resolve();
3849
- }
3850
- });
3741
+ childProcess.on('close', (code, signal) => {
3742
+ logStream.end();
3851
3743
 
3852
- childProcess.on('error', (error) => {
3853
- logger.error('Failed to execute command:');
3854
- logger.error(`Error: ${error.message}`);
3855
- if (error.stack) {
3856
- logger.error(`Stack trace:\n${error.stack}`);
3857
- }
3858
- logStream.end();
3744
+ if (code !== 0) {
3745
+ const errorMessage = `Command exited with code ${_nullishCoalesce$1(code, () => ( 'unknown'))}${signal ? ` and signal ${signal}` : ''}`;
3746
+ logger.error(errorMessage);
3747
+ logger.error(`Check log file for details: ${logFilePath}`);
3859
3748
 
3860
- // 上报错误
3861
- reportError(error, {
3749
+ // 上报命令失败
3750
+ reportError(new Error(errorMessage), {
3862
3751
  command: commandName,
3863
- type: 'child_process_error',
3752
+ exitCode: String(_nullishCoalesce$1(code, () => ( 'unknown'))),
3753
+ signal: _nullishCoalesce$1(signal, () => ( 'none')),
3754
+ logFile: logFilePath,
3864
3755
  });
3865
3756
  reportCommandComplete(commandName, false, Date.now() - cmdStartTime, {
3866
3757
  args: JSON.stringify(options),
3867
- errorCode: 1,
3868
- errorMessage: error.message,
3758
+ errorCode: _nullishCoalesce$1(code, () => ( 1)),
3759
+ errorMessage,
3869
3760
  });
3870
3761
  flushSlardar()
3871
3762
  .then(() => {
3872
- process.exit(1);
3763
+ process.exit(code || 1);
3873
3764
  })
3874
3765
  .catch(() => {
3875
3766
  // Catch any errors in the promise chain to prevent unhandled rejections
3876
- process.exit(1);
3767
+ process.exit(code || 1);
3877
3768
  });
3769
+ } else {
3770
+ logger.success('Command completed successfully');
3771
+ logger.info(`Log file: ${logFilePath}`);
3772
+
3773
+ // 上报命令成功
3774
+ reportCommandComplete(commandName, true, Date.now() - cmdStartTime, {
3775
+ args: JSON.stringify(options),
3776
+ });
3777
+ // flush 由 main 函数统一处理
3778
+ }
3779
+ });
3780
+
3781
+ childProcess.on('error', (error) => {
3782
+ logger.error('Failed to execute command:');
3783
+ logger.error(`Error: ${error.message}`);
3784
+ if (error.stack) {
3785
+ logger.error(`Stack trace:\n${error.stack}`);
3786
+ }
3787
+ logStream.end();
3788
+
3789
+ // 上报错误
3790
+ reportError(error, {
3791
+ command: commandName,
3792
+ type: 'child_process_error',
3793
+ });
3794
+ reportCommandComplete(commandName, false, Date.now() - cmdStartTime, {
3795
+ args: JSON.stringify(options),
3796
+ errorCode: 1,
3797
+ errorMessage: error.message,
3878
3798
  });
3799
+ flushSlardar()
3800
+ .then(() => {
3801
+ process.exit(1);
3802
+ })
3803
+ .catch(() => {
3804
+ // Catch any errors in the promise chain to prevent unhandled rejections
3805
+ process.exit(1);
3806
+ });
3879
3807
  });
3880
3808
  } catch (error) {
3881
3809
  const err = error instanceof Error ? error : new Error(String(error));
@@ -3906,7 +3834,7 @@ const executeRun = async (
3906
3834
  /**
3907
3835
  * 注册 dev/build/start 命令到 program
3908
3836
  */
3909
- const registerCommand$2 = program => {
3837
+ const registerCommand$1 = program => {
3910
3838
  // dev 命令
3911
3839
  program
3912
3840
  .command('dev')
@@ -3935,901 +3863,6 @@ const registerCommand$2 = program => {
3935
3863
  });
3936
3864
  };
3937
3865
 
3938
- // ABOUTME: Nuxt route scanner
3939
- // ABOUTME: Scans Nuxt file-based routing structure to extract page and server routes
3940
-
3941
-
3942
-
3943
-
3944
- const log$4 = debug('coze:routes:nuxt');
3945
-
3946
- /**
3947
- * Convert Nuxt file path to route path
3948
- * Examples:
3949
- * - pages/index.vue -> /
3950
- * - app/pages/index.vue -> /
3951
- * - src/pages/index.vue -> /
3952
- * - src/app/pages/index.vue -> /
3953
- * - pages/blog/[id].vue -> /blog/[id]
3954
- * - server/api/users.ts -> /api/users
3955
- * - server/routes/webhook.ts -> /webhook
3956
- */
3957
- const nuxtFilePathToRoute = (
3958
- filePath,
3959
- type,
3960
- ) => {
3961
- let route;
3962
-
3963
- if (type === 'page') {
3964
- // Remove pages prefix (supports all variations) and .vue extension
3965
- route = filePath
3966
- .replace(/^src\/app\/pages\//, '') // src/app/pages/
3967
- .replace(/^src\/pages\//, '') // src/pages/
3968
- .replace(/^app\/pages\//, '') // app/pages/
3969
- .replace(/^pages\//, '') // pages/
3970
- .replace(/\.vue$/, '')
3971
- .replace(/\/index$/, ''); // Remove trailing /index
3972
-
3973
- // Handle index.vue at root (becomes empty string)
3974
- if (route === 'index') {
3975
- return '/';
3976
- }
3977
- } else {
3978
- // API routes - support both server/ and src/server/
3979
- if (filePath.includes('/api/')) {
3980
- route = `/api/${filePath
3981
- .replace(/^src\/server\/api\//, '')
3982
- .replace(/^server\/api\//, '')
3983
- .replace(/\.(ts|js)$/, '')}`;
3984
- } else {
3985
- // server/routes - support both server/ and src/server/
3986
- route = `/${filePath
3987
- .replace(/^src\/server\/routes\//, '')
3988
- .replace(/^server\/routes\//, '')
3989
- .replace(/\.(ts|js)$/, '')}`;
3990
- }
3991
- }
3992
-
3993
- // Handle root route
3994
- if (route === '' || route === '/') {
3995
- return '/';
3996
- }
3997
-
3998
- // Ensure leading slash
3999
- if (!route.startsWith('/')) {
4000
- route = `/${route}`;
4001
- }
4002
-
4003
- return route;
4004
- };
4005
-
4006
- /**
4007
- * Normalize Nuxt route path to standard format
4008
- * Converts Nuxt dynamic segments to standard format:
4009
- * - [id] -> :id
4010
- * - [...slug] -> :slug*
4011
- */
4012
- const normalizeRoutePath$1 = (routePath) =>
4013
- routePath
4014
- .replace(/\[\.\.\.(\w+)\]/g, ':$1*') // [...slug] -> :slug*
4015
- .replace(/\[(\w+)\]/g, ':$1'); // [id] -> :id
4016
- /**
4017
- * Extract dynamic parameter names from route path
4018
- */
4019
- const extractParams$1 = (routePath) => {
4020
- const params = [];
4021
- const patterns = [
4022
- /\[\.\.\.(\w+)\]/g, // [...slug]
4023
- /\[(\w+)\]/g, // [id]
4024
- ];
4025
-
4026
- patterns.forEach(pattern => {
4027
- const matches = routePath.matchAll(pattern);
4028
- for (const match of matches) {
4029
- params.push(match[1]);
4030
- }
4031
- });
4032
-
4033
- return params;
4034
- };
4035
-
4036
- /**
4037
- * Scan Nuxt routes from pages and server directories
4038
- *
4039
- * Supports multiple directory structures:
4040
- * - **Page routes**:
4041
- * - pages/**\/*.vue (default)
4042
- * - app/pages/**\/*.vue (Nuxt 3 app directory)
4043
- * - src/pages/**\/*.vue (srcDir: 'src/')
4044
- * - src/app/pages/**\/*.vue (srcDir: 'src/' + app directory)
4045
- *
4046
- * - **API routes**:
4047
- * - server/api/**\/*.{ts,js} (default)
4048
- * - src/server/api/**\/*.{ts,js} (srcDir: 'src/')
4049
- *
4050
- * - **Server routes**:
4051
- * - server/routes/**\/*.{ts,js} (default)
4052
- * - src/server/routes/**\/*.{ts,js} (srcDir: 'src/')
4053
- *
4054
- * Excludes:
4055
- * - layouts/ directories - Layout components (NOT routes)
4056
- * - app.vue, error.vue - Special files (NOT regular routes)
4057
- *
4058
- * @param cwd - Current working directory
4059
- * @returns List of detected routes
4060
- */
4061
- const scanNuxtRoutes = async (cwd) => {
4062
- log$4('Scanning Nuxt routes in:', cwd);
4063
- const routes = [];
4064
-
4065
- // Scan page routes - support multiple directory structures:
4066
- // - pages/ (default)
4067
- // - app/pages/ (Nuxt 3 app directory)
4068
- // - src/pages/ (srcDir: 'src/')
4069
- // - src/app/pages/ (srcDir: 'src/' + app directory)
4070
- const pageFiles = await fastGlob.glob(
4071
- ['{pages,app/pages,src/pages,src/app/pages}/**/*.vue'],
4072
- {
4073
- cwd,
4074
- ignore: [
4075
- '**/node_modules/**',
4076
- '**/.nuxt/**',
4077
- '**/dist/**',
4078
- '**/.output/**',
4079
- // Exclude layouts directory (not routes)
4080
- '**/layouts/**',
4081
- 'app/layouts/**',
4082
- 'src/layouts/**',
4083
- 'src/app/layouts/**',
4084
- // Exclude special files
4085
- 'app.vue',
4086
- 'error.vue',
4087
- 'src/app.vue',
4088
- 'src/error.vue',
4089
- ],
4090
- onlyFiles: true,
4091
- followSymbolicLinks: false,
4092
- },
4093
- );
4094
-
4095
- log$4('Found %d page files', pageFiles.length);
4096
-
4097
- routes.push(
4098
- ...pageFiles.map(file => {
4099
- const routePath = nuxtFilePathToRoute(file, 'page');
4100
- const isDynamic = routePath.includes('[');
4101
- const params = extractParams$1(routePath);
4102
-
4103
- return {
4104
- path: normalizeRoutePath$1(routePath),
4105
- rawPath: routePath,
4106
- dynamic: isDynamic,
4107
- params,
4108
- type: 'page' ,
4109
- file,
4110
- framework: 'nuxt' ,
4111
- };
4112
- }),
4113
- );
4114
-
4115
- // Scan API routes - support both server/ and src/server/
4116
- const apiFiles = await fastGlob.glob('{server,src/server}/api/**/*.{ts,js}', {
4117
- cwd,
4118
- ignore: ['**/node_modules/**', '**/dist/**', '**/.output/**'],
4119
- onlyFiles: true,
4120
- followSymbolicLinks: false,
4121
- });
4122
-
4123
- log$4('Found %d API files', apiFiles.length);
4124
-
4125
- routes.push(
4126
- ...apiFiles.map(file => {
4127
- const routePath = nuxtFilePathToRoute(file, 'api');
4128
- const isDynamic = routePath.includes('[');
4129
- const params = extractParams$1(routePath);
4130
-
4131
- return {
4132
- path: normalizeRoutePath$1(routePath),
4133
- rawPath: routePath,
4134
- dynamic: isDynamic,
4135
- params,
4136
- type: 'api' ,
4137
- file,
4138
- framework: 'nuxt' ,
4139
- };
4140
- }),
4141
- );
4142
-
4143
- // Scan server routes - support both server/ and src/server/
4144
- const serverRouteFiles = await fastGlob.glob(
4145
- '{server,src/server}/routes/**/*.{ts,js}',
4146
- {
4147
- cwd,
4148
- ignore: ['**/node_modules/**', '**/dist/**', '**/.output/**'],
4149
- onlyFiles: true,
4150
- followSymbolicLinks: false,
4151
- },
4152
- );
4153
-
4154
- log$4('Found %d server route files', serverRouteFiles.length);
4155
-
4156
- routes.push(
4157
- ...serverRouteFiles.map(file => {
4158
- const routePath = nuxtFilePathToRoute(file, 'api');
4159
- const isDynamic = routePath.includes('[');
4160
- const params = extractParams$1(routePath);
4161
-
4162
- return {
4163
- path: normalizeRoutePath$1(routePath),
4164
- rawPath: routePath,
4165
- dynamic: isDynamic,
4166
- params,
4167
- type: 'api' ,
4168
- file,
4169
- framework: 'nuxt' ,
4170
- };
4171
- }),
4172
- );
4173
-
4174
- log$4('Total routes found: %d', routes.length);
4175
- return routes;
4176
- };
4177
-
4178
- // ABOUTME: Next.js route scanner
4179
- // ABOUTME: Scans Next.js App Router file structure to extract routes
4180
-
4181
-
4182
-
4183
-
4184
- const log$3 = debug('coze:routes:nextjs');
4185
-
4186
- /**
4187
- * Convert Next.js file path to route path
4188
- * Examples:
4189
- * - src/app/page.tsx -> /
4190
- * - src/app/blog/page.tsx -> /blog
4191
- * - src/app/blog/[id]/page.tsx -> /blog/[id]
4192
- * - src/app/api/users/route.ts -> /api/users
4193
- */
4194
- const filePathToRoute = (filePath) => {
4195
- // Remove src/app prefix and file extension
4196
- let route = filePath
4197
- .replace(/^src\/app/, '')
4198
- .replace(/\/(page|route|layout)\.(tsx?|jsx?)$/, '');
4199
-
4200
- // Handle root route
4201
- if (route === '' || route === '/') {
4202
- return '/';
4203
- }
4204
-
4205
- // Ensure leading slash
4206
- if (!route.startsWith('/')) {
4207
- route = `/${route}`;
4208
- }
4209
-
4210
- return route;
4211
- };
4212
-
4213
- /**
4214
- * Normalize route path to standard format
4215
- * Converts Next.js dynamic segments to standard format:
4216
- * - [id] -> :id
4217
- * - [...slug] -> :slug*
4218
- * - [[...slug]] -> :slug*?
4219
- */
4220
- const normalizeRoutePath = (routePath) =>
4221
- routePath
4222
- .replace(/\[\[\.\.\.(\w+)\]\]/g, ':$1*?') // [[...slug]] -> :slug*?
4223
- .replace(/\[\.\.\.(\w+)\]/g, ':$1*') // [...slug] -> :slug*
4224
- .replace(/\[(\w+)\]/g, ':$1'); // [id] -> :id
4225
- /**
4226
- * Extract dynamic parameter names from route path
4227
- * Note: Uses Set to avoid duplicates when patterns overlap (e.g., [[...slug]])
4228
- */
4229
- const extractParams = (routePath) => {
4230
- const paramsSet = new Set();
4231
- const patterns = [
4232
- /\[\[\.\.\.(\w+)\]\]/g, // [[...slug]]
4233
- /\[\.\.\.(\w+)\]/g, // [...slug]
4234
- /\[(\w+)\]/g, // [id]
4235
- ];
4236
-
4237
- patterns.forEach(pattern => {
4238
- const matches = routePath.matchAll(pattern);
4239
- for (const match of matches) {
4240
- paramsSet.add(match[1]);
4241
- }
4242
- });
4243
-
4244
- return Array.from(paramsSet);
4245
- };
4246
-
4247
- /**
4248
- * Determine route type based on file name
4249
- */
4250
- const getRouteType = (filePath) => {
4251
- if (filePath.includes('/route.')) {
4252
- return 'api';
4253
- }
4254
- return 'page';
4255
- };
4256
-
4257
- /**
4258
- * Scan Next.js App Router routes from app/ or src/app/ directory
4259
- *
4260
- * Scans for:
4261
- * - page.tsx/jsx/ts/js - Page routes
4262
- * - route.ts/js - API routes
4263
- *
4264
- * Note: layout.tsx, loading.tsx, error.tsx are NOT routes, they are UI components
4265
- */
4266
- const scanAppRouter = async (cwd) => {
4267
- log$3('Scanning App Router routes');
4268
-
4269
- const files = await fastGlob.glob('{app,src/app}/**/{page,route}.{tsx,ts,jsx,js}', {
4270
- cwd,
4271
- ignore: [
4272
- '**/node_modules/**',
4273
- '**/.next/**',
4274
- '**/dist/**',
4275
- '**/build/**',
4276
- '**/.turbo/**',
4277
- ],
4278
- onlyFiles: true,
4279
- followSymbolicLinks: false,
4280
- });
4281
-
4282
- log$3('Found %d App Router files', files.length);
4283
-
4284
- return files.map(file => {
4285
- const routePath = filePathToRoute(file);
4286
- const isDynamic = routePath.includes('[');
4287
- const params = extractParams(routePath);
4288
-
4289
- return {
4290
- path: normalizeRoutePath(routePath),
4291
- rawPath: routePath,
4292
- dynamic: isDynamic,
4293
- params,
4294
- type: getRouteType(file),
4295
- file,
4296
- framework: 'nextjs',
4297
- };
4298
- });
4299
- };
4300
-
4301
- /**
4302
- * Convert Pages Router file path to route path
4303
- * Examples:
4304
- * - pages/index.tsx -> /
4305
- * - src/pages/index.tsx -> /
4306
- * - pages/blog/[id].tsx -> /blog/[id]
4307
- * - pages/api/users.ts -> /api/users
4308
- */
4309
- const pagesFilePathToRoute = (filePath) => {
4310
- // Remove pages prefix and file extension
4311
- let route = filePath
4312
- .replace(/^src\/pages\//, '')
4313
- .replace(/^pages\//, '')
4314
- .replace(/\.(tsx?|jsx?)$/, '')
4315
- .replace(/\/index$/, ''); // pages/blog/index.tsx -> /blog
4316
-
4317
- // Handle root index
4318
- if (route === 'index' || route === '') {
4319
- return '/';
4320
- }
4321
-
4322
- // Ensure leading slash
4323
- if (!route.startsWith('/')) {
4324
- route = `/${route}`;
4325
- }
4326
-
4327
- return route;
4328
- };
4329
-
4330
- /**
4331
- * Determine if a Pages Router file is an API route
4332
- */
4333
- const isPagesApiRoute = (filePath) =>
4334
- filePath.includes('/api/') || !!filePath.match(/\/(pages|src\/pages)\/api\//);
4335
-
4336
- /**
4337
- * Scan Next.js Pages Router routes from pages/ or src/pages/ directory
4338
- *
4339
- * Scans for:
4340
- * - pages/**\/*.tsx/jsx/ts/js - Page routes
4341
- * - pages/api/**\/*.ts/js - API routes
4342
- *
4343
- * Note: _app.tsx, _document.tsx, _error.tsx are special files, NOT routes
4344
- */
4345
- const scanPagesRouter = async (cwd) => {
4346
- log$3('Scanning Pages Router routes');
4347
-
4348
- const files = await fastGlob.glob('{pages,src/pages}/**/*.{tsx,ts,jsx,js}', {
4349
- cwd,
4350
- ignore: [
4351
- '**/node_modules/**',
4352
- '**/.next/**',
4353
- '**/dist/**',
4354
- '**/build/**',
4355
- '**/.turbo/**',
4356
- // Exclude special Next.js files (these are NOT routes)
4357
- '**/_app.{tsx,ts,jsx,js}',
4358
- '**/_document.{tsx,ts,jsx,js}',
4359
- '**/_error.{tsx,ts,jsx,js}',
4360
- '**/middleware.{ts,js}',
4361
- ],
4362
- onlyFiles: true,
4363
- followSymbolicLinks: false,
4364
- });
4365
-
4366
- log$3('Found %d Pages Router files', files.length);
4367
-
4368
- return files.map(file => {
4369
- const routePath = pagesFilePathToRoute(file);
4370
- const isDynamic = routePath.includes('[');
4371
- const params = extractParams(routePath);
4372
-
4373
- return {
4374
- path: normalizeRoutePath(routePath),
4375
- rawPath: routePath,
4376
- dynamic: isDynamic,
4377
- params,
4378
- type: isPagesApiRoute(file) ? 'api' : 'page',
4379
- file,
4380
- framework: 'nextjs',
4381
- };
4382
- });
4383
- };
4384
-
4385
- /**
4386
- * Scan Next.js routes - supports both App Router and Pages Router
4387
- *
4388
- * Next.js supports two routing systems that can coexist:
4389
- * 1. **App Router** (Next.js 13+): app/ or src/app/
4390
- * - page.tsx/jsx/ts/js - Page routes
4391
- * - route.ts/js - API routes
4392
- *
4393
- * 2. **Pages Router** (Traditional): pages/ or src/pages/
4394
- * - **\/*.tsx/jsx/ts/js - Page routes
4395
- * - api/**\/*.ts/js - API routes
4396
- *
4397
- * @param cwd - Current working directory
4398
- * @returns List of detected routes from both routing systems
4399
- */
4400
- const scanNextjsRoutes = async (cwd) => {
4401
- log$3('Scanning Next.js routes in:', cwd);
4402
-
4403
- // Scan both routing systems in parallel
4404
- const [appRoutes, pagesRoutes] = await Promise.all([
4405
- scanAppRouter(cwd),
4406
- scanPagesRouter(cwd),
4407
- ]);
4408
-
4409
- const totalRoutes = [...appRoutes, ...pagesRoutes];
4410
- log$3(
4411
- 'Total routes found: %d (App Router: %d, Pages Router: %d)',
4412
- totalRoutes.length,
4413
- appRoutes.length,
4414
- pagesRoutes.length,
4415
- );
4416
-
4417
- return totalRoutes;
4418
- };
4419
-
4420
- // ABOUTME: Route manifest file writer
4421
- // ABOUTME: Writes route data to JSON file with proper formatting and directory creation
4422
-
4423
-
4424
-
4425
-
4426
- /**
4427
- * Calculate route statistics
4428
- */
4429
- const calculateStats = (routes) => {
4430
- const dynamic = routes.filter(r => r.dynamic).length;
4431
- const staticCount = routes.length - dynamic;
4432
-
4433
- return {
4434
- total: routes.length,
4435
- dynamic,
4436
- static: staticCount,
4437
- };
4438
- };
4439
-
4440
- /**
4441
- * Resolve output file path
4442
- * - Relative path: resolve based on cwd
4443
- * - Absolute path: use as-is
4444
- */
4445
- const resolveOutputPath = (cwd, outputPath) =>
4446
- path.isAbsolute(outputPath) ? outputPath : path.join(cwd, outputPath);
4447
-
4448
- /**
4449
- * Ensure parent directory exists
4450
- * Handles edge cases like existing files with same name
4451
- */
4452
- const ensureDir$1 = (filePath) => {
4453
- const dir = path.dirname(filePath);
4454
-
4455
- // If directory already exists, verify it's actually a directory
4456
- if (fs.existsSync(dir)) {
4457
- const stats = fs.statSync(dir);
4458
- if (!stats.isDirectory()) {
4459
- throw new Error(`Path exists but is not a directory: ${dir}`);
4460
- }
4461
- return; // Directory exists and is valid
4462
- }
4463
-
4464
- // Create directory with recursive option (equivalent to mkdir -p)
4465
- fs.mkdirSync(dir, { recursive: true });
4466
- };
4467
-
4468
- // JSON.stringify indent size
4469
- const JSON_INDENT = 2;
4470
-
4471
- /**
4472
- * Write route manifest to JSON file
4473
- *
4474
- * @param cwd - Current working directory (not used when outputPath is absolute)
4475
- * @param routes - List of routes to write
4476
- * @param templateType - Framework type
4477
- * @param outputPath - Output file path (absolute or relative to cwd)
4478
- */
4479
- const writeRoutesFile = (
4480
- cwd,
4481
- routes,
4482
- templateType,
4483
- outputPath,
4484
- ) => {
4485
- try {
4486
- const resolvedPath = resolveOutputPath(cwd, outputPath);
4487
-
4488
- // Ensure parent directory exists
4489
- ensureDir$1(resolvedPath);
4490
-
4491
- // Build manifest
4492
- const manifest = {
4493
- framework: templateType,
4494
- generatedAt: new Date().toISOString(),
4495
- routes,
4496
- stats: calculateStats(routes),
4497
- };
4498
-
4499
- // Write to file with pretty formatting
4500
- fs.writeFileSync(
4501
- resolvedPath,
4502
- JSON.stringify(manifest, null, JSON_INDENT),
4503
- 'utf-8',
4504
- );
4505
- } catch (error) {
4506
- // Wrap error with context for better debugging
4507
- const errorMessage = error instanceof Error ? error.message : String(error);
4508
- throw new Error(`Failed to write routes file: ${errorMessage}`);
4509
- }
4510
- };
4511
-
4512
- /**
4513
- * Get the absolute path of the output file
4514
- * Useful for logging and testing
4515
- */
4516
- const getOutputFilePath = (cwd, outputPath) =>
4517
- resolveOutputPath(cwd, outputPath);
4518
-
4519
- // ABOUTME: Template type detection logic
4520
- // ABOUTME: Detects framework type by checking config files and package.json dependencies
4521
-
4522
-
4523
-
4524
-
4525
- const log$2 = debug('coze:routes:detect');
4526
-
4527
- /**
4528
- * Check if any of the specified files exist
4529
- */
4530
- const hasFile = (cwd, ...files) =>
4531
- files.some(file => fs.existsSync(path.join(cwd, file)));
4532
-
4533
- /**
4534
- * Detect template type by checking config files and package.json dependencies
4535
- *
4536
- * Detection rules (priority order):
4537
- * 1. Next.js (highest) - has `next` dependency + next.config.{js,mjs,ts}
4538
- * 2. Nuxt - has `nuxt` dependency + nuxt.config.{ts,js,mjs}
4539
- * 3. Vite (lowest) - has `vite` + `express` dependencies + vite.config.{ts,js,mjs}
4540
- *
4541
- * @param cwd - Current working directory
4542
- * @returns Template type or null if detection fails
4543
- */
4544
- const detectTemplate = (cwd) => {
4545
- log$2('Detecting template type in:', cwd);
4546
-
4547
- const pkgPath = path.join(cwd, 'package.json');
4548
-
4549
- if (!fs.existsSync(pkgPath)) {
4550
- log$2('package.json not found');
4551
- return null;
4552
- }
4553
-
4554
- try {
4555
- const pkgContent = fs.readFileSync(pkgPath, 'utf-8');
4556
- // eslint-disable-next-line no-restricted-syntax
4557
- const pkg = JSON.parse(pkgContent)
4558
-
4559
-
4560
- ;
4561
- const deps = { ...pkg.dependencies, ...pkg.devDependencies };
4562
- log$2('Dependencies found:', Object.keys(deps).length, 'packages');
4563
-
4564
- // 1. Next.js - highest priority
4565
- const hasNextDep = !!deps.next;
4566
- const hasNextConfig = hasFile(
4567
- cwd,
4568
- 'next.config.js',
4569
- 'next.config.mjs',
4570
- 'next.config.ts',
4571
- );
4572
- log$2('Next.js check - dependency:', hasNextDep, 'config:', hasNextConfig);
4573
-
4574
- if (hasNextDep && hasNextConfig) {
4575
- log$2('✓ Detected: nextjs');
4576
- return 'nextjs';
4577
- }
4578
-
4579
- // 2. Nuxt - second priority
4580
- const hasNuxtDep = !!deps.nuxt;
4581
- const hasNuxtConfig = hasFile(
4582
- cwd,
4583
- 'nuxt.config.ts',
4584
- 'nuxt.config.js',
4585
- 'nuxt.config.mjs',
4586
- );
4587
- log$2('Nuxt check - dependency:', hasNuxtDep, 'config:', hasNuxtConfig);
4588
-
4589
- if (hasNuxtDep && hasNuxtConfig) {
4590
- log$2('✓ Detected: nuxt');
4591
- return 'nuxt';
4592
- }
4593
-
4594
- // 3. Vite - lowest priority (requires both vite and express)
4595
- const hasViteDep = !!deps.vite;
4596
- const hasExpressDep = !!deps.express;
4597
- const hasViteConfig = hasFile(
4598
- cwd,
4599
- 'vite.config.ts',
4600
- 'vite.config.js',
4601
- 'vite.config.mjs',
4602
- );
4603
- log$2(
4604
- 'Vite check - vite dep:',
4605
- hasViteDep,
4606
- 'express dep:',
4607
- hasExpressDep,
4608
- 'config:',
4609
- hasViteConfig,
4610
- );
4611
-
4612
- if (hasViteDep && hasExpressDep && hasViteConfig) {
4613
- log$2('✓ Detected: vite');
4614
- return 'vite';
4615
- }
4616
-
4617
- log$2('✗ No template detected');
4618
- return null;
4619
- } catch (error) {
4620
- // Invalid package.json or other errors
4621
- log$2('Error during detection:', error);
4622
- return null;
4623
- }
4624
- };
4625
-
4626
- // ABOUTME: Route scanner main entry point
4627
- // ABOUTME: Orchestrates template detection, route scanning, and polling-based updates
4628
-
4629
-
4630
- const log$1 = debug('coze:routes:scanner');
4631
-
4632
- /**
4633
- * Scan routes based on template type
4634
- */
4635
- const scanRoutes = async (
4636
- cwd,
4637
- templateType,
4638
- ) => {
4639
- switch (templateType) {
4640
- case 'nextjs':
4641
- return scanNextjsRoutes(cwd);
4642
- case 'nuxt':
4643
- return scanNuxtRoutes(cwd);
4644
- case 'vite':
4645
- return [];
4646
- default:
4647
- return [];
4648
- }
4649
- };
4650
-
4651
- /**
4652
- * Detect and validate template type
4653
- * @returns Template type or null if invalid/unsupported
4654
- */
4655
- const detectAndValidateTemplate = (cwd) => {
4656
- log$1('Detecting template type');
4657
- const templateType = detectTemplate(cwd);
4658
-
4659
- if (!templateType) {
4660
- log$1('No template type detected');
4661
- logger.warn('Unable to detect template type, skipping route scanning');
4662
- return null;
4663
- }
4664
-
4665
- log$1('Template detected:', templateType);
4666
-
4667
- if (templateType === 'vite') {
4668
- log$1('Skipping Vite template - not supported');
4669
- return null;
4670
- }
4671
-
4672
- return templateType;
4673
- };
4674
-
4675
- /**
4676
- * Scan routes once without starting polling
4677
- * Used by the standalone `coze routes` command
4678
- *
4679
- * @param cwd - Current working directory
4680
- * @param options - Scanning options (output path, etc.)
4681
- * @returns Route manifest with routes and metadata
4682
- */
4683
- const scanRoutesOnce = async (
4684
- cwd,
4685
- options = {},
4686
-
4687
-
4688
-
4689
-
4690
- ) => {
4691
- try {
4692
- log$1('scanRoutesOnce called with cwd:', cwd, 'options:', options);
4693
-
4694
- // Default output to ~/.coze/routes.json (user home), can be overridden via options or env var
4695
- const defaultOutputPath =
4696
- process.env.COZE_ROUTES_OUTPUT || getCozeFilePath('routes.json');
4697
- const { outputPath = defaultOutputPath } = options;
4698
-
4699
- // Step 1: Detect and validate template
4700
- const templateType = detectAndValidateTemplate(cwd);
4701
- if (!templateType) {
4702
- return null;
4703
- }
4704
-
4705
- // Step 2: Perform scan
4706
- log$1('Performing route scan');
4707
- const routes = await scanRoutes(cwd, templateType);
4708
- log$1('Scan found %d routes', routes.length);
4709
-
4710
- // Step 3: Write to file
4711
- log$1('Writing routes to file:', outputPath);
4712
- writeRoutesFile(cwd, routes, templateType, outputPath);
4713
-
4714
- const outputFilePath = getOutputFilePath(cwd, outputPath);
4715
- log$1('Routes written to: %s (%d routes)', outputFilePath, routes.length);
4716
-
4717
- return {
4718
- routes,
4719
- templateType,
4720
- outputPath: outputFilePath,
4721
- };
4722
- } catch (error) {
4723
- log$1('ERROR in scanRoutesOnce:', error);
4724
- throw error;
4725
- }
4726
- };
4727
-
4728
- function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// Route manifest generation command
4729
-
4730
-
4731
- const log = debug('coze:routes');
4732
-
4733
- /**
4734
- * Execute routes command implementation
4735
- */
4736
- const executeRoutes = async (
4737
- options = {},
4738
- ) => {
4739
- const startTime = Date.now();
4740
-
4741
- try {
4742
- // Report command start
4743
- reportCommandStart('routes');
4744
-
4745
- const cwd = process.cwd();
4746
- const projectFolder = options.directory
4747
- ? path.resolve(cwd, options.directory)
4748
- : cwd;
4749
-
4750
- log('Scanning routes in: %s', projectFolder);
4751
-
4752
- // Scan routes once (no polling)
4753
- const result = await scanRoutesOnce(projectFolder, {
4754
- outputPath: options.output,
4755
- });
4756
-
4757
- if (!result) {
4758
- logger.error(
4759
- '❌ Unable to scan routes - unsupported or undetected template',
4760
- );
4761
- logger.error('\nSupported templates:');
4762
- logger.error(' - Next.js (App Router)');
4763
- logger.error(' - Nuxt');
4764
- process.exit(1);
4765
- }
4766
-
4767
- const { routes, templateType, outputPath } = result;
4768
-
4769
- // Read and parse the generated manifest file
4770
- const manifestContent = fs.readFileSync(outputPath, 'utf-8');
4771
- const manifest = safeJsonParse(manifestContent, {
4772
- framework: templateType,
4773
- generatedAt: new Date().toISOString(),
4774
- routes: [],
4775
- stats: { total: 0, dynamic: 0, static: 0 },
4776
- });
4777
-
4778
- const JSON_INDENT = 2;
4779
-
4780
- // Output pure JSON to stdout (can be piped to other tools like jq)
4781
- console.log(JSON.stringify(manifest, null, JSON_INDENT));
4782
-
4783
- // Log execution details to debug
4784
- const duration = Date.now() - startTime;
4785
- log('✓ Routes generated successfully');
4786
- log(' File: %s', outputPath);
4787
- log(' Framework: %s', templateType);
4788
- log(' Total routes: %d', routes.length);
4789
- log(' 执行时间: %dms', duration);
4790
-
4791
- // Report command completion
4792
- reportCommandComplete('routes', true, duration, {
4793
- categories: {
4794
- framework: templateType,
4795
- routeCount: String(routes.length),
4796
- outputPath,
4797
- },
4798
- });
4799
- } catch (error) {
4800
- logger.error('❌ Failed to generate routes:');
4801
- logger.error(error instanceof Error ? error.message : String(error));
4802
-
4803
- // Report error
4804
- reportError(error instanceof Error ? error : new Error(String(error)), {
4805
- command: 'routes',
4806
- context: 'route-generation',
4807
- });
4808
-
4809
- process.exit(1);
4810
- }
4811
- };
4812
-
4813
- /**
4814
- * Register routes command to program
4815
- */
4816
- const registerCommand$1 = program => {
4817
- program
4818
- .command('routes')
4819
- .description('Generate routes manifest for the current project')
4820
- .argument(
4821
- '[directory]',
4822
- 'Target directory to scan (defaults to current directory)',
4823
- )
4824
- .option(
4825
- '-o, --output <path>',
4826
- 'Output file path (defaults to ~/.coze/routes.json)',
4827
- )
4828
- .action(async (directory, options) => {
4829
- await executeRoutes({ directory, output: _optionalChain([options, 'optionalAccess', _ => _.output]) });
4830
- });
4831
- };
4832
-
4833
3866
  /**
4834
3867
  * 在后台启动一个独立的子进程
4835
3868
  * 类似于 `setsid command args >/dev/null 2>&1 &`
@@ -6111,11 +5144,10 @@ const registerCommand = program => {
6111
5144
 
6112
5145
  const commands = [
6113
5146
  registerCommand,
5147
+ registerCommand$1,
5148
+ registerCommand$4,
6114
5149
  registerCommand$2,
6115
- registerCommand$5,
6116
5150
  registerCommand$3,
6117
- registerCommand$4,
6118
- registerCommand$1,
6119
5151
  ];
6120
5152
 
6121
5153
  const main = async () => {