@rubytech/create-maxy-lite 0.1.15 → 0.1.17

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.
@@ -15,9 +15,9 @@
15
15
  // All external effects go through injected ctx primitives so the sequence,
16
16
  // guards and idempotency are unit-testable; index.mjs wires the real ones.
17
17
 
18
- import { PATHS, launcherPath, ptyLoadCommand, GUEST_BUILD_ENV } from './paths.mjs'
18
+ import { PATHS, ptyLoadCommand, GUEST_BUILD_ENV } from './paths.mjs'
19
19
 
20
- export const STEP_NAMES = ['termux-deps', 'proot', 'ubuntu', 'node', 'toolchain', 'vault-bind', 'npm-app']
20
+ export const STEP_NAMES = ['termux-deps', 'proot', 'ubuntu', 'node', 'toolchain', 'vault-bind', 'app-code', 'npm-app']
21
21
 
22
22
  /** Throw unless the command result is a clean exit; the message carries the command's stderr. */
23
23
  function ensureOk(r) {
@@ -111,20 +111,32 @@ const STEPS = [
111
111
  ensureOk(c.run(`proot-distro login ${PATHS.distro} --bind ${PATHS.vaultHost}:${PATHS.vaultGuest} -- test -d ${PATHS.vaultGuest}`))
112
112
  },
113
113
  },
114
+ {
115
+ // The app code — payload (server.mjs, validator, schema, skills), the skills
116
+ // symlinks, and the launcher — is cheap to (re)lay and must land on EVERY run,
117
+ // including a re-install of an already-converged device. It lived inside the
118
+ // guarded npm-app step, so once node-pty/claude/launcher were present npm-app
119
+ // skipped and a changed server.mjs never reached the device (a new build had
120
+ // "no effect"). Always-run (`done: () => false`); all three ops overwrite
121
+ // idempotently. Ordered before npm-app because installDeps builds in the dir
122
+ // this lays.
123
+ name: 'app-code',
124
+ done: () => false,
125
+ run: async (c) => {
126
+ c.layPayload()
127
+ c.linkSkills()
128
+ c.writeLauncher()
129
+ },
130
+ },
114
131
  {
115
132
  name: 'npm-app',
116
- // Converged only when node-pty's native module LOADS, claude is present, AND
117
- // the launcher is written. The deps probe is `require("node-pty")`, not a
118
- // file-presence test: a present-but-unloadable `pty.node` (stale/wrong-ABI
119
- // from a prior build) would pass `test -f` yet crash the relay at launch, so
120
- // the guard would skip the very install that repairs it. The load-check is the
121
- // same condition `installDeps` asserts post-build (shared ptyLoadCommand), so
122
- // the guard admits exactly what the build proves; a non-loadable module fails
123
- // the guard and the step re-installs.
124
- done: (c) =>
125
- c.runIn(ptyLoadCommand()).code === 0 &&
126
- c.runIn('command -v claude').code === 0 &&
127
- c.existsHost(launcherPath()),
133
+ // The heavy, network-bound installs only. Converged when node-pty's native
134
+ // module LOADS and claude is present (the load-check is `require("node-pty")`,
135
+ // the same condition installDeps asserts post-build, so a present-but-
136
+ // unloadable pty.node fails the guard and the step rebuilds). The launcher +
137
+ // payload are handled by the always-run app-code step, so they are not part of
138
+ // this guard.
139
+ done: (c) => c.runIn(ptyLoadCommand()).code === 0 && c.runIn('command -v claude').code === 0,
128
140
  run: async (c) => {
129
141
  ensureOk(await c.runInStream(`npm install -g @anthropic-ai/claude-code@${c.pins.claudeCode}`))
130
142
  // Pin ttyd to the manifest version via its release binary; apt would float.
@@ -133,12 +145,7 @@ const STEPS = [
133
145
  `curl -fsSL -o /usr/local/bin/ttyd https://github.com/tsl0922/ttyd/releases/download/${c.pins.ttyd}/ttyd.aarch64 && chmod +x /usr/local/bin/ttyd`,
134
146
  ),
135
147
  )
136
- c.layPayload()
137
- // The payload now carries the skills tree into the app dir; link each skill
138
- // into the on-device personal-skills source so `claude` discovers them.
139
- c.linkSkills()
140
148
  await c.installDeps()
141
- c.writeLauncher()
142
149
  },
143
150
  },
144
151
  ]
package/lib/paths.mjs CHANGED
@@ -185,11 +185,13 @@ export function launcherScript({
185
185
  } = {}) {
186
186
  // Kill any prior relay before starting so `maxy-lite` always runs the freshly
187
187
  // installed server.mjs, never a stale process still holding the port (which made
188
- // a new build appear to "have no effect"). The relay writes its pid to
189
- // <vault>/.maxy-lite/relay.pid; kill via the bash builtin (no external tools),
190
- // and a best-effort pkill catches a relay started before pid-file support. The
191
- // relay's own EADDRINUSE handler makes any remaining conflict loud.
192
- const killPrior = `P=$(cat ${vaultGuest}/.maxy-lite/relay.pid 2>/dev/null); [ -n "$P" ] && kill "$P" 2>/dev/null; pkill -f "node server.mjs" 2>/dev/null; sleep 1`
188
+ // a new build appear to "have no effect"). Kill ONLY the pid the relay recorded in
189
+ // <vault>/.maxy-lite/relay.pid, via the bash builtin (no external tools). A broad
190
+ // `pkill -f "node server.mjs"` is NOT used: pkill -f matches the full command line,
191
+ // and this launcher's own `bash -lc '… exec node server.mjs'` contains that string,
192
+ // so it would SIGTERM its own session (proot vpid 1). A stale relay with no pid file
193
+ // is caught loudly by the relay's own EADDRINUSE handler instead.
194
+ const killPrior = `P=$(cat ${vaultGuest}/.maxy-lite/relay.pid 2>/dev/null); [ -n "$P" ] && kill "$P" 2>/dev/null; sleep 1`
193
195
  const inner = `${killPrior}; cd ${webchatDir} && ${webchatRunEnv({ vaultGuest, port })} exec node server.mjs`
194
196
  return `#!${prefix}/bin/bash
195
197
  # maxy-lite launcher — starts the on-device web chat relay.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-maxy-lite",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "Install maxy-lite on an Android phone: orchestrates proot-distro Ubuntu, glibc Node, claude, the web-chat relay, the vault and its bind-mount — run via npx in bare Termux.",
5
5
  "type": "module",
6
6
  "engines": {