Skip to content

release: sync develop -> main (cli 2.4.1 — readPackageVersion hook)#145

Merged
samuelds merged 7 commits into
mainfrom
release/sync-readpackageversion
May 24, 2026
Merged

release: sync develop -> main (cli 2.4.1 — readPackageVersion hook)#145
samuelds merged 7 commits into
mainfrom
release/sync-readpackageversion

Conversation

@samuelds
Copy link
Copy Markdown
Contributor

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

  • `@focus-mcp/cli` 2.4.0 → 2.4.1 (patch)
    • `FilesystemBrickSource.readPackageVersion()` — resolves `@focus-mcp/brick-/package.json` (with walk-up fallback) and returns the `version` string. Returns `undefined` if the package is absent or has no version field; mirrors the existing `readManifest()` resolution + `assertWithinBricksDir()` security check.
    • 6 new unit tests (24 total in `filesystem-source.test.ts`).

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

claude and others added 7 commits May 9, 2026 13:57
…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
Copilot AI review requested due to automatic review settings May 24, 2026 17:25
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

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 the version field.
  • 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.1 and document the patch in CHANGELOG.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.

@samuelds samuelds merged commit 508d24e into main May 24, 2026
15 checks passed
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.

2 participants