@oddessentials/agent-guild 0.12.0 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oddessentials/agent-guild",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "description": "Launch and watch AI coding-assistant terminal sessions from one local web page. A bundled session manager owns the terminals so the page can close and reconnect.",
5
5
  "license": "MIT",
6
6
  "repository": {
package/web/app.js CHANGED
@@ -15,6 +15,7 @@ const RELEASES_URL = 'https://github.com/oddessentials/agent-guild/releases';
15
15
  const isMac = /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent);
16
16
  const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
17
17
  const finePointer = window.matchMedia('(hover: hover) and (pointer: fine)');
18
+ const coarsePointer = window.matchMedia('(pointer: coarse)');
18
19
 
19
20
  const $ = (id) => document.getElementById(id);
20
21
  const state = {
@@ -2747,7 +2748,7 @@ class TerminalView {
2747
2748
  this.term = new window.Terminal({
2748
2749
  cursorBlink: true,
2749
2750
  fontFamily: 'ui-monospace, "Cascadia Code", "SF Mono", Menlo, Consolas, monospace',
2750
- fontSize: 13,
2751
+ fontSize: coarsePointer.matches ? 14 : 13,
2751
2752
  scrollback: 5000,
2752
2753
  macOptionIsMeta: true,
2753
2754
  theme: TERMINAL_THEME,
@@ -2828,12 +2829,51 @@ class TerminalView {
2828
2829
 
2829
2830
  mount(host) {
2830
2831
  host.replaceChildren(this.el);
2831
- if (!this.opened) { this.term.open(this.el); this.opened = true; }
2832
+ if (!this.opened) { this.term.open(this.el); this.enableTouchScroll(); this.opened = true; }
2832
2833
  this.resizeObserver.observe(host);
2833
2834
  this.refit();
2834
2835
  this.term.focus();
2835
2836
  }
2836
2837
 
2838
+ /**
2839
+ * xterm.js 6 scrolls only for the mouse wheel, so a one-finger drag would
2840
+ * scroll the page behind the panel instead. Turn the drag into scrolling.
2841
+ * Full-screen programs and programs that read the mouse get a wheel event,
2842
+ * which xterm turns into arrow keys or mouse reports as it does for a real
2843
+ * wheel. Scrollback uses scrollLines, because xterm's scrollback reads the
2844
+ * legacy wheelDeltaY that a constructed WheelEvent leaves at 0.
2845
+ */
2846
+ enableTouchScroll() {
2847
+ let lastY = null;
2848
+ let pending = 0;
2849
+ this.el.addEventListener('touchstart', (e) => {
2850
+ lastY = e.touches.length === 1 ? e.touches[0].clientY : null;
2851
+ pending = 0;
2852
+ }, { passive: true });
2853
+ this.el.addEventListener('touchmove', (e) => {
2854
+ if (lastY === null || e.touches.length !== 1) return;
2855
+ e.preventDefault();
2856
+ const touch = e.touches[0];
2857
+ const delta = lastY - touch.clientY;
2858
+ lastY = touch.clientY;
2859
+ if (this.term.buffer.active.type === 'alternate' || this.term.modes.mouseTrackingMode !== 'none') {
2860
+ const target = this.el.querySelector('.xterm-screen') || this.el;
2861
+ target.dispatchEvent(new WheelEvent('wheel', {
2862
+ deltaY: delta, deltaMode: WheelEvent.DOM_DELTA_PIXEL,
2863
+ clientX: touch.clientX, clientY: touch.clientY, bubbles: true, cancelable: true,
2864
+ }));
2865
+ return;
2866
+ }
2867
+ pending += delta;
2868
+ const lineHeight = this.el.querySelector('.xterm-rows')?.firstElementChild?.offsetHeight || 17;
2869
+ const lines = Math.trunc(pending / lineHeight);
2870
+ if (lines) { this.term.scrollLines(lines); pending -= lines * lineHeight; }
2871
+ }, { passive: false });
2872
+ const end = () => { lastY = null; };
2873
+ this.el.addEventListener('touchend', end);
2874
+ this.el.addEventListener('touchcancel', end);
2875
+ }
2876
+
2837
2877
  unmount() {
2838
2878
  this.resizeObserver.disconnect();
2839
2879
  this.el.remove();
package/web/styles.css CHANGED
@@ -354,6 +354,14 @@ body:has(#app[hidden]):has(#auth[hidden]):has(#stopped[hidden])::after {
354
354
  .panel-actions { display: flex; gap: 8px; }
355
355
  .terminal-host { flex: 1; min-height: 0; padding: 8px 4px 4px 10px; }
356
356
  .terminal-host > div { height: 100%; }
357
+ @media (pointer: coarse) {
358
+ /* A drag on the panel would otherwise scroll the page behind it. */
359
+ body:has(#terminal-panel:not([hidden])) { overflow: hidden; }
360
+ }
361
+ @media (pointer: coarse) and (max-width: 900px) {
362
+ /* Tablets in portrait are wider than the phone layout but still want the whole width. */
363
+ .terminal-panel { inset: var(--topbar-h, 56px) 0 0; border-radius: 0; }
364
+ }
357
365
 
358
366
  .models {
359
367
  width: min(880px, calc(100vw - 32px)); max-height: calc(100vh - 48px); padding: 0; overflow: hidden;