toyon 0.12.0 → 0.14.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.
Files changed (29) hide show
  1. package/README.md +1 -1
  2. package/dist/bridge.js +1 -1
  3. package/dist/cli.js +48 -66
  4. package/dist/daemon.js +1108 -845
  5. package/dist/shell/assets/{Editor-ofBOHWJt.js → Editor-Gzhl3Oqu.js} +3 -3
  6. package/dist/shell/assets/{XTerm-C_Gv5uo2.js → XTerm-D6TL52yQ.js} +1 -1
  7. package/dist/shell/assets/{cssMode-LqxC-sXw.js → cssMode-BfNm0a39.js} +1 -1
  8. package/dist/shell/assets/{freemarker2-DUqPZFAL.js → freemarker2-DhiwR6KJ.js} +1 -1
  9. package/dist/shell/assets/{grammar-CFa79rtH.js → grammar-thv9InXF.js} +1 -1
  10. package/dist/shell/assets/{handlebars-CF9us5mA.js → handlebars-BbkhCZXb.js} +1 -1
  11. package/dist/shell/assets/{html-SO575qLW.js → html-yzhYlR33.js} +1 -1
  12. package/dist/shell/assets/{htmlMode-XUsZRqmU.js → htmlMode-DPICAUY8.js} +1 -1
  13. package/dist/shell/assets/index-BYBd8f7P.css +1 -0
  14. package/dist/shell/assets/index-DJBEbneL.js +267 -0
  15. package/dist/shell/assets/{javascript-4ER2NhcO.js → javascript-D9eBjR4g.js} +1 -1
  16. package/dist/shell/assets/{jsonMode-D-UOjsYN.js → jsonMode-cNulMi5B.js} +1 -1
  17. package/dist/shell/assets/{liquid-CMXc0SdF.js → liquid-C_SKIx1n.js} +1 -1
  18. package/dist/shell/assets/{lspLanguageFeatures-D4Z0LyWk.js → lspLanguageFeatures-DNU8BRHj.js} +1 -1
  19. package/dist/shell/assets/{mdx-Dc4E4gPJ.js → mdx-Bt4opbQO.js} +1 -1
  20. package/dist/shell/assets/{python-DhCnlsga.js → python-Crb-EuXe.js} +1 -1
  21. package/dist/shell/assets/{razor-CGRu_Zyc.js → razor-D3BlkbYO.js} +1 -1
  22. package/dist/shell/assets/{tsMode-BoDg-EAl.js → tsMode-BYuAS95U.js} +1 -1
  23. package/dist/shell/assets/{xml-Dl50xhA0.js → xml-G5xafDqw.js} +1 -1
  24. package/dist/shell/assets/{yaml-CoqiVhBi.js → yaml-CRp1x3nR.js} +1 -1
  25. package/dist/shell/index.html +17 -10
  26. package/dist/shell/manifest.json +1 -1
  27. package/package.json +1 -1
  28. package/dist/shell/assets/index-BYJYiHrs.css +0 -1
  29. package/dist/shell/assets/index-Brx-QOIQ.js +0 -266
package/README.md CHANGED
@@ -48,7 +48,7 @@ npm i -g toyon
48
48
  toyon ~/projects/app
49
49
  ```
50
50
 
51
- `toyon .` opens the folder you are in and `toyon --help` lists the rest. A global install keeps itself updated; `TOYON_UPDATES=off` stops it. Run outside a project, Toyon opens with none: describe a new one in a sentence, or give the project picker a git URL to clone.
51
+ `toyon .` opens the folder you are in and `toyon --help` lists the rest. The install button in the top bar makes Toyon an app of its own in Chrome, Arc, Brave or Edge, with a Dock icon and no browser bar; from then on `toyon .` opens that. A global install keeps itself updated; `TOYON_UPDATES=off` stops it. Run outside a project, Toyon opens with none: describe a new one in a sentence, or give the project picker a git URL to clone.
52
52
 
53
53
  You need:
54
54
 
package/dist/bridge.js CHANGED
@@ -1 +1 @@
1
- var b=[{id:"quick-open",key:"p"},{id:"commands",key:"p",shift:!0,bareAlias:"F1"},{id:"search",key:"f",shift:!0},{id:"chats",key:"g"},{id:"changes",key:"b",ctrlAlias:{key:"g",shift:!0}},{id:"files",key:"e",shift:!0},{id:"panel-tab-prev",key:"ArrowLeft",alt:!0,textKeeps:!0},{id:"panel-tab-next",key:"ArrowRight",alt:!0,textKeeps:!0},{id:"composer",key:"l"},{id:"rail",key:"k",shift:!0},{id:"keys",key:","},{id:"terminal",key:"j",ctrlAlias:{key:"`"}},{id:"design",key:"d"},{id:"term-tab",key:"`",ctrl:!0,shift:!0},{id:"pick",key:"e"},{id:"inspect",key:"i"},{id:"zen",key:"."},{id:"new",key:"k",aliases:["n"]},{id:"worktree",key:"1-9"},{id:"wt-prev",key:"ArrowUp",alt:!0,ctrlAlias:{key:"Tab",shift:!0},cmdShiftAlias:["[","{"]},{id:"wt-next",key:"ArrowDown",alt:!0,ctrlAlias:{key:"Tab"},cmdShiftAlias:["]","}"]},{id:"wt-unseen-prev",key:"ArrowUp",alt:!0,shift:!0},{id:"wt-unseen-next",key:"ArrowDown",alt:!0,shift:!0},{id:"wt-archive",key:"Backspace",alt:!0,textKeeps:!0,emptyGives:!0},{id:"mark-unread",key:"u",alt:!0,textKeeps:!0},{id:"project",key:"o",ctrlAlias:{key:"r",hostOnly:!0},cmdShiftAlias:["o"]},{id:"refs",key:"g",shift:!0},{id:"routes",key:"u"},{id:"reload",key:"r"},{id:"back",key:"ArrowLeft",textKeeps:!0},{id:"forward",key:"ArrowRight",textKeeps:!0},{id:"close",key:"w"}],I=new Set(["zen","close","back","forward"]);function W(e,{guest:t=!1}={}){if(e.altKey){if(e.metaKey||e.ctrlKey)return null;let r=b.find((i)=>i.alt&&!!i.shift===e.shiftKey&&(i.key===e.key||i.key.length===1&&e.code===`Key${i.key.toUpperCase()}`));return r&&r.id!=="worktree"?{id:r.id}:null}if(!e.metaKey&&!e.ctrlKey){if(e.shiftKey||t)return null;let r=b.find((i)=>i.bareAlias===e.key);return r&&r.id!=="worktree"?{id:r.id}:null}if(!!e.ctrlKey===e.metaKey)return null;let n=e.key.length===1?e.key.toLowerCase():e.key;if(e.metaKey&&!e.shiftKey&&n>="1"&&n<="9")return{id:"worktree",digit:Number(n)};for(let r of b){if(r.id==="worktree")continue;let i=r.ctrlAlias;if(i&&e.ctrlKey&&i.key===n&&!!i.shift===e.shiftKey&&!(t&&i.hostOnly))return{id:r.id};if(e.metaKey&&e.shiftKey&&r.cmdShiftAlias?.includes(n))return{id:r.id};if(r.alt)continue;if(e.ctrlKey&&!r.ctrl||!!r.shift!==e.shiftKey)continue;if(r.key===n||r.aliases?.includes(n))return{id:r.id}}return null}function j(e){if(e.altKey||e.key.toLowerCase()!=="s")return!1;return!!e.ctrlKey!==e.metaKey}function G(e){let t=b.find((n)=>n.id===e);if(!t)throw Error(`unknown chord ${e}`);return t}function X(e){let t=e;if(!t?.tagName)return!1;if(t.isContentEditable||t.tagName==="TEXTAREA")return!0;return t.tagName==="INPUT"&&!["button","checkbox","radio","range","submit","reset"].includes(t.type??"")}var te=Symbol.for("react.forward_ref"),ne=Symbol.for("react.memo");function U(e){if(e._debugSource?.fileName)return{file:e._debugSource.fileName,line:e._debugSource.lineNumber};let t=e._debugStack?.stack;if(t){let n=t.match(/https?:\/\/[^/]+(\/src\/[^)\s?]+)(?:\?[^:)\s]*)?:(\d+):\d+/);if(n?.[1])return{file:n[1],line:Number(n[2])||void 0}}return null}function T(e){for(let t=e;t;t=t.return){let n=U(t);if(n)return n}return null}function C(e){if(typeof e==="function")return e.displayName||e.name||null;let t=e;if(t?.$$typeof===te)return t.displayName||C(t.render);if(t?.$$typeof===ne)return t.displayName||C(t.type);return null}var re=(e)=>typeof e.type==="string"||e.tag===6,ie=(e,t)=>!!e&&(e===t||!!e.stateNode&&e.stateNode===t.stateNode);function oe(e){let t=null,n=(r)=>{for(let i=r.child??null;i;i=i.sibling??null)if(re(i)){if(t)return!1;t=i}else if(!n(i))return!1;return!0};return n(e)?t:null}function le(e){for(let t=e;t;t=t.return){let n=U(t);if(n)return t._debugOwner===null?null:n}return null}function L(e){let t=T(e),n=null,r=null,i=!1;for(let o=e;o;o=o.return){let s=C(o.type);if(!s)continue;let l=!!e&&ie(oe(o),e),a=le(o);if(n&&!(l&&a))break;if(n=s,r=a,i=l,!l)break}if(r&&t&&r.file===t.file&&r.line===t.line)r=null;return{src:t,comp:n,call:r,wraps:i}}function N({src:e,call:t,wraps:n},r){let i=n?t:e,o=n?e:t;return(r?o??i:i??o)??null}if(window.__toyonBridge)throw Error("Toyon bridge already installed");window.__toyonBridge=!0;var w=window.__toyonShellOrigins??[],M=null,c=(e)=>{try{let t=M?[M]:w.length?w:["*"];for(let n of t)window.parent.postMessage({__toyon:!0,...e},n)}catch{}};c({type:"loaded",url:location.href,title:document.title});var x="#fa891e",z="#1d2021";window.addEventListener("vite:afterUpdate",()=>c({type:"hmr"}));window.addEventListener("error",(e)=>{c({type:"page-error",message:String(e.message),source:e.filename,line:e.lineno})});window.addEventListener("unhandledrejection",(e)=>{c({type:"page-error",message:`unhandled rejection: ${String(e.reason)}`})});var K=()=>c({type:"navigated",url:location.href,title:document.title}),se=history.pushState.bind(history);history.pushState=(...e)=>{se(...e),K()};var ae=history.replaceState.bind(history);history.replaceState=(...e)=>{ae(...e),K()};window.addEventListener("popstate",K);window.addEventListener("hashchange",K);var _=document.title;if(document.head)new MutationObserver(()=>{if(document.title===_)return;_=document.title,c({type:"title",title:_})}).observe(document.head,{childList:!0,subtree:!0,characterData:!0});var Y=!1,P=null;window.addEventListener("keyup",(e)=>{if(window.__toyonShell||e.key!==P)return;P=null,c({type:"key",key:e.key,meta:!1,up:!0})},!0);window.addEventListener("keydown",(e)=>{if(window.__toyonShell)return;if(j(e))e.preventDefault();let t=W(e,{guest:!0});if(t&&G(t.id).textKeeps&&X(e.target))return;if(Y){if(!t||!I.has(t.id))return}else if(e.key==="Escape"){c({type:"key",key:"Escape",meta:!1});return}else if(!t)return;e.preventDefault(),e.stopPropagation(),c({type:"key",key:e.key,code:e.code,meta:e.metaKey,ctrl:e.ctrlKey,shift:e.shiftKey,alt:e.altKey}),P=e.altKey?"Alt":e.ctrlKey?"Control":e.metaKey?"Meta":null},!0);var R=()=>c({type:"focus",gesture:navigator.userActivation?.isActive??!0});window.addEventListener("focusin",R,!0);window.addEventListener("focus",R);if(document.hasFocus()&&document.activeElement&&document.activeElement!==document.body)R();var Z=(e)=>!e.defaultPrevented&&!!e.dataTransfer?.types.includes("Files");window.addEventListener("dragover",(e)=>{if(!Z(e))return;if(e.preventDefault(),e.dataTransfer)e.dataTransfer.dropEffect="copy";c({type:"drag-files"})});window.addEventListener("drop",(e)=>{if(!Z(e))return;e.preventDefault(),c({type:"drop-files",files:Array.from(e.dataTransfer?.files??[])})});function B(e){for(let t of Object.keys(e))if(t.startsWith("__reactFiber$"))return e[t]??null;return null}var p=null;function ce(){if(p?.isConnected)return p;return p=document.createElement("div"),p.style.cssText="position:fixed;inset:0;pointer-events:none;z-index:2147483647;",document.documentElement.appendChild(p),p}function m(){if(p)p.innerHTML=""}var F=20;function v(e,t,n=!0){let r=document.createElement("div");if(r.style.cssText=`position:fixed;left:${e.left}px;top:${e.top}px;width:${e.width}px;height:${e.height}px;outline:2px solid ${x};outline-offset:-1px;${n?`background:${x}14;`:""}border-radius:2px;`,t){let i=e.top>=F,o=e.bottom+F<=window.innerHeight;if(t.style.top=i?`${-F}px`:o?`${e.height+4}px`:"2px",!i&&!o)t.style.left="2px";r.appendChild(t)}if(ce().appendChild(r),t){let i=t.getBoundingClientRect(),o=i.right-(window.innerWidth-2);if(o>0){let s=Number.parseFloat(t.style.left||"0");t.style.left=`${s-Math.min(o,Math.max(0,i.left-2))}px`}}}function g(e,t){let n=document.createElement("div");if(n.textContent=e,n.style.cssText=`position:absolute;left:0;background:${x};color:${z};font:11px -apple-system,sans-serif;padding:1px 6px;border-radius:3px;white-space:nowrap;`,t){let r=document.createElement("span");r.textContent=` ${t}`,r.style.opacity="0.55",n.appendChild(r)}return n}var E=!1,d=null,y=!1,f=!1,h=!1,O=(e)=>`${Q(e.file)}${e.line?`:${e.line}`:""}`;function A(e){d=e,m();let t=L(B(e)),{src:n,comp:r,call:i}=t,o=N(t,f),s=o===n?i:n,l=y!==h,a=(...k)=>k.filter(Boolean).join(" ")||void 0,u=l?o?g(`open ${O(o)}`,a(s&&`⇧ ${O(s)}`,h&&"⌥ chat")):g(`find ${q(e)}`,a(h&&"⌥ chat")):g(r?`<${r} />${o?` · ${O(o)}`:""}`:q(e),a(!h&&"⌥ code"));v(e.getBoundingClientRect(),u,l)}function q(e){let t=e.tagName.toLowerCase(),n=e.classList[0];return(e.id?`${t}#${e.id}`:n?`${t}.${n}`:t).slice(0,48)}var ue=new Set(["name","placeholder","aria-label","title","alt","for","href","type","role","src"]);function de(e){let t="";for(let r of Array.from(e.childNodes))if(r.nodeType===Node.TEXT_NODE)t+=r.textContent??"";let n=[];for(let r of Array.from(e.attributes)){if(n.length===12)break;if(r.value&&(ue.has(r.name)||r.name.startsWith("data-")))n.push([r.name.slice(0,40),r.value.slice(0,200)])}return{tag:e.tagName.toLowerCase().slice(0,40),id:e.id.slice(0,200),classes:Array.from(e.classList).slice(0,16).map((r)=>r.slice(0,120)),text:t.replace(/\s+/g," ").trim().slice(0,200),attrs:n}}function V(e){let t=document.elementFromPoint(e.clientX,e.clientY);if(!t)return;let n=t!==d||e.altKey!==y||e.shiftKey!==f;if(y=e.altKey,f=e.shiftKey,n)A(t)}function J(e){e.preventDefault(),e.stopPropagation();let t=d??document.elementFromPoint(e.clientX,e.clientY),n=L(t?B(t):null),{src:r,comp:i,call:o}=n;f=e.shiftKey;let s=N(n,f),l=e.altKey!==h;if(D(),!t)return;c({type:"picked",verb:l?"code":"chat",site:s&&s===o?"call":"source",component:i,file:r?.file??null,line:r?.line??null,callFile:o?.file??null,callLine:o?.line??null,selector:ye(t),tag:t.tagName.toLowerCase(),classes:t.className?.toString?.().slice(0,200)??"",text:t.textContent?.trim().slice(0,120)??"",html:t.outerHTML.slice(0,600),route:location.pathname+location.search,element:de(t)})}function S(e){if(e.key==="Escape"&&e.type==="keydown"){e.preventDefault(),e.stopPropagation(),D(),c({type:"pick-cancel"});return}if((e.key==="Alt"||e.key==="Shift")&&(y!==e.altKey||f!==e.shiftKey)){if(y=e.altKey,f=e.shiftKey,d)A(d)}}function fe(e){if(h=e,E){if(d)A(d);return}E=!0,d=null,y=!1,f=!1,document.addEventListener("mousemove",V,!0),document.addEventListener("click",J,!0),document.addEventListener("keydown",S,!0),document.addEventListener("keyup",S,!0),document.documentElement.style.cursor="crosshair"}function D(){E=!1,h=!1,d=null,y=!1,f=!1,m(),document.removeEventListener("mousemove",V,!0),document.removeEventListener("click",J,!0),document.removeEventListener("keydown",S,!0),document.removeEventListener("keyup",S,!0),document.documentElement.style.cursor=""}function ye(e){let t=[],n=e;for(let r=0;n&&n!==document.documentElement&&r<6;r++){if(n.id){t.unshift(`#${CSS.escape(n.id)}`);break}let i=n.parentElement,o=i?Array.from(i.children).indexOf(n)+1:1;t.unshift(`${n.tagName.toLowerCase()}:nth-child(${o})`),n=i}return t.join(" > ")}function Q(e){let t=e.lastIndexOf("/src/");return t>=0?e.slice(t+1):e.split("/").slice(-2).join("/")}function pe(e,t){return e.endsWith(t)||t.endsWith(Q(e))}function he(e,t){let n=[],r=0;for(let s of Array.from(document.querySelectorAll("*"))){let l=T(B(s));if(l)r++;if(!l||!pe(l.file,e))continue;n.push({el:s,line:l.line??-1})}if(!t||t.length===0)return{matched:n,fromFile:n,withSource:r};if(t.length===1&&t[0][0]===t[0][1]){let s=t[0][0],l=n.filter((u)=>u.line===s);if(l.length>0)return{matched:l,fromFile:n,withSource:r};let a=n.filter((u)=>u.line>0&&u.line<s);return a.sort((u,k)=>k.line-u.line),{matched:a.slice(0,1),fromFile:n,withSource:r}}return{matched:n.filter((s)=>t.some(([l,a])=>s.line>=l-8&&s.line<=a+1)),fromFile:n,withSource:r}}function me(e,t){m();let{matched:n,fromFile:r,withSource:i}=he(e,t),o=0;for(let{el:s}of n){if(o>=40)break;let l=s.getBoundingClientRect();if(l.width>0&&l.height>0)v(l),o++}if(o===0)c({type:"highlight-miss",path:e,fileMatched:r.length,withSource:i,ranges:t})}window.addEventListener("message",(e)=>{if(e.source!==window.parent)return;if(w.length&&!w.includes(e.origin))return;let t=e.data;if(!t?.__toyon)return;M=e.origin;let n=t;switch(n.type){case"reload":location.reload();break;case"navigate":if(/^[/?#]/.test(n.path))location.assign(n.path);break;case"back":case"forward":{let r=window.navigation;if((n.type==="back"?r?.canGoBack:r?.canGoForward)===!1)break;if(n.type==="back")history.back();else history.forward();break}case"links":{let r=new Set,i=[];for(let o of Array.from(document.querySelectorAll("a[href]"))){if(o.origin!==location.origin||o.target==="_blank"||o.hasAttribute("download"))continue;let s=o.pathname+(o.hash.startsWith("#/")?o.hash:"");if(s.startsWith("/__toyon")||r.has(s))continue;r.add(s);let l=(o.textContent||o.getAttribute("aria-label")||"").replace(/\s+/g," ").trim();if(i.push({path:s,text:l.slice(0,80)}),i.length>=200)break}c({type:"links",links:i});break}case"pick-start":fe(n.verb==="code");break;case"pick-mods":if(E&&(y!==n.alt||f!==n.shift)){if(y=n.alt,f=n.shift,d)A(d)}break;case"pick-cancel":D();break;case"highlight-file":me(n.path,n.ranges??null);break;case"highlight-computed":{m();let r=/^(color|font|line-height|letter-|text-|word-)/,i=(l)=>{if(/^(INPUT|TEXTAREA|SELECT)$/.test(l.tagName))return!0;for(let a=l.firstChild;a;a=a.nextSibling)if(a.nodeType===3&&a.textContent&&a.textContent.trim())return!0;return!1},o=document.querySelectorAll("*"),s=!0;for(let l=0;l<o.length;l++){let a=getComputedStyle(o[l]),u=([H,ee])=>a.getPropertyValue(H)===ee&&(!r.test(H)||i(o[l]));if(n.match==="any"?n.props.some(u):n.props.every(u))v(o[l].getBoundingClientRect(),s&&n.label?g(n.label):void 0),s=!1}break}case"highlight-selector":{m();try{let r=document.querySelectorAll(n.selector);for(let i=0;i<r.length;i++)v(r[i].getBoundingClientRect(),i===0&&n.label?g(n.label):void 0)}catch{}break}case"highlight-clear":m();break;case"zen":Y=n.on;break;case"theme":if(/^#[0-9a-f]{3,8}$/i.test(n.accent))x=n.accent;if(/^#[0-9a-f]{3,8}$/i.test(n.accentFg))z=n.accentFg;break}});
1
+ var b=[{id:"quick-open",key:"p"},{id:"commands",key:"p",shift:!0,bareAlias:"F1"},{id:"search",key:"f",shift:!0},{id:"chats",key:"g"},{id:"changes",key:"b",ctrlAlias:{key:"g",shift:!0}},{id:"files",key:"e",shift:!0},{id:"panel-tab-prev",key:"ArrowLeft",alt:!0,textKeeps:!0},{id:"panel-tab-next",key:"ArrowRight",alt:!0,textKeeps:!0},{id:"composer",key:"l"},{id:"rail",key:"k",shift:!0},{id:"keys",key:","},{id:"terminal",key:"j",ctrlAlias:{key:"`"}},{id:"design",key:"d"},{id:"term-tab",key:"`",ctrl:!0,shift:!0},{id:"pick",key:"e"},{id:"inspect",key:"i"},{id:"zen",key:"."},{id:"new",key:"k",aliases:["n"]},{id:"worktree",key:"1-9"},{id:"wt-prev",key:"ArrowUp",alt:!0,ctrlAlias:{key:"Tab",shift:!0},cmdShiftAlias:["[","{"]},{id:"wt-next",key:"ArrowDown",alt:!0,ctrlAlias:{key:"Tab"},cmdShiftAlias:["]","}"]},{id:"wt-unseen-prev",key:"ArrowUp",alt:!0,shift:!0},{id:"wt-unseen-next",key:"ArrowDown",alt:!0,shift:!0},{id:"wt-archive",key:"Backspace",alt:!0,textKeeps:!0,emptyGives:!0},{id:"mark-unread",key:"u",alt:!0,textKeeps:!0},{id:"project",key:"o",ctrlAlias:{key:"r",hostOnly:!0},cmdShiftAlias:["o"]},{id:"refs",key:"g",shift:!0},{id:"routes",key:"u"},{id:"reload",key:"r"},{id:"back",key:"ArrowLeft",textKeeps:!0},{id:"forward",key:"ArrowRight",textKeeps:!0},{id:"close",key:"w"}],j=new Set(["zen","close","back","forward"]);function G(e,{guest:t=!1}={}){if(e.altKey){if(e.metaKey||e.ctrlKey)return null;let r=b.find((i)=>i.alt&&!!i.shift===e.shiftKey&&(i.key===e.key||i.key.length===1&&e.code===`Key${i.key.toUpperCase()}`));return r&&r.id!=="worktree"?{id:r.id}:null}if(!e.metaKey&&!e.ctrlKey){if(e.shiftKey||t)return null;let r=b.find((i)=>i.bareAlias===e.key);return r&&r.id!=="worktree"?{id:r.id}:null}if(!!e.ctrlKey===e.metaKey)return null;let n=e.key.length===1?e.key.toLowerCase():e.key;if(e.metaKey&&!e.shiftKey&&n>="1"&&n<="9")return{id:"worktree",digit:Number(n)};for(let r of b){if(r.id==="worktree")continue;let i=r.ctrlAlias;if(i&&e.ctrlKey&&i.key===n&&!!i.shift===e.shiftKey&&!(t&&i.hostOnly))return{id:r.id};if(e.metaKey&&e.shiftKey&&r.cmdShiftAlias?.includes(n))return{id:r.id};if(r.alt)continue;if(e.ctrlKey&&!r.ctrl||!!r.shift!==e.shiftKey)continue;if(r.key===n||r.aliases?.includes(n))return{id:r.id}}return null}function X(e){if(e.altKey||e.key.toLowerCase()!=="s")return!1;return!!e.ctrlKey!==e.metaKey}function U(e){let t=b.find((n)=>n.id===e);if(!t)throw Error(`unknown chord ${e}`);return t}function q(e){let t=e;if(!t?.tagName)return!1;if(t.isContentEditable||t.tagName==="TEXTAREA")return!0;return t.tagName==="INPUT"&&!["button","checkbox","radio","range","submit","reset"].includes(t.type??"")}var re=Symbol.for("react.forward_ref"),ie=Symbol.for("react.memo");function z(e){if(e._debugSource?.fileName)return{file:e._debugSource.fileName,line:e._debugSource.lineNumber};let t=e._debugStack?.stack;if(t){let n=t.match(/https?:\/\/[^/]+(\/src\/[^)\s?]+)(?:\?[^:)\s]*)?:(\d+):\d+/);if(n?.[1])return{file:n[1],line:Number(n[2])||void 0}}return null}function L(e){for(let t=e;t;t=t.return){let n=z(t);if(n)return n}return null}function C(e){if(typeof e==="function")return e.displayName||e.name||null;let t=e;if(t?.$$typeof===re)return t.displayName||C(t.render);if(t?.$$typeof===ie)return t.displayName||C(t.type);return null}var oe=(e)=>typeof e.type==="string"||e.tag===6,le=(e,t)=>!!e&&(e===t||!!e.stateNode&&e.stateNode===t.stateNode);function se(e){let t=null,n=(r)=>{for(let i=r.child??null;i;i=i.sibling??null)if(oe(i)){if(t)return!1;t=i}else if(!n(i))return!1;return!0};return n(e)?t:null}function ae(e){for(let t=e;t;t=t.return){let n=z(t);if(n)return t._debugOwner===null?null:n}return null}function N(e){let t=L(e),n=null,r=null,i=!1;for(let o=e;o;o=o.return){let s=C(o.type);if(!s)continue;let l=!!e&&le(se(o),e),a=ae(o);if(n&&!(l&&a))break;if(n=s,r=a,i=l,!l)break}if(r&&t&&r.file===t.file&&r.line===t.line)r=null;return{src:t,comp:n,call:r,wraps:i}}function _({src:e,call:t,wraps:n},r){let i=n?t:e,o=n?e:t;return(r?o??i:i??o)??null}if(window.__toyonBridge)throw Error("Toyon bridge already installed");window.__toyonBridge=!0;var v=window.__toyonShellOrigins??[],P=null,c=(e)=>{try{let t=P?[P]:v.length?v:["*"];for(let n of t)window.parent.postMessage({__toyon:!0,...e},n)}catch{}};c({type:"loaded",url:location.href,title:document.title});var E="#fa891e",Z="#1d2021";window.addEventListener("vite:afterUpdate",()=>c({type:"hmr"}));window.addEventListener("error",(e)=>{c({type:"page-error",message:String(e.message),source:e.filename,line:e.lineno})});window.addEventListener("unhandledrejection",(e)=>{c({type:"page-error",message:`unhandled rejection: ${String(e.reason)}`})});var K=()=>c({type:"navigated",url:location.href,title:document.title}),ce=history.pushState.bind(history);history.pushState=(...e)=>{ce(...e),B(),K()};var ue=history.replaceState.bind(history);history.replaceState=(...e)=>{ue(...e),K()};window.addEventListener("popstate",K);window.addEventListener("hashchange",K);var de=window.navigation,g=null;function B(){g=de?.currentEntry?.index??null}B();window.addEventListener("popstate",()=>{let e=g;B();let t=e===null||g===null||e===g?void 0:g<e?"back":"forward";c({type:"traversed",...t?{dir:t}:{}})});var fe=performance.getEntriesByType("navigation")[0];if(fe?.type==="back_forward")c({type:"traversed"});window.addEventListener("pageshow",(e)=>{if(e.persisted)c({type:"traversed"})});var F=document.title;if(document.head)new MutationObserver(()=>{if(document.title===F)return;F=document.title,c({type:"title",title:F})}).observe(document.head,{childList:!0,subtree:!0,characterData:!0});var V=!1,R=null;window.addEventListener("keyup",(e)=>{if(window.__toyonShell||e.key!==R)return;R=null,c({type:"key",key:e.key,meta:!1,up:!0})},!0);window.addEventListener("keydown",(e)=>{if(window.__toyonShell)return;if(X(e))e.preventDefault();let t=G(e,{guest:!0});if(t&&U(t.id).textKeeps&&q(e.target))return;if(V){if(!t||!j.has(t.id))return}else if(e.key==="Escape"){c({type:"key",key:"Escape",meta:!1});return}else if(!t)return;e.preventDefault(),e.stopPropagation(),c({type:"key",key:e.key,code:e.code,meta:e.metaKey,ctrl:e.ctrlKey,shift:e.shiftKey,alt:e.altKey}),R=e.altKey?"Alt":e.ctrlKey?"Control":e.metaKey?"Meta":null},!0);var D=()=>c({type:"focus",gesture:navigator.userActivation?.isActive??!0});window.addEventListener("focusin",D,!0);window.addEventListener("focus",D);if(document.hasFocus()&&document.activeElement&&document.activeElement!==document.body)D();var J=(e)=>!e.defaultPrevented&&!!e.dataTransfer?.types.includes("Files");window.addEventListener("dragover",(e)=>{if(!J(e))return;if(e.preventDefault(),e.dataTransfer)e.dataTransfer.dropEffect="copy";c({type:"drag-files"})});window.addEventListener("drop",(e)=>{if(!J(e))return;e.preventDefault(),c({type:"drop-files",files:Array.from(e.dataTransfer?.files??[])})});function H(e){for(let t of Object.keys(e))if(t.startsWith("__reactFiber$"))return e[t]??null;return null}var y=null;function pe(){if(y?.isConnected)return y;return y=document.createElement("div"),y.style.cssText="position:fixed;inset:0;pointer-events:none;z-index:2147483647;",document.documentElement.appendChild(y),y}function m(){if(y)y.innerHTML=""}var O=20;function x(e,t,n=!0){let r=document.createElement("div");if(r.style.cssText=`position:fixed;left:${e.left}px;top:${e.top}px;width:${e.width}px;height:${e.height}px;outline:2px solid ${E};outline-offset:-1px;${n?`background:${E}14;`:""}border-radius:2px;`,t){let i=e.top>=O,o=e.bottom+O<=window.innerHeight;if(t.style.top=i?`${-O}px`:o?`${e.height+4}px`:"2px",!i&&!o)t.style.left="2px";r.appendChild(t)}if(pe().appendChild(r),t){let i=t.getBoundingClientRect(),o=i.right-(window.innerWidth-2);if(o>0){let s=Number.parseFloat(t.style.left||"0");t.style.left=`${s-Math.min(o,Math.max(0,i.left-2))}px`}}}function k(e,t){let n=document.createElement("div");if(n.textContent=e,n.style.cssText=`position:absolute;left:0;background:${E};color:${Z};font:11px -apple-system,sans-serif;padding:1px 6px;border-radius:3px;white-space:nowrap;`,t){let r=document.createElement("span");r.textContent=` ${t}`,r.style.opacity="0.55",n.appendChild(r)}return n}var S=!1,d=null,p=!1,f=!1,h=!1,M=(e)=>`${te(e.file)}${e.line?`:${e.line}`:""}`;function T(e){d=e,m();let t=N(H(e)),{src:n,comp:r,call:i}=t,o=_(t,f),s=o===n?i:n,l=p!==h,a=(...w)=>w.filter(Boolean).join(" ")||void 0,u=l?o?k(`open ${M(o)}`,a(s&&`⇧ ${M(s)}`,h&&"⌥ chat")):k(`find ${Y(e)}`,a(h&&"⌥ chat")):k(r?`<${r} />${o?` · ${M(o)}`:""}`:Y(e),a(!h&&"⌥ code"));x(e.getBoundingClientRect(),u,l)}function Y(e){let t=e.tagName.toLowerCase(),n=e.classList[0];return(e.id?`${t}#${e.id}`:n?`${t}.${n}`:t).slice(0,48)}var ye=new Set(["name","placeholder","aria-label","title","alt","for","href","type","role","src"]);function he(e){let t="";for(let r of Array.from(e.childNodes))if(r.nodeType===Node.TEXT_NODE)t+=r.textContent??"";let n=[];for(let r of Array.from(e.attributes)){if(n.length===12)break;if(r.value&&(ye.has(r.name)||r.name.startsWith("data-")))n.push([r.name.slice(0,40),r.value.slice(0,200)])}return{tag:e.tagName.toLowerCase().slice(0,40),id:e.id.slice(0,200),classes:Array.from(e.classList).slice(0,16).map((r)=>r.slice(0,120)),text:t.replace(/\s+/g," ").trim().slice(0,200),attrs:n}}function Q(e){let t=document.elementFromPoint(e.clientX,e.clientY);if(!t)return;let n=t!==d||e.altKey!==p||e.shiftKey!==f;if(p=e.altKey,f=e.shiftKey,n)T(t)}function ee(e){e.preventDefault(),e.stopPropagation();let t=d??document.elementFromPoint(e.clientX,e.clientY),n=N(t?H(t):null),{src:r,comp:i,call:o}=n;f=e.shiftKey;let s=_(n,f),l=e.altKey!==h;if(I(),!t)return;c({type:"picked",verb:l?"code":"chat",site:s&&s===o?"call":"source",component:i,file:r?.file??null,line:r?.line??null,callFile:o?.file??null,callLine:o?.line??null,selector:ge(t),tag:t.tagName.toLowerCase(),classes:t.className?.toString?.().slice(0,200)??"",text:t.textContent?.trim().slice(0,120)??"",html:t.outerHTML.slice(0,600),route:location.pathname+location.search,element:he(t)})}function A(e){if(e.key==="Escape"&&e.type==="keydown"){e.preventDefault(),e.stopPropagation(),I(),c({type:"pick-cancel"});return}if((e.key==="Alt"||e.key==="Shift")&&(p!==e.altKey||f!==e.shiftKey)){if(p=e.altKey,f=e.shiftKey,d)T(d)}}function me(e){if(h=e,S){if(d)T(d);return}S=!0,d=null,p=!1,f=!1,document.addEventListener("mousemove",Q,!0),document.addEventListener("click",ee,!0),document.addEventListener("keydown",A,!0),document.addEventListener("keyup",A,!0),document.documentElement.style.cursor="crosshair"}function I(){S=!1,h=!1,d=null,p=!1,f=!1,m(),document.removeEventListener("mousemove",Q,!0),document.removeEventListener("click",ee,!0),document.removeEventListener("keydown",A,!0),document.removeEventListener("keyup",A,!0),document.documentElement.style.cursor=""}function ge(e){let t=[],n=e;for(let r=0;n&&n!==document.documentElement&&r<6;r++){if(n.id){t.unshift(`#${CSS.escape(n.id)}`);break}let i=n.parentElement,o=i?Array.from(i.children).indexOf(n)+1:1;t.unshift(`${n.tagName.toLowerCase()}:nth-child(${o})`),n=i}return t.join(" > ")}function te(e){let t=e.lastIndexOf("/src/");return t>=0?e.slice(t+1):e.split("/").slice(-2).join("/")}function ke(e,t){return e.endsWith(t)||t.endsWith(te(e))}function we(e,t){let n=[],r=0;for(let s of Array.from(document.querySelectorAll("*"))){let l=L(H(s));if(l)r++;if(!l||!ke(l.file,e))continue;n.push({el:s,line:l.line??-1})}if(!t||t.length===0)return{matched:n,fromFile:n,withSource:r};if(t.length===1&&t[0][0]===t[0][1]){let s=t[0][0],l=n.filter((u)=>u.line===s);if(l.length>0)return{matched:l,fromFile:n,withSource:r};let a=n.filter((u)=>u.line>0&&u.line<s);return a.sort((u,w)=>w.line-u.line),{matched:a.slice(0,1),fromFile:n,withSource:r}}return{matched:n.filter((s)=>t.some(([l,a])=>s.line>=l-8&&s.line<=a+1)),fromFile:n,withSource:r}}function be(e,t){m();let{matched:n,fromFile:r,withSource:i}=we(e,t),o=0;for(let{el:s}of n){if(o>=40)break;let l=s.getBoundingClientRect();if(l.width>0&&l.height>0)x(l),o++}if(o===0)c({type:"highlight-miss",path:e,fileMatched:r.length,withSource:i,ranges:t})}window.addEventListener("message",(e)=>{if(e.source!==window.parent)return;if(v.length&&!v.includes(e.origin))return;let t=e.data;if(!t?.__toyon)return;P=e.origin;let n=t;switch(n.type){case"reload":location.reload();break;case"navigate":if(/^[/?#]/.test(n.path))location.assign(n.path);break;case"back":case"forward":{let r=window.navigation;if((n.type==="back"?r?.canGoBack:r?.canGoForward)===!1)break;if(n.type==="back")history.back();else history.forward();break}case"links":{let r=new Set,i=[];for(let o of Array.from(document.querySelectorAll("a[href]"))){if(o.origin!==location.origin||o.target==="_blank"||o.hasAttribute("download"))continue;let s=o.pathname+(o.hash.startsWith("#/")?o.hash:"");if(s.startsWith("/__toyon")||r.has(s))continue;r.add(s);let l=(o.textContent||o.getAttribute("aria-label")||"").replace(/\s+/g," ").trim();if(i.push({path:s,text:l.slice(0,80)}),i.length>=200)break}c({type:"links",links:i});break}case"pick-start":me(n.verb==="code");break;case"pick-mods":if(S&&(p!==n.alt||f!==n.shift)){if(p=n.alt,f=n.shift,d)T(d)}break;case"pick-cancel":I();break;case"highlight-file":be(n.path,n.ranges??null);break;case"highlight-computed":{m();let r=/^(color|font|line-height|letter-|text-|word-)/,i=(l)=>{if(/^(INPUT|TEXTAREA|SELECT)$/.test(l.tagName))return!0;for(let a=l.firstChild;a;a=a.nextSibling)if(a.nodeType===3&&a.textContent&&a.textContent.trim())return!0;return!1},o=document.querySelectorAll("*"),s=!0;for(let l=0;l<o.length;l++){let a=getComputedStyle(o[l]),u=([W,ne])=>a.getPropertyValue(W)===ne&&(!r.test(W)||i(o[l]));if(n.match==="any"?n.props.some(u):n.props.every(u))x(o[l].getBoundingClientRect(),s&&n.label?k(n.label):void 0),s=!1}break}case"highlight-selector":{m();try{let r=document.querySelectorAll(n.selector);for(let i=0;i<r.length;i++)x(r[i].getBoundingClientRect(),i===0&&n.label?k(n.label):void 0)}catch{}break}case"highlight-clear":m();break;case"zen":V=n.on;break;case"theme":if(/^#[0-9a-f]{3,8}$/i.test(n.accent))E=n.accent;if(/^#[0-9a-f]{3,8}$/i.test(n.accentFg))Z=n.accentFg;break}});
package/dist/cli.js CHANGED
@@ -7,7 +7,7 @@ import { join as join7, resolve } from "path";
7
7
  // package.json
8
8
  var package_default = {
9
9
  name: "toyon",
10
- version: "0.12.0",
10
+ version: "0.14.0",
11
11
  description: "Toyon is where coding agents work on your web app while you check each change by using it. Every chat gets its own running copy with a live preview.",
12
12
  license: "MIT",
13
13
  type: "module",
@@ -71,25 +71,6 @@ import { join as join2 } from "path";
71
71
  var KNOCK_TTL_MS = 5 * 60000;
72
72
  var machineLink = (host) => `https://${host}/`;
73
73
  var isTailnetName = (host) => host.endsWith(".ts.net");
74
- var listed = (names) => names.length < 2 ? names[0] ?? "" : `${names.slice(0, -1).join(", ")} and ${names.at(-1)}`;
75
- function tailnetLine(phones) {
76
- if (phones === null)
77
- return { ok: true, text: "Your phone needs Tailscale on, signed in to the same tailnet." };
78
- if (phones.length === 0) {
79
- return {
80
- ok: false,
81
- text: "No phone has joined your tailnet. Install Tailscale on it and sign in to the same account first."
82
- };
83
- }
84
- const on = phones.filter((p) => p.online).map((p) => p.name);
85
- if (on.length > 0)
86
- return { ok: true, text: `${listed(on)} ${on.length > 1 ? "are" : "is"} on your tailnet.` };
87
- const off = phones.map((p) => p.name);
88
- return {
89
- ok: false,
90
- text: `${listed(off)} ${off.length > 1 ? "are" : "is"} not answering on your tailnet. Check Tailscale is on there.`
91
- };
92
- }
93
74
 
94
75
  // ../shared/src/daemon.ts
95
76
  var APP_SCHEME = "toyon";
@@ -5392,8 +5373,9 @@ function post(route, token, body) {
5392
5373
  body: JSON.stringify(body)
5393
5374
  });
5394
5375
  }
5376
+ var shellOrigins = ["http://toyon.localhost", `http://toyon.localhost:${port}`];
5395
5377
  function shellUrl(token, branded) {
5396
- return branded ? `http://toyon.localhost/#token=${token}` : `http://toyon.localhost:${port}/#token=${token}`;
5378
+ return `${branded ? shellOrigins[0] : shellOrigins[1]}/#token=${token}`;
5397
5379
  }
5398
5380
 
5399
5381
  // src/openUrl.ts
@@ -5423,14 +5405,15 @@ function profilesOf(browser) {
5423
5405
  function pwaStillInstalled(browser, id) {
5424
5406
  return profilesOf(browser).some((p) => existsSync3(join3(p, "Web Applications", "Manifest Resources", id)));
5425
5407
  }
5426
- function findPwaId(browser, manifestId) {
5408
+ function findPwaId(browser) {
5427
5409
  const cache = join3(pwaCacheDir, `${browser.replace(/\W+/g, "-")}.id`);
5428
5410
  if (existsSync3(cache)) {
5429
5411
  const id = readFileSync2(cache, "utf8").trim();
5430
5412
  if (/^[a-p]{32}$/.test(id) && pwaStillInstalled(browser, id))
5431
5413
  return id;
5432
5414
  }
5433
- const re = new RegExp(`web_apps-dt-([a-p]{32})[\\s\\S]{0,16}?${manifestId.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&")}`);
5415
+ const ids = shellOrigins.map((o) => `${o}/`.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&")).join("|");
5416
+ const re = new RegExp(`web_apps-dt-([a-p]{32})[\\s\\S]{0,16}?(?:${ids})`);
5434
5417
  for (const p of profilesOf(browser)) {
5435
5418
  const dir = join3(p, "Sync Data", "LevelDB");
5436
5419
  if (!existsSync3(dir))
@@ -5448,29 +5431,28 @@ function findPwaId(browser, manifestId) {
5448
5431
  }
5449
5432
  return null;
5450
5433
  }
5451
- function showAppWindow(daemon) {
5452
- const appUrl = shellUrl(daemon.token, false);
5453
- console.log(`toyon: app window (${appUrl.split("#")[0]})`);
5454
- if (openAppWindow(appUrl))
5434
+ function openShell(daemon) {
5435
+ console.log(`toyon: ${daemon.url}`);
5436
+ const found = process.platform === "darwin" ? launchInstalledApp() : "none";
5437
+ if (found === "launched")
5455
5438
  return;
5456
- console.log("no Chromium browser found; opening in default browser");
5457
5439
  openUrl(daemon.url);
5440
+ if (found === "uninstalled")
5441
+ console.log("tip: install Toyon as an app from the top bar; toyon then opens in its own window");
5458
5442
  }
5459
- function openAppWindow(appUrl) {
5460
- const manifestId = new URL("/", appUrl).href;
5443
+ function launchInstalledApp() {
5444
+ let seen = false;
5461
5445
  for (const app of CHROMIUMS) {
5462
- if (spawnSync("open", ["-Ra", app]).status === 0) {
5463
- const id = findPwaId(app, manifestId);
5464
- const flag = id ? `--app-id=${id}` : `--app=${appUrl}`;
5465
- spawn3("open", ["-na", app, "--args", flag], { stdio: "ignore" }).unref();
5466
- if (!id) {
5467
- console.log(`tip: install Toyon as an app (browser menu, then Install, or the install button in the top bar when opened in a tab)`);
5468
- console.log(` once installed, it gets a native-style title bar; \`toyon --app\` then launches the installed app`);
5469
- }
5470
- return true;
5471
- }
5446
+ if (spawnSync("open", ["-Ra", app]).status !== 0)
5447
+ continue;
5448
+ seen = true;
5449
+ const id = findPwaId(app);
5450
+ if (!id)
5451
+ continue;
5452
+ spawn3("open", ["-na", app, "--args", `--app-id=${id}`], { stdio: "ignore" }).unref();
5453
+ return "launched";
5472
5454
  }
5473
- return false;
5455
+ return seen ? "uninstalled" : "none";
5474
5456
  }
5475
5457
 
5476
5458
  // src/args.ts
@@ -5551,18 +5533,14 @@ function parseArgs(argv) {
5551
5533
  }
5552
5534
  }
5553
5535
  let path = null;
5554
- let app = false;
5555
5536
  for (const a of argv) {
5556
- if (a === "--app" || a === "--pwa")
5557
- app = true;
5558
- else if (a.startsWith("-"))
5537
+ if (a.startsWith("-"))
5559
5538
  return { kind: "error", message: `unknown option ${a}` };
5560
- else if (path !== null)
5539
+ if (path !== null)
5561
5540
  return { kind: "error", message: "Toyon opens one path at a time" };
5562
- else
5563
- path = a;
5541
+ path = a;
5564
5542
  }
5565
- return { kind: "open", path, app };
5543
+ return { kind: "open", path };
5566
5544
  }
5567
5545
  function parseLogs(rest) {
5568
5546
  let follow = false;
@@ -5660,9 +5638,6 @@ usage
5660
5638
  toyon deploy fly destroy <name> [--yes]
5661
5639
  delete that app and its volume
5662
5640
 
5663
- options for toyon [path]
5664
- --app open a Chromium app window (the installed Toyon app when there is one)
5665
-
5666
5641
  environment
5667
5642
  TOYON_HOME where state lives (default ~/.toyon)
5668
5643
  TOYON_PORT the daemon's port (default 4141)
@@ -6237,7 +6212,7 @@ async function helper(args) {
6237
6212
  if (!res.ok)
6238
6213
  console.error(`could not open ${path}: ${await res.text()}`);
6239
6214
  }
6240
- showAppWindow(daemon);
6215
+ openShell(daemon);
6241
6216
  return 0;
6242
6217
  }
6243
6218
 
@@ -6344,7 +6319,7 @@ function readinessOf(json) {
6344
6319
  line: "this machine is waiting to be approved in the Tailscale admin console"
6345
6320
  };
6346
6321
  case "Stopped":
6347
- return { state: "signed-out", name, line: "Tailscale is disconnected; run `tailscale up`, then this again" };
6322
+ return { state: "disconnected", name, line: "Tailscale is disconnected; run `tailscale up`, then this again" };
6348
6323
  default:
6349
6324
  return {
6350
6325
  state: "not-running",
@@ -6484,7 +6459,7 @@ async function switched(body) {
6484
6459
  }
6485
6460
  return r.remote;
6486
6461
  }
6487
- var HOW_TO_OPEN = 'open it on your phone from the phone button in Toyon, or pick this machine under "add a machine"';
6462
+ var HOW_TO_OPEN = 'open it on your phone from the phone button in Toyon, or pick this machine under "your devices"';
6488
6463
  async function remote(cmd) {
6489
6464
  const managed = await loadManaged();
6490
6465
  if (managed.policy.remote === "off")
@@ -6576,6 +6551,18 @@ async function remote(cmd) {
6576
6551
 
6577
6552
  // src/pair.ts
6578
6553
  var POLL_MS = 2000;
6554
+ function tailnetLines(view) {
6555
+ if (view === null)
6556
+ return ["Your phone needs Tailscale on, signed in to the same tailnet."];
6557
+ const lines = [` this machine: ${view.here ? "connected" : "not connected"}`];
6558
+ for (const d of view.devices) {
6559
+ lines.push(` ${d.toyon?.machine ?? d.name}: ${d.reached ? "on your tailnet" : "not answering"}`);
6560
+ }
6561
+ if (!view.devices.some((d) => d.kind === "phone")) {
6562
+ lines.push("No phone has joined your tailnet. Install Tailscale on it and sign in to the same account.");
6563
+ }
6564
+ return lines;
6565
+ }
6579
6566
  async function waiting() {
6580
6567
  const r = await daemonFetch("/knocks");
6581
6568
  return r?.ok ? await r.json() : [];
@@ -6602,9 +6589,10 @@ async function pair() {
6602
6589
  console.log(machineLink(remote.host));
6603
6590
  console.log(HOW_TO_OPEN);
6604
6591
  if (isTailnetName(remote.host)) {
6605
- const r = await daemonFetch("/phones");
6606
- const phones = r?.ok ? await r.json() : null;
6607
- console.log(tailnetLine(phones).text);
6592
+ const r = await daemonFetch("/tailnet");
6593
+ const view = r?.ok ? await r.json() : null;
6594
+ for (const line of tailnetLines(view))
6595
+ console.log(line);
6608
6596
  }
6609
6597
  console.log("waiting for a device; ctrl-c to stop");
6610
6598
  const asked = new Set;
@@ -6855,16 +6843,10 @@ async function open2(cmd) {
6855
6843
  const res = await post("/register", daemon.token, { path: target });
6856
6844
  if (!res.ok) {
6857
6845
  console.error(`could not open ${target}: ${await res.text()}`);
6858
- if (explicit || !cmd.app)
6859
- return 1;
6846
+ return 1;
6860
6847
  }
6861
6848
  }
6862
- if (cmd.app)
6863
- showAppWindow(daemon);
6864
- else {
6865
- console.log(`toyon: ${daemon.url}`);
6866
- openUrl(daemon.url);
6867
- }
6849
+ openShell(daemon);
6868
6850
  return 0;
6869
6851
  }
6870
6852
  async function start() {