claude-simple 0.2.7 → 0.2.8

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 (59) hide show
  1. package/README.md +0 -0
  2. package/dist/app.0.2.8.min.js +1080 -0
  3. package/dist/index.html +2 -2
  4. package/dist/{style.0.2.7.min.css → style.0.2.8.min.css} +1 -1
  5. package/gateway.js +0 -0
  6. package/package.json +1 -1
  7. package/public/addon-fit.min.js +0 -0
  8. package/public/agent-panel.js +0 -0
  9. package/public/api.js +2 -0
  10. package/public/app.js +0 -0
  11. package/public/base.css +0 -0
  12. package/public/cache.js +0 -0
  13. package/public/chat.js +37 -6
  14. package/public/files.js +0 -0
  15. package/public/git.js +0 -0
  16. package/public/icons/icon-180.png +0 -0
  17. package/public/icons/icon-192.png +0 -0
  18. package/public/icons/icon-512.png +0 -0
  19. package/public/icons/icon-maskable-512.png +0 -0
  20. package/public/index.html +0 -0
  21. package/public/lib.js +0 -0
  22. package/public/manifest.webmanifest +0 -0
  23. package/public/mobile.js +0 -0
  24. package/public/notifications.js +215 -0
  25. package/public/offline.html +0 -0
  26. package/public/pwa.js +0 -0
  27. package/public/router.js +0 -0
  28. package/public/settings.js +0 -0
  29. package/public/shell/boot.js +0 -0
  30. package/public/shell/dashboard.js +46 -26
  31. package/public/shell/hub.js +0 -0
  32. package/public/shell/layout.js +2 -3
  33. package/public/shell/notes.js +0 -0
  34. package/public/shell/session-context.js +0 -0
  35. package/public/shell/session-list.js +5 -14
  36. package/public/shell/session-nav.js +18 -1
  37. package/public/shell/templates.js +18 -0
  38. package/public/shell/util.js +0 -0
  39. package/public/shell.js +24 -6
  40. package/public/state.js +49 -7
  41. package/public/style.css +0 -0
  42. package/public/sw.js +1 -1
  43. package/public/terminal.js +0 -0
  44. package/public/wake-lock.js +0 -0
  45. package/public/xterm.min.css +0 -0
  46. package/public/xterm.min.js +0 -0
  47. package/src/agents/claude.js +0 -0
  48. package/src/agents/codex.js +0 -0
  49. package/src/agents/grok.js +180 -299
  50. package/src/agents/meta-agent.js +0 -0
  51. package/src/agents/models.js +0 -0
  52. package/src/agents/sessions.js +0 -0
  53. package/src/agents/stream-batch.js +0 -0
  54. package/src/app.js +0 -0
  55. package/src/auto-update.js +0 -0
  56. package/src/runtime/approvals.js +0 -0
  57. package/src/runtime/outbox.js +0 -0
  58. package/src/runtime/protocol.js +0 -0
  59. package/dist/app.0.2.7.min.js +0 -1039
package/public/shell.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  sessionsData, workspacesData, sessionFilter, sessionSearch,
7
7
  expandedFolders, collapsedFolders, filesPath, viewingFile, filteredSessions, projectGroups,
8
8
  currentProject, currentTab, filesRoot, gitRoot,
9
- currentModel, currentEffort, currentPermission, currentAgent, setAgent,
9
+ currentModel, currentEffort, currentPermission, currentAgent, setAgent, setCurrentModel,
10
10
  sidebarView, agentFilter, timeRange, activityHits, activityLoading,
11
11
  chatDensity, setChatDensity,
12
12
  favoritesOnly, showHiddenOnly, hubMode, hubMachineReady, selectedMachineId, setSelectedMachine,
@@ -23,6 +23,9 @@ import {
23
23
  import { syncHash } from './router.js';
24
24
  import { initSettings, openSettings } from './settings.js';
25
25
  import { openMetaAgent, toggleMetaAgent } from './agent-panel.js';
26
+ import {
27
+ initNotifications, refreshNotifications, toggleNotificationsMenu, closeNotificationsMenu,
28
+ } from './notifications.js';
26
29
 
27
30
  import { AuthScreen, AppShell } from './shell/templates.js';
28
31
  import {
@@ -306,6 +309,7 @@ export function initShell(opts = {}) {
306
309
 
307
310
  initSidebarResize();
308
311
  initSidebarToggle();
312
+ initNotifications({ openSession: resumeSession });
309
313
 
310
314
  let sessionsChangedTimer = null;
311
315
  document.addEventListener('sessions-changed', () => {
@@ -519,8 +523,7 @@ export function initShell(opts = {}) {
519
523
  if (prev !== next) {
520
524
  ctx.sessionId = null;
521
525
  setAgent(next);
522
- currentModel.value = getDefaultModel(next) || currentModel.peek();
523
- localStorage.setItem('model', currentModel.peek());
526
+ setCurrentModel(getDefaultModel(next) || currentModel.peek());
524
527
  $('sel-permission').value = currentPermission.peek();
525
528
  refreshModelSelect();
526
529
  appendSystemMsg(`Agent → ${AGENT_LABELS[next] || next} · model ${currentModel.peek()} · new session`);
@@ -554,8 +557,7 @@ export function initShell(opts = {}) {
554
557
  }
555
558
  });
556
559
  delegate.on('change', '#sel-model', (_, el) => {
557
- currentModel.value = el.value;
558
- localStorage.setItem('model', el.value);
560
+ setCurrentModel(el.value);
559
561
  refreshEffortSelect();
560
562
  });
561
563
  delegate.on('click', '#btn-model-add', () => promptCustomModel({ editCurrent: false }));
@@ -590,6 +592,7 @@ export function initShell(opts = {}) {
590
592
  return;
591
593
  }
592
594
  await enterMachine(id, { forceReload: true });
595
+ refreshNotifications();
593
596
  });
594
597
  const refreshMachinesUi = async () => {
595
598
  const st = $('machine-picker-status');
@@ -611,6 +614,7 @@ export function initShell(opts = {}) {
611
614
  delegate.on('click', '#btn-machine-menu', async e => {
612
615
  e.stopPropagation();
613
616
  closeRecentMenu();
617
+ closeNotificationsMenu();
614
618
  const menu = $('machine-menu');
615
619
  if (!menu) return;
616
620
  if (menu.classList.contains('hidden')) {
@@ -625,7 +629,8 @@ export function initShell(opts = {}) {
625
629
  e.preventDefault();
626
630
  e.stopPropagation();
627
631
  closeMachineMenu();
628
- toggleRecentMenu(getDashboardSessions());
632
+ closeNotificationsMenu();
633
+ toggleRecentMenu();
629
634
  const open = !$('recent-menu')?.classList.contains('hidden');
630
635
  const btn = $('btn-recent-sessions');
631
636
  if (btn) btn.setAttribute('aria-expanded', open ? 'true' : 'false');
@@ -649,6 +654,13 @@ export function initShell(opts = {}) {
649
654
  btn?.setAttribute('aria-expanded', 'false');
650
655
  }
651
656
  });
657
+ delegate.on('click', '#btn-notifications', e => {
658
+ e.preventDefault();
659
+ e.stopPropagation();
660
+ closeMachineMenu();
661
+ closeRecentMenu();
662
+ toggleNotificationsMenu();
663
+ });
652
664
  // Keep panel glued under topbar on rotate / URL bar show-hide
653
665
  window.addEventListener('resize', () => {
654
666
  if ($('recent-menu') && !$('recent-menu').classList.contains('hidden')) {
@@ -761,6 +773,12 @@ export function initShell(opts = {}) {
761
773
  });
762
774
 
763
775
  refreshModelSelect();
776
+ effect(() => {
777
+ void hubMode.value;
778
+ void selectedMachineId.value;
779
+ if (!ctx.token) return;
780
+ refreshNotifications();
781
+ });
764
782
  $('sel-permission').value = currentPermission.peek();
765
783
  applyChatDensity();
766
784
  const dens = $('sel-density');
package/public/state.js CHANGED
@@ -15,8 +15,48 @@ export const currentTab = signal('chat');
15
15
  export const isProcessing = signal(false);
16
16
  /** Chat socket: idle | connecting | open | reconnecting | offline */
17
17
  export const wsStatus = signal('idle');
18
- export const currentAgent = signal(localStorage.getItem('agent') || 'claude'); // 'claude'|'codex'|'grok'
19
- export const currentModel = signal(localStorage.getItem('model') || 'claude-sonnet-4-5');
18
+ const MODEL_BY_SESSION_KEY = 'modelBySession';
19
+ const initialAgent = localStorage.getItem('agent') || 'claude';
20
+
21
+ function readModelBySession() {
22
+ try {
23
+ const value = JSON.parse(localStorage.getItem(MODEL_BY_SESSION_KEY) || '{}');
24
+ return value && typeof value === 'object' ? value : {};
25
+ } catch {
26
+ return {};
27
+ }
28
+ }
29
+
30
+ function modelSessionKey(agent, sessionId = ctx.sessionId, machineId = ctx.machineId) {
31
+ if (!sessionId) return '';
32
+ const a = (agent || 'claude').toLowerCase();
33
+ return `${machineId || ''}:${a}:${sessionId}`;
34
+ }
35
+
36
+ /** Restore the model explicitly selected for the active session. */
37
+ export function getSavedModel(agent, sessionId = ctx.sessionId, machineId = ctx.machineId) {
38
+ const key = modelSessionKey(agent, sessionId, machineId);
39
+ if (!key) return null;
40
+ const saved = readModelBySession()[key];
41
+ if (typeof saved === 'string' && saved.trim()) return saved;
42
+ return null;
43
+ }
44
+
45
+ /** Update the picker and persist its value only when a session exists. */
46
+ export function setCurrentModel(model, agent = currentAgent.peek(), sessionId = ctx.sessionId, machineId = ctx.machineId) {
47
+ const value = String(model || '').trim();
48
+ if (!value) return;
49
+ const key = modelSessionKey(agent, sessionId, machineId);
50
+ if (key) {
51
+ const saved = readModelBySession();
52
+ saved[key] = value;
53
+ localStorage.setItem(MODEL_BY_SESSION_KEY, JSON.stringify(saved));
54
+ }
55
+ currentModel.value = value;
56
+ }
57
+
58
+ export const currentAgent = signal(initialAgent); // 'claude'|'codex'|'grok'
59
+ export const currentModel = signal('claude-sonnet-4-5');
20
60
  export const currentEffort = signal('');
21
61
  // All local agents are trusted by default; users can still choose another mode
22
62
  // from the expanded composer options before starting a turn.
@@ -252,11 +292,13 @@ export function setAgent(agent) {
252
292
  currentPermission.value = 'bypassPermissions';
253
293
  const permissionSelect = typeof document === 'undefined' ? null : document.getElementById('sel-permission');
254
294
  if (permissionSelect) permissionSelect.value = currentPermission.peek();
255
- const models = getModelsForAgent(a);
256
- const def = getDefaultModel(a);
257
- if (!models.some(m => m.value === currentModel.peek())) {
258
- currentModel.value = def;
259
- localStorage.setItem('model', def);
295
+ // Model selection belongs to a concrete session, not to the whole agent.
296
+ // New sessions start from the agent default until they receive a session id.
297
+ const saved = getSavedModel(a);
298
+ if (saved) {
299
+ currentModel.value = saved;
300
+ } else {
301
+ setCurrentModel(getDefaultModel(a), a);
260
302
  }
261
303
  }
262
304
 
package/public/style.css CHANGED
File without changes
package/public/sw.js CHANGED
@@ -1,7 +1,7 @@
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-v13';
4
+ const CACHE = 'agent-ui-shell-v15';
5
5
  const PRECACHE = [
6
6
  '/',
7
7
  '/index.html',
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes