@trusty-squire/mcp 0.5.5 → 0.5.6

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.
@@ -10,10 +10,8 @@
10
10
  google-login.ts runHeadlessChrome). Deliberately uses ONLY noVNC's
11
11
  stable RFB API — the `RFB` default export, its constructor, the
12
12
  `scaleViewport`/`resizeSession` properties, the
13
- connect/disconnect/securityfailure events, and `rfb.focus()` (used
14
- to pop the mobile soft keyboard) — all stable across every noVNC
15
- 1.x release, so this page survives whatever version the host
16
- distro's `novnc` package pinned.
13
+ connect/disconnect/securityfailure events, and `rfb.sendKey()`
14
+ all stable across every noVNC 1.x release.
17
15
  -->
18
16
  <style>
19
17
  html, body { margin: 0; height: 100%; background: #0f1115; color: #e6e8ec;
@@ -32,38 +30,30 @@
32
30
  #dot.ok { background: #3fb950; }
33
31
  #dot.err { background: #f85149; }
34
32
  #screen { flex: 1; position: relative; background: #0f1115; min-height: 0; }
35
- #msg { position: absolute; top: 50%; left: 0; right: 0; text-align: center;
36
- transform: translateY(-50%); color: #9aa0ab; font-size: 14px; padding: 0 24px; }
37
- /* Show-keyboard button. The remote VNC view is just pixels the OS
38
- can't tell there's a typeable field, so a normal tap inside the
39
- remote Chrome doesn't pop the soft keyboard. This button focuses
40
- the hidden #kbInput element below; the OS sees an actual editable
41
- input gain focus and pops the keyboard. Each character typed
42
- into #kbInput is forwarded to the VNC stream via rfb.sendKey()
43
- and the input is cleared, so the local input never accumulates
44
- the user's password.
45
-
46
- Button is positioned 88px above the bottom edge to clear Android
47
- gesture-navigation zones and iOS home indicators (bottom: 16px
48
- used to fail on some phones because the tap landed on the OS
49
- nav instead of the button). 64px target is comfortably above the
50
- 44pt minimum tap-target size both platforms recommend. */
51
- #kb { position: absolute; right: 16px; bottom: max(88px, env(safe-area-inset-bottom, 16px));
33
+ /* Overlay siblings of #screen `position: fixed` against the
34
+ viewport, NOT positioned inside #screen. RFB appends a <canvas>
35
+ child to #screen at connect time, and that canvas can cover any
36
+ absolutely-positioned children even with z-index. Sibling +
37
+ fixed keeps them above the canvas unconditionally. */
38
+ #msg { position: fixed; top: 50%; left: 0; right: 0; text-align: center;
39
+ transform: translateY(-50%); color: #9aa0ab; font-size: 14px; padding: 0 24px;
40
+ pointer-events: none; z-index: 9; }
41
+ /* The keyboard button. Always visible (no media-query gating
42
+ desktop users see a tiny ⌨ they ignore; better than a phone user
43
+ finding nothing). Position fixed against the viewport so the OS
44
+ gesture nav area at the bottom can't swallow taps meant for it. */
45
+ #kb {
46
+ position: fixed; right: 16px;
47
+ bottom: max(96px, env(safe-area-inset-bottom, 16px));
52
48
  width: 64px; height: 64px;
49
+ display: flex; align-items: center; justify-content: center;
53
50
  border-radius: 50%; border: none; background: #4f46e5; color: #fff;
54
51
  font-size: 28px; line-height: 1; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4);
55
- cursor: pointer; z-index: 10; display: none;
52
+ cursor: pointer; z-index: 20;
56
53
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
54
+ transition: background 120ms, transform 80ms;
57
55
  }
58
- #kb:active { transform: scale(0.94); }
59
- /* Only show the button on touch-capable devices — desktops already
60
- have a hardware keyboard and the button just clutters the view.
61
- Always-on once the page loads; previously gated on RFB's connect
62
- event, but if connect fired before the listener attached (or if
63
- the user was reconnecting), the button stayed hidden forever. */
64
- @media (hover: none) and (pointer: coarse) {
65
- #kb { display: flex; align-items: center; justify-content: center; }
66
- }
56
+ #kb:active, #kb.tapped { transform: scale(0.92); background: #3fb950; }
67
57
  /* Hidden input the button focuses. The noVNC-canonical pattern:
68
58
  1×1 px, positioned off-screen, matching foreground+background so
69
59
  any flicker is invisible, z-index: -1 so it can't intercept any
@@ -71,7 +61,7 @@
71
61
  it considers "invisible" — opacity:0 is one of those triggers —
72
62
  but a 1px element positioned off-screen counts as visible enough. */
73
63
  #kbInput {
74
- position: absolute; left: -40px; top: 0;
64
+ position: fixed; left: -40px; top: 0;
75
65
  width: 1px; height: 1px;
76
66
  background: #fff; color: #fff; caret-color: transparent;
77
67
  border: 0; padding: 0; margin: 0;
@@ -85,16 +75,17 @@
85
75
  <b>Trusty Squire</b>
86
76
  <span class="sub">— sign in to your account, then return to your terminal.</span>
87
77
  </div>
88
- <div id="screen">
89
- <div id="msg">Connecting to the secure login window&hellip;</div>
90
- <!-- inputmode=text + autocorrect/autocapitalize/spellcheck off so the
91
- soft keyboard never offers autocomplete suggestions for a typed
92
- password, and never enriches characters before we forward them. -->
93
- <input id="kbInput" type="text" inputmode="text" autocomplete="off"
94
- autocorrect="off" autocapitalize="off" spellcheck="false"
95
- aria-hidden="true" tabindex="-1" />
96
- <button id="kb" type="button" aria-label="Show keyboard">⌨</button>
97
- </div>
78
+ <div id="screen"></div>
79
+ <!-- Overlays as body-level siblings, not children of #screen — see
80
+ the #msg / #kb CSS comments above. -->
81
+ <div id="msg">Connecting to the secure login window&hellip;</div>
82
+ <!-- inputmode=text + autocorrect/autocapitalize/spellcheck off so the
83
+ soft keyboard never offers autocomplete suggestions for a typed
84
+ password, and never enriches characters before we forward them. -->
85
+ <input id="kbInput" type="text" inputmode="text" autocomplete="off"
86
+ autocorrect="off" autocapitalize="off" spellcheck="false"
87
+ aria-hidden="true" tabindex="-1" />
88
+ <button id="kb" type="button" aria-label="Show keyboard">⌨</button>
98
89
  <script type="module">
99
90
  import RFB from "./core/rfb.js";
100
91
 
@@ -142,16 +133,23 @@
142
133
  msg.textContent = "Could not authenticate to the login window.";
143
134
  });
144
135
 
145
- // Tap → soft keyboard pop. The blur+focus dance is the load-
146
- // bearing trick: focus() on an already-focused element is a
147
- // no-op and the OS won't re-trigger the keyboard, but blur first
148
- // forces a fresh focus event. The whole sequence stays inside
149
- // the click handler so iOS Safari and Android Chrome both
150
- // accept the focus() as gesture-bound. Focusing a real <input>
151
- // is what triggers the OS keyboard — focusing the RFB div
152
- // (rfb.focus() in noVNC 1.x) wouldn't.
136
+ // Tap → soft keyboard pop. The blur+focus dance is load-bearing:
137
+ // focus() on an already-focused element is a no-op so the OS
138
+ // won't re-trigger the keyboard; blur first forces a fresh focus
139
+ // event. The whole sequence stays inside the click handler so
140
+ // iOS Safari and Android Chrome both accept the focus() as
141
+ // gesture-bound. Focusing a real <input> is what pops the OS
142
+ // keyboard — focusing the RFB div (rfb.focus() in noVNC 1.x)
143
+ // wouldn't.
144
+ //
145
+ // The .tapped class flashes the button green for 200ms so the
146
+ // user can see the tap registered even if the OS doesn't (yet)
147
+ // pop the keyboard — separates "did my tap reach the button?"
148
+ // from "does focus() pop the keyboard on this device?"
153
149
  kbBtn.addEventListener("click", (e) => {
154
150
  e.preventDefault();
151
+ kbBtn.classList.add("tapped");
152
+ setTimeout(() => kbBtn.classList.remove("tapped"), 200);
155
153
  kbInput.blur();
156
154
  kbInput.value = "";
157
155
  kbInput.focus();
@@ -175,10 +173,9 @@
175
173
 
176
174
  // Forward typed characters. The `input` event fires once per
177
175
  // commit (each char on most soft keyboards; sometimes batched
178
- // when an IME finalizes). We diff against the previous value
179
- // to handle paste / autocorrect insertions, send a press+release
180
- // for each new character, then clear the input so it never
181
- // accumulates the user's password.
176
+ // when an IME finalizes). We send a press+release for each
177
+ // character, then clear the input so it never accumulates the
178
+ // user's password.
182
179
  let lastKbValue = "";
183
180
  kbInput.addEventListener("input", () => {
184
181
  const newValue = kbInput.value;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trusty-squire/mcp",
3
- "version": "0.5.5",
3
+ "version": "0.5.6",
4
4
  "type": "module",
5
5
  "description": "Local MCP server vibe coding agents install. Thin relay to the Trusty Squire API, with the bundled universal signup bot.",
6
6
  "main": "./dist/server.js",