@wendongfly/myhi 1.3.111 → 1.3.112

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.
Files changed (2) hide show
  1. package/dist/grid.html +73 -12
  2. package/package.json +1 -1
package/dist/grid.html CHANGED
@@ -69,7 +69,7 @@
69
69
  <span class="spacer"></span>
70
70
  <button class="bar-btn" onclick="refreshSessions(true)" title="刷新任务列表">↻</button>
71
71
  <button class="bar-btn" onclick="addPane('')" title="加一个空窗格,从下拉选已有任务">+ 窗格</button>
72
- <button class="bar-btn" style="border-color:var(--green);color:var(--green)" onclick="newTask()" title="新建一个任务并放进新窗格">🆕 新建任务</button>
72
+ <button class="bar-btn" style="border-color:var(--green);color:var(--green)" onclick="openNewTask()" title="新建任务(和首页一致:预设/名称/命令/目录)">🆕 新建任务</button>
73
73
  </div>
74
74
  <div id="grid"></div>
75
75
  <div id="empty-hint" style="display:none">点「+ 窗格」或「🆕 新建任务」把多个任务并排看。<br>拉宽窗口自动多几格,或用上方按钮锁定布局。</div>
@@ -92,6 +92,26 @@
92
92
  </div>
93
93
  </div>
94
94
 
95
+ <!-- 新建任务面板(和首页「新建终端会话」一致)-->
96
+ <div id="new-task" style="display:none;position:fixed;inset:0;z-index:100">
97
+ <div style="position:absolute;inset:0;background:rgba(0,0,0,0.5)" onclick="closeNewTask()"></div>
98
+ <div style="position:relative;max-width:460px;width:92%;margin:8vh auto 0;background:var(--surface);border:1px solid var(--border);border-radius:12px;padding:1rem;box-shadow:0 16px 48px rgba(0,0,0,0.45)">
99
+ <div style="font-weight:600;margin-bottom:0.7rem">新建任务</div>
100
+ <div id="nt-presets" style="display:flex;gap:0.4rem;margin-bottom:0.7rem;flex-wrap:wrap"></div>
101
+ <label style="font-size:0.72rem;color:var(--muted)">名称 <span style="color:var(--red)">必填</span></label>
102
+ <input id="nt-title" placeholder="请输入任务名称" autocomplete="off" style="width:100%;box-sizing:border-box;margin:0.2rem 0 0.6rem;background:var(--bg);color:var(--text);border:1px solid var(--border);border-radius:7px;padding:0.45rem 0.6rem;font-size:0.85rem">
103
+ <label style="font-size:0.72rem;color:var(--muted)">启动命令(可选,终端类型用)</label>
104
+ <input id="nt-cmd" placeholder="留空仅打开 shell" autocomplete="off" style="width:100%;box-sizing:border-box;margin:0.2rem 0 0.6rem;background:var(--bg);color:var(--text);border:1px solid var(--border);border-radius:7px;padding:0.45rem 0.6rem;font-size:0.82rem;font-family:monospace">
105
+ <label style="font-size:0.72rem;color:var(--muted)">工作目录(可选)</label>
106
+ <input id="nt-cwd" placeholder="留空使用默认目录" autocomplete="off" style="width:100%;box-sizing:border-box;margin:0.2rem 0 0.4rem;background:var(--bg);color:var(--text);border:1px solid var(--border);border-radius:7px;padding:0.45rem 0.6rem;font-size:0.82rem">
107
+ <div id="nt-recent" style="display:flex;flex-wrap:wrap;gap:0.3rem;margin-bottom:0.7rem"></div>
108
+ <div style="display:flex;gap:0.5rem">
109
+ <button onclick="closeNewTask()" style="flex:1;background:var(--bg);border:1px solid var(--border);color:var(--muted);border-radius:8px;padding:0.5rem;cursor:pointer">取消</button>
110
+ <button onclick="submitNewTask()" style="flex:2;background:var(--green);border:none;color:#fff;border-radius:8px;padding:0.5rem;cursor:pointer;font-weight:600">创建</button>
111
+ </div>
112
+ </div>
113
+ </div>
114
+
95
115
  <script>
96
116
  const LS_KEY = 'myhi_grid_v1';
97
117
  const gridEl = document.getElementById('grid');
@@ -275,19 +295,60 @@
275
295
  }));
276
296
  document.getElementById('tp-search').addEventListener('input', renderPicker);
277
297
 
278
- // ── 新建任务(走 socket create-agent,和首页一致)──
298
+ // ── 新建任务(和首页「新建终端会话」一致:预设 + 名称 + 命令 + 目录 + 最近目录)──
279
299
  const socket = io();
280
- window.newTask = function() {
281
- const title = (prompt('新任务名称:') || '').trim();
282
- if (!title) return;
283
- socket.emit('create-agent', { title }, (res) => {
284
- if (res && res.ok && res.session) {
285
- refreshSessions(true).then(() => addPane(res.session.id));
286
- } else {
287
- alert('创建失败:' + ((res && res.error) || '未知错误'));
288
- }
289
- });
300
+ const NT_PRESETS = [
301
+ { icon:'🤖', label:'Claude', title:'claude', type:'agent', cmd:'' },
302
+ { icon:'✨', label:'Gemini', title:'gemini', type:'pty', cmd:'gemini' },
303
+ { icon:'🐚', label:'Shell', title:'shell', type:'pty', cmd:'' },
304
+ ];
305
+ let _ntPreset = 0;
306
+ const RECENT_DIRS_KEY = 'myhi_recent_dirs'; // 和首页共用
307
+ function ntRecentDirs(){ try { return JSON.parse(localStorage.getItem(RECENT_DIRS_KEY)) || {}; } catch { return {}; } }
308
+ function ntRecordDir(dir){ if(!dir) return; const d=ntRecentDirs(); d[dir]=(d[dir]||0)+1; const s=Object.entries(d).sort((a,b)=>b[1]-a[1]).slice(0,5); localStorage.setItem(RECENT_DIRS_KEY, JSON.stringify(Object.fromEntries(s))); }
309
+ function ntRenderPresets(){
310
+ document.getElementById('nt-presets').innerHTML = NT_PRESETS.map((p,i)=>`<button data-i="${i}" style="flex:1;min-width:5rem;display:flex;align-items:center;justify-content:center;gap:0.3rem;border:1px solid ${i===_ntPreset?'var(--blue2)':'var(--border)'};background:${i===_ntPreset?'var(--blue2)':'var(--bg)'};color:${i===_ntPreset?'#fff':'var(--text2)'};border-radius:8px;padding:0.4rem;font-size:0.8rem;cursor:pointer">${p.icon} ${esc(p.label)}</button>`).join('');
311
+ }
312
+ function ntRenderRecent(){
313
+ const dirs = Object.entries(ntRecentDirs()).sort((a,b)=>b[1]-a[1]);
314
+ document.getElementById('nt-recent').innerHTML = dirs.map(([p])=>`<button data-dir="${esc(p)}" style="background:var(--surface2);border:1px solid var(--border);color:var(--muted);border-radius:6px;font-size:0.68rem;padding:0.12rem 0.4rem;cursor:pointer;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${esc(p)}</button>`).join('');
315
+ }
316
+ window.openNewTask = function(){
317
+ _ntPreset = 0;
318
+ document.getElementById('new-task').style.display = '';
319
+ document.getElementById('nt-title').value = '';
320
+ document.getElementById('nt-cmd').value = '';
321
+ document.getElementById('nt-cwd').value = '';
322
+ ntRenderPresets(); ntRenderRecent();
323
+ setTimeout(()=>document.getElementById('nt-title').focus(), 30);
324
+ };
325
+ window.closeNewTask = function(){ document.getElementById('new-task').style.display='none'; };
326
+ window.submitNewTask = function(){
327
+ const title = document.getElementById('nt-title').value.trim();
328
+ if (!title) { document.getElementById('nt-title').focus(); return; }
329
+ const cmd = document.getElementById('nt-cmd').value.trim() || undefined;
330
+ const cwd = document.getElementById('nt-cwd').value.trim() || undefined;
331
+ if (cwd) ntRecordDir(cwd);
332
+ const preset = NT_PRESETS[_ntPreset];
333
+ const done = (res) => {
334
+ if (res && res.ok && res.session) { closeNewTask(); refreshSessions(true).then(()=>addPane(res.session.id)); }
335
+ else alert('创建失败:' + ((res && res.error) || '未知错误'));
336
+ };
337
+ if (preset.type === 'agent') socket.emit('create-agent', { title, cwd }, done);
338
+ else socket.emit('create', { title, initCmd: cmd, cwd }, done);
290
339
  };
340
+ document.getElementById('nt-presets').addEventListener('click', (e) => {
341
+ const b = e.target.closest('[data-i]'); if (!b) return;
342
+ _ntPreset = +b.dataset.i; const p = NT_PRESETS[_ntPreset];
343
+ const t = document.getElementById('nt-title');
344
+ if (!t.value.trim() || NT_PRESETS.some(x => x.title === t.value.trim())) t.value = p.title;
345
+ document.getElementById('nt-cmd').value = p.cmd || '';
346
+ ntRenderPresets();
347
+ });
348
+ document.getElementById('nt-recent').addEventListener('click', (e) => {
349
+ const b = e.target.closest('[data-dir]'); if (!b) return;
350
+ document.getElementById('nt-cwd').value = b.dataset.dir;
351
+ });
291
352
 
292
353
  // ── 初始化 ──
293
354
  (async function init() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wendongfly/myhi",
3
- "version": "1.3.111",
3
+ "version": "1.3.112",
4
4
  "description": "Web-based terminal sharing with chat UI — control your terminal from phone via LAN/Tailscale",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",