cowork-os 0.3.79 → 0.3.82

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/CHANGELOG.md CHANGED
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.82] - 2026-02-14
11
+
12
+ ### Fixed
13
+ - **SIGKILL regression fix for npm installs**: `setup_native` no longer uses `npm install --ignore-scripts=false` when recovering missing `better-sqlite3`, preventing `electron-winstaller` lifecycle scripts from being executed during first-time setup.
14
+ - **Recovery install hardening**: missing runtime dependency repair now uses `--omit=dev` and `--package-lock=false` to avoid reifying packaging/dev dependency trees in user runtime installs.
15
+
16
+ ## [0.3.81] - 2026-02-14
17
+
18
+ ### Fixed
19
+ - **README install path hardening**: `npm run setup` now skips a full dependency reinstall when the Electron dependency is already present, so fresh `/tmp` installs avoid avoidable reinstall-driven SIGKILL pressure.
20
+ - **Native setup reliability**: restores the 0.3.71-style flow with retryable native setup and keeps `better-sqlite3` installation script-safe, then rebuilds it explicitly against Electron ABI.
21
+
22
+ ## [0.3.80] - 2026-02-14
23
+
24
+ ### Fixed
25
+ - **macOS install reliability hardening**: setup now skips optional dependency reinstall during `npm run setup`, avoids propagating child SIGKILL events from native setup back to the shell, and documents a first-install flow that avoids macOS-terminating paths.
26
+ - **Release validation hardening**: CI now resolves release metadata before install validation and validates installability from either published npm tarball (if already published) or local `npm pack` fallback, preventing release regressions for first-release tags.
27
+
10
28
  ## [0.3.79] - 2026-02-14
11
29
 
12
30
  ### Fixed
@@ -548,6 +566,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
548
566
 
549
567
  | Version | Date | Highlights |
550
568
  |---------|------|------------|
569
+ | 0.3.82 | 2026-02-14 | Removes script-enabled recovery installs that triggered electron-winstaller SIGKILL and hardens runtime repair install flags |
570
+ | 0.3.81 | 2026-02-14 | Restored reliable /tmp install flow with retry-safe native setup and CI validation for both registry and npm-pack install paths |
571
+ | 0.3.80 | 2026-02-14 | Fixed macOS first-install runtime setup reliability and hardened release validation so new tags can still run installation checks |
551
572
  | 0.3.79 | 2026-02-14 | Retained the 0.3.71 SIGKILL workaround and hardened draft release preparation so desktop assets upload reliably |
552
573
  | 0.3.78 | 2026-02-14 | Fixes missing release-time `executor-helpers` source and remaining strict-mode TypeScript blockers |
553
574
  | 0.3.77 | 2026-02-14 | Skips lifecycle scripts during setup reinstall and prevents setup-time SIGKILL in user-first installs |
@@ -564,7 +585,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
564
585
  | 0.1.0 | 2025-01-24 | First public release with core features |
565
586
  | 0.0.1 | 2025-01-20 | Initial development setup |
566
587
 
567
- [Unreleased]: https://github.com/CoWork-OS/CoWork-OS/compare/v0.3.79...HEAD
588
+ [Unreleased]: https://github.com/CoWork-OS/CoWork-OS/compare/v0.3.82...HEAD
589
+ [0.3.82]: https://github.com/CoWork-OS/CoWork-OS/releases/tag/v0.3.82
590
+ [0.3.81]: https://github.com/CoWork-OS/CoWork-OS/releases/tag/v0.3.81
591
+ [0.3.80]: https://github.com/CoWork-OS/CoWork-OS/releases/tag/v0.3.80
568
592
  [0.3.79]: https://github.com/CoWork-OS/CoWork-OS/releases/tag/v0.3.79
569
593
  [0.3.78]: https://github.com/CoWork-OS/CoWork-OS/releases/tag/v0.3.78
570
594
  [0.3.77]: https://github.com/CoWork-OS/CoWork-OS/releases/tag/v0.3.77
package/README.md CHANGED
@@ -36,11 +36,11 @@ Your AI needs a secure home. CoWork OS provides the runtime, security layers, an
36
36
  | **Security-First** | 2800+ unit tests, configurable guardrails, approval workflows, gateway hardening |
37
37
  | **Local-First** | Your data stays on your machine. BYOK (Bring Your Own Key) |
38
38
 
39
- ### What’s new in 0.3.79
39
+ ### What’s new in 0.3.82
40
40
 
41
- - **0.3.71-style SIGKILL workaround carried forward**: the README macOS first-install flow (`npm install --ignore-scripts ...` then `npm run --prefix node_modules/cowork-os setup`) is now the officially documented path and includes retry/backoff handling for native setup SIGKILLs.
42
- - **Releaseability alignment**: this release includes the release workflow hardening that guarantees a draft release exists before Electron packaging, so desktop assets can be attached reliably on each tag.
43
- - **Version sync**: bumped to `0.3.79` so the fix is published for npm and GitHub releases.
41
+ - **SIGKILL regression fixed**: runtime native setup no longer uses script-enabled `npm install` for missing `better-sqlite3`, so `electron-winstaller` lifecycle scripts are not triggered during first-time install setup.
42
+ - **0.3.71 reliability behavior preserved**: first-install flow remains `npm install --ignore-scripts --omit=optional` followed by `npm run --prefix node_modules/cowork-os setup`, with retry handling.
43
+ - **Version sync**: bumped to `0.3.82`.
44
44
 
45
45
  > **Status**: macOS desktop app + headless/server mode (Linux/VPS). Cross-platform desktop support planned.
46
46
 
@@ -67,7 +67,7 @@ Use this flow to test like a first-time user in a clean folder:
67
67
  # Install into a local folder
68
68
  mkdir -p /tmp/cowork-run
69
69
  cd /tmp/cowork-run
70
- npm install --ignore-scripts cowork-os@latest --no-audit --no-fund
70
+ npm install --ignore-scripts --omit=optional cowork-os@latest --no-audit --no-fund
71
71
 
72
72
  # Prepare native runtime (Electron binary + native module cache)
73
73
  npm run --prefix node_modules/cowork-os setup
@@ -81,7 +81,16 @@ npx cowork-os
81
81
 
82
82
  This is the first install path users should try on macOS:
83
83
 
84
- > If you run plain `npm install cowork-os@latest`, macOS can still intermittently kill lifecycle scripts during dependency extraction. Use the `--ignore-scripts` flow above and `npm run --prefix node_modules/cowork-os setup` every time before first launch.
84
+ > If you run plain `npm install cowork-os@latest`, macOS can still intermittently kill lifecycle scripts during dependency extraction. Use the flow above with `--ignore-scripts --omit=optional` and `npm run --prefix node_modules/cowork-os setup` before first launch.
85
+
86
+ For strict reproducibility on low-memory machines:
87
+
88
+ ```bash
89
+ export COWORK_SETUP_JOBS=1
90
+ export COWORK_SETUP_NATIVE_OUTER_ATTEMPTS=10
91
+ export COWORK_SETUP_NATIVE_SHELL_ATTEMPTS=10
92
+ npm run --prefix node_modules/cowork-os setup
93
+ ```
85
94
 
86
95
  #### Install reliability notes (macOS / low-memory environments)
87
96
 
@@ -96,7 +105,7 @@ This is the first install path users should try on macOS:
96
105
  You can also install globally and launch directly:
97
106
 
98
107
  ```bash
99
- npm install -g --ignore-scripts --no-audit --no-fund cowork-os
108
+ npm install -g --ignore-scripts --omit=optional --no-audit --no-fund cowork-os
100
109
 
101
110
  # Optional: verify installed version
102
111
  npm list -g cowork-os --depth=0
@@ -143,10 +152,20 @@ npm run dev
143
152
 
144
153
  If you see `Killed: 9` during `npm run setup`, macOS terminated a native build due to memory pressure.
145
154
 
146
- `npm run setup` already retries native setup automatically with backoff. Let it continue until it exits. If it still exits non-zero, close heavy apps and run the same command again:
155
+ `npm run setup` already retries native setup automatically with backoff. Let it continue until it exits. If it still exits non-zero:
147
156
 
148
157
  ```bash
149
- npm run setup
158
+ pkill -f '/cowork-os' || true
159
+ npm run --prefix node_modules/cowork-os setup
160
+ ```
161
+
162
+ If the shell shows `zsh: killed` again, this usually means your system killed a child process. Repeat with lower-memory settings:
163
+
164
+ ```bash
165
+ COWORK_SETUP_JOBS=1 \
166
+ COWORK_SETUP_NATIVE_OUTER_ATTEMPTS=12 \
167
+ COWORK_SETUP_NATIVE_SHELL_ATTEMPTS=12 \
168
+ npm run --prefix node_modules/cowork-os setup
150
169
  ```
151
170
 
152
171
  #### Build for Production
package/bin/cowork.js CHANGED
@@ -10,6 +10,13 @@ const mainPath = path.join(packageDir, 'dist', 'electron', 'electron', 'main.js'
10
10
  const args = process.argv.slice(2);
11
11
  const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
12
12
 
13
+ function mapSignalToCode(signal) {
14
+ if (signal === 'SIGKILL') return 137;
15
+ if (signal === 'SIGTERM') return 143;
16
+ if (signal === 'SIGINT') return 130;
17
+ return 1;
18
+ }
19
+
13
20
  function buildAppAndLaunch() {
14
21
  console.log('[cowork-os] Build artifacts not found, running npm run build...');
15
22
  const build = spawn(npmCmd, ['run', 'build'], {
@@ -70,6 +77,8 @@ function ensureRuntimeDeps() {
70
77
  '--no-audit',
71
78
  '--no-fund',
72
79
  '--ignore-scripts',
80
+ '--omit=dev',
81
+ '--package-lock=false',
73
82
  ...missing.map((dep) => `${dep.name}@${dep.version}`)
74
83
  ];
75
84
 
@@ -135,7 +144,14 @@ function runNativeSetup(onDone) {
135
144
 
136
145
  setup.on('exit', (code, signal) => {
137
146
  if (signal) {
138
- process.kill(process.pid, signal);
147
+ const exitCode = mapSignalToCode(signal);
148
+ console.error(
149
+ `[cowork-os] Native setup was terminated (${signal}).` +
150
+ (signal === 'SIGKILL'
151
+ ? ' Close other memory-heavy apps and rerun `npm run setup`.'
152
+ : '')
153
+ );
154
+ process.exit(exitCode);
139
155
  return;
140
156
  }
141
157
  if (code !== 0) {
@@ -157,7 +173,7 @@ function prepareAndLaunchApp() {
157
173
  if (!electronBinary) {
158
174
  console.error(
159
175
  '[cowork-os] Electron runtime is still missing after setup. Reinstall with:\n' +
160
- ' npm install --ignore-scripts --no-audit --no-fund cowork-os@latest\n'
176
+ ' npm install --ignore-scripts --omit=optional --no-audit --no-fund cowork-os@latest\n'
161
177
  );
162
178
  process.exit(1);
163
179
  }
@@ -192,7 +208,7 @@ function launchApp(electronBinary) {
192
208
 
193
209
  electron.on('exit', (code, signal) => {
194
210
  if (signal) {
195
- process.kill(process.pid, signal);
211
+ process.exit(mapSignalToCode(signal));
196
212
  return;
197
213
  }
198
214
  process.exit(code || 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cowork-os",
3
- "version": "0.3.79",
3
+ "version": "0.3.82",
4
4
  "description": "CoWork OS - The operating system for personal AI assistants",
5
5
  "overrides": {
6
6
  "@whiskeysockets/baileys": {
@@ -74,13 +74,13 @@
74
74
  "@whiskeysockets/baileys"
75
75
  ],
76
76
  "scripts": {
77
- "setup": "npm install --ignore-scripts --no-audit --no-fund --omit=dev && { sleep 2; i=1; max=${COWORK_SETUP_NATIVE_OUTER_ATTEMPTS:-6}; delay=2; while [ $i -le $max ]; do echo \"[cowork] setup:native (outer attempt $i/$max)\"; sh scripts/setup_native_retry.sh; s=$?; if [ $s -eq 0 ]; then exit 0; fi; if [ $s -ne 137 ] && [ $s -ne 9 ]; then exit $s; fi; echo \"[cowork] setup:native was killed; retrying in ${delay}s...\"; sleep $delay; delay=$((delay * 2)); if [ $delay -gt 20 ]; then delay=20; fi; i=$((i + 1)); done; exit $s; }",
77
+ "setup": "if [ ! -f node_modules/electron/package.json ]; then npm install --ignore-scripts --omit=optional --omit=dev --no-audit --no-fund --no-save; fi; { sleep 2; i=1; max=${COWORK_SETUP_NATIVE_OUTER_ATTEMPTS:-6}; delay=2; while [ $i -le $max ]; do echo \"[cowork] setup:native (outer attempt $i/$max)\"; sh scripts/setup_native_retry.sh; s=$?; if [ $s -eq 0 ]; then exit 0; fi; if [ $s -ne 137 ] && [ $s -ne 9 ]; then exit $s; fi; echo \"[cowork] setup:native was killed; retrying in ${delay}s...\"; sleep $delay; delay=$((delay * 2)); if [ $delay -gt 20 ]; then delay=20; fi; i=$((i + 1)); done; exit $s; }",
78
78
  "setup:native": "sleep 2; i=1; max=${COWORK_SETUP_NATIVE_OUTER_ATTEMPTS:-6}; delay=2; while [ $i -le $max ]; do echo \"[cowork] setup:native (outer attempt $i/$max)\"; sh scripts/setup_native_retry.sh; s=$?; if [ $s -eq 0 ]; then exit 0; fi; if [ $s -ne 137 ] && [ $s -ne 9 ]; then exit $s; fi; echo \"[cowork] setup:native was killed; retrying in ${delay}s...\"; sleep $delay; delay=$((delay * 2)); if [ $delay -gt 20 ]; then delay=20; fi; i=$((i + 1)); done; exit $s",
79
79
  "setup:server": "npm install && npm rebuild --ignore-scripts=false better-sqlite3",
80
80
  "dev": "concurrently \"npm run dev:react\" \"npm run dev:electron\"",
81
81
  "dev:react": "vite",
82
82
  "dev:electron": "tsc -p tsconfig.electron.json && cross-env NODE_ENV=development electron .",
83
- "build": "npm run build:react && npm run build:electron && npm run build:daemon && npm run build:connectors",
83
+ "build": "npm run build:react && concurrently -n electron,daemon \"npm run build:electron\" \"npm run build:daemon\" && npm run build:connectors",
84
84
  "build:react": "vite build",
85
85
  "build:electron": "tsc -p tsconfig.electron.json",
86
86
  "build:daemon": "tsc -p tsconfig.daemon.json",
@@ -116,6 +116,7 @@
116
116
  "eventsource": "^4.1.0",
117
117
  "exceljs": "^4.4.0",
118
118
  "grammy": "^1.39.3",
119
+ "i18next": "^25.8.7",
119
120
  "jszip": "^3.10.1",
120
121
  "mammoth": "^1.11.0",
121
122
  "mime-types": "^3.0.2",
@@ -128,6 +129,7 @@
128
129
  "qrcode-terminal": "^0.12.0",
129
130
  "react": "^19.2.4",
130
131
  "react-dom": "^19.2.4",
132
+ "react-i18next": "^16.5.4",
131
133
  "react-markdown": "^10.1.0",
132
134
  "remark-breaks": "^4.0.0",
133
135
  "remark-gfm": "^4.0.1",
@@ -159,7 +161,7 @@
159
161
  "eslint": "^9.39.2",
160
162
  "globals": "^17.3.0",
161
163
  "oxlint": "^1.47.0",
162
- "typescript": "^5.7.3",
164
+ "typescript": "^5.9.0",
163
165
  "vite": "^7.3.1",
164
166
  "vite-plugin-electron": "^0.29.0",
165
167
  "vitest": "^4.0.18"
@@ -145,13 +145,16 @@ function ensureBetterSqlite3(env) {
145
145
  console.log(
146
146
  `[cowork] better-sqlite3 is missing; installing ${BETTER_SQLITE3_VERSION}...`
147
147
  );
148
+
148
149
  return run(
149
150
  NPM_CMD,
150
151
  [
151
152
  "install",
152
153
  "--no-audit",
153
154
  "--no-fund",
154
- "--ignore-scripts=false",
155
+ "--ignore-scripts",
156
+ "--omit=dev",
157
+ "--package-lock=false",
155
158
  "--no-save",
156
159
  `better-sqlite3@${BETTER_SQLITE3_VERSION}`,
157
160
  ],
@@ -210,6 +213,7 @@ function main() {
210
213
  const attempt = (attemptJobs) => {
211
214
  const env = baseEnvWithJobs(attemptJobs);
212
215
  const electronInstallScript = resolveFromCwd("electron/install.js");
216
+ const electronBinary = getElectronBinaryPath();
213
217
 
214
218
  if (!electronInstallScript) {
215
219
  console.error(
@@ -219,8 +223,12 @@ function main() {
219
223
  }
220
224
 
221
225
  // 1) Ensure Electron binary exists (postinstall is often skipped due to ignore-scripts=true).
222
- const installRes = run(process.execPath, [electronInstallScript], { env });
223
- if (installRes.status !== 0) return installRes;
226
+ if (electronBinary && fs.existsSync(electronBinary)) {
227
+ console.log("[cowork] Electron binary already present; skipping electron/install.js.");
228
+ } else {
229
+ const installRes = run(process.execPath, [electronInstallScript], { env });
230
+ if (installRes.status !== 0) return installRes;
231
+ }
224
232
 
225
233
  // If optional dependency install was skipped/failed earlier, recover here.
226
234
  const ensureBetterRes = ensureBetterSqlite3(env);
@@ -235,8 +243,8 @@ function main() {
235
243
  }`
236
244
  );
237
245
 
238
- // 2) Prefer the Electron-targeted rebuild for better-sqlite3.
239
- // This keeps binaries aligned with Electron ABI and avoids Node/host ABI mismatches.
246
+ // 2) electron-rebuild for the one module (keeps rebuild surface small).
247
+ // 2) Prefer an Electron-targeted rebuild for better-sqlite3 (often prebuilt, lighter).
240
248
  if (electronVersion) {
241
249
  const electronEnv = {
242
250
  ...env,
@@ -259,7 +267,8 @@ function main() {
259
267
  }
260
268
 
261
269
  console.log(
262
- "[cowork] better-sqlite3 did not load after Electron-targeted rebuild; falling back to electron-rebuild path with inferred settings."
270
+ "[cowork] better-sqlite3 did not load after Electron-targeted rebuild; " +
271
+ "falling back to electron-rebuild."
263
272
  );
264
273
  } else {
265
274
  console.log(
@@ -267,7 +276,7 @@ function main() {
267
276
  );
268
277
  }
269
278
 
270
- // 3) Fallback: electron-rebuild (most expensive). Keep it sequential and only rebuild the one module.
279
+ // 3) Fallback: electron-rebuild.
271
280
  const electronRebuildEntry = resolveFromCwd("@electron/rebuild");
272
281
  const electronRebuildCli = electronRebuildEntry
273
282
  ? path.join(path.dirname(electronRebuildEntry), "cli.js")
@@ -281,12 +290,25 @@ function main() {
281
290
 
282
291
  const rebuildRes = run(
283
292
  process.execPath,
284
- [electronRebuildCli, "-f", "--only", "better-sqlite3", "--sequential"],
293
+ [
294
+ electronRebuildCli,
295
+ "-f",
296
+ "--only",
297
+ "better-sqlite3",
298
+ "--sequential",
299
+ ],
285
300
  { env }
286
301
  );
287
302
  if (rebuildRes.status !== 0) return rebuildRes;
288
303
 
289
- return testBetterSqlite3InElectron(env);
304
+ const testRes = testBetterSqlite3InElectron(env);
305
+ if (testRes.status === 0) {
306
+ console.log("[cowork] better-sqlite3 loads in Electron.");
307
+ return testRes;
308
+ }
309
+
310
+ console.log("[cowork] better-sqlite3 did not load after electron-rebuild.");
311
+ return testRes;
290
312
  };
291
313
 
292
314
  let res = attempt(jobs);