Skip to content

fix: ship js-yaml as a runtime dependency - #1010

Merged
tomdps merged 2 commits into
the-open-engine:mainfrom
s0kil:fix/js-yaml-runtime-dependency
Aug 12, 2026
Merged

fix: ship js-yaml as a runtime dependency#1010
tomdps merged 2 commits into
the-open-engine:mainfrom
s0kil:fix/js-yaml-runtime-dependency

Conversation

@s0kil

@s0kil s0kil commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Problem

Every cluster that finishes in a worktree crashes during auto-stop:

Failed to auto-stop cluster zen-spire-47: Cannot find module 'js-yaml'
Require stack:
- .../@the-open-engine/zeroshot/lib/compose-utils.js
- .../@the-open-engine/zeroshot/src/orchestrator.js
- .../@the-open-engine/zeroshot/cli/index.js

lib/compose-utils.js (built from src/legacy-lib/compose-utils.ts) requires js-yaml at runtime, but js-yaml was declared as a devDependency. npm-shrinkwrap.json therefore marked it "dev": true, so no consumer install ever received it.

Flat npm trees could mask this by hoisting js-yaml from an unrelated package into top-level node_modules. pnpm's isolated store has no such accident, so the failure surfaced there first — but the dependency was never actually declared for any install.

A second defect turned a cosmetic gap into a fatal one: both call sites require('../lib/compose-utils') outside their try blocks, so a module-resolution failure escaped the "best-effort, silently ignores failures" contract and aborted cluster shutdown.

Changes

  • Move js-yaml from devDependencies to dependencies; regenerate package-lock.json / npm-shrinkwrap.json (clears dev: true on js-yaml and its argparse dependency).
  • Update checkScriptDependencies() in scripts/rust-distribution.js, which asserted the devDependency placement and would have failed the release integrity gate.
  • Load lib/compose-utils inside the teardown try blocks in src/orchestrator.js and src/isolation-manager.js so compose cleanup stays best-effort. Orchestrator logs the skip reason; worktree removal still proceeds.

Tests

  • tests/unit/published-runtime-dependencies.test.js (new): scans every published CommonJS file (respecting the files allow/deny list) and asserts each bare require() resolves to a declared runtime or optional dependency. This is the guard that would have caught the bug at commit time.
  • tests/worktree-compose-cleanup.test.js: two regression tests covering an unloadable lib/compose-utils — teardown is skipped without throwing, and worktree removal still runs.
  • tests/unit/rust-release-workflow-dependencies.test.js: updated for the new dependency placement.

Verification

npm test    # 2903 passing, 18 pending
npm run lint         # 0 errors
npm run typecheck    # clean
npm ls --omit=dev js-yaml
└── js-yaml@4.2.0    # previously unresolvable in a production install

3 pre-existing failures in tests/unit/opcore-introduced-gate.test.js reproduce identically on unmodified main in this environment (local rust.function-metrics reports unsupported_request) and are unrelated to this change.

🤖 Generated with Claude Code

lib/compose-utils.js requires js-yaml, but js-yaml was declared as a
devDependency, so npm-shrinkwrap.json marked it "dev": true and no
consumer install ever received it. Worktree Compose teardown then threw
MODULE_NOT_FOUND while auto-stopping a finished cluster:

  Failed to auto-stop cluster <id>: Cannot find module 'js-yaml'
  Require stack:
  - .../@the-open-engine/zeroshot/lib/compose-utils.js
  - .../@the-open-engine/zeroshot/src/orchestrator.js

Flat npm trees could mask it by hoisting js-yaml from another package;
pnpm's isolated store cannot, so it surfaced there first.

Move js-yaml to dependencies, update the release integrity check that
asserted the devDependency placement, and load lib/compose-utils inside
the teardown try blocks so best-effort cleanup stays best-effort instead
of aborting cluster shutdown.

Adds a guard test asserting published files only require declared
runtime dependencies.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@s0kil

s0kil commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

Closes #1009

@greptile-apps

greptile-apps Bot commented Aug 12, 2026

Copy link
Copy Markdown

Greptile Summary

The PR makes js-yaml available to published installations and keeps Compose cleanup best-effort when teardown support cannot load.

  • Moves js-yaml into runtime dependencies and synchronizes the lock and shrinkwrap metadata.
  • Moves Compose utility loading inside guarded teardown paths.
  • Adds release-integrity and published-runtime dependency checks.
  • Adds regression coverage for unloadable Compose support and continued worktree removal.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
package.json Moves js-yaml from development-only installation to the published runtime dependency set.
npm-shrinkwrap.json Pins js-yaml 4.3.1 and argparse in the production dependency closure.
package-lock.json Synchronizes the root dependency placement and resolved production dependency metadata.
src/isolation-manager.js Guards Compose utility loading, emits a warning on failure, and allows worktree removal to continue.
src/orchestrator.js Makes Compose teardown support best-effort and logs why teardown was skipped.
scripts/rust-distribution.js Updates release integrity validation to require js-yaml as a runtime dependency.
tests/unit/published-runtime-dependencies.test.js Adds a package-surface check for undeclared bare CommonJS runtime imports.
tests/unit/rust-release-workflow-dependencies.test.js Updates release workflow tests for js-yaml's runtime placement.
tests/worktree-compose-cleanup.test.js Verifies unloadable Compose support is diagnosed without blocking worktree cleanup.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Cluster teardown] --> B[Load compose-utils]
  B -->|Success| C[Resolve worktree Compose teardown]
  C -->|Scoped Compose project| D[Run docker compose down]
  C -->|No eligible project| E[Skip Compose teardown]
  B -->|Load or resolution error| F[Log skip reason]
  D --> G[Remove worktree]
  E --> G
  F --> G
Loading

Reviews (2): Last reviewed commit: "fix: update js-yaml to patched release" | Re-trigger Greptile

Comment thread src/isolation-manager.js Outdated

@tomdps tomdps left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed the published-runtime regression and reviewed the fix end to end. js-yaml is now shipped at patched 4.3.1, both lockfiles remain synchronized, teardown failures are diagnosed without blocking worktree removal, and focused plus full CI—including production audit and Ubuntu/macOS install checks—passes on this exact head.

@tomdps
tomdps added this pull request to the merge queue Aug 12, 2026
Merged via the queue into the-open-engine:main with commit 7475fa3 Aug 12, 2026
12 checks passed
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 6.39.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants