@trusty-squire/mcp 0.5.4 → 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.
- package/assets/login/vnc.html +64 -56
- package/package.json +1 -1
package/assets/login/vnc.html
CHANGED
|
@@ -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.
|
|
14
|
-
|
|
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,36 +30,42 @@
|
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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));
|
|
48
|
+
width: 64px; height: 64px;
|
|
49
|
+
display: flex; align-items: center; justify-content: center;
|
|
46
50
|
border-radius: 50%; border: none; background: #4f46e5; color: #fff;
|
|
47
|
-
font-size:
|
|
48
|
-
cursor: pointer; z-index:
|
|
51
|
+
font-size: 28px; line-height: 1; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4);
|
|
52
|
+
cursor: pointer; z-index: 20;
|
|
49
53
|
-webkit-tap-highlight-color: transparent; touch-action: manipulation;
|
|
54
|
+
transition: background 120ms, transform 80ms;
|
|
50
55
|
}
|
|
51
|
-
#kb:active { transform: scale(0.
|
|
52
|
-
/*
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
so iOS scrolls to it on focus (off-screen positioning is known to
|
|
59
|
-
break focus() on iOS Safari), but visually neutered. */
|
|
56
|
+
#kb:active, #kb.tapped { transform: scale(0.92); background: #3fb950; }
|
|
57
|
+
/* Hidden input the button focuses. The noVNC-canonical pattern:
|
|
58
|
+
1×1 px, positioned off-screen, matching foreground+background so
|
|
59
|
+
any flicker is invisible, z-index: -1 so it can't intercept any
|
|
60
|
+
tap. iOS Safari refuses to pop the soft keyboard for an element
|
|
61
|
+
it considers "invisible" — opacity:0 is one of those triggers —
|
|
62
|
+
but a 1px element positioned off-screen counts as visible enough. */
|
|
60
63
|
#kbInput {
|
|
61
|
-
position:
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
position: fixed; left: -40px; top: 0;
|
|
65
|
+
width: 1px; height: 1px;
|
|
66
|
+
background: #fff; color: #fff; caret-color: transparent;
|
|
67
|
+
border: 0; padding: 0; margin: 0;
|
|
68
|
+
z-index: -1;
|
|
65
69
|
}
|
|
66
70
|
</style>
|
|
67
71
|
</head>
|
|
@@ -71,16 +75,17 @@
|
|
|
71
75
|
<b>Trusty Squire</b>
|
|
72
76
|
<span class="sub">— sign in to your account, then return to your terminal.</span>
|
|
73
77
|
</div>
|
|
74
|
-
<div id="screen">
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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…</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>
|
|
84
89
|
<script type="module">
|
|
85
90
|
import RFB from "./core/rfb.js";
|
|
86
91
|
|
|
@@ -114,11 +119,6 @@
|
|
|
114
119
|
rfb.addEventListener("connect", () => {
|
|
115
120
|
dot.className = "ok";
|
|
116
121
|
msg.style.display = "none";
|
|
117
|
-
// Reveal the soft-keyboard button (CSS gates it to touch
|
|
118
|
-
// devices via the pointer:coarse media query). Connection
|
|
119
|
-
// success is the right moment — earlier and the button would
|
|
120
|
-
// suggest a typing target that isn't connected yet.
|
|
121
|
-
kbBtn.classList.add("ready");
|
|
122
122
|
});
|
|
123
123
|
rfb.addEventListener("disconnect", () => {
|
|
124
124
|
dot.className = "err";
|
|
@@ -126,7 +126,6 @@
|
|
|
126
126
|
msg.textContent =
|
|
127
127
|
"Login window closed. If you finished signing in, return to " +
|
|
128
128
|
"your terminal — you can close this tab.";
|
|
129
|
-
kbBtn.classList.remove("ready");
|
|
130
129
|
});
|
|
131
130
|
rfb.addEventListener("securityfailure", () => {
|
|
132
131
|
dot.className = "err";
|
|
@@ -134,14 +133,24 @@
|
|
|
134
133
|
msg.textContent = "Could not authenticate to the login window.";
|
|
135
134
|
});
|
|
136
135
|
|
|
137
|
-
// Tap →
|
|
138
|
-
//
|
|
139
|
-
//
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
//
|
|
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?"
|
|
143
149
|
kbBtn.addEventListener("click", (e) => {
|
|
144
150
|
e.preventDefault();
|
|
151
|
+
kbBtn.classList.add("tapped");
|
|
152
|
+
setTimeout(() => kbBtn.classList.remove("tapped"), 200);
|
|
153
|
+
kbInput.blur();
|
|
145
154
|
kbInput.value = "";
|
|
146
155
|
kbInput.focus();
|
|
147
156
|
});
|
|
@@ -164,10 +173,9 @@
|
|
|
164
173
|
|
|
165
174
|
// Forward typed characters. The `input` event fires once per
|
|
166
175
|
// commit (each char on most soft keyboards; sometimes batched
|
|
167
|
-
// when an IME finalizes). We
|
|
168
|
-
//
|
|
169
|
-
//
|
|
170
|
-
// 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.
|
|
171
179
|
let lastKbValue = "";
|
|
172
180
|
kbInput.addEventListener("input", () => {
|
|
173
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.
|
|
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",
|