@aiyiran/myclaw 1.0.246 → 1.0.248
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/assets/myclaw-artifacts.js +31 -55
- package/assets/myclaw-inject.js +15 -1
- package/index.js +8 -3
- package/package.json +1 -1
- package/patches/patch-python-deps.js +79 -0
- package/requirements.txt +2 -0
|
@@ -30,8 +30,7 @@
|
|
|
30
30
|
var panelVisible = false;
|
|
31
31
|
var cachedData = null;
|
|
32
32
|
var pollTimer = null;
|
|
33
|
-
var
|
|
34
|
-
var envInfo = null; // { remote: bool, clawName: string|null }
|
|
33
|
+
var lastKnownClawName = null; // 本地环境下从 API 获取,remote 环境每次从 hostname 实时派生
|
|
35
34
|
var MYCLAW_API_PORT = 18800;
|
|
36
35
|
var MYCLAW_API_BASE = 'http://127.0.0.1:' + MYCLAW_API_PORT;
|
|
37
36
|
|
|
@@ -74,56 +73,35 @@
|
|
|
74
73
|
return { remote: false, clawName: null };
|
|
75
74
|
}
|
|
76
75
|
|
|
77
|
-
// ═══
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
// 解析 agentName 和 workspaceName(与环境无关,纯粹从 URL 参数获取)
|
|
84
|
-
var agent = getAgentName() || 'main';
|
|
85
|
-
var workspace = agent === 'main' ? 'workspace' : 'workspace-' + agent;
|
|
86
|
-
|
|
87
|
-
if (envInfo.remote) {
|
|
88
|
-
// 远程:直接拿到 clawName,不需要请求
|
|
89
|
-
cachedConfig = {
|
|
90
|
-
claw: envInfo.clawName,
|
|
91
|
-
base_url: 'https://cdn.yiranlaoshi.com/' + envInfo.clawName,
|
|
92
|
-
agentName: agent,
|
|
93
|
-
workspaceName: workspace,
|
|
94
|
-
};
|
|
95
|
-
console.log('[myclaw-artifacts] ✅ 远程环境:', envInfo.clawName, '| agent:', agent, '| workspace:', workspace);
|
|
96
|
-
return Promise.resolve(cachedConfig);
|
|
76
|
+
// ═══ 获取 clawName(本地环境从 API 实时获取) ═══
|
|
77
|
+
function resolveClawName() {
|
|
78
|
+
var env = detectEnvironment();
|
|
79
|
+
if (env.remote) {
|
|
80
|
+
return Promise.resolve(env.clawName);
|
|
97
81
|
}
|
|
98
|
-
|
|
99
|
-
// 本地:从 API 获取 claw 配置
|
|
100
82
|
return fetch(MYCLAW_API_BASE + '/api/config')
|
|
101
83
|
.then(function (res) {
|
|
102
84
|
if (!res.ok) throw new Error('HTTP ' + res.status);
|
|
103
85
|
return res.json();
|
|
104
86
|
})
|
|
105
87
|
.then(function (data) {
|
|
106
|
-
|
|
107
|
-
data.
|
|
108
|
-
cachedConfig = data;
|
|
109
|
-
console.log('[myclaw-artifacts] ✅ 本地环境 | claw:', data.claw, '| agent:', agent, '| workspace:', workspace);
|
|
110
|
-
return data;
|
|
88
|
+
lastKnownClawName = data.claw;
|
|
89
|
+
return data.claw;
|
|
111
90
|
})
|
|
112
91
|
.catch(function (err) {
|
|
113
|
-
// API 不可用时仍保留 agent/workspace 信息
|
|
114
|
-
cachedConfig = { claw: null, base_url: null, agentName: agent, workspaceName: workspace };
|
|
115
92
|
console.warn('[myclaw-artifacts] ⚠ 本地 API 不可用:', err.message);
|
|
116
|
-
return
|
|
93
|
+
return lastKnownClawName; // 降级用上次成功的值
|
|
117
94
|
});
|
|
118
95
|
}
|
|
119
96
|
|
|
120
97
|
// ═══ 构建预览 URL ═══
|
|
121
|
-
// 统一走 CDN,clawName
|
|
98
|
+
// 统一走 CDN,clawName 实时派生,wsPrefix 实时从当前 URL 计算
|
|
122
99
|
function buildPreviewUrl(data, assetPath) {
|
|
123
|
-
var
|
|
124
|
-
var
|
|
100
|
+
var env = detectEnvironment();
|
|
101
|
+
var clawName = env.remote ? env.clawName : lastKnownClawName;
|
|
102
|
+
var wsPrefix = getWorkspaceId();
|
|
125
103
|
if (!clawName || !wsPrefix) {
|
|
126
|
-
console.error('[myclaw-artifacts] ❌
|
|
104
|
+
console.error('[myclaw-artifacts] ❌ clawName 未就绪,无法构建预览链接');
|
|
127
105
|
return null;
|
|
128
106
|
}
|
|
129
107
|
return 'https://cdn.yiranlaoshi.com/' + clawName + '/' + wsPrefix + '/' + assetPath;
|
|
@@ -266,7 +244,8 @@
|
|
|
266
244
|
|
|
267
245
|
// ═══ 请求数据 ═══
|
|
268
246
|
function getWorkspaceId() {
|
|
269
|
-
|
|
247
|
+
var agent = getAgentName() || 'main';
|
|
248
|
+
return agent === 'main' ? 'workspace' : 'workspace-' + agent;
|
|
270
249
|
}
|
|
271
250
|
|
|
272
251
|
function fetchArtifactsFromLocalAPI(wsPrefix) {
|
|
@@ -277,8 +256,7 @@
|
|
|
277
256
|
});
|
|
278
257
|
}
|
|
279
258
|
|
|
280
|
-
function fetchArtifactsFromCDN(wsPrefix) {
|
|
281
|
-
var clawName = cachedConfig ? cachedConfig.claw : null;
|
|
259
|
+
function fetchArtifactsFromCDN(wsPrefix, clawName) {
|
|
282
260
|
if (!clawName) return Promise.reject(new Error('no claw name'));
|
|
283
261
|
var url = 'https://cdn.yiranlaoshi.com/' + clawName + '/' + wsPrefix + '/.myclaw/__MY_ARTIFACTS__.json?t=' + Date.now();
|
|
284
262
|
return fetch(url).then(function (res) {
|
|
@@ -299,18 +277,18 @@
|
|
|
299
277
|
}
|
|
300
278
|
|
|
301
279
|
function fetchArtifacts(contentEl) {
|
|
302
|
-
|
|
303
|
-
if (!cachedConfig) return;
|
|
304
|
-
|
|
280
|
+
var env = detectEnvironment();
|
|
305
281
|
var wsPrefix = getWorkspaceId();
|
|
306
282
|
var fetcher;
|
|
307
283
|
|
|
308
|
-
if (
|
|
309
|
-
// 远程服务器 → 走 /cmd/api
|
|
284
|
+
if (env.remote) {
|
|
285
|
+
// 远程服务器 → 走 /cmd/api
|
|
310
286
|
fetcher = fetchArtifactsFromServerAPI(wsPrefix);
|
|
311
287
|
} else {
|
|
312
|
-
// 本地环境 → 走 CDN
|
|
313
|
-
fetcher =
|
|
288
|
+
// 本地环境 → 实时拿 clawName → 走 CDN
|
|
289
|
+
fetcher = resolveClawName().then(function (clawName) {
|
|
290
|
+
return fetchArtifactsFromCDN(wsPrefix, clawName);
|
|
291
|
+
});
|
|
314
292
|
}
|
|
315
293
|
|
|
316
294
|
fetcher
|
|
@@ -722,10 +700,10 @@
|
|
|
722
700
|
}
|
|
723
701
|
var payload = {
|
|
724
702
|
title: titleVal,
|
|
725
|
-
workspace:
|
|
703
|
+
workspace: getWorkspaceId(),
|
|
726
704
|
cover_path: coverSelect.value || '',
|
|
727
705
|
entry_path: entrySelect.value || '',
|
|
728
|
-
claw:
|
|
706
|
+
claw: (function () { var e = detectEnvironment(); return e.remote ? e.clawName : (lastKnownClawName || ''); }()),
|
|
729
707
|
};
|
|
730
708
|
submitBtn.disabled = true;
|
|
731
709
|
submitBtn.textContent = '\u53D1\u5E03\u4E2D...';
|
|
@@ -957,8 +935,8 @@
|
|
|
957
935
|
footer.style.cssText = 'padding: 0 24px 20px;text-align:center;display:flex;gap:10px;justify-content:center;';
|
|
958
936
|
|
|
959
937
|
var showcaseBtn = document.createElement('a');
|
|
960
|
-
var cfgAgent =
|
|
961
|
-
var cfgWs =
|
|
938
|
+
var cfgAgent = getAgentName() || 'main';
|
|
939
|
+
var cfgWs = getWorkspaceId();
|
|
962
940
|
showcaseBtn.href = 'https://www.yiranlaoshi.com/showcase?workspace=' + cfgWs;
|
|
963
941
|
showcaseBtn.target = '_blank';
|
|
964
942
|
showcaseBtn.textContent = '\uD83D\uDC41 \u67E5\u770B' + cfgAgent + '\u9879\u76EE\u96C6';
|
|
@@ -1409,11 +1387,9 @@
|
|
|
1409
1387
|
function init() {
|
|
1410
1388
|
injectStyles();
|
|
1411
1389
|
createArtifactsButton();
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
console.log('[myclaw-artifacts] ✅ 初始化完成 (' + (envInfo.remote ? '远程: ' + envInfo.clawName : '本地') + ')');
|
|
1416
|
-
});
|
|
1390
|
+
startPolling();
|
|
1391
|
+
var env = detectEnvironment();
|
|
1392
|
+
console.log('[myclaw-artifacts] ✅ 初始化完成 (' + (env.remote ? '远程: ' + env.clawName : '本地') + ')');
|
|
1417
1393
|
}
|
|
1418
1394
|
|
|
1419
1395
|
if (document.readyState === 'loading') {
|
package/assets/myclaw-inject.js
CHANGED
|
@@ -341,10 +341,18 @@ btn.addEventListener("click", function () {
|
|
|
341
341
|
if (!btn) return;
|
|
342
342
|
|
|
343
343
|
if (recording) {
|
|
344
|
+
btn.classList.remove("myclaw-voice-stopping");
|
|
344
345
|
btn.classList.add("agent-chat__input-btn--recording");
|
|
346
|
+
btn.disabled = false;
|
|
345
347
|
btn.title = "\u505c\u6b62\u8bed\u97f3";
|
|
346
|
-
} else {
|
|
348
|
+
} else if (stopping) {
|
|
347
349
|
btn.classList.remove("agent-chat__input-btn--recording");
|
|
350
|
+
btn.classList.add("myclaw-voice-stopping");
|
|
351
|
+
btn.disabled = true;
|
|
352
|
+
btn.title = "\u5904\u7406\u4e2d\u2026";
|
|
353
|
+
} else {
|
|
354
|
+
btn.classList.remove("agent-chat__input-btn--recording", "myclaw-voice-stopping");
|
|
355
|
+
btn.disabled = false;
|
|
348
356
|
btn.title = "\u8baf\u98de\u8bed\u97f3";
|
|
349
357
|
}
|
|
350
358
|
|
|
@@ -465,6 +473,7 @@ btn.addEventListener("click", function () {
|
|
|
465
473
|
voiceStopTimer = setTimeout(function () {
|
|
466
474
|
voiceStopTimer = null;
|
|
467
475
|
stopping = false;
|
|
476
|
+
updateButtonUI();
|
|
468
477
|
console.log("[myclaw-voice] 2s timer fired, closing resources...");
|
|
469
478
|
|
|
470
479
|
// 快照当前 textarea 值(2 秒内 onResult 可能已更新)
|
|
@@ -529,6 +538,11 @@ btn.addEventListener("click", function () {
|
|
|
529
538
|
" animation: myclaw-ring 1.5s ease-out infinite;",
|
|
530
539
|
" pointer-events: none;",
|
|
531
540
|
"}",
|
|
541
|
+
/* 按钮处理中态:灰色半透明,禁止点击 */
|
|
542
|
+
".myclaw-voice-stopping {",
|
|
543
|
+
" opacity: 0.4 !important;",
|
|
544
|
+
" cursor: not-allowed !important;",
|
|
545
|
+
"}",
|
|
532
546
|
/* textarea 录音态:左侧红色竖线 + 微弱红色背景 */
|
|
533
547
|
".myclaw-voice-active {",
|
|
534
548
|
" border-left: 3px solid #ff4444 !important;",
|
package/index.js
CHANGED
|
@@ -835,12 +835,17 @@ function runPatch() {
|
|
|
835
835
|
console.log('');
|
|
836
836
|
const skillResult = patchSkills();
|
|
837
837
|
|
|
838
|
-
// 3.
|
|
838
|
+
// 3. Python 依赖安装(读取 requirements.txt,pip install 缺失的包)
|
|
839
|
+
console.log('');
|
|
840
|
+
const { patchPythonDeps } = require('./patches/patch-python-deps');
|
|
841
|
+
patchPythonDeps();
|
|
842
|
+
|
|
843
|
+
// 4. 智能体上传(从 agent-list/ 复制到 ~/.openclaw/)
|
|
839
844
|
console.log('');
|
|
840
845
|
const { patchAgents } = require('./patches/patch-agent');
|
|
841
846
|
const agentResult = patchAgents();
|
|
842
847
|
|
|
843
|
-
//
|
|
848
|
+
// 5. Config 补丁(从 manifest 读取,修改 openclaw.json)
|
|
844
849
|
console.log('');
|
|
845
850
|
try {
|
|
846
851
|
const { loadManifest } = require('./patches/patch-agent');
|
|
@@ -888,7 +893,7 @@ function runPatch() {
|
|
|
888
893
|
console.log('[myclaw-config] ⚠ 配置补丁失败: ' + err.message);
|
|
889
894
|
}
|
|
890
895
|
|
|
891
|
-
//
|
|
896
|
+
// 6. 自定义注入脚本执行引擎 (Manifest `run` 数组)
|
|
892
897
|
// 此处读取 manifest.json 中的 "run" 数组,并按顺序 require 执行对应的模块。
|
|
893
898
|
// 通过修改 manifest 即可控制额外脚本(如 inject-image, inject-search)是否跟随 patch 自动执行,
|
|
894
899
|
// 从而避免硬编码具体要注入哪些模块。
|
package/package.json
CHANGED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================================
|
|
3
|
+
* MyClaw Patch Python Deps
|
|
4
|
+
* ============================================================================
|
|
5
|
+
*
|
|
6
|
+
* 功能:
|
|
7
|
+
* 读取 myclaw 根目录下的 requirements.txt,检查并安装所有 Python 依赖。
|
|
8
|
+
* 幂等:已安装的包跳过,只安装缺失的。
|
|
9
|
+
* ============================================================================
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const { execSync } = require('child_process');
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
|
|
16
|
+
function patchPythonDeps() {
|
|
17
|
+
const reqPath = path.join(__dirname, '..', 'requirements.txt');
|
|
18
|
+
|
|
19
|
+
if (!fs.existsSync(reqPath)) {
|
|
20
|
+
console.log('[myclaw-python-deps] ⚠ 未找到 requirements.txt,跳过');
|
|
21
|
+
return { success: true, installed: [] };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const packages = fs.readFileSync(reqPath, 'utf8')
|
|
25
|
+
.split('\n')
|
|
26
|
+
.map(l => l.trim())
|
|
27
|
+
.filter(l => l && !l.startsWith('#'));
|
|
28
|
+
|
|
29
|
+
if (packages.length === 0) {
|
|
30
|
+
console.log('[myclaw-python-deps] ✅ requirements.txt 为空,无需安装');
|
|
31
|
+
return { success: true, installed: [] };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log('[myclaw-python-deps] 检查 Python 依赖...');
|
|
35
|
+
|
|
36
|
+
const missing = [];
|
|
37
|
+
|
|
38
|
+
for (const pkg of packages) {
|
|
39
|
+
// pip 包名转 import 名:把连字符换成下划线(volcengine → volcengine,boto3 → boto3)
|
|
40
|
+
const importName = pkg.split(/[>=<!]/)[0].trim().replace(/-/g, '_');
|
|
41
|
+
try {
|
|
42
|
+
execSync(`python3 -c "import ${importName}"`, { stdio: 'pipe' });
|
|
43
|
+
console.log('[myclaw-python-deps] ✅ 已安装: ' + pkg);
|
|
44
|
+
} catch {
|
|
45
|
+
console.log('[myclaw-python-deps] ⚠ 缺少: ' + pkg);
|
|
46
|
+
missing.push(pkg);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (missing.length === 0) {
|
|
51
|
+
console.log('[myclaw-python-deps] ✅ 所有依赖已就绪');
|
|
52
|
+
return { success: true, installed: [] };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
console.log('[myclaw-python-deps] → 安装缺失依赖: ' + missing.join(', '));
|
|
56
|
+
|
|
57
|
+
const installed = [];
|
|
58
|
+
const failed = [];
|
|
59
|
+
|
|
60
|
+
for (const pkg of missing) {
|
|
61
|
+
try {
|
|
62
|
+
execSync(`pip3 install -q ${pkg}`, { stdio: 'pipe' });
|
|
63
|
+
console.log('[myclaw-python-deps] ✅ 已安装: ' + pkg);
|
|
64
|
+
installed.push(pkg);
|
|
65
|
+
} catch (err) {
|
|
66
|
+
console.log('[myclaw-python-deps] ❌ 安装失败: ' + pkg + ' — ' + err.message);
|
|
67
|
+
failed.push(pkg);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (failed.length > 0) {
|
|
72
|
+
console.log('[myclaw-python-deps] ⚠ 以下依赖安装失败,请手动运行:');
|
|
73
|
+
console.log(' pip3 install ' + failed.join(' '));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return { success: failed.length === 0, installed, failed };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
module.exports = { patchPythonDeps };
|
package/requirements.txt
ADDED