@aiyiran/myclaw 1.0.254 → 1.0.256

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.
@@ -193,6 +193,19 @@
193
193
  var headerRight = document.createElement('span');
194
194
  headerRight.style.cssText = 'display:flex;align-items:center;gap:10px;';
195
195
 
196
+ // 展示间跳转(发布按钮左边)
197
+ var showcaseLink = document.createElement('a');
198
+ var _scEnv = detectEnvironment();
199
+ var _scClaw = _scEnv.remote ? _scEnv.clawName : (lastKnownClawName || '');
200
+ var _scWs = getWorkspaceId();
201
+ showcaseLink.href = 'https://www.yiranlaoshi.com/showcase?claw=' + _scClaw + '&workspace=' + _scWs;
202
+ showcaseLink.target = '_blank';
203
+ showcaseLink.textContent = '\uD83D\uDC41 \u9879\u76EE\u96C6';
204
+ showcaseLink.style.cssText = 'cursor:pointer;padding:2px 10px;border-radius:3px;font-size:12px;background:rgba(255,255,255,0.08);transition:background 0.15s;color:#cdd6f4;text-decoration:none;';
205
+ showcaseLink.onmouseenter = function () { showcaseLink.style.background = 'rgba(255,255,255,0.18)'; };
206
+ showcaseLink.onmouseleave = function () { showcaseLink.style.background = 'rgba(255,255,255,0.08)'; };
207
+ headerRight.appendChild(showcaseLink);
208
+
196
209
  var publishBtn = document.createElement('span');
197
210
  publishBtn.textContent = '\u53D1\u5E03';
198
211
  publishBtn.style.cssText = 'cursor:pointer;padding:2px 10px;border-radius:3px;font-size:12px;background:rgba(255,255,255,0.08);transition:background 0.15s;';
@@ -418,6 +431,26 @@
418
431
  fname.appendChild(badge);
419
432
  }
420
433
 
434
+ // 复制相对路径按钮
435
+ var copyPathBtn = document.createElement('span');
436
+ copyPathBtn.textContent = '[复制]';
437
+ copyPathBtn.style.cssText = 'color:#6c6caa;font-size:10px;font-weight:bold;flex-shrink:0;cursor:pointer;transition:color 0.15s;';
438
+ copyPathBtn.onmouseenter = function () { copyPathBtn.style.color = '#a78bfa'; };
439
+ copyPathBtn.onmouseleave = function () { copyPathBtn.style.color = '#6c6caa'; };
440
+ copyPathBtn.onclick = function (e) {
441
+ e.stopPropagation();
442
+ var relativePath = getWorkspaceId() + '/' + (asset.path || '');
443
+ navigator.clipboard.writeText(relativePath).then(function () {
444
+ copyPathBtn.textContent = '[已复制]';
445
+ copyPathBtn.style.color = '#10b981';
446
+ setTimeout(function () {
447
+ copyPathBtn.textContent = '[复制]';
448
+ copyPathBtn.style.color = '#6c6caa';
449
+ }, 1500);
450
+ });
451
+ };
452
+ fname.appendChild(copyPathBtn);
453
+
421
454
  fname.appendChild(nameSpan);
422
455
 
423
456
  row.appendChild(time);
@@ -502,7 +535,7 @@
502
535
  }
503
536
 
504
537
  if (isImageAsset(asset)) {
505
- // ── 图片模式:img 弹框,自适应尺寸 ──
538
+ // ── 图片模式:先显示固定大小的容器,img 异步加载渐显 ──
506
539
  var imgBox = document.createElement('div');
507
540
  imgBox.style.cssText = [
508
541
  'display: flex',
@@ -510,26 +543,55 @@
510
543
  'background: #1e1e2e',
511
544
  'border-radius: 8px',
512
545
  'box-shadow: 0 8px 32px rgba(0,0,0,0.6)',
513
- 'max-width: 92vw',
514
- 'max-height: 92vh',
546
+ 'width: min(88vw, 920px)',
515
547
  'overflow: hidden',
516
548
  ].join(';');
517
549
 
518
550
  imgBox.appendChild(makeHeader('\uD83D\uDDBC\uFE0F ' + (asset.name || asset.path)));
519
551
 
552
+ // 固定尺寸的占位区域,立即可见
553
+ var imgArea = document.createElement('div');
554
+ imgArea.style.cssText = [
555
+ 'position: relative',
556
+ 'width: 100%',
557
+ 'height: min(65vh, 600px)',
558
+ 'display: flex',
559
+ 'align-items: center',
560
+ 'justify-content: center',
561
+ 'background: #252536',
562
+ ].join(';');
563
+
564
+ // 加载中提示
565
+ var hint = document.createElement('div');
566
+ hint.textContent = '\u52A0\u8F7D\u4E2D...';
567
+ hint.style.cssText = 'color:#666;font-size:13px;font-family:monospace;position:absolute;';
568
+ imgArea.appendChild(hint);
569
+
570
+ // img 在占位区内加载,opacity 0 → 1
520
571
  var img = document.createElement('img');
521
572
  img.src = previewUrl;
522
573
  img.alt = asset.name || asset.path;
523
574
  img.style.cssText = [
524
- 'display: block',
525
- 'max-width: 92vw',
526
- 'max-height: calc(92vh - 44px)',
575
+ 'max-width: 100%',
576
+ 'max-height: 100%',
527
577
  'width: auto',
528
578
  'height: auto',
529
579
  'object-fit: contain',
580
+ 'opacity: 0',
581
+ 'transition: opacity 0.25s ease',
582
+ 'position: relative',
583
+ 'z-index: 1',
530
584
  ].join(';');
585
+ img.onload = function () {
586
+ img.style.opacity = '1';
587
+ hint.style.display = 'none';
588
+ };
589
+ img.onerror = function () {
590
+ hint.textContent = '\u52A0\u8F7D\u5931\u8D25';
591
+ };
531
592
 
532
- imgBox.appendChild(img);
593
+ imgArea.appendChild(img);
594
+ imgBox.appendChild(imgArea);
533
595
  overlay.appendChild(imgBox);
534
596
  } else {
535
597
  // ── 非图片:iframe 全屏模式 ──
@@ -819,6 +881,16 @@
819
881
  'animation: myclaw-success-pop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1)',
820
882
  ].join(';');
821
883
 
884
+ // 右上角关闭按钮
885
+ var successCloseX = document.createElement('span');
886
+ successCloseX.textContent = '\u2715';
887
+ successCloseX.style.cssText = 'position:absolute;top:12px;right:14px;cursor:pointer;font-size:16px;color:#888;padding:4px 6px;border-radius:3px;transition:background 0.15s;z-index:1;';
888
+ successCloseX.onmouseenter = function () { successCloseX.style.background = 'rgba(255,255,255,0.1)'; successCloseX.style.color = '#cdd6f4'; };
889
+ successCloseX.onmouseleave = function () { successCloseX.style.background = 'none'; successCloseX.style.color = '#888'; };
890
+ successCloseX.onclick = function () { var m = document.querySelector('#myclaw-publish-success'); if (m) m.remove(); };
891
+ box.style.position = 'relative';
892
+ box.appendChild(successCloseX);
893
+
822
894
  // 头部:庆祝动画区
823
895
  var hero = document.createElement('div');
824
896
  hero.style.cssText = [
@@ -957,15 +1029,10 @@
957
1029
  var qrSection = document.createElement('div');
958
1030
  qrSection.style.cssText = 'display:flex;flex-direction:column;align-items:center;gap:6px;padding-top:4px;';
959
1031
 
960
- var qrCanvas = document.createElement('canvas');
961
- qrCanvas.style.cssText = 'width:140px;height:140px;border-radius:6px;';
962
- try {
963
- generateQR(qrCanvas, data.permanent_url, 280);
964
- } catch (e) {
965
- console.warn('[myclaw-artifacts] QR generate error:', e);
966
- qrCanvas.style.display = 'none';
967
- }
968
- qrSection.appendChild(qrCanvas);
1032
+ var qrDiv = document.createElement('div');
1033
+ qrDiv.style.cssText = 'width:140px;height:140px;border-radius:6px;overflow:hidden;background:#fff;display:flex;align-items:center;justify-content:center;';
1034
+ loadAndGenerateQR(qrDiv, data.permanent_url, 140);
1035
+ qrSection.appendChild(qrDiv);
969
1036
 
970
1037
  var qrHint = document.createElement('div');
971
1038
  qrHint.style.cssText = 'font-size:11px;color:#888;font-family:monospace;';
@@ -1006,7 +1073,7 @@
1006
1073
  footer.appendChild(showcaseBtn);
1007
1074
 
1008
1075
  var closeSuccessBtn = document.createElement('button');
1009
- closeSuccessBtn.textContent = '\u5F00\u5FC3\uFF01';
1076
+ closeSuccessBtn.textContent = '\u6211\u8981\u518D\u6539\u6539\uFF01';
1010
1077
  closeSuccessBtn.style.cssText = [
1011
1078
  'padding: 10px 40px',
1012
1079
  'background: #4a4a7a',
@@ -1045,8 +1112,38 @@
1045
1112
  return row;
1046
1113
  }
1047
1114
 
1048
- // ═══ 轻量 QR 码生成(纯 JS,无依赖) ═══
1049
- // 基于 qrcode-generator (MIT) 的核心算法精简版
1115
+ // ═══ QR 码生成(qrcodejs,按需从 CDN 加载) ═══
1116
+ function loadAndGenerateQR(container, text, size) {
1117
+ function doGenerate() {
1118
+ try {
1119
+ new window.QRCode(container, {
1120
+ text: text,
1121
+ width: size,
1122
+ height: size,
1123
+ colorDark: '#000000',
1124
+ colorLight: '#ffffff',
1125
+ correctLevel: window.QRCode.CorrectLevel.M,
1126
+ });
1127
+ } catch (e) {
1128
+ console.warn('[myclaw-artifacts] QR generate error:', e);
1129
+ container.style.display = 'none';
1130
+ }
1131
+ }
1132
+ if (window.QRCode) {
1133
+ doGenerate();
1134
+ return;
1135
+ }
1136
+ var script = document.createElement('script');
1137
+ script.src = 'https://cdn.bootcdn.net/ajax/libs/qrcodejs/1.0.0/qrcode.min.js';
1138
+ script.onload = function () { doGenerate(); };
1139
+ script.onerror = function () {
1140
+ console.warn('[myclaw-artifacts] Failed to load qrcodejs');
1141
+ container.style.display = 'none';
1142
+ };
1143
+ document.head.appendChild(script);
1144
+ }
1145
+
1146
+ // 以下为废弃的旧版手写 QR 实现(已不使用,保留以备回滚)
1050
1147
  function generateQR(canvas, text, size) {
1051
1148
  // 使用 Google Charts API 的轻量替代:用 img 加载 QR 码
1052
1149
  // 但为了避免外部依赖,这里使用内嵌的极简 QR 生成
package/index.js CHANGED
@@ -334,6 +334,10 @@ function runNew() {
334
334
  console.log(colors.dim + '如果唤醒失败,可手动发送命令:' + NC);
335
335
  console.log(' ' + Y + 'openclaw agent --agent ' + agentId + ' --message "你好"' + NC);
336
336
  console.log('');
337
+
338
+ // 在桌面创建/覆盖浏览器快捷图标
339
+ createDesktopShortcut('http://127.0.0.1:18789?token=' + TOKEN);
340
+
337
341
  process.exit(0);
338
342
  }
339
343
  }
@@ -813,6 +817,50 @@ function runOpen() {
813
817
  console.log('');
814
818
  }
815
819
 
820
+ // ============================================================================
821
+ // 桌面快捷方式(浏览器入口图标)
822
+ // ============================================================================
823
+
824
+ function createDesktopShortcut(url) {
825
+ const fs = require('fs');
826
+ const platform = os.platform();
827
+ const desktopPath = path.join(os.homedir(), 'Desktop');
828
+
829
+ if (!fs.existsSync(desktopPath)) {
830
+ console.log('[shortcut] ⚠ 未找到桌面目录,跳过');
831
+ return;
832
+ }
833
+
834
+ if (platform === 'darwin') {
835
+ // macOS: .webloc 文件,双击用默认浏览器打开
836
+ const webloc = path.join(desktopPath, 'OpenClaw.webloc');
837
+ const content = `<?xml version="1.0" encoding="UTF-8"?>
838
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
839
+ <plist version="1.0">
840
+ <dict>
841
+ <key>URL</key>
842
+ <string>${url}</string>
843
+ </dict>
844
+ </plist>`;
845
+ fs.writeFileSync(webloc, content, 'utf8');
846
+ console.log('[shortcut] ✅ 桌面快捷方式已更新: OpenClaw.webloc');
847
+ } else if (platform === 'linux') {
848
+ // Linux / WSL: .desktop 文件
849
+ const desktop = path.join(desktopPath, 'OpenClaw.desktop');
850
+ const content = `[Desktop Entry]
851
+ Type=Link
852
+ Name=OpenClaw
853
+ URL=${url}
854
+ Icon=text-html
855
+ `;
856
+ fs.writeFileSync(desktop, content, 'utf8');
857
+ try { execSync('chmod +x "' + desktop + '"', { stdio: 'pipe' }); } catch {}
858
+ console.log('[shortcut] ✅ 桌面快捷方式已更新: OpenClaw.desktop');
859
+ } else {
860
+ console.log('[shortcut] ⚠ Windows 请使用 mc bat 创建桌面快捷方式');
861
+ }
862
+ }
863
+
816
864
  // ============================================================================
817
865
  // Patch / Unpatch / Restart
818
866
  // ============================================================================
@@ -1215,7 +1263,9 @@ function showMachineMenu() {
1215
1263
  console.log(colors.green + ' → 已选择: ' + selected.name + ' (' + selected.claw + ')' + colors.nc);
1216
1264
  console.log(' ' + colors.dim + '→ 正在用 Chrome 打开...' + colors.nc);
1217
1265
  const { execSync } = require('child_process');
1218
- execSync('open -a "Google Chrome" "https://' + selected.claw + '.kekouen.cn?token=aiyiran"', { stdio: 'ignore' });
1266
+ const machineUrl = 'https://' + selected.claw + '.kekouen.cn?token=aiyiran';
1267
+ execSync('open -a "Google Chrome" "' + machineUrl + '"', { stdio: 'ignore' });
1268
+ createDesktopShortcut(machineUrl);
1219
1269
  } else {
1220
1270
  console.log('[' + colors.red + '错误' + colors.nc + '] 无效选择');
1221
1271
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiyiran/myclaw",
3
- "version": "1.0.254",
3
+ "version": "1.0.256",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -163,16 +163,14 @@ function patchAgents() {
163
163
 
164
164
  const alreadyExists = fs.existsSync(destWorkspace);
165
165
 
166
- // auto → 已存在则跳过
167
- if (strategy === 'auto' && alreadyExists) {
168
- console.log('[myclaw-agent] ⊘ 已存在: ' + agentId + ' (' + desc + ') [auto, 跳过]');
166
+ // auto → 已存在则跳过文件复制,但仍需检查 sessions
167
+ if (strategy !== 'auto' || !alreadyExists) {
168
+ copyDirSync(srcWorkspace, destWorkspace);
169
+ } else {
170
+ console.log('[myclaw-agent] ⊘ 已存在: ' + agentId + ' (' + desc + ') [auto, 跳过复制]');
169
171
  skipped++;
170
- continue;
171
172
  }
172
173
 
173
- // 执行复制
174
- copyDirSync(srcWorkspace, destWorkspace);
175
-
176
174
  // 确保 agent 目录结构存在
177
175
  if (!fs.existsSync(agentDir)) {
178
176
  fs.mkdirSync(agentDir, { recursive: true });
@@ -212,8 +210,8 @@ function patchAgents() {
212
210
  updated++;
213
211
  console.log('[myclaw-agent] ✅ 已覆盖更新: ' + agentId + ' (' + desc + ') [' + strategy + ']');
214
212
 
215
- // strategy=on 且 sessions 为空 → 补发出生消息(agent 存在但从未激活)
216
- if (strategy === 'on') {
213
+ // sessions 为空 → 补发出生消息(agent 存在但从未激活)
214
+ {
217
215
  const sessionFiles = fs.readdirSync(sessionsDir).filter(f => !f.startsWith('.'));
218
216
  if (sessionFiles.length === 0) {
219
217
  try {