itwillsync 1.2.1 → 1.3.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.
@@ -0,0 +1,2 @@
1
+ (function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))o(a);new MutationObserver(a=>{for(const s of a)if(s.type==="childList")for(const i of s.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&o(i)}).observe(document,{childList:!0,subtree:!0});function n(a){const s={};return a.integrity&&(s.integrity=a.integrity),a.referrerPolicy&&(s.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?s.credentials="include":a.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function o(a){if(a.ep)return;a.ep=!0;const s=n(a);fetch(a.href,s)}})();function B(e){const t=Math.floor(e/1e3);if(t<60)return`${t}s`;const n=Math.floor(t/60);if(n<60)return`${n}m`;const o=Math.floor(n/60),a=n%60;return`${o}h ${a}m`}function z(e){const t=e.match(/^\/(?:Users|home)\/[^/]+/)?.[0];return t?"~"+e.slice(t.length):e}function X(e){return e<1024?`${e} KB`:`${(e/1024).toFixed(1)} MB`}function H(e,t,n){const o=document.createElement("div");o.className=`session-card${e.status==="attention"?" attention":""}`,o.dataset.sessionId=e.id;const a=B(Date.now()-e.connectedAt),s=z(e.cwd),i=document.createElement("div");i.className="card-header";const c=document.createElement("div");c.className="card-agent";const p=document.createElement("div");p.className=`agent-dot ${e.status}`;const P=document.createElement("span");P.className="agent-name",P.textContent=e.name||e.agent,c.appendChild(p),c.appendChild(P);const k=document.createElement("span");k.className="card-uptime",k.textContent=a,i.appendChild(c),i.appendChild(k);const I=document.createElement("div");I.className="card-cwd",I.textContent=s;const h=document.createElement("div");h.className="card-preview";const $=document.createElement("pre");$.className="card-preview-text",$.textContent="Waiting for output...",h.appendChild($),h.addEventListener("click",l=>{l.stopPropagation(),n.onOpen(e)});const g=document.createElement("div");g.className="card-status";const E=document.createElement("span");E.className=`status-badge ${e.status}`,E.textContent=e.status,e.status==="attention"&&(E.style.display="none");const v=document.createElement("span");v.className="attention-badge",v.textContent="Needs your attention",e.status!=="attention"&&(v.style.display="none"),g.appendChild(E),g.appendChild(v);const f=document.createElement("div");f.className="card-actions";const C=document.createElement("button");C.className="action-btn stop",C.textContent="Stop",C.addEventListener("click",l=>{l.stopPropagation(),Q(o,e.id,n.onStop)});const w=document.createElement("button");w.className="action-btn rename",w.textContent="Rename",w.addEventListener("click",l=>{l.stopPropagation(),Z(o,e.id,n.onRename)});const N=document.createElement("button");N.className="action-btn info",N.textContent="Info",N.addEventListener("click",l=>{l.stopPropagation(),n.onInfo(e.id)});const b=document.createElement("button");b.className="action-btn open",b.textContent="Open",b.addEventListener("click",l=>{l.stopPropagation(),n.onOpen(e)}),f.appendChild(b),f.appendChild(w),f.appendChild(N),f.appendChild(C);const R=document.createElement("div");return R.className="card-metadata hidden",o.addEventListener("click",()=>{n.onOpen(e)}),o.appendChild(i),o.appendChild(I),o.appendChild(h),o.appendChild(g),o.appendChild(f),o.appendChild(R),o}function Q(e,t,n){e.querySelector(".confirm-overlay")?.remove();const o=document.createElement("div");o.className="confirm-overlay";const a=document.createElement("span");a.className="confirm-msg",a.textContent="Stop this session?";const s=document.createElement("button");s.className="confirm-btn yes",s.textContent="Yes",s.addEventListener("click",c=>{c.stopPropagation(),n(t),o.remove()});const i=document.createElement("button");i.className="confirm-btn no",i.textContent="No",i.addEventListener("click",c=>{c.stopPropagation(),o.remove()}),o.addEventListener("click",c=>c.stopPropagation()),o.appendChild(a),o.appendChild(s),o.appendChild(i),e.appendChild(o)}function Z(e,t,n){const o=e.querySelector(".agent-name");if(!o)return;const a=o.textContent||"",s=document.createElement("input");s.className="rename-input",s.type="text",s.value=a;const i=()=>{const c=s.value.trim();c&&c!==a&&n(t,c),o.textContent=c||a,o.style.display="",s.remove()};s.addEventListener("keydown",c=>{c.stopPropagation(),c.key==="Enter"?i():c.key==="Escape"&&(o.textContent=a,o.style.display="",s.remove())}),s.addEventListener("blur",i),s.addEventListener("click",c=>c.stopPropagation()),o.style.display="none",o.parentElement?.insertBefore(s,o.nextSibling),s.focus(),s.select()}function G(e,t){const n=e.querySelector(".agent-dot"),o=e.querySelector(".status-badge"),a=e.querySelector(".card-uptime"),s=e.querySelector(".agent-name");n&&(n.className=`agent-dot ${t.status}`),o&&(o.className=`status-badge ${t.status}`,o.textContent=t.status),a&&(a.textContent=B(Date.now()-t.connectedAt)),s&&!s.style.display&&(s.textContent=t.name||t.agent);const i=t.status==="attention";o&&(o.style.display=i?"none":"");const c=e.querySelector(".attention-badge");c&&(c.style.display=i?"":"none"),t.status==="attention"?e.classList.add("attention"):e.classList.remove("attention")}function ee(e,t){const n=e.querySelector(".card-preview-text");n&&(t.length>0?(n.textContent=t.join(`
2
+ `),n.classList.remove("empty")):(n.textContent="Waiting for output...",n.classList.add("empty")))}function te(e,t){const n=e.querySelector(".card-metadata");if(!n)return;for(;n.firstChild;)n.removeChild(n.firstChild);const o=[["PID",String(t.pid)],["Agent",t.agent],["Port",String(t.port)],["Directory",t.cwd],["Memory",X(t.memoryKB)],["Uptime",B(t.uptimeMs)]];for(const[a,s]of o){const i=document.createElement("div");i.className="meta-row";const c=document.createElement("span");c.className="meta-label",c.textContent=a;const p=document.createElement("span");p.className="meta-value",p.textContent=s,i.appendChild(c),i.appendChild(p),n.appendChild(i)}n.classList.toggle("hidden")}let r=null,q=!1;function ne(){if(!q){q=!0;try{r=new AudioContext,r.state==="suspended"&&r.resume()}catch{}}}function U(){if(!r)return;r.state==="suspended"&&r.resume();const e=r.currentTime,t=r.createOscillator(),n=r.createGain();t.frequency.value=587.33,t.type="sine",n.gain.setValueAtTime(.3,e),n.gain.exponentialRampToValueAtTime(.01,e+.3),t.connect(n),n.connect(r.destination),t.start(e),t.stop(e+.3);const o=r.createOscillator(),a=r.createGain();o.frequency.value=880,o.type="sine",a.gain.setValueAtTime(.3,e+.15),a.gain.exponentialRampToValueAtTime(.01,e+.45),o.connect(a),a.connect(r.destination),o.start(e+.15),o.stop(e+.45)}const D=120*1e3,u=new Map;function _(e){if(u.has(e))return;U();const t=setTimeout(function n(){U();const o=u.get(e);o&&(o.timerId=setTimeout(n,D))},D);u.set(e,{timerId:t})}function A(e){const t=u.get(e);t&&(clearTimeout(t.timerId),u.delete(e))}function V(){for(const e of u.values())clearTimeout(e.timerId);u.clear()}const oe=new URLSearchParams(window.location.search),J=oe.get("token");if(!J)throw document.body.textContent="Missing authentication token.",new Error("No token in URL");const ae=window.location.protocol==="https:"?"wss:":"ws:",se=`${ae}//${window.location.host}?token=${J}`,Y=window.location.hostname,y=new Map,m=new Map,ce=document.getElementById("session-list"),O=document.getElementById("empty-state"),ie=document.getElementById("session-count"),W=document.getElementById("status-dot");let M=null;function x(){ne(),document.removeEventListener("click",x),document.removeEventListener("touchstart",x)}document.addEventListener("click",x);document.addEventListener("touchstart",x);function S(e){d&&d.readyState===WebSocket.OPEN&&d.send(JSON.stringify(e))}const re={onOpen(e){const t=y.get(e.id)||e;t.status==="attention"&&(S({type:"clear-attention",sessionId:t.id}),A(t.id));const n=window.location.href,o=`http://${Y}:${t.port}?token=${t.token}&hub=${encodeURIComponent(n)}`;window.open(o,"_blank")},onStop(e){S({type:"stop-session",sessionId:e})},onRename(e,t){S({type:"rename-session",sessionId:e,name:t})},onInfo(e){S({type:"get-metadata",sessionId:e})}};function j(){const e=y.size;ie.textContent=`${e} session${e!==1?"s":""}`,e===0?O.style.display="flex":O.style.display="none"}function F(e){y.set(e.id,e);const t=H(e,Y,re);m.set(e.id,t),ce.insertBefore(t,O),j()}function K(e){y.delete(e);const t=m.get(e);t&&(t.remove(),m.delete(e)),j()}function de(e){y.set(e.id,e);const t=m.get(e.id);t&&G(t,e)}function le(){for(const[e,t]of y){const n=m.get(e);n&&G(n,t)}}let d=null,L=0;const me=1e4;function T(){d=new WebSocket(se),d.onopen=()=>{W.className="connected",L=0,M&&clearInterval(M),M=setInterval(le,1e4)},d.onmessage=e=>{try{const t=JSON.parse(e.data);switch(t.type){case"sessions":{V();for(const n of m.keys())K(n);for(const n of t.sessions)F(n),n.status==="attention"&&_(n.id);break}case"session-added":{F(t.session);break}case"session-removed":{const n=t.sessionId;A(n),K(n);break}case"session-updated":{const n=t.session;de(n),n.status==="attention"?_(n.id):A(n.id);break}case"preview":{const n=m.get(t.sessionId);n&&ee(n,t.lines);break}case"metadata":{const n=m.get(t.sessionId);n&&te(n,t.metadata);break}case"operation-error":{console.warn(`Operation "${t.operation}" failed for session ${t.sessionId}: ${t.error}`);break}}}catch{}},d.onclose=()=>{W.className="reconnecting",V(),ue()},d.onerror=()=>{d?.close()}}function ue(){const e=Math.min(1e3*Math.pow(1.5,L),me);L++,setTimeout(T,e)}document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&d?.readyState!==WebSocket.OPEN&&(L=0,T())});T();
@@ -0,0 +1 @@
1
+ *{margin:0;padding:0;box-sizing:border-box}html,body{height:100%;width:100%;background:#1a1a2e;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:#e0e0e0;overflow-x:hidden;-webkit-overflow-scrolling:touch}#header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;background:#16213e;border-bottom:1px solid #0f3460;position:sticky;top:0;z-index:10}.header-left{display:flex;align-items:center;gap:10px}.logo{font-size:16px;font-weight:700;color:#e94560;letter-spacing:-.5px}#status-dot{width:8px;height:8px;border-radius:50%;background:#e74c3c;transition:background .3s ease}#status-dot.connected{background:#2ecc71}#status-dot.reconnecting{background:#f39c12;animation:pulse 1s infinite}#session-count{font-size:13px;color:#a0a0b0}#session-list{padding:12px 12px 80px;display:flex;flex-direction:column;gap:12px}#empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:60vh;color:#606080;text-align:center;gap:8px}#empty-state .empty-icon{font-size:48px;margin-bottom:8px;opacity:.5}#empty-state p{font-size:16px}#empty-state .empty-hint{font-size:13px;color:#505070}#empty-state code{background:#252540;padding:2px 8px;border-radius:4px;font-family:Cascadia Code,Fira Code,JetBrains Mono,monospace;font-size:12px;color:#e94560}.session-card{background:#16213e;border:1px solid #0f3460;border-radius:12px;padding:14px 16px;cursor:pointer;transition:transform .15s ease,border-color .2s ease;-webkit-tap-highlight-color:transparent}.session-card:active{transform:scale(.98)}.session-card:hover{border-color:#e94560}.session-card.attention{border-color:#e94560;animation:attention-glow 2s ease-in-out infinite}@keyframes attention-glow{0%,to{box-shadow:0 0 #e9456000}50%{box-shadow:0 0 12px 2px #e945604d}}.card-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}.card-agent{display:flex;align-items:center;gap:8px}.agent-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}.agent-dot.active{background:#2ecc71}.agent-dot.idle{background:#f39c12}.agent-dot.attention{background:#e94560;animation:pulse 1s infinite}.agent-name{font-size:15px;font-weight:600;color:#f0f0f0}.card-uptime{font-size:12px;color:#707090;font-variant-numeric:tabular-nums}.card-cwd{font-size:12px;color:#808098;margin-bottom:10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-family:Cascadia Code,Fira Code,JetBrains Mono,monospace}.card-preview{background:#112;border-radius:6px;padding:8px 10px;margin-bottom:10px;overflow:hidden;min-height:24px;max-height:90px}.card-preview-text{font-family:Cascadia Code,Fira Code,JetBrains Mono,monospace;font-size:11px;line-height:1.4;color:#a0a0b0;white-space:pre;overflow:hidden;text-overflow:ellipsis;margin:0}.card-preview-text.empty{color:#505070;font-style:italic}.card-status{display:flex;align-items:center;gap:6px;font-size:12px;color:#a0a0b0}.status-badge{padding:2px 8px;border-radius:10px;font-size:11px;font-weight:500;text-transform:uppercase;letter-spacing:.5px}.status-badge.active{background:#2ecc7126;color:#2ecc71}.status-badge.idle{background:#f39c1226;color:#f39c12}.status-badge.attention{background:#e9456026;color:#e94560}.attention-badge{padding:2px 8px;border-radius:10px;font-size:11px;font-weight:600;background:#e9456033;color:#e94560;animation:attention-pulse 2s ease-in-out infinite}@keyframes attention-pulse{0%,to{opacity:1}50%{opacity:.6}}.card-actions{display:flex;gap:6px;margin-top:10px;padding-top:10px;border-top:1px solid #0f3460}.action-btn{flex:1;padding:6px 0;border:1px solid #2a2a44;border-radius:6px;background:#1e1e36;color:#a0a0b0;font-size:12px;font-weight:500;font-family:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background .15s,color .15s}.action-btn:active{background:#2a2a44}.action-btn.open{color:#2ecc71;border-color:#2ecc714d}.action-btn.stop{color:#e94560;border-color:#e945604d}.action-btn.stop:active{background:#e9456026}.confirm-overlay{display:flex;align-items:center;justify-content:center;gap:10px;padding:10px;margin-top:8px;background:#2d1810;border:1px solid #e94560;border-radius:8px;animation:fadeIn .15s ease}.confirm-msg{font-size:13px;color:#f0f0f0;flex:1}.confirm-btn{padding:5px 14px;border:none;border-radius:5px;font-size:12px;font-weight:600;font-family:inherit;cursor:pointer}.confirm-btn.yes{background:#e94560;color:#fff}.confirm-btn.no{background:#2a2a44;color:#a0a0b0}.rename-input{background:#112;border:1px solid #e94560;border-radius:4px;color:#f0f0f0;font-size:15px;font-weight:600;font-family:inherit;padding:2px 6px;outline:none;width:120px}.card-metadata{margin-top:8px;padding:8px 10px;background:#112;border-radius:6px;animation:fadeIn .2s ease}.card-metadata.hidden{display:none}.meta-row{display:flex;justify-content:space-between;padding:3px 0;font-size:11px}.meta-label{color:#707090;font-weight:500}.meta-value{color:#c0c0d0;font-family:Cascadia Code,Fira Code,JetBrains Mono,monospace;font-size:11px;text-align:right;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media(min-width:768px){#session-list{max-width:600px;margin:0 auto}}@keyframes pulse{0%,to{opacity:1}50%{opacity:.4}}@keyframes fadeIn{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.session-card{animation:fadeIn .3s ease}#reconnect-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#1a1a2ef2;display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:100;color:#e0e0e0;font-size:16px;gap:12px}#reconnect-overlay .spinner{width:32px;height:32px;border:3px solid #0f3460;border-top-color:#e94560;border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}
@@ -0,0 +1,31 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, user-scalable=no" />
6
+ <meta name="apple-mobile-web-app-capable" content="yes" />
7
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
8
+ <meta name="theme-color" content="#1a1a2e" />
9
+ <title>itwillsync Dashboard</title>
10
+ <script type="module" crossorigin src="/assets/index-DgUZUPW_.js"></script>
11
+ <link rel="stylesheet" crossorigin href="/assets/index-Erqx_a0N.css">
12
+ </head>
13
+ <body>
14
+ <header id="header">
15
+ <div class="header-left">
16
+ <span class="logo">itwillsync</span>
17
+ <span id="status-dot"></span>
18
+ </div>
19
+ <span id="session-count">0 sessions</span>
20
+ </header>
21
+
22
+ <main id="session-list">
23
+ <div id="empty-state">
24
+ <div class="empty-icon">&#x1F4BB;</div>
25
+ <p>No active sessions</p>
26
+ <p class="empty-hint">Start an agent with <code>itwillsync -- claude</code></p>
27
+ </div>
28
+ </main>
29
+
30
+ </body>
31
+ </html>