kaizen-agent 1.34.4 → 1.34.5
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 +1 -1
- package/web/board.html +3 -1
- package/web/board.js +1 -1
- package/web/notebook.js +1 -1
- package/web/term.js +16 -16
- package/web/term.ts +47 -24
package/web/term.ts
CHANGED
|
@@ -41,45 +41,68 @@ function mountTerm(el: HTMLElement, key: string, onEnd?: () => void): () => void
|
|
|
41
41
|
term.write(`\r\n\x1b[2m[${e.reason === "ended" ? "agent ended" : "connection to the board lost"}]\x1b[0m\r\n`);
|
|
42
42
|
onEnd?.();
|
|
43
43
|
};
|
|
44
|
-
// Phone/tablet: a bar of the keys a soft keyboard lacks.
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
const mods = {
|
|
44
|
+
// Phone/tablet: a bar of the keys a soft keyboard lacks. Alt is sticky for the next key.
|
|
45
|
+
// Ctrl opens its own a-z pad instead of waiting on the native keyboard, whose IME can
|
|
46
|
+
// deliver the letter without the modifier. The handle above the bar hides it.
|
|
47
|
+
const mods = { alt: false };
|
|
48
48
|
const typed = term.onData((d) => {
|
|
49
|
-
if (d.length === 1 && mods.ctrl && /[a-z@[\\\]^_]/i.test(d)) d = String.fromCharCode(d.toUpperCase().charCodeAt(0) & 31);
|
|
50
49
|
if (mods.alt) d = "\x1b" + d;
|
|
51
|
-
mods.
|
|
52
|
-
bar?.
|
|
50
|
+
mods.alt = false;
|
|
51
|
+
bar?.querySelector(".alt")?.classList.remove("on");
|
|
53
52
|
send({ t: "i", d });
|
|
54
53
|
});
|
|
55
54
|
let bar: HTMLElement | null = null;
|
|
56
55
|
if (matchMedia("(pointer: coarse)").matches) {
|
|
57
56
|
const arrow = (c: string) => () => `\x1b${term.modes.applicationCursorKeysMode ? "O" : "["}${c}`;
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
const paste = () => navigator.clipboard?.readText().then((t) => t && term.paste(t), () => {});
|
|
58
|
+
// inverted T: Up above Down, Left and Right beside it
|
|
59
|
+
const keys: [string, string | (() => unknown) | "alt" | "ctrl" | ""][] = [
|
|
60
|
+
["Esc", "\x1b"], ["Paste", paste], ["↵", "\r"], ["⇧⇥", "\x1b[Z"], ["↑", arrow("A")], ["", ""],
|
|
61
|
+
["Ctrl", "ctrl"], ["Alt", "alt"], ["^C", "\x03"], ["←", arrow("D")], ["↓", arrow("B")], ["→", arrow("C")],
|
|
61
62
|
];
|
|
62
63
|
bar = document.createElement("div");
|
|
63
64
|
bar.className = "termkeys";
|
|
64
|
-
|
|
65
|
+
// pointerdown + preventDefault: a tap must not move focus off the terminal.
|
|
66
|
+
const key = (label: string, fn: () => void) => {
|
|
65
67
|
const b = document.createElement("button");
|
|
66
68
|
b.type = "button";
|
|
67
69
|
b.textContent = label;
|
|
68
|
-
|
|
69
|
-
b
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
70
|
+
b.addEventListener("pointerdown", (e) => { e.preventDefault(); fn(); term.focus(); });
|
|
71
|
+
return b;
|
|
72
|
+
};
|
|
73
|
+
const grid = document.createElement("div");
|
|
74
|
+
grid.className = "keygrid";
|
|
75
|
+
const setPad = (on: boolean) => { pad.hidden = !on; grid.hidden = on; };
|
|
76
|
+
const pad = document.createElement("div");
|
|
77
|
+
pad.className = "ctrlpad";
|
|
78
|
+
pad.hidden = true;
|
|
79
|
+
// qwerty rows; the last row ends with ✕ to leave the pad
|
|
80
|
+
for (const row of ["qwertyuiop", "asdfghjkl", "zxcvbnm✕"]) {
|
|
81
|
+
const r = document.createElement("div");
|
|
82
|
+
for (const c of row) r.append(key(c, () => {
|
|
83
|
+
if (c !== "✕") send({ t: "i", d: String.fromCharCode(c.charCodeAt(0) & 31) });
|
|
84
|
+
setPad(false);
|
|
85
|
+
}));
|
|
86
|
+
pad.append(r);
|
|
87
|
+
}
|
|
88
|
+
for (const [label, v] of keys) {
|
|
89
|
+
if (!label) { grid.append(document.createElement("i")); continue; }
|
|
90
|
+
const b = key(label, () => {
|
|
91
|
+
if (v === "alt") b.classList.toggle("on", (mods.alt = !mods.alt));
|
|
92
|
+
else if (v === "ctrl") setPad(true);
|
|
93
|
+
else send({ t: "i", d: (typeof v === "function" ? v() : v) as string });
|
|
80
94
|
});
|
|
81
|
-
|
|
95
|
+
if (v === "alt") b.classList.add(v);
|
|
96
|
+
grid.append(b);
|
|
82
97
|
}
|
|
98
|
+
const hide = key("⌨ ▾", () => {
|
|
99
|
+
const off = hide.textContent === "⌨ ▾";
|
|
100
|
+
grid.hidden = pad.hidden = true;
|
|
101
|
+
if (!off) grid.hidden = false;
|
|
102
|
+
hide.textContent = off ? "⌨ ▴" : "⌨ ▾";
|
|
103
|
+
});
|
|
104
|
+
hide.className = "keyhide";
|
|
105
|
+
bar.append(hide, pad, grid);
|
|
83
106
|
el.after(bar);
|
|
84
107
|
}
|
|
85
108
|
// xterm.js has no touch scrolling, so on a phone a swipe did nothing. Each line's
|