claude-simple 0.2.25 → 0.2.26

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.
@@ -79,7 +79,6 @@ export const AppShell = (opts = {}) => {
79
79
  <span id="topbar-project" class="text-sm text-base-content/50 flex-1 truncate min-w-0">Select a session</span>
80
80
  <span id="conn-dot" class="w-2 h-2 rounded-full bg-base-content/30 flex-shrink-0" title="连接状态"></span>
81
81
  <div class="flex gap-2 topbar-actions">
82
- <button id="btn-share-session" class="btn btn-ghost btn-xs border border-base-300" title="复制当前会话分享链接">分享</button>
83
82
  <button id="btn-pwa-install" class="btn btn-ghost btn-xs border border-base-300 hidden" title="安装到主屏幕">安装</button>
84
83
  <button id="btn-meta-agent" class="btn btn-ghost btn-xs border border-primary/40 text-primary topbar-icon-btn" title="Meta Agent — 报告 / 问答 / VLM" aria-label="打开 Meta Agent">
85
84
  <svg class="topbar-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><path d="m12 2 1.6 6.4L20 10l-6.4 1.6L12 18l-1.6-6.4L4 10l6.4-1.6L12 2Z"/><path d="m19 16 .7 2.3L22 19l-2.3.7L19 22l-.7-2.3L16 19l2.3-.7L19 16Z"/></svg><span class="topbar-icon-label">Agent</span>
@@ -92,6 +91,10 @@ export const AppShell = (opts = {}) => {
92
91
  <button id="btn-logout" class="btn btn-ghost btn-xs border border-base-300">Sign out</button>
93
92
  </div>
94
93
  </div>
94
+ <button id="btn-expand-chat-chrome" class="chat-chrome-fab hidden" type="button"
95
+ title="显示会话工具栏" aria-label="显示会话工具栏">
96
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><path d="M7 14l5-5 5 5"/><path d="M5 19h14"/></svg>
97
+ </button>
95
98
  <!-- Fixed panel + backdrop: siblings of topbar so flex layout never clips them -->
96
99
  <div id="recent-menu-backdrop" class="hidden fixed inset-0 z-[55] bg-black/40" aria-hidden="true"></div>
97
100
  <div id="recent-menu" class="hidden fixed z-[60] w-80 max-h-[min(24rem,70vh)] overflow-y-auto
@@ -255,6 +258,7 @@ export const AppShell = (opts = {}) => {
255
258
  <div id="tab-chat" class="flex flex-col flex-1 overflow-hidden relative">
256
259
  <div id="project-notes-bar" class="bg-base-200 border-b border-base-300 px-3 py-1.5 text-xs flex flex-col gap-1" style="display:none"></div>
257
260
  <div id="session-notes-bar" class="bg-base-200/80 border-b border-base-300 px-3 py-1 text-xs flex justify-between items-center gap-2" style="display:none"></div>
261
+ <div id="session-lock-banner" class="session-lock-banner hidden px-3 py-1.5 text-[11px] text-center border-b"></div>
258
262
  <div id="ws-banner" class="hidden px-3 py-1.5 text-[11px] text-center bg-warning/15 text-warning border-b border-warning/20 flex items-center justify-center gap-2">
259
263
  <span id="ws-banner-text"></span>
260
264
  <button type="button" id="ws-banner-retry" class="btn btn-ghost btn-xs h-6 min-h-0 px-2 text-warning border border-warning/30">重连</button>
package/public/shell.js CHANGED
@@ -310,6 +310,12 @@ export function initShell(opts = {}) {
310
310
  initSidebarResize();
311
311
  initSidebarToggle();
312
312
  initNotifications({ openSession: resumeSession });
313
+ const setChatChromeCollapsed = (collapsed) => {
314
+ $('app')?.classList.toggle('chat-chrome-collapsed', collapsed);
315
+ $('btn-expand-chat-chrome')?.classList.toggle('hidden', !collapsed);
316
+ localStorage.setItem('chatChromeCollapsed', collapsed ? '1' : '0');
317
+ };
318
+ setChatChromeCollapsed(localStorage.getItem('chatChromeCollapsed') === '1');
313
319
 
314
320
  let sessionsChangedTimer = null;
315
321
  document.addEventListener('sessions-changed', () => {
@@ -336,13 +342,17 @@ export function initShell(opts = {}) {
336
342
  });
337
343
 
338
344
  delegate.on('click', '#btn-home', goHome);
339
- delegate.on('click', '#btn-share-session', async (_, el) => {
345
+ delegate.on('click', '#btn-share-session, #btn-share-session-current', async (_, el) => {
340
346
  const url = currentSessionShareUrl();
341
347
  if (!url) return;
342
348
  try {
343
349
  await navigator.clipboard.writeText(url);
344
- el.textContent = '已复制';
345
- setTimeout(() => { el.textContent = '分享'; }, 1400);
350
+ el.classList.add('is-copied');
351
+ el.title = '已复制分享链接';
352
+ setTimeout(() => {
353
+ el.classList.remove('is-copied');
354
+ el.title = '复制当前会话分享链接';
355
+ }, 1400);
346
356
  } catch {
347
357
  window.prompt('复制会话链接:', url);
348
358
  }
@@ -432,6 +442,8 @@ export function initShell(opts = {}) {
432
442
  document.getElementById('btn-pwa-install')?.classList.remove('hidden');
433
443
  });
434
444
  delegate.on('click', '#btn-settings', openSettings);
445
+ delegate.on('click', '#btn-collapse-chat-chrome', () => setChatChromeCollapsed(true));
446
+ delegate.on('click', '#btn-expand-chat-chrome', () => setChatChromeCollapsed(false));
435
447
  delegate.on('click', '#btn-meta-agent', () => toggleMetaAgent());
436
448
  delegate.on('click', '#btn-meta-agent-welcome', () => openMetaAgent('chat'));
437
449
  delegate.on('click', '#btn-theme', toggleTheme);
@@ -610,7 +622,7 @@ export function initShell(opts = {}) {
610
622
  });
611
623
  document.addEventListener('agent-changed', refreshModelSelect);
612
624
 
613
- delegate.on('click', '#btn-new-session, #btn-new-session-welcome', openNewSessionModal);
625
+ delegate.on('click', '#btn-new-session, #btn-new-session-current, #btn-new-session-welcome', openNewSessionModal);
614
626
  delegate.on('click', '#new-session-cancel', () => $('modal-new-session').close());
615
627
  delegate.on('click', '#new-session-start', startNewSession);
616
628
  delegate.on('change', '#new-session-agent', updateNewSessionAgentUI);
package/public/state.js CHANGED
@@ -108,6 +108,9 @@ export const ctx = {
108
108
  shellBubble: null,
109
109
  configDir: null,
110
110
  externalSessionReadOnly: false,
111
+ role: null,
112
+ username: null,
113
+ lock: { key: null, token: null, holder: null, held: false, foreign: false },
111
114
  };
112
115
 
113
116
  /** Select edge machine (hub). Keeps signal + ctx + localStorage in sync. */
package/public/style.css CHANGED
@@ -23,13 +23,17 @@
23
23
  #chat-input {
24
24
  min-height: 32px !important;
25
25
  max-height: 72px !important;
26
- padding: 0 !important;
26
+ padding: 8px 12px 4px !important;
27
27
  border-radius: 0.65rem 0.65rem 0 0;
28
28
  /* 16px prevents iOS Safari auto-zoom on focus */
29
29
  font-size: 16px !important;
30
30
  line-height: 1.4 !important;
31
31
  }
32
- .composer-icon-btn { width: 40px; height: 40px; font-size: 19px; }
32
+ /* Two fixed icon slots: settings + attachment never wrap below the input. */
33
+ .composer-tools { flex: 0 0 64px; flex-wrap: nowrap; gap: 0; }
34
+ .composer-icon-btn { width: 32px; height: 32px; min-width: 32px; font-size: 17px; }
35
+ .composer-actions { flex-wrap: nowrap; gap: .35rem; }
36
+ .composer-submit { min-width: 0; flex-shrink: 1; }
33
37
  .composer-send-btn, .composer-stop-btn { min-height: 40px; height: 40px; }
34
38
  .composer-hint { display: none; }
35
39
  #chat-opts {
@@ -541,6 +545,37 @@ html.pwa-standalone .ma-panel {
541
545
  white-space: pre;
542
546
  overflow-x: auto;
543
547
  }
548
+
549
+ /* Markdown files open as a rendered document; source remains one tap away. */
550
+ .file-markdown-toolbar {
551
+ display: flex;
552
+ gap: 0.25rem;
553
+ padding: 0.4rem 1rem;
554
+ border-bottom: 1px solid color-mix(in oklch, var(--color-base-content) 10%, transparent);
555
+ background: color-mix(in oklch, var(--color-base-200) 75%, transparent);
556
+ }
557
+ .file-markdown-mode {
558
+ border: 1px solid transparent;
559
+ border-radius: 0.375rem;
560
+ padding: 0.18rem 0.55rem;
561
+ color: color-mix(in oklch, var(--color-base-content) 58%, transparent);
562
+ background: transparent;
563
+ font-size: 0.72rem;
564
+ font-weight: 600;
565
+ cursor: pointer;
566
+ }
567
+ .file-markdown-mode:hover {
568
+ color: var(--color-base-content);
569
+ background: color-mix(in oklch, var(--color-base-content) 7%, transparent);
570
+ }
571
+ .file-markdown-mode.active {
572
+ color: var(--color-primary);
573
+ border-color: color-mix(in oklch, var(--color-primary) 35%, transparent);
574
+ background: color-mix(in oklch, var(--color-primary) 12%, transparent);
575
+ }
576
+ .file-markdown-preview {
577
+ min-height: 0;
578
+ }
544
579
  /* Reuse chat token palette outside .md so file preview is colored even if CDN theme lags */
545
580
  .file-preview .hljs-comment,
546
581
  .file-preview .hljs-quote {
@@ -1126,7 +1161,7 @@ html.pwa-standalone .ma-panel {
1126
1161
  width: 100%;
1127
1162
  min-height: 32px;
1128
1163
  max-height: 72px;
1129
- padding: 0;
1164
+ padding: 8px 12px 4px;
1130
1165
  border: 0;
1131
1166
  border-radius: 0.75rem 0.75rem 0 0;
1132
1167
  background: transparent;
@@ -1184,6 +1219,51 @@ html.pwa-standalone .ma-panel {
1184
1219
  flex: 0 0 auto;
1185
1220
  }
1186
1221
  .topbar-icon-label { display: inline; }
1222
+ .session-title-actions { margin-left: .1rem; }
1223
+ #session-notes-text { min-width: 0; flex: 1 1 4rem; }
1224
+ .session-bar-icon,
1225
+ #session-notes-bar .session-hide-btn {
1226
+ width: 26px;
1227
+ height: 26px;
1228
+ padding: 0;
1229
+ display: inline-flex;
1230
+ align-items: center;
1231
+ justify-content: center;
1232
+ border: 0;
1233
+ border-radius: .4rem;
1234
+ background: transparent;
1235
+ color: color-mix(in oklch, var(--color-base-content) 62%, transparent);
1236
+ cursor: pointer;
1237
+ }
1238
+ .session-bar-icon:hover,
1239
+ #session-notes-bar .session-hide-btn:hover { background: color-mix(in oklch, var(--color-base-content) 9%, transparent); color: var(--color-base-content); }
1240
+ .session-bar-icon.is-copied { color: var(--color-success); }
1241
+ .session-bar-icon svg,
1242
+ #session-notes-bar .session-hide-btn svg,
1243
+ .chat-chrome-fab svg { width: 15px; height: 15px; }
1244
+ .chat-chrome-fab {
1245
+ position: fixed;
1246
+ top: max(.6rem, env(safe-area-inset-top, 0px));
1247
+ left: max(.6rem, env(safe-area-inset-left, 0px));
1248
+ z-index: 40;
1249
+ width: 34px;
1250
+ height: 34px;
1251
+ display: inline-flex;
1252
+ align-items: center;
1253
+ justify-content: center;
1254
+ border: 1px solid color-mix(in oklch, var(--color-base-content) 16%, transparent);
1255
+ border-radius: 999px;
1256
+ color: var(--color-base-content);
1257
+ background: color-mix(in oklch, var(--color-base-100) 88%, transparent);
1258
+ box-shadow: 0 4px 14px color-mix(in oklch, black 24%, transparent);
1259
+ }
1260
+ .chat-chrome-fab.hidden { display: none; }
1261
+ #app.chat-chrome-collapsed #topbar,
1262
+ #app.chat-chrome-collapsed #project-view > .flex.bg-base-200,
1263
+ #app.chat-chrome-collapsed #project-notes-bar,
1264
+ #app.chat-chrome-collapsed #session-notes-bar,
1265
+ #app.chat-chrome-collapsed #session-lock-banner,
1266
+ #app.chat-chrome-collapsed #ws-banner { display: none !important; }
1187
1267
  .mermaid-diagram {
1188
1268
  overflow-x: auto;
1189
1269
  padding: .75rem .25rem .25rem;
@@ -1749,3 +1829,21 @@ html.settings-open #app { visibility: hidden; }
1749
1829
  .set-nav { flex-direction: row; overflow-x: auto; gap: 0.25rem; }
1750
1830
  .set-nav-item { white-space: nowrap; }
1751
1831
  }
1832
+
1833
+ /* Overlays must not eat keystrokes when hidden */
1834
+ #sidebar-overlay.hidden,
1835
+ .mermaid-zoom-overlay.hidden,
1836
+ #session-lock-banner.hidden {
1837
+ display: none !important;
1838
+ pointer-events: none !important;
1839
+ }
1840
+ #session-lock-banner {
1841
+ background: color-mix(in oklch, var(--color-warning) 16%, var(--color-base-200));
1842
+ color: color-mix(in oklch, var(--color-warning) 80%, var(--color-base-content));
1843
+ pointer-events: none;
1844
+ }
1845
+ #chat-input:disabled,
1846
+ #chat-input[readonly] {
1847
+ cursor: not-allowed;
1848
+ opacity: .78;
1849
+ }
package/public/sw.js CHANGED
@@ -1,12 +1,12 @@
1
1
  /* Agent UI service worker — cache shell assets only.
2
2
  * Never intercepts WebSocket or mutates API semantics beyond offline fallback.
3
3
  * Bump CACHE when shipping UI that must invalidate old shells. */
4
- const CACHE = 'agent-ui-shell-v25';
4
+ const CACHE = 'agent-ui-shell-v27';
5
5
  const PRECACHE = [
6
6
  '/',
7
7
  '/index.html',
8
8
  '/manifest.webmanifest',
9
- '/style.css?v=ui-20',
9
+ '/style.css?v=ui-22',
10
10
  '/style.css',
11
11
  '/ui.min.css',
12
12
  '/vendor/mini-react.min.js',
@@ -16,7 +16,7 @@ const PRECACHE = [
16
16
  '/vendor/mermaid.min.js',
17
17
  '/vendor/katex.min.js',
18
18
  '/vendor/katex.min.css',
19
- '/app.js?v=ui-20',
19
+ '/app.js?v=ui-22',
20
20
  '/icons/icon-192.png',
21
21
  '/icons/icon-512.png',
22
22
  '/icons/icon-maskable-512.png',