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/README.md +3 -3
- package/README.vi.md +2 -2
- package/dist/server/local-server.js +237 -107
- package/dist/setup/data/header.js +1 -1
- package/dist/setup/shared/docker-gen.js +7 -0
- package/dist/setup/shared/workspace-gen.js +16 -821
- package/dist/web/app.js +30 -9
- package/package.json +1 -1
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
|
-
|
|
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
|
|
846
|
-
const isInstalled = !
|
|
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 (
|
|
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 =
|
|
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('
|
|
973
|
-
|
|
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 => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])); }
|
|
1214
|
-
function fileBaseName(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() {
|