create-openclaw-bot 5.8.4 → 5.8.5

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/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  # 🦞 OpenClaw Setup
4
4
 
5
5
  <p align="center">
6
- <a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.8.4-0EA5E9?style=for-the-badge" alt="Version 5.8.4" /></a>
6
+ <a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.8.5-0EA5E9?style=for-the-badge" alt="Version 5.8.5" /></a>
7
7
  <a href="https://github.com/tuanminhhole/openclaw-setup?tab=MIT-1-ov-file"><img src="https://img.shields.io/badge/LICENSE-MIT-success?style=for-the-badge" alt="MIT License" /></a>
8
8
  <a href="https://www.npmjs.com/package/create-openclaw-bot"><img src="https://img.shields.io/npm/v/create-openclaw-bot?style=for-the-badge&label=CLI&color=2563EB&logo=npm&logoColor=white" alt="NPM Version" /></a>
9
9
  <a href="https://github.com/tuanminhhole/openclaw-setup/stargazers"><img src="https://img.shields.io/github/stars/tuanminhhole/openclaw-setup?style=for-the-badge&color=eab308&logo=github&logoColor=white" alt="GitHub Stars" /></a>
@@ -23,7 +23,7 @@ A next-generation **Web UI Setup** and management dashboard that automates 100%
23
23
 
24
24
  ---
25
25
 
26
- ## 🆕 What's New in v5.8.4
26
+ ## 🆕 What's New in v5.8.5
27
27
 
28
28
  - 🔄 **Smart Header Update Button**: Instantly upgrades the setup wizard from the UI! The button queries the npm registry dynamically and only reveals itself when a newer release is published.
29
29
  - 📡 **Live Log-Streaming Upgrade**: Kicking off the update automatically executes the migration (running `git pull && npm install && npm run build` for Git clones, or `npm install -g create-openclaw-bot` for NPM installs) while streaming standard outputs in real-time straight to the dashboard's Logs terminal.
package/README.vi.md CHANGED
@@ -3,7 +3,7 @@
3
3
  # 🦞 OpenClaw Setup
4
4
 
5
5
  <p align="center">
6
- <a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.8.4-0EA5E9?style=for-the-badge" alt="Version 5.8.4" /></a>
6
+ <a href="https://github.com/tuanminhhole/openclaw-setup/releases"><img src="https://img.shields.io/badge/RELEASE-v5.8.5-0EA5E9?style=for-the-badge" alt="Version 5.8.5" /></a>
7
7
  <a href="https://github.com/tuanminhhole/openclaw-setup?tab=MIT-1-ov-file"><img src="https://img.shields.io/badge/LICENSE-MIT-success?style=for-the-badge" alt="MIT License" /></a>
8
8
  <a href="https://www.npmjs.com/package/create-openclaw-bot"><img src="https://img.shields.io/npm/v/create-openclaw-bot?style=for-the-badge&label=CLI&color=2563EB&logo=npm&logoColor=white" alt="NPM Version" /></a>
9
9
  <a href="https://github.com/tuanminhhole/openclaw-setup/stargazers"><img src="https://img.shields.io/github/stars/tuanminhhole/openclaw-setup?style=for-the-badge&color=eab308&logo=github&logoColor=white" alt="GitHub Stars" /></a>
@@ -23,7 +23,7 @@ Trình cài đặt và quản trị **Web UI Setup** thế hệ mới giúp tự
23
23
 
24
24
  ---
25
25
 
26
- ## 🆕 Có gì mới trong v5.8.4
26
+ ## 🆕 Có gì mới trong v5.8.5
27
27
 
28
28
  - 🔄 **Nút cập nhật Header thông minh**: Nâng cấp trực tiếp setup wizard từ giao diện! Nút cập nhật tự truy vấn npm registry và chỉ hiển thị khi có phiên bản mới hơn.
29
29
  - 📡 **Nâng cấp Stream Log trực tiếp**: Khởi chạy cập nhật sẽ tự động nâng cấp (chạy `git pull && npm install && npm run build` cho bản Git, hoặc `npm install -g create-openclaw-bot` cho bản NPM) và đẩy dòng log theo thời gian thực về tab Logs.
@@ -22,6 +22,27 @@ const dataExport = loadSharedModule('../setup/data/index.js', '__openclawData');
22
22
  const __dirname = dirname(fileURLToPath(import.meta.url));
23
23
  const WEB_DIR = resolve(__dirname, '../web');
24
24
  const SETUP_VERSION = (() => { try { return JSON.parse(fs.readFileSync(resolve(__dirname, '../../package.json'), 'utf8')).version || '0.0.0'; } catch { return '0.0.0'; } })();
25
+ let latestSetupVersionCache = SETUP_VERSION;
26
+ let isFetchingLatestSetup = false;
27
+
28
+ async function fetchLatestSetupVersionBg() {
29
+ if (isFetchingLatestSetup) return;
30
+ isFetchingLatestSetup = true;
31
+ try {
32
+ const resp = await fetch('https://registry.npmjs.org/create-openclaw-bot/latest', { signal: AbortSignal.timeout(4000) });
33
+ if (resp.ok) {
34
+ const data = await resp.json();
35
+ if (data.version) {
36
+ latestSetupVersionCache = data.version;
37
+ }
38
+ }
39
+ } catch (e) {
40
+ } finally {
41
+ isFetchingLatestSetup = false;
42
+ }
43
+ }
44
+ fetchLatestSetupVersionBg().catch(() => {});
45
+
25
46
  const DEFAULT_PROJECT_NAME = 'openclaw-bot';
26
47
  const STATE_FILE = '.openclaw-setup-state.json';
27
48
  const DEFAULT_MODEL = 'smart-route';
@@ -1750,6 +1771,29 @@ async function loadSavedState(rootProjectDir) {
1750
1771
  }
1751
1772
  }
1752
1773
 
1774
+ function isRestrictedSystemDir(dirPath) {
1775
+ if (!dirPath) return true;
1776
+ const lower = resolve(dirPath).toLowerCase();
1777
+
1778
+ if (SYSTEM_DIR_BLACKLIST.has(basename(lower))) return true;
1779
+
1780
+ const winDir = process.env.SystemRoot ? resolve(process.env.SystemRoot).toLowerCase() : 'c:\\windows';
1781
+ const programFiles = process.env.ProgramFiles ? resolve(process.env.ProgramFiles).toLowerCase() : 'c:\\program files';
1782
+ const programFilesX86 = process.env['ProgramFiles(x86)'] ? resolve(process.env['ProgramFiles(x86)']).toLowerCase() : 'c:\\program files (x86)';
1783
+
1784
+ if (lower.startsWith(winDir) || lower.startsWith(programFiles) || lower.startsWith(programFilesX86)) {
1785
+ return true;
1786
+ }
1787
+
1788
+ if (lower.includes(':\\users\\') || lower.endsWith(':\\users')) {
1789
+ const home = resolve(os.homedir()).toLowerCase();
1790
+ if (lower !== home && !lower.startsWith(home + '\\') && !lower.startsWith(home + '/')) {
1791
+ return true;
1792
+ }
1793
+ }
1794
+ return false;
1795
+ }
1796
+
1753
1797
  async function findLatestProject(rootProjectDir) {
1754
1798
  const roots = [
1755
1799
  process.env.OPENCLAW_PROJECT_DIR,
@@ -1758,29 +1802,39 @@ async function findLatestProject(rootProjectDir) {
1758
1802
  join(rootProjectDir, DEFAULT_PROJECT_NAME),
1759
1803
  dirname(rootProjectDir),
1760
1804
  os.homedir(),
1761
- ];
1762
- // Scan all available drives, walking top-level dirs but skipping system folders
1805
+ join(os.homedir(), 'Documents'),
1806
+ ].filter(Boolean);
1807
+
1763
1808
  const drives = await getAvailableDrives();
1764
1809
  for (const drive of drives) {
1765
1810
  const entries = await fsp.readdir(drive, { withFileTypes: true }).catch(() => []);
1766
1811
  for (const e of entries) {
1767
1812
  if (e.isDirectory() && !e.name.startsWith('$') && !SYSTEM_DIR_BLACKLIST.has(e.name.toLowerCase())) {
1768
- roots.push(join(drive, e.name));
1813
+ const fullPath = join(drive, e.name);
1814
+ if (!isRestrictedSystemDir(fullPath)) {
1815
+ roots.push(fullPath);
1816
+ }
1769
1817
  }
1770
1818
  }
1771
1819
  }
1772
1820
  const candidates = [];
1821
+ const seen = new Set();
1773
1822
  async function walk(dir, depth = 0) {
1774
1823
  if (!dir || depth > 2 || !existsSync(dir)) return;
1775
- if (existsSync(join(dir, '.openclaw', 'openclaw.json'))) {
1776
- const st = await fsp.stat(join(dir, '.openclaw', 'openclaw.json')).catch(() => null);
1777
- if (st) candidates.push({ dir, mtimeMs: st.mtimeMs });
1824
+ const full = resolve(dir);
1825
+ if (isRestrictedSystemDir(full)) return;
1826
+ if (seen.has(full)) return;
1827
+ seen.add(full);
1828
+
1829
+ if (existsSync(join(full, '.openclaw', 'openclaw.json'))) {
1830
+ const st = await fsp.stat(join(full, '.openclaw', 'openclaw.json')).catch(() => null);
1831
+ if (st) candidates.push({ dir: full, mtimeMs: st.mtimeMs });
1778
1832
  return;
1779
1833
  }
1780
- const entries = await fsp.readdir(dir, { withFileTypes: true }).catch(() => []);
1834
+ const entries = await fsp.readdir(full, { withFileTypes: true }).catch(() => []);
1781
1835
  for (const e of entries) {
1782
1836
  if (e.isDirectory() && !e.name.startsWith('.') && e.name !== 'node_modules' && !SYSTEM_DIR_BLACKLIST.has(e.name.toLowerCase())) {
1783
- await walk(join(dir, e.name), depth + 1);
1837
+ await walk(join(full, e.name), depth + 1);
1784
1838
  }
1785
1839
  }
1786
1840
  }
@@ -1795,16 +1849,28 @@ async function discoverProjects(rootProjectDir) {
1795
1849
  rootProjectDir,
1796
1850
  dirname(rootProjectDir),
1797
1851
  process.env.OPENCLAW_HOME ? dirname(process.env.OPENCLAW_HOME) : '',
1798
- ];
1799
- // Add all available drives for scanning
1852
+ os.homedir(),
1853
+ join(os.homedir(), 'Documents'),
1854
+ ].filter(Boolean);
1855
+
1800
1856
  const drives = await getAvailableDrives();
1801
- for (const drive of drives) roots.push(drive);
1857
+ for (const drive of drives) {
1858
+ const entries = await fsp.readdir(drive, { withFileTypes: true }).catch(() => []);
1859
+ for (const e of entries) {
1860
+ if (e.isDirectory() && !e.name.startsWith('$') && !SYSTEM_DIR_BLACKLIST.has(e.name.toLowerCase())) {
1861
+ const fullPath = join(drive, e.name);
1862
+ if (!isRestrictedSystemDir(fullPath)) {
1863
+ roots.push(fullPath);
1864
+ }
1865
+ }
1866
+ }
1867
+ }
1802
1868
  const seen = new Set();
1803
1869
  const hits = [];
1804
1870
  async function walk(dir, depth = 0) {
1805
1871
  if (!dir || depth > 2 || !existsSync(dir)) return;
1806
1872
  const full = resolve(dir);
1807
- if (full === resolve(os.homedir())) return;
1873
+ if (isRestrictedSystemDir(full)) return;
1808
1874
  if (seen.has(full)) return;
1809
1875
  seen.add(full);
1810
1876
  const cfgPath = join(full, '.openclaw', 'openclaw.json');
@@ -1832,7 +1898,7 @@ async function discoverProjects(rootProjectDir) {
1832
1898
  const entries = await fsp.readdir(full, { withFileTypes: true }).catch(() => []);
1833
1899
  for (const e of entries) {
1834
1900
  if (!e.isDirectory()) continue;
1835
- if (e.name === 'node_modules' || e.name.startsWith('.git') || SYSTEM_DIR_BLACKLIST.has(e.name.toLowerCase())) continue;
1901
+ if (e.name === 'node_modules' || e.name.startsWith('.') || SYSTEM_DIR_BLACKLIST.has(e.name.toLowerCase())) continue;
1836
1902
  await walk(join(full, e.name), depth + 1);
1837
1903
  }
1838
1904
  }
@@ -2425,14 +2491,8 @@ async function handler(req, res, rootProjectDir) {
2425
2491
  };
2426
2492
  const projects = await discoverProjects(rootProjectDir).catch(() => []);
2427
2493
 
2428
- let latestSetupVersion = SETUP_VERSION;
2429
- try {
2430
- const resp = await fetch('https://registry.npmjs.org/create-openclaw-bot/latest', { signal: AbortSignal.timeout(3000) });
2431
- if (resp.ok) {
2432
- const data = await resp.json();
2433
- if (data.version) latestSetupVersion = data.version;
2434
- }
2435
- } catch (e) {}
2494
+ fetchLatestSetupVersionBg().catch(() => {});
2495
+ const latestSetupVersion = latestSetupVersionCache;
2436
2496
 
2437
2497
  return json(res, {
2438
2498
  os: osChoice,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-openclaw-bot",
3
- "version": "5.8.4",
3
+ "version": "5.8.5",
4
4
  "description": "Interactive CLI installer for OpenClaw Bot",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {