@rubytech/create-maxy-code 0.1.108 → 0.1.109
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/payload/platform/plugins/cloudflare/PLUGIN.md +1 -1
- package/payload/platform/plugins/cloudflare/scripts/list-cf-domains.sh +12 -12
- package/payload/platform/plugins/cloudflare/scripts/list-cf-domains.ts +9 -43
- package/payload/platform/plugins/cloudflare/scripts/setup-tunnel.sh +27 -29
- package/payload/platform/plugins/cloudflare/skills/setup-tunnel/SKILL.md +14 -9
- package/payload/platform/plugins/docs/references/platform.md +4 -22
- package/payload/platform/plugins/docs/references/plugins-guide.md +1 -1
- package/payload/platform/plugins/docs/references/troubleshooting.md +4 -316
- package/payload/platform/plugins/venture-studio/PLUGIN.md +35 -4
- package/payload/platform/plugins/venture-studio/bin/scaffold.sh +104 -0
- package/payload/platform/plugins/venture-studio/skills/investor-data-room/SKILL.md +3 -1
- package/payload/platform/plugins/work/mcp/dist/cli/project-create-cli.d.ts +2 -0
- package/payload/platform/plugins/work/mcp/dist/cli/project-create-cli.d.ts.map +1 -0
- package/payload/platform/plugins/work/mcp/dist/cli/project-create-cli.js +78 -0
- package/payload/platform/plugins/work/mcp/dist/cli/project-create-cli.js.map +1 -0
- package/payload/platform/scripts/vnc.sh +4 -3
- package/payload/premium-plugins/venture-studio/PLUGIN.md +35 -4
- package/payload/premium-plugins/venture-studio/bin/scaffold.sh +104 -0
- package/payload/premium-plugins/venture-studio/skills/investor-data-room/SKILL.md +3 -1
- package/payload/server/{chunk-AGFS3TVN.js → chunk-FSPPVVWM.js} +1303 -496
- package/payload/server/maxy-edge.js +21 -259
- package/payload/server/public/assets/{ChatInput-DJsqm_Gf.js → ChatInput-CsnIedhS.js} +1 -5
- package/payload/server/public/assets/{Checkbox-DGZG9BKc.js → Checkbox-CWugFyFT.js} +1 -1
- package/payload/server/public/assets/admin-D3gZuyUn.js +217 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-Dw16BhiX.js → architectureDiagram-Q4EWVU46-CeTRKWDb.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DIOpmf5Y.js → blockDiagram-DXYQGD6D-DeeIX5U3.js} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-Tdb_HZeX.js → c4Diagram-AHTNJAMY-CFsqZuil.js} +1 -1
- package/payload/server/public/assets/channel-CrSx5mnG.js +1 -0
- package/payload/server/public/assets/{chunk-336JU56O-CebpwDDe.js → chunk-336JU56O-DpIXuFM0.js} +2 -2
- package/payload/server/public/assets/{chunk-426QAEUC-BtRCmfDU.js → chunk-426QAEUC-Qk8qqrvA.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-BZ3GEWs3.js → chunk-4TB4RGXK-DtM8-CUn.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-iDI6Xu0U.js → chunk-5FUZZQ4R-CrSQ4ySU.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-SQD_EpYa.js → chunk-5PVQY5BW-Bn2nQwdj.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-CtCcA7_e.js → chunk-EDXVE4YY-CzCPnR0P.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-pXVGVCbb.js → chunk-ENJZ2VHE-CgZj9RoG.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-Dkzg9o2N.js → chunk-ICPOFSXX-wy-eNjwW.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-1ZZWzf9F.js → chunk-OYMX7WX6-CMmJtL8S.js} +1 -1
- package/payload/server/public/assets/{chunk-U2HBQHQK-CpQ3kzO0.js → chunk-U2HBQHQK-CFCW7OaT.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-C2LkxroC.js → chunk-X2U36JSP-Bgh-CJSN.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-Bl5jBOt5.js → chunk-YZCP3GAM-BXKwZ4vN.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-CHtnptPS.js → chunk-ZZ45TVLE-BiOuK5NP.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-C3IDJsqN.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BOIrJ5Zb.js +1 -0
- package/payload/server/public/assets/clone-P8Fkz7JD.js +1 -0
- package/payload/server/public/assets/{dagre-BziN0Nkh.js → dagre-DyCxa9Q2.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-B7OG1g1Y.js → dagre-KV5264BT-Cffo_hmf.js} +1 -1
- package/payload/server/public/assets/data-DRfwJPja.js +1 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-Bf31nIDs.js → diagram-5BDNPKRD-Bt93Du3V.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-DQu85hhH.js → diagram-G4DWMVQ6-v4r-tBsC.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-5tstbs4y.js → diagram-MMDJMWI5-DKrVPOP-.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635--MOV1U4o.js → diagram-TYMM5635-B1PzWQb9.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-BtAnOJmd.js → erDiagram-SMLLAGMA-ClQzsQAs.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-CybiCIih.js → flowDiagram-DWJPFMVM-h3IbpN_7.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-B44jN7Cy.js → ganttDiagram-T4ZO3ILL-ClaxOJi8.js} +1 -1
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CT7iYcwg.js → gitGraphDiagram-UUTBAWPF-pM-U4ClD.js} +1 -1
- package/payload/server/public/assets/graph-B4FFYwus.js +1 -0
- package/payload/server/public/assets/graph-labels-Cpk9Ktt0.js +1 -0
- package/payload/server/public/assets/{graphlib-DP4o0pYL.js → graphlib-CwimOv_M.js} +1 -1
- package/payload/server/public/assets/{infoDiagram-42DDH7IO-CvxFpFHN.js → infoDiagram-42DDH7IO-DcO3Giwe.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-CUwWLPeR.js → ishikawaDiagram-UXIWVN3A-BcdSL5VS.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-y-OnGgLi.js → journeyDiagram-VCZTEJTY-CYahHYzf.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-BhrSe8R4.js → kanban-definition-6JOO6SKY-Cl5KhoS4.js} +1 -1
- package/payload/server/public/assets/lib--yuBd0Xi.js +33 -0
- package/payload/server/public/assets/{line-C9uS7z4J.js → line-d_2oTxLp.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-Cg4ZdKp-.js → mermaid-parser.core-CMMDGv3x.js} +1 -1
- package/payload/server/public/assets/{mermaid.core-BHdKOsex.js → mermaid.core-DK9ENGbr.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-NBYiXHo7.js → mindmap-definition-QFDTVHPH-mA3x3MFG.js} +1 -1
- package/payload/server/public/assets/page-CgDmg_fX.js +1 -0
- package/payload/server/public/assets/{page-D9YpwhIu.js → page-D9lluVl7.js} +2 -2
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-CbojC64C.js → pieDiagram-DEJITSTG-CW1nGFlY.js} +1 -1
- package/payload/server/public/assets/public-DdLMkNdS.js +7 -0
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-CnnoZXcL.js → quadrantDiagram-34T5L4WZ-DI5igJhR.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-DFRFRtyJ.js → requirementDiagram-MS252O5E-DyVeI4e_.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-DU5gcpzO.js → sankeyDiagram-XADWPNL6-CCTTBYKY.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-BN7HZ6Hq.js → sequenceDiagram-FGHM5R23-hVVf35ly.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-DG6cCjvg.js → stateDiagram-FHFEXIEX-CSLuQDUX.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-C5JejhQU.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-qmV-8SEV.js → timeline-definition-GMOUNBTQ-sxC3W8Q4.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-BMXQ1s3n.js → vennDiagram-DHZGUBPP-Ro-ton6Z.js} +1 -1
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-CoAdP1Gw.js → wardleyDiagram-NUSXRM2D-T-dKD0Zx.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-CZlfGTEn.js → xychartDiagram-5P7HB3ND-CfProPts.js} +1 -1
- package/payload/server/public/data.html +4 -4
- package/payload/server/public/graph.html +5 -5
- package/payload/server/public/index.html +7 -7
- package/payload/server/public/public.html +4 -4
- package/payload/server/server.js +299 -1392
- package/payload/platform/plugins/cloudflare/scripts/_stream-log.sh +0 -154
- package/payload/server/chunk-BDFOTLPW.js +0 -759
- package/payload/server/chunk-JRBCOVA4.js +0 -1305
- package/payload/server/cloudflare-task-tracker-M5ONAGUT.js +0 -22
- package/payload/server/public/assets/admin-BvzMvMGo.js +0 -217
- package/payload/server/public/assets/channel-DThrH4QF.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-BC6oGTNX.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-COwC5Umh.js +0 -1
- package/payload/server/public/assets/clone-Chp7hvnA.js +0 -1
- package/payload/server/public/assets/data-BAgaPs4j.js +0 -1
- package/payload/server/public/assets/graph-Cma7EArf.js +0 -1
- package/payload/server/public/assets/graph-labels-DyKk6Sxf.js +0 -1
- package/payload/server/public/assets/lib-CpkYtEDz.js +0 -29
- package/payload/server/public/assets/page-B4IWl3aZ.js +0 -1
- package/payload/server/public/assets/public-BtOXjy3A.js +0 -8
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CvVd1Q_q.js +0 -1
|
@@ -184,325 +184,13 @@ If the initial Cloudflare login fails during setup, {{productName}} will fall ba
|
|
|
184
184
|
|
|
185
185
|
---
|
|
186
186
|
|
|
187
|
-
## Action runner — upgrade or Cloudflare setup appears stuck
|
|
188
187
|
|
|
189
|
-
|
|
188
|
+
## Software update and Cloudflare setup
|
|
190
189
|
|
|
191
|
-
|
|
190
|
+
Both flows run on the native Claude Code PTY surface in admin chat (Task 287). The retired action-runner / terminal-modal troubleshooting sections that lived here have been removed because those surfaces no longer exist; failures now manifest as plain stderr from the agent-invoked Bash command, visible in chat.
|
|
192
191
|
|
|
193
|
-
**
|
|
194
|
-
|
|
195
|
-
**Heartbeat stalled** (log panel header shows rising `silent Ns` amber badge).
|
|
196
|
-
|
|
197
|
-
- Open the log panel header: `state: <systemd_state>` tells you the unit's current state.
|
|
198
|
-
- `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.
|
|
199
|
-
- `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.
|
|
200
|
-
- `systemd_state: failed` → see the next symptom.
|
|
201
|
-
|
|
202
|
-
**`ActiveState=failed`** (log panel's exit banner shows a non-zero code).
|
|
203
|
-
|
|
204
|
-
- Read the persisted log directly: `~/.maxy/logs/actions/<actionId>.log` (or `.realagent/...`) has every stdout+stderr line the unit emitted.
|
|
205
|
-
- `journalctl --user --identifier=maxy-action-<actionId>` shows systemd's own record including ExecStartPre/ExecStopPost if any.
|
|
206
|
-
- Common cases:
|
|
207
|
-
- Wrong sudo password → `sudo: 1 incorrect password attempt` near the top of the log; re-open the upgrade modal, enter the correct password.
|
|
208
|
-
- Network failure during `npx` → `npm ERR! network` lines; re-open the modal and retry when network is restored.
|
|
209
|
-
- `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.
|
|
210
|
-
|
|
211
|
-
**"Authorise in Cloudflare" button never appears** (cloudflare-setup action).
|
|
212
|
-
|
|
213
|
-
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:
|
|
214
|
-
|
|
215
|
-
- 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).
|
|
216
|
-
- Lines present but no URL → cloudflared output-format drift; file a task with the last 20 lines of the action log.
|
|
217
|
-
|
|
218
|
-
**Log file missing (action stream returns 404).**
|
|
219
|
-
|
|
220
|
-
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>`).
|
|
221
|
-
|
|
222
|
-
**Cloudflare-setup action card shows "Failed (exit null)" after the tunnel works.**
|
|
223
|
-
|
|
224
|
-
> **Pre-Task-860 misdiagnosis.** Devices on platform versions misrender a successful `cloudflare-setup` run as red `Failed (exit null) · ~20s` because the script-armed brand-service restart kills the SSE generator before it can read the action's exit code. The Cloudflare side is fine in this case — the tunnel is created, DNS is routed, the brand service comes back up.
|
|
225
|
-
>
|
|
226
|
-
> **First-line check:** open the persisted action log directly. Two markers prove success:
|
|
227
|
-
>
|
|
228
|
-
> ```bash
|
|
229
|
-
> grep -E 'step=service-restart-armed exit=0|step=done' \
|
|
230
|
-
> ~/.{configDir}/logs/actions/cloudflare-setup-*.log | tail -2
|
|
231
|
-
> ```
|
|
232
|
-
>
|
|
233
|
-
> Both lines present in the log ⇒ the script succeeded; the UI banner is the bug, not the run. On post-Task-860 platforms the action card renders `Completed · Ns` on the same log shape; the card now distinguishes four states:
|
|
234
|
-
>
|
|
235
|
-
> - `Completed` (green) — `code === 0` (whether reported by systemd or recovered from the log).
|
|
236
|
-
> - `Failed (exit N)` (red) — non-zero exit reported by systemd. Real failure, follow the existing remediation paths.
|
|
237
|
-
> - `Restart in progress` (neutral sage) — arming line present in log but the post-arm `step=done` was not written before the unit was GC'd. Resolves automatically once `/api/admin/version` responds; if it stays >90 s, falls through to amber.
|
|
238
|
-
> - `Failed (exit unobserved)` (amber) — neither systemd nor the log can confirm a terminal state. Check `journalctl --user -u maxy-action-<id>`; the unit failed early or the log was truncated.
|
|
239
|
-
>
|
|
240
|
-
> The server emits `[action-runner] reconcile actionId=<id> result=<succeeded|failed|restart-in-progress|unresolved> source=<systemd|persisted-log> ms=<n>` once per terminal-state resolution. Missing reconcile line on a finished run = stale platform; upgrade.
|
|
241
|
-
|
|
242
|
-
**Cloudflare-setup auto-relays "completed" but the next chat turn 502s.**
|
|
243
|
-
|
|
244
|
-
The current contract is a single client-driven resume: when the setup script exits cleanly, the form fires a resume event, the chat hook waits for `/api/health` to fail then succeed (the brand-service down-then-up cycle), re-binds the conversation to the new server process, and sends the "completed" marker as a normal hidden chat POST that re-invokes the agent in the operator's real session. No relay queue, no boot-drain, no banner.
|
|
245
|
-
|
|
246
|
-
Diagnostic recipe:
|
|
247
|
-
|
|
248
|
-
```
|
|
249
|
-
grep '\[admin-resume\] reason=post-restart' ~/.maxy/logs/server.log | tail # /resume server-side
|
|
250
|
-
grep '\[session\] cookie-bridge accountId=' ~/.maxy/logs/server.log | tail # session re-hydrated
|
|
251
|
-
grep '\[persist\] .* role=user .* Cloudflare setup completed' ~/.maxy/logs/server.log | tail
|
|
252
|
-
grep '\[client-event\] kind=post-restart-resume' ~/.maxy/logs/server.log | tail
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
Failure modes:
|
|
256
|
-
- `[client-event] kind=post-restart-resume phase=start` absent: form's CustomEvent never reached the chat hook (regression in form `onExit` or chat-listener mount).
|
|
257
|
-
- `[client-event] phase=start` present, `[admin-resume] reason=post-restart` absent: `waitForRestartCycle` exhausted its bound (brand never restarted) or `/resume` rejected — check `phase=health-timeout` / `phase=resume-rejected`.
|
|
258
|
-
- All four present except `[persist] role=user … Cloudflare setup completed`: marker chat POST failed — check the chat surface for an inline error or a `phase=resume-error` line.
|
|
259
|
-
- Refresh after a successful Cloudflare setup shows a visible `Cloudflare setup completed (actionId: …)` user bubble: the resume mappers' synthetic-marker suppression broke or the marker shape drifted. Server-side `[admin-resume] syntheticHidden=<n>` field on the same line counts user rows the client should hide (`_componentDone` envelopes, `_lifecycle` envelopes, and the `Cloudflare setup completed (actionId: …)` literal) — a count of 0 against a refresh that should have hidden one means the helper at `platform/ui/app/lib/synthetic-marker.ts` no longer recognises the producing literal (check `CloudflareSetupForm.tsx` and `useAdminChat.ts` for shape drift).
|
|
260
|
-
|
|
261
|
-
---
|
|
262
|
-
|
|
263
|
-
## Software Update click shows an error instead of opening the terminal
|
|
264
|
-
|
|
265
|
-
> **First-line diagnostic for the byte-stream xterm.js terminal surface:** `sudo systemctl --user status maxy-ttyd` plus `sudo grep 'ttyd-proxy' ~/.maxy/logs/edge-boot.log | tail -20`. Failure mode signals: `ttyd-ws-upgrade accepted` with no `ttyd-proxy-open` → `maxy-ttyd.service` is down; `ttyd-proxy-open` with no `ttyd-proxy-chunk dir=upstream→client` → ttyd/tmux is not attaching a PTY.
|
|
266
|
-
|
|
267
|
-
**Symptom:** You clicked **Upgrade** in the Software Update modal, but instead of the VNC terminal overlay appearing, the modal shows a red error row like:
|
|
268
|
-
|
|
269
|
-
```
|
|
270
|
-
[terminal-launch] failed err="window absent from target display after spawn" pid=1234 display=:99 observed_windows=0 transport=vnc reason=upgrade
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
…and the Upgrade button re-labels to "Try again".
|
|
274
|
-
|
|
275
|
-
**What it means:** `POST /api/admin/terminal/launch-upgrade` returned a 502 — the admin server tried to spawn a real terminal on the VNC display `:99` with `npx -y @rubytech/create-maxy@latest` pre-loaded, but the spawn failed or the window never appeared on the target display. The modal's upgrade path uses the same pipeline as the header-menu Terminal; if the operator Terminal button works, the VNC stack itself is healthy and the fault is usually a missing dep or a stale binary. If the operator Terminal also fails, start with the "Header Terminal click shows an error alert" section below.
|
|
276
|
-
|
|
277
|
-
Step-by-step diagnosis — the error string in the modal is identical to the entry in `~/.maxy/logs/vnc-boot.log`, so you can grep it directly:
|
|
278
|
-
|
|
279
|
-
```bash
|
|
280
|
-
# 1. Find the latest upgrade launch attempt
|
|
281
|
-
sudo grep 'action=launch-upgrade' ~/.maxy/logs/vnc-boot.log | tail -10
|
|
282
|
-
|
|
283
|
-
# 2. See the script-level failure line (same string the modal shows)
|
|
284
|
-
sudo tail -n 30 ~/.maxy/logs/terminal-launch.log
|
|
285
|
-
|
|
286
|
-
# 3. Verify binaries are present
|
|
287
|
-
which xterm xdotool
|
|
288
|
-
|
|
289
|
-
# 4. Confirm the VNC display itself is up
|
|
290
|
-
DISPLAY=:99 xdpyinfo >/dev/null 2>&1 && echo "display:99 ok" || echo "display dead"
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
**Common upgrade-specific failures:**
|
|
294
|
-
|
|
295
|
-
- `err="no terminal emulator installed"` → run `sudo apt-get install -y xterm xdotool` or re-run `npx -y @rubytech/create-maxy@latest` — the installer provisions both as hard deps.
|
|
296
|
-
- `err="spawn detached but no terminal PID visible within 1s"... reason=upgrade` → X server on `:99` is wedged. the VNC stack is owned by `maxy-edge`, so the recovery is `sudo systemctl --user restart maxy-edge` (cycles `vnc.sh start` via that unit's ExecStartPre). Then click **Try again** in the modal.
|
|
297
|
-
- `err="window absent from target display after spawn"... reason=upgrade` → the spawn succeeded but landed on the wrong display (earlier platform fixes class). Re-run the installer to refresh the `resolve_terminal_bin` logic. If a stale `gnome-terminal` is hitting `:99` via D-Bus delegation, the installer's `xterm` fallback is the fix.
|
|
298
|
-
- `err="xdotool not installed — re-run installer to repair"` → earlier platform fixes preflight. `sudo apt-get install -y xdotool` or re-run the installer.
|
|
299
|
-
- `err="VNC failed to start after recovery attempt"` → `Xtigervnc` itself is not coming up. Inspect `~/.maxy/logs/vnc-boot.log` for tigervnc startup lines; `ss -ltn '(sport = 6080 or sport = 5900)'` should show both ports listening.
|
|
300
|
-
|
|
301
|
-
**Click Try again** after applying any fix — the modal re-POSTs the launch-upgrade request.
|
|
302
|
-
|
|
303
|
-
---
|
|
304
|
-
|
|
305
|
-
## Upgrade terminal stays black after clicking Upgrade (VNC WebSocket rejected)
|
|
306
|
-
|
|
307
|
-
**Symptom:** The launch-upgrade POST returns 200 (the server-side spawn succeeded), but the browser's VNC iframe shows a black rectangle and the DevTools console spins on `WebSocket connection to '/websockify' failed` / `Connection closed (code: 1006)` every few seconds.
|
|
308
|
-
|
|
309
|
-
**What it means:** The browser has a session cookie the `/websockify` auth gate refuses to accept., every rejection logs three fields that identify the failing layer:
|
|
310
|
-
|
|
311
|
-
```bash
|
|
312
|
-
sudo tail -200 ~/.maxy/logs/vnc-boot.log | grep 'decision="rejected"'
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
- `cookieHeaderPresent=false` → the browser never sent a cookie. Check the iframe context / SameSite policy / cookie domain. Most commonly: the user opened admin over HTTP instead of HTTPS, or the cookie is scoped to a different subdomain.
|
|
316
|
-
- `cookieHeaderPresent=true tokenPresent=false` → the cookie is present but the server rejects its signature. This is either tampering or a corrupted/missing shared secret. Check that `~/.maxy/credentials/remote-session-secret` exists on disk (mode `0600`, 64 hex chars) and has not been recently overwritten.
|
|
317
|
-
- `tokenExpired=true` → the 24h session TTL elapsed. Log in again.
|
|
318
|
-
|
|
319
|
-
If the secret file is missing entirely, re-run `npx -y @rubytech/create-maxy@latest` — the installer provisions it idempotently, preserving an existing file on upgrade and creating a fresh one on first install.
|
|
320
|
-
|
|
321
|
-
---
|
|
322
|
-
|
|
323
|
-
## Upgrade terminal opens but npx never runs
|
|
324
|
-
|
|
325
|
-
**Symptom:** You clicked **Upgrade**, the VNC overlay opened with a visible shell prompt, but `npx -y @rubytech/create-maxy@latest` does not execute and the shell is idle.
|
|
326
|
-
|
|
327
|
-
**What it means:** The VNC spawn succeeded but the binary-specific command dispatcher (xterm `-e` or gnome-terminal `--`) did not forward the command. Given the installer ships `xterm` on `:99` by default (with D-Bus-safe dispatching), the likely causes are:
|
|
328
|
-
|
|
329
|
-
- A stale binary override has re-pointed `resolve_terminal_bin` to `gnome-terminal` on `:99` despite the fix.
|
|
330
|
-
- A shell the operator manually spawned (via the header Terminal) wasn't killed before the upgrade click, and `ensureTerminalUpgrade`'s pre-kill step silently failed.
|
|
331
|
-
|
|
332
|
-
**Check:**
|
|
333
|
-
|
|
334
|
-
```bash
|
|
335
|
-
# The spawned binary must appear in this log with the bash-c wrapper
|
|
336
|
-
sudo grep 'started.*reason=upgrade' ~/.maxy/logs/terminal-launch.log | tail -3
|
|
337
|
-
# Expected shape: started pid=<N> display=:99 cmd="/usr/bin/xterm... -e bash -c 'npx -y @rubytech/create-maxy@latest; exec bash'" transport=vnc windowPresent=true reason=upgrade
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
If the `cmd=` field does not contain `-e bash -c`, re-run the installer — the vnc.sh on the device is stale. If the command IS logged correctly but nothing is running, open the VNC overlay and type `history | tail` inside the shell — if the npx line is there, it ran and exited (check `~/.maxy/logs/install-*.log` for the exit status).
|
|
341
|
-
|
|
342
|
-
---
|
|
343
|
-
|
|
344
|
-
## Header Terminal click shows an error alert
|
|
345
|
-
|
|
346
|
-
**Symptom:** You opened the burger menu and clicked **Terminal**, but instead of the overlay appearing you got an inline error like "Terminal failed to start" or "VNC failed to start".
|
|
347
|
-
|
|
348
|
-
**What it means:** `POST /api/admin/terminal/launch` returned a 502 — either the VNC stack on port 5900 is down or the terminal emulator could not be spawned on display `:99`. This is a VNC-stack or display-spawn failure.
|
|
349
|
-
|
|
350
|
-
Step-by-step diagnosis:
|
|
351
|
-
|
|
352
|
-
```bash
|
|
353
|
-
# 1. Check the terminal-launch log for the specific failure reason
|
|
354
|
-
sudo tail -n 50 ~/.maxy/logs/terminal-launch.log
|
|
355
|
-
|
|
356
|
-
# 2. Check the node-side state machine (ensure-terminal entries)
|
|
357
|
-
sudo grep ensure-terminal ~/.maxy/logs/vnc-boot.log | tail -20
|
|
358
|
-
|
|
359
|
-
# 3. Verify the VNC display itself is healthy
|
|
360
|
-
sudo ~/maxy/platform/scripts/vnc.sh status # should print "running"
|
|
361
|
-
DISPLAY=:99 xdpyinfo >/dev/null 2>&1 && echo "display ok" || echo "display dead"
|
|
362
|
-
|
|
363
|
-
# 4. Confirm a terminal binary is installed (xterm is the always-available fallback)
|
|
364
|
-
which gnome-terminal; which xterm
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
Most common failures and fixes:
|
|
368
|
-
|
|
369
|
-
- `[terminal-launch] failed err="no terminal emulator installed"` → run `sudo apt-get install -y xterm xdotool` (or re-run the installer, which installs both as dependencies).
|
|
370
|
-
- `[terminal-launch] failed err="spawn detached but no terminal PID visible within 1s"` → X server on `:99` is wedged. `sudo systemctl --user restart maxy-ui` cycles the VNC stack via `vnc.sh start`.
|
|
371
|
-
- `[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 (earlier platform fixes — 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).
|
|
372
|
-
- `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.
|
|
373
|
-
|
|
374
|
-
## Terminal fails after upgrade — `Invalid response` or `window absent from target display`
|
|
375
|
-
|
|
376
|
-
**Symptom:** You upgraded a {{productName}} 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.
|
|
377
|
-
|
|
378
|
-
**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 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.
|
|
379
|
-
|
|
380
|
-
**Check:**
|
|
381
|
-
|
|
382
|
-
```bash
|
|
383
|
-
dpkg -s xdotool 2>&1 | head -2 # should report "Status: install ok installed"
|
|
384
|
-
which xdotool # should return /usr/bin/xdotool
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
**Fix — two options:**
|
|
388
|
-
|
|
389
|
-
1. **Re-run the installer from an interactive shell** (preferred on upgrade — picks up any future missing deps too):
|
|
390
|
-
|
|
391
|
-
```bash
|
|
392
|
-
npx -y @rubytech/create-maxy@latest
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
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.
|
|
396
|
-
|
|
397
|
-
2. **Repair manually** (faster if you only want the one binary):
|
|
398
|
-
|
|
399
|
-
```bash
|
|
400
|
-
sudo apt-get install -y xdotool
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
Then click **Terminal** again — it should spawn within a second and the overlay should render the xterm.
|
|
404
|
-
|
|
405
|
-
**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 earlier platform fixes `window absent from target display after spawn` string. The two strings never appear for the same click.
|
|
406
|
-
|
|
407
|
-
---
|
|
408
|
-
|
|
409
|
-
## Installer aborts on Ubuntu 24.04 with `dpkg -s: chromium`
|
|
410
|
-
|
|
411
|
-
**Symptom:** On a fresh (or re-run) `npx -y @rubytech/create-maxy@latest` on an Ubuntu 24.04 Noble laptop/desktop, step 1/12 aborts:
|
|
412
|
-
|
|
413
|
-
```
|
|
414
|
-
[1/12] System dependencies and network...
|
|
415
|
-
Missing apt deps (1): chromium
|
|
416
|
-
apt install (VNC stack): tigervnc-standalone-server python3-websockify novnc xdg-utils chromium xterm xdotool
|
|
417
|
-
> sudo apt-get install -y... chromium...
|
|
418
|
-
OK in 0.3s
|
|
419
|
-
[ERROR] Setup failed: apt-get install (VNC stack) returned 0 but packages are still not installed per dpkg -s: chromium
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
Directly probing the device shows `dpkg -s chromium` non-zero, `apt-cache policy chromium` reports `Candidate: (none)`, but `/usr/bin/chromium` exists and works, and `snap list chromium` shows the snap is installed.
|
|
423
|
-
|
|
424
|
-
**What it means:** You are on a **pre-637 installer**. On Noble, `chromium` is a virtual package aliasing to `chromium-browser` — `apt-get install chromium` succeeds silently but nothing named `chromium` ever lands in dpkg's state DB. the post-install probe (correctly) notices the discrepancy and aborts. An earlier fix added alias resolution (`chromium` → `chromium-browser`) so the probe matches the dpkg-recorded name and passes.
|
|
425
|
-
|
|
426
|
-
**Fix:** Upgrade to a post-637 version of `@rubytech/create-maxy`:
|
|
427
|
-
|
|
428
|
-
```bash
|
|
429
|
-
npx -y @rubytech/create-maxy@latest
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
**Manual bypass** (if you must install before 637 publishes, or if you're on a restricted shell): pre-install the real.deb name and re-run the installer.
|
|
433
|
-
|
|
434
|
-
```bash
|
|
435
|
-
sudo apt-get install -y chromium-browser
|
|
436
|
-
npx -y @rubytech/create-maxy@latest
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
The installer's resolver will then see `dpkg -s chromium-browser` exit 0 for the alias target, filter `chromium` out of the missing set, and skip the apt-install branch entirely. Raspberry Pi OS (Debian 12 Bookworm) is unaffected — `chromium` IS a concrete.deb on Bookworm.
|
|
440
|
-
|
|
441
|
-
**Deeper diagnostic**: post-637 installer logs carry the full classification in the error message itself — `(resolved-name=<name>, apt-cache-policy=<summary>, command-v=<path>, snap-status=<summary>)`. If you see that longer form and still fail, the apt state itself is inconsistent (snap removed, `chromium-browser` uninstalled after previous install) — repair with `sudo apt-get install --reinstall -y chromium-browser`.
|
|
442
|
-
|
|
443
|
-
---
|
|
444
|
-
|
|
445
|
-
## VNC browser will not start on Linux laptop — `Permission denied (13)` on SingletonLock
|
|
446
|
-
|
|
447
|
-
**Symptom:** Boot log `~/.{brand}/logs/vnc-boot.log` shows:
|
|
448
|
-
|
|
449
|
-
```
|
|
450
|
-
Starting Chromium on :<vncDisplay> (vnc) profile=/home/<user>/.{brand}/chromium-profile CDP=:<cdpPort>
|
|
451
|
-
ERROR:chrome/browser/process_singleton_posix.cc:345] Failed to create
|
|
452
|
-
/home/<user>/.{brand}/chromium-profile/SingletonLock: Permission denied (13)
|
|
453
|
-
ERROR: Chromium failed to start on :<vncDisplay> (vnc) — CDP port <cdpPort> not listening (browser-specialist degraded)
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
`dmesg` (or `journalctl -k`) shows AppArmor `DENIED` lines naming `profile="snap.chromium.chromium"` and the `~/.{brand}/chromium-profile/` path. The brand admin chat reports the public-agent VNC browser as unavailable.
|
|
457
|
-
|
|
458
|
-
**What it means:** Your `/usr/bin/chromium` is a snap symlink. Snap's AppArmor profile excludes hidden top-level paths under `$HOME` from its `home` interface, so writes to per-brand Chromium profile dirs at `~/.maxy/chromium-profile/` and `~/.realagent/chromium-profile/` are denied — Chromium cannot create its `SingletonLock` and never starts the CDP listener. This is exclusively a Linux-laptop problem (Ubuntu Noble); Raspberry Pi OS Bookworm ships `chromium` as a real `.deb` and is unaffected.
|
|
459
|
-
|
|
460
|
-
**Fix:** Re-run the installer at version 1.0.849 or later. The installer detects the snap-confined chromium during system-dependency setup and replaces it with Google Chrome stable from Google's signed apt repo:
|
|
461
|
-
|
|
462
|
-
```bash
|
|
463
|
-
npx -y @rubytech/create-maxy@latest
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
The resolved non-snap binary path is recorded at `<INSTALL_DIR>/platform/config/chromium-binary.path` (single line) and read by every Chromium call site (VNC service, in-page wrapper, Playwright server). After re-running, verify with the bundled acceptance script:
|
|
467
|
-
|
|
468
|
-
```bash
|
|
469
|
-
MAXY_PLATFORM_ROOT=$HOME/<install-dir>/platform $HOME/<install-dir>/platform/scripts/test-laptop-vnc-boot.sh
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
The script exits 0 only when (1) the configured Chromium realpath is non-snap, (2) the path is absolute and executable, (3) the per-brand CDP port returns Chromium version JSON, and (4) `vnc-boot.log` since the last `[vnc.sh] start` ends with `VNC + browser stack running` and contains no `Chromium failed to start` line.
|
|
473
|
-
|
|
474
|
-
**Deeper diagnostic:** `vnc.sh` and the in-page wrapper now refuse to start (and exit with a snap-Chromium reference in the boot log) when `chromium-binary.path` is absent or its realpath lands under `/snap/`. If you see those messages, the install completed before the fix shipped — re-run `npx -y @rubytech/create-maxy@latest`. Manual workaround for an emergency (not a fix): `sudo apt-get install -y google-chrome-stable` and confirm `which google-chrome-stable` is non-snap, then re-run the installer to write `chromium-binary.path`.
|
|
475
|
-
|
|
476
|
-
---
|
|
477
|
-
|
|
478
|
-
## Terminal iframe renders black and cursor vanishes over the canvas
|
|
479
|
-
|
|
480
|
-
**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).
|
|
481
|
-
|
|
482
|
-
**What it means:** This is the exact symptom class that earlier platform fixes closed. Before 632, `/usr/bin/gnome-terminal` would receive `DISPLAY=:99` but D-Bus-delegate the window-create request to the session's `gnome-terminal-server`, which opens the window on `:0` (the operator's physical screen) instead. The iframe, rendering `:99`, has no window to show — hence the black canvas, dead keystrokes, and null-cursor (noVNC's Cursor pseudo-encoding renders `cursor: none` when the server sends no cursor). If you are seeing this *after* earlier platform fixes shipped, the installer did not run on this device or a stale bundle is in place.
|
|
483
|
-
|
|
484
|
-
Step-by-step diagnosis:
|
|
485
|
-
|
|
486
|
-
```bash
|
|
487
|
-
# 1. Check terminal-launch.log for the window-absent failure
|
|
488
|
-
sudo grep 'window absent from target display' ~/.maxy/logs/terminal-launch.log | tail -5
|
|
489
|
-
|
|
490
|
-
# 2. Verify the expected binaries are installed
|
|
491
|
-
which xterm xdotool # both must exist — installer adds them
|
|
492
|
-
|
|
493
|
-
# 3. Confirm the VNC display is serving the iframe
|
|
494
|
-
DISPLAY=:99 xdpyinfo >/dev/null 2>&1 && echo "display:99 ok"
|
|
495
|
-
DISPLAY=:99 xdotool search --onlyvisible --class '.' # non-empty means windows ARE on:99
|
|
496
|
-
|
|
497
|
-
# 4. Check which binary resolve_terminal_bin chose
|
|
498
|
-
grep 'cmd=' ~/.maxy/logs/terminal-launch.log | tail -3
|
|
499
|
-
# Expected for remote-origin clicks: cmd="/usr/bin/xterm"
|
|
500
|
-
# If you see: cmd="/usr/bin/gnome-terminal --wait" on:99 → stale bundle, re-run installer
|
|
501
|
-
```
|
|
502
|
-
|
|
503
|
-
If the failure log shows `window absent from target display`, the fix already ran but spawn still went to the wrong display — re-run the installer (`npx -y @rubytech/create-maxy@latest`) from a shell to pick up the latest `xterm` + `xdotool` preflight. If the failure log shows no recent entries and the iframe is still black, check `ss -ltn '(sport = 6080 or sport = 5900)'` and `pgrep -af Xtigervnc|websockify` — the symptom might be a VNC-stack regression rather than a terminal-binary mismatch.
|
|
504
|
-
|
|
505
|
-
Both the header Terminal and the Software Update modal's Upgrade button now share the same VNC spawn pipeline, so a failure in one usually reproduces in the other — if the header Terminal opens a blank shell cleanly but the Upgrade modal errors, the problem is upgrade-specific (see "Software Update click shows an error" above).
|
|
192
|
+
- **Software update.** Re-run `npx -y @rubytech/create-<brand>@latest` from a shell; if the installer fails, its stdout is the diagnostic record. HeaderMenu turns sage when `installed === latest`.
|
|
193
|
+
- **Cloudflare setup.** The agent invokes `~/setup-tunnel.sh` via Bash. Failures surface as the script's own `[setup-tunnel] step=… result=error reason=…` lines in chat plus a non-zero exit. Recovery paths live in the cloudflare plugin's `references/reset-guide.md` and `references/manual-setup.md`.
|
|
506
194
|
|
|
507
195
|
## Orphan Account Directory Archived to `.trash/`
|
|
508
196
|
|
|
@@ -23,13 +23,44 @@ Outcome (binding):
|
|
|
23
23
|
|
|
24
24
|
Constraint (binding): **No downstream venture-studio skill (`brand-pack`, `zero-to-prototype`, `investor-data-room` Stages 3+, etc.) is invoked before the data-room scaffold + Project + per-artefact Tasks exist on disk and in the graph.** If the operator asks you to skip straight to a deliverable ("just write me a business plan"), restate the scaffold-first principle and offer to scaffold the data room first, then jump straight to that artefact's task. The principle is the outcome contract; the scaffold proves it.
|
|
25
25
|
|
|
26
|
+
### Deterministic pre-flight gate
|
|
27
|
+
|
|
28
|
+
Before invoking any downstream skill, both checks below must pass. Both are deterministic — exit-code on `ls`, structured output on `project-list`. Neither check depends on LLM judgement.
|
|
29
|
+
|
|
30
|
+
1. **Directory check:** `[ -d "${PROJECT_ROOT}/.docs/data-room/01-narrative" ]` returns exit 0.
|
|
31
|
+
2. **Graph check:** the `project-list` tool returns a Project whose `name` matches the business's working name.
|
|
32
|
+
|
|
33
|
+
If either check fails, run the scaffolding script (see below) before the skill fires. If the script fails, surface the literal stderr error to the operator — do not narrate around it (memory: [[feedback_no_stdout_parsing_for_control_flow]]).
|
|
34
|
+
|
|
35
|
+
### Scaffolding script
|
|
36
|
+
|
|
37
|
+
`bin/scaffold.sh` is the deterministic enforcement layer. It creates the Project + eight artefact Tasks (via the work plugin's `project-create-cli` bridge) and materialises the ten-section directory tree. Graph write first, directories second; idempotent re-run if any partial state lands.
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
ACCOUNT_ID="${ACCOUNT_ID}" \
|
|
41
|
+
premium-plugins/venture-studio/bin/scaffold.sh \
|
|
42
|
+
"${PROJECT_ROOT}" \
|
|
43
|
+
"${BUSINESS_NAME}"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The script is the binding check, not the prose principle above. The prose explains why; the script is what makes it true.
|
|
47
|
+
|
|
26
48
|
## First-conversation routing
|
|
27
49
|
|
|
28
|
-
When the operator first invokes this agent, confirm the intent ("Are we founding a new business, or working on an existing one?") and run the scaffolding
|
|
50
|
+
When the operator first invokes this agent, confirm the intent ("Are we founding a new business, or working on an existing one?") and run the scaffolding script — it does steps 1–3 below in a single atomic invocation:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
ACCOUNT_ID="${ACCOUNT_ID}" \
|
|
54
|
+
premium-plugins/venture-studio/bin/scaffold.sh \
|
|
55
|
+
"${PROJECT_ROOT}" \
|
|
56
|
+
"${BUSINESS_NAME}"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The script's three effects:
|
|
29
60
|
|
|
30
|
-
1. **
|
|
31
|
-
2. **
|
|
32
|
-
3. **
|
|
61
|
+
1. **Scaffolds the data room.** Materialises the ten-section directory tree under `<project-root>/.docs/data-room/`. Every artefact has a slot to land in before any artefact is produced.
|
|
62
|
+
2. **Creates the `Project` node.** Tier `full` (data-room work is multi-phase). Project name is the business's working name; description references the data-room root path.
|
|
63
|
+
3. **Enumerates the eight artefact Tasks** in section order — one transaction, atomic with the Project. The work-item list the script pre-seeds:
|
|
33
64
|
- **Stage 1 — Office-hours design doc** → produces `01-narrative/office-hours-design.md` (skill: `office-hours`)
|
|
34
65
|
- **Brand pack** → produces brand identity files into `06-product-ip/brand/` (skill: `brand-pack`)
|
|
35
66
|
- **Stage 2 — Wedge validation + landing page + PRD** → produces `01-narrative/{PMF, LANDING, PRD}.md` (skill: `zero-to-prototype`)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Venture-studio data-room scaffold — deterministic enforcement of the
|
|
3
|
+
# scaffold-first principle (Task 286 + feedback_doctrine_paragraph_is_not_a_gate).
|
|
4
|
+
#
|
|
5
|
+
# Creates exactly one Project (with eight pre-seeded artefact Tasks) in
|
|
6
|
+
# the graph, then materialises the ten-section data-room directory tree
|
|
7
|
+
# on disk. The venture-studio agent's downstream skills are gated on
|
|
8
|
+
# both signals existing — see venture-studio/PLUGIN.md.
|
|
9
|
+
#
|
|
10
|
+
# Order of operations: graph write first, directories second. The CLI's
|
|
11
|
+
# duplicate-name guard makes the script safely re-runnable after any
|
|
12
|
+
# partial failure: a second run finds the existing Project, returns its
|
|
13
|
+
# id, and retries the mkdir step.
|
|
14
|
+
#
|
|
15
|
+
# Usage:
|
|
16
|
+
# ACCOUNT_ID=<uuid> scaffold.sh <project-root> <business-name>
|
|
17
|
+
#
|
|
18
|
+
# Exit codes:
|
|
19
|
+
# 0 scaffold complete (or already existed)
|
|
20
|
+
# 2 bad arguments / missing ACCOUNT_ID
|
|
21
|
+
# 1 graph write failed, directory mkdir failed, or CLI binary missing
|
|
22
|
+
|
|
23
|
+
set -euo pipefail
|
|
24
|
+
|
|
25
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
26
|
+
# Deployed layout per packages/create-maxy-code/scripts/bundle.js:
|
|
27
|
+
# <install>/premium-plugins/venture-studio/bin/scaffold.sh
|
|
28
|
+
# <install>/platform/plugins/work/mcp/dist/cli/project-create-cli.js
|
|
29
|
+
CLI_BIN="${SCRIPT_DIR}/../../../platform/plugins/work/mcp/dist/cli/project-create-cli.js"
|
|
30
|
+
|
|
31
|
+
if [[ $# -ne 2 ]]; then
|
|
32
|
+
echo "scaffold.sh: usage: ACCOUNT_ID=<uuid> $0 <project-root> <business-name>" >&2
|
|
33
|
+
exit 2
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
PROJECT_ROOT="$1"
|
|
37
|
+
BUSINESS_NAME="$2"
|
|
38
|
+
|
|
39
|
+
if [[ -z "${ACCOUNT_ID:-}" ]]; then
|
|
40
|
+
echo "scaffold.sh: ACCOUNT_ID env var required" >&2
|
|
41
|
+
exit 2
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
if [[ ! -d "$PROJECT_ROOT" ]]; then
|
|
45
|
+
echo "scaffold.sh: project root does not exist: $PROJECT_ROOT" >&2
|
|
46
|
+
exit 2
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
if [[ ! -f "$CLI_BIN" ]]; then
|
|
50
|
+
echo "scaffold.sh: project-create CLI not built or missing at: $CLI_BIN" >&2
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
DATA_ROOM="${PROJECT_ROOT}/.docs/data-room"
|
|
55
|
+
|
|
56
|
+
# Eight pre-seeded artefact tasks — order and names match
|
|
57
|
+
# premium-plugins/venture-studio/PLUGIN.md § First-conversation routing.
|
|
58
|
+
# Section order is preserved so the agent can walk them sequentially.
|
|
59
|
+
PAYLOAD=$(cat <<JSON
|
|
60
|
+
{
|
|
61
|
+
"accountId": "${ACCOUNT_ID}",
|
|
62
|
+
"name": "${BUSINESS_NAME}",
|
|
63
|
+
"description": "Venture-studio data room for ${BUSINESS_NAME}. Root: ${DATA_ROOM}",
|
|
64
|
+
"tier": "full",
|
|
65
|
+
"workItems": [
|
|
66
|
+
{"name": "Stage 1 — Office-hours design doc", "description": "Produces 01-narrative/office-hours-design.md via the office-hours skill."},
|
|
67
|
+
{"name": "Brand pack", "description": "Produces brand identity (palette, typography, logo) into 06-product-ip/brand/ via the brand-pack skill."},
|
|
68
|
+
{"name": "Stage 2 — Wedge validation + landing page + PRD", "description": "Produces 01-narrative/{PMF,LANDING,PRD}.md via the zero-to-prototype skill."},
|
|
69
|
+
{"name": "Stage 3 — Business plan", "description": "Produces 01-narrative/business-plan.md via investor-data-room Stage 3."},
|
|
70
|
+
{"name": "Stage 3b — Term sheet", "description": "Produces html/prospectus/term_sheet.html via investor-data-room Stage 3b."},
|
|
71
|
+
{"name": "Stage 4 — Deck blueprint", "description": "Produces 01-narrative/deck-blueprint.md via investor-data-room Stage 4."},
|
|
72
|
+
{"name": "Stage 4b — Prospectus", "description": "Produces html/prospectus/index.html via investor-data-room Stage 4b."},
|
|
73
|
+
{"name": "Stage 5 — Rendered PDFs", "description": "Produces html/{business-plan,prospectus,deck}/*.pdf via investor-data-room Stage 5."}
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
JSON
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# Graph write first. CLI returns {projectId, existing:bool} on stdout;
|
|
80
|
+
# on any failure it exits non-zero with a literal stderr message that
|
|
81
|
+
# propagates here verbatim — no prose-parsing for control flow
|
|
82
|
+
# (memory: feedback_no_stdout_parsing_for_control_flow).
|
|
83
|
+
RESULT=$(node "$CLI_BIN" "$PAYLOAD")
|
|
84
|
+
echo "scaffold.sh: project-create CLI returned: $RESULT"
|
|
85
|
+
|
|
86
|
+
# Directories second. The agent's pre-flight gate keys on the existence
|
|
87
|
+
# of 01-narrative/ (it AND-checks with project-list); creating it last
|
|
88
|
+
# means partial state (graph-only) is naturally invisible to the gate
|
|
89
|
+
# until mkdir succeeds.
|
|
90
|
+
for section in \
|
|
91
|
+
01-narrative \
|
|
92
|
+
02-corporate-legal \
|
|
93
|
+
03-cap-table \
|
|
94
|
+
04-financials \
|
|
95
|
+
05-team \
|
|
96
|
+
06-product-ip \
|
|
97
|
+
07-customers \
|
|
98
|
+
08-market \
|
|
99
|
+
09-traction-metrics \
|
|
100
|
+
10-supporting; do
|
|
101
|
+
mkdir -p "${DATA_ROOM}/${section}"
|
|
102
|
+
done
|
|
103
|
+
|
|
104
|
+
echo "scaffold.sh: data-room scaffolded at ${DATA_ROOM}"
|
|
@@ -96,7 +96,9 @@ This file is the working substrate. It stays internal-only. Every later artefact
|
|
|
96
96
|
|
|
97
97
|
## Stage 2 — Data room scaffold
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
When invoked under the venture-studio agent, scaffolding is done by the deterministic script at `premium-plugins/venture-studio/bin/scaffold.sh` — it creates the Project + eight artefact Tasks and the ten-section directory tree in one atomic invocation. The script is idempotent; re-runs against an existing data room are a no-op. See `venture-studio/PLUGIN.md` § "Scaffolding script".
|
|
100
|
+
|
|
101
|
+
When invoked outside the venture-studio agent (standalone usage of this skill), build the directory tree manually. Each section gets a `README.md` that doubles as a content checklist (purpose, expected contents, current state, gaps). The graph structure is fixed: ten numbered sections (`01-narrative` through `10-supporting`) plus a top-level README and an `html/` subdirectory for rendered deliverables.
|
|
100
102
|
|
|
101
103
|
**File-naming conventions:**
|
|
102
104
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-create-cli.d.ts","sourceRoot":"","sources":["../../src/cli/project-create-cli.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// CLI bridge for shell scripts that need to scaffold a Project + Tasks
|
|
2
|
+
// atomically (e.g. premium-plugins/venture-studio/bin/scaffold.sh). The
|
|
3
|
+
// scaffold script is the deterministic enforcement layer for the
|
|
4
|
+
// venture-studio scaffold-first principle (see Task 286 +
|
|
5
|
+
// feedback_doctrine_paragraph_is_not_a_gate); to remain deterministic it
|
|
6
|
+
// must invoke a single binary, not narrate intent for the LLM. This CLI
|
|
7
|
+
// is that binary.
|
|
8
|
+
//
|
|
9
|
+
// Contract:
|
|
10
|
+
// node project-create-cli.js '<json-payload>'
|
|
11
|
+
// payload: { accountId, name, description, tier, workItems[], createdBy }
|
|
12
|
+
// exit 0 + stdout JSON { projectId, existing: boolean } on success
|
|
13
|
+
// exit non-zero + literal stderr message on any failure
|
|
14
|
+
//
|
|
15
|
+
// Idempotency guard lives here, NOT in projectCreate(). projectCreate()
|
|
16
|
+
// always mints a fresh UUID — modifying it to MERGE on (accountId, name)
|
|
17
|
+
// would change semantics for every existing caller. The CLI runs a
|
|
18
|
+
// pre-check MATCH on (accountId, name); if a Project exists, it returns
|
|
19
|
+
// the existing projectId with existing=true and skips the write. This
|
|
20
|
+
// makes the scaffold script safely re-runnable after a partial failure
|
|
21
|
+
// (e.g. graph write succeeds but mkdir fails — second run finds the
|
|
22
|
+
// Project and only retries mkdir).
|
|
23
|
+
import { projectCreate } from "../tools/project-create.js";
|
|
24
|
+
import { getDriver } from "../lib/neo4j.js";
|
|
25
|
+
async function findExistingProject(accountId, name) {
|
|
26
|
+
const driver = getDriver();
|
|
27
|
+
const session = driver.session();
|
|
28
|
+
try {
|
|
29
|
+
const result = await session.run(`MATCH (p:Project {accountId: $accountId, name: $name})
|
|
30
|
+
RETURN p.taskId AS projectId LIMIT 1`, { accountId, name });
|
|
31
|
+
if (result.records.length === 0)
|
|
32
|
+
return null;
|
|
33
|
+
return result.records[0].get("projectId");
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
await session.close();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function main() {
|
|
40
|
+
const raw = process.argv[2];
|
|
41
|
+
if (!raw) {
|
|
42
|
+
process.stderr.write("project-create-cli: missing JSON payload argument\n");
|
|
43
|
+
process.exit(2);
|
|
44
|
+
}
|
|
45
|
+
let payload;
|
|
46
|
+
try {
|
|
47
|
+
payload = JSON.parse(raw);
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
process.stderr.write(`project-create-cli: malformed JSON payload: ${err.message}\n`);
|
|
51
|
+
process.exit(2);
|
|
52
|
+
}
|
|
53
|
+
if (!payload.accountId || !payload.name) {
|
|
54
|
+
process.stderr.write("project-create-cli: payload missing required field (accountId, name)\n");
|
|
55
|
+
process.exit(2);
|
|
56
|
+
}
|
|
57
|
+
const createdBy = payload.createdBy ?? {
|
|
58
|
+
tool: "project-create-cli",
|
|
59
|
+
source: "scaffold-script",
|
|
60
|
+
};
|
|
61
|
+
const existing = await findExistingProject(payload.accountId, payload.name);
|
|
62
|
+
if (existing) {
|
|
63
|
+
process.stdout.write(JSON.stringify({ projectId: existing, existing: true }) + "\n");
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const result = await projectCreate({
|
|
67
|
+
...payload,
|
|
68
|
+
createdBy,
|
|
69
|
+
});
|
|
70
|
+
process.stdout.write(JSON.stringify({ projectId: result.projectId, existing: false, childTaskIds: result.childTaskIds }) + "\n");
|
|
71
|
+
}
|
|
72
|
+
main()
|
|
73
|
+
.then(() => process.exit(0))
|
|
74
|
+
.catch((err) => {
|
|
75
|
+
process.stderr.write(`project-create-cli: ${err.message}\n`);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=project-create-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-create-cli.js","sourceRoot":"","sources":["../../src/cli/project-create-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -323,9 +323,10 @@ start_chrome() {
|
|
|
323
323
|
}
|
|
324
324
|
|
|
325
325
|
# ---------------------------------------------------------------------------
|
|
326
|
-
#
|
|
327
|
-
#
|
|
328
|
-
# the
|
|
326
|
+
# Retired in Task 287: the admin-UI terminal and browser-overlay surfaces
|
|
327
|
+
# are gone. This script still launches Chromium for legacy installs where
|
|
328
|
+
# the brand VNC is used for ad-hoc operator browsing; on maxy-code the
|
|
329
|
+
# admin chat PTY is the only interactive surface.
|
|
329
330
|
# ---------------------------------------------------------------------------
|
|
330
331
|
|
|
331
332
|
start_chrome_native() {
|