@aiyiran/myclaw 1.0.197 → 1.0.199
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 +225 -90
- package/package.json +1 -1
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ============================================================================
|
|
3
|
-
* MyClaw Artifacts —
|
|
3
|
+
* MyClaw Artifacts — 学生作品展示
|
|
4
4
|
* ============================================================================
|
|
5
5
|
*
|
|
6
6
|
* 功能:
|
|
7
|
-
* 右下角 "🎨 作品"
|
|
8
|
-
*
|
|
7
|
+
* 右下角 "🎨 作品" 按钮,点击后右侧常驻显示作品列表面板
|
|
8
|
+
* 列表展示:编号 / 标题 / 文件名 / 更新时间
|
|
9
|
+
* 点击条目弹出 iframe 预览弹框,点击遮罩或叉号关闭
|
|
9
10
|
*
|
|
10
|
-
* JSON
|
|
11
|
+
* JSON 数据格式(.myclaw/__MY_ARTIFACTS__.json):
|
|
11
12
|
* {
|
|
12
13
|
* "workspace_id": "main",
|
|
14
|
+
* "title": "我的小游戏",
|
|
15
|
+
* "updated_at": "2026-04-12T21:35:00+08:00",
|
|
13
16
|
* "assets": [
|
|
14
|
-
* { "
|
|
17
|
+
* { "id": "asset-001", "type": "html", "name": "射击游戏", "path": "myclaw/shooting-game.html" }
|
|
15
18
|
* ]
|
|
16
19
|
* }
|
|
17
20
|
*
|
|
@@ -24,12 +27,12 @@
|
|
|
24
27
|
'use strict';
|
|
25
28
|
|
|
26
29
|
// ═══ 状态 ═══
|
|
27
|
-
var
|
|
30
|
+
var panelVisible = false;
|
|
31
|
+
var cachedData = null;
|
|
28
32
|
|
|
29
33
|
// ═══ 工具:从 URL 解析 agent 名称 ═══
|
|
30
34
|
function getAgentName() {
|
|
31
35
|
var params = new URLSearchParams(window.location.search);
|
|
32
|
-
// 优先从 session 参数解析: agent:main:feishu:... → main
|
|
33
36
|
var session = params.get('session');
|
|
34
37
|
if (session) {
|
|
35
38
|
var decoded = decodeURIComponent(session);
|
|
@@ -38,12 +41,18 @@
|
|
|
38
41
|
if (parts.length >= 2) return parts[1];
|
|
39
42
|
}
|
|
40
43
|
}
|
|
41
|
-
// fallback: agent 参数
|
|
42
44
|
var agent = params.get('agent');
|
|
43
45
|
if (agent) return agent;
|
|
44
46
|
return '';
|
|
45
47
|
}
|
|
46
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
|
+
|
|
47
56
|
// ═══ 创建按钮 ═══
|
|
48
57
|
function createArtifactsButton() {
|
|
49
58
|
if (document.querySelector('#myclaw-artifacts-btn')) return;
|
|
@@ -71,10 +80,10 @@
|
|
|
71
80
|
btn.title = '\u67E5\u770B\u5B66\u751F\u4F5C\u54C1';
|
|
72
81
|
|
|
73
82
|
btn.onmouseenter = function () { btn.style.background = 'rgba(80, 80, 80, 0.95)'; btn.style.transform = 'scale(1.05)'; };
|
|
74
|
-
btn.onmouseleave = function () { if (!
|
|
83
|
+
btn.onmouseleave = function () { if (!panelVisible) { btn.style.background = 'rgba(100, 100, 100, 0.7)'; } btn.style.transform = 'scale(1)'; };
|
|
75
84
|
btn.onclick = function (e) {
|
|
76
85
|
e.stopPropagation();
|
|
77
|
-
if (
|
|
86
|
+
if (panelVisible) {
|
|
78
87
|
closeArtifactsPanel();
|
|
79
88
|
} else {
|
|
80
89
|
openArtifactsPanel();
|
|
@@ -84,43 +93,31 @@
|
|
|
84
93
|
document.body.appendChild(btn);
|
|
85
94
|
}
|
|
86
95
|
|
|
87
|
-
// ═══
|
|
96
|
+
// ═══ 打开右侧列表面板 ═══
|
|
88
97
|
function openArtifactsPanel() {
|
|
89
|
-
if (document.querySelector('#myclaw-artifacts-
|
|
90
|
-
|
|
98
|
+
if (document.querySelector('#myclaw-artifacts-panel')) return;
|
|
99
|
+
panelVisible = true;
|
|
91
100
|
|
|
92
|
-
// 按钮 active 态
|
|
93
101
|
var btn = document.querySelector('#myclaw-artifacts-btn');
|
|
94
102
|
if (btn) btn.style.background = 'rgba(80, 80, 80, 0.95)';
|
|
95
103
|
|
|
96
|
-
//
|
|
97
|
-
var
|
|
98
|
-
|
|
99
|
-
|
|
104
|
+
// 面板
|
|
105
|
+
var panel = document.createElement('div');
|
|
106
|
+
panel.id = 'myclaw-artifacts-panel';
|
|
107
|
+
panel.style.cssText = [
|
|
100
108
|
'position: fixed',
|
|
101
|
-
'top:
|
|
102
|
-
'
|
|
103
|
-
'width:
|
|
104
|
-
'height: 100vh',
|
|
105
|
-
'background: rgba(0, 0, 0, 0.3)',
|
|
106
|
-
'z-index: 99998',
|
|
107
|
-
'display: flex',
|
|
108
|
-
'align-items: center',
|
|
109
|
-
'justify-content: center',
|
|
110
|
-
'animation: myclaw-fade-in 0.15s ease',
|
|
111
|
-
].join(';');
|
|
112
|
-
|
|
113
|
-
// 面板容器
|
|
114
|
-
var box = document.createElement('div');
|
|
115
|
-
box.style.cssText = [
|
|
116
|
-
'width: 480px',
|
|
117
|
-
'max-height: 70vh',
|
|
109
|
+
'top: 400px',
|
|
110
|
+
'right: 0',
|
|
111
|
+
'width: 380px',
|
|
112
|
+
'max-height: calc(100vh - 420px)',
|
|
118
113
|
'background: #1e1e2e',
|
|
119
|
-
'border-radius: 8px',
|
|
114
|
+
'border-radius: 8px 0 0 8px',
|
|
120
115
|
'overflow: hidden',
|
|
121
116
|
'display: flex',
|
|
122
117
|
'flex-direction: column',
|
|
123
|
-
'box-shadow: 0
|
|
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',
|
|
124
121
|
].join(';');
|
|
125
122
|
|
|
126
123
|
// 标题栏
|
|
@@ -129,12 +126,13 @@
|
|
|
129
126
|
'display: flex',
|
|
130
127
|
'align-items: center',
|
|
131
128
|
'justify-content: space-between',
|
|
132
|
-
'padding: 10px
|
|
129
|
+
'padding: 10px 14px',
|
|
133
130
|
'background: #2d2d3f',
|
|
134
131
|
'color: #cdd6f4',
|
|
135
|
-
'font-size:
|
|
132
|
+
'font-size: 13px',
|
|
136
133
|
'font-family: monospace',
|
|
137
134
|
'user-select: none',
|
|
135
|
+
'flex-shrink: 0',
|
|
138
136
|
].join(';');
|
|
139
137
|
header.innerHTML = '<span>\uD83C\uDFA8 \u5B66\u751F\u4F5C\u54C1</span>';
|
|
140
138
|
|
|
@@ -152,39 +150,48 @@
|
|
|
152
150
|
content.style.cssText = [
|
|
153
151
|
'flex: 1',
|
|
154
152
|
'overflow-y: auto',
|
|
155
|
-
'padding:
|
|
153
|
+
'padding: 8px',
|
|
156
154
|
'color: #cdd6f4',
|
|
157
155
|
'font-family: monospace',
|
|
158
|
-
'font-size:
|
|
156
|
+
'font-size: 12px',
|
|
159
157
|
].join(';');
|
|
160
158
|
|
|
161
|
-
// 加载中
|
|
162
159
|
content.innerHTML = '<div style="text-align:center;padding:32px;color:#888;">加载中...</div>';
|
|
163
160
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
161
|
+
panel.appendChild(header);
|
|
162
|
+
panel.appendChild(content);
|
|
163
|
+
document.body.appendChild(panel);
|
|
167
164
|
|
|
168
|
-
//
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
165
|
+
// 请求数据
|
|
166
|
+
if (cachedData) {
|
|
167
|
+
renderArtifactsList(content, cachedData);
|
|
168
|
+
} else {
|
|
169
|
+
fetchArtifacts(content);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
172
|
|
|
173
|
-
|
|
173
|
+
// ═══ 关闭右侧面板 ═══
|
|
174
|
+
function closeArtifactsPanel() {
|
|
175
|
+
var panel = document.querySelector('#myclaw-artifacts-panel');
|
|
176
|
+
if (panel) panel.remove();
|
|
177
|
+
panelVisible = false;
|
|
174
178
|
|
|
175
|
-
|
|
176
|
-
|
|
179
|
+
var btn = document.querySelector('#myclaw-artifacts-btn');
|
|
180
|
+
if (btn) btn.style.background = 'rgba(100, 100, 100, 0.7)';
|
|
177
181
|
}
|
|
178
182
|
|
|
179
183
|
// ═══ 请求数据 ═══
|
|
180
184
|
function fetchArtifacts(contentEl) {
|
|
181
|
-
var
|
|
185
|
+
var agentName = getAgentName();
|
|
186
|
+
var wsPrefix = agentName === 'main' ? 'workspace' : 'workspace-' + agentName;
|
|
187
|
+
var url = window.location.origin + '/cmd/api/preview?path=' + wsPrefix + '/.myclaw/__MY_ARTIFACTS__.json';
|
|
182
188
|
fetch(url)
|
|
183
189
|
.then(function (res) {
|
|
184
190
|
if (!res.ok) throw new Error('HTTP ' + res.status);
|
|
185
191
|
return res.json();
|
|
186
192
|
})
|
|
187
193
|
.then(function (data) {
|
|
194
|
+
cachedData = data;
|
|
188
195
|
if (!data || !data.assets || !data.assets.length) {
|
|
189
196
|
contentEl.innerHTML = '<div style="text-align:center;padding:32px;color:#888;">暂无作品</div>';
|
|
190
197
|
return;
|
|
@@ -200,57 +207,185 @@
|
|
|
200
207
|
// ═══ 渲染列表 ═══
|
|
201
208
|
function renderArtifactsList(container, data) {
|
|
202
209
|
container.innerHTML = '';
|
|
203
|
-
|
|
204
|
-
//
|
|
205
|
-
var
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
210
|
+
|
|
211
|
+
// 表头
|
|
212
|
+
var tableHeader = document.createElement('div');
|
|
213
|
+
tableHeader.style.cssText = [
|
|
214
|
+
'display: flex',
|
|
215
|
+
'padding: 6px 10px',
|
|
216
|
+
'background: #252536',
|
|
217
|
+
'color: #888',
|
|
218
|
+
'font-size: 11px',
|
|
219
|
+
'border-bottom: 1px solid #3d3d5c',
|
|
220
|
+
'flex-shrink: 0',
|
|
221
|
+
].join(';');
|
|
222
|
+
tableHeader.innerHTML = [
|
|
223
|
+
'<span style="width:30px;text-align:center;">#</span>',
|
|
224
|
+
'<span style="flex:2;">标题</span>',
|
|
225
|
+
'<span style="flex:1.5;">文件名</span>',
|
|
226
|
+
'<span style="flex:1;text-align:right;">更新时间</span>',
|
|
227
|
+
].join('');
|
|
228
|
+
container.appendChild(tableHeader);
|
|
229
|
+
|
|
230
|
+
data.assets.forEach(function (asset, idx) {
|
|
231
|
+
var row = document.createElement('div');
|
|
232
|
+
row.style.cssText = [
|
|
233
|
+
'display: flex',
|
|
234
|
+
'align-items: center',
|
|
235
|
+
'padding: 8px 10px',
|
|
236
|
+
'border-bottom: 1px solid rgba(255,255,255,0.05)',
|
|
223
237
|
'cursor: pointer',
|
|
238
|
+
'transition: background 0.15s',
|
|
224
239
|
].join(';');
|
|
225
|
-
|
|
226
|
-
|
|
240
|
+
row.onmouseenter = function () { row.style.background = '#2d2d3f'; };
|
|
241
|
+
row.onmouseleave = function () { row.style.background = 'transparent'; };
|
|
242
|
+
row.onclick = function () { openPreviewModal(data, asset); };
|
|
243
|
+
|
|
244
|
+
// 编号
|
|
245
|
+
var num = document.createElement('span');
|
|
246
|
+
num.style.cssText = 'width:30px;text-align:center;color:#888;flex-shrink:0;';
|
|
247
|
+
num.textContent = String(idx + 1);
|
|
227
248
|
|
|
228
|
-
|
|
229
|
-
title
|
|
230
|
-
title.
|
|
249
|
+
// 标题
|
|
250
|
+
var title = document.createElement('span');
|
|
251
|
+
title.style.cssText = 'flex:2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';
|
|
252
|
+
title.textContent = asset.name || '未命名';
|
|
253
|
+
title.title = asset.name || '';
|
|
231
254
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
255
|
+
// 文件名
|
|
256
|
+
var fname = document.createElement('span');
|
|
257
|
+
fname.style.cssText = 'flex:1.5;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#888;';
|
|
258
|
+
// 从 path 中提取文件名
|
|
259
|
+
var pathParts = (asset.path || '').split('/');
|
|
260
|
+
fname.textContent = pathParts[pathParts.length - 1] || '';
|
|
261
|
+
fname.title = asset.path || '';
|
|
235
262
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
263
|
+
// 更新时间
|
|
264
|
+
var time = document.createElement('span');
|
|
265
|
+
time.style.cssText = 'flex:1;text-align:right;color:#888;font-size:11px;flex-shrink:0;';
|
|
266
|
+
// 优先用 asset 自身的,fallback 到 data 级别的 updated_at
|
|
267
|
+
var updatedAt = asset.updated_at || data.updated_at || '';
|
|
268
|
+
if (updatedAt) {
|
|
269
|
+
try {
|
|
270
|
+
var d = new Date(updatedAt);
|
|
271
|
+
time.textContent = (d.getMonth() + 1) + '/' + d.getDate() + ' ' + String(d.getHours()).padStart(2, '0') + ':' + String(d.getMinutes()).padStart(2, '0');
|
|
272
|
+
} catch (e) {
|
|
273
|
+
time.textContent = '';
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
row.appendChild(num);
|
|
278
|
+
row.appendChild(title);
|
|
279
|
+
row.appendChild(fname);
|
|
280
|
+
row.appendChild(time);
|
|
281
|
+
container.appendChild(row);
|
|
239
282
|
});
|
|
240
283
|
}
|
|
241
284
|
|
|
242
|
-
// ═══
|
|
243
|
-
function
|
|
244
|
-
|
|
285
|
+
// ═══ 预览弹框(iframe) ═══
|
|
286
|
+
function openPreviewModal(data, asset) {
|
|
287
|
+
if (document.querySelector('#myclaw-artifacts-preview')) return;
|
|
288
|
+
|
|
289
|
+
var overlay = document.createElement('div');
|
|
290
|
+
overlay.id = 'myclaw-artifacts-preview';
|
|
291
|
+
overlay.style.cssText = [
|
|
292
|
+
'position: fixed',
|
|
293
|
+
'top: 0',
|
|
294
|
+
'left: 0',
|
|
295
|
+
'width: 100vw',
|
|
296
|
+
'height: 100vh',
|
|
297
|
+
'background: rgba(0, 0, 0, 0.4)',
|
|
298
|
+
'z-index: 99999',
|
|
299
|
+
'display: flex',
|
|
300
|
+
'align-items: center',
|
|
301
|
+
'justify-content: center',
|
|
302
|
+
'animation: myclaw-fade-in 0.15s ease',
|
|
303
|
+
].join(';');
|
|
304
|
+
|
|
305
|
+
var box = document.createElement('div');
|
|
306
|
+
box.style.cssText = [
|
|
307
|
+
'width: 90vw',
|
|
308
|
+
'height: 85vh',
|
|
309
|
+
'background: #1e1e2e',
|
|
310
|
+
'border-radius: 8px',
|
|
311
|
+
'overflow: hidden',
|
|
312
|
+
'display: flex',
|
|
313
|
+
'flex-direction: column',
|
|
314
|
+
'box-shadow: 0 8px 32px rgba(0,0,0,0.5)',
|
|
315
|
+
].join(';');
|
|
316
|
+
|
|
317
|
+
// 标题栏
|
|
318
|
+
var header = document.createElement('div');
|
|
319
|
+
header.style.cssText = [
|
|
320
|
+
'display: flex',
|
|
321
|
+
'align-items: center',
|
|
322
|
+
'justify-content: space-between',
|
|
323
|
+
'padding: 8px 14px',
|
|
324
|
+
'background: #2d2d3f',
|
|
325
|
+
'color: #cdd6f4',
|
|
326
|
+
'font-size: 13px',
|
|
327
|
+
'font-family: monospace',
|
|
328
|
+
'user-select: none',
|
|
329
|
+
'flex-shrink: 0',
|
|
330
|
+
].join(';');
|
|
331
|
+
header.innerHTML = '<span>\uD83C\uDFA8 ' + (asset.name || '预览') + '</span>';
|
|
332
|
+
|
|
333
|
+
var closeBtn = document.createElement('span');
|
|
334
|
+
closeBtn.textContent = '\u2715';
|
|
335
|
+
closeBtn.style.cssText = 'cursor:pointer;padding:2px 6px;border-radius:3px;font-size:14px;transition:background 0.15s;';
|
|
336
|
+
closeBtn.onmouseenter = function () { closeBtn.style.background = 'rgba(255,255,255,0.1)'; };
|
|
337
|
+
closeBtn.onmouseleave = function () { closeBtn.style.background = 'none'; };
|
|
338
|
+
closeBtn.onclick = function () { closePreviewModal(); };
|
|
339
|
+
header.appendChild(closeBtn);
|
|
340
|
+
|
|
341
|
+
// iframe
|
|
342
|
+
var iframe = document.createElement('iframe');
|
|
343
|
+
iframe.src = buildPreviewUrl(data, asset.path);
|
|
344
|
+
iframe.style.cssText = [
|
|
345
|
+
'flex: 1',
|
|
346
|
+
'width: 100%',
|
|
347
|
+
'border: none',
|
|
348
|
+
'background: #fff',
|
|
349
|
+
].join(';');
|
|
350
|
+
|
|
351
|
+
box.appendChild(header);
|
|
352
|
+
box.appendChild(iframe);
|
|
353
|
+
overlay.appendChild(box);
|
|
354
|
+
|
|
355
|
+
// 点击遮罩关闭
|
|
356
|
+
overlay.onclick = function (e) {
|
|
357
|
+
if (e.target === overlay) closePreviewModal();
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
document.body.appendChild(overlay);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
function closePreviewModal() {
|
|
364
|
+
var modal = document.querySelector('#myclaw-artifacts-preview');
|
|
245
365
|
if (modal) modal.remove();
|
|
246
|
-
|
|
366
|
+
}
|
|
247
367
|
|
|
248
|
-
|
|
249
|
-
|
|
368
|
+
// ═══ 注入样式 ═══
|
|
369
|
+
function injectStyles() {
|
|
370
|
+
if (document.querySelector('#myclaw-artifacts-styles')) return;
|
|
371
|
+
var style = document.createElement('style');
|
|
372
|
+
style.id = 'myclaw-artifacts-styles';
|
|
373
|
+
style.textContent = [
|
|
374
|
+
'@keyframes myclaw-slide-in-right {',
|
|
375
|
+
' from { transform: translateX(100%); }',
|
|
376
|
+
' to { transform: translateX(0); }',
|
|
377
|
+
'}',
|
|
378
|
+
'@keyframes myclaw-fade-in {',
|
|
379
|
+
' from { opacity: 0; }',
|
|
380
|
+
' to { opacity: 1; }',
|
|
381
|
+
'}',
|
|
382
|
+
].join('\n');
|
|
383
|
+
document.head.appendChild(style);
|
|
250
384
|
}
|
|
251
385
|
|
|
252
386
|
// ═══ 启动 ═══
|
|
253
387
|
function init() {
|
|
388
|
+
injectStyles();
|
|
254
389
|
createArtifactsButton();
|
|
255
390
|
console.log('[myclaw-artifacts] ✅ 初始化完成');
|
|
256
391
|
}
|