oonacode 0.3.130 → 0.3.132

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.
package/README.md CHANGED
@@ -64,5 +64,8 @@ irm https://oonacode.oonak.ai/install.ps1 | iex
64
64
  - `private: true` is set on this package until the first publish (TODO: flip in `package.json`
65
65
  once the npm org is ready; the release workflow refuses to publish while it is private).
66
66
  - In the monorepo `optionalDependencies` use `workspace:<version>` so pnpm links the sibling
67
- platform package; `packaging/scripts/prepare-npm.mjs` rewrites it to the concrete version right
68
- before `npm publish` (npm does not understand the workspace protocol).
67
+ platform package. npm does not understand the workspace protocol, so what `packaging/release.ps1`
68
+ publishes is a copy staged outside the repo by `packaging/scripts/stage-npm.mjs`, whose
69
+ `optionalDependencies` are concrete versions and name only the platforms that release built
70
+ (until 0.3.131 this directory was published as it was, and `npm i -g oonacode` failed with
71
+ `EUNSUPPORTEDPROTOCOL` — review C18/C26, 2026-09-23).
package/bin/oona.js CHANGED
@@ -135,6 +135,16 @@ function run() {
135
135
  const native = resolveNative();
136
136
  const bundled = native ? null : resolveBundledJs();
137
137
  if (native) {
138
+ // A release is packed on Windows, which carries no POSIX mode into the tarball: postinstall
139
+ // sets the exec bit, and this covers an install whose lifecycle scripts were blocked (pnpm,
140
+ // bun). Best effort — a tree we may not write reports its own spawn error below.
141
+ if (!IS_WIN) {
142
+ try {
143
+ fs.chmodSync(native.bin, 0o755);
144
+ } catch {
145
+ /* not ours to change */
146
+ }
147
+ }
138
148
  engineEnv(env, [native.dir, __dirname]);
139
149
  child = spawn(native.bin, args, { stdio: 'inherit', env, windowsHide: false });
140
150
  } else if (bundled) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oonacode",
3
- "version": "0.3.130",
3
+ "version": "0.3.132",
4
4
  "description": "OonaCode — Windows-first multi-provider coding agent: the `oona` CLI, headless host service and local web UI. npm wrapper; the native binary is installed through the per-platform optional dependency.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "commonjs",
@@ -32,10 +32,9 @@
32
32
  ],
33
33
  "scripts": {
34
34
  "postinstall": "node postinstall.mjs",
35
- "test": "node --test test/wrapper.test.js test/packaging-scripts.test.js test/release-feed.test.js test/manifests.test.js test/set-version.test.js"
35
+ "test": "node --test test/wrapper.test.js test/packaging-scripts.test.js test/release-feed.test.js test/manifests.test.js test/set-version.test.js test/npm-stage.test.js test/ship-plan.test.js"
36
36
  },
37
37
  "optionalDependencies": {
38
- "@oonacode/win32-x64": "workspace:0.3.130",
39
- "@oonacode/linux-x64": "workspace:0.3.130"
38
+ "@oonacode/win32-x64": "0.3.132"
40
39
  }
41
40
  }
package/postinstall.mjs CHANGED
@@ -6,6 +6,13 @@
6
6
  * node_modules/oonacode-win32-x64/oonaclaude.exe -> ./bin/oonaclaude.exe (engine sidecar — must sit next to oona.exe)
7
7
  * node_modules/oonacode-win32-x64/web-ui/ -> ./bin/web-ui/ (directory junction, falls back to copy)
8
8
  * node_modules/oonacode-win32-x64/build/ -> ./bin/build/ (native addons, same treatment)
9
+ * node_modules/oonacode-win32-x64/registry.json -> ./bin/registry.json (hard link, falls back to copy)
10
+ *
11
+ * registry.json has to sit beside the LINKED binary, not only in the platform package: a compiled
12
+ * oona.exe finds the provider registry only as `<dir of the executable>/registry.json`
13
+ * (host-service provider-service.ts), and the host refuses to start without one. On Linux the
14
+ * binaries also get their exec bit here — a package packed on Windows carries no POSIX mode, and
15
+ * an engine that cannot be spawned hangs the SDK instead of failing.
9
16
  *
10
17
  * `oonaclaude(.exe)` is a byte-for-byte copy of the pinned, UNMODIFIED Claude Code binary from the
11
18
  * Claude Agent SDK. OonaCode does not fork or patch it — the filename differs only so it can never be
@@ -39,6 +46,7 @@ const ENGINE_NAME = IS_WIN ? 'oonaclaude.exe' : 'oonaclaude';
39
46
  /** Pre-rename filename, still linked when a package published before the rename is installed. */
40
47
  const LEGACY_ENGINE_NAME = IS_WIN ? 'claude.exe' : 'claude';
41
48
  const LINKED_DIRS = ['web-ui', 'build', 'prebuilds', 'lib'];
49
+ const LINKED_FILES = ['registry.json'];
42
50
 
43
51
  const log = (msg) => console.log(`[oonacode] ${msg}`);
44
52
  const INSTALL_HINT =
@@ -65,6 +73,16 @@ function linkFile(src, dst) {
65
73
  }
66
74
  }
67
75
 
76
+ /** Give a POSIX binary its exec bit; a no-op on Windows and never a failure. */
77
+ function makeExecutable(file) {
78
+ if (IS_WIN) return;
79
+ try {
80
+ fs.chmodSync(file, 0o755);
81
+ } catch {
82
+ /* read-only install tree: bin/oona.js reports the spawn error */
83
+ }
84
+ }
85
+
68
86
  function linkDir(src, dst) {
69
87
  fs.rmSync(dst, { recursive: true, force: true });
70
88
  try {
@@ -131,6 +149,15 @@ function main() {
131
149
  const src = path.join(pkgDir, dir);
132
150
  if (fs.existsSync(src)) parts.push(`${dir}/ ${linkDir(src, path.join(binDir, dir))}`);
133
151
  }
152
+ for (const name of LINKED_FILES) {
153
+ const src = path.join(pkgDir, name);
154
+ if (fs.existsSync(src)) parts.push(`${name} ${linkFile(src, path.join(binDir, name))}`);
155
+ }
156
+ // Both copies: the platform package's is what bin/oona.js runs when this script was skipped.
157
+ for (const name of [EXE_NAME, engineName].filter(Boolean)) {
158
+ makeExecutable(path.join(pkgDir, name));
159
+ makeExecutable(path.join(binDir, name));
160
+ }
134
161
  log(`ready: ${parts.join(', ')} -> ${binDir}`);
135
162
  }
136
163