🤖
Summary
Build a first-class eegprep command-line interface for AI agents, batch jobs, and reproducible EEG preprocessing. This should complement, not replace, the existing human-facing eegprep-gui and mixed GUI/IPython eegprep-console workflows.
The CLI should expose EEGLAB-style workflows in a Python-native, deterministic, machine-readable interface:
EEGPrep CLI = EEGLAB-style workflows + Python reproducibility + machine-readable agent contract
Branch for implementation: feature/eegprep-agent-cli.
Base context: branched from feature/eeglab-full-standalone-completion; this work is stacked until that PR and its upstream stack land in origin/develop.
Product Goal
Agents should be able to inspect datasets, validate state, plan preprocessing, run transformations, capture provenance, recover from errors, and generate reports without importing Python objects or driving the GUI. Human users should still use eegprep-gui and eegprep-console for interactive workflows.
The CLI must be boring, predictable, and reproducible:
eegprep inspect sample_data/eeglab_data.set --json
eegprep validate sample_data/eeglab_data.set --json
eegprep resample sample_data/eeglab_data.set --freq 128 --output /tmp/resampled.set --json
eegprep pipeline validate preprocessing.yaml --json
eegprep pipeline plan preprocessing.yaml --json
eegprep pipeline run preprocessing.yaml --json
Core Design Decisions
-
Add a new script entry point named eegprep.
- Keep
eegprep-gui and eegprep-console unchanged.
- CLI runtime must not import Qt, IPython, or open a GUI unless a future explicit command asks for that.
-
Prefer a real subcommand framework for long-term maintainability.
- Recommended: Typer/Click, with Rich only for human help/table output if needed.
--json output must bypass Rich/color and write clean JSON to stdout.
- If Typer adds more dependency cost than value during implementation, argparse is acceptable, but the command tree and tests should stay modular.
-
Make stdout/stderr contracts strict.
- stdout: command result only, JSON when
--json is used.
- stderr: progress, logs, and warnings.
- files: datasets, manifests, reports, and artifacts.
-
Use stable schemas and error codes.
- Every JSON response includes
status, schema_version, and either result payload or structured error.
- Failures include stable
code, message, optional path, and optional suggestion.
- Suggested initial codes:
INPUT_FILE_NOT_FOUND, UNSUPPORTED_FORMAT, OUTPUT_EXISTS, CONFIG_SCHEMA_ERROR, MISSING_CHANNEL_LOCATIONS, INVALID_EVENT_LATENCY, ICA_NOT_FOUND, DEPENDENCY_MISSING, BIDS_VALIDATION_FAILED, COMMAND_NOT_IMPLEMENTED.
-
Never mutate inputs by surprise.
- Commands that write data require
--output or explicit --overwrite.
- Default should be no-overwrite.
- Expensive/destructive commands support
--dry-run or --plan where meaningful.
-
Preserve EEGLAB mental models without copying MATLAB ergonomics blindly.
- Commands should map to researcher workflows, not internal module names.
- Under the hood, use existing
pop_*, IO, validation, BIDS, QC, and report functionality.
- Returned manifests should include equivalent
pop_* history when available.
Required Agent Help Surface
eegprep --help must include a section near the top:
Start here (for AI agents):
eegprep skills get eegprep-cli
Skills ship with the CLI, stay version-matched, and include workflow patterns,
JSON contracts, safety boundaries, and copy-paste examples. Prefer this over
guessing from flag docs alone.
Add commands:
eegprep skills list
eegprep skills get eegprep-cli
eegprep skills get eegprep-cli --full
eegprep skills path eegprep-cli
The initial bundled skill should live in package resources and explain:
- Always use
--json for machine-readable output.
- Use
capabilities --json and schema ... --json before constructing commands.
- Use
pipeline validate and pipeline plan before running pipelines.
- Read manifests after writing outputs.
- Use stable error codes for recovery.
- Keep GUI/console workflows separate from headless CLI workflows.
Command Grammar
Use a consistent pattern:
eegprep <workflow> <input> [options] --output <path> --json
Avoid clever positional overloads. Prefer explicit option names.
Global flags expected on commands where relevant:
--json
--quiet
--verbose
--no-progress
--no-color
--manifest <path>
--overwrite / --no-overwrite
--seed <int>
--deterministic
--threads <n>
Initial Command Set
Discovery and agent contract
eegprep capabilities --json
eegprep schema command inspect --json
eegprep schema pipeline --json
eegprep examples inspect
eegprep examples pipeline
eegprep skills list
eegprep skills get eegprep-cli
Read-only dataset workflows
eegprep inspect dataset <path> --json
eegprep inspect events <path> --json
eegprep inspect channels <path> --json
eegprep inspect ica <path> --json
eegprep validate <path> --json
Transform workflows
eegprep resample <input> --freq 128 --output <output> --json
eegprep rereference <input> --method average --output <output> --json
eegprep filter <input> --highpass 1 --lowpass 40 --notch 60 --output <output> --json
eegprep clean <input> --method asr --burst-criterion 20 --output <output> --json
eegprep epoch <input> --event-type target --tmin -0.2 --tmax 0.8 --output <output> --json
eegprep ica <input> --method runica --seed 42 --output <output> --json
QC, reports, and pipelines
eegprep qc <input> --json
eegprep qc report <input> --html qc.html --json
eegprep report <input> --output report.html --json
eegprep pipeline validate config.yaml --json
eegprep pipeline plan config.yaml --json
eegprep pipeline run config.yaml --json
BIDS and EEGLAB compatibility
eegprep bids validate <bids_root> --json
eegprep bids import <bids_root> --subject 01 --task rest --output sub-01.set --json
eegprep bids export <input.set> --bids-root bids_out --subject 01 --task rest --json
eegprep eeglab history <input.set> --json
eegprep eeglab compare <left.set> <right.set> --json
eegprep eeglab convert-script pipeline.m --to eegprep-yaml --output pipeline.yaml --json
The EEGLAB script converter can be best-effort. It must report confidence and unsupported commands rather than pretending unsupported MATLAB code is fully converted.
Pipeline Config Shape
Support YAML first because the repo already uses PyYAML in dev and pipeline configs are easier to edit than long shell commands.
Example:
schema_version: eegprep.pipeline.v1
input:
path: sub-01.set
format: eeglab
output:
directory: derivatives/eegprep/sub-01
overwrite: false
steps:
- name: filter
highpass: 1.0
lowpass: 40.0
notch: 60
- name: rereference
method: average
- name: clean
method: asr
burst_criterion: 20
- name: ica
method: runica
seed: 42
- name: report
format: html
pipeline plan --json should emit normalized steps, output paths, estimated destructive actions, and unsupported/missing dependency warnings without doing the work.
Manifest Contract
Every command that writes output supports --manifest. If omitted, pipeline commands should write a default manifest next to outputs.
Manifest fields:
{
"schema_version": "eegprep.manifest.v1",
"command": "resample",
"input_files": [{"path": "sub-01.set", "sha256": "..."}],
"output_files": [{"path": "sub-01_resampled.set", "type": "eeglab_set"}],
"parameters": {"freq": 128.0},
"history": "EEG = pop_resample(EEG, freq=128)",
"software": {"eegprep_version": "...", "python_version": "..."},
"runtime": {"started_at": "...", "finished_at": "..."},
"deterministic": true,
"warnings": []
}
Implementation Phases
Phase 1: CLI Foundation and Agent Contract
Scope:
- Add
eegprep entry point.
- Add CLI package under a locally appropriate path such as
src/eegprep/cli/.
- Add result/error/manifest helpers.
- Add global options and clean stdout/stderr routing.
- Add
skills, capabilities, schema, and examples command foundations.
- Add bundled
eegprep-cli skill content as packaged resource.
- Add Sphinx docs page:
Using EEGPrep with AI agents.
Acceptance criteria:
uv run eegprep --help shows the AI agents start-here section.
uv run eegprep skills get eegprep-cli prints version-matched skill content.
uv run eegprep capabilities --json emits parseable JSON.
uv run eegprep schema pipeline --json emits parseable schema-like JSON.
- No CLI command imports Qt/IPython unless explicitly intended.
- Tests prove JSON stdout is clean and errors are structured.
Phase 2: Read-Only Dataset Inspection and Validation
Scope:
- Implement
inspect dataset/events/channels/ica and validate.
- Use existing loaders and
eeg_checkset/session-neutral helpers.
- Return stable schema versions and warning/error codes.
Acceptance criteria:
sample_data/eeglab_data.set can be inspected and validated from the CLI.
- Events, channels, ICA, duration, data shape, sampling rate, and file metadata are reported in JSON.
- Invalid/missing files return stable errors and nonzero exit codes.
- stdout/stderr separation is tested.
Phase 3: Core Transform Commands
Scope:
- Implement
resample, rereference, filter, clean, epoch, and ica as headless commands.
- Require explicit outputs unless
--overwrite is supplied.
- Write manifests and preserve
pop_* history strings.
- Support deterministic options where the underlying method supports them.
Acceptance criteria:
- Commands run on
sample_data/eeglab_data.set and write valid .set outputs.
- Output overwrite/cancel/error behavior is deterministic and tested.
- Commands return machine-readable summaries, warnings, and manifests.
- Expensive commands provide progress on stderr without polluting JSON stdout.
Phase 4: Pipeline, Batch, QC, and Reports
Scope:
- Implement
pipeline validate, pipeline plan, and pipeline run.
- Implement
qc and qc report with JSON metrics and optional HTML.
- Add batch execution for BIDS-like subject lists or explicit input lists.
Acceptance criteria:
- Pipeline validation catches schema errors before work starts.
- Plan mode emits normalized steps and expected outputs without mutating files.
- Pipeline run produces outputs plus manifest.
- Batch mode returns per-subject status and partial-success summaries.
- QC outputs include stable recommendation codes agents can reason about.
Phase 5: BIDS and EEGLAB Migration Commands
Scope:
- Implement
bids validate/import/export using existing EEGPrep BIDS functionality.
- Implement
eeglab history, eeglab compare, and best-effort eeglab convert-script.
Acceptance criteria:
- BIDS commands are explicit about missing optional dependencies.
- EEGLAB history parsing maps recognized
pop_* commands to CLI/pipeline equivalents with confidence.
- Unsupported MATLAB commands are reported with stable codes and suggestions.
- Comparison command emits structured differences, not free-form prose.
Phase 6: Closeout, Docs, and Agent QA
Scope:
- Finish Sphinx CLI reference docs.
- Add quickstarts for humans and agents.
- Add examples for single command, pipeline, batch, BIDS, and EEGLAB migration.
- Run mixed verification with shell-agent style subprocess tests.
Acceptance criteria:
- Docs clearly distinguish
eegprep, eegprep-gui, and eegprep-console.
- Agent guide explains the stable contract and recovery patterns.
uv run --no-sync ruff check ., uv run --no-sync ruff format --check ., uv run --no-sync ty check, ./pre-commit.py --changed-from origin/develop, focused CLI tests, and EEGPREP_SKIP_MATLAB=1 uv run --no-sync pytest -m "not slow" pass.
MVP Recommendation
The first implementation PR should complete Phase 1 and enough of Phase 2 to prove the architecture:
eegprep --help
eegprep skills list|get|path
eegprep capabilities --json
eegprep schema pipeline --json
eegprep inspect dataset sample_data/eeglab_data.set --json
eegprep validate sample_data/eeglab_data.set --json
Then subsequent PRs can add transforms, pipelines, BIDS, and reports without reworking the contract.
Required References
AGENTS.md
.agents/skills/eegprep-feature-development/SKILL.md
.agents/skills/gui-agent-flow-qa/SKILL.md only for any workflow that crosses back into GUI/console behavior
- Existing
eegprep-console docs and tests, especially tests/test_console_workspace.py
- Existing dataset IO, BIDS, QC,
pop_*, and report code before adding new implementations
Suggested /goal Prompt
/goal Build the first agent-friendly EEGPrep CLI PR from issue <ISSUE_NUMBER> on branch feature/eegprep-agent-cli. Preserve existing eegprep-gui and eegprep-console behavior, add a new headless eegprep command with agent-focused help, skills retrieval, JSON/stdout-stderr contracts, stable errors, capabilities/schema discovery, and inspect/validate commands over sample_data. Use existing EEGPrep loaders and pop/session-neutral helpers rather than duplicating processing logic. Verify with subprocess CLI tests, sample_data integration tests, clean JSON stdout tests, manifest/error-code tests where applicable, docs updates, ruff/format/ty, pre-commit, and the relevant non-slow pytest subset. Fix review findings unless they are explicit scope creep and report any accepted non-goals.
Explicit Non-Goals For The First PR
- Do not replace or rename
eegprep-gui or eegprep-console.
- Do not require agents to drive the GUI.
- Do not add a hidden global session for the CLI.
- Do not implement every preprocessing command before the JSON contract and discovery surface are stable.
- Do not silently fake BIDS validation, MATLAB script conversion, or missing optional dependencies.
🤖
Summary
Build a first-class
eegprepcommand-line interface for AI agents, batch jobs, and reproducible EEG preprocessing. This should complement, not replace, the existing human-facingeegprep-guiand mixed GUI/IPythoneegprep-consoleworkflows.The CLI should expose EEGLAB-style workflows in a Python-native, deterministic, machine-readable interface:
EEGPrep CLI = EEGLAB-style workflows + Python reproducibility + machine-readable agent contractBranch for implementation:
feature/eegprep-agent-cli.Base context: branched from
feature/eeglab-full-standalone-completion; this work is stacked until that PR and its upstream stack land inorigin/develop.Product Goal
Agents should be able to inspect datasets, validate state, plan preprocessing, run transformations, capture provenance, recover from errors, and generate reports without importing Python objects or driving the GUI. Human users should still use
eegprep-guiandeegprep-consolefor interactive workflows.The CLI must be boring, predictable, and reproducible:
Core Design Decisions
Add a new script entry point named
eegprep.eegprep-guiandeegprep-consoleunchanged.Prefer a real subcommand framework for long-term maintainability.
--jsonoutput must bypass Rich/color and write clean JSON to stdout.Make stdout/stderr contracts strict.
--jsonis used.Use stable schemas and error codes.
status,schema_version, and either result payload or structured error.code,message, optionalpath, and optionalsuggestion.INPUT_FILE_NOT_FOUND,UNSUPPORTED_FORMAT,OUTPUT_EXISTS,CONFIG_SCHEMA_ERROR,MISSING_CHANNEL_LOCATIONS,INVALID_EVENT_LATENCY,ICA_NOT_FOUND,DEPENDENCY_MISSING,BIDS_VALIDATION_FAILED,COMMAND_NOT_IMPLEMENTED.Never mutate inputs by surprise.
--outputor explicit--overwrite.--dry-runor--planwhere meaningful.Preserve EEGLAB mental models without copying MATLAB ergonomics blindly.
pop_*, IO, validation, BIDS, QC, and report functionality.pop_*history when available.Required Agent Help Surface
eegprep --helpmust include a section near the top:Add commands:
The initial bundled skill should live in package resources and explain:
--jsonfor machine-readable output.capabilities --jsonandschema ... --jsonbefore constructing commands.pipeline validateandpipeline planbefore running pipelines.Command Grammar
Use a consistent pattern:
Avoid clever positional overloads. Prefer explicit option names.
Global flags expected on commands where relevant:
Initial Command Set
Discovery and agent contract
eegprep capabilities --json eegprep schema command inspect --json eegprep schema pipeline --json eegprep examples inspect eegprep examples pipeline eegprep skills list eegprep skills get eegprep-cliRead-only dataset workflows
Transform workflows
QC, reports, and pipelines
BIDS and EEGLAB compatibility
The EEGLAB script converter can be best-effort. It must report confidence and unsupported commands rather than pretending unsupported MATLAB code is fully converted.
Pipeline Config Shape
Support YAML first because the repo already uses PyYAML in dev and pipeline configs are easier to edit than long shell commands.
Example:
pipeline plan --jsonshould emit normalized steps, output paths, estimated destructive actions, and unsupported/missing dependency warnings without doing the work.Manifest Contract
Every command that writes output supports
--manifest. If omitted, pipeline commands should write a default manifest next to outputs.Manifest fields:
{ "schema_version": "eegprep.manifest.v1", "command": "resample", "input_files": [{"path": "sub-01.set", "sha256": "..."}], "output_files": [{"path": "sub-01_resampled.set", "type": "eeglab_set"}], "parameters": {"freq": 128.0}, "history": "EEG = pop_resample(EEG, freq=128)", "software": {"eegprep_version": "...", "python_version": "..."}, "runtime": {"started_at": "...", "finished_at": "..."}, "deterministic": true, "warnings": [] }Implementation Phases
Phase 1: CLI Foundation and Agent Contract
Scope:
eegprepentry point.src/eegprep/cli/.skills,capabilities,schema, andexamplescommand foundations.eegprep-cliskill content as packaged resource.Using EEGPrep with AI agents.Acceptance criteria:
uv run eegprep --helpshows the AI agents start-here section.uv run eegprep skills get eegprep-cliprints version-matched skill content.uv run eegprep capabilities --jsonemits parseable JSON.uv run eegprep schema pipeline --jsonemits parseable schema-like JSON.Phase 2: Read-Only Dataset Inspection and Validation
Scope:
inspect dataset/events/channels/icaandvalidate.eeg_checkset/session-neutral helpers.Acceptance criteria:
sample_data/eeglab_data.setcan be inspected and validated from the CLI.Phase 3: Core Transform Commands
Scope:
resample,rereference,filter,clean,epoch, andicaas headless commands.--overwriteis supplied.pop_*history strings.Acceptance criteria:
sample_data/eeglab_data.setand write valid.setoutputs.Phase 4: Pipeline, Batch, QC, and Reports
Scope:
pipeline validate,pipeline plan, andpipeline run.qcandqc reportwith JSON metrics and optional HTML.Acceptance criteria:
Phase 5: BIDS and EEGLAB Migration Commands
Scope:
bids validate/import/exportusing existing EEGPrep BIDS functionality.eeglab history,eeglab compare, and best-efforteeglab convert-script.Acceptance criteria:
pop_*commands to CLI/pipeline equivalents with confidence.Phase 6: Closeout, Docs, and Agent QA
Scope:
Acceptance criteria:
eegprep,eegprep-gui, andeegprep-console.uv run --no-sync ruff check .,uv run --no-sync ruff format --check .,uv run --no-sync ty check,./pre-commit.py --changed-from origin/develop, focused CLI tests, andEEGPREP_SKIP_MATLAB=1 uv run --no-sync pytest -m "not slow"pass.MVP Recommendation
The first implementation PR should complete Phase 1 and enough of Phase 2 to prove the architecture:
eegprep --helpeegprep skills list|get|patheegprep capabilities --jsoneegprep schema pipeline --jsoneegprep inspect dataset sample_data/eeglab_data.set --jsoneegprep validate sample_data/eeglab_data.set --jsonThen subsequent PRs can add transforms, pipelines, BIDS, and reports without reworking the contract.
Required References
AGENTS.md.agents/skills/eegprep-feature-development/SKILL.md.agents/skills/gui-agent-flow-qa/SKILL.mdonly for any workflow that crosses back into GUI/console behavioreegprep-consoledocs and tests, especiallytests/test_console_workspace.pypop_*, and report code before adding new implementationsSuggested /goal Prompt
Explicit Non-Goals For The First PR
eegprep-guioreegprep-console.