Skip to content

feat(node): add configure() for embedder setting defaults - #1053

Merged
jdx merged 2 commits into
mainfrom
feat/aube-node-configure
Jul 16, 2026
Merged

jdx merged 2 commits into
mainfrom
feat/aube-node-configure

Conversation

@jdx

@jdx jdx commented Jul 16, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • add configure({ defaults }) to @jdxcode/aube-node so embedding hosts can register setting defaults (e.g. minimumReleaseAge) programmatically — previously the addon hardcoded minimumReleaseAge=0 with no override short of env vars or per-project .npmrc
  • validate default names against canonical settings; unknown names reject with new stable code ERR_AUBE_EMBED_INVALID_SETTING
  • reject configure-after-install (or repeated configure) with new stable code ERR_AUBE_EMBED_ALREADY_INITIALIZED — registration is process-global and first-write-wins, so silent non-application would be a policy hazard
  • expose osvTransitiveCheck on InstallInput, matching the C ABI's install options
  • npm surface: configure re-export, .d.ts types, typecheck fixture, README + docs

Motivation

opencode's aube adoption (anomalyco/opencode#37301) promises supply-chain policy on runtime installs — a cooldown matching its bunfig minimumReleaseAge. The C ABI already supports this via aube_init host-profile defaults; the Node-API addon had no equivalent.

Validation

  • cargo test --locked -p aube-node (new unit tests for default merging and name validation)
  • cargo clippy --all-targets, cargo fmt
  • docs/error-codes.data.json regenerated
  • CI's npm smoke/typecheck covers the new export

This PR was written by an AI coding assistant (Claude Code), directed by @jdx.


Note

Medium Risk
Process-global embedder init and supply-chain settings (minimumReleaseAge, osvTransitiveCheck) affect install behavior for all subsequent installs in the host; mis-ordered configure vs install is fail-closed but hosts must adopt the new API correctly.

Overview
Adds configure({ defaults }) to @jdxcode/aube-node so hosts can register embedder setting defaults (e.g. minimumReleaseAge) before the first install, paralleling C ABI aube_init host-profile defaults. Defaults merge with built-ins (nodeLinker=hoisted, minimumReleaseAge=0), validate names via aube_settings::find, and register once per process through EMBEDDER_INIT so configure and the first install race safely.

Late or duplicate configure throws ERR_AUBE_EMBED_ALREADY_INITIALIZED; unknown keys throw ERR_AUBE_EMBED_INVALID_SETTING (new stable codes in aube-codes and docs/error-codes.data.json). osvTransitiveCheck is wired through InstallInput into both embed::add and embed::install.

The npm layer re-exports configure, updates .d.ts, README, embedding docs, and typecheck fixture; aube-node gains aube-settings and unit tests for default merge/validation.

Reviewed by Cursor Bugbot for commit 45ecae4. Bugbot is set up for automated code reviews on this repo. Configure here.

Expose embedder setting defaults through the Node-API addon so hosts
can set policy (e.g. minimumReleaseAge) programmatically instead of
relying on env vars or per-project npmrc files. The addon previously
hardcoded minimumReleaseAge=0 with no override. Also expose
osvTransitiveCheck per install, matching the C ABI options.

configure() must run before the first install: registration is
process-global and first-write-wins, so late or repeated calls reject
with the new stable code ERR_AUBE_EMBED_ALREADY_INITIALIZED, and
unknown setting names reject with ERR_AUBE_EMBED_INVALID_SETTING
instead of silently not applying.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 16, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

@jdx, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 26 seconds

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 8eae6d18-6b6f-4a61-94b2-b12a1365fb05

📥 Commits

Reviewing files that changed from the base of the PR and between fe94473 and 45ecae4.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • crates/aube-codes/src/errors.rs
  • crates/aube-node/Cargo.toml
  • crates/aube-node/README.md
  • crates/aube-node/npm/index.d.ts
  • crates/aube-node/npm/index.js
  • crates/aube-node/npm/typecheck.ts
  • crates/aube-node/src/lib.rs
  • docs/embedding/node.md
  • docs/error-codes.data.json

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b17dd18. Configure here.

Comment thread crates/aube-node/src/lib.rs Resolved
@greptile-apps

greptile-apps Bot commented Jul 16, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds configure({ defaults }) to @jdxcode/aube-node so embedding hosts can register setting defaults (e.g. minimumReleaseAge) before the first install, backed by OnceLock-based process-global first-write-wins initialization. Also threads osvTransitiveCheck from the install input through to embed::add / embed::install, replacing the previously hardcoded false.

  • configure() is a synchronous NAPI function guarded by EMBEDDER_INIT: OnceLock<()>; calling after initialization or with an unknown setting name raises new stable error codes ERR_AUBE_EMBED_ALREADY_INITIALIZED / ERR_AUBE_EMBED_INVALID_SETTING.
  • Both README.md and docs/embedding/node.md describe the errors with "rejects" \u2014 the promise-rejection term \u2014 while configure is synchronous and throws; the .d.ts JSDoc correctly uses "throw".
  • New unit tests cover default merging, override precedence, and setting-name validation.

Confidence Score: 4/5

Safe to merge after fixing the "rejects" wording in README and docs — the Rust implementation is correct but the prose documentation will mislead JS callers into using .catch() on a synchronous function.

The core Rust logic is sound: OnceLock correctly serializes concurrent configure/install races, merged_defaults properly handles override precedence, and osvTransitiveCheck is wired through both code paths. The only concrete defect is in the documentation — both README.md and docs/embedding/node.md use "rejects" for a synchronous function that throws, which is the wrong error-handling pattern for JS callers reading the prose docs.

crates/aube-node/README.md and docs/embedding/node.md both need the "rejects" → "throws" fix.

Important Files Changed

Filename Overview
crates/aube-node/src/lib.rs Adds configure() with OnceLock-based first-write-wins initialization; osvTransitiveCheck threaded through to embed::add/install; unit tests cover merge and validation logic.
crates/aube-codes/src/errors.rs Adds two new stable error codes ERR_AUBE_EMBED_INVALID_SETTING and ERR_AUBE_EMBED_ALREADY_INITIALIZED with correct category and description.
crates/aube-node/npm/index.d.ts ConfigureInput type and configure() export added; osvTransitiveCheck added to InstallInput; JSDoc correctly uses "throw" for the synchronous configure function.
crates/aube-node/README.md Documents the new configure() API but incorrectly uses "rejects" for a synchronous function that throws; identical error in docs/embedding/node.md.
docs/embedding/node.md Configuration section added, mirrors README error — uses "rejects" for configure(), which is synchronous and throws.
crates/aube-node/npm/index.js Exports configure from the native addon alongside the existing install export; straightforward one-line addition.
crates/aube-node/npm/typecheck.ts Typecheck fixture exercises configure({ defaults }) and osvTransitiveCheck; validates both new API surfaces compile correctly.

Reviews (2): Last reviewed commit: "fix(node): serialize embedder registrati..." | Re-trigger Greptile

Comment thread crates/aube-node/src/lib.rs Resolved
Review feedback: the AtomicBool flag let a concurrent install proceed
before configure's embed::initialize completed (running under the
standalone profile), and a typo'd setting name after initialization
returned ERR_AUBE_EMBED_INVALID_SETTING where the documented contract
promises ERR_AUBE_EMBED_ALREADY_INITIALIZED. OnceLock::get_or_init
blocks racers until registration completes and records who won;
configure fast-paths the already-initialized check before validation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jdx

jdx commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator Author

Both findings addressed in the follow-up commit:

  • Init race (Bugbot): EMBEDDER_INIT is now a OnceLock — get_or_init makes a concurrent install block until configure's embed::initialize completes instead of skipping past a half-done registration, and records which caller performed it.
  • Error-code precedence (Greptile): configure fast-paths the already-initialized check before validating names, so configure-after-install always returns ERR_AUBE_EMBED_ALREADY_INITIALIZED regardless of typos, with the get_or_init result covering the TOCTOU window.

This comment was generated by an AI coding assistant.

@jdx
jdx enabled auto-merge (squash) July 16, 2026 15:19
@jdx
jdx merged commit 6c61295 into main Jul 16, 2026
37 checks passed
@jdx
jdx deleted the feat/aube-node-configure branch July 16, 2026 15:23
@cursor cursor Bot mentioned this pull request Jul 16, 2026
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