release: sync develop -> main (cli 2.4.1 — readPackageVersion hook)#145
Merged
Conversation
…09-post-readme-align chore: back-merge main into develop (post-readme-align 2026-05-09)
Implements the optional BrickSource.readPackageVersion() hook so the
core brick-loader can inject a brick's package.json version into its
manifest when mcp-brick.json doesn't carry a "version" field (the
current shape of every published @focus-mcp/brick-* package).
Without this, parseManifest() throws INVALID_VERSION at load time
because the disk manifest and the JS module's exported manifest both
lack a SemVer "version".
Implementation mirrors readManifest():
- Preferred: require.resolve('@focus-mcp/brick-<name>/package.json')
which works unconditionally since Node 14 (./package.json is always
exported, regardless of the package's exports field).
- Fallback: walk up from the package's main entry until a
package.json is found (handles older bricks that restrict exports).
- Returns undefined when no package.json is found or it has no string
version field — the loader is then free to fall back to its existing
INVALID_VERSION behaviour.
Adds 4 unit tests covering: direct resolve happy path, walk-up
fallback on ERR_PACKAGE_PATH_NOT_EXPORTED, missing version field, and
total miss.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…curity test Addresses copilot[bot] review on PR #144 plus a biome complexity rule: - Bug: if the package itself isn't installed, the first require.resolve('.../package.json') throws MODULE_NOT_FOUND, the fallback then calls require.resolve('@focus-mcp/brick-<name>') which also throws MODULE_NOT_FOUND — and that throw wasn't caught, breaking the JSDoc contract ("returns undefined if not found"). Now caught. - Security: added a test for assertWithinBricksDir() on readPackageVersion() — symlink/alias escape protection. - Complexity: extracted three helpers (resolvePackageJsonPath, resolvePackageMain, walkUpForPackageJson, extractVersion) so the public method's cyclomatic complexity drops back under Biome's threshold of 15. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-package-version feat(source): add readPackageVersion to FilesystemBrickSource
There was a problem hiding this comment.
Pull request overview
Syncs develop into main for the @focus-mcp/cli@2.4.1 release, including a new FilesystemBrickSource.readPackageVersion() hook implementation so @focus-mcp/core can inject a missing SemVer version into brick manifests.
Changes:
- Add
FilesystemBrickSource.readPackageVersion()that resolves@focus-mcp/brick-<name>/package.json(with a walk-up fallback) and extracts theversionfield. - Add unit tests covering direct resolve, fallback walk-up, missing version, missing package.json, missing package, and bricksDir escape protection.
- Bump CLI version to
2.4.1and document the patch inCHANGELOG.md.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/source/filesystem-source.ts | Implements readPackageVersion() plus helper resolution/extraction logic, reusing bricksDir containment checks. |
| src/source/filesystem-source.test.ts | Adds test coverage for readPackageVersion() success/fallback/undefined/error cases. |
| package.json | Bumps package version to 2.4.1. |
| CHANGELOG.md | Adds 2.4.1 release notes describing the new hook and behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Sync `develop` → `main` to publish `@focus-mcp/cli@2.4.1`.
Bundles the fix from #144: adds the optional `BrickSource.readPackageVersion()` hook implementation on `FilesystemBrickSource`, so the core brick-loader can inject the package.json version into the manifest when `mcp-brick.json` doesn't carry one (currently the case for every published `@focus-mcp/brick-*` package).
Included changes
Post-merge
`stable-publish` workflow on main publishes `2.4.1` to npm via Trusted Publishers OIDC.
Dependency on core
This release ships the hook implementation. The hook is consumed by the corresponding change in `@focus-mcp/core` (`BrickSource.readPackageVersion?()` optional interface + `brick-loader.ts` injects the result into both raw manifests before `parseManifest()`). Until that core change is published, the hook is dead code — but it ships safely as a no-op extra method.
🤖 Generated with Claude Code