Skip to content

[5/5] feat(neuroflow): headless DICOM ingest CLI - #15

Closed
cdrake wants to merge 1 commit into
neuroflow/4-node-fs-adaptersfrom
neuroflow/5-headless-cli
Closed

cdrake wants to merge 1 commit into
neuroflow/4-node-fs-adaptersfrom
neuroflow/5-headless-cli

Conversation

@cdrake

@cdrake cdrake commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Part 5 of 5. bun run neuroflow-ingest runs the same import as the window (runImport, the post-pass, and relocation to <out>/bids) under Bun with no window and no user input. It then writes the same handoff and provenance line. This lets NeuroFlow hosts that can't wait on an app, such as its MCP server, run the ingest step.

bun run neuroflow-ingest -- --neuroflow-session "$NEUROFLOW_SESSION"
bun run neuroflow-ingest -- --workflow wf.neuroflow.json --input dicom_dir=/data/dicom --out /data/out
bun run neuroflow-ingest -- --dicom /data/dicom --out /data/out --importer dcm2niix-reproin --json
  • Settings come from flags first, then the step's inputs, then defaults: importer, subject, session, anonymize, shift_dates, save_derivatives, heuristic, config.
  • Importers: dcm2niix-reproin (the default), pet2bids, heudiconv, dcm2bids. The MEG/EEG importers aren't supported headless.
  • Exit codes: 0 done, 1 import failed, 2 usage error. It refuses to run if <out>/bids already exists.

Changes

  • $lib/neuroflow/headless: settings resolution, workflow step binding (constants and inputs.* refs), and runHeadlessIngest.
  • $lib/neuroflow/nodeExecutor: a spawn-based ImportExecutor.
    • It uses the bundled dcm2niix sidecar for the host triple, then $DCM2NIIX, then PATH.
    • It keeps the Rust side's partial-success exit codes (8, 10) and the dcm2bids PATH shim.
  • scripts/neuroflow-ingest.ts, the package.json script, and a README section.

Stack (merge in order; each PR is based on the one before):

  1. [1/5] feat(neuroflow): session contract and Rust commands #11 Session contract and Rust commands
  2. [2/5] feat(neuroflow): place an import's BIDS root at a chosen path #12 Place an import's BIDS root at a chosen path
  3. [3/5] feat(neuroflow): run the ingest step when launched by NeuroFlow #13 Run the ingest step when launched by NeuroFlow
  4. [4/5] refactor(test): promote the node:fs adapters out of test-only files #14 Promote the node:fs adapters out of test-only files
  5. [5/5] feat(neuroflow): headless DICOM ingest CLI #15 Headless DICOM ingest CLI ← this PR

Checks

  • bun test
  • bun run typecheck
  • bun run lint
  • Real Siemens session (the converter created 90 files): exit 0 in about 53 s. The file list matches the window import, and every JSON/TSV file is byte-identical. The headless output also has a .bidsignore that the window output lacks; that looks like a window-side dotfile scope issue and is not part of this PR.
  • Run through the NeuroFlow MCP server via a NeuroFlow tool that wraps this CLI (in a separate NeuroFlow PR, not yet opened): same output, and provenance recorded.

🤖 Generated with Claude Code

`bun run neuroflow-ingest` runs the same import as the window (runImport,
the post-pass, relocation to <out>/bids) under Bun with no window and no
user input, then writes the same handoff and provenance line. This makes
the ingest step runnable by NeuroFlow hosts that cannot wait on an app,
such as its MCP server.

It takes a NeuroFlow session (context.json), a step of a workflow document
(constants and inputs.* bindings), or plain flags. Settings come from flags,
then the step inputs, then defaults: importer dcm2niix-reproin, subject,
session, anonymize, shift_dates, save_derivatives, heuristic, config.
Importers: dcm2niix-reproin, pet2bids, heudiconv, dcm2bids. Exit codes:
0 done, 1 import failed, 2 usage error.

- $lib/neuroflow/headless: settings resolution, workflow step binding,
  runHeadlessIngest (refuses an existing <out>/bids before converting).
- $lib/neuroflow/nodeExecutor: spawn-based ImportExecutor. Uses the bundled
  dcm2niix sidecar for the host triple, then $DCM2NIIX / PATH; keeps the
  Rust side's partial-success exit codes (8, 10) and the dcm2bids PATH shim.
- scripts/neuroflow-ingest.ts and the package.json script; README section.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cdrake

cdrake commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #18, which collapses this stack into one PR: the headless ingest CLI plus only the pieces it needs. The window ingest mode (#13 and the Rust commands from #11) is kept on the neuroflow/window-ingest branch for later.

@cdrake cdrake closed this Oct 13, 2026
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.

1 participant