Skip to content

chore: streamline toolchain, packaging and CI - #3

Open
Maximvdw wants to merge 6 commits into
masterfrom
chore/streamline
Open

chore: streamline toolchain, packaging and CI#3
Maximvdw wants to merge 6 commits into
masterfrom
chore/streamline

Conversation

@Maximvdw

@Maximvdw Maximvdw commented Aug 9, 2026

Copy link
Copy Markdown
Member

Brings this module onto the shared OpenHPS toolchain baseline, applied by the openhps-devtools codemod so every repository lands the same shape.

Toolchain: TypeScript 5.9, ESLint 9 with a native flat config, typescript-eslint 8, prettier 3, mocha 11, chai 6, c8, typedoc 0.28, @types/node 24, engines.node >=22. npm replaces yarn, with npm ci in CI instead of the bare npm install/yarn install that silently rewrote lockfiles.

Packaging: types resolves to dist/types, the exports map lists types first in every condition and points import at dist/esm, and the redundant esm5 target is gone — its tsconfig used target es6 while the esm one used es2015, the same TypeScript alias. tslib is now declared, since the tsconfig sets both importHelpers and noEmitHelpers, a combination that always emits an import of it.

scripts/finalize-esm.mjs makes dist/esm genuinely loadable as ES modules: it writes the per-directory type markers — without which both Node and webpack parse the output as CommonJS and fail on the first import — and rewrites TypeScript's directory imports to the explicit file paths Node's ESM resolver requires.

Dependency policy: @openhps/* peer ranges gain an upper bound (>=1.0.16 <2") and every declared peer has a matching devDependency, so CI tests what consumers receive. scripts/check-peers.mjs` enforces both as part of lint.

CI: replaces a hand-forked main.yml with a thin caller onto OpenHPS/workflows. The fleet had 24 distinct variants of that file. Every job now installs its own dependency tree rather than depending on an actions/cache hit for node_modules, lint no longer waits on build, and the matrix covers Node 22 and 24.

Coverage moves from nyc to c8: nyc 18's spawn-wrap breaks down on Node 22, running the tests while reporting 0 passing and 0% coverage.

The ESM smoke test still resolves @openhps/core from the registry, where 1.0.16 ships the old dist/esm5 with directory imports. It passes against a locally built core and will pass here once core is released.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FtN6Tx33QW5a6AtCH1zYQh

Maximvdw and others added 6 commits August 9, 2026 17:51
npm is the package manager fleet-wide. Every CI workflow previously ran a bare
`yarn install` or `npm install` rather than a frozen install, so lockfiles
silently churned in CI. Yarn 1.22 is unmaintained; npm ships with Node 22 and 24,
supports `overrides` for transitive CVE pinning, and can publish with
`--provenance`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FtN6Tx33QW5a6AtCH1zYQh
tsconfig.bundle.esm5.json used target "es6" while tsconfig.bundle.esm.json used
"es2015" -- the same TypeScript alias, with the same module: es2020 -- so the
esm5 output was pure duplication, and exports.import pointed at it while dist/esm
went unreachable.

scripts/finalize-esm.mjs now post-processes dist/esm so it is genuinely loadable as
ES modules: it writes the per-directory "type" markers (without which both Node
and webpack read the output as CommonJS and fail on the first import statement) and
rewrites TypeScript's directory imports to explicit file paths, which Node's ESM
resolver requires.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FtN6Tx33QW5a6AtCH1zYQh
Replaces a hand-forked main.yml with a thin caller. The fleet had 24 distinct
variants of that file, Node was unpinned in 22 repositories, and 13 ran
`npm install` rather than `npm ci`.

Every job now installs its own dependency tree instead of depending on an
actions/cache hit for node_modules, lint no longer waits on build, and the matrix
covers Node 22 and 24. dependabot.yml and the auto-merge workflow arrive here for
the first time outside openhps-core.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FtN6Tx33QW5a6AtCH1zYQh
TypeScript 5.9, ESLint 9 with a native flat config, typescript-eslint 8,
prettier 3, mocha 11, chai 6, c8, typedoc 0.28, @types/node 24, engines.node >=22.

Packaging is brought onto the fleet contract: `types` resolves to dist/types
rather than dist/cjs, the exports map lists `types` first in every condition and
points `import` at dist/esm, and tslib is declared -- the tsconfig sets both
importHelpers and noEmitHelpers, a combination that always emits an import of
tslib, which previously resolved only by hoisting.

@openhps/* peer ranges gain an upper bound (">=1.0.16 <2"), and every declared
peer now has a matching devDependency so CI tests what consumers receive;
scripts/check-peers.mjs enforces both as part of lint.

Coverage moves from nyc to c8: nyc 18's spawn-wrap breaks down on Node 22, running
the tests but reporting 0 passing and 0% coverage. cover:ci also writes a real
test-results.xml -- reporterEnabled had been sitting at the top level of
.mocharc.json where mocha ignores it, so the JUnit file CI consumed had never been
produced.

standard-version is replaced by commit-and-tag-version (unmaintained since 2023),
and eslint-plugin-deprecation by @typescript-eslint/no-deprecated (archived).
CONTRIBUTING.md and SECURITY.md move to the org-wide OpenHPS/.github repository.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FtN6Tx33QW5a6AtCH1zYQh
Formatting only. The lint script was `eslint src/**`, so test/ had never been seen
by prettier; widening it to `eslint .` surfaced hundreds of formatting-only
findings. Kept separate so the toolchain diff stays reviewable.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FtN6Tx33QW5a6AtCH1zYQh
`this.globalSystemUID === undefined;` is an expression statement that does nothing —
`===` where `=` was meant. Destroying the global VSLAM system therefore left
`globalSystemUID` pointing at a system that had just been deleted. Found by
@typescript-eslint/no-unused-expressions, which this repository had never run.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FtN6Tx33QW5a6AtCH1zYQh
@Maximvdw

Maximvdw commented Aug 9, 2026

Copy link
Copy Markdown
Member Author

CI cannot pass until the native OpenCV build is resolved — the same blocker as OpenHPS/openhps-opencv#1, inherited transitively.

@openhps/opencv runs build:opencv from its postinstall, compiling OpenCV 4.6.0 from source, and that fails on a modern toolchain. npm ci therefore fails here before any job runs. This PR does not change that; #2 tracks the deprecate-vs-fix decision for this package.

Verified locally against an install with --ignore-scripts:

  • npm run build succeeds
  • npm run lint reports 0 errors

Linting this repository for the first time also surfaced a real defect, fixed here: VSLAMService wrote this.globalSystemUID === undefined; where it meant =, so destroying the global VSLAM system left the UID pointing at a system that had just been deleted.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant