@aiyiran/myclaw 1.0.196 → 1.0.198
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 +396 -0
- package/assets/myclaw-inject.js +0 -221
- package/package.json +1 -1
- package/patch.js +19 -0
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================================
|
|
3
|
+
* MyClaw Artifacts — 学生作品展示
|
|
4
|
+
* ============================================================================
|
|
5
|
+
*
|
|
6
|
+
* 功能:
|
|
7
|
+
* 右下角 "🎨 作品" 按钮,点击后右侧常驻显示作品列表面板
|
|
8
|
+
* 列表展示:编号 / 标题 / 文件名 / 更新时间
|
|
9
|
+
* 点击条目弹出 iframe 预览弹框,点击遮罩或叉号关闭
|
|
10
|
+
*
|
|
11
|
+
* JSON 数据格式(.myclaw/__MY_ARTIFACTS__.json):
|
|
12
|
+
* {
|
|
13
|
+
* "workspace_id": "main",
|
|
14
|
+
* "title": "我的小游戏",
|
|
15
|
+
* "updated_at": "2026-04-12T21:35:00+08:00",
|
|
16
|
+
* "assets": [
|
|
17
|
+
* { "id": "asset-001", "type": "html", "name": "射击游戏", "path": "myclaw/shooting-game.html" }
|
|
18
|
+
* ]
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* URL 拼接规则:
|
|
22
|
+
* {origin}/cmd/api/preview?path={wsPrefix}/{asset.path}
|
|
23
|
+
* main → workspace, 其他 → workspace-{name}
|
|
24
|
+
* ============================================================================
|
|
25
|
+
*/
|
|
26
|
+
(function () {
|
|
27
|
+
'use strict';
|
|
28
|
+
|
|
29
|
+
// ═══ 状态 ═══
|
|
30
|
+
var panelVisible = false;
|
|
31
|
+
var cachedData = null;
|
|
32
|
+
|
|
33
|
+
// ═══ 工具:从 URL 解析 agent 名称 ═══
|
|
34
|
+
function getAgentName() {
|
|
35
|
+
var params = new URLSearchParams(window.location.search);
|
|
36
|
+
var session = params.get('session');
|
|
37
|
+
if (session) {
|
|
38
|
+
var decoded = decodeURIComponent(session);
|
|
39
|
+
if (decoded.indexOf('agent:') === 0) {
|
|
40
|
+
var parts = decoded.split(':');
|
|
41
|
+
if (parts.length >= 2) return parts[1];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
var agent = params.get('agent');
|
|
45
|
+
if (agent) return agent;
|
|
46
|
+
return '';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// ═══ 构建预览 URL ═══
|
|
50
|
+
function buildPreviewUrl(data, assetPath) {
|
|
51
|
+
var wsName = data.workspace_id || '';
|
|
52
|
+
var wsPrefix = wsName === 'main' ? 'workspace' : 'workspace-' + wsName;
|
|
53
|
+
return window.location.origin + '/cmd/api/preview?path=' + wsPrefix + '/' + assetPath;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// ═══ 创建按钮 ═══
|
|
57
|
+
function createArtifactsButton() {
|
|
58
|
+
if (document.querySelector('#myclaw-artifacts-btn')) return;
|
|
59
|
+
|
|
60
|
+
var btn = document.createElement('div');
|
|
61
|
+
btn.id = 'myclaw-artifacts-btn';
|
|
62
|
+
btn.style.cssText = [
|
|
63
|
+
'position: fixed',
|
|
64
|
+
'bottom: 8px',
|
|
65
|
+
'right: 140px',
|
|
66
|
+
'padding: 3px 10px',
|
|
67
|
+
'background: rgba(100, 100, 100, 0.7)',
|
|
68
|
+
'color: #fff',
|
|
69
|
+
'font-size: 11px',
|
|
70
|
+
'font-weight: bold',
|
|
71
|
+
'font-family: monospace',
|
|
72
|
+
'border-radius: 4px',
|
|
73
|
+
'z-index: 99999',
|
|
74
|
+
'user-select: none',
|
|
75
|
+
'cursor: pointer',
|
|
76
|
+
'transition: all 0.2s',
|
|
77
|
+
'letter-spacing: 0.5px',
|
|
78
|
+
].join(';');
|
|
79
|
+
btn.textContent = '\uD83C\uDFA8 \u4F5C\u54C1';
|
|
80
|
+
btn.title = '\u67E5\u770B\u5B66\u751F\u4F5C\u54C1';
|
|
81
|
+
|
|
82
|
+
btn.onmouseenter = function () { btn.style.background = 'rgba(80, 80, 80, 0.95)'; btn.style.transform = 'scale(1.05)'; };
|
|
83
|
+
btn.onmouseleave = function () { if (!panelVisible) { btn.style.background = 'rgba(100, 100, 100, 0.7)'; } btn.style.transform = 'scale(1)'; };
|
|
84
|
+
btn.onclick = function (e) {
|
|
85
|
+
e.stopPropagation();
|
|
86
|
+
if (panelVisible) {
|
|
87
|
+
closeArtifactsPanel();
|
|
88
|
+
} else {
|
|
89
|
+
openArtifactsPanel();
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
document.body.appendChild(btn);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ═══ 打开右侧列表面板 ═══
|
|
97
|
+
function openArtifactsPanel() {
|
|
98
|
+
if (document.querySelector('#myclaw-artifacts-panel')) return;
|
|
99
|
+
panelVisible = true;
|
|
100
|
+
|
|
101
|
+
var btn = document.querySelector('#myclaw-artifacts-btn');
|
|
102
|
+
if (btn) btn.style.background = 'rgba(80, 80, 80, 0.95)';
|
|
103
|
+
|
|
104
|
+
// 面板
|
|
105
|
+
var panel = document.createElement('div');
|
|
106
|
+
panel.id = 'myclaw-artifacts-panel';
|
|
107
|
+
panel.style.cssText = [
|
|
108
|
+
'position: fixed',
|
|
109
|
+
'top: 400px',
|
|
110
|
+
'right: 0',
|
|
111
|
+
'width: 380px',
|
|
112
|
+
'max-height: calc(100vh - 420px)',
|
|
113
|
+
'background: #1e1e2e',
|
|
114
|
+
'border-radius: 8px 0 0 8px',
|
|
115
|
+
'overflow: hidden',
|
|
116
|
+
'display: flex',
|
|
117
|
+
'flex-direction: column',
|
|
118
|
+
'box-shadow: -4px 0 24px rgba(0,0,0,0.3)',
|
|
119
|
+
'z-index: 99997',
|
|
120
|
+
'animation: myclaw-slide-in-right 0.2s ease',
|
|
121
|
+
].join(';');
|
|
122
|
+
|
|
123
|
+
// 标题栏
|
|
124
|
+
var header = document.createElement('div');
|
|
125
|
+
header.style.cssText = [
|
|
126
|
+
'display: flex',
|
|
127
|
+
'align-items: center',
|
|
128
|
+
'justify-content: space-between',
|
|
129
|
+
'padding: 10px 14px',
|
|
130
|
+
'background: #2d2d3f',
|
|
131
|
+
'color: #cdd6f4',
|
|
132
|
+
'font-size: 13px',
|
|
133
|
+
'font-family: monospace',
|
|
134
|
+
'user-select: none',
|
|
135
|
+
'flex-shrink: 0',
|
|
136
|
+
].join(';');
|
|
137
|
+
header.innerHTML = '<span>\uD83C\uDFA8 \u5B66\u751F\u4F5C\u54C1</span>';
|
|
138
|
+
|
|
139
|
+
var closeBtn = document.createElement('span');
|
|
140
|
+
closeBtn.textContent = '\u2715';
|
|
141
|
+
closeBtn.style.cssText = 'cursor:pointer;padding:2px 6px;border-radius:3px;font-size:14px;transition:background 0.15s;';
|
|
142
|
+
closeBtn.onmouseenter = function () { closeBtn.style.background = 'rgba(255,255,255,0.1)'; };
|
|
143
|
+
closeBtn.onmouseleave = function () { closeBtn.style.background = 'none'; };
|
|
144
|
+
closeBtn.onclick = function () { closeArtifactsPanel(); };
|
|
145
|
+
header.appendChild(closeBtn);
|
|
146
|
+
|
|
147
|
+
// 内容区
|
|
148
|
+
var content = document.createElement('div');
|
|
149
|
+
content.id = 'myclaw-artifacts-content';
|
|
150
|
+
content.style.cssText = [
|
|
151
|
+
'flex: 1',
|
|
152
|
+
'overflow-y: auto',
|
|
153
|
+
'padding: 8px',
|
|
154
|
+
'color: #cdd6f4',
|
|
155
|
+
'font-family: monospace',
|
|
156
|
+
'font-size: 12px',
|
|
157
|
+
].join(';');
|
|
158
|
+
|
|
159
|
+
content.innerHTML = '<div style="text-align:center;padding:32px;color:#888;">加载中...</div>';
|
|
160
|
+
|
|
161
|
+
panel.appendChild(header);
|
|
162
|
+
panel.appendChild(content);
|
|
163
|
+
document.body.appendChild(panel);
|
|
164
|
+
|
|
165
|
+
// 请求数据
|
|
166
|
+
if (cachedData) {
|
|
167
|
+
renderArtifactsList(content, cachedData);
|
|
168
|
+
} else {
|
|
169
|
+
fetchArtifacts(content);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ═══ 关闭右侧面板 ═══
|
|
174
|
+
function closeArtifactsPanel() {
|
|
175
|
+
var panel = document.querySelector('#myclaw-artifacts-panel');
|
|
176
|
+
if (panel) panel.remove();
|
|
177
|
+
panelVisible = false;
|
|
178
|
+
|
|
179
|
+
var btn = document.querySelector('#myclaw-artifacts-btn');
|
|
180
|
+
if (btn) btn.style.background = 'rgba(100, 100, 100, 0.7)';
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// ═══ 请求数据 ═══
|
|
184
|
+
function fetchArtifacts(contentEl) {
|
|
185
|
+
var url = window.location.origin + '/cmd/api/preview?path=.myclaw/__MY_ARTIFACTS__.json';
|
|
186
|
+
fetch(url)
|
|
187
|
+
.then(function (res) {
|
|
188
|
+
if (!res.ok) throw new Error('HTTP ' + res.status);
|
|
189
|
+
return res.json();
|
|
190
|
+
})
|
|
191
|
+
.then(function (data) {
|
|
192
|
+
cachedData = data;
|
|
193
|
+
if (!data || !data.assets || !data.assets.length) {
|
|
194
|
+
contentEl.innerHTML = '<div style="text-align:center;padding:32px;color:#888;">暂无作品</div>';
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
renderArtifactsList(contentEl, data);
|
|
198
|
+
})
|
|
199
|
+
.catch(function (err) {
|
|
200
|
+
console.error('[myclaw-artifacts] 加载失败:', err);
|
|
201
|
+
contentEl.innerHTML = '<div style="text-align:center;padding:32px;color:#ff6b6b;">加载失败,请稍后重试</div>';
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// ═══ 渲染列表 ═══
|
|
206
|
+
function renderArtifactsList(container, data) {
|
|
207
|
+
container.innerHTML = '';
|
|
208
|
+
|
|
209
|
+
// 表头
|
|
210
|
+
var tableHeader = document.createElement('div');
|
|
211
|
+
tableHeader.style.cssText = [
|
|
212
|
+
'display: flex',
|
|
213
|
+
'padding: 6px 10px',
|
|
214
|
+
'background: #252536',
|
|
215
|
+
'color: #888',
|
|
216
|
+
'font-size: 11px',
|
|
217
|
+
'border-bottom: 1px solid #3d3d5c',
|
|
218
|
+
'flex-shrink: 0',
|
|
219
|
+
].join(';');
|
|
220
|
+
tableHeader.innerHTML = [
|
|
221
|
+
'<span style="width:30px;text-align:center;">#</span>',
|
|
222
|
+
'<span style="flex:2;">标题</span>',
|
|
223
|
+
'<span style="flex:1.5;">文件名</span>',
|
|
224
|
+
'<span style="flex:1;text-align:right;">更新时间</span>',
|
|
225
|
+
].join('');
|
|
226
|
+
container.appendChild(tableHeader);
|
|
227
|
+
|
|
228
|
+
data.assets.forEach(function (asset, idx) {
|
|
229
|
+
var row = document.createElement('div');
|
|
230
|
+
row.style.cssText = [
|
|
231
|
+
'display: flex',
|
|
232
|
+
'align-items: center',
|
|
233
|
+
'padding: 8px 10px',
|
|
234
|
+
'border-bottom: 1px solid rgba(255,255,255,0.05)',
|
|
235
|
+
'cursor: pointer',
|
|
236
|
+
'transition: background 0.15s',
|
|
237
|
+
].join(';');
|
|
238
|
+
row.onmouseenter = function () { row.style.background = '#2d2d3f'; };
|
|
239
|
+
row.onmouseleave = function () { row.style.background = 'transparent'; };
|
|
240
|
+
row.onclick = function () { openPreviewModal(data, asset); };
|
|
241
|
+
|
|
242
|
+
// 编号
|
|
243
|
+
var num = document.createElement('span');
|
|
244
|
+
num.style.cssText = 'width:30px;text-align:center;color:#888;flex-shrink:0;';
|
|
245
|
+
num.textContent = String(idx + 1);
|
|
246
|
+
|
|
247
|
+
// 标题
|
|
248
|
+
var title = document.createElement('span');
|
|
249
|
+
title.style.cssText = 'flex:2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';
|
|
250
|
+
title.textContent = asset.name || '未命名';
|
|
251
|
+
title.title = asset.name || '';
|
|
252
|
+
|
|
253
|
+
// 文件名
|
|
254
|
+
var fname = document.createElement('span');
|
|
255
|
+
fname.style.cssText = 'flex:1.5;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#888;';
|
|
256
|
+
// 从 path 中提取文件名
|
|
257
|
+
var pathParts = (asset.path || '').split('/');
|
|
258
|
+
fname.textContent = pathParts[pathParts.length - 1] || '';
|
|
259
|
+
fname.title = asset.path || '';
|
|
260
|
+
|
|
261
|
+
// 更新时间
|
|
262
|
+
var time = document.createElement('span');
|
|
263
|
+
time.style.cssText = 'flex:1;text-align:right;color:#888;font-size:11px;flex-shrink:0;';
|
|
264
|
+
// 优先用 asset 自身的,fallback 到 data 级别的 updated_at
|
|
265
|
+
var updatedAt = asset.updated_at || data.updated_at || '';
|
|
266
|
+
if (updatedAt) {
|
|
267
|
+
try {
|
|
268
|
+
var d = new Date(updatedAt);
|
|
269
|
+
time.textContent = (d.getMonth() + 1) + '/' + d.getDate() + ' ' + String(d.getHours()).padStart(2, '0') + ':' + String(d.getMinutes()).padStart(2, '0');
|
|
270
|
+
} catch (e) {
|
|
271
|
+
time.textContent = '';
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
row.appendChild(num);
|
|
276
|
+
row.appendChild(title);
|
|
277
|
+
row.appendChild(fname);
|
|
278
|
+
row.appendChild(time);
|
|
279
|
+
container.appendChild(row);
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// ═══ 预览弹框(iframe) ═══
|
|
284
|
+
function openPreviewModal(data, asset) {
|
|
285
|
+
if (document.querySelector('#myclaw-artifacts-preview')) return;
|
|
286
|
+
|
|
287
|
+
var overlay = document.createElement('div');
|
|
288
|
+
overlay.id = 'myclaw-artifacts-preview';
|
|
289
|
+
overlay.style.cssText = [
|
|
290
|
+
'position: fixed',
|
|
291
|
+
'top: 0',
|
|
292
|
+
'left: 0',
|
|
293
|
+
'width: 100vw',
|
|
294
|
+
'height: 100vh',
|
|
295
|
+
'background: rgba(0, 0, 0, 0.4)',
|
|
296
|
+
'z-index: 99999',
|
|
297
|
+
'display: flex',
|
|
298
|
+
'align-items: center',
|
|
299
|
+
'justify-content: center',
|
|
300
|
+
'animation: myclaw-fade-in 0.15s ease',
|
|
301
|
+
].join(';');
|
|
302
|
+
|
|
303
|
+
var box = document.createElement('div');
|
|
304
|
+
box.style.cssText = [
|
|
305
|
+
'width: 90vw',
|
|
306
|
+
'height: 85vh',
|
|
307
|
+
'background: #1e1e2e',
|
|
308
|
+
'border-radius: 8px',
|
|
309
|
+
'overflow: hidden',
|
|
310
|
+
'display: flex',
|
|
311
|
+
'flex-direction: column',
|
|
312
|
+
'box-shadow: 0 8px 32px rgba(0,0,0,0.5)',
|
|
313
|
+
].join(';');
|
|
314
|
+
|
|
315
|
+
// 标题栏
|
|
316
|
+
var header = document.createElement('div');
|
|
317
|
+
header.style.cssText = [
|
|
318
|
+
'display: flex',
|
|
319
|
+
'align-items: center',
|
|
320
|
+
'justify-content: space-between',
|
|
321
|
+
'padding: 8px 14px',
|
|
322
|
+
'background: #2d2d3f',
|
|
323
|
+
'color: #cdd6f4',
|
|
324
|
+
'font-size: 13px',
|
|
325
|
+
'font-family: monospace',
|
|
326
|
+
'user-select: none',
|
|
327
|
+
'flex-shrink: 0',
|
|
328
|
+
].join(';');
|
|
329
|
+
header.innerHTML = '<span>\uD83C\uDFA8 ' + (asset.name || '预览') + '</span>';
|
|
330
|
+
|
|
331
|
+
var closeBtn = document.createElement('span');
|
|
332
|
+
closeBtn.textContent = '\u2715';
|
|
333
|
+
closeBtn.style.cssText = 'cursor:pointer;padding:2px 6px;border-radius:3px;font-size:14px;transition:background 0.15s;';
|
|
334
|
+
closeBtn.onmouseenter = function () { closeBtn.style.background = 'rgba(255,255,255,0.1)'; };
|
|
335
|
+
closeBtn.onmouseleave = function () { closeBtn.style.background = 'none'; };
|
|
336
|
+
closeBtn.onclick = function () { closePreviewModal(); };
|
|
337
|
+
header.appendChild(closeBtn);
|
|
338
|
+
|
|
339
|
+
// iframe
|
|
340
|
+
var iframe = document.createElement('iframe');
|
|
341
|
+
iframe.src = buildPreviewUrl(data, asset.path);
|
|
342
|
+
iframe.style.cssText = [
|
|
343
|
+
'flex: 1',
|
|
344
|
+
'width: 100%',
|
|
345
|
+
'border: none',
|
|
346
|
+
'background: #fff',
|
|
347
|
+
].join(';');
|
|
348
|
+
|
|
349
|
+
box.appendChild(header);
|
|
350
|
+
box.appendChild(iframe);
|
|
351
|
+
overlay.appendChild(box);
|
|
352
|
+
|
|
353
|
+
// 点击遮罩关闭
|
|
354
|
+
overlay.onclick = function (e) {
|
|
355
|
+
if (e.target === overlay) closePreviewModal();
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
document.body.appendChild(overlay);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function closePreviewModal() {
|
|
362
|
+
var modal = document.querySelector('#myclaw-artifacts-preview');
|
|
363
|
+
if (modal) modal.remove();
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// ═══ 注入样式 ═══
|
|
367
|
+
function injectStyles() {
|
|
368
|
+
if (document.querySelector('#myclaw-artifacts-styles')) return;
|
|
369
|
+
var style = document.createElement('style');
|
|
370
|
+
style.id = 'myclaw-artifacts-styles';
|
|
371
|
+
style.textContent = [
|
|
372
|
+
'@keyframes myclaw-slide-in-right {',
|
|
373
|
+
' from { transform: translateX(100%); }',
|
|
374
|
+
' to { transform: translateX(0); }',
|
|
375
|
+
'}',
|
|
376
|
+
'@keyframes myclaw-fade-in {',
|
|
377
|
+
' from { opacity: 0; }',
|
|
378
|
+
' to { opacity: 1; }',
|
|
379
|
+
'}',
|
|
380
|
+
].join('\n');
|
|
381
|
+
document.head.appendChild(style);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// ═══ 启动 ═══
|
|
385
|
+
function init() {
|
|
386
|
+
injectStyles();
|
|
387
|
+
createArtifactsButton();
|
|
388
|
+
console.log('[myclaw-artifacts] ✅ 初始化完成');
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if (document.readyState === 'loading') {
|
|
392
|
+
document.addEventListener('DOMContentLoaded', init);
|
|
393
|
+
} else {
|
|
394
|
+
init();
|
|
395
|
+
}
|
|
396
|
+
})();
|
package/assets/myclaw-inject.js
CHANGED
|
@@ -96,7 +96,6 @@
|
|
|
96
96
|
|
|
97
97
|
// ═══ 1.2 右下角 CMD 按钮(弹框 iframe) ═══
|
|
98
98
|
var cmdOpen = false;
|
|
99
|
-
var artifactsOpen = false;
|
|
100
99
|
|
|
101
100
|
function createCmdButton() {
|
|
102
101
|
if (document.querySelector("#myclaw-cmd-btn")) return;
|
|
@@ -229,225 +228,6 @@
|
|
|
229
228
|
if (btn) btn.style.background = "rgba(59, 130, 246, 0.85)";
|
|
230
229
|
}
|
|
231
230
|
|
|
232
|
-
// ═══ 1.3 学生作品展示 ═══
|
|
233
|
-
|
|
234
|
-
function getAgentName() {
|
|
235
|
-
var params = new URLSearchParams(window.location.search);
|
|
236
|
-
// 优先从 session 参数解析: agent:main:feishu:... → main
|
|
237
|
-
var session = params.get("session");
|
|
238
|
-
if (session) {
|
|
239
|
-
var decoded = decodeURIComponent(session);
|
|
240
|
-
if (decoded.indexOf("agent:") === 0) {
|
|
241
|
-
var parts = decoded.split(":");
|
|
242
|
-
if (parts.length >= 2) return parts[1];
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
// fallback: agent 参数
|
|
246
|
-
var agent = params.get("agent");
|
|
247
|
-
if (agent) return agent;
|
|
248
|
-
return "";
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
function createArtifactsButton() {
|
|
252
|
-
if (document.querySelector("#myclaw-artifacts-btn")) return;
|
|
253
|
-
|
|
254
|
-
var btn = document.createElement("div");
|
|
255
|
-
btn.id = "myclaw-artifacts-btn";
|
|
256
|
-
btn.style.cssText = [
|
|
257
|
-
"position: fixed",
|
|
258
|
-
"bottom: 8px",
|
|
259
|
-
"right: 140px",
|
|
260
|
-
"padding: 3px 10px",
|
|
261
|
-
"background: rgba(100, 100, 100, 0.7)",
|
|
262
|
-
"color: #fff",
|
|
263
|
-
"font-size: 11px",
|
|
264
|
-
"font-weight: bold",
|
|
265
|
-
"font-family: monospace",
|
|
266
|
-
"border-radius: 4px",
|
|
267
|
-
"z-index: 99999",
|
|
268
|
-
"user-select: none",
|
|
269
|
-
"cursor: pointer",
|
|
270
|
-
"transition: all 0.2s",
|
|
271
|
-
"letter-spacing: 0.5px",
|
|
272
|
-
].join(";");
|
|
273
|
-
btn.textContent = "\uD83C\uDFA8 \u4F5C\u54C1";
|
|
274
|
-
btn.title = "\u67E5\u770B\u5B66\u751F\u4F5C\u54C1";
|
|
275
|
-
|
|
276
|
-
btn.onmouseenter = function () { btn.style.background = "rgba(80, 80, 80, 0.95)"; btn.style.transform = "scale(1.05)"; };
|
|
277
|
-
btn.onmouseleave = function () { if (!artifactsOpen) { btn.style.background = "rgba(100, 100, 100, 0.7)"; } btn.style.transform = "scale(1)"; };
|
|
278
|
-
btn.onclick = function (e) {
|
|
279
|
-
e.stopPropagation();
|
|
280
|
-
if (artifactsOpen) {
|
|
281
|
-
closeArtifactsPanel();
|
|
282
|
-
} else {
|
|
283
|
-
openArtifactsPanel();
|
|
284
|
-
}
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
document.body.appendChild(btn);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
function openArtifactsPanel() {
|
|
291
|
-
if (document.querySelector("#myclaw-artifacts-modal")) return;
|
|
292
|
-
artifactsOpen = true;
|
|
293
|
-
|
|
294
|
-
// 按钮 active 态
|
|
295
|
-
var btn = document.querySelector("#myclaw-artifacts-btn");
|
|
296
|
-
if (btn) btn.style.background = "rgba(80, 80, 80, 0.95)";
|
|
297
|
-
|
|
298
|
-
// 遮罩
|
|
299
|
-
var overlay = document.createElement("div");
|
|
300
|
-
overlay.id = "myclaw-artifacts-modal";
|
|
301
|
-
overlay.style.cssText = [
|
|
302
|
-
"position: fixed",
|
|
303
|
-
"top: 0",
|
|
304
|
-
"left: 0",
|
|
305
|
-
"width: 100vw",
|
|
306
|
-
"height: 100vh",
|
|
307
|
-
"background: rgba(0, 0, 0, 0.3)",
|
|
308
|
-
"z-index: 99998",
|
|
309
|
-
"display: flex",
|
|
310
|
-
"align-items: center",
|
|
311
|
-
"justify-content: center",
|
|
312
|
-
"animation: myclaw-fade-in 0.15s ease",
|
|
313
|
-
].join(";");
|
|
314
|
-
|
|
315
|
-
// 面板容器
|
|
316
|
-
var box = document.createElement("div");
|
|
317
|
-
box.style.cssText = [
|
|
318
|
-
"width: 480px",
|
|
319
|
-
"max-height: 70vh",
|
|
320
|
-
"background: #1e1e2e",
|
|
321
|
-
"border-radius: 8px",
|
|
322
|
-
"overflow: hidden",
|
|
323
|
-
"display: flex",
|
|
324
|
-
"flex-direction: column",
|
|
325
|
-
"box-shadow: 0 8px 32px rgba(0,0,0,0.4)",
|
|
326
|
-
].join(";");
|
|
327
|
-
|
|
328
|
-
// 标题栏
|
|
329
|
-
var header = document.createElement("div");
|
|
330
|
-
header.style.cssText = [
|
|
331
|
-
"display: flex",
|
|
332
|
-
"align-items: center",
|
|
333
|
-
"justify-content: space-between",
|
|
334
|
-
"padding: 10px 16px",
|
|
335
|
-
"background: #2d2d3f",
|
|
336
|
-
"color: #cdd6f4",
|
|
337
|
-
"font-size: 14px",
|
|
338
|
-
"font-family: monospace",
|
|
339
|
-
"user-select: none",
|
|
340
|
-
].join(";");
|
|
341
|
-
header.innerHTML = '<span>\uD83C\uDFA8 \u5B66\u751F\u4F5C\u54C1</span>';
|
|
342
|
-
|
|
343
|
-
var closeBtn = document.createElement("span");
|
|
344
|
-
closeBtn.textContent = "\u2715";
|
|
345
|
-
closeBtn.style.cssText = "cursor:pointer;padding:2px 6px;border-radius:3px;font-size:14px;transition:background 0.15s;";
|
|
346
|
-
closeBtn.onmouseenter = function () { closeBtn.style.background = "rgba(255,255,255,0.1)"; };
|
|
347
|
-
closeBtn.onmouseleave = function () { closeBtn.style.background = "none"; };
|
|
348
|
-
closeBtn.onclick = function () { closeArtifactsPanel(); };
|
|
349
|
-
header.appendChild(closeBtn);
|
|
350
|
-
|
|
351
|
-
// 内容区
|
|
352
|
-
var content = document.createElement("div");
|
|
353
|
-
content.id = "myclaw-artifacts-content";
|
|
354
|
-
content.style.cssText = [
|
|
355
|
-
"flex: 1",
|
|
356
|
-
"overflow-y: auto",
|
|
357
|
-
"padding: 16px",
|
|
358
|
-
"color: #cdd6f4",
|
|
359
|
-
"font-family: monospace",
|
|
360
|
-
"font-size: 13px",
|
|
361
|
-
].join(";");
|
|
362
|
-
|
|
363
|
-
// 加载中
|
|
364
|
-
content.innerHTML = '<div style="text-align:center;padding:32px;color:#888;">加载中...</div>';
|
|
365
|
-
|
|
366
|
-
box.appendChild(header);
|
|
367
|
-
box.appendChild(content);
|
|
368
|
-
overlay.appendChild(box);
|
|
369
|
-
|
|
370
|
-
// 点击遮罩关闭
|
|
371
|
-
overlay.onclick = function (e) {
|
|
372
|
-
if (e.target === overlay) closeArtifactsPanel();
|
|
373
|
-
};
|
|
374
|
-
|
|
375
|
-
document.body.appendChild(overlay);
|
|
376
|
-
|
|
377
|
-
// 异步请求数据
|
|
378
|
-
fetchArtifacts(content);
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
function fetchArtifacts(contentEl) {
|
|
382
|
-
var url = window.location.origin + "/cmd/api/preview?path=.myclaw/__MY_ARTIFACTS__.json";
|
|
383
|
-
fetch(url)
|
|
384
|
-
.then(function (res) {
|
|
385
|
-
if (!res.ok) throw new Error("HTTP " + res.status);
|
|
386
|
-
return res.json();
|
|
387
|
-
})
|
|
388
|
-
.then(function (data) {
|
|
389
|
-
if (!data || !data.assets || !data.assets.length) {
|
|
390
|
-
contentEl.innerHTML = '<div style="text-align:center;padding:32px;color:#888;">暂无作品</div>';
|
|
391
|
-
return;
|
|
392
|
-
}
|
|
393
|
-
renderArtifactsList(contentEl, data);
|
|
394
|
-
})
|
|
395
|
-
.catch(function (err) {
|
|
396
|
-
console.error("[myclaw-artifacts] 加载失败:", err);
|
|
397
|
-
contentEl.innerHTML = '<div style="text-align:center;padding:32px;color:#ff6b6b;">加载失败,请稍后重试</div>';
|
|
398
|
-
});
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
function renderArtifactsList(container, data) {
|
|
402
|
-
container.innerHTML = "";
|
|
403
|
-
// 拼接: base + workspace前缀 + / + 资源路径
|
|
404
|
-
// main → workspace, 其他 → workspace-{name}
|
|
405
|
-
var wsName = data.workspace_id || "";
|
|
406
|
-
var wsPrefix = wsName === "main" ? "workspace" : "workspace-" + wsName;
|
|
407
|
-
var baseUrl = window.location.origin + "/cmd/api/preview?path=" + wsPrefix + "/";
|
|
408
|
-
|
|
409
|
-
data.assets.forEach(function (asset) {
|
|
410
|
-
var card = document.createElement("a");
|
|
411
|
-
card.href = baseUrl + asset.path;
|
|
412
|
-
card.target = "_blank";
|
|
413
|
-
card.rel = "noopener noreferrer";
|
|
414
|
-
card.style.cssText = [
|
|
415
|
-
"display: block",
|
|
416
|
-
"padding: 12px 14px",
|
|
417
|
-
"margin-bottom: 10px",
|
|
418
|
-
"background: #2d2d3f",
|
|
419
|
-
"border-radius: 6px",
|
|
420
|
-
"color: #cdd6f4",
|
|
421
|
-
"text-decoration: none",
|
|
422
|
-
"transition: background 0.15s",
|
|
423
|
-
"cursor: pointer",
|
|
424
|
-
].join(";");
|
|
425
|
-
card.onmouseenter = function () { card.style.background = "#3d3d5c"; };
|
|
426
|
-
card.onmouseleave = function () { card.style.background = "#2d2d3f"; };
|
|
427
|
-
|
|
428
|
-
var title = document.createElement("div");
|
|
429
|
-
title.style.cssText = "font-size: 14px; font-weight: bold; margin-bottom: 4px;";
|
|
430
|
-
title.textContent = asset.name || "未命名作品";
|
|
431
|
-
|
|
432
|
-
var meta = document.createElement("div");
|
|
433
|
-
meta.style.cssText = "font-size: 11px; color: #888;";
|
|
434
|
-
meta.textContent = asset.type ? asset.type.toUpperCase() : "";
|
|
435
|
-
|
|
436
|
-
card.appendChild(title);
|
|
437
|
-
card.appendChild(meta);
|
|
438
|
-
container.appendChild(card);
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
function closeArtifactsPanel() {
|
|
443
|
-
var modal = document.querySelector("#myclaw-artifacts-modal");
|
|
444
|
-
if (modal) modal.remove();
|
|
445
|
-
artifactsOpen = false;
|
|
446
|
-
|
|
447
|
-
var btn = document.querySelector("#myclaw-artifacts-btn");
|
|
448
|
-
if (btn) btn.style.background = "rgba(100, 100, 100, 0.7)";
|
|
449
|
-
}
|
|
450
|
-
|
|
451
231
|
// \u6D4B\u8BD5\u9EA6\u514B\u98CE\u51FD\u6570
|
|
452
232
|
function testMicrophone() {
|
|
453
233
|
console.log("[myclaw] \u5F00\u59CB\u6D4B\u8BD5\u9EA6\u514B\u98CE...");
|
|
@@ -806,7 +586,6 @@
|
|
|
806
586
|
createVersionBar();
|
|
807
587
|
createDocButton();
|
|
808
588
|
createCmdButton();
|
|
809
|
-
createArtifactsButton();
|
|
810
589
|
injectStyles();
|
|
811
590
|
|
|
812
591
|
// 初始化 VoiceInput SDK
|
package/package.json
CHANGED
package/patch.js
CHANGED
|
@@ -26,6 +26,7 @@ const INJECT_FILENAME = 'myclaw-inject.js';
|
|
|
26
26
|
const VOICE_SDK_FILENAME = 'voice-input.js';
|
|
27
27
|
const VOICE_OUTPUT_SDK_FILENAME = 'voice-output.js';
|
|
28
28
|
const TTS_INJECT_FILENAME = 'myclaw-tts.js';
|
|
29
|
+
const ARTIFACTS_INJECT_FILENAME = 'myclaw-artifacts.js';
|
|
29
30
|
const BACKUP_SUFFIX = '.myclaw-backup';
|
|
30
31
|
|
|
31
32
|
/**
|
|
@@ -115,6 +116,8 @@ function patch() {
|
|
|
115
116
|
const voiceOutputSdkDest = path.join(uiDir, VOICE_OUTPUT_SDK_FILENAME);
|
|
116
117
|
const ttsInjectSrc = path.join(__dirname, 'assets', TTS_INJECT_FILENAME);
|
|
117
118
|
const ttsInjectDest = path.join(uiDir, TTS_INJECT_FILENAME);
|
|
119
|
+
const artifactsInjectSrc = path.join(__dirname, 'assets', ARTIFACTS_INJECT_FILENAME);
|
|
120
|
+
const artifactsInjectDest = path.join(uiDir, ARTIFACTS_INJECT_FILENAME);
|
|
118
121
|
const version = getMyclawVersion();
|
|
119
122
|
|
|
120
123
|
console.log('[myclaw-patch] → control-ui: ' + uiDir);
|
|
@@ -166,6 +169,14 @@ function patch() {
|
|
|
166
169
|
console.error('[myclaw-patch] ⚠ TTS 注入脚本复制失败 (非致命): ' + err.message);
|
|
167
170
|
}
|
|
168
171
|
|
|
172
|
+
// 5.5 复制 Artifacts 注入脚本
|
|
173
|
+
try {
|
|
174
|
+
fs.copyFileSync(artifactsInjectSrc, artifactsInjectDest);
|
|
175
|
+
console.log('[myclaw-patch] ✅ Artifacts 注入脚本已复制');
|
|
176
|
+
} catch (err) {
|
|
177
|
+
console.error('[myclaw-patch] ⚠ Artifacts 注入脚本复制失败 (非致命): ' + err.message);
|
|
178
|
+
}
|
|
179
|
+
|
|
169
180
|
// 6. Patch index.html(幂等)
|
|
170
181
|
try {
|
|
171
182
|
let html = fs.readFileSync(indexPath, 'utf8');
|
|
@@ -183,6 +194,7 @@ function patch() {
|
|
|
183
194
|
'<script src="./' + VOICE_OUTPUT_SDK_FILENAME + '"></script>',
|
|
184
195
|
'<script src="./' + VOICE_SDK_FILENAME + '"></script>',
|
|
185
196
|
'<script src="./' + TTS_INJECT_FILENAME + '"></script>',
|
|
197
|
+
'<script src="./' + ARTIFACTS_INJECT_FILENAME + '"></script>',
|
|
186
198
|
'<script src="./' + INJECT_FILENAME + '"></script>',
|
|
187
199
|
'',
|
|
188
200
|
].join('\n');
|
|
@@ -266,6 +278,7 @@ function unpatch() {
|
|
|
266
278
|
const voiceSdkDest = path.join(uiDir, VOICE_SDK_FILENAME);
|
|
267
279
|
const voiceOutputSdkDest = path.join(uiDir, VOICE_OUTPUT_SDK_FILENAME);
|
|
268
280
|
const ttsInjectDest = path.join(uiDir, TTS_INJECT_FILENAME);
|
|
281
|
+
const artifactsInjectDest = path.join(uiDir, ARTIFACTS_INJECT_FILENAME);
|
|
269
282
|
|
|
270
283
|
// 恢复备份
|
|
271
284
|
if (fs.existsSync(backupPath)) {
|
|
@@ -298,6 +311,12 @@ function unpatch() {
|
|
|
298
311
|
console.log('[myclaw-patch] ✅ TTS 注入脚本已删除');
|
|
299
312
|
}
|
|
300
313
|
|
|
314
|
+
// 删除 Artifacts 注入脚本
|
|
315
|
+
if (fs.existsSync(artifactsInjectDest)) {
|
|
316
|
+
fs.unlinkSync(artifactsInjectDest);
|
|
317
|
+
console.log('[myclaw-patch] ✅ Artifacts 注入脚本已删除');
|
|
318
|
+
}
|
|
319
|
+
|
|
301
320
|
// 恢复 gateway-cli-*.js 的 Permissions-Policy
|
|
302
321
|
try {
|
|
303
322
|
const distParent = path.resolve(uiDir, '..');
|