Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .changeset/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ SPDX-License-Identifier: MIT

This folder holds the FocusMCP CLI changesets. Every PR that changes user-facing behaviour must add a changeset via `pnpm changeset`.

- Mode: **single package** — `@focusmcp/cli` is published as one npm package.
- `access: public` — published to the public npm registry on the `@focusmcp/` scope.
- Mode: **single package** — `@focus-mcp/cli` is published as one npm package.
- `access: public` — published to the public npm registry on the `@focus-mcp/` scope.
- `baseBranch: develop` — changesets are opened against `develop` and promoted to `main` at release time.

Format: Markdown with frontmatter listing the package + bump level (patch / minor / major).
Expand Down
14 changes: 7 additions & 7 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

name: Setup toolchain
description: |
Clone @focusmcp/core as a sibling directory (../core), install and build it,
Clone @focus-mcp/core as a sibling directory (../core), install and build it,
then set up pnpm + Node and install this repo's dependencies.
The CLI depends on `@focusmcp/core` via a `file:../core/packages/core` path,
The CLI depends on `@focus-mcp/core` via a `file:../core/packages/core` path,
so the sibling must exist and have a built `dist/` before `pnpm install`.

inputs:
Expand All @@ -17,7 +17,7 @@ inputs:
runs:
using: composite
steps:
- name: Checkout @focusmcp/core (inside workspace — actions/checkout restriction)
- name: Checkout @focus-mcp/core (inside workspace — actions/checkout restriction)
uses: actions/checkout@v4
with:
repository: focus-mcp/core
Expand All @@ -26,7 +26,7 @@ runs:
fetch-depth: 1

# actions/checkout refuses paths outside the workspace; move it to the real sibling now.
- name: Move @focusmcp/core to sibling location
- name: Move @focus-mcp/core to sibling location
shell: bash
run: |
mv "$GITHUB_WORKSPACE/.core-sibling" "$GITHUB_WORKSPACE/../core"
Expand All @@ -41,15 +41,15 @@ runs:
cache: pnpm
registry-url: 'https://registry.npmjs.org'

- name: Install @focusmcp/core dependencies
- name: Install @focus-mcp/core dependencies
shell: bash
working-directory: ../core
run: pnpm install --frozen-lockfile

- name: Build @focusmcp/core
- name: Build @focus-mcp/core
shell: bash
working-directory: ../core
run: pnpm --filter "@focusmcp/core" build
run: pnpm --filter "@focus-mcp/core" build

- name: Install CLI dependencies
shell: bash
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/dev-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ on:

permissions:
contents: read
packages: write

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

jobs:
publish-dev:
name: Publish @focusmcp/cli@dev
name: Publish @focus-mcp/cli@dev
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
Expand All @@ -28,7 +29,7 @@ jobs:
with:
node-version: 22
registry-url: https://registry.npmjs.org
scope: '@focusmcp'
scope: '@focus-mcp'
- name: Compute dev version
id: version
run: |
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/publish-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ permissions:

jobs:
publish:
name: Publish @focusmcp/cli to GitHub Packages
name: Publish @focus-mcp/cli to npmjs.org
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
Expand All @@ -24,9 +24,9 @@ jobs:
with:
node-version: 22
cache: pnpm
registry-url: https://npm.pkg.github.com
scope: '@focusmcp'
registry-url: https://registry.npmjs.org
scope: '@focus-mcp'
- run: pnpm build
- run: npm publish --access public 2>&1 || echo "→ skipped (already published or error)"
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
12 changes: 6 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Read [PRD.md](./PRD.md) for the complete CLI vision (commands, transport, distri

- **Node.js ≥ 22** (LTS), **pnpm ≥ 10**, **TypeScript 5.7+** strict
- **ESM only** (`"type": "module"`)
- **Single package** — `@focusmcp/cli` published to npm under the `@focusmcp` scope
- **Single package** — `@focus-mcp/cli` published to npm under the `@focusmcp` scope
- Tests: **Vitest**
- Lint/format: **Biome 2.x**
- Build: **tsup** (ESM, Node 22 target, dts for the programmatic entry only)
Expand All @@ -38,14 +38,14 @@ Source code lives in `src/`:

1. **Strict TDD** — write the test BEFORE the code (Red → Green → Refactor). Coverage ≥ 80 % global.
2. **No `any`**, no untyped catch, no `!` non-null assertions.
3. **No `console.log` outside `src/bin/` and `src/commands/`.** The Biome override allows console in those two folders (they are the CLI surface); everywhere else, use structured logging via `@focusmcp/core`.
3. **No `console.log` outside `src/bin/` and `src/commands/`.** The Biome override allows console in those two folders (they are the CLI surface); everywhere else, use structured logging via `@focus-mcp/core`.
4. **SPDX header** in every source file: `SPDX-FileCopyrightText: 2026 FocusMCP contributors` + `SPDX-License-Identifier: MIT`.
For JSON files (no comment support), create a sibling `.license` file (REUSE convention).
5. **Imports**: `node:` protocol (`import { parseArgs } from 'node:util'`).
6. **Commits**: [Conventional Commits](https://www.conventionalcommits.org/) — allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`.
7. **No unsolicited features** — stick strictly to the requested scope.
8. **stdio MCP is the canonical transport.** An HTTP admin API is Phase 2, gated behind an explicit flag; it is not the way AI clients attach.
9. **`@focusmcp/core` is a git dependency** (`github:focus-mcp/core`). Do not try to publish `@focusmcp/core` to npm from this repo.
9. **`@focus-mcp/core` is a git dependency** (`github:focus-mcp/core`). Do not try to publish `@focus-mcp/core` to npm from this repo.
10. **Pure command functions.** Every `src/commands/<name>.ts` exports a function that takes already-parsed state (or structured input) and returns the string to print — no I/O, no `process.exit`. The binary in `src/bin/focus.ts` is the only layer allowed to touch `process.*`, stdin/stdout, and the filesystem.

## Commands
Expand All @@ -68,9 +68,9 @@ pnpm changeset # create a changeset before merging
AI client (Claude Code, Cursor, …)
│ stdio (JSON-RPC / MCP)
@focusmcp/cli (focus start)
@focus-mcp/cli (focus start)
├─ @modelcontextprotocol/sdk StdioServerTransport
├─ @focusmcp/core (createFocusMcp)
├─ @focus-mcp/core (createFocusMcp)
│ Registry + EventBus + Router + bricks
└─ ~/.focus/center.json + ~/.focus/center.lock
```
Expand All @@ -87,7 +87,7 @@ AI client (Claude Code, Cursor, …)

- **No secrets** in the code (gitleaks blocks in pre-commit and CI).
- **No `eval`**, no `new Function()`.
- Every external input (center.json, center.lock) is validated structurally before reaching `@focusmcp/core`.
- Every external input (center.json, center.lock) is validated structurally before reaching `@focus-mcp/core`.

## Git remote

Expand Down
32 changes: 16 additions & 16 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ SPDX-FileCopyrightText: 2026 FocusMCP contributors
SPDX-License-Identifier: MIT
-->

# CLAUDE.md — @focusmcp/cli
# CLAUDE.md — @focus-mcp/cli

> Auto-loaded by Claude Code (and any agents.md-compatible tool) when working in this repo.
> This file is the **source of truth for AI agent behaviour** on this project. It replaces the
Expand All @@ -14,16 +14,16 @@ SPDX-License-Identifier: MIT
**FocusMCP** — orchestrateur MCP. Reduces AI-agent context from 200k to ~2k tokens by composing
**briques** (atomic MCP modules). Site [focusmcp.dev](https://focusmcp.dev).

Ce repo est **le point d'entrée primaire** : `@focusmcp/cli`, une CLI Node publiée sur npm,
qui embarque `@focusmcp/core` et parle **stdio MCP** (via `@modelcontextprotocol/sdk`) aux
Ce repo est **le point d'entrée primaire** : `@focus-mcp/cli`, une CLI Node publiée sur npm,
qui embarque `@focus-mcp/core` et parle **stdio MCP** (via `@modelcontextprotocol/sdk`) aux
clients AI (Claude Code, Cursor, Codex, Gemini CLI…).

## Écosystème (3 repos actifs + 1 archivé)

| Repo | Rôle |
|---|---|
| `focus-mcp/core` | Monorepo lib TS — 3 piliers (Registry/EventBus/Router) + SDK/Validator/Marketplace resolver. Importé par ce repo via `file:../core/packages/core`. |
| `focus-mcp/cli` (ici) | `@focusmcp/cli` — stdio MCP, brick manager (`focus list/info/add/remove/...`). Publié npm. |
| `focus-mcp/cli` (ici) | `@focus-mcp/cli` — stdio MCP, brick manager (`focus list/info/add/remove/...`). Publié npm. |
| `focus-mcp/marketplace` | Catalogue officiel + `bricks/*` + `modules/*` (dont `manager` = dashboard optionnel). |
| `focus-mcp/client` | **archivé** — ex desktop Tauri, gelé post-pivot CLI-first. |

Expand All @@ -33,21 +33,21 @@ clients AI (Claude Code, Cursor, Codex, Gemini CLI…).
AI client (Claude Code, Cursor, Codex, Gemini…)
│ stdio (JSON-RPC MCP)
@focusmcp/cli (ce repo)
@focus-mcp/cli (ce repo)
├─ @modelcontextprotocol/sdk StdioServerTransport
├─ @focusmcp/core (Registry + EventBus + Router + bricks loader)
├─ @focus-mcp/core (Registry + EventBus + Router + bricks loader)
└─ (opt-in P1) admin API HTTP côté latéral (consommé par marketplace/modules/manager)
```

**Distribution** : `npm install -g @focusmcp/cli` ou `npx @focusmcp/cli start`.
**Distribution** : `npm install -g @focus-mcp/cli` ou `npx @focus-mcp/cli start`.
**Claude Code plugin** natif via `.claude-plugin/plugin.json` :

```json
{
"mcpServers": {
"focus": {
"command": "npx",
"args": ["@focusmcp/cli", "start"]
"args": ["@focus-mcp/cli", "start"]
}
}
}
Expand All @@ -67,8 +67,8 @@ AI client (Claude Code, Cursor, Codex, Gemini…)
`PRD.md` et `CLAUDE.md` (ce fichier) restent en français (docs internes).
6. **Git-flow strict** — `develop` est **permanente**, jamais `--delete-branch` sur PR
`develop→main`.
7. **npm orgs** — `focusmcp` + `focus-mcp` réservées (squatting). `@focusmcp/cli` est LE package
publié au MVP (primary distribution). Scope canonique : `@focusmcp/*`.
7. **npm orgs** — `focusmcp` + `focus-mcp` réservées (squatting). `@focus-mcp/cli` est LE package
publié au MVP (primary distribution). Scope canonique : `@focus-mcp/*`.
8. **Rulesets GitHub** (identiques sur les 3 repos actifs) :
- `main protection` cible **UNIQUEMENT `refs/heads/main`** (status checks, PR, CodeQL,
Code Quality, linear history, pas de `required_signatures`).
Expand All @@ -80,16 +80,16 @@ AI client (Claude Code, Cursor, Codex, Gemini…)
## Dans ce repo (cli)

**Stack** : Node ≥ 22, pnpm ≥ 10, TS 5.7+ strict, ESM, Vitest, Biome 2.x, tsup, Changesets,
`@modelcontextprotocol/sdk` (stdio transport), `@focusmcp/core` en file: dep.
`@modelcontextprotocol/sdk` (stdio transport), `@focus-mcp/core` en file: dep.

**Dépendance critique** : `@focusmcp/core` est consommé via `file:../core/packages/core`. Cela
**Dépendance critique** : `@focus-mcp/core` est consommé via `file:../core/packages/core`. Cela
implique :
- **Dev local** : le user doit avoir `focus-mcp/core` cloné comme repo sibling de ce repo
(layout attendu : `../core`, avec le package à `../core/packages/core`). Indépendant de l'OS.
- **CI** : action composite `.github/actions/setup` qui clone `focus-mcp/core` comme sibling,
le build (pnpm filter), puis install ce repo.
- **Publish npm** : `tsup --noExternal '@focusmcp/core'` bundle le core dans le dist de la CLI,
donc les users finaux installent uniquement `@focusmcp/cli`.
- **Publish npm** : `tsup --noExternal '@focus-mcp/core'` bundle le core dans le dist de la CLI,
donc les users finaux installent uniquement `@focus-mcp/cli`.

**Commandes** :
```bash
Expand Down Expand Up @@ -120,7 +120,7 @@ pnpm changeset # avant toute PR qui change l'API publique
focus add <name>
├─ http-fetch-adapter → catalog.json (URL source)
├─ catalog-store-adapter → cache local + résolution brique
└─ npm-installer-adapter → npm install @focusmcp/<name>
└─ npm-installer-adapter → npm install @focus-mcp/<name>
```

## Workflow pour une feature
Expand All @@ -137,7 +137,7 @@ focus add <name>

- Aucun secret commité (gitleaks en CI)
- Le sandbox OS vient du parent process (Claude Code spawn en stdio via Seatbelt/bubblewrap)
- EventBus guards (couche 1 sécurité) intactes, fournies par `@focusmcp/core`
- EventBus guards (couche 1 sécurité) intactes, fournies par `@focus-mcp/core`
- Pour run des briques non-reviewed : ajouter `isolated-vm` Phase 2 (pas au MVP)

## Documentation à lire en priorité
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pnpm reuse # REUSE compliance (SPDX headers)

1. **Strict TDD** — tests first. Coverage ≥ 80 % global (the `vitest` config enforces this).
2. **No `any`**, no `!` non-null assertion, no untyped `catch`.
3. **No `console.*` outside `src/bin/` and `src/commands/`.** Use structured logging from `@focusmcp/core` everywhere else.
3. **No `console.*` outside `src/bin/` and `src/commands/`.** Use structured logging from `@focus-mcp/core` everywhere else.
4. **ESM only**, `node:` protocol for Node built-ins.
5. **SPDX headers** in every source file (`SPDX-FileCopyrightText: 2026 FocusMCP contributors` + `SPDX-License-Identifier: MIT`). For JSON files, add a sibling `.license` file (REUSE convention).
6. **Conventional Commits** — enforced by commitlint (`feat(list): ...`, `fix(info): ...`, `docs(readme): ...`). Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`.
Expand Down
Loading
Loading