@wendongfly/myhi 1.0.118 → 1.0.119
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/dist/chat.html +115 -5
- package/dist/package.json +1 -1
- package/package.json +1 -1
package/dist/chat.html
CHANGED
|
@@ -94,6 +94,25 @@
|
|
|
94
94
|
.btn-allow:hover { background: #2ea043; }
|
|
95
95
|
.btn-deny { background: #21262d; color: #f85149; border: 1px solid #30363d !important; }
|
|
96
96
|
|
|
97
|
+
/* 权限弹窗 modal */
|
|
98
|
+
#perm-modal { display: none; position: fixed; inset: 0; z-index: 90; align-items: flex-end; justify-content: center; }
|
|
99
|
+
#perm-modal.open { display: flex; }
|
|
100
|
+
#perm-modal-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,0.55); }
|
|
101
|
+
#perm-modal-box { position: relative; background: #161b22; border-radius: 16px 16px 0 0; width: 100%; max-width: 480px; padding: 1rem 1rem; padding-bottom: max(1rem, env(safe-area-inset-bottom)); z-index: 1; animation: slideUp 0.25s ease; border-top: 3px solid #d29922; }
|
|
102
|
+
@keyframes slideUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
|
|
103
|
+
#perm-modal-box .pm-icon { text-align: center; font-size: 1.6rem; margin-bottom: 0.4rem; }
|
|
104
|
+
#perm-modal-box .pm-title { text-align: center; font-size: 0.95rem; font-weight: 600; color: #d29922; margin-bottom: 0.6rem; }
|
|
105
|
+
#perm-modal-box .pm-tool { text-align: center; font-size: 0.78rem; color: #8b949e; margin-bottom: 0.3rem; }
|
|
106
|
+
#perm-modal-box .pm-detail { background: #0d1117; border: 1px solid #21262d; border-radius: 8px; padding: 0.6rem 0.75rem; font-family: 'SF Mono', 'Consolas', monospace; font-size: 0.78rem; line-height: 1.4; color: #e6edf3; white-space: pre-wrap; word-break: break-all; max-height: 200px; overflow-y: auto; margin-bottom: 0.75rem; }
|
|
107
|
+
#perm-modal-box .pm-actions { display: flex; gap: 0.5rem; }
|
|
108
|
+
#perm-modal-box .pm-actions button { flex: 1; padding: 0.6rem; border-radius: 10px; font-size: 0.88rem; font-weight: 600; cursor: pointer; border: none; transition: all 0.15s; }
|
|
109
|
+
#perm-modal-box .pm-actions button:active { transform: scale(0.96); }
|
|
110
|
+
#perm-modal-box .pm-btn-allow { background: #238636; color: #fff; }
|
|
111
|
+
#perm-modal-box .pm-btn-allow:hover { background: #2ea043; }
|
|
112
|
+
#perm-modal-box .pm-btn-deny { background: #21262d; color: #f85149; border: 1px solid #30363d; }
|
|
113
|
+
#perm-modal-box .pm-btn-deny:hover { background: #30363d; }
|
|
114
|
+
#perm-modal-box .pm-queue { text-align: center; font-size: 0.7rem; color: #8b949e; margin-top: 0.5rem; }
|
|
115
|
+
|
|
97
116
|
/* Diff 视图 */
|
|
98
117
|
.msg-diff { font-family: 'SF Mono', 'Consolas', monospace; font-size: 0.78rem; background: #161b22; border: 1px solid #30363d; border-radius: 8px; padding: 0.5rem 0.6rem; overflow-x: auto; line-height: 1.35; }
|
|
99
118
|
.diff-add { color: #3fb950; background: rgba(46,160,67,0.1); }
|
|
@@ -230,9 +249,6 @@
|
|
|
230
249
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M15 18l-6-6 6-6"/></svg>
|
|
231
250
|
</button>
|
|
232
251
|
<button class="top-btn" onclick="showUsage()" title="用量" style="font-size:0.7rem;color:var(--muted)">用量</button>
|
|
233
|
-
<button class="top-btn" id="logout-btn" onclick="doLogout()" title="退出" style="display:none;color:#f0883e">
|
|
234
|
-
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>
|
|
235
|
-
</button>
|
|
236
252
|
</div>
|
|
237
253
|
|
|
238
254
|
<div id="status-bar">
|
|
@@ -393,6 +409,22 @@
|
|
|
393
409
|
</div>
|
|
394
410
|
</div>
|
|
395
411
|
|
|
412
|
+
<!-- 权限授权弹窗 -->
|
|
413
|
+
<div id="perm-modal">
|
|
414
|
+
<div id="perm-modal-backdrop"></div>
|
|
415
|
+
<div id="perm-modal-box">
|
|
416
|
+
<div class="pm-icon">🛡️</div>
|
|
417
|
+
<div class="pm-title" id="pm-title">请求权限</div>
|
|
418
|
+
<div class="pm-tool" id="pm-tool"></div>
|
|
419
|
+
<div class="pm-detail" id="pm-detail"></div>
|
|
420
|
+
<div class="pm-actions">
|
|
421
|
+
<button class="pm-btn-deny" id="pm-btn-deny">拒绝</button>
|
|
422
|
+
<button class="pm-btn-allow" id="pm-btn-allow">允许</button>
|
|
423
|
+
</div>
|
|
424
|
+
<div class="pm-queue" id="pm-queue" style="display:none"></div>
|
|
425
|
+
</div>
|
|
426
|
+
</div>
|
|
427
|
+
|
|
396
428
|
<div id="status-overlay">连接中...</div>
|
|
397
429
|
|
|
398
430
|
<script type="module">
|
|
@@ -945,12 +977,83 @@
|
|
|
945
977
|
if (actions) actions.innerHTML = answer === 'y' ? '<span style="color:#3fb950">已允许</span>' : '<span style="color:#f85149">已拒绝</span>';
|
|
946
978
|
};
|
|
947
979
|
|
|
980
|
+
// ── 权限弹窗队列管理 ──────────────────────────────
|
|
981
|
+
const permQueue = []; // { reqId, toolName, detail }
|
|
982
|
+
let permModalOpen = false;
|
|
983
|
+
|
|
984
|
+
function showPermModal(item) {
|
|
985
|
+
const modal = document.getElementById('perm-modal');
|
|
986
|
+
document.getElementById('pm-title').textContent = `${item.toolName} 请求权限`;
|
|
987
|
+
document.getElementById('pm-tool').textContent = item.toolLabel || '';
|
|
988
|
+
document.getElementById('pm-detail').textContent = item.detail;
|
|
989
|
+
const queueEl = document.getElementById('pm-queue');
|
|
990
|
+
if (permQueue.length > 0) {
|
|
991
|
+
queueEl.textContent = `还有 ${permQueue.length} 个权限请求等待处理`;
|
|
992
|
+
queueEl.style.display = '';
|
|
993
|
+
} else {
|
|
994
|
+
queueEl.style.display = 'none';
|
|
995
|
+
}
|
|
996
|
+
// 绑定按钮
|
|
997
|
+
document.getElementById('pm-btn-allow').onclick = () => respondPermModal(item.reqId, true);
|
|
998
|
+
document.getElementById('pm-btn-deny').onclick = () => respondPermModal(item.reqId, false);
|
|
999
|
+
modal.classList.add('open');
|
|
1000
|
+
permModalOpen = true;
|
|
1001
|
+
// 振动提醒(移动端)
|
|
1002
|
+
if (navigator.vibrate) navigator.vibrate(100);
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
function closePermModal() {
|
|
1006
|
+
document.getElementById('perm-modal').classList.remove('open');
|
|
1007
|
+
permModalOpen = false;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
function respondPermModal(requestId, allow) {
|
|
1011
|
+
if (!isController) { addStatusMessage('你没有控制权,无法操作'); return; }
|
|
1012
|
+
socket.emit('agent:permission', { requestId, allow });
|
|
1013
|
+
// 更新内联卡片
|
|
1014
|
+
const inlineActions = document.querySelector(`.perm-actions[data-reqid="${requestId}"]`);
|
|
1015
|
+
if (inlineActions) inlineActions.innerHTML = allow ? '<span style="color:#3fb950">✓ 已允许</span>' : '<span style="color:#f85149">✗ 已拒绝</span>';
|
|
1016
|
+
closePermModal();
|
|
1017
|
+
setWorkState('working');
|
|
1018
|
+
// 处理队列中的下一个
|
|
1019
|
+
if (permQueue.length > 0) {
|
|
1020
|
+
const next = permQueue.shift();
|
|
1021
|
+
setTimeout(() => showPermModal(next), 200);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
function enqueuePermission(reqId, toolName, detail, toolLabel) {
|
|
1026
|
+
const item = { reqId, toolName, detail, toolLabel };
|
|
1027
|
+
if (!permModalOpen) {
|
|
1028
|
+
showPermModal(item);
|
|
1029
|
+
} else {
|
|
1030
|
+
permQueue.push(item);
|
|
1031
|
+
// 更新队列提示
|
|
1032
|
+
const queueEl = document.getElementById('pm-queue');
|
|
1033
|
+
queueEl.textContent = `还有 ${permQueue.length} 个权限请求等待处理`;
|
|
1034
|
+
queueEl.style.display = '';
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
// backdrop 点击不关闭弹窗(防止误触),但可以拒绝
|
|
1039
|
+
document.getElementById('perm-modal-backdrop').addEventListener('click', () => {
|
|
1040
|
+
// 不自动关闭,必须明确选择
|
|
1041
|
+
});
|
|
1042
|
+
|
|
948
1043
|
window.respondAgentPermission = function(requestId, allow, btn) {
|
|
949
1044
|
if (!isController) { addStatusMessage('你没有控制权,无法操作'); return; }
|
|
950
1045
|
socket.emit('agent:permission', { requestId, allow });
|
|
951
1046
|
const actions = btn.closest('.perm-actions');
|
|
952
|
-
if (actions) actions.innerHTML = allow ? '<span style="color:#3fb950"
|
|
1047
|
+
if (actions) actions.innerHTML = allow ? '<span style="color:#3fb950">✓ 已允许</span>' : '<span style="color:#f85149">✗ 已拒绝</span>';
|
|
953
1048
|
setWorkState('working');
|
|
1049
|
+
// 如果弹窗正在显示同一个请求,也关闭它
|
|
1050
|
+
if (permModalOpen) {
|
|
1051
|
+
closePermModal();
|
|
1052
|
+
if (permQueue.length > 0) {
|
|
1053
|
+
const next = permQueue.shift();
|
|
1054
|
+
setTimeout(() => showPermModal(next), 200);
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
954
1057
|
};
|
|
955
1058
|
|
|
956
1059
|
// ── 输出处理 ──────────────────────────────────
|
|
@@ -1176,10 +1279,15 @@
|
|
|
1176
1279
|
const toolName = msg.request.tool_name || '未知工具';
|
|
1177
1280
|
const input = msg.request.input || {};
|
|
1178
1281
|
const detail = toolName === 'Bash' ? (input.command || JSON.stringify(input))
|
|
1179
|
-
: toolName === 'Edit' ? `${input.file_path || ''}`
|
|
1282
|
+
: toolName === 'Edit' ? `${input.file_path || ''}\n${input.old_string ? '替换: ' + input.old_string.slice(0, 120) : ''}`
|
|
1180
1283
|
: toolName === 'Write' ? `${input.file_path || ''}`
|
|
1284
|
+
: toolName === 'Read' ? `${input.file_path || ''}`
|
|
1181
1285
|
: JSON.stringify(input, null, 2);
|
|
1182
1286
|
const reqId = msg.request_id || msg.request?.request_id || msg.uuid;
|
|
1287
|
+
// 工具类型标签
|
|
1288
|
+
const toolLabels = { Bash: '执行命令', Edit: '编辑文件', Write: '写入文件', Read: '读取文件', Glob: '搜索文件', Grep: '搜索内容' };
|
|
1289
|
+
const toolLabel = toolLabels[toolName] || toolName;
|
|
1290
|
+
// 内联卡片
|
|
1183
1291
|
const el = document.createElement('div');
|
|
1184
1292
|
el.className = 'msg msg-permission';
|
|
1185
1293
|
el.innerHTML = `<div class="perm-title">${escHtml(toolName)} 请求权限</div><div class="perm-detail">${escHtml(detail)}</div>
|
|
@@ -1191,6 +1299,8 @@
|
|
|
1191
1299
|
trimMessages();
|
|
1192
1300
|
scrollToBottom();
|
|
1193
1301
|
setWorkState('waiting');
|
|
1302
|
+
// 弹窗授权
|
|
1303
|
+
enqueuePermission(reqId, toolName, detail, toolLabel);
|
|
1194
1304
|
}
|
|
1195
1305
|
break;
|
|
1196
1306
|
case 'result':
|
package/dist/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"type":"module","version":"1.0.
|
|
1
|
+
{"type":"module","version":"1.0.119"}
|
package/package.json
CHANGED