Skip to content

Release/1.11.13 - #79

Merged
hotheadhacker merged 25 commits into
mainfrom
release/1.11.13
Jun 18, 2026
Merged

Release/1.11.13#79
hotheadhacker merged 25 commits into
mainfrom
release/1.11.13

Conversation

@hotheadhacker

Copy link
Copy Markdown
Contributor

No description provided.

… and source filtering

Signal channel now has full parity with Telegram:

Source filtering (signal.ts):
- Private mode: only Note to Self messages pass through
- Group mode: only Mercury group messages pass through
- All other chats/DMs silently dropped before any processing
- /pair only works in group mode after source filter
- Private mode auto-pairs account owner as admin on first message

Routing fixes (signal.ts):
- Removed channelId sanitization — phone numbers and group IDs
  are no longer mangled, fixing all outgoing message routing
- sendFile() group guard aligned with sendRaw()
- resolveTarget() now correctly routes in both modes

Permissions (index.ts):
- Signal wired into onAsk permission handler
- Signal wired into setOnPermissionMode callback
- Signal wired into setChatCommandContext
- Signal wired into setSendFileHandler with explicit channel param

Task lifecycle (agent.ts):
- Signal wired into beginTask/resetStepCounter at task start
- Signal wired into sendToolFeedback/sendStepDone during tool execution
- Signal wired into endTask/resetStepCounter on error
- Signal wired into sendCompletion/popDeferredResponse on completion
- Signal included in canStream for canned text streaming
- SignalChannel imported alongside TelegramChannel

send_file channel parameter (send-file.ts, registry.ts):
- Added optional 'channel' param (signal|telegram)
- When user says 'send via Signal', routes to Signal explicitly

Unregister fixes (setup.ts, index.ts):
- checkLocalAccountData() now checks registered field — treats
  unregistered accounts as not linked
- deleteSignalCliAccountData() removes local account data after
  unregister so next setup triggers fresh device link
- unregisterSignalNumber() uses findSignalCli() not ensureSignalCli()
  to avoid downloading signal-cli just to unregister
- Both unregister flows (CLI and configure) call deleteSignalCliAccountData()
- 'Keep config → No' no longer deletes signal-cli account data (device
  is still linked on server, only Mercury config is cleared)

Setup flow fixes (index.ts):
- 'Keep config → No' now re-asks mode (group/private)
- Private mode auto-pairs account owner as admin during setup
- Removed link URI display (QR code only)
- startLinking timeout increased from 15s to 60s
- startLinking now checks stderr for sgnl:// URI
- sendSignalMessage uses findSignalCli() not ensureSignalCli()
Channels should be open — anyone can talk to Mercury in a channel where
it's been installed. Access requests (admin approval) only apply to DMs.

Also adds token prefix hints (xoxb-/xapp-) and App Home step to setup.
- message event handler now only processes DMs
- app_mention handler processes channel @mentions (with rate limiting)
- Removed handleChannelMessage method (no longer needed)
… DM approval, no pairing codes

- First user to DM /mercury start auto-becomes admin (no CLI pairing needed)
- Subsequent users get 3-button approval DM to admins: Approve as Admin, Approve as Member, Reject
- Removed completeInitialSlackPairing() from CLI (no longer needed)
- Removed pairing code generation and approveSlackPendingRequestByPairingCode usage
- Updated slack approve CLI command to only accept userId (no pairing code)
- Cleaned up formatSlackUser to remove pairing code display
…or android/x86_64

Rollup has no native binary for android/x86_64, causing tsup/vitest to
crash with throwUnsupportedError. After npm ci, install @rollup/wasm-node
and symlink it over node_modules/rollup so the WASM build is used instead.

Also adds PATH and HOME exports needed for the Termux container environment.
- chown entire /home/builder (not just project dir)
- mkdir+chown /home/builder/.npm before su
- use 'su system' (no login flag) to preserve env exports
- set npm_config_cache inside project dir (owned by system)
- replace rollup with @rollup/wasm-node symlink (no native binary for android/x86_64)
- Web assets (UI + static) now resolve relative to the binary when
  running as a Bun --compile standalone, fixing the dashboard for
  binary users who previously got 'Run: cd ui && npm run build'
- server.ts, auth.ts, brain-fallback.ts detect  in __dirname
  and fall back to process.execPath-based paths
- build-bin.cjs copies dist/web/ alongside each binary and creates
  web.tar.gz for GitHub release uploads; checksums include web assets
- install.sh and install.ps1 download and extract web.tar.gz
- mercury upgrade detects standalone binary via isStandaloneBinary()
  and re-runs the appropriate installer script instead of npm
- Termux CI: fix ownership, cache, and rollup wasm fallback for
  android/x86_64
ash (Termux /bin/sh) reported 'ci: syntax error: unmatched {' for
the previous npm ci || { ... } block. Replace with plain
'npm ci || npm install' which ash accepts while keeping the same
fallback behavior when better-sqlite3 native build fails.
…r optional native deps

npm ci aborts the entire install when better-sqlite3's gyp build fails,
which is fine, but the previous || npm install fallback regenerated the
lockfile and node_modules lost the tsup .bin symlink, causing
'tsup: not found' on the next step.

Switch to plain 'npm install' for Termux — it tolerates optional native
dep build failures (better-sqlite3) while keeping all devDeps installed.
python + build-essential are still installed for any package that does
need a native build.
…ectly

npm 11's new allow-scripts policy blocks esbuild's postinstall, which
prevents the esbuild platform binary from being downloaded. As a side
effect, tsup's .bin symlink resolution can fail in some Termux/ash
setups, causing 'sh: 1: tsup: not found' even though tsup itself is
installed.

Workaround: set npm_config_allow_scripts=true so esbuild's binary is
fetched, and invoke tsup directly via 'node node_modules/tsup/dist/cli-default.js'
to skip the .bin symlink lookup entirely. Then run the post-build
script and tests as before.
… 11)

npm 11 added a project-scoped install-script policy that blocks all
postinstall scripts by default. The --allow-scripts flag and the
npm_config_allow_scripts env var are both rejected in project installs
with EALLOWSCRIPTS; the only allowed path is the allowScripts field in
package.json (or .npmrc).

Add 'allowScripts.esbuild: true' so the esbuild platform binary is
downloaded during install. Drop the env var that caused the previous
run to fail.

This also fixes the tsup bin-link issue in Termux, because the
postinstall chain that esbuild triggers is what makes tsup's .bin
symlink resolve correctly.
Stop guessing. Add:
  - set -ex for full command tracing
  - node/npm/uname/pwd versions
  - ls -la of node_modules/.bin/tsup and node_modules/tsup/dist/
  - file/readlink on the symlink
  - head -1 of cli-default.js to confirm the file is a real script
  - foreground-scripts on npm install so gyp output is visible
  - tail -200 to keep log size sane

This will tell us, on the next run, exactly:
  1. Which npm version is in the Termux container
  2. Whether tsup is actually installed and linked
  3. Whether the .bin symlink is broken or absent
  4. Whether the better-sqlite3 gyp build is silently failing

Once we have this data, we can replace this debug step with a real fix.
The previous 'su system -c \' ... \'' nested quoting was being mangled
by bash — su received 'set' as the user and the script body as
positional args, producing 'su: Unknown option -' followed by the
script content.

Fix: write the Termux CI commands to a file via heredoc on the host,
mount it into the container read-only, copy to /home/builder, chown to
system, and 'su system /home/builder/termux-ci.sh' — no inner quoting
required. This is the same pattern the working d4028ba used.
The previous order printed node --version before pkg install nodejs-lts,
so the script failed with 'node: not found' on the very first check —
we never got any actual debug data.

Reorder: env, then pkg install, then versions, then install, then
inspection. Also add 'which node' / 'which npm' so we can see exactly
where they live.
…uilt

The previous failures were all chasing the wrong target. The real
data from the diagnostic run proved:
  - node 24.16.0 / npm 11.17.0 install fine in Termux
  - node_modules/.bin/tsup symlink is present and correct
  - 'node node_modules/tsup/dist/cli-default.js' runs and tsup
    reports 'ESM Build success in 2882ms'
  - The actual failure is scripts/post-build.cjs, which runs
    'npm install' in ui/ and then 'npx vite build'. Vite pulls in
    esbuild, and esbuild's postinstall tries to download a platform
    binary for android|x64 — which esbuild does not ship. The
    install.js script later tries 'spawnSync ui/node_modules/esbuild/
    bin/esbuild' and fails with ENOENT.

The CLI agent does not need the web dashboard to run, and the web
dashboard is already exercised by the linux/macos/windows CI jobs.
Skip the UI install + build when TERMUX_VERSION is set, and skip the
ui/dist copy when the dir doesn't exist.

Clean up the debug noise from the Termux step now that the root
cause is known. Keep the file-based su invocation (works), the
python + build-essential install (needed for better-sqlite3 gyp),
and the @rollup/wasm-node symlink swap (works).
npm run build's 'tsup' command isn't finding node_modules/.bin/tsup
in PATH inside the Termux container (ash). The diagnostic run proved
the symlink exists and node node_modules/tsup/dist/cli-default.js works.
Replace npm run build with the two explicit node invocations.
Some Termux mirrors are unreliable. If pkg update hits a bad mirror,
fall back and continue — the install step will still work with cached
indices.
The service worker file writes to dist/web/ui/sw.js, but on Termux
the entire ui/ dir is skipped (no esbuild prebuilt). Guard the
writeFileSync behind an existsSync check.
npm run script invocations and vitest rely on node_modules/.bin being in
PATH. In Termux's ash shell this isn't set up automatically. Add it
explicitly after cd into the project dir so all bin scripts (tsup,
vitest, etc.) are found.
…itest

npm test spawns 'sh -c vitest run' but the child shell doesn't inherit
the PATH we set. npx resolves the binary directly.
npx spawns 'sh -c vitest' which still can't find the binary.
Invoke vitest.mjs directly with node, same as tsup.
@hotheadhacker
hotheadhacker merged commit 0de8955 into main Jun 18, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants