create-openclaw-bot 5.8.16 → 5.8.18

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/web/app.js CHANGED
@@ -268,7 +268,18 @@ async function pickFolderPathShared() {
268
268
  const picked = await api('/api/project/pick-folder', { method: 'POST', body: {} });
269
269
  const projectDir = String(picked.projectDir || '').trim();
270
270
  if (projectDir) return { projectDir };
271
- } catch {}
271
+ } catch (err) {
272
+ return new Promise((resolve) => {
273
+ openPathModal({
274
+ title: t('Nhập đường dẫn project', 'Enter project path'),
275
+ message: t('Vui lòng nhập đường dẫn tuyệt đối đến thư mục project (ví dụ: /Users/mac/my-bot)', 'Please enter the absolute path to your project directory (e.g. /Users/mac/my-bot)'),
276
+ value: state.install?.projectDir || '',
277
+ placeholder: state.os === 'macos' ? '/Users/your-name/my-bot' : '/home/your-name/my-bot',
278
+ onConfirm: (val) => resolve({ projectDir: val }),
279
+ onCancel: () => resolve(null)
280
+ });
281
+ });
282
+ }
272
283
  return null;
273
284
  }
274
285
 
@@ -445,7 +456,8 @@ function wireSkillsHandlers(scope = document) {
445
456
  await api('/api/features/install', { method:'POST', body:{ kind, id, agentId: currentBotId() } });
446
457
  await loadFeatureFlags(true);
447
458
  await loadFiles(true);
448
- showToast(t('Thành công', 'Success'), t('Cài đặt/Cập nhật thành công plugin: ', 'Successfully installed/updated plugin: ') + id, 'success');
459
+ const label = kind === 'skill' ? t('kỹ năng: ', 'skill: ') : t('plugin: ', 'plugin: ');
460
+ showToast(t('Thành công', 'Success'), t('Cài đặt/Cập nhật thành công ', 'Successfully installed/updated ') + label + id, 'success');
449
461
  } catch (err) {
450
462
  showToast(t('Thất bại', 'Failed'), err.message, 'error');
451
463
  } finally {
@@ -842,13 +854,13 @@ function botSkillsPanel() {
842
854
  const row = (item, group) => {
843
855
  const key = `${group}:${item.id}`;
844
856
  const loading = !!state.featureLoading[key];
845
- const isPlugin = group === 'plugin';
846
- const isInstalled = !isPlugin || !!state.featureInstalled?.[key];
857
+ const requiresInstall = group === 'plugin' || (group === 'skill' && (item.id === 'image-gen' || item.id === 'sticker-mention'));
858
+ const isInstalled = !requiresInstall || !!state.featureInstalled?.[key];
847
859
 
848
860
  let actionsHtml = '';
849
861
  if (isInstalled) {
850
862
  actionsHtml = `<div style="display:flex; align-items:center; gap:8px;">`;
851
- if (isPlugin) {
863
+ if (requiresInstall) {
852
864
  actionsHtml += `<button class="secondary icon-btn2 update-plugin-btn" type="button" data-feature-install="${key}" ${loading ? 'disabled' : ''} title="${t('Cập nhật lên bản mới nhất','Update to latest version')}" style="padding: 4px 8px; font-size: 11px; height: 28px; border-width: 1px; color:#ffb020; border-color: rgba(255,176,32,0.25); background: rgba(255,176,32,0.05);">${actionIcon('refresh')}<span>${t('Cập nhật','Update')}</span></button>`;
853
865
  }
854
866
  actionsHtml += `<label class="feature-switch"><input type="checkbox" data-feature-toggle="${key}" ${flags[key] ? 'checked' : ''} ${loading ? 'disabled' : ''}/><span></span></label></div>`;
@@ -856,7 +868,7 @@ function botSkillsPanel() {
856
868
  actionsHtml = `<button class="secondary icon-btn2" type="button" data-feature-install="${key}" ${loading ? 'disabled' : ''}>${actionIcon('download')} ${ui('installVerb')}</button>`;
857
869
  }
858
870
 
859
- const version = isPlugin && isInstalled ? (state.featureVersions?.[key] || '') : '';
871
+ const version = requiresInstall && isInstalled ? (state.featureVersions?.[key] || '') : '';
860
872
  const versionBadge = version ? `<span class="plugin-version-badge" style="display:inline-block; font-size: 11px; background: rgba(66, 133, 244, 0.15); color: #4285F4; padding: 2px 6px; border-radius: 4px; font-weight: 600; margin-left: 8px; border: 1px solid rgba(66,133,244,0.25);">v${escapeHtml(version)}</span>` : '';
861
873
 
862
874
  return `<article class="card feature-card ${loading ? 'is-loading' : ''}"><div class="feature-head"><div><b>${escapeHtml(item.title)}${versionBadge}</b><p>${escapeHtml(item.desc)}</p></div>` +
@@ -940,6 +952,7 @@ function wireTab() {
940
952
  state.activeBotId = '';
941
953
  state.selectedFile = '';
942
954
  state.files = [];
955
+ await loadSystem(true);
943
956
  await loadStatus(true);
944
957
  // Auto-switch to the first channel that has bots in the new project
945
958
  autoSwitchBotChannel();
@@ -969,12 +982,18 @@ function wireTab() {
969
982
  }));
970
983
  document.querySelectorAll('[data-project-pick-folder]').forEach(btn => btn.onclick = () => withButtonLoading(btn, async () => {
971
984
  const result = await pickFolderPathShared();
972
- if (!result) throw new Error(t('Ch?a ch?n th? m?c','No folder selected'));
973
- state.projectConnectMessage = `OK ${t('?? k?t n?i','Connected')}: ${result.projectDir}`;
985
+ if (!result) throw new Error(t('Chưa chọn thư mục','No folder selected'));
986
+ await api('/api/project/connect', { method: 'POST', body: { projectDir: result.projectDir } });
987
+ state.projectConnectMessage = `OK ${t('Đã kết nối','Connected')}: ${result.projectDir}`;
974
988
  showToast(t('Đã kết nối', 'Connected'), t('Kết nối thành công project: ', 'Successfully connected project: ') + fileBaseName(result.projectDir), 'success');
975
989
  state.selectedProjectDir = result.projectDir;
976
990
  state.pendingProjectDir = '';
991
+ state.activeBotId = '';
992
+ state.selectedFile = '';
993
+ state.files = [];
994
+ await loadSystem(true);
977
995
  await loadStatus(true);
996
+ autoSwitchBotChannel();
978
997
  await loadFiles(true);
979
998
  await loadFeatureFlags(true);
980
999
  state.tab = 'bot';
@@ -1151,6 +1170,8 @@ document.querySelectorAll('[data-project-pick-folder]').forEach(btn => btn.oncli
1151
1170
  if (action === 'ok') {
1152
1171
  const value = document.getElementById('path-modal-input')?.value?.trim() || '';
1153
1172
  if (value && typeof modal.onConfirm === 'function') modal.onConfirm(value);
1173
+ } else {
1174
+ if (typeof modal.onCancel === 'function') modal.onCancel();
1154
1175
  }
1155
1176
  state.pathModal = null;
1156
1177
  render();
@@ -1211,7 +1232,7 @@ document.querySelectorAll('[data-project-pick-folder]').forEach(btn => btn.oncli
1211
1232
  }
1212
1233
 
1213
1234
  function escapeHtml(s='') { return String(s).replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c])); }
1214
- function fileBaseName(s='') { return String(s).split(/[\\/]/).pop() || s; }
1235
+ function fileBaseName(s='') { const clean = String(s).replace(/[\\/]+$/, ''); return clean.split(/[\\/]/).pop() || s; }
1215
1236
  async function loadSystem(silent=false){ state.system = await api('/api/system'); if (!silent) render(); }
1216
1237
  async function loadStatus(silent=false){ state.install = await api('/api/bot/status'); if (!state.selectedProjectDir && state.install?.projectDir) state.selectedProjectDir = state.install.projectDir; if (!silent) render(); }
1217
1238
  function autoSwitchBotChannel() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-openclaw-bot",
3
- "version": "5.8.16",
3
+ "version": "5.8.18",
4
4
  "description": "Interactive CLI installer for OpenClaw Bot",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {