fix: cap pm item reads at 64 MiB instead of Node's 1 MiB spawnSync default

Merged
UN
3mo ago
+210-6

Problem

readPmItems() — the documented safe read pattern every demo reuses spawns the pm CLI to read items but passes no maxBuffer, so Node's 1 MiB spawnSync default applies.

Measured with this package's exact argv against a real 443-item pm workspace: 1,054,002 bytes — over the cap, failing today.

Past the cap the child is killed and the result comes back as:

status: null   signal: SIGTERM   error.code: ENOBUFS   stderr: ""

Because stderr is empty, the failure surfaced with nothing to diagnose. And at larger sizes stdout is genuinely truncated mid-document — verified by forcing a 100 KiB cap on the same workspace:

JSON.parse -> Unterminated string in JSON at position 130829

Because this path is contractually never-throw (return [] on any failure), a read failure was indistinguishable from an empty workspace — every demo would show no items and look correct. The cap fix is paired with a stderr line so the cause is visible without breaking the contract.

This was a straggler: pm-changelog, pm-context, pm-brief, pm-graph and pm-linear already cap their pm reads explicitly. A fleet-wide audit this session found 8 packages that did not.

Change

  • cap the pm read at 64 MiB, matching the sibling packages
  • report an ENOBUFS overrun explicitly — naming the limit and the remedy — instead of an unexplained failure

Verification

Same argv, same real 443-item workspace:

read bufferresult
Node default (1 MiB)status: null, ENOBUFS, empty stderr
64 MiB (this PR)status: 0, complete payload

Typecheck and the full test suite pass; changelog:check green.

pm items

itemstatus
pm-starter-y8hb — pm item reads are capped at Node's 1 MiB spawnSync default, so a mature tracker fails with no diagnosisclosed

Companion-tracked fleet sweep; the same fix landed in pm-github (unbraind/pm-github#13), where it additionally unblocked --atomic --dry-run.

🤖 Generated with Claude Code


Summary by cubic

Capped pm item reads at 64 MiB with a per‑call PM_JSON_MAX_BUFFER override and clearer errors so large or failing workspaces don’t look empty. Malformed overrides now fall back to the default instead of imposing tiny caps.

  • Bug Fixes
    • Resolve PM_JSON_MAX_BUFFER on every readPmItems call; reject invalid/non‑positive values with Number() + isSafeInteger; overrun message names the actual byte limit and points to the env var. Matches sibling packages and resolves pm-starter-y8hb.
    • Keep the never‑throw [] contract but log ENOBUFS and non‑zero exits (exit code + stderr); restored the safe‑read JSDoc in the emitted d.ts.
    • Added smoke tests for a forced 64‑byte cap and malformed overrides; disabled jshint on generated dist/ in Hound to avoid ES5 lint noise.