prjct-cli 3.15.0 → 3.15.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [3.15.1] - 2026-07-02
6
+
7
+ ### Bug Fixes
8
+
9
+ - harden session ships — sync ping-pong, node 22.5–22.12 fallback, classifier false positives (#501)
10
+
11
+
5
12
  ## [3.15.0] - 2026-07-01
6
13
 
7
14
  ### Features
package/bin/prjct.cjs CHANGED
@@ -285,31 +285,47 @@ function runWithNode(args) {
285
285
  * Fastest path: run the bundled entry IN-PROCESS under the node that already
286
286
  * booted to run this launcher — NO second runtime boot. The historical design
287
287
  * spawned a fresh bun/node process solely to inject `--experimental-sqlite`;
288
- * but node:sqlite is available WITHOUT that flag on node >=22.5 (the supported
289
- * minimum), so the second process is pure overhead (~40ms). The bundled
290
- * `dist/bin/prjct.mjs` is a thin cold-entry (daemon client) that reads
291
- * process.argv directlyidentical argv in-process vs spawned and calls
292
- * process.exit() itself, so once imported it OWNS the process.
288
+ * when node:sqlite loads WITHOUT that flag (node >=22.13 / >=23.4), the second
289
+ * process is pure overhead (~40ms). The bundled `dist/bin/prjct.mjs` is a thin
290
+ * cold-entry (daemon client) that reads process.argv directly — identical argv
291
+ * in-process vs spawned and calls process.exit() itself, so once imported it
292
+ * OWNS the process.
293
293
  *
294
294
  * Returns true once the entry has started (caller must NOT fall through to a
295
295
  * spawn, or the command would run twice). Returns false only when in-process
296
- * load is not viable (old node, missing bundle, Windows) or the module fails
297
- * to load — then the caller falls back to the spawn path.
296
+ * load is not viable (old node, missing bundle, Windows, flagged sqlite) or
297
+ * the module fails to load — then the caller falls back to the spawn path.
298
298
  */
299
299
  async function runInProcess() {
300
300
  // Windows keeps the well-tested spawn path (shim/pathext nuances).
301
301
  if (process.platform === 'win32') return false
302
302
  const distBin = path.join(ROOT_DIR, 'dist', 'bin', 'prjct.mjs')
303
303
  if (!fs.existsSync(distBin) || !nodeVersionOk()) return false
304
- // node:sqlite is experimental on node 22.x suppress the cosmetic
305
- // ExperimentalWarning so stderr stays clean for `--md` consumers (the
306
- // module is functionally available without the flag).
304
+ // node:sqlite still emits a one-time ExperimentalWarning on some versions
305
+ // suppress ONLY that warning class so stderr stays clean for `--md`
306
+ // consumers without muting genuine sqlite-related warnings. Installed BEFORE
307
+ // the probe below, which would otherwise trip the warning itself.
307
308
  const origEmit = process.emitWarning.bind(process)
308
309
  process.emitWarning = (warning, ...rest) => {
309
310
  const msg = typeof warning === 'string' ? warning : warning?.message || ''
310
- if (typeof msg === 'string' && /sqlite/i.test(msg)) return
311
+ const name =
312
+ (typeof warning === 'object' && warning?.name) ||
313
+ (typeof rest[0] === 'string' ? rest[0] : rest[0]?.type) ||
314
+ ''
315
+ if (name === 'ExperimentalWarning' && typeof msg === 'string' && /sqlite/i.test(msg)) return
311
316
  return origEmit(warning, ...rest)
312
317
  }
318
+ // In-process cannot inject NODE_OPTIONS, so node:sqlite must be loadable
319
+ // WITHOUT --experimental-sqlite. That's node >=22.13 / >=23.4; on 22.5–22.12
320
+ // the flag is still required. Probe instead of hardcoding version ranges —
321
+ // if the un-flagged require throws, fall back to the spawn path (which
322
+ // injects the flag) so those versions keep working.
323
+ try {
324
+ require('node:sqlite')
325
+ } catch {
326
+ process.emitWarning = origEmit
327
+ return false
328
+ }
313
329
  try {
314
330
  // Resolves when the entry's top-level finishes; the entry keeps the event
315
331
  // loop alive (daemon socket / core fallback) and exits the process itself.