@wendongfly/myhi 1.3.150 → 1.3.152

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 CHANGED
@@ -105,13 +105,13 @@
105
105
  .msg-assistant .content pre { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 0.6rem 0.75rem; overflow-x: auto; margin: 0.5rem 0; font-family: 'SF Mono', 'Consolas', monospace; font-size: 0.8rem; line-height: 1.35; }
106
106
  .msg-assistant .content pre code { background: none; padding: 0; }
107
107
  .msg-assistant .content ul, .msg-assistant .content ol { padding-left: 1.5rem; margin: 0.3rem 0; }
108
- .msg-assistant .content strong { color: #fff; }
108
+ .msg-assistant .content strong { color: var(--text); }
109
109
  .msg-assistant .content a { color: var(--blue); text-decoration: none; word-break: break-all; }
110
110
  .msg-assistant .content a:hover { text-decoration: underline; }
111
111
  .md-table { border-collapse: collapse; margin: 0.5rem 0; font-size: 0.82rem; width: 100%; display: block; overflow-x: auto; white-space: nowrap; }
112
112
  .md-table thead { background: var(--surface); }
113
113
  .md-table th, .md-table td { border: 1px solid var(--border); padding: 0.4rem 0.7rem; text-align: left; }
114
- .md-table th { color: #fff; font-weight: 600; }
114
+ .md-table th { color: var(--text); font-weight: 600; }
115
115
  .md-table tbody tr:nth-child(even) { background: var(--bg); }
116
116
  .md-table tbody tr:hover { background: var(--surface3); }
117
117
 
package/dist/grid.html CHANGED
@@ -313,7 +313,6 @@
313
313
  const socket = io();
314
314
  const NT_PRESETS = [
315
315
  { icon:'🤖', label:'Claude', title:'claude', type:'agent', cmd:'' },
316
- { icon:'✨', label:'Gemini', title:'gemini', type:'pty', cmd:'gemini' },
317
316
  { icon:'🐚', label:'Shell', title:'shell', type:'pty', cmd:'' },
318
317
  ];
319
318
  let _ntPreset = 0;
package/dist/index.html CHANGED
@@ -548,9 +548,10 @@
548
548
  <input id="inp-cmd" type="text" placeholder="留空仅打开 shell" autocomplete="off" spellcheck="false" style="font-family:'SF Mono',Consolas,monospace;font-size:0.85rem">
549
549
  </div>
550
550
  <div class="field">
551
- <label>工作目录 <span style="font-weight:400;text-transform:none">(可选)</span></label>
551
+ <label>工作目录 <span style="font-weight:400;text-transform:none">(可选,默认按任务名建在根目录下)</span></label>
552
552
  <div style="display:flex;gap:0.5rem">
553
- <input id="inp-cwd" type="text" placeholder="留空使用默认目录" autocomplete="off" spellcheck="false" style="flex:1">
553
+ <input id="inp-cwd" type="text" placeholder="输入任务名后自动填充,可改可另选" autocomplete="off" spellcheck="false" style="flex:1">
554
+ <button onclick="pinTaskRoot(this)" title="把当前目录的上级记为默认根目录(新建任务时自动拼 任务名)" style="flex-shrink:0;background:var(--bg);border:1px solid var(--border);border-radius:8px;padding:0 0.75rem;color:var(--text);font-size:0.95rem;cursor:pointer">📌</button>
554
555
  <button onclick="openDirPicker()" style="flex-shrink:0;background:var(--bg);border:1px solid var(--border);border-radius:8px;padding:0 0.75rem;color:var(--text);font-size:1.1rem;cursor:pointer">📁</button>
555
556
  </div>
556
557
  <div id="recent-dirs" style="display:flex;flex-wrap:wrap;gap:0.35rem;margin-top:0.4rem"></div>
@@ -1185,7 +1186,6 @@
1185
1186
  // Agent 模式
1186
1187
  { icon: '🤖', label: 'Claude', title: 'claude', type: 'agent', cmd: 'claude' },
1187
1188
  // PTY 模式(终端)
1188
- { icon: '✨', label: 'Gemini', title: 'gemini', type: 'pty', cmd: 'gemini' },
1189
1189
  { icon: '🐚', label: 'Shell', title: 'shell', type: 'pty', cmd: '' },
1190
1190
  ];
1191
1191
 
@@ -1206,7 +1206,7 @@
1206
1206
  document.querySelectorAll('.chip').forEach((c, j) =>
1207
1207
  c.classList.toggle('selected', j === i));
1208
1208
  const p = PRESETS[i];
1209
- // 不再自动把名称填成 claude/gemini/shell —— 名称必填、留给用户输入任务名
1209
+ // 不再自动把名称填成 claude/shell —— 名称必填、留给用户输入任务名
1210
1210
  document.getElementById('inp-cmd').value = p.cmd || '';
1211
1211
  }
1212
1212
 
@@ -1216,6 +1216,9 @@
1216
1216
  document.getElementById('sheet').classList.add('open');
1217
1217
  // Default to first preset
1218
1218
  selectPreset(0);
1219
+ // 重置目录接管状态:按当前任务名重新算默认目录(title 已被上次创建清空 → 目录清空)
1220
+ _cwdTouched = false;
1221
+ syncCwdToTitle();
1219
1222
  setTimeout(() => document.getElementById('inp-title').focus(), 300);
1220
1223
  }
1221
1224
  function closeSheet() {
@@ -1225,6 +1228,52 @@
1225
1228
  document.querySelectorAll('.chip').forEach(c => c.classList.remove('selected'));
1226
1229
  }
1227
1230
 
1231
+ // ── 工作目录默认跟随任务名 ─────────────────────────────────
1232
+ // 任务名 → <根目录>/<任务名>,如 EPS3 → D:\project\EPS3(服务端会自动 mkdir)。
1233
+ // 手改目录 / 📁 选择 / 点最近目录 = 用户接管,本次弹窗内不再自动覆盖;📌 把当前目录
1234
+ // 的上级记为根目录(localStorage 持久)。
1235
+ const ROOT_KEY = 'myhi_newtask_root';
1236
+ const IS_WIN = /Win/i.test(navigator.platform || '');
1237
+ const ROOT_DEFAULT = IS_WIN ? 'D:\\project' : '';
1238
+ let _cwdTouched = false;
1239
+
1240
+ function taskRoot() {
1241
+ try { const v = localStorage.getItem(ROOT_KEY); if (v) return v; } catch {}
1242
+ return ROOT_DEFAULT;
1243
+ }
1244
+ function sanitizeTaskName(name) {
1245
+ // 与服务端 taskCwdFromTitle 同款清洗:Windows 目录非法字符 → '_',掐头尾点和空白
1246
+ return String(name || '').trim().replace(/[\\/:*?"<>|]+/g, '_').replace(/^\.+/, '').trim().slice(0, 80);
1247
+ }
1248
+ function defaultTaskDir(name) {
1249
+ const n = sanitizeTaskName(name);
1250
+ if (!n) return '';
1251
+ const root = taskRoot();
1252
+ if (!root) return ''; // 非 Windows 且没设过根:不猜,留空自选
1253
+ const sep = root.includes('\\') ? '\\' : '/';
1254
+ return root.replace(/[\\/]+$/, '') + sep + n;
1255
+ }
1256
+ function syncCwdToTitle() {
1257
+ if (_cwdTouched) return;
1258
+ document.getElementById('inp-cwd').value = defaultTaskDir(document.getElementById('inp-title').value);
1259
+ }
1260
+ function pinTaskRoot(btn) {
1261
+ const cur = document.getElementById('inp-cwd').value.trim();
1262
+ if (!cur) { alert('请先填写或选择一个目录,再点 📌 把它的上级记为默认根目录'); return; }
1263
+ const m = cur.replace(/[\\/]+$/, '');
1264
+ const idx = Math.max(m.lastIndexOf('\\'), m.lastIndexOf('/'));
1265
+ const root = idx > 2 ? m.slice(0, idx) : m;
1266
+ try { localStorage.setItem(ROOT_KEY, root); } catch {}
1267
+ _cwdTouched = false;
1268
+ syncCwdToTitle();
1269
+ const old = btn.textContent;
1270
+ btn.textContent = '已记住';
1271
+ setTimeout(() => { btn.textContent = old; }, 1200);
1272
+ }
1273
+
1274
+ document.getElementById('inp-title').addEventListener('input', syncCwdToTitle);
1275
+ document.getElementById('inp-cwd').addEventListener('input', () => { _cwdTouched = true; });
1276
+
1228
1277
  document.getElementById('inp-title').addEventListener('keydown', e => {
1229
1278
  if (e.key === 'Enter') createSession();
1230
1279
  });
@@ -1296,7 +1345,7 @@
1296
1345
  btn.textContent = short;
1297
1346
  btn.title = path;
1298
1347
  btn.style.cssText = 'background:var(--bg);color:var(--accent);border:1px solid var(--border);border-radius:6px;padding:0.2rem 0.5rem;font-size:0.72rem;cursor:pointer;font-family:"SF Mono",Consolas,monospace;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap';
1299
- btn.onclick = () => { document.getElementById('inp-cwd').value = path; };
1348
+ btn.onclick = () => { document.getElementById('inp-cwd').value = path; _cwdTouched = true; };
1300
1349
  container.appendChild(btn);
1301
1350
  });
1302
1351
  }
@@ -1315,6 +1364,7 @@
1315
1364
  }
1316
1365
  function selectDir() {
1317
1366
  document.getElementById('inp-cwd').value = _dirCurrent;
1367
+ _cwdTouched = true; // 用户明确选了目录:接管,不再自动跟随任务名
1318
1368
  recordDir(_dirCurrent);
1319
1369
  closeDirPicker();
1320
1370
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wendongfly/myhi",
3
- "version": "1.3.150",
3
+ "version": "1.3.152",
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",