@aiyiran/myclaw 1.1.178 → 1.1.180

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.
@@ -27,8 +27,10 @@
27
27
  var committedText = ""; // 已经提交到 textarea 的文字(上一轮累积)
28
28
  var cursorOffset = 0; // 录音开始时光标在 textarea 中的位置
29
29
  var injected = false;
30
- var stopping = false; // 正在等待最终识别结果(stopVoice 的 2 秒窗口)
30
+ var stopping = false; // 正在等待最终识别结果(stopVoice 的等待窗口)
31
31
  var suppressNextClipboardCopy = false;
32
+ var VOICE_STOP_WAIT_MS = 1000;
33
+ var VOICE_STOP_WAIT_SECONDS = VOICE_STOP_WAIT_MS / 1000;
32
34
 
33
35
  // ═══ 1. 右下角版本入口(打开快捷命令) ═══
34
36
  function createVersionBar() {
@@ -861,7 +863,7 @@ btn.addEventListener("click", function () {
861
863
 
862
864
  voice = new window.VoiceInput({
863
865
  onResult: function (text) {
864
- // 完全停止后才忽略;stopping 期间(2秒等待窗口)仍允许写入
866
+ // 完全停止后才忽略;stopping 期间仍允许写入
865
867
  if (!recording && !stopping) return;
866
868
  // 讯飞实时返回识别文字,替换到光标位置
867
869
  pendingText = text;
@@ -931,7 +933,7 @@ btn.addEventListener("click", function () {
931
933
 
932
934
 
933
935
  /**
934
- * 语音录入结束时,等待 2 秒后关闭录音资源
936
+ * 语音录入结束时,短暂等待后关闭录音资源
935
937
  * @param {Function} [onDone] - 等待完成后执行的回调(如发送)
936
938
  */
937
939
  var voiceStopTimer = null;
@@ -943,13 +945,13 @@ btn.addEventListener("click", function () {
943
945
  return;
944
946
  }
945
947
 
946
- // 进入 stopping 态:UI 立即更新,但 onResult 仍允许在 2 秒内写入文字
948
+ // 进入 stopping 态:UI 立即更新,但 onResult 仍允许在等待窗口内写入文字
947
949
  stopping = true;
948
950
  recording = false;
949
951
  updateButtonUI();
950
- console.log("[myclaw-voice] stopping=true, UI updated, starting 2s timer...");
952
+ console.log("[myclaw-voice] stopping=true, UI updated, starting " + VOICE_STOP_WAIT_SECONDS + "s timer...");
951
953
 
952
- // 延迟 2 秒后关闭录音资源(等讯飞把剩余识别结果全部推过来)
954
+ // 延迟关闭录音资源(等讯飞把剩余识别结果全部推过来)
953
955
  if (voiceStopTimer) {
954
956
  console.log("[myclaw-voice] clearing previous timer");
955
957
  clearTimeout(voiceStopTimer);
@@ -958,9 +960,9 @@ btn.addEventListener("click", function () {
958
960
  voiceStopTimer = null;
959
961
  stopping = false;
960
962
  updateButtonUI();
961
- console.log("[myclaw-voice] 2s timer fired, closing resources...");
963
+ console.log("[myclaw-voice] " + VOICE_STOP_WAIT_SECONDS + "s timer fired, closing resources...");
962
964
 
963
- // 快照当前 textarea 值(2 秒内 onResult 可能已更新)
965
+ // 快照当前 textarea 值(等待窗口内 onResult 可能已更新)
964
966
  var finalText = getTextareaValue();
965
967
  console.log("[myclaw-voice] finalText:", JSON.stringify(finalText.substring(0, 50)));
966
968
  if (voice) {
@@ -977,7 +979,7 @@ btn.addEventListener("click", function () {
977
979
  }
978
980
 
979
981
  console.log("[myclaw-voice] 停止录音完成");
980
- }, 2000);
982
+ }, VOICE_STOP_WAIT_MS);
981
983
  }
982
984
 
983
985
  // ═══ 5. DOM 注入 ═══
@@ -1061,7 +1063,7 @@ btn.addEventListener("click", function () {
1061
1063
  ".myclaw-problem-menu-item:hover, .myclaw-problem-menu-item:focus {",
1062
1064
  " background: #31314a; color: #fff; outline: none;",
1063
1065
  "}",
1064
- /* 按钮处理中态:半透明 + 2秒红圈收缩动画 */
1066
+ /* 按钮处理中态:半透明 + 红圈收缩动画 */
1065
1067
  ".myclaw-voice-stopping {",
1066
1068
  " opacity: 0.5 !important;",
1067
1069
  " position: relative;",
@@ -1076,7 +1078,7 @@ btn.addEventListener("click", function () {
1076
1078
  " border-radius: 50%;",
1077
1079
  " border: 2px solid #ff4444;",
1078
1080
  " transform: translate(-50%, -50%) scale(1.5);",
1079
- " animation: myclaw-countdown 2s linear forwards;",
1081
+ " animation: myclaw-countdown " + VOICE_STOP_WAIT_SECONDS + "s linear forwards;",
1080
1082
  " pointer-events: none;",
1081
1083
  "}",
1082
1084
  "@keyframes myclaw-countdown {",
@@ -1215,7 +1217,7 @@ btn.addEventListener("click", function () {
1215
1217
  }
1216
1218
 
1217
1219
  /**
1218
- * 拦截 Enter 键:语音态下按回车 → 等待 2 秒后发送
1220
+ * 拦截 Enter 键:语音态下按回车 → 等待语音收尾后发送
1219
1221
  */
1220
1222
  function hookVoiceEnter() {
1221
1223
  document.addEventListener("keydown", function (e) {
@@ -1249,7 +1251,7 @@ btn.addEventListener("click", function () {
1249
1251
  var text = getTextareaValue();
1250
1252
  if (!text || !text.trim()) return; // 空文字不处理
1251
1253
 
1252
- // 1) 停止语音输入(等待 2 秒后关闭,关闭后触发发送)
1254
+ // 1) 停止语音输入(等待语音收尾后关闭,关闭后触发发送)
1253
1255
  if (recording) {
1254
1256
  e.preventDefault();
1255
1257
  e.stopPropagation();
@@ -1380,7 +1382,7 @@ btn.addEventListener("click", function () {
1380
1382
  }
1381
1383
 
1382
1384
  // 弹出命令输入小弹框
1383
- function promptAndRun(title, placeholder, hint, cmdTemplate, btnColor, defaultValue, allowAnyName) {
1385
+ function promptAndRun(title, placeholder, hint, cmdTemplate, btnColor, defaultValue, allowAnyName, afterDelay, afterFn) {
1384
1386
  var mask = document.createElement("div");
1385
1387
  mask.style.cssText = [
1386
1388
  "position:fixed",
@@ -1443,7 +1445,7 @@ btn.addEventListener("click", function () {
1443
1445
  input.focus();
1444
1446
  return;
1445
1447
  }
1446
- // allowAnyName=true(如「新伙伴」):允许中文,后端 mc new 会自动生成 ascii id 并把中文存为显示名。
1448
+ // allowAnyName=true(如「新项目」):允许中文,后端 mc new 会自动生成 ascii id 并把中文存为显示名。
1447
1449
  // 否则(如「添加对话」):仍要求 ascii,因为它需要的是真实 agent id。
1448
1450
  if (!allowAnyName && !/^[a-zA-Z0-9\-]+$/.test(val)) {
1449
1451
  input.style.borderColor = "#ff4444";
@@ -1456,6 +1458,9 @@ btn.addEventListener("click", function () {
1456
1458
  var cmd = cmdTemplate.replace("{name}", safeName);
1457
1459
  runCommand(cmd);
1458
1460
  setTimeout(function () { mask.remove(); }, 1000);
1461
+ if (afterDelay) {
1462
+ setTimeout(afterFn || function () { location.reload(); }, afterDelay);
1463
+ }
1459
1464
  }
1460
1465
 
1461
1466
  submitBtn.onclick = doSubmit;
@@ -1471,14 +1476,36 @@ btn.addEventListener("click", function () {
1471
1476
  }
1472
1477
 
1473
1478
  function openNewAgentPrompt() {
1479
+ var apiBase = (function () {
1480
+ var h = window.location.hostname;
1481
+ var isRemote = h === 'claw.yiranlaoshi.com' || h.endsWith('.kekouen.cn');
1482
+ return isRemote ? window.location.origin + '/sync' : 'http://127.0.0.1:18800';
1483
+ })();
1484
+
1485
+ function redirectToNewestAgent() {
1486
+ fetch(apiBase + '/api/agents')
1487
+ .then(function (r) { return r.json(); })
1488
+ .then(function (data) {
1489
+ var agents = (data.agents || []).filter(function (a) { return a && a.id; });
1490
+ if (!agents.length) { location.reload(); return; }
1491
+ var newest = agents.reduce(function (a, b) {
1492
+ return (b.lastUpdated || 0) > (a.lastUpdated || 0) ? b : a;
1493
+ });
1494
+ window.location.href = window.location.origin + '/chat?session=' + encodeURIComponent('agent:' + newest.id + ':main');
1495
+ })
1496
+ .catch(function () { location.reload(); });
1497
+ }
1498
+
1474
1499
  promptAndRun(
1475
- "\u65B0\u5EFA\u4F19\u4F34",
1476
- "\u8F93\u5165\u65B0\u4F19\u4F34\u540D\u79F0\uFF0C\u5982 my-cat",
1477
- "\u7ED9\u4F60\u7684\u65B0 AI \u4F19\u4F34\u8D77\u4E2A\u540D\u5B57\uFF08\u4E2D\u6587 / \u82F1\u6587\u5747\u53EF\uFF09\uFF0C\u70B9\u51FB\u540E\u4F1A\u81EA\u52A8\u521B\u5EFA",
1500
+ "\u65B0\u5EFA\u9879\u76EE",
1501
+ "\u8F93\u5165\u65B0\u9879\u76EE\u540D\u79F0\uFF0C\u5982 my-cat",
1502
+ "\u7ED9\u4F60\u7684\u65B0\u9879\u76EE\u8D77\u4E2A\u540D\u5B57\uFF08\u4E2D\u6587 / \u82F1\u6587\u5747\u53EF\uFF09\uFF0C\u70B9\u51FB\u540E\u4F1A\u81EA\u52A8\u521B\u5EFA",
1478
1503
  "mc new {name}",
1479
1504
  "#3b82f6",
1480
1505
  "",
1481
- true
1506
+ true,
1507
+ 3000,
1508
+ redirectToNewestAgent
1482
1509
  );
1483
1510
  }
1484
1511
 
@@ -1587,7 +1614,7 @@ btn.addEventListener("click", function () {
1587
1614
  btn.style.cssText = [
1588
1615
  "position: fixed",
1589
1616
  "bottom: 8px",
1590
- "right: 335px",
1617
+ "right: 190px",
1591
1618
  "padding: 3px 10px",
1592
1619
  "background: rgba(139, 92, 246, 0.85)",
1593
1620
  "color: #fff",
@@ -1601,7 +1628,7 @@ btn.addEventListener("click", function () {
1601
1628
  "transition: all 0.2s",
1602
1629
  "letter-spacing: 0.5px",
1603
1630
  ].join(";");
1604
- btn.textContent = "🆕 新会话";
1631
+ btn.textContent = "💬 新会话";
1605
1632
  btn.title = "创建新会话(可中文命名)";
1606
1633
 
1607
1634
  btn.onmouseenter = function () { btn.style.background = "rgba(124, 58, 237, 1)"; btn.style.transform = "scale(1.05)"; };
@@ -1622,7 +1649,7 @@ btn.addEventListener("click", function () {
1622
1649
  btn.style.cssText = [
1623
1650
  "position: fixed",
1624
1651
  "bottom: 8px",
1625
- "right: 430px",
1652
+ "right: 285px",
1626
1653
  "padding: 3px 10px",
1627
1654
  "background: rgba(59, 130, 246, 0.85)",
1628
1655
  "color: #fff",
@@ -1636,8 +1663,8 @@ btn.addEventListener("click", function () {
1636
1663
  "transition: all 0.2s",
1637
1664
  "letter-spacing: 0.5px",
1638
1665
  ].join(";");
1639
- btn.textContent = "🤝 新伙伴";
1640
- btn.title = "创建一个新的 AI 伙伴";
1666
+ btn.textContent = "📁 新项目";
1667
+ btn.title = "创建一个新的项目";
1641
1668
 
1642
1669
  btn.onmouseenter = function () { btn.style.background = "rgba(37, 99, 235, 1)"; btn.style.transform = "scale(1.05)"; };
1643
1670
  btn.onmouseleave = function () { btn.style.background = "rgba(59, 130, 246, 0.85)"; btn.style.transform = "scale(1)"; };
@@ -1674,7 +1701,7 @@ btn.addEventListener("click", function () {
1674
1701
 
1675
1702
  var header = document.createElement("div");
1676
1703
  header.style.cssText = "display:flex;align-items:center;justify-content:space-between;padding:10px 14px;background:#2d2d3f;color:#cdd6f4;font-size:13px;font-family:monospace;user-select:none;";
1677
- header.innerHTML = "<span>🆕 新会话</span>";
1704
+ header.innerHTML = "<span>💬 新会话</span>";
1678
1705
  var closeBtn = document.createElement("span");
1679
1706
  closeBtn.textContent = "✕";
1680
1707
  closeBtn.style.cssText = "cursor:pointer;padding:2px 6px;border-radius:3px;font-size:14px;transition:background 0.15s;";
@@ -1801,7 +1828,7 @@ btn.addEventListener("click", function () {
1801
1828
 
1802
1829
  // ── 按钮列表 ──
1803
1830
  var btns = [
1804
- { label: "\uD83E\uDD1D \u65B0\u4F19\u4F34", desc: "\u521B\u5EFA\u4E00\u4E2A\u65B0\u7684 AI \u4F19\u4F34", hasInput: true, inputTitle: "\u65B0\u5EFA\u4F19\u4F34", placeholder: "\u8F93\u5165\u65B0\u4F19\u4F34\u540D\u79F0\uFF0C\u5982 my-cat", hint: "\u7ED9\u4F60\u7684\u65B0 AI \u4F19\u4F34\u8D77\u4E2A\u540D\u5B57\uFF08\u4E2D\u6587 / \u82F1\u6587\u5747\u53EF\uFF09\uFF0C\u70B9\u51FB\u540E\u4F1A\u81EA\u52A8\u521B\u5EFA", cmd: "mc new {name}", color: "#3b82f6", allowAnyName: true },
1831
+ { label: "\uD83D\uDCC1 \u65B0\u9879\u76EE", desc: "\u521B\u5EFA\u4E00\u4E2A\u65B0\u9879\u76EE", hasInput: true, inputTitle: "\u65B0\u5EFA\u9879\u76EE", placeholder: "\u8F93\u5165\u65B0\u9879\u76EE\u540D\u79F0\uFF0C\u5982 my-cat", hint: "\u7ED9\u4F60\u7684\u65B0\u9879\u76EE\u8D77\u4E2A\u540D\u5B57\uFF08\u4E2D\u6587 / \u82F1\u6587\u5747\u53EF\uFF09\uFF0C\u70B9\u51FB\u540E\u4F1A\u81EA\u52A8\u521B\u5EFA", cmd: "mc new {name}", color: "#3b82f6", allowAnyName: true, afterDelay: 3000 },
1805
1832
  { label: "\uD83D\uDCAC \u6DFB\u52A0\u5BF9\u8BDD", desc: "\u6253\u5F00\u5DF2\u6709\u4F19\u4F34\u7684\u5BF9\u8BDD\u7A97\u53E3", hasInput: true, inputTitle: "\u6DFB\u52A0\u5BF9\u8BDD", placeholder: "\u8F93\u5165\u4F19\u4F34\u540D\u79F0\uFF0C\u5982 kakaxi", hint: "\u8F93\u5165\u4F60\u7684\u4F19\u4F34\u7684\u540D\u79F0\uFF08\u82F1\u6587\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u8FDE\u5B57\u7B26\uFF09\uFF0C\u70B9\u51FB\u540E\u4F1A\u6253\u5F00\u5BF9\u8BDD\u7A97\u53E3", cmd: "mc tui {name}", color: "#10b981", getDefault: getCurrentAgentName },
1806
1833
  { label: "\uD83D\uDD04 \u91CD\u542F\u670D\u52A1", desc: "\u91CD\u542F\u6587\u4EF6\u670D\u52A1", hasInput: false, cmd: "mc server", color: "#ef4444" },
1807
1834
  { label: "\uD83E\uDD9E \u91CD\u542F\u9F99\u867E", desc: "\u91CD\u542F OpenClaw \u6838\u5FC3\u670D\u52A1", hasInput: false, cmd: "mc all", color: "#f59e0b" },
@@ -1850,7 +1877,7 @@ btn.addEventListener("click", function () {
1850
1877
 
1851
1878
  row.onclick = function () {
1852
1879
  if (item.hasInput) {
1853
- promptAndRun(item.inputTitle, item.placeholder, item.hint, item.cmd, item.color, item.getDefault ? item.getDefault() : '', item.allowAnyName);
1880
+ promptAndRun(item.inputTitle, item.placeholder, item.hint, item.cmd, item.color, item.getDefault ? item.getDefault() : '', item.allowAnyName, item.afterDelay, item.afterFn);
1854
1881
  } else {
1855
1882
  runCommand(item.cmd);
1856
1883
  }
package/create_agent.js CHANGED
@@ -92,7 +92,7 @@ function pad2(n) { return String(n).padStart(2, '0'); }
92
92
 
93
93
  function generateFallbackKey(existingIds) {
94
94
  const bj = new Date(Date.now() + 8 * 60 * 60 * 1000);
95
- const MD = String(bj.getUTCMonth() + 1) + String(bj.getUTCDate());
95
+ const MD = pad2(bj.getUTCMonth() + 1) + pad2(bj.getUTCDate());
96
96
 
97
97
  const pattern = /^z(\d{3})-/;
98
98
  let minCounter = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiyiran/myclaw",
3
- "version": "1.1.178",
3
+ "version": "1.1.180",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {