@rubytech/create-realagent 1.0.667 → 1.0.669
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/dist/index.js +70 -20
- package/package.json +1 -1
- package/payload/platform/plugins/docs/references/memory-guide.md +1 -1
- package/payload/platform/plugins/docs/references/troubleshooting.md +35 -0
- package/payload/platform/scripts/vnc.sh +39 -3
- package/payload/server/public/assets/{admin-Brug36E-.js → admin-tBhWa-8P.js} +1 -1
- package/payload/server/public/assets/{data-woLf2Tmp.js → data-CNSW6fWU.js} +1 -1
- package/payload/server/public/assets/{file-rN5uuyaV.js → file-BOrQXRZl.js} +1 -1
- package/payload/server/public/assets/{graph-DwWdaLpw.js → graph-BFLumOll.js} +2 -2
- package/payload/server/public/assets/{house-DnFgpCt2.js → house-sBJRwZUg.js} +1 -1
- package/payload/server/public/assets/{jsx-runtime-CSCPZpLN.css → jsx-runtime-ZtLisuuZ.css} +1 -1
- package/payload/server/public/assets/{public-BRrqpeVH.js → public-BSWCSR50.js} +1 -1
- package/payload/server/public/assets/{share-2-DLjRUEiG.js → share-2-DfQskeTu.js} +1 -1
- package/payload/server/public/assets/{useVoiceRecorder-D_efR3Nx.js → useVoiceRecorder-C2dkRb9r.js} +1 -1
- package/payload/server/public/assets/{x-L6KPMfIN.js → x-BpzGzquU.js} +1 -1
- package/payload/server/public/data.html +6 -6
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +7 -7
- package/payload/server/public/public.html +4 -4
- package/payload/server/server.js +1 -2
- /package/payload/server/public/assets/{jsx-runtime-XWiDQoTG.js → jsx-runtime-BPzLmqnP.js} +0 -0
package/dist/index.js
CHANGED
|
@@ -206,6 +206,33 @@ function canSudo() {
|
|
|
206
206
|
const result = spawnSync("sudo", ["-n", "true"], { stdio: "pipe", timeout: 5_000 });
|
|
207
207
|
return result.status === 0;
|
|
208
208
|
}
|
|
209
|
+
// Task 634 — verified-not-asserted apt-dep reconciliation.
|
|
210
|
+
//
|
|
211
|
+
// Returns the subset of `pkgs` that are not currently installed. Uses
|
|
212
|
+
// `dpkg -s <pkg>` per package (exit 0 = installed, any non-zero = missing)
|
|
213
|
+
// so we never parse dpkg's prose output for control flow
|
|
214
|
+
// (feedback_no_stdout_parsing_for_control_flow.md).
|
|
215
|
+
function pkgsMissing(pkgs) {
|
|
216
|
+
return pkgs.filter((p) => {
|
|
217
|
+
const r = spawnSync("dpkg", ["-s", p], { stdio: "pipe", timeout: 5_000 });
|
|
218
|
+
return r.status !== 0;
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Install a logical group of apt packages, then verify each one landed in
|
|
223
|
+
* dpkg's installed state. The post-install `dpkg -s` probe catches the
|
|
224
|
+
* partial-failure class where `apt-get install` returns 0 but a package did
|
|
225
|
+
* not actually install — silent regressions that would otherwise only
|
|
226
|
+
* surface at runtime when the binary is missing.
|
|
227
|
+
*/
|
|
228
|
+
function installAptGroup(label, pkgs) {
|
|
229
|
+
logFile(` apt install (${label}): ${pkgs.join(" ")}`);
|
|
230
|
+
shell("apt-get", ["install", "-y", ...pkgs], { sudo: true });
|
|
231
|
+
const stillMissing = pkgsMissing(pkgs);
|
|
232
|
+
if (stillMissing.length > 0) {
|
|
233
|
+
throw new Error(`apt-get install (${label}) returned 0 but packages are still not installed per dpkg -s: ${stillMissing.join(", ")}`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
209
236
|
// ---------------------------------------------------------------------------
|
|
210
237
|
// Installation steps
|
|
211
238
|
// ---------------------------------------------------------------------------
|
|
@@ -216,28 +243,51 @@ function installSystemDeps() {
|
|
|
216
243
|
console.log(" Skipping Linux-specific setup (not on Linux).");
|
|
217
244
|
return;
|
|
218
245
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
246
|
+
const BASE_DEPS = ["curl", "git", "unzip", "jq", "avahi-daemon", "avahi-utils", "poppler-utils", "ffmpeg"];
|
|
247
|
+
// xterm is the *preferred* terminal-emulator binary for the VNC-rendered
|
|
248
|
+
// Terminal surface (Task 632 — gnome-terminal is a D-Bus launcher that
|
|
249
|
+
// delegates window creation to the session's gnome-terminal-server,
|
|
250
|
+
// opening windows on the wrong display; xterm has no IPC layer and
|
|
251
|
+
// honours DISPLAY directly). Kept in the apt list unconditionally so
|
|
252
|
+
// vnc.sh's resolve_terminal_bin has a display-safe binary on every
|
|
253
|
+
// supported distro (Ubuntu 24.04 noble/universe, Debian 12 bookworm/main
|
|
254
|
+
// verified). xdotool (Task 632) backs the post-spawn display-membership
|
|
255
|
+
// assertion in vnc.sh check_window_on_display, closing the silent-fail
|
|
256
|
+
// class where PID is alive but no window is mapped on the target display.
|
|
257
|
+
const VNC_DEPS = ["tigervnc-standalone-server", "python3-websockify", "novnc", "xdg-utils", "chromium", "xterm", "xdotool"];
|
|
258
|
+
const WIFI_DEPS = ["hostapd", "dnsmasq"];
|
|
259
|
+
// tmux backs the admin terminal's persistent named session (Task 591).
|
|
260
|
+
// ttyd is NOT in Debian Bookworm's apt repo (Task 602) — it ships as a
|
|
261
|
+
// pinned upstream binary installed by provisionTtydBinary() in step 11.
|
|
262
|
+
const TERMINAL_DEPS = ["tmux"];
|
|
263
|
+
const ALL_APT_DEPS = [...BASE_DEPS, ...VNC_DEPS, ...WIFI_DEPS, ...TERMINAL_DEPS];
|
|
264
|
+
// Task 634 — verify the "deps are present" assumption with `dpkg -s` instead
|
|
265
|
+
// of asserting it (feedback_loud_failures.md). The previous silent-skip
|
|
266
|
+
// branch was benign until Task 632 added xdotool (the first new apt dep
|
|
267
|
+
// since the skip path became load-bearing on user-password-sudo devices).
|
|
268
|
+
const missing = pkgsMissing(ALL_APT_DEPS);
|
|
269
|
+
if (missing.length === 0) {
|
|
270
|
+
logFile(` all system deps present per dpkg -s (${ALL_APT_DEPS.length} packages) — skipping apt install`);
|
|
271
|
+
console.log(` All ${ALL_APT_DEPS.length} system deps already installed — skipping apt install.`);
|
|
238
272
|
}
|
|
239
273
|
else {
|
|
240
|
-
|
|
274
|
+
const canEscalate = canSudo() || process.stdout.isTTY === true;
|
|
275
|
+
if (!canEscalate) {
|
|
276
|
+
const repair = `sudo apt-get install -y ${missing.join(" ")}`;
|
|
277
|
+
console.error(` MISSING ${missing.length} system deps per dpkg -s: ${missing.join(" ")}`);
|
|
278
|
+
console.error(` Non-interactive sudo is unavailable; cannot prompt for password from a non-TTY shell.`);
|
|
279
|
+
console.error(` Re-run this installer from an interactive shell, or repair manually:`);
|
|
280
|
+
console.error(` ${repair}`);
|
|
281
|
+
logFile(` FAIL: missing apt deps without interactive sudo: ${missing.join(",")}`);
|
|
282
|
+
throw new Error(`installSystemDeps: missing packages (${missing.join(", ")}) and sudo is unavailable non-interactively — repair with: ${repair}`);
|
|
283
|
+
}
|
|
284
|
+
console.log(` Missing apt deps (${missing.length}): ${missing.join(", ")}`);
|
|
285
|
+
console.log(` Installing via sudo apt-get — sudo may prompt for your password...`);
|
|
286
|
+
shell("apt-get", ["update"], { sudo: true });
|
|
287
|
+
installAptGroup("base utilities", BASE_DEPS);
|
|
288
|
+
installAptGroup("VNC stack", VNC_DEPS);
|
|
289
|
+
installAptGroup("WiFi AP", WIFI_DEPS);
|
|
290
|
+
installAptGroup("terminal", TERMINAL_DEPS);
|
|
241
291
|
}
|
|
242
292
|
// Hostname resolution — four sources, in priority order:
|
|
243
293
|
// 1. --hostname flag (unconditional — the caller is the authority)
|
package/package.json
CHANGED
|
@@ -84,7 +84,7 @@ Ask naturally:
|
|
|
84
84
|
|
|
85
85
|
Maxy answers relational questions — "list all my people", "how many tasks do I have", "find the person with email X", "show me the 20 most recently created nodes" — via direct read-only Cypher against your Neo4j. This is faster and more precise than semantic search when the question is "the exact set where", not "things similar to".
|
|
86
86
|
|
|
87
|
-
You can also open a visual view of your graph at any time from the burger menu → **Graph**. Click the **Filter** button in the toolbar to open the filter menu — it lists only the node types that actually exist in your graph, one row per type, showing your per-type node count and sorted so the most-connected types sit at the top. Leaf types that only appear inside a parent (messages inside a conversation, sections inside a document) are never filter rows — you reach them by clicking the parent and exploring its neighbourhood. Infrastructural types (`ToolCall`, `WorkflowRun`, `WorkflowStep`, `ReviewAlert`) never appear as filter rows — the first three are execution plumbing, and `ReviewAlert` has its own dedicated surface in admin chat. Active rows render a force-directed map, coloured by label (Person, Service, KnowledgeDocument, Task, …). Click a node to
|
|
87
|
+
You can also open a visual view of your graph at any time from the burger menu → **Graph**. Click the **Filter** button in the toolbar to open the filter menu — it lists only the node types that actually exist in your graph, one row per type, showing your per-type node count and sorted so the most-connected types sit at the top. Leaf types that only appear inside a parent (messages inside a conversation, sections inside a document) are never filter rows — you reach them by clicking the parent and exploring its neighbourhood. Infrastructural types (`ToolCall`, `WorkflowRun`, `WorkflowStep`, `ReviewAlert`) never appear as filter rows — the first three are execution plumbing, and `ReviewAlert` has its own dedicated surface in admin chat. Active rows render a force-directed map, coloured by label (Person, Service, KnowledgeDocument, Task, …). Click a node from the filter view to explore its neighbourhood. Once inside a neighbourhood, clicking another node (a Message inside a Conversation, for example) opens its properties in the side panel without collapsing the view — peer Messages stay on canvas and **Back** still returns to your filter rows in one step. Click the **Back** control or empty canvas to return to your filter view with the same rows still selected. Type in the search box to highlight matches; submitting a search also widens the filter to include any node types the hits belong to, so relevant matches render instead of disappearing into a "not in current view" banner. The **×** buttons on the search box and inside the filter menu clear the current search and the current selection respectively — clearing the filter selection does not touch your saved default.
|
|
88
88
|
|
|
89
89
|
Conversations and Messages carry role/channel sublabels so you can read the chat topology by colour alone — admin vs public conversations and user vs assistant messages render in distinct shades, and the filter menu splits them into separate rows.
|
|
90
90
|
|
|
@@ -172,6 +172,41 @@ Most common failures and fixes:
|
|
|
172
172
|
- `[terminal-launch] failed err="window absent from target display after spawn" pid=<N> display=:99 observed_windows=0` → the spawned emulator's window landed on the wrong display (Task 632 — almost always a stale gnome-terminal binary on an upgraded install; the fix ships `xterm` as the `:99` default but a stale `resolve_terminal_bin` on an old bundle can still trigger it). Check `which gnome-terminal xterm xdotool` — all three should exist; if not, re-run the installer. Also check `DISPLAY=:99 xdotool search --onlyvisible --class '.'` manually: empty output confirms no window on `:99`; a non-empty result after a fresh click means the window IS there and the check itself is wrong (file an issue).
|
|
173
173
|
- `ensure-terminal action="escalate-vnc-restart"` followed by `degraded` → `Xtigervnc` itself is not coming up. Check `~/.maxy/logs/vnc-boot.log` for the tigervnc startup lines.
|
|
174
174
|
|
|
175
|
+
## Terminal fails after upgrade — `Invalid response` or `window absent from target display`
|
|
176
|
+
|
|
177
|
+
**Symptom:** You upgraded a Maxy device and the header-menu **Terminal** click now fails — overlay shows `Invalid response`, or `terminal-launch.log` shows `[terminal-launch] failed err="window absent from target display after spawn" pid=<N> display=:99 observed_windows=0 transport=vnc cmd="/usr/bin/xterm "`. The terminal worked on the previous version and the upgrade reported success.
|
|
178
|
+
|
|
179
|
+
**What it means:** The installer declared a new apt dep between versions (e.g. `xdotool` in 1.0.667), but on your device the installer's apt step was silently skipped because `sudo` requires a password and the installer could not escalate non-interactively. The declared dep was never installed, and `vnc.sh check_window_on_display` then either failed to find the binary (exit 127 — Task 634 now surfaces this as a distinct `failed err="xdotool not installed — re-run installer to repair"` line) or reached the `window absent` path because its preflight tool was missing. See `.docs/deployment.md` ("sudo interactivity contract") for the full mechanism.
|
|
180
|
+
|
|
181
|
+
**Check:**
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
dpkg -s xdotool 2>&1 | head -2 # should report "Status: install ok installed"
|
|
185
|
+
which xdotool # should return /usr/bin/xdotool
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Fix — two options:**
|
|
189
|
+
|
|
190
|
+
1. **Re-run the installer from an interactive shell** (preferred on upgrade — picks up any future missing deps too):
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
npx -y @rubytech/create-maxy@latest
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
The installer now probes `dpkg -s` for every declared apt dep and either prompts you for your sudo password to install missing ones, or loud-fails non-interactively with the exact `sudo apt-get install -y <list>` command to repair. It will no longer print `Skipping apt-get (deps assumed present from prior install)` and continue as if green.
|
|
197
|
+
|
|
198
|
+
2. **Repair manually** (faster if you only want the one binary):
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
sudo apt-get install -y xdotool
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Then click **Terminal** again — it should spawn within a second and the overlay should render the xterm.
|
|
205
|
+
|
|
206
|
+
**Regression boundary:** if you see `[terminal-launch] failed err="xdotool not installed — re-run installer to repair"` in `~/.maxy/logs/terminal-launch.log`, the vnc.sh preflight is telling you the binary is missing before spawn — same class as above, distinct from the Task 632 `window absent from target display after spawn` string. The two strings never appear for the same click.
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
175
210
|
## Terminal iframe renders black and cursor vanishes over the canvas
|
|
176
211
|
|
|
177
212
|
**Symptom:** Header-menu Terminal click appears to succeed — no error toast, overlay opens — but the iframe renders uniformly black, keystrokes do not reach any shell, and the mouse cursor disappears the moment it enters the iframe (visible elsewhere in the page).
|
|
@@ -214,6 +214,16 @@ start_chrome() {
|
|
|
214
214
|
# loud-fail log if neither is installed — matches the operator invariant
|
|
215
215
|
# "no ttyd fallback, no silent substitution" from Task 627. gnome-terminal
|
|
216
216
|
# retains `--wait` (see Task 627 pgrep-visibility fix). xterm takes no flag.
|
|
217
|
+
# xterm flags for the :99 VNC framebuffer. Fontconfig alias `monospace`
|
|
218
|
+
# resolves via /etc/fonts to the distro's default monospace face (DejaVu
|
|
219
|
+
# Sans Mono on Ubuntu/Debian) — no quoting needed, so the flag string
|
|
220
|
+
# survives unquoted $flags word-splitting in start_terminal_on. Geometry
|
|
221
|
+
# 160x45 fills the Xtigervnc display (1280x800 — see Xtigervnc -geometry
|
|
222
|
+
# flag below) at 11pt; the prior empty flag string left xterm at its 80x24
|
|
223
|
+
# default with the 6x13 `fixed` bitmap font, which rendered ~480x312 px of
|
|
224
|
+
# the 1280x800 framebuffer with a black void around it.
|
|
225
|
+
XTERM_VNC_FLAGS='-fa monospace -fs 11 -geometry 160x45'
|
|
226
|
+
|
|
217
227
|
resolve_terminal_bin() {
|
|
218
228
|
local target_display="${1:-:99}"
|
|
219
229
|
local xterm_bin='' gnome_bin=''
|
|
@@ -221,17 +231,35 @@ resolve_terminal_bin() {
|
|
|
221
231
|
[ -x /usr/bin/gnome-terminal ] && gnome_bin='/usr/bin/gnome-terminal'
|
|
222
232
|
|
|
223
233
|
if [ "$target_display" = ":99" ]; then
|
|
224
|
-
[ -n "$xterm_bin" ] && { printf '%s\t%s\n' "$xterm_bin"
|
|
234
|
+
[ -n "$xterm_bin" ] && { printf '%s\t%s\n' "$xterm_bin" "$XTERM_VNC_FLAGS"; return 0; }
|
|
225
235
|
[ -n "$gnome_bin" ] && { printf '%s\t%s\n' "$gnome_bin" '--wait'; return 0; }
|
|
226
236
|
else
|
|
227
237
|
[ -n "$gnome_bin" ] && { printf '%s\t%s\n' "$gnome_bin" '--wait'; return 0; }
|
|
228
|
-
[ -n "$xterm_bin" ] && { printf '%s\t%s\n' "$xterm_bin"
|
|
238
|
+
[ -n "$xterm_bin" ] && { printf '%s\t%s\n' "$xterm_bin" "$XTERM_VNC_FLAGS"; return 0; }
|
|
229
239
|
fi
|
|
230
240
|
tlog "failed err=\"no terminal emulator installed (expected /usr/bin/gnome-terminal or /usr/bin/xterm)\""
|
|
231
241
|
log "ERROR: no terminal emulator binary found — install xterm (apt-get install -y xterm)"
|
|
232
242
|
return 1
|
|
233
243
|
}
|
|
234
244
|
|
|
245
|
+
# Task 634 — runtime preflight for terminal-launch dependencies. Separates
|
|
246
|
+
# exit 127 (xdotool missing from PATH) from exit 1 (xdotool present but no
|
|
247
|
+
# window mapped) in check_window_on_display. The installer now verifies
|
|
248
|
+
# apt deps via `dpkg -s` but an operator can still `apt remove xdotool`
|
|
249
|
+
# post-install, so this is the matching runtime guard. Emits the failure
|
|
250
|
+
# string on stderr so ensureTerminal's extractFailureLine captures it
|
|
251
|
+
# verbatim into server.log's `ensure-terminal err=...` field.
|
|
252
|
+
preflight_terminal_deps() {
|
|
253
|
+
if command -v xdotool >/dev/null 2>&1; then
|
|
254
|
+
log "xdotool: $(command -v xdotool)"
|
|
255
|
+
return 0
|
|
256
|
+
fi
|
|
257
|
+
tlog "failed err=\"xdotool not installed — re-run installer to repair\""
|
|
258
|
+
log "ERROR: xdotool missing — start-terminal cannot assert display-membership (re-run: npx -y @rubytech/create-maxy@latest)"
|
|
259
|
+
echo "[terminal-launch] failed err=\"xdotool not installed — re-run installer to repair\"" >&2
|
|
260
|
+
return 1
|
|
261
|
+
}
|
|
262
|
+
|
|
235
263
|
# Verify that at least one visible window is mapped on $target_display. Closes
|
|
236
264
|
# the "PID visible in pgrep but window is not on target" class of silent fail
|
|
237
265
|
# (Task 632). Uses xdotool's exit code directly — no stdout parsing for
|
|
@@ -243,8 +271,14 @@ resolve_terminal_bin() {
|
|
|
243
271
|
# Returns 0 if any visible window appears on the display within ~1s, 1 otherwise.
|
|
244
272
|
check_window_on_display() {
|
|
245
273
|
local target_display="$1"
|
|
274
|
+
# Task 634 — route xdotool stderr to vnc-boot.log instead of /dev/null.
|
|
275
|
+
# preflight_terminal_deps removes the 127-vs-1 conflation from production,
|
|
276
|
+
# but if xdotool ever fails for a non-missing-binary reason (broken X
|
|
277
|
+
# server, malformed DISPLAY), the diagnostic now lands in a grep-addressable
|
|
278
|
+
# log instead of vanishing. Control flow still depends solely on the exit
|
|
279
|
+
# code (feedback_no_stdout_parsing_for_control_flow.md).
|
|
246
280
|
for _ in 1 2 3; do
|
|
247
|
-
if DISPLAY="$target_display" xdotool search --onlyvisible --class '.' >/dev/null 2
|
|
281
|
+
if DISPLAY="$target_display" xdotool search --onlyvisible --class '.' >/dev/null 2>>"$LOG_FILE"; then
|
|
248
282
|
return 0
|
|
249
283
|
fi
|
|
250
284
|
sleep 0.3
|
|
@@ -386,10 +420,12 @@ start_terminal_on() {
|
|
|
386
420
|
}
|
|
387
421
|
|
|
388
422
|
start_terminal() {
|
|
423
|
+
preflight_terminal_deps || return 1
|
|
389
424
|
start_terminal_on ":99" "vnc"
|
|
390
425
|
}
|
|
391
426
|
|
|
392
427
|
start_terminal_native() {
|
|
428
|
+
preflight_terminal_deps || return 1
|
|
393
429
|
discover_native_session
|
|
394
430
|
start_terminal_on "${NATIVE_DISPLAY}" "native"
|
|
395
431
|
}
|