Skip to content

Packaging and README release blockers (BLK-17, API-49, B-3..B-5, R-1..R-4) - #67

Merged
krassx merged 5 commits into
mainfrom
fix/packaging-and-readme
Oct 9, 2026
Merged

krassx merged 5 commits into
mainfrom
fix/packaging-and-readme

Conversation

@krassx

@krassx krassx commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Fixes the packaging and documentation blockers the campaign's build lane found (campaign-prep-build.md, section 3). Each fix has a test that failed first.

What changes

Item Fix Test (red before)
BLK-17 native-versions.json missing from both tarballs: pod install and Gradle configuration failed for every npm install prepack stages the repo-root file at each package root (scripts/pack-native-versions.ts), postpack removes it; files ships it; both podspecs read the package copy first (repo-root fallback), the Gradle walk-up finds it scripts/pack/__tests__/pack-contents.test.ts; scripts/check-pack-install.sh on origin/main: Gradle native-versions.json not found above …/node_modules/@bugsee/react-native/android, pod install Invalid BugseeReactNative.podspec … native-versions.json
API-49 consumer tsc failed on 0.87 CodegenTypes from the react-native root instead of the deep Libraries/Types/CodegenTypes path (core and feedback); RN version type widened for 0.87's numeric prerelease. Codegen schemas are byte-identical before/after on 0.81.6 and 0.87.1 (Android and iOS). tsconfig.base.json drops the react-native-legacy-deep-imports condition so a deep import fails our own typecheck (the example app keeps it) check-pack-install.sh 0.87 --typecheck: 5 errors before (incl. the feedback package's deep import, not in the original finding), clean on 0.81–0.87 after
B-3 yarn pack dropped plugin/build files: plugin/build/**. Root cause is not .gitignore: Yarn 4 rejects every file under a nested directory entry such as plugin/build (the parent plugin/ is outside files, and its reject-all is inherited) pack-contents test packs with npm and yarn and asserts identical file lists
B-4 fixed /tmp download path in both prepare_commands mktemp -d under TMPDIR for the download, staging dir beside the destination, rename into place, trap cleanup podspec-prepare.test.ts runs the real heredocs twice concurrently with a stub curl that refuses a shared path
B-5 tests in the tarball excluded __tests__, __mocks__, src/testSupport, android/src/test. ios/Support/Tests stays: SwiftPM refuses the Support manifest without its test target's sources (verified: "overlapping sources") pack-contents test
R-1 options.serialize() BugseeLaunchOptions.serialize(options) consumer typecheck compiles the README "Use" block verbatim (red before) + package-metadata test
R-2/R-3 README "Release symbolication": Bugsee Gradle plugin (settings/root/app, NDK module + debugSymbolLevel, bugsee.properties) and the iOS bundle phase through bugsee-xcode.sh; the Expo plugin does both package-metadata test: Gradle plugin pin in the README equals native-versions.json
R-4 pnpm 11 ERR_PNPM_IGNORED_BUILDS README: decide allowBuilds['@bugsee/cli']; false is enough (verified with pnpm 11.3.0: install succeeds and the binary resolves from the platform optional dependency). The wrapper cannot avoid the decision while @bugsee/cli keeps its postinstall —
W-3 README troubleshooting: fmt 11.0.2 as C++17 on RN 0.81/0.82 with Xcode 26.4+ (fmtlib/fmt#4740) —

CI

  • pack install (<minor>[, android]): scripts/check-pack-install.sh packs both packages with npm pack, react-native inits a fresh app, installs the tarballs, runs the template's tsc over every public export and both README "Use" blocks (0.81–0.87), and Gradle configuration with both modules autolinked (0.81, 0.87).
  • pack install (<minor>, ios): pod install from the tarballs, both pods in the lockfile, the xcframework vendored at the pinned version (0.81, 0.87).
  • rn compat now covers every minor 0.81–0.87.

Device proof (WOD_LX1 and simulator launches from apps built from these tarballs, without the W-1 workaround) is in the plan directory's pack-fix-report.md.

🤖 Generated with Claude Code

krassx added 2 commits October 7, 2026 13:50
….R-4)

- Ship native-versions.json in both tarballs: prepack stages the repo-root
  file at each package root (scripts/pack-native-versions.ts), postpack
  removes it; the podspecs read that copy first and the Gradle walk-up
  finds it. Without it pod install and Gradle configuration failed in
  every app installed from npm (BLK-17).
- files: `plugin/build/**` instead of `plugin/build`. Yarn 4 drops the
  files under a nested directory entry, so `yarn pack` shipped
  app.plugin.js without the compiled plugin it requires (B-3).
- Exclude __tests__, __mocks__, testSupport and android/src/test from
  the tarballs (B-5). ios/Support/Tests stays: SwiftPM refuses the
  Support manifest without its declared test target's sources.
- podspec prepare_command: download into a mktemp directory under
  TMPDIR, unpack into a staging directory beside the destination and
  rename into place, instead of a fixed /tmp path that concurrent pod
  installs shared (B-4).
- Codegen types from the react-native root (`CodegenTypes.*`) instead of
  the deep Libraries/Types/CodegenTypes path, which 0.87 types only
  behind an opt-in condition; widen the RN version type for 0.87's
  numeric prerelease. Consumer tsc on 0.87 failed (API-49). Codegen
  schemas are byte-identical on 0.81 and 0.87. The library tsconfig
  drops the deep-import condition so a regression fails our typecheck.
- README: static BugseeLaunchOptions.serialize; Release symbolication
  steps for bare apps (Bugsee Gradle plugin with NDK symbols, iOS bundle
  phase through bugsee-xcode.sh); pnpm 10+/11 allowBuilds for
  @bugsee/cli; fmt C++17 troubleshooting for RN 0.81/0.82 + Xcode 26.4.
- CI: scripts/check-pack-install.sh installs the packed tarballs into a
  fresh `react-native init` app: consumer tsc (template tsconfig) on
  0.81-0.87, Gradle configuration on 0.81/0.87, pod install on
  0.81/0.87. rn compat matrix widened to every minor.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
… asserted)

Stryker (scripts config, --mutate scripts/pack-native-versions.ts): 88.46 -> 96.00.
The one survivor, 'utf8' -> '' on the read used only to validate the JSON,
is equivalent: JSON.parse accepts the Buffer.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale comment

Deep review (f7d5176)

Reviewed against the campaign blockers this PR claims to close (BLK-17, API-49, B-3–B-5, R-1–R-4), not the diff in isolation. Callers checked: both podspecs, both Android build.gradle walk-ups, Expo baked pins, RN codegen parser (getTypeAnnotationName on TSQualifiedName), consumer tsc via the init template tsconfig (include: **/*.ts), prepack/postpack lifecycle, and the new pack/podspec tests.

No P0–P3 issues. Nothing here has a credible customer failure mode that the change doesn’t already cover with a test.

What was checked and held:

  • BLK-17. Staging native-versions.json at each package root is the right shape: in an app, Gradle walks up from android/ and the podspec reads __dir__ first; neither lookup can see the repo root. unstage is guarded by @bugsee/ package name so it cannot delete the repo-root file. Pack-contents asserts the file is in both npm and yarn tarballs and gone from the working tree afterwards.
  • API-49. import type { CodegenTypes } from 'react-native' is the supported namespaced form from 0.80. Codegen does not care about the import path; it takes the right-hand name of CodegenTypes.EventEmitter. RN 0.87 public types re-export that namespace. check-rn-compat.sh still generates Android/iOS specs and the Java-signature gate would fail if emitters dropped out.
  • B-3 / B-5. Yarn 4’s nested-directory files bug is the real root cause; plugin/build/** plus explicit test-path negations, with npm/yarn listings required to be identical, is the right lock.
  • B-4. Moving the download into a per-run mktemp under TMPDIR and renaming from a sibling staging dir is an improvement over the old rm -rf before curl. Concurrent installs no longer share /tmp/Bugsee-<version>.zip. Failed curl leaves the previous artifact in place. The stub-curl test actually races two copies.
  • R-1. BugseeLaunchOptions.serialize is static; the README Use block matches, and check-pack-install.sh typechecks that block verbatim against the template tsc.

Residual (not a merge blocker): if npm pack is interrupted after prepack, the gitignored package-root copy can shadow the repo-root pins for a later local pod install / Gradle configure. Lookup order has to stay package-first for real npm installs, so this is an operational leftover, not something to invert. postpack, gitignore, and overwrite-on-next-stage are the mitigations.

CI pack install was still queued at review time; I did not treat a green run as a given.

Overall risk: Low

Merge recommendation: Approve

Most important issues to fix

None.

Positives

The tests failed on the actual customer path first (packed tarball into react-native init, not the workspace). Yarn vs npm pack file lists being asserted equal is what makes B-3 stay fixed. Preferring to delete the old xcframework only after a successful extract is the correct failure behaviour.

Open in Web View Automation 

Sent by Cursor Automation: Bugsee code review

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale comment

Deep code review — PR #67 (01739d3)

Packaging and install-path work for BLK-17 / B-3 / B-4 / B-5 looks correct, and CI already proved the iOS tarball path: pack install (0.81, ios) and pack install (0.87, ios) are green (podspecs resolve native-versions.json from the packed package, both pods lock, xcframework vendored).

The API-49 type change does not match what a 0.87 consumer actually typechecks against. That is the one issue that should block merge.

Findings

  1. P1 High — import type { CodegenTypes } is not exported from RN 0.87’s default (strict) typings. Consumer tsc on 0.87, and this repo’s own yarn typecheck against react-native@0.87.1, will fail with has no exported member 'CodegenTypes'. Same import in the feedback spec.

Overall risk: Medium

Runtime / CocoaPods / Gradle packaging is in good shape. The advertised 0.87 consumer-typecheck fix is inverted for the types 0.87 apps actually load.

Merge recommendation: Request changes

Do not merge until 0.87 default tsc accepts the specs (the new pack install (0.87, android) job is the right gate; it had not finished at review time).

Most important to fix

  • Native specs must typecheck on both 0.81’s export * as CodegenTypes and 0.87’s flattened export type * from CodegenTypesNamespace, without relying on react-native-legacy-deep-imports (the template does not set it).

Positives

  • Staging native-versions.json in prepack / removing it in postpack, with the podspec package-local-first lookup and Gradle walk-up, is the right BLK-17 shape; iOS pack-install already confirms it.
  • plugin/build/** plus npm+yarn pack assertions is a real Yarn 4 nested-files fix, not a guess.
  • prepare_command now downloads under a per-run mktemp, stages beside the destination, and leaves the old artifact in place until rename; the concurrent-stub-curl tests match the old /tmp CRC failure.
  • Test exclusions keep ios/Support/Tests for SwiftPM, which is the actual constraint.
Open in Web View Automation 

Sent by Cursor Automation: Bugsee code review

Comment thread packages/react-native/src/NativeBugsee.ts

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale comment

Deep review (01739d3, was f7d5176)

Re-reviewed the new commit (pack-native-versions: kill two mutants). Prior assessment at f7d5176 still holds: no P0–P3 on the packaging/README work. The follow-up does not introduce any.

01739d3. requireBugseePackage now uses existsSync instead of a try/catch that swallowed every read/parse failure. A missing package.json still becomes “not a @bugsee package” (the unstage-from-repo-root test exercises the false path). A present but invalid manifest now surfaces JSON.parse's SyntaxError instead of that same message — better for a corrupt package, and not a pack-path regression (npm has already parsed package.json before prepack). The invalid-pins test now asserts error.cause instanceof SyntaxError, which is what makes the { cause } wrapper observable.

No prior inline threads. Residual from last time unchanged: an interrupted pack can leave a gitignored package-root copy that shadows repo-root pins locally; lookup order must stay package-first for npm installs.

CI pack install is still queued (37596638245 on 01739d3), not treated as green.

Overall risk: Low

Merge recommendation: Approve

Most important issues to fix

None.

Open in Web View Automation 

Sent by Cursor Automation: Bugsee code review

krassx added 2 commits October 7, 2026 14:11
The view-tree guard grepped NativeDOM.h one line at a time. React Native
0.82 formats the alias over two lines (`using
MeasureInWindowOnSuccessCallback =` / `SyncCallback<...>`), so the guard
read it as a changed type and failed. 0.82 was not in the compat matrix
until this PR widened it to every minor. The check now runs over the
whole file; a header declaring AsyncCallback still fails it.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
…0.87)

single-source.test.ts asserts REACT_NATIVE_SUPPORT.matrix equals the
workflow's rn compat matrix, which this PR widened; the declaration had
not followed, failing the js job and the scripts mutation gate's dry run.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale comment

Deep review (bc275e7)

Re-reviewed the current head against the campaign blockers this PR claims to close (BLK-17, API-49, B-3–B-5, R-1–R-4), including the three follow-ups on f7d5176. Callers checked: both podspecs, both Android build.gradle walk-ups, Expo baked pins, RN codegen’s getTypeAnnotationName on TSQualifiedName, consumer tsc via the init-template tsconfig, prepack/postpack, pack/podspec tests, check-rn-compat.sh, and REACT_NATIVE_SUPPORT.matrix vs the workflow.

No P0–P3 issues. Nothing here has a credible customer failure mode that the change does not already cover.

API-49 (the prior P1 was wrong)

import type { CodegenTypes } from 'react-native' is the supported namespaced form from 0.80. RN 0.87’s default types condition is types_generated/index.d.ts, which does export type * from "./Libraries/Types/CodegenTypesNamespace". That file is import * as CodegenTypes from "./CodegenTypes"; export type { CodegenTypes }; — so the named type namespace is on the default typings, not only behind react-native-legacy-deep-imports (that condition still serves the deep Libraries/Types/CodegenTypes path this PR correctly left).

Checked, not inferred:

  • TypeScript module resolution of 'react-native' from a bundler/skipLibCheck tsconfig lands on types_generated/index.d.ts.
  • tsc --noEmit on CodegenTypes.EventEmitter / CodegenTypes.UnsafeObject / TurboModule exits 0 both with and without customConditions: ["react-native"].
  • CI pack install (0.87, android) on 01739d3 (run 37596638245) is SUCCESS: that job is the customer path (react-native init template tsconfig over the packed @bugsee/react-native sources, plus Gradle configuration). The same typecheck job is green for 0.81–0.86.

Codegen does not care about the import path; it takes the right-hand name of CodegenTypes.EventEmitter. check-rn-compat.sh still generates Android/iOS specs.

Packaging

  • BLK-17. Staging native-versions.json at each package root is the right shape: in an app, Gradle walks up from android/ and the podspec reads __dir__ first; neither lookup can see the repo root. unstage is guarded by @bugsee/ so it cannot delete the repo-root file. Pack-contents asserts the file is in both npm and yarn tarballs and gone from the working tree afterwards. Do not invert lookup order — package-first is load-bearing for npm installs.
  • B-3 / B-5. Yarn 4 drops files under a nested directory files entry; plugin/build/** plus explicit test-path negations, with npm/yarn listings required to be identical, is the right lock. SPM Support test sources stay because the manifest declares that target.
  • B-4. Per-run mktemp under TMPDIR and rename from a sibling staging dir. Concurrent installs no longer share /tmp/Bugsee-<version>.zip. Failed curl leaves the previous artifact in place.
  • R-1. BugseeLaunchOptions.serialize is static; the README Use block matches, and check-pack-install.sh typechecks that block verbatim.

Follow-up commits

  • 01739d3. requireBugseePackage uses existsSync then JSON.parse (mutant: swallow-parse). Missing package.json still maps to the @bugsee/ error; invalid JSON in that manifest now surfaces as SyntaxError instead of being treated as “not a Bugsee package”, which is correct for prepack. The pins-file parse still wraps cause; the test asserts error.cause instanceof SyntaxError.
  • d1b9ab0. 0.82 formats using MeasureInWindowOnSuccessCallback = / SyncCallback<…> across two lines. A whole-file /using\s+MeasureInWindowOnSuccessCallback\s*=\s*SyncCallback\s*</ matches that wrap and the one-line form on 0.83+. 0.81 has no alias (jsi::Function) and correctly takes the existing else branch. Confirmed against v0.82.1 and v0.81.0 headers.
  • bc275e7. single-source.test.ts requires REACT_NATIVE_SUPPORT.matrix to equal the first react-native: list in ci.yml (the compat job). Widening that job without the declaration failed the js job; the arrays now match ['0.81'..'0.87'].

Residual (not a merge blocker): if npm pack is interrupted after prepack, the gitignored package-root copy can shadow the repo-root pins for a later local pod install / Gradle configure. Lookup order has to stay package-first for real npm installs. postpack, gitignore, and overwrite-on-next-stage are the mitigations.

bc275e7 CI was still running at review time; pack-install on the packaging commit (01739d3) is already green. I did not treat the in-flight run as a given.

Overall risk: Low

Merge recommendation: Approve

Most important issues to fix

None.

Positives

The tests failed on the actual customer path first (packed tarball into react-native init, not the workspace). Yarn vs npm pack file lists being asserted equal is what makes B-3 stay fixed. Preferring to delete the old xcframework only after a successful extract is the correct failure behaviour. The 0.82 header check and the matrix declaration were the right response to the widened compat job, not drive-by edits.

Open in Web View Automation 

Sent by Cursor Automation: Bugsee code review

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale comment

Deep review — PR #67 (bc275e7)

Re-reviewed the full packaging/README change plus the three follow-ups (01739d3, d1b9ab0, bc275e7), against callers (both podspecs, both Android build.gradle walk-ups, Expo baked pins, prepack/postpack, pack/podspec tests, check-rn-compat.sh, REACT_NATIVE_SUPPORT.matrix).

No P0–P3 findings. Nothing here has a credible customer failure that the change does not already cover.

Prior P1 (CodegenTypes) — fully addressed / was incorrect

import type { CodegenTypes } from 'react-native' is a named export on RN 0.87’s default typings. The earlier read of export type * from CodegenTypesNamespace as “flattened, no namespace” missed the namespace file itself.

Verified against react-native@0.87.1:

  • exports["."].types → types_generated/index.d.ts
  • that file: export type * from "./Libraries/Types/CodegenTypesNamespace"
  • namespace file: import * as CodegenTypes from "./CodegenTypes"; export type { CodegenTypes };
  • 0.81 still has export * as CodegenTypes on types/index.d.ts, so the same import typechecks on the floor

CI already proved the customer path: pack install (0.87, android) on 01739d3 (run 37596638245) is SUCCESS — stock react-native init template tsc over the packed sources, plus Gradle configuration. Typecheck jobs for 0.81–0.86 on that run were also green. The author’s reply matches the type files.

Packaging (held)

  • BLK-17. Staging native-versions.json at each package root is the right shape. In an app, Gradle walks up from android/ and the podspec reads __dir__ first; neither lookup can see the repo root. unstage is gated on @bugsee/ so it cannot delete the repo-root file. Pack-contents asserts the file is in both npm and yarn tarballs and gone from the working tree afterwards. Do not invert lookup order — package-first is load-bearing for npm installs.
  • B-3 / B-5. Yarn 4 drops files under a nested directory files entry; plugin/build/** plus explicit test-path negations, with npm/yarn listings required to be identical, is the right lock. SPM Support test sources stay because the manifest declares that target.
  • B-4. Per-run mktemp under TMPDIR, extract into a sibling staging dir, rename into place. The heredoc already has set -e, so a failed curl/unzip exits before rm -rf of the previous artifact. Concurrent installs no longer share /tmp/Bugsee-<version>.zip.
  • R-1. BugseeLaunchOptions.serialize is static; the README Use block matches, and check-pack-install.sh typechecks that block verbatim from the packed README.

Follow-up commits on this head

  • 01739d3. requireBugseePackage uses existsSync then JSON.parse. Missing package.json is still “not a @bugsee package”; a present but invalid manifest now surfaces SyntaxError instead of that same message. The pins-file parse still wraps { cause }; the test asserts error.cause instanceof SyntaxError.
  • d1b9ab0. Needed: rn compat (0.82) failed on 01739d3 because 0.82 formats using MeasureInWindowOnSuccessCallback = / SyncCallback<…> across two lines. A whole-file /using\s+MeasureInWindowOnSuccessCallback\s*=\s*SyncCallback\s*</ matches that wrap and the one-line form. 0.81 has no alias (jsi::Function) and correctly takes the existing else branch.
  • bc275e7. single-source.test.ts requires REACT_NATIVE_SUPPORT.matrix to equal the first react-native: list in ci.yml (the compat job). Widening that job without the declaration failed the js job; the arrays now match ['0.81'..'0.87'].

Residual (not a merge blocker): if npm pack is interrupted after prepack, the gitignored package-root copy can shadow the repo-root pins for a later local pod install / Gradle configure. Lookup order has to stay package-first for real npm installs. postpack, gitignore, and overwrite-on-next-stage are the mitigations.

bc275e7 CI was still running at review time. Pack-install on the packaging commit (01739d3) is already green, including the 0.87 consumer typecheck that is API-49. I did not treat the in-flight run as a given.

Overall risk: Low

Merge recommendation: Approve

Most important issues to fix

None.

Positives

The tests failed on the actual customer path first (packed tarball into react-native init, not the workspace). Yarn vs npm pack file lists being asserted equal is what makes B-3 stay fixed. Deleting the old xcframework only after a successful extract is the correct failure behaviour. The 0.82 header check and the matrix declaration were the right response to the widened compat job.

Open in Web View Automation 

Sent by Cursor Automation: Bugsee code review

Both package READMEs state "Hermes is required; JavaScriptCore (Hermes
off) is not supported" with the reason: React Native removed JSC from core
in 0.81 and @react-native-community/javascriptcore does not work with
current React Native (Android JSC cannot parse RN's bundle; iOS fails on
0.86/0.87). The core README no longer describes the Hermes-off source-map
path as an option. The design doc records the decision in §4.5 and notes
that the wrapper still reports js-engine "jsc" when Hermes is off
(harmless reporting, left as is).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale comment

Deep review (9ae85ce)

Re-checked the CodegenTypes thread against the matrix in the latest comment, then reviewed the new docs commit.

No P0–P3. The prior P1 does not hold. 9ae85ce is documentation of an already-made support decision; it does not change runtime behavior.

CodegenTypes thread — finding does not hold (resolve it)

import type { CodegenTypes } from 'react-native' typechecks on RN 0.87.1 default typings. types_generated/index.d.ts re-exports export type { CodegenTypes } from CodegenTypesNamespace.d.ts via export type *. That is a named type namespace, not a flattened-only surface.

Your matrix matches what we already measured: bundler with customConditions: ["react-native"] (template default), bundler with no customConditions, bundler plus legacy, node16, and nodenext all resolve to types_generated except the legacy condition (which still has export * as CodegenTypes on types/index.d.ts). TS 5.9.3 and 6.0.3: 0 CodegenTypes errors. The two failing cells (TS 5.0.4 es2024.promise / @types/react 19.3 needing 5.6; node10 ignoring exports so RN 0.87 has no types) fail the same way on a stock App.tsx with no Bugsee import — they are not this package.

Independent gates on the same import: local tsc probe EXIT 0; CI pack install (0.87, android) SUCCESS (template tsc over packed sources); lint, typecheck, unit SUCCESS on bc275e7 after dropping the legacy condition from the library tsconfig. No spec change is required. Thread PRRT_kwDOTk5MSM6p1Rsh recorded fully_addressed.

9ae85ce (Hermes required / JSC unsupported)

Both READMEs and design §4.5 now state Hermes is required. The core README no longer presents the Hermes-off source-map path as an option. The design note that the wrapper still reports js-engine: jsc when Hermes is off is accurate (identity.ts still does facts.hermes ? 'hermes' : 'jsc') and correctly labeled unsupported leftover reporting, not a product path. Gradle’s Hermes-off inject remains in code for the same reason; that is not a README contradiction after this commit.

Overall risk: Low

Merge recommendation: Approve

Most important issues to fix

None.

Open in Web View Automation 

Sent by Cursor Automation: Bugsee code review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Deep review — PR #67 (9ae85ce)

Re-reviewed the packaging/README change plus follow-ups (01739d3, d1b9ab0, bc275e7, 9ae85ce), against callers (both podspecs, both Android build.gradle walk-ups, Expo baked pins, prepack/postpack, pack/podspec tests, check-rn-compat.sh, REACT_NATIVE_SUPPORT.matrix, source-map hook, wrapper identity).

No P0–P3 findings. Nothing here has a credible customer failure that the change does not already cover.

Prior P1 (CodegenTypes) — fully addressed / was incorrect

Re-checked against the matrix in the thread (fresh 0.87.1 react-native init, packed tarballs, template @react-native/typescript-config 0.87.1). import type { CodegenTypes } from 'react-native' is a named export on 0.87’s default typings.

  • 0.87 exports["."].types → types_generated/index.d.ts → export type * from CodegenTypesNamespace
  • namespace file: import * as CodegenTypes from "./CodegenTypes"; export type { CodegenTypes };
  • 0.81 still has export * as CodegenTypes on types/index.d.ts

The configurations that fail (TS 5.0.4 vs es2024.promise / @types/react 19.3; moduleResolution: node10 ignoring exports) fail a plain template App.tsx with no Bugsee import. They are not this package.

On this SHA: lint, typecheck, unit is SUCCESS, and rn compat (0.81–0.87) are all SUCCESS. pack install (0.87, android) on bc275e7 / 01739d3 already proved stock template tsc over the packed sources.

9ae85ce — Hermes required (docs only)

Support policy, not a runtime gate. Both package READMEs and design §4.5 now state Hermes is required and JavaScriptCore (Hermes off) is unsupported. Cross-checked against remaining code:

  • wrapperIdentity still reports js-engine: jsc when HermesInternal is absent
  • bugsee-sourcemaps.gradle still injects into Metro’s bundle/map when hermesEnabled is false
  • README no longer documents that Hermes-off path as an option

That matches the design note: left in place, not supported. Removing the README sentence does not change a Hermes (supported) build. No launch-time check was added; that is the stated decision, not an omission in this diff.

Packaging (held)

  • BLK-17. Staging native-versions.json at each package root is the right shape. In an app, Gradle walks up from android/ and the podspec reads __dir__ first; neither lookup can see the repo root. unstage is gated on @bugsee/ so it cannot delete the repo-root file. Do not invert lookup order — package-first is load-bearing for npm installs.
  • B-3 / B-5. Yarn 4 drops files under a nested directory files entry; plugin/build/** plus explicit test-path negations, with npm/yarn listings required to be identical, is the right lock. SPM Support test sources stay because the manifest declares that target.
  • B-4. Per-run mktemp under TMPDIR, extract into a sibling staging dir, rename into place. The heredoc already has set -e, so a failed curl/unzip exits before rm -rf of the previous artifact.
  • R-1. BugseeLaunchOptions.serialize is static; the README Use block matches, and check-pack-install.sh typechecks that block verbatim from the packed README.

Residual (not a merge blocker): if npm pack is interrupted after prepack, the gitignored package-root copy can shadow the repo-root pins for a later local pod install / Gradle configure. Lookup order has to stay package-first for real npm installs. postpack, gitignore, and overwrite-on-next-stage are the mitigations.

Follow-ups still held

  • 01739d3. existsSync then JSON.parse. Invalid package.json is now SyntaxError; pins-file parse still wraps { cause }.
  • d1b9ab0. Whole-file /using\s+MeasureInWindowOnSuccessCallback\s*=\s*SyncCallback\s*</ matches 0.82’s two-line alias and the one-line form. Confirmed: rn compat (0.82) is SUCCESS on this SHA (it failed on 01739d3).
  • bc275e7. REACT_NATIVE_SUPPORT.matrix matches the compat job (0.81–0.87).

CI on 9ae85ce (run 37603636714, not finished)

Already green: lint, typecheck, unit; rn compat (0.81–0.87); pack-install typecheck 0.81–0.86; pack install (0.81, android); pack install (0.87, ios); expo prebuild. pack install (0.87, android) was still running at review time; it is docs-only relative to bc275e7, where that job was SUCCESS. I did not treat the unfinished jobs as a given.

Overall risk: Low

Merge recommendation: Approve

Most important issues to fix

None.

Positives

The CodegenTypes reply is the right kind of evidence (stock template, both TS versions, every moduleResolution a consumer actually uses). The Hermes decision is written as a support floor rather than pretending the leftover reporting/hook paths were deleted. Packaging tests still fail on the customer path first (packed tarball into react-native init).

Open in Web View Automation 

Sent by Cursor Automation: Bugsee code review

@krassx
krassx merged commit 4a417b7 into main Oct 9, 2026
52 checks passed
@krassx
krassx deleted the fix/packaging-and-readme branch October 9, 2026 11:34
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.

1 participant