Skip to content

Commit ece85d5

Browse files
brovelliclaude
andcommitted
Release 1.1.0: plugin/ layout, new tools, tests, CI, restructured skills
Packaging - Move everything the plugin installs under plugin/ (manifest, MCP server, skills, examples, hooks, scripts, evals); marketplace source -> ./plugin. Install size drops from 68 MB to ~2 MB; papers/tutorials/usecases stay in the repo only - uv lockfile for the server script; SessionStart hook pre-warms the uv environment so the first MCP connection does not time out - /braina:check skill + scripts/smoke_test.py for installation self-checks - Remove duplicate check_frites.py / check_hoi.py; check_env.py prints the JAX backend - CHANGELOG.md; version 1.1.0 MCP tools (22 -> 34) - HOI: expose method, samples_path and bootstrap CIs (n_boots, ci_percentiles, random_state -> <output>_ci.nc) on every metric; add hoi_tc, hoi_sinfo, hoi_infotot, hoi_transfer_entropy, hoi_dotot, hoi_redundancy_phiid, hoi_atoms_phiid; label the appended target y in multiplet names - Frites: norm/n_jobs (covgc), estimator (dfc), normalized (ccf), n_jobs on all conn tools; mcp/cluster_th/cluster_alpha/random_state/estimator on frites_wf_mi and frites_wf_conn_comod; frites_wf_mi_combine via save_workflow pickles; frites_conn_reshape and frites_conn_net; frites_sim_ar gains sf/dt/n_std/stim_onset/random_state and stores sfreq - convert_to_nc (.fif epochs, .mat, .csv, .npy -> labelled .nc) and plot_result (PNG of any output) Tests and evals - pytest suite (tests/, run with uv run tests/run_tests.py) covering all 34 tools; GitHub Actions CI; six claude plugin eval cases mirroring TESTING.md Skills - Short SKILL.md per skill plus references/ files read on demand; document the new tools and parameters, drop limitations fixed since 1.0.0, cite papers by their GitHub URL; README, CLAUDE.md and TESTING.md updated Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 8d8718e commit ece85d5

123 files changed

Lines changed: 6949 additions & 1856 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.claude-plugin/marketplace.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
22
"name": "braina-plugins",
33
"owner": {
4-
"name": "Andrea Brovelli — BraiNets, Institut de Neurosciences de la Timone"
4+
"name": "Andrea Brovelli \u2014 BraiNets, Institut de Neurosciences de la Timone"
55
},
66
"plugins": [
77
{
88
"name": "braina",
9-
"source": "."
9+
"source": "./plugin"
1010
}
1111
]
1212
}

‎.github/workflows/ci.yml‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
8+
jobs:
9+
test:
10+
runs-on: ubuntu-latest
11+
timeout-minutes: 40
12+
steps:
13+
- uses: actions/checkout@v4
14+
- uses: astral-sh/setup-uv@v5
15+
with:
16+
enable-cache: true
17+
- name: Check the environment
18+
run: uv run check_env.py
19+
- name: Library verification (Frites + HOI)
20+
run: uv run plugin/mcp/verify_libs.py
21+
- name: MCP tool tests
22+
run: uv run tests/run_tests.py
23+
- name: Plugin manifests are valid JSON
24+
run: |
25+
python3 -c "import json; json.load(open('.claude-plugin/marketplace.json')); json.load(open('plugin/.claude-plugin/plugin.json')); json.load(open('plugin/hooks/hooks.json')); print('manifests OK')"

‎.gitignore‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,7 @@ tutorials/seeg_ebrains_frites/datasets/seeg/*.nc
66

77
# Python bytecode
88
__pycache__/
9+
10+
# Eval runs and test artefacts
11+
plugin/evals/results/
12+
.pytest_cache/

‎CHANGELOG.md‎

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Changelog
2+
3+
## 1.1.0 - 2026-09-18
4+
5+
### Fixed
6+
- MCP server is declared in `plugin/.claude-plugin/plugin.json` (`mcpServers`);
7+
the root `.mcp.json`, which failed to resolve `${CLAUDE_PLUGIN_ROOT}` in a
8+
plain clone, is gone.
9+
- The `mcp/` directory no longer shadows the `mcp` SDK package.
10+
- Frites connectivity tools now pass the `roi`/`times` coordinate names to
11+
Frites, so `.nc` input really keeps ROI names, a time axis in seconds and
12+
`sfreq` (previously silently replaced by `roi_0, roi_1, ...` and 1 Hz).
13+
- HOI tools convert `.nc` input to numpy (HOI rejects xarray) and keep the
14+
multiplet metadata (`multiplets`, `order`, `multiplet_names`) in their
15+
`.nc` output; `hoi_get_nbest_mult` resolves region names from it.
16+
- `frites_wf_stats` writes `.nc` with `times`/`roi` coords; `frites_conn_pid`
17+
takes `dt` instead of a nonexistent `max_delay`; `frites_conn_te` forwards
18+
`sfreq`; random-effect inference with fewer than two subjects is refused.
19+
- All tools catch exceptions and return `Error in <tool>: ...` strings, and
20+
return a summary (shape, coords, min/mean/max) of what they wrote.
21+
22+
### Added
23+
- Multi-subject workflows: `frites_wf_mi` / `frites_wf_conn_comod` accept one
24+
file per subject or a `.nc` with a `subject` dimension, plus `mcp`,
25+
`cluster_th`, `cluster_alpha`, `random_state`, `estimator`.
26+
- `frites_wf_mi_combine` (WfMiCombine) via `save_workflow=True` pickles.
27+
- `frites_conn_reshape` (pairs -> sources x targets matrix) and
28+
`frites_conn_net` (A->B minus B->A).
29+
- Extra Frites parameters: `norm`, `n_jobs` (covgc), `estimator` (dfc),
30+
`normalized` (ccf), `n_jobs` everywhere; `frites_sim_ar` gains `sf`, `dt`,
31+
`n_std`, `stim_onset`, `random_state` and stores `sfreq`.
32+
- HOI: `method` (gc / gauss / binning / knn / kernel), `samples_path`, and
33+
bootstrap confidence intervals (`n_boots`, `ci_percentiles`,
34+
`random_state`, written to `<output>_ci.nc`) on every metric; new metrics
35+
`hoi_tc`, `hoi_sinfo`, `hoi_infotot`, `hoi_transfer_entropy`, `hoi_dotot`,
36+
`hoi_redundancy_phiid`, `hoi_atoms_phiid`.
37+
- `convert_to_nc` (MNE `.fif` epochs, `.mat`, `.csv`, relabelling `.npy`) and
38+
`plot_result` (PNG of any braina output).
39+
- `/braina:check` skill with `scripts/smoke_test.py`; SessionStart hook that
40+
pre-warms the `uv` environment; `uv` lockfile for the server script.
41+
- pytest suite (`tests/`), GitHub Actions CI, `claude plugin eval` cases.
42+
43+
### Changed
44+
- Repository layout: everything the plugin installs now lives under
45+
`plugin/` (manifest, MCP server, skills, examples, hooks, evals); papers,
46+
tutorials and use cases stay at the root and are no longer copied on
47+
install (68 MB -> ~2 MB).
48+
- Skills restructured for progressive disclosure: short `SKILL.md` plus
49+
per-tool `references/` files; limitations fixed in 1.1.0 removed from
50+
the text; papers cited by DOI/URL.
51+
- Tool count corrected (22 in 1.0.0, 34 in 1.1.0).
52+
53+
## 1.0.0 - 2026-09-13
54+
55+
Initial release: MCP server wrapping Frites and HOI (22 tools) and four
56+
skills (orientation, frites-connectivity, hoi-metrics, workflows).

‎CLAUDE.md‎

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,52 @@ The user may be a novice in computational neuroscience. Explain mathematical con
1515
uv run check_env.py
1616

1717
# Run the verification test suite for Frites + HOI
18-
uv run mcp/verify_libs.py
18+
uv run plugin/mcp/verify_libs.py
19+
20+
# Run the pytest suite over all MCP tools (synthetic data, ~30 s)
21+
uv run tests/run_tests.py
22+
23+
# End-to-end smoke test of the installation (what /braina:check runs)
24+
uv run plugin/scripts/smoke_test.py
1925

2026
# Launch the MCP server standalone
21-
uv run mcp/braina_mcp.py
27+
uv run plugin/mcp/braina_mcp.py
28+
29+
# Refresh the server lockfile after editing its dependency block
30+
uv lock --script plugin/mcp/braina_mcp.py
31+
32+
# Behavioural evals of the skills
33+
claude plugin eval plugin
2234

2335
# Run any example script (all use uv inline dependencies)
24-
uv run examples/frites/conn/plot_covgc.py
25-
uv run examples/hoi/metrics/plot_oinfo.py
36+
uv run plugin/examples/frites/conn/plot_covgc.py
37+
uv run plugin/examples/hoi/metrics/plot_oinfo.py
2638
```
2739

2840
All scripts use `uv` with PEP 723 inline script metadata (`# /// script` blocks) for dependency management — no virtualenv setup needed.
2941

3042
## Architecture
3143

32-
### MCP Server (`mcp/braina_mcp.py`)
44+
### Repository layout
3345

34-
The central integration layer. A FastMCP server exposing 22 tools that wrap Frites and HOI library functions with standardized file-based I/O. Each tool takes file paths as input (`.npy` or `.nc`), calls the underlying library function, saves results, and returns a text summary (shape, coords, min/mean/max). Exceptions are caught and returned as `Error in <tool>: ...` strings. The server is declared in `.claude-plugin/plugin.json` under `mcpServers`. This is registered as a Claude Code MCP server (`braina`).
46+
Everything the plugin installs lives under `plugin/` (manifest, MCP server + lockfile, skills, examples, hooks, scripts, evals); the marketplace points at it (`.claude-plugin/marketplace.json`, `source: ./plugin`). Papers, tutorials, use cases, tests and CI stay at the root and are not installed.
47+
48+
### MCP Server (`plugin/mcp/braina_mcp.py`)
49+
50+
The central integration layer. A FastMCP server exposing 34 tools that wrap Frites and HOI library functions with standardized file-based I/O. Each tool takes file paths as input (`.npy` or `.nc`), calls the underlying library function, saves results, and returns a text summary (shape, coords, min/mean/max). Exceptions are caught and returned as `Error in <tool>: ...` strings. The server is declared in `plugin/.claude-plugin/plugin.json` under `mcpServers`; `plugin/hooks/hooks.json` pre-warms its uv environment at session start. This is registered as a Claude Code MCP server (`braina`).
3551

3652
`load_data`/`save_data` are internal I/O helpers (not exposed as MCP tools) that handle the `.npy` vs `.nc` dispatch for every tool.
3753

3854
Tool categories:
39-
- **Data I/O**: `inspect_data`, `read_pdf`
40-
- **Frites connectivity**: `frites_conn_covgc`, `frites_conn_dfc`, `frites_conn_pid`, `frites_conn_ii`, `frites_conn_te`, `frites_conn_fit`, `frites_conn_spec`, `frites_conn_ccf`
41-
- **Frites workflows**: `frites_wf_stats` (WfStats), `frites_wf_mi` (WfMi), `frites_wf_conn_comod` (WfConnComod)
42-
- **Frites simulation**: `frites_sim_ar` (StimSpecAR)
43-
- **HOI metrics**: `hoi_oinfo`, `hoi_gradient_oinfo`, `hoi_infotopo`, `hoi_redundancy_mmi`, `hoi_synergy_mmi`, `hoi_rsi`, `hoi_dtc`, `hoi_get_nbest_mult`
55+
- **Data I/O**: `inspect_data`, `convert_to_nc` (.fif/.mat/.csv/.npy → labelled .nc), `plot_result` (PNG), `read_pdf`
56+
- **Frites connectivity**: `frites_conn_covgc`, `frites_conn_dfc`, `frites_conn_pid`, `frites_conn_ii`, `frites_conn_te`, `frites_conn_fit`, `frites_conn_spec`, `frites_conn_ccf`; post-processing `frites_conn_reshape` (pairs → sources×targets), `frites_conn_net` (A→B minus B→A)
57+
- **Frites workflows**: `frites_wf_stats` (WfStats), `frites_wf_mi` (WfMi, multi-subject, `save_workflow`), `frites_wf_mi_combine` (WfMiCombine from pickles), `frites_wf_conn_comod` (WfConnComod)
58+
- **Frites simulation**: `frites_sim_ar` (StimSpecAR, `random_state`)
59+
- **HOI static metrics** (all with `method`, `samples_path`, bootstrap `n_boots`): `hoi_oinfo`, `hoi_gradient_oinfo`, `hoi_infotopo`, `hoi_redundancy_mmi`, `hoi_synergy_mmi`, `hoi_rsi`, `hoi_dtc`, `hoi_tc`, `hoi_sinfo`, `hoi_infotot`
60+
- **HOI dynamic metrics** (3D input, lag `tau`): `hoi_transfer_entropy`, `hoi_dotot`, `hoi_redundancy_phiid`, `hoi_atoms_phiid`
61+
- **HOI utilities**: `hoi_get_nbest_mult`
62+
63+
Skills: `orientation`, `frites-connectivity`, `hoi-metrics`, `workflows`, `check` — each a short `SKILL.md` plus `references/*.md` read on demand. When adding or changing a tool, update the matching reference file, the pytest suite (`tests/test_mcp_tools.py`, which asserts the tool count) and `CHANGELOG.md`.
4464

4565
### Core Libraries
4666

@@ -60,9 +80,10 @@ Tool categories:
6080

6181
## Working in this Repo
6282

63-
- Consult `/examples` for usage patterns before writing new analysis code.
64-
- Read `mcp/braina_mcp.py` for canonical function signatures and parameter conventions.
83+
- Consult `plugin/examples` for usage patterns before writing new analysis code.
84+
- Read `plugin/mcp/braina_mcp.py` for canonical function signatures and parameter conventions.
6585
- For library internals, read source on GitHub via `gh api` or `gh browse` against `brainets/frites` and `brainets/hoi`.
66-
- When writing analysis scripts, test with small dummy data first (see `mcp/verify_libs.py` for patterns).
86+
- When writing analysis scripts, test with small dummy data first (see `plugin/mcp/verify_libs.py` for patterns).
6787
- Prefer JAX for high-performance math in HOI contexts; use xarray/MNE structures for Frites connectivity.
88+
- Papers are cited in the skills by their GitHub URL under `papers/`; the installed plugin does not ship them.
6889
- Frites must be `>=0.4.5`; earlier versions crash on import under NumPy 2. HOI has never restricted the NumPy version. With Frites `>=0.4.5`, NumPy 2 is supported.

‎README.md‎

Lines changed: 60 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ at the Institut de Neurosciences de la Timone:
2222
(O-information, synergy, redundancy, RSI, DTC, InfoTopo), GPU-capable via
2323
JAX.
2424

25-
It ships as an MCP server (22 tools wrapping Frites and HOI) plus 4 skills
26-
that know how to pick the right tool, explain what it actually computes, and
27-
run the statistics correctly — grounded in the real library source, not just
28-
tool docstrings.
25+
It ships as an MCP server (34 tools wrapping Frites and HOI, plus data
26+
conversion and plotting) and 5 skills that know how to pick the right tool,
27+
explain what it actually computes, run the statistics correctly and check
28+
the installation — grounded in the real library source, not just tool
29+
docstrings.
2930

3031
## Quick start
3132

@@ -35,8 +36,11 @@ claude plugin marketplace add brainets/braina
3536
claude plugin install braina@braina-plugins
3637
```
3738

38-
That's it — no need to clone the repo or run from inside it. Then, in any
39-
Claude Code session:
39+
That's it — no need to clone the repo or run from inside it. The first
40+
session pre-warms the Python environment in the background (about 150 MB of
41+
wheels, once); if the `braina` MCP server shows "Connection closed" in that
42+
very first session, run `/braina:check` or simply start a new session. Then,
43+
in any Claude Code session:
4044

4145
> **You:** I have LFP recordings from two regions during a working-memory
4246
> task (`data.nc`). Does region A drive region B?
@@ -61,26 +65,31 @@ Claude Code session:
6165
| `frites-connectivity` | Explains each Frites connectivity tool (Granger causality, transfer entropy, PID, coherence, cross-correlation, ...) once one's been picked. |
6266
| `hoi-metrics` | Explains HOI's higher-order metrics (O-info, synergy, redundancy, DTC, ...) — including sign-convention gotchas and CPU/GPU notes. |
6367
| `workflows` | Explains permutation testing, cluster correction, bootstrapping, and fixed/random-effect inference, for Frites *and* HOI output. |
68+
| `check` | `/braina:check` — verifies the installation: versions, JAX backend (CPU/GPU), MCP connection, end-to-end smoke test. |
69+
70+
Each skill is a short `SKILL.md` plus `references/` files that Claude reads
71+
on demand, so only the relevant detail enters the context.
6472

6573
## MCP tools
6674

6775
<details>
68-
<summary>22 tools wrapping Frites and HOI (click to expand)</summary>
76+
<summary>34 tools wrapping Frites and HOI (click to expand)</summary>
6977

7078
| Category | Tools |
7179
|---|---|
72-
| Data I/O | `inspect_data`, `read_pdf` |
73-
| Frites connectivity | `frites_conn_covgc`, `frites_conn_dfc`, `frites_conn_pid`, `frites_conn_ii`, `frites_conn_te`, `frites_conn_fit`, `frites_conn_spec`, `frites_conn_ccf` |
74-
| Frites workflows | `frites_wf_mi`, `frites_wf_stats`, `frites_wf_conn_comod` |
80+
| Data I/O | `inspect_data`, `convert_to_nc` (MNE `.fif`, `.mat`, `.csv`, `.npy` → labelled `.nc`), `plot_result` (PNG), `read_pdf` |
81+
| Frites connectivity | `frites_conn_covgc`, `frites_conn_dfc`, `frites_conn_pid`, `frites_conn_ii`, `frites_conn_te`, `frites_conn_fit`, `frites_conn_spec`, `frites_conn_ccf`, `frites_conn_reshape`, `frites_conn_net` |
82+
| Frites workflows | `frites_wf_mi` (multi-subject), `frites_wf_mi_combine`, `frites_wf_stats`, `frites_wf_conn_comod` |
7583
| Frites simulation | `frites_sim_ar` |
76-
| HOI metrics | `hoi_oinfo`, `hoi_gradient_oinfo`, `hoi_infotopo`, `hoi_redundancy_mmi`, `hoi_synergy_mmi`, `hoi_rsi`, `hoi_dtc`, `hoi_get_nbest_mult` |
84+
| HOI metrics | `hoi_oinfo`, `hoi_gradient_oinfo`, `hoi_infotopo`, `hoi_redundancy_mmi`, `hoi_synergy_mmi`, `hoi_rsi`, `hoi_dtc`, `hoi_tc`, `hoi_sinfo`, `hoi_infotot`, `hoi_transfer_entropy`, `hoi_dotot`, `hoi_redundancy_phiid`, `hoi_atoms_phiid`, `hoi_get_nbest_mult` |
7785

7886
Each tool wraps a Frites or HOI function with file-based I/O (`.npy` or
7987
`.nc`) and returns a summary of the result (shape, coordinates, min/mean/max).
8088
Use `.nc` input with `roi` and `times` coordinates so that outputs keep ROI
8189
names and a time axis in seconds; HOI outputs saved as `.nc` keep the
82-
multiplet metadata that `hoi_get_nbest_mult` needs. See `mcp/braina_mcp.py`
83-
for exact signatures.
90+
multiplet metadata that `hoi_get_nbest_mult` needs. Every HOI metric accepts
91+
`method` (estimator) and bootstrap confidence intervals (`n_boots`). See
92+
`plugin/mcp/braina_mcp.py` for exact signatures.
8493

8594
</details>
8695

@@ -89,8 +98,9 @@ for exact signatures.
8998
Beyond the plugin itself, this repo also carries the reference material the
9099
skills point to:
91100

92-
- **`examples/`** — ~50 self-contained scripts (Frites + HOI), runnable with
93-
`uv run examples/frites/conn/plot_covgc.py`.
101+
- **`plugin/examples/`** — ~50 self-contained scripts (Frites + HOI), runnable with
102+
`uv run plugin/examples/frites/conn/plot_covgc.py` (shipped with the plugin,
103+
the skills point to them).
94104
- **`tutorials/`** — longer walkthroughs, including a full SEEG analysis
95105
pipeline and a Frites+HOI+XGI integration notebook.
96106
- **`usecases/`** — end-to-end analysis scenarios (AR simulation, dynamic FC,
@@ -104,20 +114,29 @@ skills point to:
104114
git clone https://github.com/brainets/braina.git
105115
cd braina
106116

107-
# Verify the environment
117+
# Verify the environment and run the test suite
108118
uv run check_env.py
109-
uv run mcp/verify_libs.py
119+
uv run plugin/mcp/verify_libs.py
120+
uv run tests/run_tests.py # pytest over all 34 MCP tools
121+
uv run plugin/scripts/smoke_test.py # what /braina:check runs
110122

111123
# Register the MCP server (one-time setup)
112-
claude mcp add braina -- uv run mcp/braina_mcp.py
124+
claude mcp add braina -- uv run plugin/mcp/braina_mcp.py
113125

114126
claude
115127
```
116128

117-
The MCP server is declared in `.claude-plugin/plugin.json` (`mcpServers`,
118-
using `${CLAUDE_PLUGIN_ROOT}`), which only applies to a plugin install — a
119-
plain clone does not auto-register the server, hence the manual
120-
`claude mcp add` step above.
129+
`plugin/mcp/braina_mcp.py.lock` pins the server's dependencies (`uv lock
130+
--script plugin/mcp/braina_mcp.py` to refresh after changing them).
131+
Behavioural checks of the skills live in `plugin/evals/` and run with
132+
`claude plugin eval plugin`. CI (`.github/workflows/ci.yml`) runs the
133+
environment check, the library verification and the test suite.
134+
135+
The MCP server is declared in `plugin/.claude-plugin/plugin.json`
136+
(`mcpServers`, using `${CLAUDE_PLUGIN_ROOT}`), which only applies to a plugin
137+
install — a plain clone does not auto-register the server, hence the manual
138+
`claude mcp add` step above. The marketplace installs only the `plugin/`
139+
directory (~2 MB); papers, tutorials and use cases stay in the repo.
121140

122141
Reads `CLAUDE.md` for project context.
123142

@@ -128,19 +147,25 @@ Reads `CLAUDE.md` for project context.
128147

129148
```
130149
braina/
131-
├── .claude-plugin/
132-
│ ├── plugin.json # Plugin manifest (incl. MCP server declaration)
133-
│ └── marketplace.json # Self-hosted marketplace
134-
├── skills/ # orientation, frites-connectivity, hoi-metrics, workflows
135-
├── mcp/
136-
│ ├── braina_mcp.py # MCP server — 22 tools wrapping Frites & HOI
137-
│ └── verify_libs.py # Test suite for all wrapped functions
138-
├── examples/ # ~50 example scripts (frites/, hoi/)
139-
├── tutorials/
140-
├── usecases/
141-
├── papers/
142-
├── CLAUDE.md # Project context for Claude Code
143-
└── check_env.py # Environment verification
150+
├── .claude-plugin/marketplace.json # Self-hosted marketplace → source: ./plugin
151+
├── plugin/ # Everything the plugin installs
152+
│ ├── .claude-plugin/plugin.json # Manifest (incl. MCP server declaration)
153+
│ ├── mcp/
154+
│ │ ├── braina_mcp.py # MCP server — 34 tools wrapping Frites & HOI
155+
│ │ ├── braina_mcp.py.lock # uv lockfile for the server script
156+
│ │ └── verify_libs.py # Library-level verification
157+
│ ├── skills/ # orientation, frites-connectivity, hoi-metrics, workflows, check
158+
│ │ └── <skill>/SKILL.md + references/
159+
│ ├── examples/ # ~50 example scripts (frites/, hoi/)
160+
│ ├── hooks/hooks.json # SessionStart: pre-warm the uv environment
161+
│ ├── scripts/ # warmup.sh, smoke_test.py
162+
│ └── evals/ # `claude plugin eval` cases
163+
├── tests/ # pytest suite (uv run tests/run_tests.py)
164+
├── .github/workflows/ci.yml
165+
├── tutorials/ usecases/ papers/ docs/
166+
├── CHANGELOG.md
167+
├── CLAUDE.md # Project context for Claude Code
168+
└── check_env.py # Environment verification
144169
```
145170

146171
</details>

‎check_env.py‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# /// script
2-
# dependencies = ["frites", "hoi", "xgi", "numpy", "xarray", "jax", "jaxlib", "mne"]
2+
# dependencies = ["frites>=0.4.5", "hoi", "xgi", "numpy", "xarray", "jax", "jaxlib", "mne"]
33
# ///
4+
"""Quick environment check: imports, versions and the JAX backend.
5+
6+
For an end-to-end check of the MCP tools, run
7+
`uv run plugin/scripts/smoke_test.py` (or the /braina:check skill).
8+
"""
49
import frites
510
import hoi
611
import xgi
@@ -11,4 +16,8 @@
1116
print(f"frites version: {frites.__version__}")
1217
print(f"hoi version: {hoi.__version__}")
1318
print(f"xgi version: {xgi.__version__}")
19+
print(f"numpy version: {np.__version__}")
20+
print(f"xarray version: {xr.__version__}")
21+
print(f"mne version: {mne.__version__}")
22+
print(f"jax version: {jax.__version__} | devices: {jax.devices()}")
1423
print("All packages imported successfully!")

‎check_frites.py‎

Lines changed: 0 additions & 8 deletions
This file was deleted.

‎check_hoi.py‎

Lines changed: 0 additions & 8 deletions
This file was deleted.

0 commit comments

Comments
 (0)