itwillsync 1.5.2 → 1.6.0
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/hub/daemon.js +187 -21
- package/dist/hub/daemon.js.map +1 -1
- package/dist/hub/dashboard/assets/{index-Erqx_a0N.css → index-D6z7Ixhf.css} +1 -1
- package/dist/hub/dashboard/assets/index-DbIKRpLQ.js +2 -0
- package/dist/hub/dashboard/index.html +47 -2
- package/dist/index.js +58 -47
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/hub/dashboard/assets/index-DdOxsvuU.js +0 -2
|
@@ -1 +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)}}
|
|
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)}}#fab-create{position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;background:#e94560;color:#fff;font-size:28px;font-weight:300;border:none;cursor:pointer;box-shadow:0 4px 16px #e9456066;z-index:20;-webkit-tap-highlight-color:transparent;transition:transform .15s,box-shadow .15s;display:flex;align-items:center;justify-content:center;line-height:1}#fab-create:active{transform:scale(.92)}.modal-overlay{position:fixed;inset:0;background:#0a0a14d9;z-index:50;display:flex;align-items:flex-end;justify-content:center;animation:fadeIn .15s ease}.modal-overlay.hidden{display:none}.modal-content{background:#16213e;border-radius:16px 16px 0 0;width:100%;max-width:480px;max-height:85vh;overflow-y:auto;padding:20px;animation:slideUp .2s ease}@keyframes slideUp{0%{transform:translateY(100%)}to{transform:translateY(0)}}.modal-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px}.modal-title{font-size:18px;font-weight:600;color:#f0f0f0}.modal-close{background:none;border:none;color:#707090;font-size:24px;cursor:pointer;padding:4px 8px;line-height:1}.form-label{display:block;font-size:13px;font-weight:500;color:#a0a0b0;margin-bottom:6px;margin-top:16px}.form-label:first-of-type{margin-top:0}.form-input{width:100%;padding:10px 12px;background:#112;border:1px solid #2a2a44;border-radius:8px;color:#f0f0f0;font-size:15px;font-family:Cascadia Code,Fira Code,JetBrains Mono,monospace;outline:none;transition:border-color .15s}.form-input:focus{border-color:#e94560}.form-input.hidden{display:none}.chip-row{display:flex;gap:6px;margin-top:8px;flex-wrap:wrap}.chip{padding:5px 12px;background:#1e1e36;border:1px solid #2a2a44;border-radius:16px;font-size:12px;color:#c0c0d0;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background .15s,border-color .15s;white-space:nowrap;font-family:Cascadia Code,Fira Code,JetBrains Mono,monospace}.chip:active,.chip.selected{background:#e9456026;border-color:#e94560;color:#e94560}.dir-display{padding:10px 12px;background:#112;border:1px solid #2a2a44;border-radius:8px;font-size:13px;font-family:Cascadia Code,Fira Code,JetBrains Mono,monospace;color:#c0c0d0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dir-actions{display:flex;gap:8px;margin-top:10px}.dir-action-btn{flex:1;padding:8px 0;background:#1e1e36;border:1px solid #2a2a44;border-radius:8px;color:#a0a0b0;font-size:13px;font-family:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background .15s}.dir-action-btn:active{background:#2a2a44}.btn-create{width:100%;margin-top:20px;padding:14px;background:#e94560;color:#fff;border:none;border-radius:10px;font-size:16px;font-weight:600;font-family:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:opacity .15s}.btn-create:disabled{opacity:.4;cursor:default}.btn-create:not(:disabled):active{opacity:.8}.create-error{margin-top:12px;padding:8px 12px;background:#e9456026;border-radius:6px;font-size:13px;color:#e94560}.create-error.hidden{display:none}.create-spinner{display:flex;flex-direction:column;align-items:center;gap:12px;padding:32px 0;color:#a0a0b0;font-size:14px}.create-spinner.hidden{display:none}.browse-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}.browse-back{background:none;border:none;color:#a0a0b0;font-size:14px;font-family:inherit;cursor:pointer;padding:4px 0}.browse-select{padding:6px 14px;background:#e94560;color:#fff;border:none;border-radius:6px;font-size:13px;font-weight:500;font-family:inherit;cursor:pointer}.browse-breadcrumb{display:flex;gap:4px;align-items:center;margin-bottom:12px;font-size:13px;font-family:Cascadia Code,Fira Code,JetBrains Mono,monospace;color:#808098;flex-wrap:wrap}.breadcrumb-segment{cursor:pointer;color:#a0a0b0;transition:color .15s}.breadcrumb-segment:hover,.breadcrumb-segment:active{color:#e94560}.breadcrumb-sep{color:#505070}.browse-list{display:flex;flex-direction:column;gap:2px;max-height:50vh;overflow-y:auto}.browse-item{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;background:#112;border-radius:6px;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background .1s}.browse-item:active{background:#1e1e36}.browse-item-name{font-size:14px;color:#d0d0e0;font-family:Cascadia Code,Fira Code,JetBrains Mono,monospace}.browse-item-arrow{color:#505070;font-size:14px}.browse-empty{text-align:center;padding:24px;color:#505070;font-size:13px}.hidden{display:none!important}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))o(s);new MutationObserver(s=>{for(const a of s)if(a.type==="childList")for(const c of a.addedNodes)c.tagName==="LINK"&&c.rel==="modulepreload"&&o(c)}).observe(document,{childList:!0,subtree:!0});function n(s){const a={};return s.integrity&&(a.integrity=s.integrity),s.referrerPolicy&&(a.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?a.credentials="include":s.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function o(s){if(s.ep)return;s.ep=!0;const a=n(s);fetch(s.href,a)}})();function K(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),s=n%60;return`${o}h ${s}m`}function ue(e){const t=e.match(/^\/(?:Users|home)\/[^/]+/)?.[0];return t?"~"+e.slice(t.length):e}function pe(e){return e<1024?`${e} KB`:`${(e/1024).toFixed(1)} MB`}function fe(e,t,n){const o=document.createElement("div");o.className=`session-card${e.status==="attention"?" attention":""}`,o.dataset.sessionId=e.id;const s=K(Date.now()-e.connectedAt),a=ue(e.cwd),c=document.createElement("div");c.className="card-header";const i=document.createElement("div");i.className="card-agent";const f=document.createElement("div");f.className=`agent-dot ${e.status}`;const R=document.createElement("span");R.className="agent-name",R.textContent=e.name||e.agent,i.appendChild(f),i.appendChild(R);const q=document.createElement("span");q.className="card-uptime",q.textContent=s,c.appendChild(i),c.appendChild(q);const U=document.createElement("div");U.className="card-cwd",U.textContent=a;const L=document.createElement("div");L.className="card-preview";const D=document.createElement("pre");D.className="card-preview-text",D.textContent="Waiting for output...",L.appendChild(D),L.addEventListener("click",l=>{l.stopPropagation(),n.onOpen(e)});const N=document.createElement("div");N.className="card-status";const S=document.createElement("span");S.className=`status-badge ${e.status}`,S.textContent=e.status,e.status==="attention"&&(S.style.display="none");const I=document.createElement("span");I.className="attention-badge",I.textContent="Needs your attention",e.status!=="attention"&&(I.style.display="none"),N.appendChild(S),N.appendChild(I);const h=document.createElement("div");h.className="card-actions";const k=document.createElement("button");k.className="action-btn stop",k.textContent="Stop",k.addEventListener("click",l=>{l.stopPropagation(),he(o,e.id,n.onStop)});const B=document.createElement("button");B.className="action-btn rename",B.textContent="Rename",B.addEventListener("click",l=>{l.stopPropagation(),ye(o,e.id,n.onRename)});const x=document.createElement("button");x.className="action-btn info",x.textContent="Info",x.addEventListener("click",l=>{l.stopPropagation(),n.onInfo(e.id)});const P=document.createElement("button");P.className="action-btn open",P.textContent="Open",P.addEventListener("click",l=>{l.stopPropagation(),n.onOpen(e)}),h.appendChild(P),h.appendChild(B),h.appendChild(x),h.appendChild(k);const X=document.createElement("div");return X.className="card-metadata hidden",o.addEventListener("click",()=>{n.onOpen(e)}),o.appendChild(c),o.appendChild(U),o.appendChild(L),o.appendChild(N),o.appendChild(h),o.appendChild(X),o}function he(e,t,n){e.querySelector(".confirm-overlay")?.remove();const o=document.createElement("div");o.className="confirm-overlay";const s=document.createElement("span");s.className="confirm-msg",s.textContent="Stop this session?";const a=document.createElement("button");a.className="confirm-btn yes",a.textContent="Yes",a.addEventListener("click",i=>{i.stopPropagation(),n(t),o.remove()});const c=document.createElement("button");c.className="confirm-btn no",c.textContent="No",c.addEventListener("click",i=>{i.stopPropagation(),o.remove()}),o.addEventListener("click",i=>i.stopPropagation()),o.appendChild(s),o.appendChild(a),o.appendChild(c),e.appendChild(o)}function ye(e,t,n){const o=e.querySelector(".agent-name");if(!o)return;const s=o.textContent||"",a=document.createElement("input");a.className="rename-input",a.type="text",a.value=s;const c=()=>{const i=a.value.trim();i&&i!==s&&n(t,i),o.textContent=i||s,o.style.display="",a.remove()};a.addEventListener("keydown",i=>{i.stopPropagation(),i.key==="Enter"?c():i.key==="Escape"&&(o.textContent=s,o.style.display="",a.remove())}),a.addEventListener("blur",c),a.addEventListener("click",i=>i.stopPropagation()),o.style.display="none",o.parentElement?.insertBefore(a,o.nextSibling),a.focus(),a.select()}function ie(e,t){const n=e.querySelector(".agent-dot"),o=e.querySelector(".status-badge"),s=e.querySelector(".card-uptime"),a=e.querySelector(".agent-name");n&&(n.className=`agent-dot ${t.status}`),o&&(o.className=`status-badge ${t.status}`,o.textContent=t.status),s&&(s.textContent=K(Date.now()-t.connectedAt)),a&&!a.style.display&&(a.textContent=t.name||t.agent);const c=t.status==="attention";o&&(o.style.display=c?"none":"");const i=e.querySelector(".attention-badge");i&&(i.style.display=c?"":"none"),t.status==="attention"?e.classList.add("attention"):e.classList.remove("attention")}function ge(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 Ee(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",pe(t.memoryKB)],["Uptime",K(t.uptimeMs)]];for(const[s,a]of o){const c=document.createElement("div");c.className="meta-row";const i=document.createElement("span");i.className="meta-label",i.textContent=s;const f=document.createElement("span");f.className="meta-value",f.textContent=a,c.appendChild(i),c.appendChild(f),n.appendChild(c)}n.classList.toggle("hidden")}let r=null,Q=!1;function ve(){if(!Q){Q=!0;try{r=new AudioContext,r.state==="suspended"&&r.resume()}catch{}}}function Z(){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(),s=r.createGain();o.frequency.value=880,o.type="sine",s.gain.setValueAtTime(.3,e+.15),s.gain.exponentialRampToValueAtTime(.01,e+.45),o.connect(s),s.connect(r.destination),o.start(e+.15),o.stop(e+.45)}const ee=120*1e3,p=new Map;function te(e){if(p.has(e))return;Z();const t=setTimeout(function n(){Z();const o=p.get(e);o&&(o.timerId=setTimeout(n,ee))},ee);p.set(e,{timerId:t})}function W(e){const t=p.get(e);t&&(clearTimeout(t.timerId),p.delete(e))}function ne(){for(const e of p.values())clearTimeout(e.timerId);p.clear()}const Ce=new URLSearchParams(window.location.search),O=Ce.get("token");if(!O)throw document.body.textContent="Missing authentication token.",new Error("No token in URL");const be=window.location.protocol==="https:"?"wss:":"ws:",we=`${be}//${window.location.host}?token=${O}`,re=window.location.hostname,E=new Map,u=new Map,Le=document.getElementById("session-list"),_=document.getElementById("empty-state"),Ne=document.getElementById("session-count"),oe=document.getElementById("status-dot");let V=null;function $(){ve(),document.removeEventListener("click",$),document.removeEventListener("touchstart",$)}document.addEventListener("click",$);document.addEventListener("touchstart",$);function C(e){d&&d.readyState===WebSocket.OPEN&&d.send(JSON.stringify(e))}const Se={onOpen(e){const t=E.get(e.id)||e;t.status==="attention"&&(C({type:"clear-attention",sessionId:t.id}),W(t.id));const n=window.location.href,o=`http://${re}:${t.port}?token=${t.token}&hub=${encodeURIComponent(n)}`;window.open(o,`session-${t.id}`)},onStop(e){C({type:"stop-session",sessionId:e})},onRename(e,t){C({type:"rename-session",sessionId:e,name:t})},onInfo(e){C({type:"get-metadata",sessionId:e})}};function de(){const e=E.size;Ne.textContent=`${e} session${e!==1?"s":""}`,e===0?_.style.display="flex":_.style.display="none"}function se(e){E.set(e.id,e);const t=fe(e,re,Se);u.set(e.id,t),Le.insertBefore(t,_),de()}function ae(e){E.delete(e);const t=u.get(e);t&&(t.remove(),u.delete(e)),de()}function Ie(e){E.set(e.id,e);const t=u.get(e.id);t&&ie(t,e)}function ke(){for(const[e,t]of E){const n=u.get(e);n&&ie(n,t)}}const Be=document.getElementById("fab-create"),b=document.getElementById("create-modal"),xe=document.getElementById("modal-close"),g=document.getElementById("tool-input"),ce=document.getElementById("tool-chips"),le=document.getElementById("dir-selected"),Pe=document.getElementById("btn-browse"),me=document.getElementById("btn-create-session"),M=document.getElementById("create-error"),v=document.getElementById("create-form-view"),T=document.getElementById("browse-view"),F=document.getElementById("browse-breadcrumb"),y=document.getElementById("browse-list"),$e=document.getElementById("browse-back"),Me=document.getElementById("browse-select"),G=document.getElementById("create-spinner");let w="~",j="~";function m(e,t,n){const o=document.createElement(e);return o.className=t,o.textContent=n,o}function Ae(){b.classList.remove("hidden"),v.classList.remove("hidden"),T.classList.add("hidden"),G.classList.add("hidden"),M.classList.add("hidden"),g.value="",w="~",le.textContent="~",Y(),Oe(),g.focus()}function J(){b.classList.add("hidden")}function Y(){me.disabled=!g.value.trim()}async function Oe(){try{const t=await(await fetch(`/api/tool-history?token=${O}`)).json();ce.replaceChildren();for(const n of t.tools.slice(0,6)){const o=m("span","chip",n);o.addEventListener("click",()=>{g.value=n,Y()}),ce.appendChild(o)}}catch{}}async function z(e){j=e,y.replaceChildren(m("div","browse-empty","Loading..."));try{const n=await(await fetch(`/api/browse?path=${encodeURIComponent(e)}&token=${O}`)).json();if(n.error){y.replaceChildren(m("div","browse-empty",n.error));return}const o=n.path||e;j=o,Te(o);const s=n.entries;if(s.length===0){y.replaceChildren(m("div","browse-empty","No subdirectories"));return}y.replaceChildren();for(const a of s){const c=document.createElement("div");c.className="browse-item",c.appendChild(m("span","browse-item-name",a)),c.appendChild(m("span","browse-item-arrow","›")),c.addEventListener("click",()=>z(`${o}/${a}`)),y.appendChild(c)}}catch{y.replaceChildren(m("div","browse-empty","Failed to load"))}}function Te(e){F.replaceChildren();const t=e.split("/").filter(Boolean);for(let n=0;n<t.length;n++){n>0&&F.appendChild(m("span","breadcrumb-sep"," / "));const o=m("span","breadcrumb-segment",t[n]),s=t.slice(0,n+1).join("/");o.addEventListener("click",()=>z(s)),F.appendChild(o)}}function Re(){const e=g.value.trim();e&&(M.classList.add("hidden"),v.classList.add("hidden"),G.classList.remove("hidden"),C({type:"create-session",tool:e,cwd:w}))}Be.addEventListener("click",Ae);xe.addEventListener("click",J);b.addEventListener("click",e=>{e.target===b&&J()});g.addEventListener("input",Y);me.addEventListener("click",Re);Pe.addEventListener("click",()=>{v.classList.add("hidden"),T.classList.remove("hidden"),z(w)});$e.addEventListener("click",()=>{T.classList.add("hidden"),v.classList.remove("hidden")});Me.addEventListener("click",()=>{w=j,le.textContent=w,T.classList.add("hidden"),v.classList.remove("hidden")});let d=null,A=0;const qe=1e4;function H(){d=new WebSocket(we),d.onopen=()=>{oe.className="connected",A=0,V&&clearInterval(V),V=setInterval(ke,1e4)},d.onmessage=e=>{try{const t=JSON.parse(e.data);switch(t.type){case"sessions":{ne();for(const n of u.keys())ae(n);for(const n of t.sessions)se(n),n.status==="attention"&&te(n.id);break}case"session-added":{se(t.session),b.classList.contains("hidden")||J();break}case"session-removed":{const n=t.sessionId;W(n),ae(n);break}case"session-updated":{const n=t.session;Ie(n),n.status==="attention"?te(n.id):W(n.id);break}case"preview":{const n=u.get(t.sessionId);n&&ge(n,t.lines);break}case"metadata":{const n=u.get(t.sessionId);n&&Ee(n,t.metadata);break}case"session-creating":break;case"session-create-error":{G.classList.add("hidden"),v.classList.remove("hidden"),M.textContent=t.error,M.classList.remove("hidden");break}case"operation-error":{console.warn(`Operation "${t.operation}" failed for session ${t.sessionId}: ${t.error}`);break}}}catch{}},d.onclose=()=>{oe.className="reconnecting",ne(),Ue()},d.onerror=()=>{d?.close()}}function Ue(){const e=Math.min(1e3*Math.pow(1.5,A),qe);A++,setTimeout(H,e)}document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&d?.readyState!==WebSocket.OPEN&&(A=0,H())});H();
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
|
8
8
|
<meta name="theme-color" content="#1a1a2e" />
|
|
9
9
|
<title>itwillsync Dashboard</title>
|
|
10
|
-
<script type="module" crossorigin src="/assets/index-
|
|
11
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
10
|
+
<script type="module" crossorigin src="/assets/index-DbIKRpLQ.js"></script>
|
|
11
|
+
<link rel="stylesheet" crossorigin href="/assets/index-D6z7Ixhf.css">
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
14
14
|
<header id="header">
|
|
@@ -27,5 +27,50 @@
|
|
|
27
27
|
</div>
|
|
28
28
|
</main>
|
|
29
29
|
|
|
30
|
+
<!-- FAB: Create Session -->
|
|
31
|
+
<button id="fab-create" aria-label="New session">+</button>
|
|
32
|
+
|
|
33
|
+
<!-- Create Session Modal -->
|
|
34
|
+
<div id="create-modal" class="modal-overlay hidden">
|
|
35
|
+
<div class="modal-content">
|
|
36
|
+
<div class="modal-header">
|
|
37
|
+
<span class="modal-title">New Session</span>
|
|
38
|
+
<button class="modal-close" id="modal-close">×</button>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<!-- View: Create Form -->
|
|
42
|
+
<div id="create-form-view">
|
|
43
|
+
<label class="form-label">Tool</label>
|
|
44
|
+
<input type="text" id="tool-input" class="form-input" placeholder="e.g. claude, aider, bash" autocomplete="off" autocapitalize="off" />
|
|
45
|
+
<div id="tool-chips" class="chip-row"></div>
|
|
46
|
+
|
|
47
|
+
<label class="form-label">Working Directory</label>
|
|
48
|
+
<div id="dir-selected" class="dir-display">~</div>
|
|
49
|
+
<div class="dir-actions">
|
|
50
|
+
<button class="dir-action-btn" id="btn-browse">Browse...</button>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<div id="create-error" class="create-error hidden"></div>
|
|
54
|
+
<button id="btn-create-session" class="btn-create" disabled>Create Session</button>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<!-- View: Directory Browser -->
|
|
58
|
+
<div id="browse-view" class="hidden">
|
|
59
|
+
<div class="browse-header">
|
|
60
|
+
<button class="browse-back" id="browse-back">← Back</button>
|
|
61
|
+
<button class="browse-select" id="browse-select">Select this folder</button>
|
|
62
|
+
</div>
|
|
63
|
+
<div id="browse-breadcrumb" class="browse-breadcrumb"></div>
|
|
64
|
+
<div id="browse-list" class="browse-list"></div>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<!-- Loading spinner shown during session creation -->
|
|
68
|
+
<div id="create-spinner" class="create-spinner hidden">
|
|
69
|
+
<div class="spinner"></div>
|
|
70
|
+
<span>Creating session...</span>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
|
|
30
75
|
</body>
|
|
31
76
|
</html>
|
package/dist/index.js
CHANGED
|
@@ -4640,7 +4640,8 @@ function parseArgs(argv) {
|
|
|
4640
4640
|
local: false,
|
|
4641
4641
|
hubInfo: false,
|
|
4642
4642
|
hubStop: false,
|
|
4643
|
-
hubStatus: false
|
|
4643
|
+
hubStatus: false,
|
|
4644
|
+
headless: false
|
|
4644
4645
|
};
|
|
4645
4646
|
const args = argv.slice(2);
|
|
4646
4647
|
if (args.length > 0 && args[0] === "setup") {
|
|
@@ -4685,6 +4686,9 @@ function parseArgs(argv) {
|
|
|
4685
4686
|
} else if (arg === "--hub-status") {
|
|
4686
4687
|
options.hubStatus = true;
|
|
4687
4688
|
i++;
|
|
4689
|
+
} else if (arg === "--headless") {
|
|
4690
|
+
options.headless = true;
|
|
4691
|
+
i++;
|
|
4688
4692
|
} else if (arg === "--help" || arg === "-h") {
|
|
4689
4693
|
printHelp();
|
|
4690
4694
|
process.exit(0);
|
|
@@ -4869,7 +4873,7 @@ async function main() {
|
|
|
4869
4873
|
console.error("Error: Cannot use both --tailscale and --local.\n");
|
|
4870
4874
|
process.exit(1);
|
|
4871
4875
|
}
|
|
4872
|
-
if (!configExists() && !options.tailscale && !options.local && process.stdin.isTTY) {
|
|
4876
|
+
if (!options.headless && !configExists() && !options.tailscale && !options.local && process.stdin.isTTY) {
|
|
4873
4877
|
await runSetupWizard();
|
|
4874
4878
|
}
|
|
4875
4879
|
if (options.command.length === 0) {
|
|
@@ -4877,6 +4881,7 @@ async function main() {
|
|
|
4877
4881
|
printHelp();
|
|
4878
4882
|
process.exit(1);
|
|
4879
4883
|
}
|
|
4884
|
+
const headless = options.headless;
|
|
4880
4885
|
const config = loadConfig();
|
|
4881
4886
|
let networkingMode = "local";
|
|
4882
4887
|
if (options.tailscale) {
|
|
@@ -4930,58 +4935,64 @@ async function main() {
|
|
|
4930
4935
|
console.warn(` Warning: Failed to register with hub: ${err.message}`);
|
|
4931
4936
|
}
|
|
4932
4937
|
}
|
|
4933
|
-
|
|
4934
|
-
if (
|
|
4935
|
-
|
|
4938
|
+
let sleepGuard = null;
|
|
4939
|
+
if (!headless) {
|
|
4940
|
+
let handleResize2 = function() {
|
|
4941
|
+
if (process.stdout.columns && process.stdout.rows) {
|
|
4942
|
+
server.resizeFromLocal(process.stdout.columns, process.stdout.rows);
|
|
4943
|
+
}
|
|
4944
|
+
};
|
|
4945
|
+
var handleResize = handleResize2;
|
|
4946
|
+
const dashboardUrl = hubConfig ? `http://${ip}:${HUB_EXTERNAL_PORT}?token=${hubConfig.masterToken}` : null;
|
|
4947
|
+
if (dashboardUrl && !options.noQr) {
|
|
4948
|
+
if (!isFirstSession) {
|
|
4949
|
+
console.log(`
|
|
4950
|
+
Session "${cmd}" registered with hub.`);
|
|
4951
|
+
}
|
|
4952
|
+
displayQR(dashboardUrl);
|
|
4953
|
+
} else if (dashboardUrl) {
|
|
4936
4954
|
console.log(`
|
|
4937
4955
|
Session "${cmd}" registered with hub.`);
|
|
4956
|
+
console.log(` Dashboard: ${dashboardUrl}`);
|
|
4957
|
+
console.log("");
|
|
4958
|
+
} else if (!options.noQr) {
|
|
4959
|
+
const directUrl = `http://${ip}:${port}?token=${token}`;
|
|
4960
|
+
displayQR(directUrl);
|
|
4938
4961
|
}
|
|
4939
|
-
|
|
4940
|
-
|
|
4941
|
-
console.log(`
|
|
4942
|
-
|
|
4943
|
-
console.log(`
|
|
4962
|
+
sleepGuard = preventSleep();
|
|
4963
|
+
console.log(` Server listening on ${host}:${port}`);
|
|
4964
|
+
console.log(` Running: ${options.command.join(" ")}`);
|
|
4965
|
+
console.log(` PID: ${ptyManager.pid}`);
|
|
4966
|
+
console.log(` Sleep prevention: ${sleepGuard ? "active" : "unavailable"}`);
|
|
4944
4967
|
console.log("");
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
displayQR(directUrl);
|
|
4948
|
-
}
|
|
4949
|
-
const sleepGuard = preventSleep();
|
|
4950
|
-
console.log(` Server listening on ${host}:${port}`);
|
|
4951
|
-
console.log(` Running: ${options.command.join(" ")}`);
|
|
4952
|
-
console.log(` PID: ${ptyManager.pid}`);
|
|
4953
|
-
console.log(` Sleep prevention: ${sleepGuard ? "active" : "unavailable"}`);
|
|
4954
|
-
console.log("");
|
|
4955
|
-
if (process.stdin.isTTY) {
|
|
4956
|
-
process.stdin.setRawMode(true);
|
|
4957
|
-
}
|
|
4958
|
-
process.stdin.resume();
|
|
4959
|
-
process.stdin.setEncoding("utf-8");
|
|
4960
|
-
process.stdin.on("data", (data) => {
|
|
4961
|
-
if (process.stdout.columns && process.stdout.rows) {
|
|
4962
|
-
if (process.stdout.columns !== ptyManager.cols || process.stdout.rows !== ptyManager.rows) {
|
|
4963
|
-
server.resizeFromLocal(process.stdout.columns, process.stdout.rows);
|
|
4964
|
-
}
|
|
4965
|
-
}
|
|
4966
|
-
ptyManager.write(data);
|
|
4967
|
-
});
|
|
4968
|
-
ptyManager.onData((data) => {
|
|
4969
|
-
process.stdout.write(data);
|
|
4970
|
-
});
|
|
4971
|
-
function handleResize() {
|
|
4972
|
-
if (process.stdout.columns && process.stdout.rows) {
|
|
4973
|
-
server.resizeFromLocal(process.stdout.columns, process.stdout.rows);
|
|
4968
|
+
if (process.stdin.isTTY) {
|
|
4969
|
+
process.stdin.setRawMode(true);
|
|
4974
4970
|
}
|
|
4971
|
+
process.stdin.resume();
|
|
4972
|
+
process.stdin.setEncoding("utf-8");
|
|
4973
|
+
process.stdin.on("data", (data) => {
|
|
4974
|
+
if (process.stdout.columns && process.stdout.rows) {
|
|
4975
|
+
if (process.stdout.columns !== ptyManager.cols || process.stdout.rows !== ptyManager.rows) {
|
|
4976
|
+
server.resizeFromLocal(process.stdout.columns, process.stdout.rows);
|
|
4977
|
+
}
|
|
4978
|
+
}
|
|
4979
|
+
ptyManager.write(data);
|
|
4980
|
+
});
|
|
4981
|
+
ptyManager.onData((data) => {
|
|
4982
|
+
process.stdout.write(data);
|
|
4983
|
+
});
|
|
4984
|
+
process.stdout.on("resize", handleResize2);
|
|
4985
|
+
handleResize2();
|
|
4975
4986
|
}
|
|
4976
|
-
process.stdout.on("resize", handleResize);
|
|
4977
|
-
handleResize();
|
|
4978
4987
|
async function cleanup() {
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
|
|
4984
|
-
process.stdin.
|
|
4988
|
+
if (!headless) {
|
|
4989
|
+
process.stdout.write(
|
|
4990
|
+
"\x1B[>0u\x1B[?2004l\x1B[?1000l\x1B[?1002l\x1B[?1003l\x1B[?1006l\x1B[?25h\x1B[?1049l"
|
|
4991
|
+
// Exit alternate screen buffer (if active)
|
|
4992
|
+
);
|
|
4993
|
+
if (process.stdin.isTTY) {
|
|
4994
|
+
process.stdin.setRawMode(false);
|
|
4995
|
+
}
|
|
4985
4996
|
}
|
|
4986
4997
|
if (heartbeatInterval) {
|
|
4987
4998
|
clearInterval(heartbeatInterval);
|