@gjsify/cli 0.4.44 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,10 +28,31 @@
28
28
  // We still reuse Biome's platform/arch/musl detection — it's used to name the
29
29
  // expected NAPI binding package in the not-found install hint, so the user
30
30
  // knows exactly which optionalDependency npm failed to place.
31
+ //
32
+ // NATIVE ENGINE (GJS) — `@gjsify/oxfmt-native`
33
+ // ────────────────────────────────────────────
34
+ // Under GJS the Node launcher path is a dead end: there is no Node host to
35
+ // spawn. For oxfmt the dual-engine pick mirrors `bundler-pick.ts`'s
36
+ // native/npm pattern exactly: `shouldUseNativeOxfmt()` prefers the
37
+ // `@gjsify/oxfmt-native` GI bridge (Vala/Rust prebuild wrapping the full
38
+ // pure-Rust oxfmt CLI — config resolution, ignore handling, file walking,
39
+ // --write/--check/--list-different) when running under GJS and the prebuild
40
+ // is loadable, and falls back to spawning the Node launcher otherwise.
41
+ // `GJSIFY_OXFMT=native|npm` is the explicit override (native throws when the
42
+ // prebuild isn't loadable instead of silently switching engines).
43
+ //
44
+ // oxlint has NO native path yet: its JS-plugin host (the internal
45
+ // `gjsify/register-class-order` rule wired via `.oxlintrc.json` jsPlugins)
46
+ // lives in the Node launcher, so a native oxlint bridge could only run the
47
+ // Rust rule subset. Lint stays Node-spawned until that trade-off is decided
48
+ // (tracked in STATUS.md Open TODOs).
31
49
  import { existsSync, readFileSync } from 'node:fs';
32
50
  import { join, resolve } from 'node:path';
33
51
  import { spawn } from 'node:child_process';
52
+ import { createRequire } from 'node:module';
53
+ import { pathToFileURL } from 'node:url';
34
54
  import { findWorkspaceRoot } from './workspace-root.js';
55
+ import { resolveNpmPackage } from './resolve-npm-package.js';
35
56
  /**
36
57
  * Map Node.js `process.platform` + `arch` (+ musl on Linux) to the
37
58
  * napi-rs binding-package suffix oxc uses, e.g. `linux-x64-gnu`,
@@ -178,17 +199,99 @@ function findConfigFile(cwd, names) {
178
199
  }
179
200
  return null;
180
201
  }
202
+ let _nativeOxfmtProbe = null;
203
+ /**
204
+ * Try to load `@gjsify/oxfmt-native` (GJS only). Same multi-anchor
205
+ * resolution as `bundler-pick.ts`'s `tryLoadNative()` — GJS's native ESM
206
+ * loader has no node_modules walker, so bare specifiers must be resolved
207
+ * to a `file://` URL via createRequire/resolveNpmPackage first.
208
+ */
209
+ async function tryLoadNativeOxfmt() {
210
+ if (_nativeOxfmtProbe)
211
+ return _nativeOxfmtProbe;
212
+ _nativeOxfmtProbe = (async () => {
213
+ const isGjs = typeof globalThis.imports?.gi !== 'undefined';
214
+ if (!isGjs)
215
+ return null;
216
+ try {
217
+ const specifier = '@gjsify/oxfmt-native';
218
+ const resolved = resolveNpmPackage(specifier, { bundleUrl: import.meta.url }) ??
219
+ createRequire(import.meta.url).resolve(specifier);
220
+ const target = pathToFileURL(resolved).href;
221
+ const mod = (await import(/* @vite-ignore */ target));
222
+ if (!mod.hasNativeOxfmt())
223
+ return null;
224
+ return mod;
225
+ }
226
+ catch {
227
+ return null;
228
+ }
229
+ })();
230
+ return _nativeOxfmtProbe;
231
+ }
232
+ /**
233
+ * Engine pick for oxfmt — mirrors `bundler-pick.ts`'s `shouldUseNative()`:
234
+ * - `GJSIFY_OXFMT=npm` forces the Node launcher.
235
+ * - `GJSIFY_OXFMT=native` forces the GI bridge and throws when it is not
236
+ * loadable (instead of silently switching engines).
237
+ * - Default: native under GJS when loadable (the Node launcher cannot run
238
+ * without a Node host), npm launcher on Node.
239
+ */
240
+ export async function shouldUseNativeOxfmt() {
241
+ const env = globalThis.process?.env ?? {};
242
+ const choice = env.GJSIFY_OXFMT;
243
+ if (choice === 'npm')
244
+ return false;
245
+ if (choice === 'native') {
246
+ const native = await tryLoadNativeOxfmt();
247
+ if (!native) {
248
+ throw new Error('GJSIFY_OXFMT=native but @gjsify/oxfmt-native is not loadable (no prebuild for this architecture, or not running under GJS).');
249
+ }
250
+ return true;
251
+ }
252
+ const isGjs = typeof globalThis.imports?.gi !== 'undefined';
253
+ if (!isGjs)
254
+ return false;
255
+ return (await tryLoadNativeOxfmt()) !== null;
256
+ }
181
257
  /**
182
- * Spawn an oxc tool (oxlint / oxfmt) via its Node ESM launcher. Inherits
183
- * stdio so the tool's own output (diagnostics, reformatted files, summary
184
- * lines) reaches the user.
258
+ * Run an oxc tool (oxlint / oxfmt).
259
+ *
260
+ * oxfmt: dual-engine — under GJS the `@gjsify/oxfmt-native` GI bridge runs
261
+ * the full oxfmt CLI in-process (Node-free); otherwise the npm Node ESM
262
+ * launcher is spawned. `GJSIFY_OXFMT=native|npm` overrides the pick.
263
+ *
264
+ * oxlint: always spawned via its Node ESM launcher with the current Node
265
+ * executable (`process.execPath`) so the JS plugin host is available —
266
+ * required for the `jsPlugins`-wired `gjsify/register-class-order` rule.
185
267
  *
186
- * The launcher is run with the current Node executable (`process.execPath`)
187
- * so the JS plugin host is available — required for oxlint's `jsPlugins`.
268
+ * Inherits stdio so the tool's own output (diagnostics, reformatted files,
269
+ * summary lines) reaches the user.
188
270
  *
189
271
  * Returns the exit code; never throws on non-zero exit (callers check it).
190
272
  */
191
- export function runOxc(tool, args, opts = {}) {
273
+ export async function runOxc(tool, args, opts = {}) {
274
+ if (tool === 'oxfmt' && (await shouldUseNativeOxfmt())) {
275
+ const native = await tryLoadNativeOxfmt();
276
+ if (!native) {
277
+ // Unreachable: shouldUseNativeOxfmt() returned true above.
278
+ throw new Error('@gjsify/oxfmt-native not loadable');
279
+ }
280
+ if (opts.verbose) {
281
+ console.log(`[gjsify oxc] @gjsify/oxfmt-native (in-process) ${args.join(' ')}`);
282
+ }
283
+ // The native runner walks from the process working directory; the
284
+ // command handlers always pass cwd = process.cwd(), so no chdir is
285
+ // needed here.
286
+ return native.runOxfmt(args);
287
+ }
288
+ return spawnOxcLauncher(tool, args, opts);
289
+ }
290
+ /**
291
+ * Spawn an oxc tool via its Node ESM launcher (`node_modules/<tool>/bin/…`)
292
+ * with the current Node executable.
293
+ */
294
+ function spawnOxcLauncher(tool, args, opts = {}) {
192
295
  const cwd = opts.cwd ?? process.cwd();
193
296
  const launcher = findOxcLauncher(tool, cwd);
194
297
  const node = process.execPath || 'node';
@@ -242,6 +345,29 @@ export function loadOxfmtTemplate() {
242
345
  export function printOxcNotFound(err) {
243
346
  console.error(err.message);
244
347
  }
348
+ /**
349
+ * Propagate an oxc tool's exit code from a command handler.
350
+ *
351
+ * On Node, setting `process.exitCode` is the gentle idiom (streams flush,
352
+ * the process ends naturally). Under GJS there is no atexit hook, so
353
+ * `process.exitCode` alone is NOT honored at natural shutdown — the gjs
354
+ * process would exit 0 after a failed `--check`. Call `imports.system.exit`
355
+ * directly for non-zero codes there: SpiderMonkey raises its uncatchable
356
+ * exit exception from any context — including the yargs `parseAsync`
357
+ * microtask continuation this runs in — and stdout writes are synchronous
358
+ * under GJS, so the tool's report is already flushed. (`process.exit`'s
359
+ * idle-scheduled path is NOT used here: the scheduled idle never fires from
360
+ * this continuation — the module's top-level await is still pending and gjs
361
+ * exits 0 before the hook-registered loop runs.)
362
+ */
363
+ export function setOxcExitCode(code) {
364
+ process.exitCode = code;
365
+ if (code === 0)
366
+ return;
367
+ const gjs = globalThis.imports;
368
+ if (gjs?.system?.exit)
369
+ gjs.system.exit(code);
370
+ }
245
371
  /**
246
372
  * Has the given oxc tool's npm package (or its companion) been declared in the
247
373
  * project's dependencies? Useful as a cheap pre-flight check — `gjsify flatpak
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Prefix every line of `src` with `prefix` and route it to `sink`. When
3
+ * `buffered` is false (tty), lines are written live. When true (non-tty /
4
+ * CI pipe), they are accumulated and emitted only by the returned `flush()`
5
+ * — call it once the child has closed.
6
+ */
7
+ export declare function prefixLines(src: NodeJS.ReadableStream, sink: NodeJS.WritableStream, prefix: string, buffered: boolean): () => void;
@@ -0,0 +1,52 @@
1
+ // Shared line-prefixed child-output forwarding for the parallel runners
2
+ // (`gjsify foreach`, `gjsify check`).
3
+ //
4
+ // Under GJS, `process.stdout.write` is a BLOCKING `Gio.write_all`. Writing
5
+ // each prefixed line LIVE during a PARALLEL run into a backpressuring pipe
6
+ // (a CI log collector that drains slowly) stalls the single GLib main loop
7
+ // on a full pipe → every parallel child's pipe backs up → their reads stall
8
+ // → the whole run HANGS. (A tty or file sink never backpressures, which is
9
+ // why this only ever bites in CI.) On a NON-tty sink we therefore BUFFER
10
+ // each child's prefixed output and flush it as ONE write when that child
11
+ // closes: the child is already done by then, so its own read can't stall,
12
+ // and concurrent flushes serialize into brief loop stalls instead of a
13
+ // deadlock. On a tty (interactive) lines are written live for responsive
14
+ // output.
15
+ //
16
+ // This helper is the single home for that logic — `foreach` shipped the fix
17
+ // first; `check` had an unbuffered copy that kept the hang class alive.
18
+ /**
19
+ * Prefix every line of `src` with `prefix` and route it to `sink`. When
20
+ * `buffered` is false (tty), lines are written live. When true (non-tty /
21
+ * CI pipe), they are accumulated and emitted only by the returned `flush()`
22
+ * — call it once the child has closed.
23
+ */
24
+ export function prefixLines(src, sink, prefix, buffered) {
25
+ let buf = '';
26
+ let acc = '';
27
+ const emit = (line) => {
28
+ if (buffered)
29
+ acc += line;
30
+ else
31
+ sink.write(line);
32
+ };
33
+ src.setEncoding('utf-8');
34
+ src.on('data', (chunk) => {
35
+ buf += chunk;
36
+ let idx;
37
+ while ((idx = buf.indexOf('\n')) !== -1) {
38
+ emit(prefix + buf.slice(0, idx + 1));
39
+ buf = buf.slice(idx + 1);
40
+ }
41
+ });
42
+ src.on('end', () => {
43
+ if (buf.length > 0)
44
+ emit(prefix + buf + '\n');
45
+ });
46
+ return () => {
47
+ if (acc.length > 0) {
48
+ sink.write(acc);
49
+ acc = '';
50
+ }
51
+ };
52
+ }
@@ -0,0 +1,45 @@
1
+ import { type NpmrcConfig } from '@gjsify/npm-registry';
2
+ /**
3
+ * Percent-encode a package name for the publish PUT path, matching
4
+ * npm-package-arg's `escapedName` convention (npa.js:188):
5
+ * `this.escapedName = name.replace('/', '%2f')`.
6
+ *
7
+ * Scoped: `@scope/name` → `@scope%2fname` (literal `@`, lowercase `%2f`, the
8
+ * scope/name segments NOT otherwise re-encoded — npm only replaces the slash).
9
+ * Unscoped: returned unchanged (npa stores the bare name; the only characters
10
+ * npm forbids are those `encodeURIComponent` would touch, which npa rejects up
11
+ * front). The npm registry is picky about this exact shape on the publish PUT
12
+ * URL — `%2F` (uppercase) or a re-encoded `@` would miss the create route.
13
+ */
14
+ export declare function escapePackageName(name: string): string;
15
+ export interface PublishHeaderOptions {
16
+ /** Parsed ~/.npmrc — supplies the `authorization` (Bearer/Basic) header. */
17
+ npmrc?: NpmrcConfig;
18
+ /** 2FA one-time code. When present, sent as `npm-otp` AND flips auth-type. */
19
+ otp?: string;
20
+ /**
21
+ * Override the `authorization` header (e.g. an OIDC Bearer token resolved
22
+ * after `buildHeaders` ran). When set it replaces whatever the npmrc auth
23
+ * resolution produced.
24
+ */
25
+ authorization?: string;
26
+ /**
27
+ * npm user-agent. Defaults to an npm-CLI-shaped string. The registry does
28
+ * not validate the exact value, but a real UA is what npm sends; the dead
29
+ * `gjsify-install/0.3.7` placeholder is not used here.
30
+ */
31
+ userAgent?: string;
32
+ }
33
+ /**
34
+ * Build the full set of headers for the publish PUT, mirroring
35
+ * `npm-registry-fetch`'s `getHeaders` for `npm publish`.
36
+ *
37
+ * The set: `authorization`, `content-type: application/json`,
38
+ * `npm-command: publish`, `npm-auth-type` (`web`, or `legacy` when `--otp`),
39
+ * `user-agent`, and `npm-otp` when an OTP is supplied.
40
+ *
41
+ * Notably it does NOT set an `accept: *` wildcard — `npm-registry-fetch` sends
42
+ * no `accept` header on the publish PUT; the stray wildcard gjsify used to send
43
+ * is dropped to match.
44
+ */
45
+ export declare function buildPublishHeaders(url: string, opts: PublishHeaderOptions): Record<string, string>;
@@ -0,0 +1,99 @@
1
+ // Publish-request header builder — matches what npm's CLI sends on a publish
2
+ // PUT so the npm registry's create-package frontdoor routes a *new* scoped
3
+ // package correctly.
4
+ //
5
+ // Root cause this fixes: a first-publish of a never-before-published
6
+ // `@scope/<name>` via token auth was returning a bare `404 Not Found` (body
7
+ // `Not Found`, NOT a JSON npm error). That is a routing miss, not a
8
+ // payload-validation failure — npm's write frontdoor keys the create path on
9
+ // the `npm-command` header, which gjsify was not sending. `npm publish` with
10
+ // the same ~/.npmrc token succeeds because libnpmpublish goes through
11
+ // `npm-registry-fetch`'s `getHeaders`, which always sets `npm-command`
12
+ // (+ `npm-auth-type`, + a real `user-agent`).
13
+ //
14
+ // Evidence (refs/npm-cli):
15
+ // - `lib/npm.js:404` `flat.npmCommand = this.command` → set for EVERY npm
16
+ // command; equals `"publish"` for `npm publish`.
17
+ // - `node_modules/npm-registry-fetch/lib/index.js:231-233`
18
+ // `if (opts.npmCommand) headers['npm-command'] = opts.npmCommand`
19
+ // and `:219-221` `if (opts.authType) headers['npm-auth-type'] = …`
20
+ // and `:215-217` `'user-agent': opts.userAgent`.
21
+ // - `workspaces/config/lib/definitions/definitions.js:282-290` — `auth-type`
22
+ // default `'web'`, flattened to `flatOptions.authType`.
23
+ // - `:1581-1587` — when `--otp` is set, npm forces `auth-type` to `'legacy'`
24
+ // before flattening, so an OTP publish sends `npm-auth-type: legacy`.
25
+ // - `node_modules/npm-package-arg/lib/npa.js:188`
26
+ // `this.escapedName = name.replace('/', '%2f')` — lowercase `%2f`,
27
+ // literal `@`. (gjsify's URL encoding already matches this — it was never
28
+ // the bug.)
29
+ //
30
+ // This module is pure (no I/O, no `gi://`) so it is unit-testable on both Node
31
+ // and GJS without dragging in the runtime fetch/Soup stack.
32
+ import { buildHeaders } from '@gjsify/npm-registry';
33
+ /**
34
+ * Percent-encode a package name for the publish PUT path, matching
35
+ * npm-package-arg's `escapedName` convention (npa.js:188):
36
+ * `this.escapedName = name.replace('/', '%2f')`.
37
+ *
38
+ * Scoped: `@scope/name` → `@scope%2fname` (literal `@`, lowercase `%2f`, the
39
+ * scope/name segments NOT otherwise re-encoded — npm only replaces the slash).
40
+ * Unscoped: returned unchanged (npa stores the bare name; the only characters
41
+ * npm forbids are those `encodeURIComponent` would touch, which npa rejects up
42
+ * front). The npm registry is picky about this exact shape on the publish PUT
43
+ * URL — `%2F` (uppercase) or a re-encoded `@` would miss the create route.
44
+ */
45
+ export function escapePackageName(name) {
46
+ return name.replace('/', '%2f');
47
+ }
48
+ /**
49
+ * Build the full set of headers for the publish PUT, mirroring
50
+ * `npm-registry-fetch`'s `getHeaders` for `npm publish`.
51
+ *
52
+ * The set: `authorization`, `content-type: application/json`,
53
+ * `npm-command: publish`, `npm-auth-type` (`web`, or `legacy` when `--otp`),
54
+ * `user-agent`, and `npm-otp` when an OTP is supplied.
55
+ *
56
+ * Notably it does NOT set an `accept: *` wildcard — `npm-registry-fetch` sends
57
+ * no `accept` header on the publish PUT; the stray wildcard gjsify used to send
58
+ * is dropped to match.
59
+ */
60
+ export function buildPublishHeaders(url, opts) {
61
+ const headers = buildHeaders(url, { npmrc: opts.npmrc });
62
+ // npm-registry-fetch never sets `accept` on the publish PUT — drop the
63
+ // placeholder `accept-encoding` we don't want to influence the create route
64
+ // either. (buildHeaders defaults accept-encoding to `identity`; a publish
65
+ // PUT body is JSON we generated, so the encoding header is irrelevant — but
66
+ // we keep it harmless and explicit by leaving it as buildHeaders set it.)
67
+ // content-type: application/json — npm-registry-fetch sets this for any
68
+ // non-string/non-stream/non-buffer body (index.js:63-67); our body is a
69
+ // JSON string, so we set it explicitly.
70
+ headers['content-type'] = 'application/json';
71
+ // npm-command: publish — THE routing header. npm sets it for every command
72
+ // (npm.js:404); the registry's write frontdoor uses it to route the
73
+ // create-package PUT. Missing it = bare `404 Not Found` on a new package.
74
+ headers['npm-command'] = 'publish';
75
+ // npm-auth-type — `web` by default, `legacy` when an OTP is supplied
76
+ // (definitions.js:1583-1586). Sent by getHeaders (index.js:219-221).
77
+ headers['npm-auth-type'] = opts.otp ? 'legacy' : 'web';
78
+ // user-agent — a real npm-shaped UA (getHeaders index.js:215-217).
79
+ headers['user-agent'] = opts.userAgent ?? defaultUserAgent();
80
+ // npm-otp — only when an OTP is supplied (index.js:243-245).
81
+ if (opts.otp)
82
+ headers['npm-otp'] = opts.otp;
83
+ // authorization override (OIDC token resolved after npmrc auth).
84
+ if (opts.authorization)
85
+ headers['authorization'] = opts.authorization;
86
+ return headers;
87
+ }
88
+ /**
89
+ * npm-CLI-shaped user-agent. Format mirrors npm-registry-fetch's
90
+ * `default-opts.js` (`npm@<v>/node@<v>+<arch> (<platform>)`); we substitute the
91
+ * gjsify CLI identity. The registry does not validate the exact value — it just
92
+ * must be a non-placeholder UA, which some WAF / CDN frontdoors require.
93
+ */
94
+ function defaultUserAgent() {
95
+ const proc = globalThis.process;
96
+ const arch = proc?.arch ?? 'x64';
97
+ const platform = proc?.platform ?? 'linux';
98
+ return `gjsify-publish/0.5.0 (${platform} ${arch})`;
99
+ }
@@ -16,4 +16,18 @@ export declare function computeNativeEnvForBundle(bundlePath: string, cwd?: stri
16
16
  * for any installed native gjsify packages discoverable from either the CWD
17
17
  * or the bundle's own node_modules tree.
18
18
  */
19
- export declare function runGjsBundle(bundlePath: string, extraArgs?: string[]): Promise<void>;
19
+ export interface RunGjsBundleOptions {
20
+ /**
21
+ * Exit this process with code 0 once the child succeeds. Under GJS,
22
+ * `ensureMainLoop()` (armed by spawn) keeps the parent's GLib loop alive
23
+ * after the child exits — a TERMINAL caller (`gjsify run <file>`, `dlx`)
24
+ * must opt in here or it parks forever (this exact gap hung CI's
25
+ * "Test WebGL conformance" for 83 min: the suite finished in 1.35 s, the
26
+ * parent `gjsify run conformance.gjs.js` never exited). Callers that
27
+ * continue after the bundle (e.g. `gjsify test`'s multi-runtime
28
+ * aggregation loop) MUST leave this false — an unconditional exit here
29
+ * truncated `gjsify test` after the first gjs bundle.
30
+ */
31
+ exitOnSuccess?: boolean;
32
+ }
33
+ export declare function runGjsBundle(bundlePath: string, extraArgs?: string[], options?: RunGjsBundleOptions): Promise<void>;
@@ -38,12 +38,7 @@ export function computeNativeEnvForBundle(bundlePath, cwd = process.cwd()) {
38
38
  .join(' ');
39
39
  return { env, envPrefix };
40
40
  }
41
- /**
42
- * Run a GJS bundle, automatically setting LD_LIBRARY_PATH and GI_TYPELIB_PATH
43
- * for any installed native gjsify packages discoverable from either the CWD
44
- * or the bundle's own node_modules tree.
45
- */
46
- export async function runGjsBundle(bundlePath, extraArgs = []) {
41
+ export async function runGjsBundle(bundlePath, extraArgs = [], options = {}) {
47
42
  const { env: nativeEnv, envPrefix } = computeNativeEnvForBundle(bundlePath);
48
43
  const env = {
49
44
  ...process.env,
@@ -53,8 +48,10 @@ export async function runGjsBundle(bundlePath, extraArgs = []) {
53
48
  // Print the exact command being executed so users can copy-paste it to
54
49
  // run gjs directly without the wrapper. Env vars are only shown if we
55
50
  // actually set any (i.e. native gjsify packages were detected).
51
+ // Use stderr so that children speaking a protocol on stdout (e.g. an
52
+ // MCP stdio server) receive an uncontaminated stdout stream.
56
53
  const gjsCommand = ['gjs', ...gjsArgs.map((a) => (a.includes(' ') ? `"${a}"` : a))].join(' ');
57
- console.log(`$ ${envPrefix ? `${envPrefix} ` : ''}${gjsCommand}`);
54
+ console.error(`$ ${envPrefix ? `${envPrefix} ` : ''}${gjsCommand}`);
58
55
  const child = spawn('gjs', gjsArgs, { env, stdio: 'inherit' });
59
56
  await new Promise((resolvePromise, reject) => {
60
57
  child.on('close', (code) => {
@@ -70,4 +67,8 @@ export async function runGjsBundle(bundlePath, extraArgs = []) {
70
67
  console.error(err.message);
71
68
  process.exit(1);
72
69
  });
70
+ // See RunGjsBundleOptions.exitOnSuccess — terminal callers opt in,
71
+ // mid-flow callers (test.ts's runtime loop) keep the process alive.
72
+ if (options.exitOnSuccess)
73
+ process.exit(0);
73
74
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/cli",
3
- "version": "0.4.44",
3
+ "version": "0.5.1",
4
4
  "description": "CLI for Gjsify",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -120,34 +120,38 @@
120
120
  "cli"
121
121
  ],
122
122
  "dependencies": {
123
- "@gjsify/buffer": "^0.4.44",
124
- "@gjsify/create-app": "^0.4.44",
125
- "@gjsify/node-globals": "^0.4.44",
126
- "@gjsify/node-polyfills": "^0.4.44",
127
- "@gjsify/npm-registry": "^0.4.44",
128
- "@gjsify/resolve-npm": "^0.4.44",
129
- "@gjsify/rolldown-plugin-gjsify": "^0.4.44",
130
- "@gjsify/rolldown-plugin-pnp": "^0.4.44",
131
- "@gjsify/semver": "^0.4.44",
132
- "@gjsify/tar": "^0.4.44",
133
- "@gjsify/tsc": "^0.4.44",
134
- "@gjsify/web-polyfills": "^0.4.44",
135
- "@gjsify/workspace": "^0.4.44",
136
- "cosmiconfig": "^9.0.1",
123
+ "@gjsify/buffer": "^0.5.1",
124
+ "@gjsify/create-app": "^0.5.1",
125
+ "@gjsify/node-globals": "^0.5.1",
126
+ "@gjsify/node-polyfills": "^0.5.1",
127
+ "@gjsify/npm-registry": "^0.5.1",
128
+ "@gjsify/resolve-npm": "^0.5.1",
129
+ "@gjsify/rolldown-plugin-gjsify": "^0.5.1",
130
+ "@gjsify/rolldown-plugin-pnp": "^0.5.1",
131
+ "@gjsify/semver": "^0.5.1",
132
+ "@gjsify/tar": "^0.5.1",
133
+ "@gjsify/tsc": "^0.5.1",
134
+ "@gjsify/web-polyfills": "^0.5.1",
135
+ "@gjsify/workspace": "^0.5.1",
136
+ "cosmiconfig": "^9.0.2",
137
137
  "get-tsconfig": "^4.14.0",
138
138
  "pkg-types": "^2.3.1",
139
- "rolldown": "^1.0.3",
139
+ "rolldown": "^1.1.0",
140
140
  "yargs": "^18.0.0"
141
141
  },
142
142
  "devDependencies": {
143
- "@gjsify/unit": "^0.4.44",
143
+ "@gjsify/unit": "^0.5.1",
144
144
  "@types/yargs": "^17.0.35",
145
145
  "typescript": "^6.0.3"
146
146
  },
147
147
  "peerDependencies": {
148
- "@gjsify/rolldown-native": "^0.4.44"
148
+ "@gjsify/oxfmt-native": "^0.5.1",
149
+ "@gjsify/rolldown-native": "^0.5.1"
149
150
  },
150
151
  "peerDependenciesMeta": {
152
+ "@gjsify/oxfmt-native": {
153
+ "optional": true
154
+ },
151
155
  "@gjsify/rolldown-native": {
152
156
  "optional": true
153
157
  }