Skip to content

Package npm CLI for Node runtimes#9

Open
batuhan wants to merge 1 commit into
mainfrom
codex/npm-runtime-cli
Open

Package npm CLI for Node runtimes#9
batuhan wants to merge 1 commit into
mainfrom
codex/npm-runtime-cli

Conversation

@batuhan
Copy link
Copy Markdown
Member

@batuhan batuhan commented May 19, 2026

Summary

  • replace the npm package binary downloader with a generated Node launcher plus the compiled CLI tree
  • copy and minify emitted CLI JavaScript for npm/npx while keeping Bun for dependency management, binary builds, and Homebrew packaging
  • re-exec accounts add --webview through bun when Node is running and report a clear unavailable message when Bun/WebView is unavailable

Verification

  • bun run --filter ./packages/npm test
  • bun run --filter @beeper/cli typecheck
  • bun run --filter @beeper/cli test
  • node packages/npm/bin/beeper.js --help
  • node packages/npm/bin/beeper.js accounts add --help
  • bun pm pack --dry-run in packages/npm
  • PATH without Bun: node packages/npm/bin/beeper.js accounts add discord --webview --non-interactive reports Bun is required

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 19, 2026

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Accounts "add" command can relaunch under a Bun/WebView environment to collect cookies when requested.
  • Chores

    • CLI packaging and build were reworked: distribution layout and launcher behavior updated; startup logo behavior adjusted.
    • JavaScript minification added to the CLI build.
    • Package metadata and runtime dependency declarations updated.

Walkthrough

This PR modernizes the Beeper CLI distribution by replacing a platform-specific binary download mechanism with prebuilt copying, adds WebView cookie-collection support via Bun re-execution, introduces terser-based JavaScript minification, and updates the npm package manifest with dependencies and oclif CLI framework configuration.

Changes

CLI Distribution Modernization and WebView Support

Layer / File(s) Summary
Minification Tool Foundation
package.json
Adds terser as a shared dev dependency to support JavaScript minification in the build pipeline.
WebView Runtime Re-execution
packages/cli/src/commands/accounts/add.ts
Implements reexecWithBunForWebViewIfNeeded() to detect Bun/WebView availability, verify Bun is executable, and re-launch the CLI under Bun when WebView cookie collection is requested; includes PATH fallback to an installed beeper binary, synchronous probing/spawn via spawnSync, and explicit error paths.
NPM Package Configuration
packages/npm/package.json
Updates package metadata, publish file list (removes binaries.json, adds dist), runtime dependencies (@beeper/desktop-api on next ref plus CLI libraries), and adds comprehensive oclif CLI configuration for command generation, help options, JIT plugins, update-warning behavior, and command topics.
Build Process Refactoring and Minification
packages/npm/scripts/build.ts
Replaces binary download logic with prebuilt copy strategy, introduces new @oclif/core-based launcher with conditional logo output, and adds minifyJavaScriptTree() and walkJavaScriptFiles() helpers to minify both dist/ and bin/ trees while preserving shebangs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: packaging the CLI for Node runtimes, which aligns with replacing the binary downloader with a generated Node launcher.
Description check ✅ Passed The description provides relevant context about the changeset, covering the three main aspects: binary downloader replacement, minification for npm/npx, and WebView re-execution logic.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/npm-runtime-cli

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
packages/npm/package.json (1)

22-37: ⚡ Quick win

GitHub branch reference may cause non-reproducible builds.

The @beeper/desktop-api dependency references github:beeper/desktop-api-js#next, which tracks a branch rather than a specific commit. This means builds at different times could resolve to different code, making debugging and rollbacks harder.

Consider pinning to a specific commit SHA or published version for reproducibility:

-    "`@beeper/desktop-api`": "github:beeper/desktop-api-js#next",
+    "`@beeper/desktop-api`": "github:beeper/desktop-api-js#<commit-sha>",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/npm/package.json` around lines 22 - 37, The dependency entry for
"`@beeper/desktop-api`" in package.json currently points to the branch ref
"github:beeper/desktop-api-js#next", which can produce non-reproducible builds;
update that dependency in package.json to a stable reference by replacing
"github:beeper/desktop-api-js#next" with either a published semver version
(e.g., "1.2.3") or a full commit SHA reference (e.g.,
"github:beeper/desktop-api-js#<commit-sha>"), then run your lockfile update (npm
install / npm ci / yarn install) to regenerate package-lock.json or yarn.lock so
builds are deterministic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/cli/src/commands/accounts/add.ts`:
- Around line 90-93: Replace the loose existence check of globalThis.Bun with
explicit checks for Bun and Bun.WebView: if globalThis.Bun is undefined, return
early (same behavior); else if Bun exists but Bun.WebView is falsy, throw a
clear Error stating Bun.WebView is unavailable (use the existing message or
similar). Update the conditional logic around the existing lines that reference
(globalThis as { Bun?: unknown }).Bun and the
process.env.BEEPER_CLI_WEBVIEW_REEXEC branch so callers (and account-login.ts)
get an immediate, specific error when Bun.WebView is missing.

In `@packages/npm/scripts/build.ts`:
- Line 3: Remove the unused `dirname` import from the top-level import
statement: update the import from 'node:path' to only import `join` (remove
`dirname`) since `dirname` is not referenced in this module and the launcher
code uses a string literal instead; locate the import line that currently reads
`import { dirname, join } from 'node:path'` and change it so only `join` is
imported.

---

Nitpick comments:
In `@packages/npm/package.json`:
- Around line 22-37: The dependency entry for "`@beeper/desktop-api`" in
package.json currently points to the branch ref
"github:beeper/desktop-api-js#next", which can produce non-reproducible builds;
update that dependency in package.json to a stable reference by replacing
"github:beeper/desktop-api-js#next" with either a published semver version
(e.g., "1.2.3") or a full commit SHA reference (e.g.,
"github:beeper/desktop-api-js#<commit-sha>"), then run your lockfile update (npm
install / npm ci / yarn install) to regenerate package-lock.json or yarn.lock so
builds are deterministic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b9804022-ccac-4bbc-8d09-90dcd7fd672b

📥 Commits

Reviewing files that changed from the base of the PR and between 9502715 and 506c140.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • package.json
  • packages/cli/src/commands/accounts/add.ts
  • packages/npm/package.json
  • packages/npm/scripts/build.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: test (macos-latest / bun 1.3.10)
  • GitHub Check: test (ubuntu-latest / bun 1.3.10)
  • GitHub Check: test (ubuntu-latest / bun 1.3.10)
  • GitHub Check: test (macos-latest / bun 1.3.10)
🧰 Additional context used
🪛 ESLint
packages/cli/src/commands/accounts/add.ts

[error] 111-111: Don't use process.exit(); throw an error instead.

(n/no-process-exit)


[error] 111-111: Only use process.exit() in CLI apps. Throw an error instead.

(unicorn/no-process-exit)

packages/npm/scripts/build.ts

[error] 3-3: 'dirname' is defined but never used.

(@typescript-eslint/no-unused-vars)

🔇 Additional comments (7)
package.json (1)

33-33: LGTM!

packages/npm/package.json (1)

4-21: LGTM!

Also applies to: 38-121

packages/npm/scripts/build.ts (3)

31-45: LGTM!


47-67: LGTM!


16-29: LGTM!

packages/cli/src/commands/accounts/add.ts (2)

2-2: LGTM!

Also applies to: 34-34


95-112: LGTM!

Comment on lines +90 to +93
if ((globalThis as { Bun?: unknown }).Bun) return
if (process.env.BEEPER_CLI_WEBVIEW_REEXEC === '1') {
throw new Error('Account web views are unavailable because this Bun runtime does not expose Bun.WebView.')
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Find usage patterns of Bun.WebView to confirm the correct check

# Search for Bun.WebView usage
rg -nP --type=ts -C3 'Bun\.WebView'

# Search for Bun global checks
rg -nP --type=ts -C3 'globalThis.*Bun'

Repository: beeper/cli

Length of output: 4532


Check specifically for Bun.WebView, not just Bun.

The current check on line 90 verifies that the Bun global exists, but the feature requires Bun.WebView specifically. If the code runs under a Bun runtime that exposes the Bun global but lacks Bun.WebView, the function returns early and later code in account-login.ts will throw a generic error when it tries to use WebView. Checking both conditions separately provides immediate, clear error messages for each case.

🔍 Proposed fix
 function reexecWithBunForWebViewIfNeeded(): void {
-  if ((globalThis as { Bun?: unknown }).Bun) return
+  const hasBunWebView = Boolean((globalThis as { Bun?: { WebView?: unknown } }).Bun?.WebView)
+  const hasBun = Boolean((globalThis as { Bun?: unknown }).Bun)
+  
+  if (hasBunWebView) return
+  
+  if (hasBun) {
+    throw new Error('Account web views require Bun.WebView, which is not available in this Bun runtime. Provide cookies manually with --cookie.')
+  }
+  
   if (process.env.BEEPER_CLI_WEBVIEW_REEXEC === '1') {
     throw new Error('Account web views are unavailable because this Bun runtime does not expose Bun.WebView.')
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if ((globalThis as { Bun?: unknown }).Bun) return
if (process.env.BEEPER_CLI_WEBVIEW_REEXEC === '1') {
throw new Error('Account web views are unavailable because this Bun runtime does not expose Bun.WebView.')
}
const hasBunWebView = Boolean((globalThis as { Bun?: { WebView?: unknown } }).Bun?.WebView)
const hasBun = Boolean((globalThis as { Bun?: unknown }).Bun)
if (hasBunWebView) return
if (hasBun) {
throw new Error('Account web views require Bun.WebView, which is not available in this Bun runtime. Provide cookies manually with --cookie.')
}
if (process.env.BEEPER_CLI_WEBVIEW_REEXEC === '1') {
throw new Error('Account web views are unavailable because this Bun runtime does not expose Bun.WebView.')
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/src/commands/accounts/add.ts` around lines 90 - 93, Replace the
loose existence check of globalThis.Bun with explicit checks for Bun and
Bun.WebView: if globalThis.Bun is undefined, return early (same behavior); else
if Bun exists but Bun.WebView is falsy, throw a clear Error stating Bun.WebView
is unavailable (use the existing message or similar). Update the conditional
logic around the existing lines that reference (globalThis as { Bun?: unknown
}).Bun and the process.env.BEEPER_CLI_WEBVIEW_REEXEC branch so callers (and
account-login.ts) get an immediate, specific error when Bun.WebView is missing.

import { chmod, cp, mkdir, readFile, rm, writeFile } from 'node:fs/promises'
import { existsSync } from 'node:fs'
import { join } from 'node:path'
import { dirname, join } from 'node:path'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove unused dirname import.

Static analysis correctly identifies that dirname is imported but never used in this file. The launcher function's generated code uses dirname, but that's a string literal, not this import.

Proposed fix
-import { dirname, join } from 'node:path'
+import { join } from 'node:path'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { dirname, join } from 'node:path'
import { join } from 'node:path'
🧰 Tools
🪛 ESLint

[error] 3-3: 'dirname' is defined but never used.

(@typescript-eslint/no-unused-vars)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/npm/scripts/build.ts` at line 3, Remove the unused `dirname` import
from the top-level import statement: update the import from 'node:path' to only
import `join` (remove `dirname`) since `dirname` is not referenced in this
module and the launcher code uses a string literal instead; locate the import
line that currently reads `import { dirname, join } from 'node:path'` and change
it so only `join` is imported.

@batuhan batuhan force-pushed the codex/npm-runtime-cli branch from 506c140 to cf88821 Compare May 19, 2026 23:12
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/npm/package.json`:
- Line 23: Replace the moving branch ref for the dependency key
"`@beeper/desktop-api`" in package.json so installs are reproducible: change the
value currently using "`#next`" to the immutable commit SHA
"550009b71f922f605d4ca0e0059bbed6627e5fbe" (e.g.
"github:beeper/desktop-api#550009b71f922f605d4ca0e0059bbed6627e5fbe") or to a
published semver release; update the package.json entry for
"`@beeper/desktop-api`" and run a fresh install to verify lockfile changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e910f2f4-89db-4ad5-9b1a-dec4e549e051

📥 Commits

Reviewing files that changed from the base of the PR and between 506c140 and cf88821.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • package.json
  • packages/cli/src/commands/accounts/add.ts
  • packages/npm/package.json
  • packages/npm/scripts/build.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: test (macos-latest / bun 1.3.10)
  • GitHub Check: test (ubuntu-latest / bun 1.3.10)
  • GitHub Check: test (macos-latest / bun 1.3.10)
  • GitHub Check: test (ubuntu-latest / bun 1.3.10)
🧰 Additional context used
🪛 ESLint
packages/cli/src/commands/accounts/add.ts

[error] 110-110: Don't use process.exit(); throw an error instead.

(n/no-process-exit)


[error] 110-110: Only use process.exit() in CLI apps. Throw an error instead.

(unicorn/no-process-exit)


[error] 126-126: Don't use process.exit(); throw an error instead.

(n/no-process-exit)


[error] 126-126: Only use process.exit() in CLI apps. Throw an error instead.

(unicorn/no-process-exit)


[error] 141-141: Expected blank line before this statement.

(@stylistic/padding-line-between-statements)

packages/npm/scripts/build.ts

[error] 3-3: 'dirname' is defined but never used.

(@typescript-eslint/no-unused-vars)

🔇 Additional comments (5)
packages/cli/src/commands/accounts/add.ts (2)

92-95: Still missing an explicit Bun.WebView capability check before returning.

This still short-circuits on Bun presence alone, so environments with Bun but without Bun.WebView won’t fail early with the intended clear message.


2-3: LGTM!

Also applies to: 5-5, 36-37, 129-150

packages/npm/scripts/build.ts (2)

3-3: Already reported: remove unused dirname import.


5-68: LGTM!

packages/npm/package.json (1)

4-22: LGTM!

Also applies to: 24-122

Comment thread packages/npm/package.json
"typecheck": "bun build scripts/build.ts --target=bun --outdir=/tmp/beeper-cli-npm-check --entry-naming='[name].js'"
},
"dependencies": {
"@beeper/desktop-api": "github:beeper/desktop-api-js#next",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Declared dependency:"
jq -r '.dependencies["`@beeper/desktop-api`"]' packages/npm/package.json

echo
echo "Current commit behind 'next' branch:"
curl -s https://api.github.com/repos/beeper/desktop-api-js/commits/next | jq -r '.sha, .commit.committer.date'

Repository: beeper/cli

Length of output: 209


Pin @beeper/desktop-api to an immutable version.

Line 23 uses a moving branch ref (#next), which makes installs non-reproducible and increases supply-chain risk for published npm consumers. The current commit behind the next branch is 550009b71f922f605d4ca0e0059bbed6627e5fbe. Replace the branch reference with this or a stable commit SHA:

-    "`@beeper/desktop-api`": "github:beeper/desktop-api-js#next",
+    "`@beeper/desktop-api`": "github:beeper/desktop-api-js#550009b71f922f605d4ca0e0059bbed6627e5fbe",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"@beeper/desktop-api": "github:beeper/desktop-api-js#next",
"`@beeper/desktop-api`": "github:beeper/desktop-api-js#550009b71f922f605d4ca0e0059bbed6627e5fbe",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/npm/package.json` at line 23, Replace the moving branch ref for the
dependency key "`@beeper/desktop-api`" in package.json so installs are
reproducible: change the value currently using "`#next`" to the immutable commit
SHA "550009b71f922f605d4ca0e0059bbed6627e5fbe" (e.g.
"github:beeper/desktop-api#550009b71f922f605d4ca0e0059bbed6627e5fbe") or to a
published semver release; update the package.json entry for
"`@beeper/desktop-api`" and run a fresh install to verify lockfile changes.

@batuhan
Copy link
Copy Markdown
Member Author

batuhan commented May 21, 2026

@indent review

@indent
Copy link
Copy Markdown

indent Bot commented May 21, 2026

PR Summary

Replaces the npm beeper-cli package's "download a Bun-compiled binary" launcher with a Node-runnable distribution: the build copies packages/cli/dist/ plus bin/logo.js into the npm package, mirrors the oclif config and runtime dependencies, writes a thin Node ESM launcher that just calls @oclif/core execute(), and minifies every emitted .js with terser. To keep the only Bun-only feature usable, accounts add --webview now re-execs under an installed beeper binary on PATH or under bun (guarded against loops via BEEPER_CLI_WEBVIEW_REEXEC=1).

  • packages/npm/package.json: mirrors packages/cli dependencies and full oclif block (topics, plugins, jit plugins, warn-if-update-available); ships dist/ in files; drops binaries.json; adds terser devDep.
  • packages/npm/scripts/build.ts: stops generating a binaries manifest and instead copies packages/cli/dist + bin/logo.js, writes a Node bin/beeper.js launcher (prints logo when no args unless BEEPER_NO_LOGO=1, then await execute({ dir: packageRoot })), and runs terser per-file with module: true, mangle: true, compress: true, ecma: 2022, preserving shebangs and /*! ... */ comments.
  • packages/cli/src/commands/accounts/add.ts: adds reexecWithBunForWebViewIfNeeded() invoked when --webview is set — short-circuits if globalThis.Bun is present, otherwise searches PATH for beeper/beeper.exe (deduped by realpath) and re-execs it, or falls back to bun <entrypoint>, or throws guidance to install Bun / use --cookie.
  • Updates bun.lock for the new terser and mirrored deps, and bumps @beeper/desktop-api pin.

Issues

5 potential issues found:

  • Webview re-exec can pick a non-Bun beeper from PATH and surface a misleading "Bun runtime does not expose Bun.WebView" error: findInstalledBeeperBinary only dedupes by realpath, so any other Node-based beeper shim earlier on PATH gets spawned with BEEPER_CLI_WEBVIEW_REEXEC=1, which then makes the child throw blaming Bun even though no Bun was involved. → Autofix
  • packages/npm/package.json now hand-mirrors the entire dependencies block and oclif config from packages/cli/package.json, but nothing enforces parity. Future cli dependency upgrades that aren't echoed into the npm wrapper will silently ship broken Node-runtime installs (missing modules, version skew with @oclif/core plugins, etc.). → Autofix
  • packages/npm's test script is still just bun run build, so CI never invokes the built launcher. A terser regression (e.g. losing the commands export, breaking @oclif/core execute, broken import.meta handling) would only be discovered after publish. Add at least one smoke invocation like node bin/beeper.js --version to the test script. → Autofix
  • Build copies packages/cli/dist wholesale, so the published npm tarball ships ~138 .d.ts / .d.ts.map files (~900KB of dead weight) that no consumer of beeper-cli will ever import. Filter to *.js (and any other runtime-needed assets) in the cp step or strip declarations after copy. → Autofix
  • clean no longer removes the legacy binaries.json, and packages/npm/.gitignore still lists /binaries.json. After this PR that file is never generated, but a contributor with a stale local copy from the previous launcher will keep seeing it — and the gitignore line is dead. Either drop the gitignore entry or extend clean to also rm -f binaries.json. → Autofix

CI Checks

Waiting for CI checks...


⚡ Autofix All Issues

@indent
Copy link
Copy Markdown

indent Bot commented May 21, 2026

Review posted in the banner. Summary of what I found after building the package locally and exercising node bin/beeper.js --version/--help/accounts add --help against the minified output:

Functional / latent

  • accounts add --webview re-exec picks any beeper on PATH by realpath only — if a different Node-based beeper shim is earlier on PATH it gets spawned with BEEPER_CLI_WEBVIEW_REEXEC=1, which then makes the child throw "this Bun runtime does not expose Bun.WebView" even though no Bun was involved.
  • packages/npm/package.json now hand-mirrors the full dependencies block and oclif config from packages/cli/package.json with nothing enforcing parity — any future cli dep bump that isn't echoed here will publish a broken npm install.
  • npm test is still just bun run build; the launcher itself is never invoked, so a terser/oclif regression won't surface until after publish.

Nits

  • dist/ ships ~138 .d.ts/.d.ts.map files (~900KB) that no consumer imports.
  • clean no longer touches the legacy binaries.json and packages/npm/.gitignore still lists it.
  • Build assumes packages/cli/dist is already built; a fresh-checkout bun --cwd packages/npm run build hard-throws ENOENT instead of a clear error.

Build + minified launcher both work end-to-end on my sandbox (oclif command discovery, help, version), and the BEEPER_CLI_WEBVIEW_REEXEC loop guard correctly prevents infinite recursion.

const entrypoint = process.argv[1]
if (!entrypoint) throw new Error('Account web views require Bun. Install Bun and retry, or provide cookies manually with --cookie.')

const binary = findInstalledBeeperBinary(entrypoint)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Latent: re-exec into a non-Bun beeper produces a confusing error. findInstalledBeeperBinary only filters by realpath, so any other Node-based beeper earlier on PATH (e.g. a second node_modules/.bin/beeper from a sibling project, or a future Node-only build) is treated as a valid Bun target. We then spawn it with BEEPER_CLI_WEBVIEW_REEXEC=1; the child re-enters this function, hits the process.env.BEEPER_CLI_WEBVIEW_REEXEC === '1' guard at line 93, and throws Account web views are unavailable because this Bun runtime does not expose Bun.WebView. — even though no Bun runtime was ever invoked.

Consider verifying the candidate is actually a Bun-compiled binary before re-execing (e.g. probe it for globalThis.Bun), or rewording the guard error to say "Re-exec did not land in a Bun runtime" so it's not misattributed to a missing WebView module.

Comment thread packages/npm/package.json
"@oclif/plugin-plugins": "^5.4.67",
"@oclif/plugin-warn-if-update-available": "^3.1.49",
"figures": "^6.1.0",
"ink": "^7.0.3",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maintenance: dependency block is now hand-duplicated from packages/cli/package.json. Every entry here — @oclif/core, @oclif/plugin-*, ink, react, qrcode, ws, @beeper/desktop-api, @beeper/cli-plugin-cloudflare, etc. — must stay in sync with packages/cli/package.json. Nothing currently enforces that. When someone later bumps @oclif/core in the cli but not here, the npm package will publish with mismatched versions (or missing modules) and break at runtime in users' shells.

Consider adding a CI check that diffs the two dependencies blocks (and the oclif plugins/jitPlugins arrays which are also duplicated), or generating this block from packages/cli/package.json at build time.

Comment thread packages/npm/package.json
"scripts": {
"build": "bun scripts/build.ts",
"clean": "rm -rf bin binaries.json README.md LICENSE",
"clean": "rm -rf bin dist README.md LICENSE",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI gap: test doesn't exercise the published artifact. bun run build only produces the bundle; it never runs node bin/beeper.js against it. With terser doing aggressive mangle + compress + module: true minification per file, a future change to terser options, an oclif version bump, or a new top-level import.meta/await usage in dist/**/*.js could break the published launcher silently.

Consider extending this to something like:

"test": "bun run build && BEEPER_NO_LOGO=1 node bin/beeper.js --version && BEEPER_NO_LOGO=1 node bin/beeper.js --help > /dev/null"

so CI smoke-runs the artifact before it ships to npm.

await cp(join(cliRoot, 'README.md'), join(root, 'README.md'))
await cp(join(cliRoot, 'LICENSE'), join(root, 'LICENSE'))
await writeFile(join(root, 'binaries.json'), `${JSON.stringify(binaries, null, 2)}\n`)
await cp(join(cliRoot, 'dist'), join(root, 'dist'), { recursive: true })
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: tarball bloat. This copies the entire cli dist verbatim, which means the published beeper-cli package ships all of tsc's .d.ts and .d.ts.map files — 138 of them, ~900KB — even though packages/npm isn't a library and nothing imports those types. Either filter to *.js/*.json in this cp, or follow up with a sweep that removes **/*.d.ts and **/*.d.ts.map from packages/npm/dist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant