mirror of
https://github.com/different-ai/openwork
synced 2026-04-25 17:15:34 +02:00
fix(headless): align openwrk TUI compile path with OpenTUI + branch CI (#536)
* fix(headless): align openwrk compile path with OpenTUI Solid Use the upstream @opentui/solid build plugin and preload/tsconfig wiring so compiled openwrk binaries keep TUI runtime compatibility instead of emitting broken React runtime behavior. * ci: run openwrk checks on feature branch pushes Trigger CI for fix/openwrk-react-shim and add an openwrk binary build job so bundling regressions are caught before merging to dev. * ci: relax binary validation to runtime smoke Use openwrk --version/--help checks instead of grepping embedded strings so the branch CI validates bundling without false failures from defensive error text. * fix(desktop): build openwrk sidecar via headless build script Route desktop sidecar preparation through packages/headless/script/build.ts so OpenTUI plugin settings are applied consistently and Linux CI no longer compiles openwrk with incompatible JSX defaults.
This commit is contained in:
3
.github/workflows/ci-tests.yml
vendored
3
.github/workflows/ci-tests.yml
vendored
@@ -2,9 +2,12 @@ name: OpenWork Tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- dev
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- fix/openwrk-react-shim
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
41
.github/workflows/ci.yml
vendored
41
.github/workflows/ci.yml
vendored
@@ -4,6 +4,10 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- fix/openwrk-react-shim
|
||||
pull_request:
|
||||
branches:
|
||||
- dev
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -32,3 +36,40 @@ jobs:
|
||||
|
||||
- name: Build web
|
||||
run: pnpm --filter @different-ai/openwork build:web
|
||||
|
||||
build-openwrk-binary:
|
||||
name: Build openwrk binary
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10.27.0
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v1
|
||||
with:
|
||||
bun-version: 1.3.9
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Typecheck openwrk
|
||||
run: pnpm --filter openwrk typecheck
|
||||
|
||||
- name: Build openwrk binary
|
||||
run: pnpm --filter openwrk build:bin
|
||||
|
||||
- name: Validate compiled binary
|
||||
run: |
|
||||
./packages/headless/dist/bin/openwrk --version
|
||||
./packages/headless/dist/bin/openwrk --help >/dev/null
|
||||
|
||||
@@ -567,28 +567,17 @@ if (shouldBuildOpenwrk) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
// openwrk uses bun build --compile directly
|
||||
const openwrkCliPath = resolve(openwrkDir, "src", "cli.ts");
|
||||
if (!existsSync(openwrkCliPath)) {
|
||||
console.error(`Openwrk CLI source not found at ${openwrkCliPath}`);
|
||||
const openwrkBuildScript = resolveBuildScript(openwrkDir);
|
||||
if (!existsSync(openwrkBuildScript)) {
|
||||
console.error(`Openwrk build script not found at ${openwrkBuildScript}`);
|
||||
process.exit(1);
|
||||
}
|
||||
const openwrkVersionForDefine = (() => {
|
||||
try {
|
||||
const raw = readFileSync(resolve(openwrkDir, "package.json"), "utf8");
|
||||
return String(JSON.parse(raw).version ?? "").trim();
|
||||
} catch {
|
||||
return "";
|
||||
}
|
||||
})();
|
||||
const openwrkArgs = [
|
||||
"build",
|
||||
"--compile",
|
||||
openwrkCliPath,
|
||||
"--define",
|
||||
`__OPENWRK_VERSION__=\"${openwrkVersionForDefine}\"`,
|
||||
"--outfile",
|
||||
openwrkBuildPath,
|
||||
openwrkBuildScript,
|
||||
"--outdir",
|
||||
sidecarDir,
|
||||
"--filename",
|
||||
"openwrk",
|
||||
];
|
||||
if (bunTarget) {
|
||||
openwrkArgs.push("--target", bunTarget);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"build": "tsc -p tsconfig.json",
|
||||
"build:bin": "node scripts/clean-dist.mjs && bun ./script/build.ts --outdir dist/bin --filename openwrk",
|
||||
"build:bin:all": "node scripts/clean-dist.mjs && bun ./script/build.ts --outdir dist/bin --filename openwrk --target bun-darwin-arm64 --target bun-darwin-x64 --target bun-linux-x64 --target bun-linux-arm64 --target bun-windows-x64",
|
||||
"build:bin:bundled": "node scripts/clean-dist.mjs && node ../desktop/scripts/prepare-sidecar.mjs --outdir dist && bun build --compile src/cli.ts --plugin ./script/opentui-solid-plugin.mjs --define __OPENWRK_VERSION__=\\\"$npm_package_version\\\" --outfile dist/openwrk && bun scripts/build-bin.ts",
|
||||
"build:bin:bundled": "node scripts/clean-dist.mjs && node ../desktop/scripts/prepare-sidecar.mjs --outdir dist && bun ./script/build.ts --outdir dist --filename openwrk && bun scripts/build-bin.ts",
|
||||
"build:sidecars": "node scripts/build-sidecars.mjs",
|
||||
"typecheck": "tsc -p tsconfig.typecheck.json",
|
||||
"test:router": "pnpm build && node scripts/router.mjs",
|
||||
@@ -51,15 +51,12 @@
|
||||
"solid-js": "1.9.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.28.6",
|
||||
"@babel/preset-typescript": "7.28.5",
|
||||
"@opentui/core-darwin-arm64": "0.1.77",
|
||||
"@opentui/core-darwin-x64": "0.1.77",
|
||||
"@opentui/core-linux-arm64": "0.1.77",
|
||||
"@opentui/core-linux-x64": "0.1.77",
|
||||
"@opentui/core-win32-x64": "0.1.77",
|
||||
"@types/node": "^22.10.2",
|
||||
"babel-preset-solid": "1.9.9",
|
||||
"bun-types": "^1.3.6",
|
||||
"typescript": "^5.6.3"
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { mkdirSync, readFileSync } from "node:fs";
|
||||
import { join, resolve } from "node:path";
|
||||
import solidPlugin from "../node_modules/@opentui/solid/scripts/solid-plugin";
|
||||
|
||||
const bunRuntime = (globalThis as typeof globalThis & {
|
||||
Bun?: {
|
||||
@@ -88,29 +88,41 @@ function outputName(filename: string, target?: string) {
|
||||
return `${filename}${suffix}${ext}`;
|
||||
}
|
||||
|
||||
function defaultTarget(): string {
|
||||
const os = process.platform === "win32" ? "windows" : process.platform;
|
||||
return `bun-${os}-${process.arch}`;
|
||||
}
|
||||
|
||||
async function buildOnce(entrypoint: string, outdir: string, filename: string, target?: string) {
|
||||
mkdirSync(outdir, { recursive: true });
|
||||
const outfile = join(outdir, outputName(filename, target));
|
||||
const solidPluginPath = resolve("script", "opentui-solid-plugin.mjs");
|
||||
|
||||
const args = ["build", entrypoint, "--compile", "--plugin", solidPluginPath, "--outfile", outfile];
|
||||
const define: Record<string, string> = {};
|
||||
const pkgPath = resolve("package.json");
|
||||
try {
|
||||
const pkg = JSON.parse(readFileSync(pkgPath, "utf8")) as { version?: string };
|
||||
if (typeof pkg.version === "string" && pkg.version.trim()) {
|
||||
args.push("--define", `__OPENWRK_VERSION__=\"${pkg.version.trim()}\"`);
|
||||
define.__OPENWRK_VERSION__ = `\"${pkg.version.trim()}\"`;
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (target) {
|
||||
args.push("--target", target);
|
||||
}
|
||||
|
||||
const result = spawnSync("bun", args, { stdio: "inherit" });
|
||||
if (result.status !== 0) {
|
||||
process.exit(result.status ?? 1);
|
||||
const resolvedTarget = target ?? defaultTarget();
|
||||
const result = await bun.build({
|
||||
tsconfig: "./tsconfig.json",
|
||||
plugins: [solidPlugin],
|
||||
entrypoints: [entrypoint],
|
||||
define,
|
||||
compile: {
|
||||
target: resolvedTarget,
|
||||
outfile,
|
||||
},
|
||||
});
|
||||
if (!result.success) {
|
||||
for (const log of result.logs) {
|
||||
console.error(log);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
import { transformAsync } from "@babel/core";
|
||||
import ts from "@babel/preset-typescript";
|
||||
import solid from "babel-preset-solid";
|
||||
|
||||
const openTuiSolidPlugin = {
|
||||
name: "openwrk-opentui-solid",
|
||||
setup(build) {
|
||||
build.onLoad({ filter: /\/node_modules\/solid-js\/dist\/server\.js$/ }, async (args) => {
|
||||
const path = args.path.replace("server.js", "solid.js");
|
||||
const file = Bun.file(path);
|
||||
const code = await file.text();
|
||||
return { contents: code, loader: "js" };
|
||||
});
|
||||
|
||||
build.onLoad({ filter: /\/node_modules\/solid-js\/store\/dist\/server\.js$/ }, async (args) => {
|
||||
const path = args.path.replace("server.js", "store.js");
|
||||
const file = Bun.file(path);
|
||||
const code = await file.text();
|
||||
return { contents: code, loader: "js" };
|
||||
});
|
||||
|
||||
build.onLoad({ filter: /\.(js|ts)x$/ }, async (args) => {
|
||||
const file = Bun.file(args.path);
|
||||
const code = await file.text();
|
||||
const transformed = await transformAsync(code, {
|
||||
filename: args.path,
|
||||
presets: [
|
||||
[
|
||||
solid,
|
||||
{
|
||||
moduleName: "@opentui/solid",
|
||||
generate: "universal",
|
||||
},
|
||||
],
|
||||
[ts],
|
||||
],
|
||||
});
|
||||
return {
|
||||
contents: transformed?.code ?? "",
|
||||
loader: "js",
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default openTuiSolidPlugin;
|
||||
@@ -1,17 +1,8 @@
|
||||
import { RGBA, TextAttributes, type InputRenderable, type KeyEvent, type TabSelectRenderable } from "@opentui/core";
|
||||
import {
|
||||
createElement as openTuiCreateElement,
|
||||
render,
|
||||
useKeyboard,
|
||||
useRenderer,
|
||||
useSelectionHandler,
|
||||
useTerminalDimensions,
|
||||
} from "@opentui/solid";
|
||||
import { render, useKeyboard, useRenderer, useSelectionHandler, useTerminalDimensions } from "@opentui/solid";
|
||||
import { For, Show, createEffect, createMemo, createSignal, onCleanup } from "solid-js";
|
||||
import { createStore } from "solid-js/store";
|
||||
|
||||
const React = { createElement: openTuiCreateElement };
|
||||
|
||||
export type TuiLogLevel = "debug" | "info" | "warn" | "error";
|
||||
|
||||
export type TuiServiceStatus = "starting" | "running" | "healthy" | "stopped" | "disabled" | "error";
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"jsx": "preserve",
|
||||
"jsxImportSource": "solid-js",
|
||||
"jsxImportSource": "@opentui/solid",
|
||||
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
|
||||
79
pnpm-lock.yaml
generated
79
pnpm-lock.yaml
generated
@@ -119,12 +119,6 @@ importers:
|
||||
specifier: 1.9.9
|
||||
version: 1.9.9
|
||||
devDependencies:
|
||||
'@babel/core':
|
||||
specifier: 7.28.6
|
||||
version: 7.28.6
|
||||
'@babel/preset-typescript':
|
||||
specifier: 7.28.5
|
||||
version: 7.28.5(@babel/core@7.28.6)
|
||||
'@opentui/core-darwin-arm64':
|
||||
specifier: 0.1.77
|
||||
version: 0.1.77
|
||||
@@ -143,9 +137,6 @@ importers:
|
||||
'@types/node':
|
||||
specifier: ^22.10.2
|
||||
version: 22.19.7
|
||||
babel-preset-solid:
|
||||
specifier: 1.9.9
|
||||
version: 1.9.9(@babel/core@7.28.6)(solid-js@1.9.9)
|
||||
bun-types:
|
||||
specifier: ^1.3.6
|
||||
version: 1.3.6
|
||||
@@ -381,12 +372,6 @@ packages:
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/preset-typescript@7.28.5':
|
||||
resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/template@7.28.6':
|
||||
resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -2636,19 +2621,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.28.6)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.6
|
||||
'@babel/helper-annotate-as-pure': 7.27.3
|
||||
'@babel/helper-member-expression-to-functions': 7.28.5
|
||||
'@babel/helper-optimise-call-expression': 7.27.1
|
||||
'@babel/helper-replace-supers': 7.28.6(@babel/core@7.28.6)
|
||||
'@babel/helper-skip-transparent-expression-wrappers': 7.27.1
|
||||
'@babel/traverse': 7.28.6
|
||||
semver: 6.3.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helper-globals@7.28.0': {}
|
||||
|
||||
'@babel/helper-member-expression-to-functions@7.28.5':
|
||||
@@ -2702,15 +2674,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helper-replace-supers@7.28.6(@babel/core@7.28.6)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.6
|
||||
'@babel/helper-member-expression-to-functions': 7.28.5
|
||||
'@babel/helper-optimise-call-expression': 7.27.1
|
||||
'@babel/traverse': 7.28.6
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helper-skip-transparent-expression-wrappers@7.27.1':
|
||||
dependencies:
|
||||
'@babel/traverse': 7.28.6
|
||||
@@ -2748,11 +2711,6 @@ snapshots:
|
||||
'@babel/core': 7.28.0
|
||||
'@babel/helper-plugin-utils': 7.28.6
|
||||
|
||||
'@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.28.6)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.6
|
||||
'@babel/helper-plugin-utils': 7.28.6
|
||||
|
||||
'@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.28.0)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.0
|
||||
@@ -2761,14 +2719,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.28.6)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.6
|
||||
'@babel/helper-module-transforms': 7.28.6(@babel/core@7.28.6)
|
||||
'@babel/helper-plugin-utils': 7.28.6
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-typescript@7.28.6(@babel/core@7.28.0)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.0
|
||||
@@ -2780,17 +2730,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-typescript@7.28.6(@babel/core@7.28.6)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.6
|
||||
'@babel/helper-annotate-as-pure': 7.27.3
|
||||
'@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.28.6)
|
||||
'@babel/helper-plugin-utils': 7.28.6
|
||||
'@babel/helper-skip-transparent-expression-wrappers': 7.27.1
|
||||
'@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.28.6)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/preset-typescript@7.27.1(@babel/core@7.28.0)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.0
|
||||
@@ -2802,17 +2741,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/preset-typescript@7.28.5(@babel/core@7.28.6)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.6
|
||||
'@babel/helper-plugin-utils': 7.28.6
|
||||
'@babel/helper-validator-option': 7.27.1
|
||||
'@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.28.6)
|
||||
'@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.28.6)
|
||||
'@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.28.6)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/template@7.28.6':
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.28.6
|
||||
@@ -3718,13 +3646,6 @@ snapshots:
|
||||
optionalDependencies:
|
||||
solid-js: 1.9.10
|
||||
|
||||
babel-preset-solid@1.9.9(@babel/core@7.28.6)(solid-js@1.9.9):
|
||||
dependencies:
|
||||
'@babel/core': 7.28.6
|
||||
babel-plugin-jsx-dom-expressions: 0.40.3(@babel/core@7.28.6)
|
||||
optionalDependencies:
|
||||
solid-js: 1.9.9
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
base64-js@1.5.1: {}
|
||||
|
||||
Reference in New Issue
Block a user