fix(ecosystem): use 'node --import tsx' for cross-platform PM2 spawn (closes #234)#245
Merged
Conversation
install.sh and install.ps1 previously hardcoded the install path to $HOME/metabot. Add a CLI flag (and matching PowerShell parameter) plus an interactive prompt so users can install MetaBot anywhere. - Priority: --dir / -Dir > METABOT_HOME env var > prompt > default. - Tilde expansion + absolute-path validation; refuses to clobber $HOME / system roots. - Persists METABOT_HOME to ~/.bashrc / ~/.zshrc (Linux/macOS) or user-level env (Windows) when non-default, so the mm/mb/metabot CLIs can locate the install in new shells.
fix(codex): show model metadata in cards
fix(codex): mirror skills and avoid bwrap sandbox
fix(codex): tolerate AGENTS deployment failures
…back fix(codex): install bundled skills when user cache is empty
docs: explain Codex skill migration
Closes #234. The previous interpreter pointed at node_modules/.bin/tsx, which is a POSIX shell wrapper on Windows with no .cmd shim. PM2 spawns the interpreter via child_process.spawn, which cannot exec a sh script directly on Windows (EINVAL) — the process appeared to start but died at exec time, leaving 'pm2 list' showing online with pid: N/A. Switching to 'node --import tsx' is tsx 4.x's documented cross-platform entrypoint and behaves identically on Linux, macOS, and Windows. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
5 tasks
This was referenced May 11, 2026
Liyunlun
added a commit
to Liyunlun/metabot
that referenced
this pull request
May 12, 2026
* fix(executor): switch to auto permission mode when running as root (xvirobotics#212) Claude Code blocks --dangerously-skip-permissions under root/sudo privileges (exit code 1). Detect root via process.getuid() and fall back to permissionMode 'auto', which auto-approves all tool permissions without that flag. Non-root behaviour is unchanged (bypassPermissions). Also update docs/troubleshooting.md and CLAUDE.md to document this as Cause B of the "process exited with code 1" error. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(feishu): propagate send/update failures so retry + fallback actually trigger (xvirobotics#213) MessageSender's updateCard / sendImage / sendFile silently swallowed API errors and returned void. Downstream: - sendFinalCard's retry + text fallback in MessageBridge never ran — the try/catch was unreachable. When a long task produced many throttled card updates, the final "complete" update could be rate-limited by Feishu and silently lost, leaving the card stuck on an intermediate tool state (e.g. "⏳ bash") even after the task finished. (fixes xvirobotics#186) - sendImageFile / sendLocalFile returned true even when the actual message send step failed after a successful upload. The text fallback in OutputHandler (triggered on false) never fired, so group chats whose file-send call failed got no file and no notification. (fixes xvirobotics#190) Change updateCard / sendImage / sendFile to return Promise<boolean>, and propagate the real success signal through sendImageFile / sendLocalFile and sendFinalCard. Return-based signalling (not throw) keeps the many fire-and-forget call sites inside rate-limiter schedule callbacks safe from unhandled promise rejections. Also updated the IMessageSender interface and the Telegram / WeChat / Null sender implementations to match. Co-authored-by: Flood Sung <floodsung@xvirobotics.ai> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * feat(feishu): surface Monitor / background task events on the live card (xvirobotics#217) When Claude kicked off a background task (Monitor, long-running Task tool, etc.) the Feishu card stopped updating — task_started / task_progress / task_notification / task_updated system messages were dropped in StreamProcessor, so the user saw "bot went silent" even though the agent was receiving live events. - Add `BackgroundEvent` to the shared CardState shape (taskId, description, status, lastEvent). - StreamProcessor now tracks one BackgroundEvent per task_id and updates it on every SDK `type:'system'` with a task_* subtype. Also covers the Codex translator's `type:'task_notification'` shape. Ambient / `skip_transcript:true` tasks stay hidden. - Card builder renders a "📡 Background" section with per-task status icon (⏳ running, ✅ completed, ❌ failed, ⏹️ stopped), short task id, description, and the latest event line. - Tests: 9 new cases in stream-processor.test.ts covering started / progress / notification statuses / updated patch / skip_transcript / missing task_id / codex shape / result propagation; 2 new cases in card-builder.test.ts for the rendered section. Co-authored-by: Flood Sung <floodsung@xvirobotics.ai> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * feat(installer): allow custom install directory via --dir / -Dir flag (xvirobotics#220) install.sh and install.ps1 previously hardcoded the install path to $HOME/metabot. Add a CLI flag (and matching PowerShell parameter) plus an interactive prompt so users can install MetaBot anywhere. - Priority: --dir / -Dir > METABOT_HOME env var > prompt > default. - Tilde expansion + absolute-path validation; refuses to clobber $HOME / system roots. - Persists METABOT_HOME to ~/.bashrc / ~/.zshrc (Linux/macOS) or user-level env (Windows) when non-default, so the mm/mb/metabot CLIs can locate the install in new shells. Co-authored-by: Flood Sung <floodsung@xvirobotics.ai> * fix(feishu): require explicit @mention match when botOpenId is known (xvirobotics#225) * feat(installer): allow custom install directory via --dir / -Dir flag install.sh and install.ps1 previously hardcoded the install path to $HOME/metabot. Add a CLI flag (and matching PowerShell parameter) plus an interactive prompt so users can install MetaBot anywhere. - Priority: --dir / -Dir > METABOT_HOME env var > prompt > default. - Tilde expansion + absolute-path validation; refuses to clobber $HOME / system roots. - Persists METABOT_HOME to ~/.bashrc / ~/.zshrc (Linux/macOS) or user-level env (Windows) when non-default, so the mm/mb/metabot CLIs can locate the install in new shells. * fix(feishu): require explicit @mention match when botOpenId is known The previous `!botOpenId || m.id?.open_id === botOpenId` short-circuit treated *any* @mention in a group as if the bot were mentioned whenever botOpenId was unset, and incidentally also matched any single mention when it was set (because `.some()` returns true on the first iteration where `!botOpenId` is true). Replace with a clearer branch: when botOpenId is known, match strictly; otherwise fall back to "any mention present" so bots without a resolved open_id still behave reasonably. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Flood Sung <floodsung@xvirobotics.ai> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * fix(ecosystem): use 'node --import tsx' for cross-platform PM2 spawn (closes xvirobotics#234) (xvirobotics#245) * feat(installer): allow custom install directory via --dir / -Dir flag install.sh and install.ps1 previously hardcoded the install path to $HOME/metabot. Add a CLI flag (and matching PowerShell parameter) plus an interactive prompt so users can install MetaBot anywhere. - Priority: --dir / -Dir > METABOT_HOME env var > prompt > default. - Tilde expansion + absolute-path validation; refuses to clobber $HOME / system roots. - Persists METABOT_HOME to ~/.bashrc / ~/.zshrc (Linux/macOS) or user-level env (Windows) when non-default, so the mm/mb/metabot CLIs can locate the install in new shells. * fix(codex): show model metadata in cards * fix(codex): mirror skills and avoid bwrap sandbox * fix(codex): tolerate agents deployment failures * fix(codex): install bundled skills when user cache is empty * docs: explain Codex skill migration * fix(ecosystem): use 'node --import tsx' for cross-platform spawn Closes xvirobotics#234. The previous interpreter pointed at node_modules/.bin/tsx, which is a POSIX shell wrapper on Windows with no .cmd shim. PM2 spawns the interpreter via child_process.spawn, which cannot exec a sh script directly on Windows (EINVAL) — the process appeared to start but died at exec time, leaving 'pm2 list' showing online with pid: N/A. Switching to 'node --import tsx' is tsx 4.x's documented cross-platform entrypoint and behaves identically on Linux, macOS, and Windows. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Flood Sung <floodsung@xvirobotics.ai> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * feat(session): disable session TTL (sessions never expire) (xvirobotics#242) Previously sessions auto-expired after 24h. This made resuming long-running projects unreliable — users would return after a day and find their context gone, even though Claude's session JSONL still exists on disk. Set SESSION_TTL_MS = Infinity. Users can still manually /reset. Also adds a comment about the sibling concern: when switching a bot's defaultWorkingDirectory, sessions-*.json must be preserved so old projects can be resumed. Co-authored-by: uestney <uestney@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * fix(install): fail fast on git pull error and stale checkout (refs xvirobotics#224) (xvirobotics#246) * feat(installer): allow custom install directory via --dir / -Dir flag install.sh and install.ps1 previously hardcoded the install path to $HOME/metabot. Add a CLI flag (and matching PowerShell parameter) plus an interactive prompt so users can install MetaBot anywhere. - Priority: --dir / -Dir > METABOT_HOME env var > prompt > default. - Tilde expansion + absolute-path validation; refuses to clobber $HOME / system roots. - Persists METABOT_HOME to ~/.bashrc / ~/.zshrc (Linux/macOS) or user-level env (Windows) when non-default, so the mm/mb/metabot CLIs can locate the install in new shells. * fix(codex): show model metadata in cards * fix(codex): mirror skills and avoid bwrap sandbox * fix(codex): tolerate agents deployment failures * fix(codex): install bundled skills when user cache is empty * docs: explain Codex skill migration * fix(install): fail fast on git pull error and stale checkout Closes xvirobotics#224. Both install.sh and install.ps1 previously swallowed `git pull --ff-only` failures with a warning and continued with stale code, causing later phases (typically Phase 6 'skill not found') to error with a confusing 'cannot find path src/skills/metaskill/SKILL.md' even though that path is in the repo — the user's local checkout had simply diverged. - Phase 2: `git pull --ff-only` failure now exits with diagnostics and three concrete remediation commands (inspect / stash+retry / hard reset) instead of warn-and-continue. - Phase 6: Adds a one-shot Test-Path / [[ -f ]] sentinel on the bundled metaskill SKILL.md so a stale checkout fails immediately with a clear message rather than midway through a Copy-Item / cp. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Flood Sung <floodsung@xvirobotics.ai> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * fix(cli): auto-detect METABOT_HOME from script's own location (xvirobotics#247) * feat(installer): allow custom install directory via --dir / -Dir flag install.sh and install.ps1 previously hardcoded the install path to $HOME/metabot. Add a CLI flag (and matching PowerShell parameter) plus an interactive prompt so users can install MetaBot anywhere. - Priority: --dir / -Dir > METABOT_HOME env var > prompt > default. - Tilde expansion + absolute-path validation; refuses to clobber $HOME / system roots. - Persists METABOT_HOME to ~/.bashrc / ~/.zshrc (Linux/macOS) or user-level env (Windows) when non-default, so the mm/mb/metabot CLIs can locate the install in new shells. * fix(codex): show model metadata in cards * fix(codex): mirror skills and avoid bwrap sandbox * fix(codex): tolerate agents deployment failures * fix(codex): install bundled skills when user cache is empty * docs: explain Codex skill migration * fix(cli): auto-detect METABOT_HOME from script's own location `mb` and `metabot` previously hard-coded `$HOME/metabot` as the fallback install path. When MetaBot is installed elsewhere and METABOT_HOME isn't exported (e.g. on a fresh shell, or after a non-default install where the shell rc was never updated), the CLIs read no .env, fall back to API_SECRET=changeme, and every API call returns 401 Unauthorized. Resolve the script's own path via `readlink -f` and use its parent as METABOT_HOME when METABOT_HOME is unset. This makes both `~/.local/bin/mb` copies (default install) and symlinks (manual setup) discover the right .env without requiring the user to export METABOT_HOME. `mm` already had this fallback — port the same pattern to mb/metabot. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Flood Sung <floodsung@xvirobotics.ai> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: zhangsanxueai <149186776+zhangsanxueai@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Flood Sung <floodsung@gmail.com> Co-authored-by: Flood Sung <floodsung@xvirobotics.ai> Co-authored-by: uestney <uestney@gmail.com> Co-authored-by: uestney <uestney@users.noreply.github.com>
SimonYeyi
pushed a commit
to SimonYeyi/metabot
that referenced
this pull request
May 26, 2026
…loses xvirobotics#234) (xvirobotics#245) * feat(installer): allow custom install directory via --dir / -Dir flag install.sh and install.ps1 previously hardcoded the install path to $HOME/metabot. Add a CLI flag (and matching PowerShell parameter) plus an interactive prompt so users can install MetaBot anywhere. - Priority: --dir / -Dir > METABOT_HOME env var > prompt > default. - Tilde expansion + absolute-path validation; refuses to clobber $HOME / system roots. - Persists METABOT_HOME to ~/.bashrc / ~/.zshrc (Linux/macOS) or user-level env (Windows) when non-default, so the mm/mb/metabot CLIs can locate the install in new shells. * fix(codex): show model metadata in cards * fix(codex): mirror skills and avoid bwrap sandbox * fix(codex): tolerate agents deployment failures * fix(codex): install bundled skills when user cache is empty * docs: explain Codex skill migration * fix(ecosystem): use 'node --import tsx' for cross-platform spawn Closes xvirobotics#234. The previous interpreter pointed at node_modules/.bin/tsx, which is a POSIX shell wrapper on Windows with no .cmd shim. PM2 spawns the interpreter via child_process.spawn, which cannot exec a sh script directly on Windows (EINVAL) — the process appeared to start but died at exec time, leaving 'pm2 list' showing online with pid: N/A. Switching to 'node --import tsx' is tsx 4.x's documented cross-platform entrypoint and behaves identically on Linux, macOS, and Windows. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Flood Sung <floodsung@xvirobotics.ai> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces
interpreter: node_modules/.bin/tsxwithinterpreter: node+interpreter_args: '--import tsx'so PM2 can launch MetaBot on Windows withoutEINVAL.Why
The POSIX shell wrapper at
node_modules/.bin/tsxcannot beexec'd directly bychild_process.spawnon Windows (no.cmdshim is consulted withoutshell: true). The result was thatpm2 start ecosystem.config.cjsreported the process as online while it actually died at exec time —pm2 infoshowedpid: N/A/mem: 0b, and pidusage spammed "PID invalid" errors.node --import tsxis tsx 4.x's documented cross-platform entrypoint and works identically on Linux, macOS, and Windows. tsx is already a dependency (^4.21.0) and Node ≥ 20.6 is already a documented prerequisite, so no version bumps are needed.Test plan
node --import tsx -e "..."resolves the loader locallynpm run buildpassesnpm test— 219/219 passnpm run lint— no new errorspm2 start ecosystem.config.cjs && pm2 listshows real pid + memoryNotes
PR #244 also rewrites
ecosystem.config.cjs. If #244 lands first, the fix needs to be re-applied there (the diff still spawns tsx via the wrapper script).Closes #234.
🤖 Generated with Claude Code