@rubytech/create-maxy 1.0.684 → 1.0.686
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 +49 -203
- package/dist/pinned-binaries.js +10 -41
- package/dist/uninstall.js +47 -19
- package/package.json +1 -1
- package/payload/platform/config/brand.json +1 -0
- package/payload/platform/plugins/cloudflare/scripts/setup-tunnel.sh +35 -9
- package/payload/platform/plugins/docs/PLUGIN.md +2 -0
- package/payload/platform/plugins/docs/references/cloudflare.md +1 -1
- package/payload/platform/plugins/docs/references/deployment.md +19 -6
- package/payload/platform/plugins/docs/references/graph.md +38 -0
- package/payload/platform/plugins/docs/references/platform.md +10 -7
- package/payload/platform/plugins/docs/references/troubleshooting.md +23 -13
- package/payload/platform/scripts/vnc.sh +7 -7
- package/payload/platform/templates/systemd/{maxy-edge.service → edge.service.template} +9 -6
- package/payload/server/maxy-edge.js +7 -369
- package/payload/server/public/assets/admin-BqLtaMVu.js +352 -0
- package/payload/server/public/assets/{data-DUSyrydY.js → data-BZ7v-zug.js} +1 -1
- package/payload/server/public/assets/{file-CDJ6dUV3.js → file-CScYkZq5.js} +1 -1
- package/payload/server/public/assets/graph-tjXdtwk-.js +50 -0
- package/payload/server/public/assets/{house-CNP_bwvT.js → house-CdFRNujU.js} +1 -1
- package/payload/server/public/assets/{jsx-runtime-BFFQvkdQ.css → jsx-runtime-Og0q7dXg.css} +1 -1
- package/payload/server/public/assets/{public-sHoAccvb.js → public-CrkQJek6.js} +2 -2
- package/payload/server/public/assets/{share-2-DBcb9j6E.js → share-2-Ev-D4Lm9.js} +1 -1
- package/payload/server/public/assets/{useVoiceRecorder-CtSgpc95.js → useVoiceRecorder-DyDXH7EA.js} +2 -2
- package/payload/server/public/assets/{x-CTVJaC_u.js → x-D5W7ddgP.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 -8
- package/payload/server/public/public.html +4 -4
- package/payload/server/server.js +830 -258
- package/payload/platform/templates/dotfiles/.tmux.conf +0 -1
- package/payload/platform/templates/systemd/maxy-ttyd.service +0 -25
- package/payload/server/public/assets/admin-WQxJgaus.js +0 -362
- package/payload/server/public/assets/admin-kHJ-D0s7.css +0 -1
- package/payload/server/public/assets/graph-CWcYp5bE.js +0 -50
- /package/payload/server/public/assets/{jsx-runtime-BVKWELH6.js → jsx-runtime-CHqDsKlc.js} +0 -0
|
@@ -68,19 +68,32 @@ The logs will show which service failed to start and why. Common causes:
|
|
|
68
68
|
|
|
69
69
|
## Systemd units on each device
|
|
70
70
|
|
|
71
|
-
Each
|
|
71
|
+
Each installed brand runs two per-brand `--user` systemd units (Task 662 + Task 664 — unit filenames are prefixed with the brand's `hostname` so two brands on the same device never share a unit file):
|
|
72
72
|
|
|
73
|
-
- `
|
|
74
|
-
- `
|
|
75
|
-
- `maxy-ttyd.service` — `ttyd` bound to `127.0.0.1:7681`, running `tmux new-session -A -s maxy-pty`. Owns the byte-stream admin terminal rendered by xterm.js in the header overlay and the Software Update modal (Task 657). Independent of `maxy-ui` and `maxy-edge`; outlives service restarts so scrollback is preserved.
|
|
73
|
+
- `{hostname}.service` — the admin + public HTTP server on `127.0.0.1:19199`. Restarted by the upgrade flow; short downtime is expected during steps 8→11 of an upgrade.
|
|
74
|
+
- `{hostname}-edge.service` — the always-on public listener on the configured port (default 19200). Reverse-proxies HTTP to the main brand service and handles `/websockify` (VNC) WebSocket upgrades locally. Does NOT restart during an upgrade — the browser WebSocket stays connected by construction.
|
|
76
75
|
|
|
77
|
-
|
|
76
|
+
Upgrade and Cloudflare setup (Task 664) run as detached actions: `systemd-run --user` transient units per invocation with stdout+stderr persisted to `~/.maxy/logs/actions/<actionId>.log` and streamed to the UI via SSE. No boot-time service file exists for these.
|
|
77
|
+
|
|
78
|
+
If an action looks stuck, read `~/.maxy/logs/actions/<actionId>.log` directly for the full output, or `journalctl --user --identifier=maxy-action-<actionId>` for systemd's record.
|
|
79
|
+
|
|
80
|
+
**Pre-Task-662 / pre-Task-664 upgrade** — devices that ran an installer before Task 662 have legacy shared `maxy-edge.service` / `maxy-ttyd.service` units; devices that ran before Task 664 have per-brand `{hostname}-ttyd.service` units plus a pinned `/usr/local/bin/ttyd` binary. Neither is removed automatically — do this cleanup once per device before re-running any installer:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
systemctl --user stop maxy-edge maxy-ttyd realagent-ttyd 2>/dev/null || true
|
|
84
|
+
systemctl --user disable maxy-edge maxy-ttyd realagent-ttyd 2>/dev/null || true
|
|
85
|
+
rm -f ~/.config/systemd/user/maxy-edge.service \
|
|
86
|
+
~/.config/systemd/user/maxy-ttyd.service \
|
|
87
|
+
~/.config/systemd/user/realagent-ttyd.service
|
|
88
|
+
sudo rm -f /usr/local/bin/ttyd
|
|
89
|
+
systemctl --user daemon-reload
|
|
90
|
+
```
|
|
78
91
|
|
|
79
92
|
## Running multiple brands on one device
|
|
80
93
|
|
|
81
94
|
A single Pi or laptop can host more than one brand (for example Maxy and Real Agent) side by side. Each brand runs as its own service on its own port, with its own install directory and its own data. Installing one brand does not touch the other.
|
|
82
95
|
|
|
83
|
-
- **Separate:** each brand has its own install folder (`~/maxy/`, `~/realagent/`), its own config folder (`~/.maxy/`, `~/.realagent/`), its own web port, its own Cloudflare tunnel state, and by default its own Neo4j database (Maxy on bolt port 7687, Real Agent on 7688).
|
|
96
|
+
- **Separate:** each brand has its own install folder (`~/maxy/`, `~/realagent/`), its own config folder (`~/.maxy/`, `~/.realagent/`), its own web port, its own Cloudflare tunnel state, its own edge systemd unit (`maxy-edge.service` vs `realagent-edge.service`), and by default its own Neo4j database (Maxy on bolt port 7687, Real Agent on 7688). Action runner units are transient and per-invocation, not per-brand, so no naming conflict is possible.
|
|
84
97
|
- **Shared:** both brands share the system Chromium/VNC stack, the Ollama model server, and the `cloudflared` command itself. Browser automation is serialised — one admin session at a time across both brands.
|
|
85
98
|
|
|
86
99
|
To install a second brand on a device that already runs the first, just run the other installer. No flags needed for isolation:
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Graph View
|
|
2
|
+
|
|
3
|
+
The **Graph** admin page (`/graph`) renders a force-directed view of your
|
|
4
|
+
account's Neo4j subgraph. Labels on the canvas follow the zoom level, so you
|
|
5
|
+
see the most useful identity at every scale.
|
|
6
|
+
|
|
7
|
+
## Conversation label tiers
|
|
8
|
+
|
|
9
|
+
Conversation nodes carry the most operator-meaningful identity in the
|
|
10
|
+
subgraph (the conversation name or summary, the date it started, the message
|
|
11
|
+
count). They render in one of three tiers, switched by canvas scale:
|
|
12
|
+
|
|
13
|
+
| Zoom | Label shape | Example |
|
|
14
|
+
|------|-------------|---------|
|
|
15
|
+
| Zoomed out (< 0.7×) | Compact — one line, capped at 24 characters. Preserves the no-overlap contract that matters when nodes are tightly packed. | `Maxyfi branding conflict…` |
|
|
16
|
+
| Mid zoom (0.7× to 1.3×) | Wrapped — up to two lines of 24 characters each, soft-ellipsis on overflow. Full name is visible without hover. | `Maxyfi branding conflict` / `with Rubytech` |
|
|
17
|
+
| Zoomed in (≥ 1.3×) | Detailed — wrapped name plus a metadata line reading `YYYY-MM-DD · N msgs`. | `Maxyfi branding conflict` / `with Rubytech` / `2026-04-23 · 7 msgs` |
|
|
18
|
+
|
|
19
|
+
Non-Conversation nodes (People, Messages, Tasks, WorkflowRuns, etc.) keep
|
|
20
|
+
their concise single-line labels at every zoom level — the canvas stays
|
|
21
|
+
readable when you zoom out to see a large subgraph.
|
|
22
|
+
|
|
23
|
+
Tier transitions are debounced so spinning the scroll wheel does not cause
|
|
24
|
+
label flicker; labels only rewrite once zoom settles on a new tier.
|
|
25
|
+
|
|
26
|
+
## Tooltips and side panel
|
|
27
|
+
|
|
28
|
+
Hovering a node still shows the full 5-line tooltip (display name, labels,
|
|
29
|
+
id, created at, updated at). Clicking a Conversation opens the side panel
|
|
30
|
+
with the full property table — zoom-tier changes never alter these paths.
|
|
31
|
+
|
|
32
|
+
## Trashed conversations
|
|
33
|
+
|
|
34
|
+
Trashed Conversation nodes are hidden by default. Toggle **Show trashed** in
|
|
35
|
+
the filter popover to surface them; they render with a faded fill and dashed
|
|
36
|
+
border, with their zoom-tier labels intact. The `N msgs` count excludes
|
|
37
|
+
trashed Messages, so the detailed-tier label reflects only live turns in the
|
|
38
|
+
conversation.
|
|
@@ -62,19 +62,22 @@ There is no dashboard, no settings panel, no menus. Everything is done through c
|
|
|
62
62
|
|
|
63
63
|
The chat input auto-grows as you type — it expands to fit your message and shrinks back when you delete text. You can also drag the resize handle above the input to set a custom height.
|
|
64
64
|
|
|
65
|
-
##
|
|
65
|
+
## Software Update and Cloudflare Setup
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
There is no free-form terminal surface in the admin UI — ad-hoc shell access stays on SSH. The two flows that used to need a terminal (upgrade, Cloudflare tunnel setup) run as **detached actions** instead.
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
**Software Update flow.** Click Upgrade in the modal → the modal asks for your sudo password once → the admin server validates it and launches a transient `systemd-run --user` unit running `npx -y @rubytech/create-maxy@latest`. The action unit is a peer of the brand service (not a child), so the installer's mid-run `systemctl --user restart maxy` does not kill the upgrade itself — it finishes running, then the web UI reloads on the new version. The modal shows a live log panel with three event types:
|
|
70
|
+
- every stdout/stderr line the installer emits, timestamped server-side;
|
|
71
|
+
- a heartbeat every 5 seconds carrying `state=active` + `last_phase` so you can see the installer is alive even during silent phases (tarball download, dep install);
|
|
72
|
+
- a final banner on exit with the return code and elapsed time.
|
|
70
73
|
|
|
71
|
-
|
|
74
|
+
If the browser drops the SSE connection mid-upgrade (typical during the maxy restart window), the panel reconnects within two seconds and replays any lines you missed from the persisted log.
|
|
72
75
|
|
|
73
|
-
**
|
|
76
|
+
**Cloudflare setup flow.** Same pattern — POST to `/api/admin/cloudflare/setup` launches a `cloudflare-setup` action that runs `~/setup-tunnel.sh <brand> <port> <hostname...>`. When the script emits the OAuth consent URL on stdout, the log panel surfaces an **"Authorise in Cloudflare"** button; clicking it opens the consent page in a new tab. After you approve, the script's callback receives `cert.pem` and the setup continues through `tunnel create`/`route`/`run`. On devices where a VNC Chromium is also running, the script can drive the click via CDP automatically (same button remains a harmless safety net).
|
|
74
77
|
|
|
75
|
-
**
|
|
78
|
+
**Sudo password** is prompted once per upgrade. The admin server pipes it to `sudo -S -v` to validate + cache, then forwards it to the action unit via `systemd-run --setenv=SUDO_PASSWORD` so the installer's in-unit `sudo -S` reads it directly — per-TTY sudoers configurations where the user-level cache does not cover a fresh systemd-run unit still work. The password is never written to any log, SSE frame, or persisted file.
|
|
76
79
|
|
|
77
|
-
**
|
|
80
|
+
**Log files.** Each action writes its full output to `~/.maxy/logs/actions/<actionId>.log` for seven days. `journalctl --user --identifier=maxy-action-<actionId>` gives the systemd-level view.
|
|
78
81
|
|
|
79
82
|
**Authorisation** is inherited from the same `canAccessAdmin()` gate that wraps every `/api/admin/*` route.
|
|
80
83
|
|
|
@@ -93,26 +93,36 @@ If the initial Cloudflare login fails during setup, Maxy will fall back to askin
|
|
|
93
93
|
|
|
94
94
|
---
|
|
95
95
|
|
|
96
|
-
##
|
|
96
|
+
## Action runner — upgrade or Cloudflare setup appears stuck
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
Task 664 replaced the ttyd/xterm admin terminal with a detached action runner. Upgrades and Cloudflare setup now run under transient `systemd-run --user` units whose stdout+stderr land in a persisted per-action log, streamed to the browser via SSE.
|
|
99
99
|
|
|
100
|
-
**
|
|
100
|
+
**Heartbeat stalled** (log panel header shows rising `silent Ns` amber badge).
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
- Open the log panel header: `state: <systemd_state>` tells you the unit's current state.
|
|
103
|
+
- `systemd_state: active` + silent >30s → the child is running but emitting nothing. Expected for `npx` while it downloads the tarball, or `cloudflared tunnel login` waiting for an operator click.
|
|
104
|
+
- `systemd_state: inactive` + no `exit` event → the exit event was missed; the server-side heartbeat timer will emit it on the next 5 s tick.
|
|
105
|
+
- `systemd_state: failed` → see the next symptom.
|
|
103
106
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
107
|
+
**`ActiveState=failed`** (log panel's exit banner shows a non-zero code).
|
|
108
|
+
|
|
109
|
+
- Read the persisted log directly: `~/.maxy/logs/actions/<actionId>.log` (or `.realagent/...`) has every stdout+stderr line the unit emitted.
|
|
110
|
+
- `journalctl --user --identifier=maxy-action-<actionId>` shows systemd's own record including ExecStartPre/ExecStopPost if any.
|
|
111
|
+
- Common cases:
|
|
112
|
+
- Wrong sudo password → `sudo: 1 incorrect password attempt` near the top of the log; re-open the upgrade modal, enter the correct password.
|
|
113
|
+
- Network failure during `npx` → `npm ERR! network` lines; re-open the modal and retry when network is restored.
|
|
114
|
+
- `cloudflared tunnel login` timed out waiting for OAuth → action exits non-zero with `Timed out after Ns waiting for cert.pem`; re-trigger from the Cloudflare setup form.
|
|
115
|
+
|
|
116
|
+
**"Authorise in Cloudflare" button never appears** (cloudflare-setup action).
|
|
117
|
+
|
|
118
|
+
The setup script emits either the raw `https://dash.cloudflare.com/argotunnel?...` URL in cloudflared's own stderr OR an explicit `OAUTH_URL: <url>` stdout line once URL extraction succeeds. The log panel's regex matches either. If neither appears within ~15 s of launch:
|
|
108
119
|
|
|
109
|
-
-
|
|
110
|
-
-
|
|
111
|
-
- Neither line appears → the WebSocket itself isn't connecting; see the "Admin terminal blank / flashing cursor" section below (pre-Task-657 sections are historical, not applicable).
|
|
120
|
+
- The action log file (`~/.maxy/logs/actions/<actionId>.log`) should show `[script:setup-tunnel:cloudflared]` lines. No such lines → cloudflared isn't spawning (check whether the binary is on PATH in the transient unit; `systemctl --user show maxy-action-<actionId>` reveals the environment).
|
|
121
|
+
- Lines present but no URL → cloudflared output-format drift; file a task with the last 20 lines of the action log.
|
|
112
122
|
|
|
113
|
-
**
|
|
123
|
+
**Log file missing (action stream returns 404).**
|
|
114
124
|
|
|
115
|
-
|
|
125
|
+
The transient unit was auto-collected by systemd before the client subscribed. Race condition: action finished in <1 s. The per-action log file is retained for 7 days; look for it by name under `~/.maxy/logs/actions/`. If it isn't there, the unit failed before any output (check `journalctl --user -u maxy-action-<id>`).
|
|
116
126
|
|
|
117
127
|
---
|
|
118
128
|
|
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
# Chromium :9222 — headed browser with CDP enabled
|
|
11
11
|
# (Playwright MCP connects via --cdp-endpoint)
|
|
12
12
|
#
|
|
13
|
-
# Task
|
|
14
|
-
#
|
|
15
|
-
#
|
|
13
|
+
# Task 664 retired the admin-UI terminal surface entirely. This script
|
|
14
|
+
# no longer spawns GUI terminal emulators of any kind; upgrades and
|
|
15
|
+
# cloudflare-setup actions run via the detached action runner
|
|
16
|
+
# (/api/admin/actions/*) rather than an in-browser terminal.
|
|
16
17
|
#
|
|
17
18
|
# Display modes (DISPLAY_MODE env var, set by installer --display flag):
|
|
18
19
|
# virtual (default) — Chromium runs on :99 (VNC virtual display)
|
|
@@ -185,10 +186,9 @@ start_chrome() {
|
|
|
185
186
|
}
|
|
186
187
|
|
|
187
188
|
# ---------------------------------------------------------------------------
|
|
188
|
-
# Task
|
|
189
|
-
# TerminalOverlay
|
|
190
|
-
#
|
|
191
|
-
# Only the Chromium surface remains for BrowserOverlay.
|
|
189
|
+
# Task 664 retired the admin-UI terminal surface entirely: the header
|
|
190
|
+
# TerminalOverlay + UpdateModal embedded terminal stack is gone. Only
|
|
191
|
+
# the Chromium surface remains for BrowserOverlay.
|
|
192
192
|
# ---------------------------------------------------------------------------
|
|
193
193
|
|
|
194
194
|
start_chrome_native() {
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
[Unit]
|
|
2
|
-
Description=
|
|
3
|
-
# No ordering dependency on
|
|
4
|
-
#
|
|
5
|
-
# the edge is listening, but this unit has no such reciprocal
|
|
2
|
+
Description=Edge service (public port + VNC transport — independent of the main brand service)
|
|
3
|
+
# No ordering dependency on the main brand service: the edge is the long-running
|
|
4
|
+
# front door. The main brand unit declares Wants/After this unit so it only
|
|
5
|
+
# starts once the edge is listening, but this unit has no such reciprocal
|
|
6
|
+
# dependency.
|
|
6
7
|
|
|
7
8
|
[Service]
|
|
8
9
|
Type=simple
|
|
9
10
|
# ExecStartPre owns the VNC stack so an `npx -y @rubytech/create-maxy@latest`
|
|
10
|
-
# run from the admin
|
|
11
|
-
#
|
|
11
|
+
# run from the admin UI can restart the main brand service without taking
|
|
12
|
+
# Xtigervnc or websockify down with it. Task 647. Task 664 removed the ttyd
|
|
13
|
+
# transport — upgrades now run via systemd-run --user transient units that
|
|
14
|
+
# are peers of maxy-ui and survive its restart structurally.
|
|
12
15
|
ExecStartPre=/bin/bash __INSTALL_DIR__/platform/scripts/vnc.sh start
|
|
13
16
|
ExecStart=/usr/bin/node __INSTALL_DIR__/server/maxy-edge.js
|
|
14
17
|
ExecStopPost=/bin/bash __INSTALL_DIR__/platform/scripts/vnc.sh stop
|