Skip to content

Scaffold and organize JavaScript workspace packages#109

Open
omarluq wants to merge 8 commits intomainfrom
add-boilerplate-js-libs
Open

Scaffold and organize JavaScript workspace packages#109
omarluq wants to merge 8 commits intomainfrom
add-boilerplate-js-libs

Conversation

@omarluq
Copy link
Copy Markdown
Owner

@omarluq omarluq commented Feb 28, 2026

Summary

  • scaffolded the multi-package JavaScript workspace structure
  • grouped framework adapters under javascript/framework/*
  • grouped starters under javascript/starter/*
  • grouped native targets under javascript/native/{platform}/{arch}/{libc?}
  • removed TanStack adapter/starter from the plan and workspace
  • updated workspace globs, TS path mappings, and lockfile

Validation

  • bun install
  • bun run js:typecheck
  • bun run --cwd javascript/create-tui typecheck
  • starter package typechecks (next, nuxt, sveltekit)

@netlify
Copy link
Copy Markdown

netlify bot commented Feb 28, 2026

Deploy Preview for termisu canceled.

Name Link
🔨 Latest commit 43ef846
🔍 Latest deploy log https://app.netlify.com/projects/termisu/deploys/69d2e473adab8d0008ce6a21

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 28, 2026

📝 Walkthrough

Summary by CodeRabbit

  • Documentation

    • Added comprehensive architecture guides covering core system design and JavaScript-to-native library integration patterns.
  • New Features

    • Enabled native library resolution for cross-platform support: Linux (x64/ARM64 with GNU and musl), macOS (x64/ARM64), and FreeBSD (x64/ARM64).
    • Introduced modular workspace structure organizing platform-specific native library packages.

Walkthrough

Added architecture documentation defining Termisu's Crystal core and JS runtime FFI integration, introduced JavaScript workspace structure documentation, scaffolded native package manifests for supported Linux/macOS/FreeBSD targets, and implemented platform detection and native library resolution logic in the JS core.

Changes

Cohort / File(s) Summary
Architecture Documentation
architecture/README.md, architecture/core-architecture.md, architecture/js-runtime-ffi-architecture.md
Establishes implementation-backed architecture documentation covering Crystal core components, event/rendering pipelines, platform-specific pollers, FFI boundary semantics, and JS runtime integration strategy.
JavaScript Workspace Documentation
javascript/README.md
Introduces JS workspace structure, defines @termisu/core as the sole user-facing package, documents supported native targets (Linux GNU/musl, macOS, FreeBSD on x64/arm64), and lists development commands.
Native Platform Scaffolds
javascript/native/*/README.md, javascript/native/*/manifest.json, javascript/native/*/package.json
Creates npm package scaffolds for eight native targets (darwin arm64/x64, freebsd arm64/x64, linux arm64/x64 with gnu/musl variants), each declaring target metadata, library artifact names, and distribution constraints.
Platform Detection & Resolution
javascript/core/src/platform.ts, javascript/core/src/native.ts, javascript/core/tests/native.test.ts
Adds detectTarget() for runtime platform/libc detection (musl vs glibc check on Linux), exports nativePackageByTarget mapping, updates resolveLibraryPath() to consult native package manifests, and adds test coverage for resolution fallback chains.
Configuration & Dependency Updates
package.json, tsconfig.base.json, javascript/core/package.json, javascript/core/tsconfig.json, javascript/platform/.gitignore
Expands monorepo workspace patterns to include native package dirs, adds @termisu/* TypeScript path alias, declares optional native package dependencies in @termisu/core, sets compiler root directory, and excludes dist from version control.

Possibly related PRs

  • PR #100: Extends the JS FFI/native-loader surface introduced in that PR by adding platform detection and native package resolution logic in javascript/core/src/platform.ts and javascript/core/src/native.ts.
  • PR #107: Modifies the same JavaScript workspace layout and configuration files (package.json workspaces and javascript/core/tsconfig.json), coordinating package structure changes.
  • PR #103: Aligns on repository JS workspace and TypeScript base configuration updates (tsconfig.base.json path aliases and monorepo workspace patterns).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes


🐰 Hop, hop, hooray! The native scaffold's in place,
With targets for Darwin, BSD, and Linux's embrace,
Platform detection hops platform to platform,
While manifests guide each library transform,
Architecture documents blooming—a hop-tastic performance! 🌿✨

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely summarizes the main change: scaffolding and organizing the JavaScript workspace with a multi-package structure.
Description check ✅ Passed The PR description provides relevant details about the changes, including the workspace structure organization, removed items, and validation steps performed.

✏️ 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 add-boilerplate-js-libs

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

@omarluq omarluq force-pushed the add-boilerplate-js-libs branch 2 times, most recently from dd4a33b to ecb57d9 Compare March 8, 2026 06:46
@omarluq omarluq force-pushed the add-boilerplate-js-libs branch from ecb57d9 to f87cdb2 Compare March 15, 2026 00:48
@omarluq omarluq marked this pull request as ready for review March 15, 2026 00:48
Copilot AI review requested due to automatic review settings March 15, 2026 00:48
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Scaffolds a multi-package JavaScript workspace for Termisu, reorganizing adapters/starters/native targets into a consistent package topology and updating workspace + TS configuration to support it.

Changes:

  • Expanded Bun workspaces to include framework adapters, starters, and native target packages.
  • Added scaffolding packages for @termisu/runtime, @termisu/reconciler, @termisu/platform, framework adapters, starters, and native target manifests.
  • Added architecture documentation describing the intended JS runtime + FFI package topology.

Reviewed changes

Copilot reviewed 86 out of 88 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
tsconfig.base.json Adds TS baseUrl + paths mappings for workspace imports.
package.json Updates workspace globs to include newly scaffolded packages.
javascript/starter/sveltekit/tsconfig.json Adds TS config for sveltekit starter package.
javascript/starter/sveltekit/src/index.ts Adds starter scaffold export.
javascript/starter/sveltekit/package.json Adds starter package manifest + scripts.
javascript/starter/sveltekit/README.md Adds starter README.
javascript/starter/sveltekit/.gitignore Ignores build output.
javascript/starter/nuxt/tsconfig.json Adds TS config for nuxt starter package.
javascript/starter/nuxt/src/index.ts Adds starter scaffold export.
javascript/starter/nuxt/package.json Adds starter package manifest + scripts.
javascript/starter/nuxt/README.md Adds starter README.
javascript/starter/nuxt/.gitignore Ignores build output.
javascript/starter/next/tsconfig.json Adds TS config for next starter package.
javascript/starter/next/src/index.ts Adds starter scaffold export.
javascript/starter/next/package.json Adds starter package manifest + scripts.
javascript/starter/next/README.md Adds starter README.
javascript/starter/next/.gitignore Ignores build output.
javascript/runtime/tsconfig.json Adds TS config for runtime package.
javascript/runtime/src/index.ts Adds runtime scaffold API surface.
javascript/runtime/package.json Adds runtime package manifest + scripts.
javascript/runtime/README.md Adds runtime README.
javascript/runtime/.gitignore Ignores build output.
javascript/reconciler/tsconfig.json Adds TS config for reconciler package.
javascript/reconciler/src/index.ts Adds reconciler scaffold API surface.
javascript/reconciler/package.json Adds reconciler package manifest + scripts.
javascript/reconciler/README.md Adds reconciler README.
javascript/reconciler/.gitignore Ignores build output.
javascript/platform/tsconfig.json Adds TS config for platform resolver package.
javascript/platform/src/index.ts Adds target detection + native package mapping.
javascript/platform/package.json Adds platform package manifest + optional native deps.
javascript/platform/README.md Adds platform README.
javascript/platform/.gitignore Ignores build output.
javascript/native/linux/x64/musl/package.json Adds linux x64 musl native target package scaffold.
javascript/native/linux/x64/musl/manifest.json Adds linux x64 musl target metadata.
javascript/native/linux/x64/musl/README.md Adds native target README.
javascript/native/linux/x64/gnu/package.json Adds linux x64 glibc native target package scaffold.
javascript/native/linux/x64/gnu/manifest.json Adds linux x64 glibc target metadata.
javascript/native/linux/x64/gnu/README.md Adds native target README.
javascript/native/linux/arm64/musl/package.json Adds linux arm64 musl native target package scaffold.
javascript/native/linux/arm64/musl/manifest.json Adds linux arm64 musl target metadata.
javascript/native/linux/arm64/musl/README.md Adds native target README.
javascript/native/linux/arm64/gnu/package.json Adds linux arm64 glibc native target package scaffold.
javascript/native/linux/arm64/gnu/manifest.json Adds linux arm64 glibc target metadata.
javascript/native/linux/arm64/gnu/README.md Adds native target README.
javascript/native/freebsd/x64/package.json Adds freebsd x64 native target package scaffold.
javascript/native/freebsd/x64/manifest.json Adds freebsd x64 target metadata.
javascript/native/freebsd/x64/README.md Adds native target README.
javascript/native/freebsd/arm64/package.json Adds freebsd arm64 native target package scaffold.
javascript/native/freebsd/arm64/manifest.json Adds freebsd arm64 target metadata.
javascript/native/freebsd/arm64/README.md Adds native target README.
javascript/native/darwin/x64/package.json Adds darwin x64 native target package scaffold.
javascript/native/darwin/x64/manifest.json Adds darwin x64 target metadata.
javascript/native/darwin/x64/README.md Adds native target README.
javascript/native/darwin/arm64/package.json Adds darwin arm64 native target package scaffold.
javascript/native/darwin/arm64/manifest.json Adds darwin arm64 target metadata.
javascript/native/darwin/arm64/README.md Adds native target README.
javascript/framework/vue/tsconfig.json Adds TS config for Vue adapter package.
javascript/framework/vue/src/index.ts Adds Vue adapter scaffold export.
javascript/framework/vue/package.json Adds Vue adapter package manifest + scripts.
javascript/framework/vue/README.md Adds adapter README.
javascript/framework/vue/.gitignore Ignores build output.
javascript/framework/svelte/tsconfig.json Adds TS config for Svelte adapter package.
javascript/framework/svelte/src/index.ts Adds Svelte adapter scaffold export.
javascript/framework/svelte/package.json Adds Svelte adapter package manifest + scripts.
javascript/framework/svelte/README.md Adds adapter README.
javascript/framework/svelte/.gitignore Ignores build output.
javascript/framework/solid/tsconfig.json Adds TS config for Solid adapter package.
javascript/framework/solid/src/index.ts Adds Solid adapter scaffold export.
javascript/framework/solid/package.json Adds Solid adapter package manifest + scripts.
javascript/framework/solid/README.md Adds adapter README.
javascript/framework/solid/.gitignore Ignores build output.
javascript/framework/react/tsconfig.json Adds TS config for React adapter package.
javascript/framework/react/src/index.ts Adds React adapter scaffold export.
javascript/framework/react/package.json Adds React adapter package manifest + scripts.
javascript/framework/react/README.md Adds adapter README.
javascript/framework/react/.gitignore Ignores build output.
javascript/create-tui/tsconfig.json Adds TS config for scaffolder CLI package.
javascript/create-tui/src/index.ts Adds starter ID list scaffold.
javascript/create-tui/src/cli.ts Adds CLI entrypoint scaffold + starter listing.
javascript/create-tui/package.json Adds CLI package manifest with bin entry.
javascript/create-tui/README.md Adds CLI README.
javascript/create-tui/.gitignore Ignores build output.
javascript/README.md Documents JS workspace packages and paths.
bun.lock Updates lockfile for new workspace topology/packages.
architecture/js-runtime-ffi-architecture.md Adds JS runtime + FFI architecture plan and package topology.
architecture/core-architecture.md Adds Crystal core architecture documentation.
architecture/README.md Adds index for architecture docs.
.gitignore Ignores nested javascript/**/node_modules.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.base.json",
Comment on lines +11 to +22
export const detectTarget = (): PlatformTarget | null => {
const platform = process.platform;
const arch = process.arch;

if (platform === "linux" && arch === "x64") return "linux-x64-gnu";
if (platform === "linux" && arch === "arm64") return "linux-arm64-gnu";
if (platform === "darwin" && arch === "x64") return "darwin-x64";
if (platform === "darwin" && arch === "arm64") return "darwin-arm64";
if (platform === "freebsd" && arch === "x64") return "freebsd-x64";
if (platform === "freebsd" && arch === "arm64") return "freebsd-arm64";

return null;
Comment on lines +195 to +206
- [src/termisu/render_state.cr](/home/omar/sandbox/crystal/termisu/src/termisu/render_state.cr)
- [src/termisu/event/loop.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/loop.cr)
- [src/termisu/event/source/input.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/source/input.cr)
- [src/termisu/event/source/resize.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/source/resize.cr)
- [src/termisu/event/source/timer.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/source/timer.cr)
- [src/termisu/event/source/system_timer.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/source/system_timer.cr)
- [src/termisu/event/poller.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/poller.cr)
- [src/termisu/ffi/exports.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/exports.cr)
- [src/termisu/ffi/core.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/core.cr)
- [src/termisu/ffi/runtime.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/runtime.cr)
- [src/termisu/ffi/layout.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/layout.cr)
- [include/termisu/ffi.h](/home/omar/sandbox/crystal/termisu/include/termisu/ffi.h)
@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.base.json",
Comment on lines +1 to +3
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
Comment on lines +5 to +6
| Package | Path |
| ---------------------------------- | ------------------------------------ |
Comment on lines +164 to +175
- [src/termisu/event/poller.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/poller.cr)
- [src/termisu/event/poller/linux.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/poller/linux.cr)
- [src/termisu/event/poller/kqueue.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/poller/kqueue.cr)
- [src/termisu/event/poller/poll.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/poller/poll.cr)
- [src/termisu/tty.cr](/home/omar/sandbox/crystal/termisu/src/termisu/tty.cr)
- [src/termisu/terminal/backend.cr](/home/omar/sandbox/crystal/termisu/src/termisu/terminal/backend.cr)
- [src/termisu/ffi/exports.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/exports.cr)
- [src/termisu/ffi/layout.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/layout.cr)
- [javascript/core/src/native.ts](/home/omar/sandbox/crystal/termisu/javascript/core/src/native.ts)
- [javascript/core/src/termisu.ts](/home/omar/sandbox/crystal/termisu/javascript/core/src/termisu.ts)
- [javascript/platform/src/index.ts](/home/omar/sandbox/crystal/termisu/javascript/platform/src/index.ts)
- [javascript/runtime/src/index.ts](/home/omar/sandbox/crystal/termisu/javascript/runtime/src/index.ts)
Comment on lines +6 to +13
"baseUrl": ".",
"paths": {
"@termisu/*": [
"javascript/*/src/index.ts",
"javascript/framework/*/src/index.ts",
"javascript/starter/*/src/index.ts"
]
},
@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.base.json",
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: 17

🧹 Nitpick comments (4)
javascript/framework/react/tsconfig.json (1)

10-10: Consider including .tsx files for React adapter.

The include pattern only covers .ts files. If this React adapter will contain JSX components, you'll need to also include .tsx files.

📝 Suggested change
-  "include": ["src/**/*.ts"]
+  "include": ["src/**/*.ts", "src/**/*.tsx"]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@javascript/framework/react/tsconfig.json` at line 10, The tsconfig.json
include pattern currently only matches TypeScript files ("include":
["src/**/*.ts"]); update the tsconfig.json include setting used by the React
adapter to also match TSX files by adding the .tsx glob (e.g., include both
"src/**/*.ts" and "src/**/*.tsx" or a combined pattern like "src/**/*.{ts,tsx}")
so React components with JSX are compiled; modify the "include" array in
tsconfig.json accordingly.
javascript/native/linux/x64/gnu/package.json (1)

6-7: Add explicit publish access for scoped package.

Line 6 marks the package as publishable, but scoped packages can still publish as restricted by default. Set publishConfig.access explicitly to avoid release-time surprises.

Suggested change
   "private": false,
+  "publishConfig": {
+    "access": "public"
+  },
   "os": ["linux"],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@javascript/native/linux/x64/gnu/package.json` around lines 6 - 7, The
package.json currently sets "private": false but doesn't specify publish access
for a scoped package; add an explicit publishConfig object with "access":
"public" (i.e., set publishConfig.access) to ensure the package can be published
as public rather than defaulting to restricted for scoped packages—edit
package.json to include publishConfig with access set to "public".
javascript/create-tui/package.json (1)

25-29: Consider if starter dependencies should be devDependencies.

The dependencies on starter packages (@termisu/next-starter, @termisu/nuxt-starter, @termisu/sveltekit-starter) are listed as runtime dependencies. If the CLI only reads template files or metadata from these packages at scaffold-time (rather than bundling them into the output), they could be devDependencies to reduce install footprint for end users.

However, if the starters are dynamically resolved/imported at runtime, keeping them as dependencies is correct.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@javascript/create-tui/package.json` around lines 25 - 29, The package.json
currently lists the starter packages "@termisu/next-starter",
"@termisu/nuxt-starter", and "@termisu/sveltekit-starter" under "dependencies"
but they may only be used at scaffold-time; determine whether these packages are
imported/required at runtime (search for dynamic imports or require calls of
those exact package names in your CLI code) — if they are only used during
development/scaffolding, move them from "dependencies" to "devDependencies" in
package.json to reduce the runtime install footprint; if they are resolved or
imported dynamically at runtime, leave them in "dependencies" and ensure any
runtime import logic (the code that references these package names) handles
missing packages gracefully.
javascript/starter/sveltekit/package.json (1)

16-24: Missing devDependencies for build tooling.

The clean script uses rimraf and build:types/typecheck use tsc, but neither rimraf nor typescript are declared as dependencies. While these may be hoisted from the workspace root, explicitly declaring them ensures the package can be built in isolation and documents the actual requirements.

📦 Proposed addition
   "dependencies": {
     "@termisu/svelte": "workspace:*"
   },
+  "devDependencies": {
+    "rimraf": "^6.0.0",
+    "typescript": "^5.9.0"
+  },
   "license": "MIT"
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@javascript/starter/sveltekit/package.json` around lines 16 - 24, Add missing
devDependencies used by the package scripts: declare "rimraf" and "typescript"
under devDependencies so the "clean" script (rimraf) and
"build:types"/"typecheck" (tsc) work when the package is built in isolation;
update package.json's devDependencies to include rimraf and typescript (matching
the versions used in the workspace or a compatible semver) and keep the existing
script names ("clean", "build:types", "typecheck") unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@architecture/core-architecture.md`:
- Line 154: Change the phrase "FreeBSD/OpenBSD specific" to the hyphenated
compound adjective "FreeBSD/OpenBSD-specific" where it describes the TTY open
mode branch (the sentence mentioning `TTY` uses a FreeBSD/OpenBSD specific open
mode branch) to correct compound modifier style.
- Around line 192-206: The listed links use local absolute paths and must be
converted to repo-relative links so they work for all readers: update each link
(e.g., src/termisu.cr, src/termisu/terminal.cr, src/termisu/buffer.cr,
src/termisu/render_state.cr, src/termisu/event/loop.cr,
src/termisu/event/source/input.cr, src/termisu/event/source/resize.cr,
src/termisu/event/source/timer.cr, src/termisu/event/source/system_timer.cr,
src/termisu/event/poller.cr, src/termisu/ffi/exports.cr,
src/termisu/ffi/core.cr, src/termisu/ffi/runtime.cr, src/termisu/ffi/layout.cr,
include/termisu/ffi.h) to use repository-relative paths (e.g.,
[src/termisu.cr](src/termisu.cr)) instead of /home/omar/... so the links resolve
correctly for everyone.

In `@architecture/js-runtime-ffi-architecture.md`:
- Around line 164-175: The documentation contains absolute local paths like
/home/omar/sandbox/crystal/termisu/... which will not resolve for other
contributors; update the links on the referenced block to use
repository-relative paths instead (e.g., src/termisu/event/poller.cr,
src/termisu/event/poller/linux.cr, src/termisu/event/poller/kqueue.cr,
src/termisu/event/poller/poll.cr, src/termisu/tty.cr,
src/termisu/terminal/backend.cr, src/termisu/ffi/exports.cr,
src/termisu/ffi/layout.cr, javascript/core/src/native.ts,
javascript/core/src/termisu.ts, javascript/platform/src/index.ts,
javascript/runtime/src/index.ts) so they point to the files relative to the repo
root (or to the correct GitHub paths) rather than the local /home/omar/...
absolute paths.

In `@javascript/create-tui/src/cli.ts`:
- Around line 1-3: The import in cli.ts uses a relative import without a .js
extension which will break under Node ESM output; update the import that
references the symbol starterIds to use an explicit .js extension (import from
"./index.js") and scan other relative imports in the same module for the same
issue so the built ESM output from bun works in Node.

In `@javascript/framework/solid/tsconfig.json`:
- Line 2: The "extends" entry in the tsconfig.json currently points to
"../../tsconfig.base.json" which resolves to a non-existent
javascript/tsconfig.base.json; update the "extends" value (key: extends) in
javascript/framework/solid/tsconfig.json from "../../tsconfig.base.json" to
"../../../tsconfig.base.json" so it correctly resolves to the repository root
tsconfig.base.json and allows the project to inherit the shared base config.

In `@javascript/framework/svelte/tsconfig.json`:
- Line 2: The extends path in javascript/framework/svelte/tsconfig.json is
incorrect and points to a non-existent javascript/tsconfig.base.json; update the
"extends" property in that tsconfig.json to reference the shared root
tsconfig.base.json by climbing three directory levels from the Svelte package
(i.e., change the extends value to point to the root-level tsconfig.base.json)
so it matches other packages at the same depth (like javascript/starter/next and
javascript/starter/nuxt).

In `@javascript/native/darwin/x64/README.md`:
- Around line 3-5: The first line "Native target package scaffold for - OS:
darwin" mixes prose and the first bullet; split the heading/prose ("Native
target package scaffold for") onto its own line, add a blank line, and place
each list item on its own line as separate bullets ("- OS: darwin", "- CPU:
x64", "- libc: n/a") so the markdown renders correctly.

In `@javascript/native/freebsd/arm64/README.md`:
- Around line 3-5: The README's target summary mixes prose and list dashes
("Native target package scaffold for - OS: freebsd"), breaking the bullet list;
update the block so the opening sentence is separate and the OS/CPU/libc lines
are proper list items (e.g., a sentence "Native target package scaffold for:"
followed by three bullet lines "OS: freebsd", "CPU: arm64", "libc: n/a") to fix
the malformed markdown list formatting.

In `@javascript/native/freebsd/x64/README.md`:
- Around line 3-5: The README currently has a malformed list where the line
"Native target package scaffold for - OS: freebsd" combines prose with the first
bullet; split the header/prose from the bullet list and format the items as
separate bullets by moving "OS: freebsd" onto its own line prefixed with a
hyphen and ensuring "CPU: x64" and "libc: n/a" are each on their own
hyphen-prefixed lines (look for the exact strings "Native target package
scaffold for - OS: freebsd", "CPU: x64", and "libc: n/a" and correct them to a
header or sentence followed by a three-item bullet list).

In `@javascript/native/linux/arm64/gnu/README.md`:
- Around line 3-5: The README line mixes prose and list syntax; change the
heading sentence "Native target package scaffold for" to a standalone sentence
or header (e.g., "Native target package scaffold") and convert the combined "-
OS: linux - CPU: arm64 - libc: glibc" into a proper Markdown bullet list with
each item on its own line prefixed by "- " (e.g., "- OS: linux", "- CPU: arm64",
"- libc: glibc") so the intro and bullets are clearly separated; update the top
text that currently reads "Native target package scaffold for - OS: linux - CPU:
arm64 - libc: glibc" accordingly.

In `@javascript/native/linux/arm64/musl/README.md`:
- Around line 3-5: The README's first line merges the intro with a list item
("Native target package scaffold for - OS: linux"), breaking Markdown list
rendering; split that into an intro sentence and a proper bullet list by moving
the dash off the intro line so the file reads something like a standalone intro
line (e.g., "Native target package scaffold for:") followed by separate lines
beginning with "- OS: linux", "- CPU: arm64", "- libc: musl" to restore correct
Markdown list formatting.

In `@javascript/native/linux/x64/gnu/README.md`:
- Around line 3-5: The intro line "Native target package scaffold for - OS:
linux" is malformed—replace it with a proper sentence or header (e.g., "Native
target package scaffold for:") and convert the following lines into a Markdown
list of items ("- OS: linux", "- CPU: x64", "- libc: glibc") so the header and
list are separated and render correctly; locate the text "Native target package
scaffold for - OS: linux" in the README.md and update it accordingly.

In `@javascript/platform/package.json`:
- Around line 22-31: The package.json currently contains "workspace:*" entries
in optionalDependencies which will be published as-is and break npm consumers;
update the release process to either use bun publish or add a prepublish (or
prepack) script that rewrites all "workspace:*" values in optionalDependencies
to concrete semver versions (resolving them from your workspace manifests or
lockfile) before npm publish, and verify the generated tarball (npm pack)
contains resolved versions rather than workspace:*.

In `@javascript/platform/src/index.ts`:
- Around line 11-23: detectTarget currently always returns "gnu" Linux variants,
causing musl-based systems to get wrong packages; update detectTarget to detect
the libc family (use detect-libc's familySync) when platform === "linux" and
choose "musl" vs "gnu" accordingly so it returns "linux-x64-musl" or
"linux-x64-gnu" (and same for arm64). Modify import/usage to call familySync()
and map its result into the target string used by detectTarget; ensure the
returned values match the existing PlatformTarget/nativePackageByTarget keys.

In `@javascript/reconciler/package.json`:
- Line 17: The reconciler package.json build script currently sets the Bun build
target to "--target bun"; update the "build" npm script (the "build" entry in
javascript/reconciler/package.json) to use "--target node" instead of "--target
bun" so consumers match framework adapters, and apply the same change to the
equivalent "build" script in javascript/runtime/package.json to keep runtime
consistent.

In `@javascript/runtime/package.json`:
- Line 17: The build scripts for the runtime and reconciler packages currently
use "--target bun"; update the "build" script in both package.json files for the
runtime and reconciler packages to use "--target node" instead of "--target bun"
so the produced artifacts match the frameworks that target Node; locate the
"build" npm script entries (the "build" key) in each package.json and replace
the target flag, then run the package builds to verify no Bun-specific APIs are
required.

In `@javascript/runtime/src/index.ts`:
- Around line 5-9: The returned object from createRuntime currently exposes the
caller's options object directly (options), allowing external mutation; fix this
by returning a copy instead (e.g., shallow-clone the options object) so the
runtime retains its own immutable config snapshot—update createRuntime to assign
options: { ...options } (or a deep clone if nested mutability is a concern) so
callers cannot mutate the runtime via the original options reference.

---

Nitpick comments:
In `@javascript/create-tui/package.json`:
- Around line 25-29: The package.json currently lists the starter packages
"@termisu/next-starter", "@termisu/nuxt-starter", and
"@termisu/sveltekit-starter" under "dependencies" but they may only be used at
scaffold-time; determine whether these packages are imported/required at runtime
(search for dynamic imports or require calls of those exact package names in
your CLI code) — if they are only used during development/scaffolding, move them
from "dependencies" to "devDependencies" in package.json to reduce the runtime
install footprint; if they are resolved or imported dynamically at runtime,
leave them in "dependencies" and ensure any runtime import logic (the code that
references these package names) handles missing packages gracefully.

In `@javascript/framework/react/tsconfig.json`:
- Line 10: The tsconfig.json include pattern currently only matches TypeScript
files ("include": ["src/**/*.ts"]); update the tsconfig.json include setting
used by the React adapter to also match TSX files by adding the .tsx glob (e.g.,
include both "src/**/*.ts" and "src/**/*.tsx" or a combined pattern like
"src/**/*.{ts,tsx}") so React components with JSX are compiled; modify the
"include" array in tsconfig.json accordingly.

In `@javascript/native/linux/x64/gnu/package.json`:
- Around line 6-7: The package.json currently sets "private": false but doesn't
specify publish access for a scoped package; add an explicit publishConfig
object with "access": "public" (i.e., set publishConfig.access) to ensure the
package can be published as public rather than defaulting to restricted for
scoped packages—edit package.json to include publishConfig with access set to
"public".

In `@javascript/starter/sveltekit/package.json`:
- Around line 16-24: Add missing devDependencies used by the package scripts:
declare "rimraf" and "typescript" under devDependencies so the "clean" script
(rimraf) and "build:types"/"typecheck" (tsc) work when the package is built in
isolation; update package.json's devDependencies to include rimraf and
typescript (matching the versions used in the workspace or a compatible semver)
and keep the existing script names ("clean", "build:types", "typecheck")
unchanged.
🪄 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: 30ea9254-3283-4c93-b984-0df35edd6d4e

📥 Commits

Reviewing files that changed from the base of the PR and between 4940270 and f87cdb2.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (87)
  • .gitignore
  • architecture/README.md
  • architecture/core-architecture.md
  • architecture/js-runtime-ffi-architecture.md
  • javascript/README.md
  • javascript/create-tui/.gitignore
  • javascript/create-tui/README.md
  • javascript/create-tui/package.json
  • javascript/create-tui/src/cli.ts
  • javascript/create-tui/src/index.ts
  • javascript/create-tui/tsconfig.json
  • javascript/framework/react/.gitignore
  • javascript/framework/react/README.md
  • javascript/framework/react/package.json
  • javascript/framework/react/src/index.ts
  • javascript/framework/react/tsconfig.json
  • javascript/framework/solid/.gitignore
  • javascript/framework/solid/README.md
  • javascript/framework/solid/package.json
  • javascript/framework/solid/src/index.ts
  • javascript/framework/solid/tsconfig.json
  • javascript/framework/svelte/.gitignore
  • javascript/framework/svelte/README.md
  • javascript/framework/svelte/package.json
  • javascript/framework/svelte/src/index.ts
  • javascript/framework/svelte/tsconfig.json
  • javascript/framework/vue/.gitignore
  • javascript/framework/vue/README.md
  • javascript/framework/vue/package.json
  • javascript/framework/vue/src/index.ts
  • javascript/framework/vue/tsconfig.json
  • javascript/native/darwin/arm64/README.md
  • javascript/native/darwin/arm64/manifest.json
  • javascript/native/darwin/arm64/package.json
  • javascript/native/darwin/x64/README.md
  • javascript/native/darwin/x64/manifest.json
  • javascript/native/darwin/x64/package.json
  • javascript/native/freebsd/arm64/README.md
  • javascript/native/freebsd/arm64/manifest.json
  • javascript/native/freebsd/arm64/package.json
  • javascript/native/freebsd/x64/README.md
  • javascript/native/freebsd/x64/manifest.json
  • javascript/native/freebsd/x64/package.json
  • javascript/native/linux/arm64/gnu/README.md
  • javascript/native/linux/arm64/gnu/manifest.json
  • javascript/native/linux/arm64/gnu/package.json
  • javascript/native/linux/arm64/musl/README.md
  • javascript/native/linux/arm64/musl/manifest.json
  • javascript/native/linux/arm64/musl/package.json
  • javascript/native/linux/x64/gnu/README.md
  • javascript/native/linux/x64/gnu/manifest.json
  • javascript/native/linux/x64/gnu/package.json
  • javascript/native/linux/x64/musl/README.md
  • javascript/native/linux/x64/musl/manifest.json
  • javascript/native/linux/x64/musl/package.json
  • javascript/platform/.gitignore
  • javascript/platform/README.md
  • javascript/platform/package.json
  • javascript/platform/src/index.ts
  • javascript/platform/tsconfig.json
  • javascript/reconciler/.gitignore
  • javascript/reconciler/README.md
  • javascript/reconciler/package.json
  • javascript/reconciler/src/index.ts
  • javascript/reconciler/tsconfig.json
  • javascript/runtime/.gitignore
  • javascript/runtime/README.md
  • javascript/runtime/package.json
  • javascript/runtime/src/index.ts
  • javascript/runtime/tsconfig.json
  • javascript/starter/next/.gitignore
  • javascript/starter/next/README.md
  • javascript/starter/next/package.json
  • javascript/starter/next/src/index.ts
  • javascript/starter/next/tsconfig.json
  • javascript/starter/nuxt/.gitignore
  • javascript/starter/nuxt/README.md
  • javascript/starter/nuxt/package.json
  • javascript/starter/nuxt/src/index.ts
  • javascript/starter/nuxt/tsconfig.json
  • javascript/starter/sveltekit/.gitignore
  • javascript/starter/sveltekit/README.md
  • javascript/starter/sveltekit/package.json
  • javascript/starter/sveltekit/src/index.ts
  • javascript/starter/sveltekit/tsconfig.json
  • package.json
  • tsconfig.base.json

Comment on lines +1 to +3
#!/usr/bin/env node

import { starterIds } from "./index";
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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Inspect create-tui package runtime fields:"
rg -n '"name"|"type"|"bin"|"main"|"exports"' javascript/create-tui/package.json -C1

echo
echo "Inspect create-tui tsconfig module settings:"
rg -n '"module"|"moduleResolution"|"outDir"' javascript/create-tui/tsconfig.json -C1 || true

echo
echo "Find extensionless relative imports in create-tui source:"
rg -nP --type=ts 'from\s+"\.\/[^".]+"' javascript/create-tui/src

Repository: omarluq/termisu

Length of output: 699


🏁 Script executed:

cat -n javascript/create-tui/tsconfig.json

Repository: omarluq/termisu

Length of output: 363


🏁 Script executed:

head -20 javascript/create-tui/dist/cli.js 2>/dev/null || echo "dist/ directory may not exist in sandbox"

Repository: omarluq/termisu

Length of output: 99


🏁 Script executed:

ls -la javascript/create-tui/dist/ 2>/dev/null || echo "No dist directory found"

Repository: omarluq/termisu

Length of output: 82


🏁 Script executed:

fd -e ts javascript/create-tui/src/ | head -20

Repository: omarluq/termisu

Length of output: 468


🏁 Script executed:

cat -n javascript/create-tui/tsconfig.base.json 2>/dev/null || cat -n tsconfig.base.json

Repository: omarluq/termisu

Length of output: 589


🏁 Script executed:

fd . javascript/create-tui/src/ --extension ts

Repository: omarluq/termisu

Length of output: 126


🏁 Script executed:

rg -n "moduleResolution|module|" javascript/create-tui/tsconfig.base.json

Repository: omarluq/termisu

Length of output: 139


🏁 Script executed:

rg -n "rewriteImportExtensions|emitDeclarationOnly|declaration" javascript/create-tui/tsconfig.json javascript/create-tui/tsconfig.base.json

Repository: omarluq/termisu

Length of output: 286


🏁 Script executed:

rg -A5 '"scripts"' javascript/create-tui/package.json

Repository: omarluq/termisu

Length of output: 361


🏁 Script executed:

fd -t f javascript/create-tui -name "esbuild*" -o -name "rollup*" -o -name ".swcrc"

Repository: omarluq/termisu

Length of output: 289


🌐 Web query:

Bun bundler --target node --format esm relative imports .js extension

💡 Result:

When you run bun build --target node --format esm, you’re generating Node ESM, where relative import specifiers must include a file extension (e.g. ./foo.js, not ./foo). This is a Node ESM rule (same as browsers). [2][3]

Can Bun “add .js extensions” for relative imports?

  • Not as a dedicated flag/option. Bun’s bundler docs list many CLI options (including --target, --format, --splitting, --no-bundle), but there’s no documented “rewrite specifiers / add extensions” option. [1]

What to do instead (practical options)

  • Best practice: write source imports with .js already (even in TS), so the emitted JS is Node-valid. [2][3]
  • If you are transpiling without bundling (bun build --no-bundle), Bun will “transpile only” and you should expect to need Node-valid specifiers in the emitted files (so: use .js in source or run a post-step rewrite). [1]
  • If you bundle into a single file, the extension issue typically disappears because there are no runtime relative imports left.
  • If you use code-splitting (--splitting), Bun will emit chunk files with .js names (and the generated cross-chunk imports are handled by the bundler). [1]

Sources: Bun bundler docs [1]; Node ESM extension requirement references [2][3].


Use explicit .js extension for Node ESM relative import.

The build process uses bun build --target node --format esm, which produces Node ESM code. Node ESM strictly requires explicit .js extensions for relative imports; Bun does not automatically rewrite these. Line 3 will fail at runtime without the extension.

Proposed fix
- import { starterIds } from "./index";
+ import { starterIds } from "./index.js";
📝 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
#!/usr/bin/env node
import { starterIds } from "./index";
#!/usr/bin/env node
import { starterIds } from "./index.js";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@javascript/create-tui/src/cli.ts` around lines 1 - 3, The import in cli.ts
uses a relative import without a .js extension which will break under Node ESM
output; update the import that references the symbol starterIds to use an
explicit .js extension (import from "./index.js") and scan other relative
imports in the same module for the same issue so the built ESM output from bun
works in Node.

@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.base.json",
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 | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

python - <<'PY'
import json
from pathlib import Path

p = Path("javascript/framework/solid/tsconfig.json")
cfg = json.loads(p.read_text())
ext = cfg.get("extends")
resolved = (p.parent / ext).resolve()
print("extends =", ext)
print("resolved =", resolved)
print("exists   =", resolved.exists())
PY

echo
echo "== tsconfig.base.json files in repo =="
fd -a tsconfig.base.json

Repository: omarluq/termisu

Length of output: 248


Fix incorrect extends path to resolve to root-level tsconfig.base.json.

The current path ../../tsconfig.base.json resolves to javascript/tsconfig.base.json, which does not exist. The base config is located at the repository root. Update to ../../../tsconfig.base.json to correctly resolve from javascript/framework/solid/:

Suggested fix
-  "extends": "../../tsconfig.base.json",
+  "extends": "../../../tsconfig.base.json",

Without this fix, the typecheck/build will fail to inherit the shared tsconfig settings.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@javascript/framework/solid/tsconfig.json` at line 2, The "extends" entry in
the tsconfig.json currently points to "../../tsconfig.base.json" which resolves
to a non-existent javascript/tsconfig.base.json; update the "extends" value
(key: extends) in javascript/framework/solid/tsconfig.json from
"../../tsconfig.base.json" to "../../../tsconfig.base.json" so it correctly
resolves to the repository root tsconfig.base.json and allows the project to
inherit the shared base config.

},
"files": ["dist", "README.md"],
"scripts": {
"build": "bun run clean && bun build src/index.ts --outdir dist --target bun --format esm && bun run build:types",
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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, understand the reconciler package structure
echo "=== Reconciler package.json ==="
cat javascript/reconciler/package.json

echo -e "\n=== Finding references to reconciler ==="
rg "reconciler" --type js --type ts --type json -l | head -20

Repository: omarluq/termisu

Length of output: 1112


🏁 Script executed:

#!/bin/bash
# Check what packages depend on reconciler
echo "=== Search for reconciler imports ==="
rg "from ['\"].*reconciler" --type js --type ts -A 2 | head -50

echo -e "\n=== Look for package dependencies on reconciler ==="
find . -name "package.json" -type f | xargs grep -l "reconciler" | head -10

Repository: omarluq/termisu

Length of output: 353


🏁 Script executed:

#!/bin/bash
# Understand the package structure and consumers
echo "=== Check runtime package for comparison ==="
if [ -f "javascript/runtime/package.json" ]; then
  cat javascript/runtime/package.json
fi

echo -e "\n=== Search adapter packages ==="
find javascript -name "package.json" -type f | xargs grep -l "adapter" -l 2>/dev/null | head -5

Repository: omarluq/termisu

Length of output: 1078


🏁 Script executed:

#!/bin/bash
# Find all adapters and their dependencies
echo "=== Find adapter directories ==="
find javascript -type d -name "*adapter*" | head -10

echo -e "\n=== Check adapter package.json files ==="
find javascript -path "*/adapter*/package.json" -type f | head -5 | xargs cat

Repository: omarluq/termisu

Length of output: 133


🏁 Script executed:

#!/bin/bash
# Search for actual imports of reconciler in adapter code
echo "=== Reconciler imports in JavaScript/TypeScript files ==="
rg "reconciler" javascript --type js --type ts -B 2 -A 2 | grep -E "(import|from|require)" -A 1 -B 1 | head -40

echo -e "\n=== Check if reconciler is exported from runtime ==="
rg "reconciler" javascript/runtime --type js --type ts -B 2 -A 2 | head -30

Repository: omarluq/termisu

Length of output: 170


🏁 Script executed:

#!/bin/bash
# Check what target the framework packages build for
echo "=== Framework package.json build scripts ==="
for pkg in javascript/framework/*/package.json; do
  echo "--- $(dirname $pkg) ---"
  grep -A 2 '"build"' "$pkg" | head -3
done

echo -e "\n=== Check for any Node-specific target patterns ==="
find javascript -name "package.json" -type f | xargs grep -h "\-\-target" | sort | uniq -c

Repository: omarluq/termisu

Length of output: 1561


🏁 Script executed:

#!/bin/bash
# Check if there's any documentation about runtime targets
echo "=== Look for README or docs about runtime compatibility ==="
find javascript -name "README*" -type f | head -5 | xargs cat 2>/dev/null | head -50

echo -e "\n=== Check root-level documentation ==="
if [ -f "README.md" ]; then
  cat README.md | head -80
fi

Repository: omarluq/termisu

Length of output: 6236


🏁 Script executed:

#!/bin/bash
# Check the reconciler source to understand its purpose
echo "=== Reconciler source files ==="
ls -la javascript/reconciler/src/

echo -e "\n=== Reconciler main index file ==="
head -30 javascript/reconciler/src/index.ts

echo -e "\n=== Check runtime source ==="
ls -la javascript/runtime/src/

Repository: omarluq/termisu

Length of output: 743


Change reconciler build target to --target node for consistency with framework consumers.

Line 17: All framework adapters (react, solid, svelte, vue) that depend on this package use --target node, but the reconciler builds with --target bun. This creates a runtime target mismatch. Switch to --target node.

Note: The runtime package has the same issue The runtime dependency (javascript/runtime/package.json) also uses `--target bun` and should be updated to `--target node` for the same reason.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@javascript/reconciler/package.json` at line 17, The reconciler package.json
build script currently sets the Bun build target to "--target bun"; update the
"build" npm script (the "build" entry in javascript/reconciler/package.json) to
use "--target node" instead of "--target bun" so consumers match framework
adapters, and apply the same change to the equivalent "build" script in
javascript/runtime/package.json to keep runtime consistent.

},
"files": ["dist", "README.md"],
"scripts": {
"build": "bun run clean && bun build src/index.ts --outdir dist --target bun --format esm && bun run build:types",
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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Build target scan ==="
rg -nP '"build":\s*".*--target\s+(bun|node)' \
  javascript/runtime/package.json \
  javascript/reconciler/package.json \
  javascript/framework/react/package.json \
  javascript/framework/solid/package.json

echo "=== Bun-specific API usage scan ==="
rg -nP --type=ts '\bBun\.' javascript/runtime/src javascript/reconciler/src || true

Repository: omarluq/termisu

Length of output: 757


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Framework dependencies ==="
echo "=== React framework dependencies ==="
cat javascript/framework/react/package.json | jq '.dependencies,.devDependencies' 2>/dev/null || grep -E '"(reconciler|runtime)"' javascript/framework/react/package.json || echo "No reconciler/runtime deps found"

echo ""
echo "=== Solid framework dependencies ==="
cat javascript/framework/solid/package.json | jq '.dependencies,.devDependencies' 2>/dev/null || grep -E '"(reconciler|runtime)"' javascript/framework/solid/package.json || echo "No reconciler/runtime deps found"

echo ""
echo "=== Reconciler dependencies ==="
cat javascript/reconciler/package.json | jq '.dependencies,.devDependencies' 2>/dev/null || grep -E '"runtime"' javascript/reconciler/package.json || echo "No runtime deps found"

Repository: omarluq/termisu

Length of output: 412


Both runtime and reconciler packages build with --target bun while downstream frameworks target Node.

The mismatch is broader than runtime alone: both javascript/runtime/package.json (line 17) and javascript/reconciler/package.json (line 17) use --target bun, while the frameworks that depend on them (javascript/framework/react and javascript/framework/solid) build with --target node. Since the frameworks consume reconciler and reconciler consumes runtime, the build targets should align to node for consistent Node compatibility across the dependency chain.

No Bun-specific APIs were detected in the source code, so the issue is build configuration rather than runtime API usage. However, misaligned targets can result in suboptimal or inconsistent output for Node environments.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@javascript/runtime/package.json` at line 17, The build scripts for the
runtime and reconciler packages currently use "--target bun"; update the "build"
script in both package.json files for the runtime and reconciler packages to use
"--target node" instead of "--target bun" so the produced artifacts match the
frameworks that target Node; locate the "build" npm script entries (the "build"
key) in each package.json and replace the target flag, then run the package
builds to verify no Bun-specific APIs are required.

Comment on lines +5 to +9
export const createRuntime = (options: RuntimeOptions = {}) => {
return {
kind: "termisu-runtime" as const,
options,
};
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

Avoid exposing a mutable alias of caller-provided options.

On Line 8, returning the same options object means external code can mutate runtime config after creation.

🔧 Proposed fix
 export const createRuntime = (options: RuntimeOptions = {}) => {
+  const runtimeOptions: RuntimeOptions = { ...options };
   return {
     kind: "termisu-runtime" as const,
-    options,
+    options: runtimeOptions,
   };
 };
📝 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
export const createRuntime = (options: RuntimeOptions = {}) => {
return {
kind: "termisu-runtime" as const,
options,
};
export const createRuntime = (options: RuntimeOptions = {}) => {
const runtimeOptions: RuntimeOptions = { ...options };
return {
kind: "termisu-runtime" as const,
options: runtimeOptions,
};
};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@javascript/runtime/src/index.ts` around lines 5 - 9, The returned object from
createRuntime currently exposes the caller's options object directly (options),
allowing external mutation; fix this by returning a copy instead (e.g.,
shallow-clone the options object) so the runtime retains its own immutable
config snapshot—update createRuntime to assign options: { ...options } (or a
deep clone if nested mutability is a concern) so callers cannot mutate the
runtime via the original options reference.

@omarluq omarluq force-pushed the add-boilerplate-js-libs branch from f87cdb2 to c1c5608 Compare March 30, 2026 20:17
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.

♻️ Duplicate comments (2)
architecture/core-architecture.md (2)

154-154: ⚠️ Potential issue | 🟡 Minor

Fix compound modifier hyphenation at Line 154.

Use “FreeBSD/OpenBSD-specific” instead of “FreeBSD/OpenBSD specific” for correct grammar in this noun modifier.

Suggested fix
-- `TTY` uses a FreeBSD/OpenBSD specific open mode branch.
+- `TTY` uses a FreeBSD/OpenBSD-specific open mode branch.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@architecture/core-architecture.md` at line 154, Update the compound modifier
in the sentence referencing TTY so the noun modifier is hyphenated correctly:
replace the phrase "FreeBSD/OpenBSD specific" with "FreeBSD/OpenBSD-specific" in
the line that mentions `TTY` to produce "TTY uses a FreeBSD/OpenBSD-specific
open mode branch."

192-206: ⚠️ Potential issue | 🟡 Minor

Replace local absolute file links with repo-relative links.

At Lines 192-206, links point to /home/omar/... and will not resolve for other contributors/readers.

Suggested fix
-- [src/termisu.cr](/home/omar/sandbox/crystal/termisu/src/termisu.cr)
-- [src/termisu/terminal.cr](/home/omar/sandbox/crystal/termisu/src/termisu/terminal.cr)
-- [src/termisu/buffer.cr](/home/omar/sandbox/crystal/termisu/src/termisu/buffer.cr)
-- [src/termisu/render_state.cr](/home/omar/sandbox/crystal/termisu/src/termisu/render_state.cr)
-- [src/termisu/event/loop.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/loop.cr)
-- [src/termisu/event/source/input.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/source/input.cr)
-- [src/termisu/event/source/resize.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/source/resize.cr)
-- [src/termisu/event/source/timer.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/source/timer.cr)
-- [src/termisu/event/source/system_timer.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/source/system_timer.cr)
-- [src/termisu/event/poller.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/poller.cr)
-- [src/termisu/ffi/exports.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/exports.cr)
-- [src/termisu/ffi/core.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/core.cr)
-- [src/termisu/ffi/runtime.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/runtime.cr)
-- [src/termisu/ffi/layout.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/layout.cr)
-- [include/termisu/ffi.h](/home/omar/sandbox/crystal/termisu/include/termisu/ffi.h)
+- [src/termisu.cr](../src/termisu.cr)
+- [src/termisu/terminal.cr](../src/termisu/terminal.cr)
+- [src/termisu/buffer.cr](../src/termisu/buffer.cr)
+- [src/termisu/render_state.cr](../src/termisu/render_state.cr)
+- [src/termisu/event/loop.cr](../src/termisu/event/loop.cr)
+- [src/termisu/event/source/input.cr](../src/termisu/event/source/input.cr)
+- [src/termisu/event/source/resize.cr](../src/termisu/event/source/resize.cr)
+- [src/termisu/event/source/timer.cr](../src/termisu/event/source/timer.cr)
+- [src/termisu/event/source/system_timer.cr](../src/termisu/event/source/system_timer.cr)
+- [src/termisu/event/poller.cr](../src/termisu/event/poller.cr)
+- [src/termisu/ffi/exports.cr](../src/termisu/ffi/exports.cr)
+- [src/termisu/ffi/core.cr](../src/termisu/ffi/core.cr)
+- [src/termisu/ffi/runtime.cr](../src/termisu/ffi/runtime.cr)
+- [src/termisu/ffi/layout.cr](../src/termisu/ffi/layout.cr)
+- [include/termisu/ffi.h](../include/termisu/ffi.h)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@architecture/core-architecture.md` around lines 192 - 206, The listed
markdown links under the block that references src/termisu.cr,
src/termisu/terminal.cr, src/termisu/buffer.cr, src/termisu/render_state.cr, the
files under src/termisu/event/* (loop.cr, input.cr, resize.cr, timer.cr,
system_timer.cr, poller.cr), the ffi files (src/termisu/ffi/exports.cr, core.cr,
runtime.cr, layout.cr) and include/termisu/ffi.h use absolute local paths
(/home/omar/...) — change each to repo-relative paths (e.g., ./src/termisu.cr or
/src/termisu/cr depending on repo style) so links resolve for all contributors;
update each link target consistently in the core-architecture.md list.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@architecture/core-architecture.md`:
- Line 154: Update the compound modifier in the sentence referencing TTY so the
noun modifier is hyphenated correctly: replace the phrase "FreeBSD/OpenBSD
specific" with "FreeBSD/OpenBSD-specific" in the line that mentions `TTY` to
produce "TTY uses a FreeBSD/OpenBSD-specific open mode branch."
- Around line 192-206: The listed markdown links under the block that references
src/termisu.cr, src/termisu/terminal.cr, src/termisu/buffer.cr,
src/termisu/render_state.cr, the files under src/termisu/event/* (loop.cr,
input.cr, resize.cr, timer.cr, system_timer.cr, poller.cr), the ffi files
(src/termisu/ffi/exports.cr, core.cr, runtime.cr, layout.cr) and
include/termisu/ffi.h use absolute local paths (/home/omar/...) — change each to
repo-relative paths (e.g., ./src/termisu.cr or /src/termisu/cr depending on repo
style) so links resolve for all contributors; update each link target
consistently in the core-architecture.md list.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2040bc02-4869-47ab-adde-b82cb6100f32

📥 Commits

Reviewing files that changed from the base of the PR and between f87cdb2 and c1c5608.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (86)
  • architecture/README.md
  • architecture/core-architecture.md
  • architecture/js-runtime-ffi-architecture.md
  • javascript/README.md
  • javascript/create-tui/.gitignore
  • javascript/create-tui/README.md
  • javascript/create-tui/package.json
  • javascript/create-tui/src/cli.ts
  • javascript/create-tui/src/index.ts
  • javascript/create-tui/tsconfig.json
  • javascript/framework/react/.gitignore
  • javascript/framework/react/README.md
  • javascript/framework/react/package.json
  • javascript/framework/react/src/index.ts
  • javascript/framework/react/tsconfig.json
  • javascript/framework/solid/.gitignore
  • javascript/framework/solid/README.md
  • javascript/framework/solid/package.json
  • javascript/framework/solid/src/index.ts
  • javascript/framework/solid/tsconfig.json
  • javascript/framework/svelte/.gitignore
  • javascript/framework/svelte/README.md
  • javascript/framework/svelte/package.json
  • javascript/framework/svelte/src/index.ts
  • javascript/framework/svelte/tsconfig.json
  • javascript/framework/vue/.gitignore
  • javascript/framework/vue/README.md
  • javascript/framework/vue/package.json
  • javascript/framework/vue/src/index.ts
  • javascript/framework/vue/tsconfig.json
  • javascript/native/darwin/arm64/README.md
  • javascript/native/darwin/arm64/manifest.json
  • javascript/native/darwin/arm64/package.json
  • javascript/native/darwin/x64/README.md
  • javascript/native/darwin/x64/manifest.json
  • javascript/native/darwin/x64/package.json
  • javascript/native/freebsd/arm64/README.md
  • javascript/native/freebsd/arm64/manifest.json
  • javascript/native/freebsd/arm64/package.json
  • javascript/native/freebsd/x64/README.md
  • javascript/native/freebsd/x64/manifest.json
  • javascript/native/freebsd/x64/package.json
  • javascript/native/linux/arm64/gnu/README.md
  • javascript/native/linux/arm64/gnu/manifest.json
  • javascript/native/linux/arm64/gnu/package.json
  • javascript/native/linux/arm64/musl/README.md
  • javascript/native/linux/arm64/musl/manifest.json
  • javascript/native/linux/arm64/musl/package.json
  • javascript/native/linux/x64/gnu/README.md
  • javascript/native/linux/x64/gnu/manifest.json
  • javascript/native/linux/x64/gnu/package.json
  • javascript/native/linux/x64/musl/README.md
  • javascript/native/linux/x64/musl/manifest.json
  • javascript/native/linux/x64/musl/package.json
  • javascript/platform/.gitignore
  • javascript/platform/README.md
  • javascript/platform/package.json
  • javascript/platform/src/index.ts
  • javascript/platform/tsconfig.json
  • javascript/reconciler/.gitignore
  • javascript/reconciler/README.md
  • javascript/reconciler/package.json
  • javascript/reconciler/src/index.ts
  • javascript/reconciler/tsconfig.json
  • javascript/runtime/.gitignore
  • javascript/runtime/README.md
  • javascript/runtime/package.json
  • javascript/runtime/src/index.ts
  • javascript/runtime/tsconfig.json
  • javascript/starter/next/.gitignore
  • javascript/starter/next/README.md
  • javascript/starter/next/package.json
  • javascript/starter/next/src/index.ts
  • javascript/starter/next/tsconfig.json
  • javascript/starter/nuxt/.gitignore
  • javascript/starter/nuxt/README.md
  • javascript/starter/nuxt/package.json
  • javascript/starter/nuxt/src/index.ts
  • javascript/starter/nuxt/tsconfig.json
  • javascript/starter/sveltekit/.gitignore
  • javascript/starter/sveltekit/README.md
  • javascript/starter/sveltekit/package.json
  • javascript/starter/sveltekit/src/index.ts
  • javascript/starter/sveltekit/tsconfig.json
  • package.json
  • tsconfig.base.json
✅ Files skipped from review due to trivial changes (77)
  • javascript/runtime/README.md
  • javascript/framework/react/.gitignore
  • javascript/create-tui/.gitignore
  • javascript/reconciler/.gitignore
  • javascript/framework/svelte/.gitignore
  • javascript/platform/.gitignore
  • javascript/framework/solid/.gitignore
  • javascript/platform/README.md
  • javascript/framework/vue/.gitignore
  • javascript/framework/react/src/index.ts
  • javascript/starter/next/src/index.ts
  • javascript/runtime/.gitignore
  • javascript/starter/next/.gitignore
  • javascript/native/linux/arm64/musl/README.md
  • javascript/starter/sveltekit/src/index.ts
  • javascript/framework/react/README.md
  • javascript/native/darwin/x64/README.md
  • javascript/framework/vue/src/index.ts
  • javascript/starter/nuxt/.gitignore
  • javascript/framework/vue/README.md
  • javascript/native/darwin/arm64/README.md
  • javascript/framework/svelte/README.md
  • javascript/starter/nuxt/src/index.ts
  • javascript/framework/solid/src/index.ts
  • javascript/starter/next/README.md
  • architecture/README.md
  • javascript/create-tui/README.md
  • javascript/reconciler/README.md
  • javascript/native/linux/arm64/musl/manifest.json
  • javascript/native/freebsd/arm64/manifest.json
  • javascript/starter/nuxt/README.md
  • package.json
  • javascript/starter/sveltekit/README.md
  • javascript/native/linux/x64/gnu/README.md
  • javascript/native/darwin/x64/manifest.json
  • javascript/native/freebsd/x64/manifest.json
  • javascript/framework/svelte/src/index.ts
  • javascript/native/linux/arm64/gnu/README.md
  • javascript/native/freebsd/x64/README.md
  • javascript/native/linux/x64/musl/manifest.json
  • javascript/native/freebsd/arm64/README.md
  • javascript/native/linux/x64/musl/README.md
  • javascript/native/linux/x64/gnu/manifest.json
  • javascript/native/linux/arm64/gnu/manifest.json
  • javascript/framework/solid/README.md
  • javascript/starter/sveltekit/.gitignore
  • javascript/native/freebsd/x64/package.json
  • javascript/create-tui/src/cli.ts
  • javascript/platform/tsconfig.json
  • javascript/native/darwin/arm64/manifest.json
  • javascript/create-tui/src/index.ts
  • javascript/reconciler/tsconfig.json
  • javascript/runtime/tsconfig.json
  • tsconfig.base.json
  • javascript/native/linux/x64/gnu/package.json
  • javascript/framework/vue/tsconfig.json
  • javascript/starter/next/tsconfig.json
  • javascript/native/linux/arm64/gnu/package.json
  • javascript/native/darwin/x64/package.json
  • javascript/reconciler/src/index.ts
  • javascript/native/darwin/arm64/package.json
  • javascript/starter/next/package.json
  • javascript/runtime/package.json
  • javascript/framework/solid/package.json
  • javascript/native/linux/x64/musl/package.json
  • javascript/native/freebsd/arm64/package.json
  • javascript/native/linux/arm64/musl/package.json
  • javascript/starter/nuxt/package.json
  • javascript/starter/nuxt/tsconfig.json
  • javascript/framework/svelte/tsconfig.json
  • javascript/framework/react/package.json
  • javascript/framework/react/tsconfig.json
  • javascript/framework/vue/package.json
  • architecture/js-runtime-ffi-architecture.md
  • javascript/starter/sveltekit/package.json
  • javascript/platform/package.json
  • javascript/create-tui/package.json
🚧 Files skipped from review as they are similar to previous changes (6)
  • javascript/runtime/src/index.ts
  • javascript/framework/solid/tsconfig.json
  • javascript/starter/sveltekit/tsconfig.json
  • javascript/reconciler/package.json
  • javascript/create-tui/tsconfig.json
  • javascript/framework/svelte/package.json

Copilot AI review requested due to automatic review settings April 1, 2026 00:28
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.

🧹 Nitpick comments (1)
javascript/README.md (1)

3-3: Avoid hard-coding the package count.

Line 3 can drift as packages are added/removed; consider wording that doesn’t require manual recount.

Proposed doc tweak
-This workspace is split into 20 packages.
+This workspace is split into the following packages.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@javascript/README.md` at line 3, The README currently hard-codes "This
workspace is split into 20 packages." — replace that sentence with wording that
doesn't require manual updates (e.g., "This workspace is split into multiple
packages." or "This workspace contains several packages.") so it won't drift as
packages are added/removed; locate the existing sentence "This workspace is
split into 20 packages." in README.md and update it to a generic, count-free
phrase.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@javascript/README.md`:
- Line 3: The README currently hard-codes "This workspace is split into 20
packages." — replace that sentence with wording that doesn't require manual
updates (e.g., "This workspace is split into multiple packages." or "This
workspace contains several packages.") so it won't drift as packages are
added/removed; locate the existing sentence "This workspace is split into 20
packages." in README.md and update it to a generic, count-free phrase.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6d2918f3-bf28-45af-9e08-315ebd940448

📥 Commits

Reviewing files that changed from the base of the PR and between c1c5608 and 00337dd.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (86)
  • architecture/README.md
  • architecture/core-architecture.md
  • architecture/js-runtime-ffi-architecture.md
  • javascript/README.md
  • javascript/create-tui/.gitignore
  • javascript/create-tui/README.md
  • javascript/create-tui/package.json
  • javascript/create-tui/src/cli.ts
  • javascript/create-tui/src/index.ts
  • javascript/create-tui/tsconfig.json
  • javascript/framework/react/.gitignore
  • javascript/framework/react/README.md
  • javascript/framework/react/package.json
  • javascript/framework/react/src/index.ts
  • javascript/framework/react/tsconfig.json
  • javascript/framework/solid/.gitignore
  • javascript/framework/solid/README.md
  • javascript/framework/solid/package.json
  • javascript/framework/solid/src/index.ts
  • javascript/framework/solid/tsconfig.json
  • javascript/framework/svelte/.gitignore
  • javascript/framework/svelte/README.md
  • javascript/framework/svelte/package.json
  • javascript/framework/svelte/src/index.ts
  • javascript/framework/svelte/tsconfig.json
  • javascript/framework/vue/.gitignore
  • javascript/framework/vue/README.md
  • javascript/framework/vue/package.json
  • javascript/framework/vue/src/index.ts
  • javascript/framework/vue/tsconfig.json
  • javascript/native/darwin/arm64/README.md
  • javascript/native/darwin/arm64/manifest.json
  • javascript/native/darwin/arm64/package.json
  • javascript/native/darwin/x64/README.md
  • javascript/native/darwin/x64/manifest.json
  • javascript/native/darwin/x64/package.json
  • javascript/native/freebsd/arm64/README.md
  • javascript/native/freebsd/arm64/manifest.json
  • javascript/native/freebsd/arm64/package.json
  • javascript/native/freebsd/x64/README.md
  • javascript/native/freebsd/x64/manifest.json
  • javascript/native/freebsd/x64/package.json
  • javascript/native/linux/arm64/gnu/README.md
  • javascript/native/linux/arm64/gnu/manifest.json
  • javascript/native/linux/arm64/gnu/package.json
  • javascript/native/linux/arm64/musl/README.md
  • javascript/native/linux/arm64/musl/manifest.json
  • javascript/native/linux/arm64/musl/package.json
  • javascript/native/linux/x64/gnu/README.md
  • javascript/native/linux/x64/gnu/manifest.json
  • javascript/native/linux/x64/gnu/package.json
  • javascript/native/linux/x64/musl/README.md
  • javascript/native/linux/x64/musl/manifest.json
  • javascript/native/linux/x64/musl/package.json
  • javascript/platform/.gitignore
  • javascript/platform/README.md
  • javascript/platform/package.json
  • javascript/platform/src/index.ts
  • javascript/platform/tsconfig.json
  • javascript/reconciler/.gitignore
  • javascript/reconciler/README.md
  • javascript/reconciler/package.json
  • javascript/reconciler/src/index.ts
  • javascript/reconciler/tsconfig.json
  • javascript/runtime/.gitignore
  • javascript/runtime/README.md
  • javascript/runtime/package.json
  • javascript/runtime/src/index.ts
  • javascript/runtime/tsconfig.json
  • javascript/starter/next/.gitignore
  • javascript/starter/next/README.md
  • javascript/starter/next/package.json
  • javascript/starter/next/src/index.ts
  • javascript/starter/next/tsconfig.json
  • javascript/starter/nuxt/.gitignore
  • javascript/starter/nuxt/README.md
  • javascript/starter/nuxt/package.json
  • javascript/starter/nuxt/src/index.ts
  • javascript/starter/nuxt/tsconfig.json
  • javascript/starter/sveltekit/.gitignore
  • javascript/starter/sveltekit/README.md
  • javascript/starter/sveltekit/package.json
  • javascript/starter/sveltekit/src/index.ts
  • javascript/starter/sveltekit/tsconfig.json
  • package.json
  • tsconfig.base.json
✅ Files skipped from review due to trivial changes (76)
  • javascript/create-tui/README.md
  • javascript/framework/vue/README.md
  • javascript/framework/vue/.gitignore
  • javascript/create-tui/.gitignore
  • architecture/README.md
  • javascript/framework/svelte/src/index.ts
  • javascript/framework/solid/.gitignore
  • javascript/framework/svelte/.gitignore
  • javascript/framework/react/README.md
  • javascript/platform/.gitignore
  • javascript/native/linux/arm64/gnu/README.md
  • javascript/starter/next/.gitignore
  • javascript/reconciler/.gitignore
  • javascript/framework/react/src/index.ts
  • javascript/framework/svelte/README.md
  • javascript/framework/react/.gitignore
  • javascript/runtime/.gitignore
  • javascript/framework/solid/src/index.ts
  • javascript/framework/vue/src/index.ts
  • javascript/framework/solid/README.md
  • javascript/starter/nuxt/README.md
  • javascript/runtime/README.md
  • javascript/native/freebsd/arm64/README.md
  • javascript/starter/next/README.md
  • javascript/reconciler/README.md
  • javascript/native/darwin/arm64/manifest.json
  • javascript/platform/README.md
  • javascript/starter/next/src/index.ts
  • javascript/native/freebsd/arm64/manifest.json
  • javascript/starter/nuxt/.gitignore
  • javascript/native/linux/x64/musl/README.md
  • javascript/native/linux/arm64/musl/manifest.json
  • javascript/native/darwin/arm64/README.md
  • javascript/native/linux/x64/gnu/README.md
  • javascript/native/linux/x64/gnu/manifest.json
  • javascript/native/linux/arm64/musl/README.md
  • javascript/starter/nuxt/src/index.ts
  • javascript/native/freebsd/x64/README.md
  • javascript/starter/sveltekit/src/index.ts
  • javascript/starter/sveltekit/README.md
  • javascript/create-tui/src/index.ts
  • javascript/native/freebsd/x64/manifest.json
  • javascript/native/darwin/x64/manifest.json
  • javascript/native/freebsd/x64/package.json
  • javascript/native/linux/x64/musl/manifest.json
  • javascript/create-tui/src/cli.ts
  • javascript/starter/sveltekit/.gitignore
  • javascript/native/linux/arm64/gnu/manifest.json
  • package.json
  • javascript/native/darwin/x64/README.md
  • javascript/create-tui/tsconfig.json
  • javascript/framework/react/tsconfig.json
  • javascript/native/linux/x64/gnu/package.json
  • javascript/reconciler/tsconfig.json
  • javascript/platform/tsconfig.json
  • javascript/native/linux/x64/musl/package.json
  • javascript/runtime/tsconfig.json
  • javascript/runtime/src/index.ts
  • javascript/starter/next/tsconfig.json
  • tsconfig.base.json
  • javascript/native/linux/arm64/gnu/package.json
  • javascript/native/darwin/x64/package.json
  • javascript/platform/src/index.ts
  • javascript/starter/next/package.json
  • javascript/reconciler/src/index.ts
  • javascript/starter/sveltekit/package.json
  • javascript/framework/solid/package.json
  • javascript/native/darwin/arm64/package.json
  • javascript/framework/react/package.json
  • javascript/runtime/package.json
  • javascript/reconciler/package.json
  • javascript/native/linux/arm64/musl/package.json
  • architecture/js-runtime-ffi-architecture.md
  • javascript/starter/nuxt/package.json
  • javascript/create-tui/package.json
  • javascript/platform/package.json
🚧 Files skipped from review as they are similar to previous changes (8)
  • javascript/framework/svelte/tsconfig.json
  • javascript/framework/vue/tsconfig.json
  • javascript/framework/solid/tsconfig.json
  • javascript/starter/nuxt/tsconfig.json
  • javascript/starter/sveltekit/tsconfig.json
  • javascript/framework/vue/package.json
  • javascript/native/freebsd/arm64/package.json
  • javascript/framework/svelte/package.json

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR scaffolds and reorganizes the repository’s JavaScript workspace into a multi-package structure, grouping framework adapters, starters, and native target packages under consistent directory conventions, and wiring up workspace/TypeScript resolution accordingly.

Changes:

  • Expanded Bun workspaces to include all JavaScript packages (framework adapters, starters, native targets).
  • Added new scaffold packages (@termisu/runtime, @termisu/reconciler, @termisu/platform, framework adapters, starters, and native target stubs).
  • Added initial architecture documentation for core + JS runtime/FFI package topology.

Reviewed changes

Copilot reviewed 86 out of 87 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
tsconfig.base.json Adds @termisu/* path mappings for the new workspace structure.
package.json Expands root workspaces globs to include all JS packages and native targets.
bun.lock Updates lockfile to reflect newly added workspace packages.
javascript/README.md Documents the JS workspace package list and locations.
architecture/README.md Adds an index for architecture documentation.
architecture/js-runtime-ffi-architecture.md Adds planned JS runtime + FFI architecture and package topology notes.
architecture/core-architecture.md Adds implementation-backed Crystal core architecture notes.
javascript/runtime/tsconfig.json Adds TS config for the runtime package.
javascript/runtime/src/index.ts Scaffolds createRuntime and RuntimeOptions.
javascript/runtime/README.md Adds runtime package README.
javascript/runtime/package.json Adds runtime package manifest/scripts/deps.
javascript/runtime/.gitignore Ignores runtime build output.
javascript/reconciler/tsconfig.json Adds TS config for the reconciler package.
javascript/reconciler/src/index.ts Scaffolds createReconciler and options types.
javascript/reconciler/README.md Adds reconciler package README.
javascript/reconciler/package.json Adds reconciler package manifest/scripts/deps.
javascript/reconciler/.gitignore Ignores reconciler build output.
javascript/platform/tsconfig.json Adds TS config for the platform package.
javascript/platform/src/index.ts Adds initial target detection + native package name mapping.
javascript/platform/README.md Adds platform package README.
javascript/platform/package.json Adds platform package manifest/scripts + optional native deps.
javascript/platform/.gitignore Ignores platform build output.
javascript/create-tui/tsconfig.json Adds TS config for the CLI scaffolder package.
javascript/create-tui/src/index.ts Defines supported starter IDs.
javascript/create-tui/src/cli.ts Adds initial CLI entrypoint scaffold.
javascript/create-tui/README.md Adds create-tui package README.
javascript/create-tui/package.json Adds CLI package manifest/scripts and starter deps.
javascript/create-tui/.gitignore Ignores create-tui build output.
javascript/framework/react/tsconfig.json Adds TS config for the React adapter scaffold.
javascript/framework/react/src/index.ts Scaffolds React adapter entrypoint.
javascript/framework/react/README.md Adds React adapter README.
javascript/framework/react/package.json Adds React adapter manifest/scripts/deps.
javascript/framework/react/.gitignore Ignores React adapter build output.
javascript/framework/solid/tsconfig.json Adds TS config for the Solid adapter scaffold.
javascript/framework/solid/src/index.ts Scaffolds Solid adapter entrypoint.
javascript/framework/solid/README.md Adds Solid adapter README.
javascript/framework/solid/package.json Adds Solid adapter manifest/scripts/deps.
javascript/framework/solid/.gitignore Ignores Solid adapter build output.
javascript/framework/svelte/tsconfig.json Adds TS config for the Svelte adapter scaffold.
javascript/framework/svelte/src/index.ts Scaffolds Svelte adapter entrypoint.
javascript/framework/svelte/README.md Adds Svelte adapter README.
javascript/framework/svelte/package.json Adds Svelte adapter manifest/scripts/deps.
javascript/framework/svelte/.gitignore Ignores Svelte adapter build output.
javascript/framework/vue/tsconfig.json Adds TS config for the Vue adapter scaffold.
javascript/framework/vue/src/index.ts Scaffolds Vue adapter entrypoint.
javascript/framework/vue/README.md Adds Vue adapter README.
javascript/framework/vue/package.json Adds Vue adapter manifest/scripts/deps.
javascript/framework/vue/.gitignore Ignores Vue adapter build output.
javascript/starter/next/tsconfig.json Adds TS config for the Next starter scaffold.
javascript/starter/next/src/index.ts Scaffolds Next starter ID export.
javascript/starter/next/README.md Adds Next starter README.
javascript/starter/next/package.json Adds Next starter manifest/scripts/deps.
javascript/starter/next/.gitignore Ignores Next starter build output.
javascript/starter/nuxt/tsconfig.json Adds TS config for the Nuxt starter scaffold.
javascript/starter/nuxt/src/index.ts Scaffolds Nuxt starter ID export.
javascript/starter/nuxt/README.md Adds Nuxt starter README.
javascript/starter/nuxt/package.json Adds Nuxt starter manifest/scripts/deps.
javascript/starter/nuxt/.gitignore Ignores Nuxt starter build output.
javascript/starter/sveltekit/tsconfig.json Adds TS config for the SvelteKit starter scaffold.
javascript/starter/sveltekit/src/index.ts Scaffolds SvelteKit starter ID export.
javascript/starter/sveltekit/README.md Adds SvelteKit starter README.
javascript/starter/sveltekit/package.json Adds SvelteKit starter manifest/scripts/deps.
javascript/starter/sveltekit/.gitignore Ignores SvelteKit starter build output.
javascript/native/linux/x64/gnu/README.md Adds Linux x64 glibc native target scaffold README.
javascript/native/linux/x64/gnu/package.json Adds Linux x64 glibc native target package manifest.
javascript/native/linux/x64/gnu/manifest.json Adds Linux x64 glibc target metadata manifest.
javascript/native/linux/x64/musl/README.md Adds Linux x64 musl native target scaffold README.
javascript/native/linux/x64/musl/package.json Adds Linux x64 musl native target package manifest.
javascript/native/linux/x64/musl/manifest.json Adds Linux x64 musl target metadata manifest.
javascript/native/linux/arm64/gnu/README.md Adds Linux arm64 glibc native target scaffold README.
javascript/native/linux/arm64/gnu/package.json Adds Linux arm64 glibc native target package manifest.
javascript/native/linux/arm64/gnu/manifest.json Adds Linux arm64 glibc target metadata manifest.
javascript/native/linux/arm64/musl/README.md Adds Linux arm64 musl native target scaffold README.
javascript/native/linux/arm64/musl/package.json Adds Linux arm64 musl native target package manifest.
javascript/native/linux/arm64/musl/manifest.json Adds Linux arm64 musl target metadata manifest.
javascript/native/darwin/x64/README.md Adds macOS x64 native target scaffold README.
javascript/native/darwin/x64/package.json Adds macOS x64 native target package manifest.
javascript/native/darwin/x64/manifest.json Adds macOS x64 target metadata manifest.
javascript/native/darwin/arm64/README.md Adds macOS arm64 native target scaffold README.
javascript/native/darwin/arm64/package.json Adds macOS arm64 native target package manifest.
javascript/native/darwin/arm64/manifest.json Adds macOS arm64 target metadata manifest.
javascript/native/freebsd/x64/README.md Adds FreeBSD x64 native target scaffold README.
javascript/native/freebsd/x64/package.json Adds FreeBSD x64 native target package manifest.
javascript/native/freebsd/x64/manifest.json Adds FreeBSD x64 target metadata manifest.
javascript/native/freebsd/arm64/README.md Adds FreeBSD arm64 native target scaffold README.
javascript/native/freebsd/arm64/package.json Adds FreeBSD arm64 native target package manifest.
javascript/native/freebsd/arm64/manifest.json Adds FreeBSD arm64 target metadata manifest.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 3 to +12
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"paths": {
"@termisu/*": [
"./javascript/*/src/index.ts",
"./javascript/framework/*/src/index.ts",
"./javascript/starter/*/src/index.ts"
]
},
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

compilerOptions.paths is configured but baseUrl is not set. TypeScript requires baseUrl when using paths (otherwise the mapping is ignored or can error), so the workspace alias resolution for @termisu/* may not work during typecheck/build. Add a baseUrl (typically ".") or move these path mappings into per-package tsconfigs that already define one.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.base.json",
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

The extends path is incorrect for this nested package: ../../tsconfig.base.json resolves to javascript/tsconfig.base.json, which doesn't exist. This will break tsc -p for the framework package. Update the path to point to the repo root tsconfig (e.g. ../../../tsconfig.base.json).

Suggested change
"extends": "../../tsconfig.base.json",
"extends": "../../../tsconfig.base.json",

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +3
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

The extends path is incorrect for this nested package: ../../tsconfig.base.json resolves to javascript/tsconfig.base.json, which doesn't exist. This will break tsc -p for the framework package. Update the path to point to the repo root tsconfig (e.g. ../../../tsconfig.base.json).

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.base.json",
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

The extends path is incorrect for this nested package: ../../tsconfig.base.json resolves to javascript/tsconfig.base.json, which doesn't exist. This will break tsc -p for the framework package. Update the path to point to the repo root tsconfig (e.g. ../../../tsconfig.base.json).

Suggested change
"extends": "../../tsconfig.base.json",
"extends": "../../../tsconfig.base.json",

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.base.json",
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

The extends path is incorrect for this nested package: ../../tsconfig.base.json resolves to javascript/tsconfig.base.json, which doesn't exist. This will break tsc -p for the framework package. Update the path to point to the repo root tsconfig (e.g. ../../../tsconfig.base.json).

Suggested change
"extends": "../../tsconfig.base.json",
"extends": "../../../tsconfig.base.json",

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +22
export type PlatformTarget =
| "linux-x64-gnu"
| "linux-arm64-gnu"
| "linux-x64-musl"
| "linux-arm64-musl"
| "darwin-x64"
| "darwin-arm64"
| "freebsd-x64"
| "freebsd-arm64";

export const detectTarget = (): PlatformTarget | null => {
const platform = process.platform;
const arch = process.arch;

if (platform === "linux" && arch === "x64") return "linux-x64-gnu";
if (platform === "linux" && arch === "arm64") return "linux-arm64-gnu";
if (platform === "darwin" && arch === "x64") return "darwin-x64";
if (platform === "darwin" && arch === "arm64") return "darwin-arm64";
if (platform === "freebsd" && arch === "x64") return "freebsd-x64";
if (platform === "freebsd" && arch === "arm64") return "freebsd-arm64";

return null;
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

PlatformTarget includes linux-*-musl variants, but detectTarget() never returns them (Linux always maps to *-gnu). This makes the musl targets unreachable and can cause incorrect native package resolution on musl-based distros (e.g. Alpine). Either implement libc detection and return the appropriate *-musl target, or remove the musl variants until detection/path resolution is implemented.

Copilot uses AI. Check for mistakes.
Comment on lines +164 to +175
- [src/termisu/event/poller.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/poller.cr)
- [src/termisu/event/poller/linux.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/poller/linux.cr)
- [src/termisu/event/poller/kqueue.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/poller/kqueue.cr)
- [src/termisu/event/poller/poll.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/poller/poll.cr)
- [src/termisu/tty.cr](/home/omar/sandbox/crystal/termisu/src/termisu/tty.cr)
- [src/termisu/terminal/backend.cr](/home/omar/sandbox/crystal/termisu/src/termisu/terminal/backend.cr)
- [src/termisu/ffi/exports.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/exports.cr)
- [src/termisu/ffi/layout.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/layout.cr)
- [javascript/core/src/native.ts](/home/omar/sandbox/crystal/termisu/javascript/core/src/native.ts)
- [javascript/core/src/termisu.ts](/home/omar/sandbox/crystal/termisu/javascript/core/src/termisu.ts)
- [javascript/platform/src/index.ts](/home/omar/sandbox/crystal/termisu/javascript/platform/src/index.ts)
- [javascript/runtime/src/index.ts](/home/omar/sandbox/crystal/termisu/javascript/runtime/src/index.ts)
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

The “Source Anchors” section links to absolute local filesystem paths (e.g. /home/omar/sandbox/...), which won’t work for other contributors or in GitHub. Switch these links to repo-relative paths (e.g. /src/... or ../src/...) so the documentation remains portable.

Suggested change
- [src/termisu/event/poller.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/poller.cr)
- [src/termisu/event/poller/linux.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/poller/linux.cr)
- [src/termisu/event/poller/kqueue.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/poller/kqueue.cr)
- [src/termisu/event/poller/poll.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/poller/poll.cr)
- [src/termisu/tty.cr](/home/omar/sandbox/crystal/termisu/src/termisu/tty.cr)
- [src/termisu/terminal/backend.cr](/home/omar/sandbox/crystal/termisu/src/termisu/terminal/backend.cr)
- [src/termisu/ffi/exports.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/exports.cr)
- [src/termisu/ffi/layout.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/layout.cr)
- [javascript/core/src/native.ts](/home/omar/sandbox/crystal/termisu/javascript/core/src/native.ts)
- [javascript/core/src/termisu.ts](/home/omar/sandbox/crystal/termisu/javascript/core/src/termisu.ts)
- [javascript/platform/src/index.ts](/home/omar/sandbox/crystal/termisu/javascript/platform/src/index.ts)
- [javascript/runtime/src/index.ts](/home/omar/sandbox/crystal/termisu/javascript/runtime/src/index.ts)
- [src/termisu/event/poller.cr](/src/termisu/event/poller.cr)
- [src/termisu/event/poller/linux.cr](/src/termisu/event/poller/linux.cr)
- [src/termisu/event/poller/kqueue.cr](/src/termisu/event/poller/kqueue.cr)
- [src/termisu/event/poller/poll.cr](/src/termisu/event/poller/poll.cr)
- [src/termisu/tty.cr](/src/termisu/tty.cr)
- [src/termisu/terminal/backend.cr](/src/termisu/terminal/backend.cr)
- [src/termisu/ffi/exports.cr](/src/termisu/ffi/exports.cr)
- [src/termisu/ffi/layout.cr](/src/termisu/ffi/layout.cr)
- [javascript/core/src/native.ts](/javascript/core/src/native.ts)
- [javascript/core/src/termisu.ts](/javascript/core/src/termisu.ts)
- [javascript/platform/src/index.ts](/javascript/platform/src/index.ts)
- [javascript/runtime/src/index.ts](/javascript/runtime/src/index.ts)

Copilot uses AI. Check for mistakes.
Comment on lines +195 to +206
- [src/termisu/render_state.cr](/home/omar/sandbox/crystal/termisu/src/termisu/render_state.cr)
- [src/termisu/event/loop.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/loop.cr)
- [src/termisu/event/source/input.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/source/input.cr)
- [src/termisu/event/source/resize.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/source/resize.cr)
- [src/termisu/event/source/timer.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/source/timer.cr)
- [src/termisu/event/source/system_timer.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/source/system_timer.cr)
- [src/termisu/event/poller.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/poller.cr)
- [src/termisu/ffi/exports.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/exports.cr)
- [src/termisu/ffi/core.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/core.cr)
- [src/termisu/ffi/runtime.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/runtime.cr)
- [src/termisu/ffi/layout.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/layout.cr)
- [include/termisu/ffi.h](/home/omar/sandbox/crystal/termisu/include/termisu/ffi.h)
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

The “Source Anchors” section links to absolute local filesystem paths (e.g. /home/omar/sandbox/...), which won’t work for other contributors or in GitHub. Switch these links to repo-relative paths (e.g. /src/... or ../src/...) so the documentation remains portable.

Suggested change
- [src/termisu/render_state.cr](/home/omar/sandbox/crystal/termisu/src/termisu/render_state.cr)
- [src/termisu/event/loop.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/loop.cr)
- [src/termisu/event/source/input.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/source/input.cr)
- [src/termisu/event/source/resize.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/source/resize.cr)
- [src/termisu/event/source/timer.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/source/timer.cr)
- [src/termisu/event/source/system_timer.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/source/system_timer.cr)
- [src/termisu/event/poller.cr](/home/omar/sandbox/crystal/termisu/src/termisu/event/poller.cr)
- [src/termisu/ffi/exports.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/exports.cr)
- [src/termisu/ffi/core.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/core.cr)
- [src/termisu/ffi/runtime.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/runtime.cr)
- [src/termisu/ffi/layout.cr](/home/omar/sandbox/crystal/termisu/src/termisu/ffi/layout.cr)
- [include/termisu/ffi.h](/home/omar/sandbox/crystal/termisu/include/termisu/ffi.h)
- [src/termisu/render_state.cr](/src/termisu/render_state.cr)
- [src/termisu/event/loop.cr](/src/termisu/event/loop.cr)
- [src/termisu/event/source/input.cr](/src/termisu/event/source/input.cr)
- [src/termisu/event/source/resize.cr](/src/termisu/event/source/resize.cr)
- [src/termisu/event/source/timer.cr](/src/termisu/event/source/timer.cr)
- [src/termisu/event/source/system_timer.cr](/src/termisu/event/source/system_timer.cr)
- [src/termisu/event/poller.cr](/src/termisu/event/poller.cr)
- [src/termisu/ffi/exports.cr](/src/termisu/ffi/exports.cr)
- [src/termisu/ffi/core.cr](/src/termisu/ffi/core.cr)
- [src/termisu/ffi/runtime.cr](/src/termisu/ffi/runtime.cr)
- [src/termisu/ffi/layout.cr](/src/termisu/ffi/layout.cr)
- [include/termisu/ffi.h](/include/termisu/ffi.h)

Copilot uses AI. Check for mistakes.
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

🧹 Nitpick comments (1)
javascript/platform/src/index.ts (1)

42-60: Consider extracting a lookup table to reduce cognitive complexity.

SonarCloud flags cognitive complexity of 16 (allowed: 15). While the current logic is correct, extracting the platform/arch combinations into a lookup structure could reduce complexity and improve maintainability.

♻️ Optional refactor using lookup table
+const TARGET_MAP: Partial<Record<string, PlatformTarget | ((arch: NodeJS.Architecture) => PlatformTarget)>> = {
+  "linux-x64": (arch) => isLinuxMusl(arch) ? "linux-x64-musl" : "linux-x64-gnu",
+  "linux-arm64": (arch) => isLinuxMusl(arch) ? "linux-arm64-musl" : "linux-arm64-gnu",
+  "darwin-x64": "darwin-x64",
+  "darwin-arm64": "darwin-arm64",
+  "freebsd-x64": "freebsd-x64",
+  "freebsd-arm64": "freebsd-arm64",
+};
+
 export const detectTarget = (): PlatformTarget | null => {
   const platform = process.platform;
   const arch = process.arch;
-
-  if (platform === "linux" && arch === "x64") {
-    return isLinuxMusl(arch) ? "linux-x64-musl" : "linux-x64-gnu";
-  }
-
-  if (platform === "linux" && arch === "arm64") {
-    return isLinuxMusl(arch) ? "linux-arm64-musl" : "linux-arm64-gnu";
-  }
-
-  if (platform === "darwin" && arch === "x64") return "darwin-x64";
-  if (platform === "darwin" && arch === "arm64") return "darwin-arm64";
-  if (platform === "freebsd" && arch === "x64") return "freebsd-x64";
-  if (platform === "freebsd" && arch === "arm64") return "freebsd-arm64";
-
-  return null;
+  const key = `${platform}-${arch}`;
+  const entry = TARGET_MAP[key];
+  if (entry === undefined) return null;
+  return typeof entry === "function" ? entry(arch) : entry;
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@javascript/platform/src/index.ts` around lines 42 - 60, The detectTarget
function has elevated cognitive complexity from multiple conditional branches;
refactor it to use a lookup table mapping (process.platform, process.arch) keys
to PlatformTarget values and use isLinuxMusl only for linux entries that differ
by musl/gnu. Replace the cascading ifs in detectTarget with a concise map lookup
(e.g., a Map or object keyed by `${platform}:${arch}`) and handle linux-x64 and
linux-arm64 by calling isLinuxMusl(process.arch) to pick between "linux-*-musl"
and "linux-*-gnu", keeping the function signature and PlatformTarget type
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@javascript/core/src/native.ts`:
- Around line 104-125: resolveNativePackageLibraryPath currently calls
import.meta.resolve(`${packageName}/manifest`) which will throw if the optional
native package isn't installed; wrap that call in a try-catch inside
resolveNativePackageLibraryPath so a thrown error returns null (or continues to
the other candidate checks) instead of bubbling up. Specifically, around the
import.meta.resolve call for packageName (used with nativePackageByTarget and
detectTarget), catch any exception from import.meta.resolve and proceed to check
the remaining candidate paths or return null if nothing is found, ensuring
resolveNativePackageLibraryPath never throws when the optional dependency is
absent.

---

Nitpick comments:
In `@javascript/platform/src/index.ts`:
- Around line 42-60: The detectTarget function has elevated cognitive complexity
from multiple conditional branches; refactor it to use a lookup table mapping
(process.platform, process.arch) keys to PlatformTarget values and use
isLinuxMusl only for linux entries that differ by musl/gnu. Replace the
cascading ifs in detectTarget with a concise map lookup (e.g., a Map or object
keyed by `${platform}:${arch}`) and handle linux-x64 and linux-arm64 by calling
isLinuxMusl(process.arch) to pick between "linux-*-musl" and "linux-*-gnu",
keeping the function signature and PlatformTarget type unchanged.
🪄 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: 0803ff88-5094-479b-8137-3c630f1e6fc1

📥 Commits

Reviewing files that changed from the base of the PR and between 00337dd and c6530c2.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (11)
  • architecture/README.md
  • architecture/js-runtime-ffi-architecture.md
  • javascript/README.md
  • javascript/core/package.json
  • javascript/core/src/native.ts
  • javascript/core/tsconfig.json
  • javascript/platform/package.json
  • javascript/platform/src/index.ts
  • javascript/platform/tsconfig.json
  • package.json
  • tsconfig.base.json
✅ Files skipped from review due to trivial changes (5)
  • tsconfig.base.json
  • package.json
  • architecture/README.md
  • javascript/platform/tsconfig.json
  • javascript/platform/package.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • architecture/js-runtime-ffi-architecture.md

Copilot AI review requested due to automatic review settings April 2, 2026 20:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 38 out of 39 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 2 to +8
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"paths": {
"@termisu/*": ["./javascript/*/src/index.ts"]
},
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

compilerOptions.paths is configured, but baseUrl is not set. TypeScript only applies paths when baseUrl is defined, so these workspace aliases may be ignored. Set compilerOptions.baseUrl (typically ".") alongside paths so @termisu/* resolves consistently.

Copilot uses AI. Check for mistakes.
Comment on lines 140 to 160
@@ -119,7 +154,7 @@ function resolveLibraryPath(explicit?: string): string {
throw new Error(
[
"Could not locate Termisu native library.",
"Set TERMISU_LIB_PATH or pass { libraryPath }.",
"Install @termisu/core on a supported target, set TERMISU_LIB_PATH, or pass { libraryPath }.",
`Checked: ${candidates.join(", ")}`,
].join(" ")
);
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

The error message only lists the repository-local bin/ candidates, but resolveLibraryPath also checks platform-package candidates via resolveNativePackageLibraryPath(). When the native package isn't installed / doesn't contain artifacts, the thrown error won’t show what package/paths were attempted, which makes debugging installs harder. Include the detected target/package name and the package candidate paths (or the reason package resolution failed) in the thrown error details.

Copilot uses AI. Check for mistakes.
Comment on lines +5 to +13
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
}
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

@termisu/platform exports only ./dist/index.js, but dist/ is gitignored and the root js:build script builds only @termisu/core. If @termisu/core’s build/runtime resolves @termisu/platform via its package exports, this will fail unless @termisu/platform is built first. Consider either (a) adding a build step/dependency so platform is built before core, or (b) pointing workspace/dev resolution to src/index.ts (while keeping dist/ for published artifacts).

Copilot uses AI. Check for mistakes.

- `@termisu/core` already validates ABI and struct layout signature.
- `@termisu/platform` currently detects `os/arch` and maps to package names.
- `@termisu/core` currently resolves explicit paths, `TERMISU_LIB_PATH`, and
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

There’s a duplicated bullet in “Current Implementation Notes” (the @termisu/core resolution line appears twice, and one ends with “and” mid-sentence). Collapse this into a single bullet with proper line wrapping to avoid confusing readers.

Suggested change
- `@termisu/core` currently resolves explicit paths, `TERMISU_LIB_PATH`, and

Copilot uses AI. Check for mistakes.
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

🧹 Nitpick comments (3)
javascript/core/tests/native.test.ts (1)

46-61: Add coverage for the bin/ fallback inside native packages.

resolveNativePackageLibraryPath() now checks both ${packageDir}/libtermisu.${suffix} and ${packageDir}/bin/libtermisu.${suffix}, but this test only exercises the root candidate. A regression in the bin/ branch would currently pass unnoticed.

🧪 Suggested test case
   it("uses the resolved native package path when available", () => {
     const packageDir = "/tmp/termisu-native-package";
     const manifestUrl = pathToFileURL(`${packageDir}/manifest.json`).toString();
     const packageLibraryPath = resolve(`${packageDir}/libtermisu.${suffix}`);
@@
 
     expect(resolvedPath).toBe(packageLibraryPath);
   });
+
+  it("falls back to bin/libtermisu when the package root does not contain the library", () => {
+    const packageDir = "/tmp/termisu-native-package";
+    const manifestUrl = pathToFileURL(`${packageDir}/manifest.json`).toString();
+    const packageLibraryPath = resolve(`${packageDir}/bin/libtermisu.${suffix}`);
+
+    const resolvedPath = resolveLibraryPath(undefined, {
+      cwd: "/tmp/termisu-project",
+      detectTarget: () => "linux-x64-gnu",
+      env: {},
+      fileExists: (candidate) => candidate === packageLibraryPath,
+      moduleUrl: pathToFileURL("/tmp/termisu-project/javascript/core/src/native.ts").toString(),
+      resolveModule: () => manifestUrl,
+    });
+
+    expect(resolvedPath).toBe(packageLibraryPath);
+  });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@javascript/core/tests/native.test.ts` around lines 46 - 61, Add a new test
that asserts resolveLibraryPath (which calls resolveNativePackageLibraryPath)
falls back to the bin/ candidate: create a packageDir and set the expected
library path to `${packageDir}/bin/libtermisu.${suffix}`, make fileExists return
true only for that bin path (and false for the root lib path), call
resolveLibraryPath with the same inputs as the existing test, and assert the
resolvedPath equals the bin path so the bin/ branch in
resolveNativePackageLibraryPath is covered.
javascript/platform/src/index.ts (1)

52-56: Compute the libc probe once in detectLinuxTarget().

isLinuxMusl(arch) does the report lookup and may hit the filesystem. Calling it twice here repeats the same work for every detection with no change in outcome.

♻️ Proposed cleanup
 const detectLinuxTarget = (arch: NodeJS.Architecture): PlatformTarget | null => {
+  const musl = isLinuxMusl(arch);
   const linuxTargetByArch = {
-    arm64: isLinuxMusl(arch) ? "linux-arm64-musl" : "linux-arm64-gnu",
-    x64: isLinuxMusl(arch) ? "linux-x64-musl" : "linux-x64-gnu",
+    arm64: musl ? "linux-arm64-musl" : "linux-arm64-gnu",
+    x64: musl ? "linux-x64-musl" : "linux-x64-gnu",
   } as const satisfies Record<"arm64" | "x64", PlatformTarget>;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@javascript/platform/src/index.ts` around lines 52 - 56, detectLinuxTarget
calls isLinuxMusl(arch) twice causing redundant filesystem/report lookups;
compute the libc probe once and reuse it. Inside detectLinuxTarget, call
isLinuxMusl(arch) once (e.g., assign to a local musl variable) and then use that
variable when choosing between "linux-*-musl" and "linux-*-gnu" for the arm64
and x64 entries so you avoid duplicate work in the function.
javascript/core/src/native.ts (1)

148-156: Honor injected cwd for relative explicit and env paths.

The fallback probes use deps.cwd, but resolve(explicit) and resolve(envPath) still bind to the process cwd. That makes the seam partial and keeps relative-path behavior dependent on how the caller or test was launched.

♻️ Proposed cleanup
 export function resolveLibraryPath(explicit?: string, deps: NativeResolutionDeps = {}): string {
   const env = deps.env ?? process.env;
   const cwd = deps.cwd ?? process.cwd();
   const fileExists = deps.fileExists ?? existsSync;
 
-  if (explicit) return resolve(explicit);
+  if (explicit) return resolve(cwd, explicit);
 
   const envPath = env.TERMISU_LIB_PATH;
-  if (envPath) return resolve(envPath);
+  if (envPath) return resolve(cwd, envPath);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@javascript/core/src/native.ts` around lines 148 - 156, resolveLibraryPath
currently calls resolve(explicit) and resolve(envPath) which use the process
cwd; change this to honor deps.cwd by checking if the provided explicit or
envPath is absolute (use path.isAbsolute) and if not, resolve it against the
injected cwd (the variable cwd from deps.cwd ?? process.cwd()) so relative paths
are evaluated against deps.cwd; update the resolve calls in resolveLibraryPath
for both explicit and env.TERMISU_LIB_PATH branches to use resolve(cwd, ...)
when not absolute.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@architecture/core-architecture.md`:
- Line 99: Define the acronyms on first use: update the occurrence of "BSU"
(seen in the diagram label "Emit BSU") to include its full form in parentheses,
e.g. "BSU (Begin Synchronized Update)", and similarly update the first
occurrence of "ESU" to "ESU (End Synchronized Update)"; alternatively add a
short clarifying sentence before the "Notes:" section that explicitly defines
both BSU and ESU and references their meaning in the sync_updates context so
readers don't have to infer the acronyms.

---

Nitpick comments:
In `@javascript/core/src/native.ts`:
- Around line 148-156: resolveLibraryPath currently calls resolve(explicit) and
resolve(envPath) which use the process cwd; change this to honor deps.cwd by
checking if the provided explicit or envPath is absolute (use path.isAbsolute)
and if not, resolve it against the injected cwd (the variable cwd from deps.cwd
?? process.cwd()) so relative paths are evaluated against deps.cwd; update the
resolve calls in resolveLibraryPath for both explicit and env.TERMISU_LIB_PATH
branches to use resolve(cwd, ...) when not absolute.

In `@javascript/core/tests/native.test.ts`:
- Around line 46-61: Add a new test that asserts resolveLibraryPath (which calls
resolveNativePackageLibraryPath) falls back to the bin/ candidate: create a
packageDir and set the expected library path to
`${packageDir}/bin/libtermisu.${suffix}`, make fileExists return true only for
that bin path (and false for the root lib path), call resolveLibraryPath with
the same inputs as the existing test, and assert the resolvedPath equals the bin
path so the bin/ branch in resolveNativePackageLibraryPath is covered.

In `@javascript/platform/src/index.ts`:
- Around line 52-56: detectLinuxTarget calls isLinuxMusl(arch) twice causing
redundant filesystem/report lookups; compute the libc probe once and reuse it.
Inside detectLinuxTarget, call isLinuxMusl(arch) once (e.g., assign to a local
musl variable) and then use that variable when choosing between "linux-*-musl"
and "linux-*-gnu" for the arm64 and x64 entries so you avoid duplicate work in
the function.
🪄 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: d36eccff-3b59-43d4-b153-aede2da8a330

📥 Commits

Reviewing files that changed from the base of the PR and between c6530c2 and c4de765.

📒 Files selected for processing (20)
  • architecture/core-architecture.md
  • javascript/core/src/native.ts
  • javascript/core/tests/native.test.ts
  • javascript/native/darwin/arm64/README.md
  • javascript/native/darwin/arm64/package.json
  • javascript/native/darwin/x64/README.md
  • javascript/native/darwin/x64/package.json
  • javascript/native/freebsd/arm64/README.md
  • javascript/native/freebsd/arm64/package.json
  • javascript/native/freebsd/x64/README.md
  • javascript/native/freebsd/x64/package.json
  • javascript/native/linux/arm64/gnu/README.md
  • javascript/native/linux/arm64/gnu/package.json
  • javascript/native/linux/arm64/musl/README.md
  • javascript/native/linux/arm64/musl/package.json
  • javascript/native/linux/x64/gnu/README.md
  • javascript/native/linux/x64/gnu/package.json
  • javascript/native/linux/x64/musl/README.md
  • javascript/native/linux/x64/musl/package.json
  • javascript/platform/src/index.ts
✅ Files skipped from review due to trivial changes (16)
  • javascript/native/freebsd/x64/README.md
  • javascript/native/darwin/arm64/README.md
  • javascript/native/freebsd/x64/package.json
  • javascript/native/darwin/x64/README.md
  • javascript/native/linux/arm64/gnu/README.md
  • javascript/native/linux/arm64/musl/README.md
  • javascript/native/freebsd/arm64/README.md
  • javascript/native/linux/x64/gnu/README.md
  • javascript/native/linux/x64/musl/README.md
  • javascript/native/darwin/x64/package.json
  • javascript/native/linux/x64/musl/package.json
  • javascript/native/linux/x64/gnu/package.json
  • javascript/native/freebsd/arm64/package.json
  • javascript/native/darwin/arm64/package.json
  • javascript/native/linux/arm64/gnu/package.json
  • javascript/native/linux/arm64/musl/package.json

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.

🧹 Nitpick comments (1)
javascript/core/tests/native.test.ts (1)

63-83: Consider consolidating duplicate error assertions.

The two expect().toThrow() calls invoke resolveLibraryPath with identical arguments. Consolidating into a single call with multiple assertions on the error message would be slightly cleaner.

♻️ Optional consolidation
   it("raises an actionable error when no library path can be found", () => {
-    expect(() =>
-      resolveLibraryPath(undefined, {
-        cwd: "/tmp/termisu-project",
-        detectTarget: () => null,
-        env: {},
-        fileExists: () => false,
-        moduleUrl: pathToFileURL("/tmp/termisu-project/javascript/core/src/native.ts").toString(),
-      })
-    ).toThrow(/Could not locate Termisu native library/);
-
-    expect(() =>
-      resolveLibraryPath(undefined, {
-        cwd: "/tmp/termisu-project",
-        detectTarget: () => null,
-        env: {},
-        fileExists: () => false,
-        moduleUrl: pathToFileURL("/tmp/termisu-project/javascript/core/src/native.ts").toString(),
-      })
-    ).toThrow(/TERMISU_LIB_PATH/);
+    let error: Error | undefined;
+    try {
+      resolveLibraryPath(undefined, {
+        cwd: "/tmp/termisu-project",
+        detectTarget: () => null,
+        env: {},
+        fileExists: () => false,
+        moduleUrl: pathToFileURL("/tmp/termisu-project/javascript/core/src/native.ts").toString(),
+      });
+    } catch (e) {
+      error = e as Error;
+    }
+
+    expect(error).toBeDefined();
+    expect(error?.message).toMatch(/Could not locate Termisu native library/);
+    expect(error?.message).toMatch(/TERMISU_LIB_PATH/);
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@javascript/core/tests/native.test.ts` around lines 63 - 83, The test calls
resolveLibraryPath(...) twice with identical args; capture the thrown error once
and assert both message patterns against it to avoid duplication. Replace the
two expect(...toThrow()) calls with a single try/catch (or use expect(() =>
...).toThrowErrorMatchingSnapshot()) pattern that calls resolveLibraryPath,
assigns the caught Error to a variable, then assert the error.message contains
/Could not locate Termisu native library/ and /TERMISU_LIB_PATH/; reference
resolveLibraryPath and the test case in native.test.ts when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@javascript/core/tests/native.test.ts`:
- Around line 63-83: The test calls resolveLibraryPath(...) twice with identical
args; capture the thrown error once and assert both message patterns against it
to avoid duplication. Replace the two expect(...toThrow()) calls with a single
try/catch (or use expect(() => ...).toThrowErrorMatchingSnapshot()) pattern that
calls resolveLibraryPath, assigns the caught Error to a variable, then assert
the error.message contains /Could not locate Termisu native library/ and
/TERMISU_LIB_PATH/; reference resolveLibraryPath and the test case in
native.test.ts when making the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1157d2bd-db6c-4463-ada5-62423673bc40

📥 Commits

Reviewing files that changed from the base of the PR and between c6530c2 and c4de765.

📒 Files selected for processing (20)
  • architecture/core-architecture.md
  • javascript/core/src/native.ts
  • javascript/core/tests/native.test.ts
  • javascript/native/darwin/arm64/README.md
  • javascript/native/darwin/arm64/package.json
  • javascript/native/darwin/x64/README.md
  • javascript/native/darwin/x64/package.json
  • javascript/native/freebsd/arm64/README.md
  • javascript/native/freebsd/arm64/package.json
  • javascript/native/freebsd/x64/README.md
  • javascript/native/freebsd/x64/package.json
  • javascript/native/linux/arm64/gnu/README.md
  • javascript/native/linux/arm64/gnu/package.json
  • javascript/native/linux/arm64/musl/README.md
  • javascript/native/linux/arm64/musl/package.json
  • javascript/native/linux/x64/gnu/README.md
  • javascript/native/linux/x64/gnu/package.json
  • javascript/native/linux/x64/musl/README.md
  • javascript/native/linux/x64/musl/package.json
  • javascript/platform/src/index.ts
✅ Files skipped from review due to trivial changes (15)
  • javascript/native/darwin/arm64/README.md
  • javascript/native/freebsd/arm64/README.md
  • javascript/native/freebsd/x64/README.md
  • javascript/native/linux/arm64/gnu/README.md
  • javascript/native/linux/x64/musl/README.md
  • javascript/native/linux/x64/gnu/README.md
  • javascript/native/linux/arm64/musl/README.md
  • javascript/native/linux/arm64/gnu/package.json
  • javascript/native/darwin/x64/package.json
  • javascript/native/freebsd/x64/package.json
  • javascript/native/linux/x64/gnu/package.json
  • javascript/native/darwin/arm64/package.json
  • javascript/native/linux/x64/musl/package.json
  • javascript/native/linux/arm64/musl/package.json
  • javascript/native/freebsd/arm64/package.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • javascript/native/darwin/x64/README.md

Copilot AI review requested due to automatic review settings April 5, 2026 22:38
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 5, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
3 Security Hotspots
7.1% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

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.

🧹 Nitpick comments (1)
javascript/core/tests/native.test.ts (1)

46-80: Remove duplicated test case to keep the suite lean.

Line 46–62 and Line 64–80 currently validate the same behavior with equivalent setup and assertion. Keeping one avoids redundant maintenance.

♻️ Suggested cleanup
-  it("uses the resolved native package path when available", () => {
-    const packageDir = "/tmp/termisu-native-package";
-    const manifestUrl = pathToFileURL(`${packageDir}/manifest.json`).toString();
-    const packageLibraryPath = resolve(`${packageDir}/libtermisu.${suffix}`);
-
-    const resolvedPath = resolveLibraryPath(undefined, {
-      cwd: "/tmp/termisu-project",
-      detectTarget: () => "linux-x64-gnu",
-      env: {},
-      fileExists: (candidate) => candidate === packageLibraryPath,
-      moduleUrl: pathToFileURL("/tmp/termisu-project/javascript/core/src/native.ts").toString(),
-      readFile: () => JSON.stringify({ library: `libtermisu.${suffix}` }),
-      resolveModule: () => manifestUrl,
-    });
-
-    expect(resolvedPath).toBe(packageLibraryPath);
-  });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@javascript/core/tests/native.test.ts` around lines 46 - 80, Two identical
test cases are present that both call resolveLibraryPath with the same setup and
assertion; remove one of the duplicated it blocks (either the "uses the resolved
native package path when available" or the "uses the manifest-declared library
path when the package is installed") so the suite only contains a single test
covering this behavior, ensuring references to resolveLibraryPath, packageDir,
manifestUrl, packageLibraryPath, and the same mock options are preserved in the
remaining test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@javascript/core/tests/native.test.ts`:
- Around line 46-80: Two identical test cases are present that both call
resolveLibraryPath with the same setup and assertion; remove one of the
duplicated it blocks (either the "uses the resolved native package path when
available" or the "uses the manifest-declared library path when the package is
installed") so the suite only contains a single test covering this behavior,
ensuring references to resolveLibraryPath, packageDir, manifestUrl,
packageLibraryPath, and the same mock options are preserved in the remaining
test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 27dc6131-ac74-492b-bb70-183077a706a9

📥 Commits

Reviewing files that changed from the base of the PR and between c6530c2 and 43ef846.

📒 Files selected for processing (32)
  • architecture/core-architecture.md
  • architecture/js-runtime-ffi-architecture.md
  • javascript/README.md
  • javascript/core/package.json
  • javascript/core/src/native.ts
  • javascript/core/src/platform.ts
  • javascript/core/tests/native.test.ts
  • javascript/core/tsconfig.json
  • javascript/native/darwin/arm64/README.md
  • javascript/native/darwin/arm64/manifest.json
  • javascript/native/darwin/arm64/package.json
  • javascript/native/darwin/x64/README.md
  • javascript/native/darwin/x64/manifest.json
  • javascript/native/darwin/x64/package.json
  • javascript/native/freebsd/arm64/README.md
  • javascript/native/freebsd/arm64/manifest.json
  • javascript/native/freebsd/arm64/package.json
  • javascript/native/freebsd/x64/README.md
  • javascript/native/freebsd/x64/manifest.json
  • javascript/native/freebsd/x64/package.json
  • javascript/native/linux/arm64/gnu/README.md
  • javascript/native/linux/arm64/gnu/manifest.json
  • javascript/native/linux/arm64/gnu/package.json
  • javascript/native/linux/arm64/musl/README.md
  • javascript/native/linux/arm64/musl/manifest.json
  • javascript/native/linux/arm64/musl/package.json
  • javascript/native/linux/x64/gnu/README.md
  • javascript/native/linux/x64/gnu/manifest.json
  • javascript/native/linux/x64/gnu/package.json
  • javascript/native/linux/x64/musl/README.md
  • javascript/native/linux/x64/musl/manifest.json
  • javascript/native/linux/x64/musl/package.json
✅ Files skipped from review due to trivial changes (26)
  • javascript/core/tsconfig.json
  • javascript/native/linux/x64/musl/README.md
  • javascript/native/linux/arm64/gnu/README.md
  • javascript/native/darwin/arm64/README.md
  • javascript/native/linux/arm64/musl/README.md
  • javascript/native/freebsd/arm64/README.md
  • javascript/native/darwin/x64/README.md
  • javascript/native/linux/x64/gnu/README.md
  • javascript/native/darwin/arm64/manifest.json
  • javascript/native/linux/x64/gnu/manifest.json
  • javascript/native/freebsd/arm64/manifest.json
  • javascript/native/freebsd/x64/README.md
  • javascript/native/linux/x64/musl/manifest.json
  • javascript/native/freebsd/x64/package.json
  • javascript/native/linux/x64/gnu/package.json
  • javascript/native/linux/arm64/gnu/manifest.json
  • javascript/native/freebsd/x64/manifest.json
  • javascript/native/linux/arm64/musl/manifest.json
  • javascript/native/darwin/x64/manifest.json
  • javascript/native/darwin/x64/package.json
  • javascript/native/linux/x64/musl/package.json
  • javascript/native/linux/arm64/gnu/package.json
  • javascript/native/darwin/arm64/package.json
  • javascript/native/linux/arm64/musl/package.json
  • javascript/core/package.json
  • architecture/js-runtime-ffi-architecture.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • javascript/core/src/native.ts
  • javascript/native/freebsd/arm64/package.json

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 36 out of 37 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +35 to +42
"@termisu/native-darwin-arm64": "workspace:*",
"@termisu/native-darwin-x64": "workspace:*",
"@termisu/native-freebsd-arm64": "workspace:*",
"@termisu/native-freebsd-x64": "workspace:*",
"@termisu/native-linux-arm64-gnu": "workspace:*",
"@termisu/native-linux-arm64-musl": "workspace:*",
"@termisu/native-linux-x64-gnu": "workspace:*",
"@termisu/native-linux-x64-musl": "workspace:*"
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

optionalDependencies uses the workspace:* protocol. Since @termisu/core is published via .github/workflows/publish-core.yml (npm publish), consumers installing from npm will not be able to resolve workspace:*. Replace these entries with real semver ranges (e.g. the same version as @termisu/core), or add a publish-time step that rewrites workspace:* to published versions before publishing.

Suggested change
"@termisu/native-darwin-arm64": "workspace:*",
"@termisu/native-darwin-x64": "workspace:*",
"@termisu/native-freebsd-arm64": "workspace:*",
"@termisu/native-freebsd-x64": "workspace:*",
"@termisu/native-linux-arm64-gnu": "workspace:*",
"@termisu/native-linux-arm64-musl": "workspace:*",
"@termisu/native-linux-x64-gnu": "workspace:*",
"@termisu/native-linux-x64-musl": "workspace:*"
"@termisu/native-darwin-arm64": "0.0.0",
"@termisu/native-darwin-x64": "0.0.0",
"@termisu/native-freebsd-arm64": "0.0.0",
"@termisu/native-freebsd-x64": "0.0.0",
"@termisu/native-linux-arm64-gnu": "0.0.0",
"@termisu/native-linux-arm64-musl": "0.0.0",
"@termisu/native-linux-x64-gnu": "0.0.0",
"@termisu/native-linux-x64-musl": "0.0.0"

Copilot uses AI. Check for mistakes.
Comment on lines 6 to 11
"workspaces": [
"javascript/core",
"javascript/*",
"javascript/native/*/*",
"javascript/native/*/*/*",
"e2e"
],
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

The workspace glob javascript/* currently includes javascript/platform, but that directory has no package.json (it only contains .gitignore). However bun.lock now records a javascript/platform workspace (@termisu/platform). Either add the missing javascript/platform/package.json (and sources) or remove/adjust the workspace globs and regenerate bun.lock so the lockfile matches the actual workspace layout.

Copilot uses AI. Check for mistakes.
Comment on lines +138 to +142
const packageDir = dirname(fileURLToPath(manifestPath));
let manifest: NativePackageManifest;

try {
manifest = JSON.parse(readFile(fileURLToPath(manifestPath))) as NativePackageManifest;
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

resolveNativePackageLibraryPath assumes resolveModule() returns a file: URL (it passes the result to fileURLToPath). But the injected deps.resolveModule is typed as returning string and could reasonably return an absolute filesystem path; in that case fileURLToPath will throw and the function will incorrectly return null (or skip resolution). Consider normalizing with manifestFsPath = manifestPath.startsWith('file:') ? fileURLToPath(manifestPath) : manifestPath (and using it for both packageDir and readFile), or explicitly documenting/enforcing that resolveModule must return a file: URL.

Suggested change
const packageDir = dirname(fileURLToPath(manifestPath));
let manifest: NativePackageManifest;
try {
manifest = JSON.parse(readFile(fileURLToPath(manifestPath))) as NativePackageManifest;
const manifestFsPath = manifestPath.startsWith("file:")
? fileURLToPath(manifestPath)
: manifestPath;
const packageDir = dirname(manifestFsPath);
let manifest: NativePackageManifest;
try {
manifest = JSON.parse(readFile(manifestFsPath)) as NativePackageManifest;

Copilot uses AI. Check for mistakes.
Comment on lines +64 to +81
it("uses the manifest-declared library path when the package is installed", () => {
const packageDir = "/tmp/termisu-native-package";
const manifestUrl = pathToFileURL(`${packageDir}/manifest.json`).toString();
const packageLibraryPath = resolve(`${packageDir}/libtermisu.${suffix}`);

const resolvedPath = resolveLibraryPath(undefined, {
cwd: "/tmp/termisu-project",
detectTarget: () => "linux-x64-gnu",
env: {},
fileExists: (candidate) => candidate === packageLibraryPath,
moduleUrl: pathToFileURL("/tmp/termisu-project/javascript/core/src/native.ts").toString(),
readFile: () => JSON.stringify({ library: `libtermisu.${suffix}` }),
resolveModule: () => manifestUrl,
});

expect(resolvedPath).toBe(packageLibraryPath);
});

Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

This test case duplicates the previous "uses the resolved native package path when available" test (same setup + assertions). Consider removing one of them or changing one to cover a distinct behavior (e.g. resolution fallback when the manifest-declared library is missing).

Suggested change
it("uses the manifest-declared library path when the package is installed", () => {
const packageDir = "/tmp/termisu-native-package";
const manifestUrl = pathToFileURL(`${packageDir}/manifest.json`).toString();
const packageLibraryPath = resolve(`${packageDir}/libtermisu.${suffix}`);
const resolvedPath = resolveLibraryPath(undefined, {
cwd: "/tmp/termisu-project",
detectTarget: () => "linux-x64-gnu",
env: {},
fileExists: (candidate) => candidate === packageLibraryPath,
moduleUrl: pathToFileURL("/tmp/termisu-project/javascript/core/src/native.ts").toString(),
readFile: () => JSON.stringify({ library: `libtermisu.${suffix}` }),
resolveModule: () => manifestUrl,
});
expect(resolvedPath).toBe(packageLibraryPath);
});

Copilot uses AI. Check for mistakes.
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