linkshell-cli 0.10.95 → 0.10.96

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.
@@ -83,8 +83,9 @@ const STYLE = String.raw `
83
83
  .choice.on { background: rgba(255,255,255,0.16); }
84
84
  .choice b { display: block; font-weight: 600; font-size: calc(15px * var(--text-scale, 1)); }
85
85
  .choice span { display: block; font-size: calc(12px * var(--text-scale, 1)); color: rgba(255,255,255,0.62); }
86
- #widths { padding: 0 6px 6px; }
87
- #widths .group { padding-top: 4px; }
86
+ #widths, #pacing { padding: 0 6px 6px; }
87
+ #widths .group, #pacing .group { padding-top: 4px; }
88
+ #pacing .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
88
89
  #status { padding: 2px 10px 10px; font-size: calc(12px * var(--text-scale, 1)); line-height: 1.5;
89
90
  color: rgba(255,255,255,0.5); white-space: pre-line; font-variant-numeric: tabular-nums; }
90
91
  #toast { position: absolute; left: 50%; max-width: min(86vw, 420px); width: max-content; transform: translateX(-50%); padding: 10px 16px; border-radius: 18px;
@@ -414,6 +415,15 @@ function comboSign(k, m) {
414
415
  * The user's own shortcuts, from wherever they were kept (the app, the browser): only those the computer
415
416
  * would take, 24 at most, each with a name (the shortcut itself when it was given none).
416
417
  */
418
+ /**
419
+ * The offer without the playout-delay extension, for a receiver that chose even pacing. The sender writes
420
+ * 0/0 into that header (show each frame the moment it is decoded); an answer that never agreed to it leaves
421
+ * the receiver its adaptive jitter buffer. Taken out of the remote offer, so the answer stays the browser's own.
422
+ */
423
+ function withoutPlayoutDelay(sdp) {
424
+ return String(sdp).split(/\r\n/).filter((line) => !/^a=extmap:\d+(?:\/\w+)?\s+http:\/\/www\.webrtc\.org\/experiments\/rtp-hdrext\/playout-delay(?:\s|$)/.test(line)).join("\r\n");
425
+ }
426
+
417
427
  function cleanShortcuts(list) {
418
428
  const out = [];
419
429
  for (const one of Array.isArray(list) ? list : []) {
@@ -737,6 +747,14 @@ if (session.desired().maxFps) asked.set("maxFps", String(session.desired().maxFp
737
747
  const framed = document.URL === "about:srcdoc";
738
748
  const reloadVia = framed && typeof window.__linkshellReload === "function" ? window.__linkshellReload : null;
739
749
  const canChooseWidth = !framed || !!reloadVia;
750
+ // How the receiver paces the picture: "immediate" shows each frame as it is decoded (the default, most
751
+ // responsive); "smooth" leaves the receiver its jitter buffer, about +50 ms on Wi-Fi (ScreenPacing.swift).
752
+ // A new choice needs a new negotiation: an app says it in the address and reconnects; a plain browser reloads.
753
+ let keptPacing = null;
754
+ try { keptPacing = localStorage.getItem("linkshell.screen.pacing"); } catch {}
755
+ const pacing = query.get("pacing") === "smooth" || (!app && query.get("pacing") === null && keptPacing === "smooth") ? "smooth" : "immediate";
756
+ // An app that reconnects for it says so; a srcdoc page has no address to load again.
757
+ const canChoosePacing = () => (app ? chrome.canPace === true : !framed);
740
758
  const ws = nativePicture
741
759
  ? { readyState: 1, send: (data) => nativePost({ kind: "signal", message: JSON.parse(data) }) }
742
760
  : new WebSocket((location.protocol === "https:" ? "wss://" : "ws://") + location.host + "/stream?" + asked);
@@ -923,8 +941,9 @@ function signal(message) {
923
941
  tried = true;
924
942
  patience = setTimeout(() => connectionPatience(mine), patienceSeconds * 1000);
925
943
  if (failAfter) setTimeout(() => { if (rtc === mine) giveUp("asked to (failAfter)"); }, failAfter * 1000);
926
- // The answer is the browser's own, as it made it: the sender's playout-delay header has to survive in it.
927
- mine.described = mine.pc.setRemoteDescription({ type: "offer", sdp: message.sdp })
944
+ // The answer is the browser's own, as it made it: the sender's playout-delay header has to survive in it,
945
+ // unless the viewer chose even pacing, which is not agreeing to that header at all.
946
+ mine.described = mine.pc.setRemoteDescription({ type: "offer", sdp: pacing === "smooth" ? withoutPlayoutDelay(message.sdp) : message.sdp })
928
947
  .then(() => mine.pc.createAnswer())
929
948
  .then((answer) => mine.pc.setLocalDescription(answer))
930
949
  .then(() => { if (rtc === mine) send({ t: "rtc.answer", sdp: mine.pc.localDescription.sdp }); });
@@ -948,8 +967,11 @@ function connect(iceServers) {
948
967
  };
949
968
  pc.ontrack = ({ receiver, track, streams }) => {
950
969
  // No waiting beyond what decoding takes. Safari has neither knob: there the sender's playout-delay header does it.
951
- if ("jitterBufferTarget" in receiver) receiver.jitterBufferTarget = 0;
952
- if ("playoutDelayHint" in receiver) receiver.playoutDelayHint = 0;
970
+ // Even pacing keeps the browser's adaptive buffer.
971
+ if (pacing !== "smooth") {
972
+ if ("jitterBufferTarget" in receiver) receiver.jitterBufferTarget = 0;
973
+ if ("playoutDelayHint" in receiver) receiver.playoutDelayHint = 0;
974
+ }
953
975
  video.srcObject = streams[0] || new MediaStream([track]);
954
976
  // The <video> starts either way: it is what shows the picture where this page cannot present
955
977
  // the frames itself, and what it falls back to if the presenter stops. Taking the frames is
@@ -2624,6 +2646,12 @@ async function status() {
2624
2646
  $("widths").classList.toggle("gone", !choosing);
2625
2647
  layout();
2626
2648
  }
2649
+ // Only a video track has a jitter buffer to keep; the socket's picture is paced by this page.
2650
+ const pacingShown = live && !windowsHost && canChoosePacing();
2651
+ if ($("pacing").classList.contains("gone") === pacingShown) {
2652
+ $("pacing").classList.toggle("gone", !pacingShown);
2653
+ layout();
2654
+ }
2627
2655
  const way = !content.w ? "正在连接…" : live ? "直连 · 视频" : (relayed ? "中继" : "直连") + " · 兼容\n" + content.w + "×" + content.h;
2628
2656
  if (windowsHost && !live && content.w) {
2629
2657
  const stats = jpegVitals();
@@ -2684,6 +2712,23 @@ for (const tile of $("widths").querySelectorAll(".tile")) {
2684
2712
  window.linkshellSession({ width: chosen });
2685
2713
  });
2686
2714
  }
2715
+ for (const tile of $("pacing").querySelectorAll(".tile")) {
2716
+ tile.classList.toggle("on", tile.dataset.pacing === pacing);
2717
+ tile.setAttribute("aria-pressed", String(tile.dataset.pacing === pacing));
2718
+ pressable(tile, () => {
2719
+ const chosen = tile.dataset.pacing;
2720
+ if (chosen === pacing || !canChoosePacing()) return;
2721
+ try { localStorage.setItem("linkshell.screen.pacing", chosen); } catch {}
2722
+ hint(chosen === "smooth" ? "流畅优先:画面更均匀,Wi-Fi 下延迟约多 50 毫秒" : "延迟优先:最跟手,网络抖动时会短暂停顿", 2500);
2723
+ if (app) return tellApp({ type: "pacing", pacing: chosen });
2724
+ const next = new URLSearchParams(location.search);
2725
+ next.set("pacing", chosen);
2726
+ next.set("width", width);
2727
+ next.set("display", String(session.desired().display));
2728
+ next.set("mode", mode);
2729
+ location.replace(location.pathname + "?" + next);
2730
+ });
2731
+ }
2687
2732
  pressable($("full"), () => {
2688
2733
  beginPresentation(app ? !chrome.fullscreen : !document.fullscreenElement);
2689
2734
  if (app) return tellApp({ type: "fullscreen", on: !chrome.fullscreen });
@@ -3212,6 +3257,13 @@ ${SCREEN_LOADING_HTML}
3212
3257
  <div class="tile" role="button" aria-label="原生,屏幕本身的分辨率" data-width="native"><b>原生</b><span>最高 4K</span></div>
3213
3258
  </div>
3214
3259
  </div>
3260
+ <div id="pacing" class="gone">
3261
+ <div class="group"><span>画面节奏</span></div>
3262
+ <div class="tiles">
3263
+ <div class="tile" role="button" aria-label="延迟优先,最跟手,网络抖动时会短暂停顿" data-pacing="immediate"><b>延迟优先</b><span>最跟手</span></div>
3264
+ <div class="tile" role="button" aria-label="流畅优先,画面更均匀,Wi-Fi 下延迟约多 50 毫秒,适合只观看" data-pacing="smooth"><b>流畅优先</b><span>适合观看</span></div>
3265
+ </div>
3266
+ </div>
3215
3267
  </div>
3216
3268
  <div id="control-shell" class="glass" aria-hidden="true"></div>
3217
3269
  <div id="bar">
@@ -1 +1 @@
1
- {"version":3,"file":"screen-viewer.js","sourceRoot":"","sources":["../../../../host/src/screen-viewer.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,2EAA2E;AAC3E,6EAA6E;AAC7E,mEAAmE;AACnE,EAAE;AACF,4DAA4D;AAC5D,yEAAyE;AACzE,2CAA2C;AAC3C,6EAA6E;AAC7E,+EAA+E;AAC/E,2CAA2C;AAC3C,qGAAqG;AACrG,+EAA+E;AAC/E,6FAA6F;AAC7F,EAAE;AACF,oGAAoG;AACpG,mGAAmG;AACnG,+FAA+F;AAC/F,8FAA8F;AAE9F,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEvG,gHAAgH;AAChH,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CAAC;AAC5C,gIAAgI;AAChI,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC;AAE3C,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAC5B,uJAAuJ,IAAI,QAAQ,CAAC;AAEtK,MAAM,KAAK,GAAG;IACZ,IAAI,EAAE,IAAI,CAAC,qHAAqH,CAAC;IACjI,QAAQ,EAAE,IAAI,CAAC,6DAA6D,CAAC;IAC7E,KAAK,EAAE,IAAI,CAAC,oGAAoG,CAAC;IACjH,QAAQ,EAAE,IAAI,CAAC,iJAAiJ,CAAC;IACjK,GAAG,EAAE,IAAI,CAAC,0EAA0E,CAAC;IACrF,MAAM,EAAE,IAAI,CAAC,oDAAoD,CAAC;IAClE,MAAM,EAAE,IAAI,CAAC,oDAAoD,CAAC;IAClE,IAAI,EAAE,IAAI,CAAC,4BAA4B,CAAC;IACxC,KAAK,EAAE,IAAI,CAAC,qDAAqD,CAAC;IAClE,OAAO,EAAE,IAAI,CAAC,sEAAsE,CAAC;IACrF,IAAI,EAAE,IAAI,CAAC,iEAAiE,CAAC;IAC7E,KAAK,EAAE,IAAI,CAAC,4CAA4C,CAAC;CAC1D,CAAC;AAEF,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkHvB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4YrC,CAAC;AAEF,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAskFtB,CAAC;AAEF,MAAM,MAAM,GAAG,gCAAgC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,wBAAwB,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,YAAY,GAAG,qBAAqB,GAAG,IAAI,OAAO,CAAC;AAErL,MAAM,UAAU,UAAU,CAAC,WAA4B,QAAQ;IAC7D,OAAO;;;;SAIA,KAAK,GAAG,oBAAoB;uBACd,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;;EAE9D,mBAAmB;;;;;;;;iHAQ4F,KAAK,CAAC,KAAK;;;;;;;;;;;;;;;kEAe1D,KAAK,CAAC,QAAQ;iEACf,KAAK,CAAC,KAAK;+DACb,KAAK,CAAC,GAAG;gEACR,KAAK,CAAC,IAAI;;;;;;;;;;;;;;;4CAe9B,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,aAAa,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ;;4CAEtF,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,aAAa,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;;;;;;;;;;;;;;;;;;;;;;;oCAuBnG,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG;oCAClC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG;;;;;;;;;;6CAUzB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;UACxD,MAAM;eACD,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"screen-viewer.js","sourceRoot":"","sources":["../../../../host/src/screen-viewer.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,2EAA2E;AAC3E,6EAA6E;AAC7E,mEAAmE;AACnE,EAAE;AACF,4DAA4D;AAC5D,yEAAyE;AACzE,2CAA2C;AAC3C,6EAA6E;AAC7E,+EAA+E;AAC/E,2CAA2C;AAC3C,qGAAqG;AACrG,+EAA+E;AAC/E,6FAA6F;AAC7F,EAAE;AACF,oGAAoG;AACpG,mGAAmG;AACnG,+FAA+F;AAC/F,8FAA8F;AAE9F,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEvG,gHAAgH;AAChH,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CAAC;AAC5C,gIAAgI;AAChI,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC;AAE3C,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAC5B,uJAAuJ,IAAI,QAAQ,CAAC;AAEtK,MAAM,KAAK,GAAG;IACZ,IAAI,EAAE,IAAI,CAAC,qHAAqH,CAAC;IACjI,QAAQ,EAAE,IAAI,CAAC,6DAA6D,CAAC;IAC7E,KAAK,EAAE,IAAI,CAAC,oGAAoG,CAAC;IACjH,QAAQ,EAAE,IAAI,CAAC,iJAAiJ,CAAC;IACjK,GAAG,EAAE,IAAI,CAAC,0EAA0E,CAAC;IACrF,MAAM,EAAE,IAAI,CAAC,oDAAoD,CAAC;IAClE,MAAM,EAAE,IAAI,CAAC,oDAAoD,CAAC;IAClE,IAAI,EAAE,IAAI,CAAC,4BAA4B,CAAC;IACxC,KAAK,EAAE,IAAI,CAAC,qDAAqD,CAAC;IAClE,OAAO,EAAE,IAAI,CAAC,sEAAsE,CAAC;IACrF,IAAI,EAAE,IAAI,CAAC,iEAAiE,CAAC;IAC7E,KAAK,EAAE,IAAI,CAAC,4CAA4C,CAAC;CAC1D,CAAC;AAEF,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmHvB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqZrC,CAAC;AAEF,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAymFtB,CAAC;AAEF,MAAM,MAAM,GAAG,gCAAgC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,wBAAwB,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,YAAY,GAAG,qBAAqB,GAAG,IAAI,OAAO,CAAC;AAErL,MAAM,UAAU,UAAU,CAAC,WAA4B,QAAQ;IAC7D,OAAO;;;;SAIA,KAAK,GAAG,oBAAoB;uBACd,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;;EAE9D,mBAAmB;;;;;;;;iHAQ4F,KAAK,CAAC,KAAK;;;;;;;;;;;;;;;;;;;;;;kEAsB1D,KAAK,CAAC,QAAQ;iEACf,KAAK,CAAC,KAAK;+DACb,KAAK,CAAC,GAAG;gEACR,KAAK,CAAC,IAAI;;;;;;;;;;;;;;;4CAe9B,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,aAAa,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ;;4CAEtF,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,aAAa,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;;;;;;;;;;;;;;;;;;;;;;;oCAuBnG,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG;oCAClC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG;;;;;;;;;;6CAUzB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;UACxD,MAAM;eACD,CAAC;AAChB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "linkshell-cli",
3
- "version": "0.10.95",
3
+ "version": "0.10.96",
4
4
  "description": "Follow, steer and approve the coding agents on your computer (Claude Code, Codex, Gemini, Copilot and more) from your phone",
5
5
  "type": "module",
6
6
  "main": "dist/cli/src/index.js",
@@ -35,8 +35,8 @@
35
35
  "qrcode-terminal": "^0.12.0",
36
36
  "ws": "^8.21.0",
37
37
  "@linkshell/gateway": "0.6.59",
38
- "@linkshell/host": "0.4.89",
39
- "@linkshell/wire": "0.2.28"
38
+ "@linkshell/wire": "0.2.28",
39
+ "@linkshell/host": "0.4.90"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/ws": "^8.5.14",