nio-cat 0.5.1 → 0.6.1

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/web/app/style.css CHANGED
@@ -314,7 +314,7 @@ body.board-mode .view-enter { animation: none; }
314
314
 
315
315
  @media (prefers-reduced-motion: no-preference) {
316
316
  .view-enter { animation: view-in .25s var(--ease); }
317
- @keyframes view-in { from { opacity: 0; transform: translateY(10px); } }
317
+ @keyframes view-in { from { opacity: 0; } }
318
318
  }
319
319
  @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } }
320
320
 
@@ -348,12 +348,13 @@ body.board-mode .view-enter { animation: none; }
348
348
  .paste .pair-form { flex-direction: column; }
349
349
  .side nav .grp { padding: 16px 12px 4px; }
350
350
  .top h1 { font-size: 26px; }
351
- .chat { height: calc(100dvh - 56px - var(--safe-t)); }
352
- body.chat-mode { overflow: hidden; }
353
- body.chat-mode .shell { min-height: 0; }
354
- body.chat-mode .mbar { position: fixed; left: 0; right: 0; transform: translateY(var(--vvt, 0px)); }
355
- body.chat-mode .chat { position: fixed; left: 0; right: 0; top: calc(56px + var(--safe-t) + var(--vvt, 0px)); height: calc(var(--vvh, 100dvh) - 56px - var(--safe-t)); }
356
- body.chat-mode.kb .composer { padding-bottom: 10px; }
351
+ /* Al mòbil només fa scroll el document: res de contenidors amb scroll propi. */
352
+ .chat { height: auto; min-height: calc(100dvh - 56px - var(--safe-t)); }
353
+ .mode-bar { position: sticky; top: calc(56px + var(--safe-t)); z-index: 20; background: color-mix(in srgb, var(--bg) 82%, transparent); -webkit-backdrop-filter: blur(18px) saturate(160%); backdrop-filter: blur(18px) saturate(160%); }
354
+ .feed { flex: 1 0 auto; overflow: visible; overscroll-behavior: auto; }
355
+ .composer { position: sticky; bottom: var(--kb, 0px); z-index: 20; background: var(--bg); }
356
+ body.kb .composer { padding-bottom: 10px; }
357
+ .tool pre, .approval pre, .ev-logs pre, .proj-list { max-height: none; overflow-y: visible; }
357
358
  .composer textarea, input[type="text"], input[type="password"], input[type="url"], input[type="search"], select, textarea.field { font-size: 16px; }
358
359
  .chat-head { display: none; }
359
360
  .mode-bar { padding: 10px 16px; }
@@ -569,3 +570,58 @@ dialog.sheet.wiz.compact .sheet-in, .compact .wiz-body { flex: 0 1 auto; }
569
570
  .new-fab { position: fixed; right: 16px; bottom: calc(72px + var(--safe-b)); z-index: 25; height: 48px; padding: 0 18px 0 14px; border-radius: 16px; box-shadow: 0 14px 30px -14px color-mix(in srgb, var(--fg) 70%, transparent); }
570
571
  body:not(.no-tabs):not(.kb) .main:has(.new-fab) { padding-bottom: calc(130px + var(--safe-b)); }
571
572
  }
573
+
574
+ .skel { display: block; height: 14px; border-radius: 8px; background: linear-gradient(90deg, var(--border) 25%, color-mix(in srgb, var(--border) 45%, var(--white)) 50%, var(--border) 75%) 0 0 / 200% 100%; animation: skel 1.3s linear infinite; }
575
+ .skel.tall { height: 22px; }
576
+ .skel.r { margin-left: auto; }
577
+ .skel-card { display: grid; gap: 12px; padding: 18px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--white); }
578
+ .skel-feed { display: grid; gap: 14px; padding: 8px 16px; max-width: 760px; margin: 0 auto; width: 100%; box-sizing: border-box; }
579
+ @keyframes skel { to { background-position: -200% 0; } }
580
+ .chip.fav { border-color: color-mix(in srgb, var(--lemon) 70%, var(--border)); }
581
+ .chip[data-fav][aria-pressed="true"] { background: var(--lemon); border-color: var(--lemon); }
582
+ .manage-bar { position: sticky; top: 0; z-index: 5; display: grid; gap: 10px; margin: 0 0 12px; padding: 12px; border: 1px solid var(--border); border-radius: 14px; background: var(--bg); }
583
+ .manage-bar .row { flex-wrap: wrap; }
584
+ .session-card.pick-mode { cursor: pointer; position: relative; padding-left: 46px; user-select: none; }
585
+ .session-card.pick-mode::before { content: ""; position: absolute; left: 14px; top: 16px; width: 20px; height: 20px; border-radius: 6px; border: 1.5px solid var(--border); background: var(--white); }
586
+ .session-card.picked { border-color: var(--fg); }
587
+ .session-card.picked::before { background: var(--fg); border-color: var(--fg); }
588
+ .session-card.picked::after { content: ""; position: absolute; left: 21px; top: 20px; width: 6px; height: 11px; border: solid var(--bg); border-width: 0 2px 2px 0; transform: rotate(45deg); }
589
+
590
+ .mode-bar .chip { height: 30px; gap: 7px; padding: 0 12px 0 10px; }
591
+ .mode-bar .chip > .ico, .mode-bar .chip > .agent-tag .ico { width: 15px; height: 15px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
592
+ .mode-bar .chip > span:not(.agent-tag) { line-height: 1; }
593
+ .mode-bar .chip .abot { --s: 18px; display: inline-grid; place-items: center; }
594
+ .mode-bar .chip .agent-tag { gap: 7px; line-height: 1; }
595
+
596
+ /* lliscar entre pàgines: es mou només el contingut; barres i botons fixos no es toquen */
597
+ @media (max-width: 820px) {
598
+ .main { overflow-x: clip; }
599
+ #view.swiping .page, #view.swipe-anim .page { position: relative; left: var(--sx, 0); opacity: var(--so, 1); will-change: left, opacity; }
600
+ #view.swipe-anim .page { transition: left .18s var(--ease), opacity .18s ease-out; }
601
+ }
602
+
603
+ /* ---------- Motiu i captura a les aprovacions ---------- */
604
+ .approval .why { display: grid; gap: 2px; padding: 10px 12px; border-radius: 8px; background: color-mix(in srgb, var(--lemon) 22%, var(--white)); }
605
+ .approval .why p { font-size: 14px; white-space: pre-wrap; overflow-wrap: anywhere; }
606
+ .approval .shot, .screen-img { width: 100%; border-radius: 10px; border: 1px solid var(--border); background: var(--bg-2); display: block; }
607
+
608
+ /* ---------- Activitat ---------- */
609
+ .act-filter { margin-bottom: 16px; overflow-x: auto; scrollbar-width: none; }
610
+ .act-filter button { padding: 0 12px; }
611
+ .act { display: grid; }
612
+ .act-day { font-size: 12px; font-weight: 600; color: var(--fg-muted); margin: 18px 0 6px; text-transform: capitalize; }
613
+ .act-day:first-child { margin-top: 0; }
614
+ .act-row { display: flex; gap: 12px; padding: 10px 0; border-top: 1px solid color-mix(in srgb, var(--border) 70%, transparent); }
615
+ .act-t { flex: none; width: 44px; font-size: 12px; color: var(--fg-muted); padding-top: 2px; }
616
+ .act-row .row { gap: 8px; }
617
+ .act-what { overflow-wrap: anywhere; color: var(--fg); margin-top: 2px; }
618
+ .act-row .verdict { font-size: 12px; }
619
+
620
+ /* ---------- Feines ---------- */
621
+ .job .title { font-size: 16px; font-weight: 500; letter-spacing: -.02em; margin-top: 8px; }
622
+ .job .meta { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; font-size: 12px; color: var(--fg-muted); }
623
+ .chip.ok { color: var(--moss); border-color: color-mix(in srgb, var(--moss) 40%, transparent); }
624
+ .grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
625
+ .check { gap: 10px; font-size: 14px; }
626
+ .check input { width: 18px; height: 18px; accent-color: var(--fg); }
627
+ @media (max-width: 520px) { .grid-2 { grid-template-columns: 1fr; } }
package/web/board.css CHANGED
@@ -104,9 +104,10 @@
104
104
  .bd-chat .m.nio b { font-weight: 600; }
105
105
  .bd-chat .mav { --s: 24px; --bw: .15; margin-bottom: 4px; }
106
106
  @keyframes bd-msg { from { opacity: 0; transform: translateY(6px); } }
107
- .bd-chat .chips { display: flex; gap: 6px; overflow-x: auto; padding: 0 16px 10px; scrollbar-width: none; }
107
+ .bd-chat .chips { flex: none; display: flex; gap: 6px; overflow-x: auto; overflow-y: hidden; padding: 4px 16px 10px; scrollbar-width: none; -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain; scroll-snap-type: x proximity; }
108
+ .bd-chat header, .bd-chat .brain, .bd-chat .cin { flex: none; }
108
109
  .bd-chat .chips::-webkit-scrollbar { display: none; }
109
- .bd-chat .chip-s { flex: none; max-width: 260px; box-sizing: border-box; height: 32px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 0 12px; line-height: 30px; text-align: center; border: 1px solid var(--border); border-radius: 999px; background: var(--white); font-size: 12px; font-weight: 500; cursor: pointer; }
110
+ .bd-chat .chip-s { flex: none; scroll-snap-align: start; max-width: 260px; box-sizing: border-box; height: 32px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 0 12px; line-height: 30px; text-align: center; border: 1px solid var(--border); border-radius: 999px; background: var(--white); font-size: 12px; font-weight: 500; cursor: pointer; }
110
111
  .bd-chat .chip-s:hover { border-color: var(--fg); }
111
112
  .bd-chat .cin { display: flex; gap: 8px; align-items: flex-end; padding: 12px 14px calc(14px + env(safe-area-inset-bottom)); border-top: 1px solid var(--border); }
112
113
  .bd-chat .cin textarea { flex: 1; min-height: 42px; max-height: 140px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 12px; background: var(--white); resize: none; font: inherit; font-size: 14px; line-height: 1.4; outline: none; }
package/web/board.js CHANGED
@@ -952,7 +952,8 @@ function drawBrains() {
952
952
  const sel_ = R.root.querySelector('#bdBrain'); if (!sel_) return;
953
953
  const list = window.NioBrains?.list() || [{ id: 'rules', label: 'Ordres ràpides' }];
954
954
  const cur = list.some((b) => b.id === B.opts.brain) ? B.opts.brain : 'rules'; // la preferència es manté encara que ara no hi sigui
955
- sel_.innerHTML = list.map((b) => `<option value="${esc(b.id)}" ${b.id === cur ? 'selected' : ''}>${esc(b.label)}</option>`).join('');
955
+ const html = list.map((b) => `<option value="${esc(b.id)}" ${b.id === cur ? 'selected' : ''}>${esc(b.label)}</option>`).join('');
956
+ if (sel_.dataset.sig !== html) { sel_.dataset.sig = html; sel_.innerHTML = html; }
956
957
  }
957
958
 
958
959
  /* ---------- Panell d'estil ---------- */
@@ -1034,7 +1035,7 @@ function openChat(open, focus = true, persist = true) {
1034
1035
  R.root.classList.toggle('chat-open', open);
1035
1036
  R.chat.inert = !open;
1036
1037
  const t = R.root.querySelector('[data-bd=chat]'); t.setAttribute('aria-pressed', open);
1037
- if (open && focus) setTimeout(() => R.input.focus(), reduce ? 0 : 280);
1038
+ if (open && focus && !matchMedia('(pointer: coarse)').matches) setTimeout(() => R.input.focus(), reduce ? 0 : 280);
1038
1039
  if (!open && wasOpen && R.chat.contains(document.activeElement)) t.focus({ preventScroll: true });
1039
1040
  }
1040
1041
 
@@ -1175,7 +1176,7 @@ function mount(root) {
1175
1176
  on(R.input, 'keydown', e => { if (e.key === 'Enter' && !e.shiftKey && !e.isComposing) { e.preventDefault(); send(); } if (e.key === 'Escape') { e.stopPropagation(); openChat(false); } });
1176
1177
  on(R.input, 'input', () => { R.input.style.height = ''; R.input.style.height = Math.min(140, R.input.scrollHeight) + 'px'; });
1177
1178
  on(R.root.querySelector('#bdBrain'), 'change', (e) => { B.opts.brain = e.target.value; save(); say(B.opts.brain === 'rules' ? 'Faig servir les ordres ràpides. Escriu <b>ajuda</b> per veure-les.' : `Ara t’entendré amb <b>${esc(e.target.selectedOptions[0].textContent)}</b>. Demana’m el diagrama com vulguis.`); });
1178
- on(R.root.querySelector('#bdBrain'), 'focus', drawBrains);
1179
+ on(R.root.querySelector('#bdBrain'), 'focus', () => { drawBrains(); window.NioBrains?.refresh?.(); });
1179
1180
  on(R.root.querySelector('#bdImport'), 'change', e => { const f = e.target.files[0]; if (f) importJSON(f); e.target.value = ''; });
1180
1181
  on(document, 'click', e => { if (R && !e.target.closest('.bd-menuwrap')) { const m = R.root.querySelector('#bdMenu'); if (m) m.hidden = true; } });
1181
1182
  on(window, 'resize', () => { applyView(); drawSel(); });
package/web/sw.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // nio · service worker: obre l'app encara que no hi hagi connexió i mostra els avisos.
2
- const SHELL = 'nio-shell-v15';
2
+ const SHELL = 'nio-shell-v20';
3
3
  const FILES = ['/app', '/app/style.css', '/app/app.js', '/bot.css', '/bot.js', '/board.css', '/board.js', '/favicon.svg', '/manifest.webmanifest'];
4
4
 
5
5
  self.addEventListener('install', (e) => {
@@ -37,16 +37,20 @@ self.addEventListener('message', (e) => {
37
37
  }
38
38
  });
39
39
 
40
- // Els avisos arriben buits: el detall es demana directament a l'ordinador.
40
+ // Normalment l'avís arriba xifrat de punta a punta amb el text dins (RFC 8291).
41
+ // Si arriba buit (nio antic), en demanem el detall a l'ordinador.
41
42
  self.addEventListener('push', (e) => {
42
43
  e.waitUntil((async () => {
43
- let title = 'nio', body = 'Un agent et necessita', session = null;
44
- try {
45
- const cfg = await (await (await caches.open('nio-cfg')).match('/cfg')).json();
46
- const [n] = await (await fetch(`${cfg.url}/api/notices`, { headers: { Authorization: `Bearer ${cfg.token}` } })).json();
47
- if (n) { title = n.title; body = n.body; session = n.session; }
48
- } catch { /* sense detall: avís genèric */ }
49
- await self.registration.showNotification(title, { body, icon: '/icon-192.png', badge: '/icon-192.png', tag: session || 'nio', renotify: true, data: { session } });
44
+ let n = null;
45
+ try { n = e.data ? e.data.json() : null; } catch { n = null; }
46
+ if (!n) {
47
+ try {
48
+ const cfg = await (await (await caches.open('nio-cfg')).match('/cfg')).json();
49
+ [n] = await (await fetch(`${cfg.url}/api/notices`, { headers: { Authorization: `Bearer ${cfg.token}` } })).json();
50
+ } catch { /* sense detall: avís genèric */ }
51
+ }
52
+ const title = n?.title || 'nio', body = n?.body || 'Un agent et necessita', session = n?.session || null;
53
+ await self.registration.showNotification(title, { body, icon: '/icon-192.png', badge: '/badge.png', tag: session || n?.job || 'nio', renotify: true, data: { session, job: n?.job || null } });
50
54
  })());
51
55
  });
52
56