Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
16e8af3
ci: run CodeQL on develop branch as well (#4)
samuelds Apr 15, 2026
ea6d309
docs(prd): split PRD into per-repo focused docs (#2)
samuelds Apr 15, 2026
84adba5
feat(core): add brick loader with abstract source (#3)
samuelds Apr 15, 2026
3383666
feat(core): marketplace resolver (parse + find + semver + updates) (#5)
samuelds Apr 16, 2026
bc51101
style: migrate indent from 2 to 4 spaces (#6)
samuelds Apr 17, 2026
29d4285
docs: add CLAUDE.md (agent guidance, replaces ~/.claude memory) (#7)
samuelds Apr 17, 2026
3832ba8
chore: configure GitHub Packages for @focusmcp/* packages (#8)
samuelds Apr 20, 2026
953fa2a
feat: mandatory tool prefix in brick manifest (#10)
samuelds Apr 20, 2026
9a374c1
ci: add Claude Code Review action (#11)
samuelds Apr 21, 2026
80bdeb5
chore(ci): bump GitHub Actions to v5 (Node.js 24) (#14)
samuelds Apr 21, 2026
b74dda0
feat: enforce bare tool names in manifest — prefix applied at runtime…
samuelds Apr 22, 2026
8df9f55
feat(marketplace): add catalog-store, catalog-fetcher, installer modu…
samuelds Apr 22, 2026
843d164
feat: update default catalog URL to raw.githubusercontent.com (#17)
samuelds Apr 22, 2026
2866ec6
ci: add GitHub Packages publish workflow for dev channel (#18)
samuelds Apr 22, 2026
d7c120e
feat: rename npm scope from @focusmcp to @focus-mcp (#21)
samuelds Apr 22, 2026
8d820b5
fix(ci): add id-token permission for npm provenance (#22)
samuelds Apr 22, 2026
d7ddffa
feat(ci): dev publish workflow (#24)
samuelds Apr 22, 2026
db99bbb
fix(ci): use GitHub Packages for dev publish (#25)
samuelds Apr 23, 2026
ca06889
fix(ci): add id-token:write permission + remove duplicate workflows (…
samuelds Apr 23, 2026
d0b760b
chore(release): v1.0.0 + stable-publish workflow (#27)
samuelds Apr 23, 2026
abb8c08
docs: v1 cleanup — README, VISION, ARCHITECTURE (#30)
samuelds Apr 23, 2026
036359c
fix(ci): rename \`direct_prompt\` → \`prompt\` in claude-code-action …
samuelds Apr 23, 2026
4faa7ad
fix(ci): add checkout step to claude-review workflow (#34)
samuelds Apr 24, 2026
1f20ab2
chore: sync main back into develop (release bumps) (#35)
samuelds Apr 24, 2026
29d5edd
fix(catalog-store): allow removing default catalog with --force option
samuelds Apr 24, 2026
2fea2aa
chore(release): core 1.1.0
samuelds Apr 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions .changeset/config.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [["@focusmcp/core", "@focusmcp/sdk"]],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": ["@focusmcp/ui", "@focusmcp/tauri-app"],
"privatePackages": {
"version": false,
"tag": false
}
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [["@focus-mcp/core", "@focus-mcp/sdk"]],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": [],
"privatePackages": {
"version": false,
"tag": false
}
}
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 2
indent_size = 4

[*.md]
trim_trailing_whitespace = false
Expand Down
70 changes: 35 additions & 35 deletions .github/renovate.json
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended",
":semanticCommits",
":semanticCommitTypeAll(chore)",
"group:monorepos",
"group:recommended",
"schedule:weekly"
],
"labels": ["dependencies"],
"rangeStrategy": "bump",
"lockFileMaintenance": {
"enabled": true,
"schedule": ["before 5am on monday"]
},
"vulnerabilityAlerts": {
"labels": ["security"],
"schedule": ["at any time"]
},
"packageRules": [
{
"matchUpdateTypes": ["patch", "minor"],
"matchCurrentVersion": "!/^0/",
"automerge": true,
"automergeType": "branch"
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended",
":semanticCommits",
":semanticCommitTypeAll(chore)",
"group:monorepos",
"group:recommended",
"schedule:weekly"
],
"labels": ["dependencies"],
"rangeStrategy": "bump",
"lockFileMaintenance": {
"enabled": true,
"schedule": ["before 5am on monday"]
},
{
"matchPackageNames": ["typescript", "@biomejs/biome", "vitest"],
"automerge": false
"vulnerabilityAlerts": {
"labels": ["security"],
"schedule": ["at any time"]
},
{
"matchDepTypes": ["devDependencies"],
"automerge": true
}
],
"prHourlyLimit": 4,
"prConcurrentLimit": 10
"packageRules": [
{
"matchUpdateTypes": ["patch", "minor"],
"matchCurrentVersion": "!/^0/",
"automerge": true,
"automergeType": "branch"
},
{
"matchPackageNames": ["typescript", "@biomejs/biome", "vitest"],
"automerge": false
},
{
"matchDepTypes": ["devDependencies"],
"automerge": true
}
],
"prHourlyLimit": 4,
"prConcurrentLimit": 10
}
40 changes: 20 additions & 20 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ jobs:
name: Lint (Biome)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
- uses: actions/setup-node@v5
with:
node-version: 22
cache: pnpm
Expand All @@ -35,11 +35,11 @@ jobs:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
fetch-depth: 0
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
- uses: actions/setup-node@v5
with:
node-version: 22
cache: pnpm
Expand All @@ -50,9 +50,9 @@ jobs:
name: Typecheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
- uses: actions/setup-node@v5
with:
node-version: 22
cache: pnpm
Expand All @@ -63,15 +63,15 @@ jobs:
name: Test + Coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
- uses: actions/setup-node@v5
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm test:coverage
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v5
if: always()
with:
name: coverage
Expand All @@ -84,9 +84,9 @@ jobs:
if: github.event_name == 'pull_request'
continue-on-error: true
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
- uses: actions/setup-node@v5
with:
node-version: 22
cache: pnpm
Expand All @@ -102,16 +102,16 @@ jobs:
name: REUSE compliance
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: fsfe/reuse-action@v5

audit:
name: Dependency audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
- uses: actions/setup-node@v5
with:
node-version: 22
cache: pnpm
Expand All @@ -125,7 +125,7 @@ jobs:
name: Gitleaks (secret scan)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Install gitleaks
Expand All @@ -141,15 +141,15 @@ jobs:
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')
continue-on-error: true
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
- uses: actions/setup-node@v5
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm sbom
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v5
if: always()
with:
name: sbom
Expand All @@ -161,9 +161,9 @@ jobs:
runs-on: ubuntu-latest
needs: [typecheck, test]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
- uses: actions/setup-node@v5
with:
node-version: 22
cache: pnpm
Expand Down
42 changes: 42 additions & 0 deletions .github/workflows/claude-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# SPDX-FileCopyrightText: 2026 FocusMCP contributors
# SPDX-License-Identifier: MIT

name: Claude Code Review

on:
pull_request:
types: [opened, synchronize]
issue_comment:
types: [created]

jobs:
review:
if: |
(github.event_name == 'pull_request') ||
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude'))
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
issues: write
id-token: write
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
prompt: |
Review this pull request as a senior engineer. Post inline comments on issues you find. At the end, post a summary review with verdict (approve / request changes / comment).

Focus areas (in order of priority):
1. **Correctness** — does the code do what the PR description claims? Any obvious bugs, race conditions, or broken edge cases?
2. **Security** — input validation, injection risks, unsafe shell/eval, secret leaks, unsafe deps.
3. **Test coverage** — are new code paths tested? Any missing edge-case tests?
4. **TypeScript strictness** — no `any`, proper types, `node:` protocol for stdlib imports.
5. **Consistency** — matches surrounding patterns, naming conventions, file layout.
6. **Docs** — public API changes reflected in README/AGENTS.md.

Be terse and concrete. If the PR is clean, say "LGTM" and approve. Do not hedge.
Reject `--no-verify` and any bypasses of CI gates in the code.
10 changes: 5 additions & 5 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ name: CodeQL

on:
push:
branches: [main]
branches: [main, develop]
pull_request:
branches: [main]
branches: [main, develop]
schedule:
- cron: '0 6 * * 1'
workflow_dispatch:
Expand All @@ -31,11 +31,11 @@ jobs:
matrix:
language: [typescript]
steps:
- uses: actions/checkout@v4
- uses: github/codeql-action/init@v3
- uses: actions/checkout@v5
- uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
config-file: ./.github/codeql-config.yml
- uses: github/codeql-action/analyze@v3
- uses: github/codeql-action/analyze@v4
with:
category: /language:${{ matrix.language }}
78 changes: 78 additions & 0 deletions .github/workflows/dev-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# SPDX-FileCopyrightText: 2026 FocusMCP contributors
# SPDX-License-Identifier: MIT

name: Dev Publish

on:
push:
branches: [develop]
workflow_dispatch:

permissions:
contents: read
packages: write
id-token: write

concurrency:
group: dev-publish-${{ github.ref }}
cancel-in-progress: true

jobs:
publish-dev:
name: Publish @focus-mcp/* dev packages
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v5
with:
node-version: 22
cache: pnpm
registry-url: https://registry.npmjs.org
scope: '@focus-mcp'
- run: pnpm install --frozen-lockfile
- name: Compute dev version
id: version
run: |
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || git rev-list --max-parents=0 HEAD)
DEV_NUM=$(git rev-list --count ${LAST_TAG}..HEAD)
BASE_VERSION=$(node -e "const p=require('./package.json'); console.log(p.version || '0.1.0')")
DEV_VERSION="${BASE_VERSION}-dev.${DEV_NUM}"
echo "version=${DEV_VERSION}" >> "$GITHUB_OUTPUT"
echo "Dev version: ${DEV_VERSION}"
- name: Set dev versions on all packages
env:
DEV_VERSION: ${{ steps.version.outputs.version }}
run: |
for dir in packages/*/; do
if [ -f "${dir}package.json" ]; then
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('${dir}package.json', 'utf-8'));
if (pkg.private !== true) {
pkg.version = process.env.DEV_VERSION;
fs.writeFileSync('${dir}package.json', JSON.stringify(pkg, null, 4) + '\n');
console.log(' → ' + pkg.name + '@' + process.env.DEV_VERSION);
}
"
fi
done
- run: pnpm build
- name: Publish all packages with dev tag
run: |
for dir in packages/*/; do
if [ -f "${dir}package.json" ]; then
PRIVATE=$(node -e "console.log(require('./${dir}package.json').private)")
if [ "$PRIVATE" != "true" ]; then
NAME=$(node -e "console.log(require('./${dir}package.json').name)")
echo "Publishing ${NAME}..."
cd "$dir"
npm publish --tag dev --access public 2>&1 || echo " → skipped"
cd ../..
fi
fi
done
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Loading
Loading