Add Subworkflow
Scaffold a Bactopia subworkflow that orchestrates one or more existing modules. Subworkflows are glue -- they wire modules together, aggregate results, and provide a clean interface for workflows.
Prerequisites
- The module(s) this subworkflow will use must already exist under
modules/
- Read
.agents/docs/standards/04-subworkflow-documentation.md for documentation standards
Interactive Questioning
This skill is interactive -- ask the user early and often, especially before creating files.
- Multiple questions at once: Use
AskUserQuestion popups (up to 4 questions per batch).
Mark the recommended option with "(Recommended)" at the end of its label and place it first.
- Single simple question: Just ask in chat, no popup needed.
- When in doubt: Ask. It's cheaper to clarify upfront than to regenerate files.
What a Subworkflow Contains
A subworkflow is a single main.nf file plus tests:
subworkflows/{tool}/
main.nf # Workflow definition with GroovyDoc
tests/
main.nf.test # nf-test specification
main.nf.test.snap # Snapshot (generated by nf-test)
nextflow.config # Includes ALL module.configs used by this subworkflow
nf-test.config # Standard nf-test config
.nftignore # Exclude unstable files from snapshots
No module.config or schema.json -- those belong to modules only.
Phased Workflow
Phase 1: Gather Information
Goal: Determine which modules to orchestrate and how, using interactive prompts.
Important: Use the AskUserQuestion tool for structured choices throughout this phase.
Present up to 4 questions per batch. Mark the recommended option with "(Recommended)"
at the end of its label and place it first in the options list.
Ask the user which modules this subworkflow uses. Get the module paths (e.g., modules/nohuman/run, modules/mlst).
- Read each module's
main.nf to understand its inputs and outputs.
- Does it call other subworkflows? If so, use
@subworkflows tag (not @modules) for those includes.
Run the lookup command if package info is needed:
bash .agents/skills/add-bactopia-tool/scripts/run-bactopia-scaffold.sh lookup {package_name} --bactopia-path . --pretty
Determine the input type from the primary module's inputs, then run test-data discovery:
bash .agents/skills/add-bactopia-tool/scripts/run-bactopia-scaffold.sh test-data --input-type {input_type} --bactopia-path . --pretty
This returns species/accession combinations already used by similar modules, with
pre-computed test_data_path, test_uncompressed_path, test_species, and
test_sample_id values. Use the returned paths directly in the scaffold config
(Phase 2) -- do NOT construct paths manually. Subworkflow tests use the
compressed path (test_data_path).
Batch 1: Design choices (AskUserQuestion, up to 3 questions)
Question 1 -- Aggregation strategy:
- CSVTK_CONCAT -- concatenate per-sample tabular output (most common) (Recommended)
- Dedicated summary module -- tool has its own aggregation command (rare)
- No aggregation -- tool doesn't produce per-sample tabular output
Question 2 -- Test data species:
Present top 3-4 species from the test-data discovery results. Recommend species that
exercise the tool's functionality. Include the accession in each option's description.
Question 3 -- Aggregation field (if CSVTK_CONCAT or dedicated_summary selected):
Which output field should be aggregated? (e.g., tsv, report, csv)
What format? (tsv or csv)
Present the following for confirmation (derive from module main.nf and lookup):
- Tool identity: name (snake_case), display name, one-sentence description
- Outputs: from the primary module's output block (for
@output GroovyDoc tags)
- Citation key and keywords for GroovyDoc
Final confirmation (AskUserQuestion, 1 question)
After presenting the summary, ask:
- Looks good, proceed to file generation
- I need to make changes (user provides details via "Other" or notes)
Phase 2: File Generation
Goal: Generate the 5 subworkflow files using bactopia-scaffold.
Construct the JSON config from the design decisions. Write it to /tmp/scaffold-config.json:
{
"tool": "{tool_name}",
"display_name": "{DisplayName}",
"description": "{One-sentence description}",
"process_name": "{TOOL_NAME}",
"package": "{package_name}",
"version": "{version}",
"build": "{build}",
"home_url": "{github_url}",
"input_type": "assembly",
"has_database": false,
"handles_gz": false,
"layout": "flat",
"resource_label": "process_low",
"version_command": "{version_command}",
"citation_key": "{citation_key}",
"keywords": ["{keyword1}", "{keyword2}"],
"aggregation": {
"strategy": "csvtk_concat",
"field": "{output_field}",
"format": "{tsv|csv}"
},
"outputs": [
{"name": "{field}", "extension": "{ext}", "description": "{desc}"}
],
"parameters": [],
"container_refs": {
"toolName": "{from lookup}",
"docker": "{from lookup}",
"image": "{from lookup}"
},
"test_species": "{species}",
"test_sample_id": "{sample_id}",
"test_data_path": "{compressed_path}",
"test_uncompressed_path": "{uncompressed_path}"
}
For database-dependent subworkflows, also include:
{
"database": {
"param_name": "{tool}_db",
"test_path": "datasets/{tool}/{db_file}"
}
}
Run the scaffold command:
bash .agents/skills/add-bactopia-tool/scripts/run-bactopia-scaffold.sh subworkflow --config /tmp/scaffold-config.json --bactopia-path . --pretty
The command creates 5 files:
subworkflows/{tool}/main.nf
subworkflows/{tool}/tests/main.nf.test
subworkflows/{tool}/tests/nextflow.config
subworkflows/{tool}/tests/nf-test.config
subworkflows/{tool}/tests/.nftignore
Phase 3: Review & Customize
Goal: Review generated files and make tool-specific adjustments.
Subworkflow main.nf -- review and customize:
- The
@input GroovyDoc should match the subworkflow's take channel name
- For the CSVTK_CONCAT pattern, verify the gather field and format are correct
- If the subworkflow uses modules not in the standard pattern (e.g., calls other subworkflows), add the appropriate
@subworkflows tag and adjust includes
- The
@modules tag should use underscore-delimited directory keys: csvtk_concat, {tool}
Test nextflow.config -- verify it includes ALL module.configs for processes in the subworkflow:
- The primary module's config
csvtk/concat/module.config if using CSVTK_CONCAT
- Any other module configs
Test main.nf.test -- verify:
- Test data paths match the species/sample chosen
- Database input lines are present if needed
- Snapshot fields include the right output field names
Run the linter to catch structural issues before proceeding:
bash .agents/skills/add-bactopia-tool/scripts/run-bactopia-lint.sh {tool} --bactopia-path .
This runs bactopia-lint scoped to the new subworkflow (and module if it exists).
Fix any FAILs before moving on. Common issues:
- S011: misaligned include braces in subworkflow
- S019: citation key not found in
data/citations.yml
Update data/citations.yml -- add the tool citation entry in alphabetical order
(if not already present from a prior /add-module run):
{tool}:
name: "{ToolName}"
link: "{github_url}"
description: "{One-sentence description}"
cite: "{Full citation text}"
List all created files with full paths.
Remind the user to run these follow-up steps in order:
/run-tests {tool} subworkflow --generate -- generate snapshots and verify the subworkflow test passes (new subworkflows have no existing snapshots)
- The subworkflow needs a workflow entry point to be usable -- use
/add-bactopia-tool if this is a standalone bactopia-tool
The --generate flag is required because newly scaffolded subworkflows have no
snapshot files yet. Without it, nf-test will fail immediately on missing
snapshots.
Subworkflow Patterns
The scaffold generates one of three patterns based on the aggregation.strategy:
| Strategy |
Pattern |
Include |
Emit |
csvtk_concat |
CSVTK_CONCAT aggregation |
gatherCsvtk from plugin |
sample_outputs + run_outputs |
dedicated_summary |
Tool's own summary command |
gatherFields from plugin |
sample_outputs + run_outputs |
none |
No aggregation |
No plugin |
sample_outputs + Channel.empty() |
CSVTK_CONCAT is the default and most common (~80% of subworkflows).
Edge Cases
Multi-module subworkflows (e.g., snippy + snpdists + gubbins): The scaffold generates a single-module pattern. For complex orchestration, generate the scaffold then manually adjust the includes and channel wiring.
Composite subworkflows that call other subworkflows: Add @subworkflows tag manually and adjust includes to point to ../../subworkflows/{name}/main instead of ../../modules/{name}/main.
Test Data Discovery
Test data paths are discovered dynamically from existing module tests using:
bash .agents/skills/add-bactopia-tool/scripts/run-bactopia-scaffold.sh test-data --input-type {type} --bactopia-path . --pretty
This scans modules/*/tests/main.nf.test for paths matching the input type and returns
pre-computed template variables. Always use the discovered paths -- never construct test
data paths manually. The output includes test_data_path (compressed, for subworkflow
tests), test_uncompressed_path (for module tests), test_species, and test_sample_id.
Supported input types: assembly, reads, assembly_reads, proteins, gff, genbank.
1---2name: add-subworkflow3description: Scaffold a new Bactopia subworkflow that orchestrates existing modules. Creates main.nf with GroovyDoc and test files. Use when asked to add a new subworkflow, create a subworkflow, or wire up modules into a subworkflow.4---56# Add Subworkflow78Scaffold a Bactopia subworkflow that orchestrates one or more existing modules. Subworkflows are glue -- they wire modules together, aggregate results, and provide a clean interface for workflows.910## Prerequisites1112- The module(s) this subworkflow will use must already exist under `modules/`13- Read `.agents/docs/standards/04-subworkflow-documentation.md` for documentation standards1415## Interactive Questioning1617This skill is interactive -- ask the user early and often, especially before creating files.1819- **Multiple questions at once:** Use `AskUserQuestion` popups (up to 4 questions per batch).20 Mark the recommended option with "(Recommended)" at the end of its label and place it first.21- **Single simple question:** Just ask in chat, no popup needed.22- **When in doubt:** Ask. It's cheaper to clarify upfront than to regenerate files.2324## What a Subworkflow Contains2526A subworkflow is a single `main.nf` file plus tests:2728```29subworkflows/{tool}/30 main.nf # Workflow definition with GroovyDoc31 tests/32 main.nf.test # nf-test specification33 main.nf.test.snap # Snapshot (generated by nf-test)34 nextflow.config # Includes ALL module.configs used by this subworkflow35 nf-test.config # Standard nf-test config36 .nftignore # Exclude unstable files from snapshots37```3839**No module.config or schema.json** -- those belong to modules only.4041## Phased Workflow4243### Phase 1: Gather Information4445**Goal:** Determine which modules to orchestrate and how, using interactive prompts.4647**Important:** Use the `AskUserQuestion` tool for structured choices throughout this phase.48Present up to 4 questions per batch. Mark the recommended option with "(Recommended)"49at the end of its label and place it first in the options list.50511. **Ask the user which modules this subworkflow uses.** Get the module paths (e.g., `modules/nohuman/run`, `modules/mlst`).52 - Read each module's `main.nf` to understand its inputs and outputs.53 - **Does it call other subworkflows?** If so, use `@subworkflows` tag (not `@modules`) for those includes.54552. **Run the lookup command** if package info is needed:56 ```bash57 bash .agents/skills/add-bactopia-tool/scripts/run-bactopia-scaffold.sh lookup {package_name} --bactopia-path . --pretty58 ```59603. **Determine the input type** from the primary module's inputs, then **run test-data discovery**:61 ```bash62 bash .agents/skills/add-bactopia-tool/scripts/run-bactopia-scaffold.sh test-data --input-type {input_type} --bactopia-path . --pretty63 ```64 This returns species/accession combinations already used by similar modules, with65 pre-computed `test_data_path`, `test_uncompressed_path`, `test_species`, and66 `test_sample_id` values. Use the returned paths directly in the scaffold config67 (Phase 2) -- do NOT construct paths manually. Subworkflow tests use the68 **compressed** path (`test_data_path`).69704. **Batch 1: Design choices** (AskUserQuestion, up to 3 questions)7172 **Question 1 -- Aggregation strategy:**73 - CSVTK_CONCAT -- concatenate per-sample tabular output (most common) (Recommended)74 - Dedicated summary module -- tool has its own aggregation command (rare)75 - No aggregation -- tool doesn't produce per-sample tabular output7677 **Question 2 -- Test data species:**78 Present top 3-4 species from the test-data discovery results. Recommend species that79 exercise the tool's functionality. Include the accession in each option's description.8081 **Question 3 -- Aggregation field** (if CSVTK_CONCAT or dedicated_summary selected):82 Which output field should be aggregated? (e.g., `tsv`, `report`, `csv`)83 What format? (`tsv` or `csv`)84855. **Present the following for confirmation** (derive from module `main.nf` and lookup):8687 - **Tool identity**: name (snake_case), display name, one-sentence description88 - **Outputs**: from the primary module's output block (for `@output` GroovyDoc tags)89 - **Citation key** and **keywords** for GroovyDoc90916. **Final confirmation** (AskUserQuestion, 1 question)9293 After presenting the summary, ask:94 - Looks good, proceed to file generation95 - I need to make changes (user provides details via "Other" or notes)9697---9899### Phase 2: File Generation100101**Goal:** Generate the 5 subworkflow files using `bactopia-scaffold`.1021031. Construct the JSON config from the design decisions. Write it to `/tmp/scaffold-config.json`:104105 ```json106 {107 "tool": "{tool_name}",108 "display_name": "{DisplayName}",109 "description": "{One-sentence description}",110 "process_name": "{TOOL_NAME}",111 "package": "{package_name}",112 "version": "{version}",113 "build": "{build}",114 "home_url": "{github_url}",115 "input_type": "assembly",116 "has_database": false,117 "handles_gz": false,118 "layout": "flat",119 "resource_label": "process_low",120 "version_command": "{version_command}",121 "citation_key": "{citation_key}",122 "keywords": ["{keyword1}", "{keyword2}"],123 "aggregation": {124 "strategy": "csvtk_concat",125 "field": "{output_field}",126 "format": "{tsv|csv}"127 },128 "outputs": [129 {"name": "{field}", "extension": "{ext}", "description": "{desc}"}130 ],131 "parameters": [],132 "container_refs": {133 "toolName": "{from lookup}",134 "docker": "{from lookup}",135 "image": "{from lookup}"136 },137 "test_species": "{species}",138 "test_sample_id": "{sample_id}",139 "test_data_path": "{compressed_path}",140 "test_uncompressed_path": "{uncompressed_path}"141 }142 ```143144 For database-dependent subworkflows, also include:145 ```json146 {147 "database": {148 "param_name": "{tool}_db",149 "test_path": "datasets/{tool}/{db_file}"150 }151 }152 ```1531542. Run the scaffold command:155 ```bash156 bash .agents/skills/add-bactopia-tool/scripts/run-bactopia-scaffold.sh subworkflow --config /tmp/scaffold-config.json --bactopia-path . --pretty157 ```1581593. The command creates 5 files:160 - `subworkflows/{tool}/main.nf`161 - `subworkflows/{tool}/tests/main.nf.test`162 - `subworkflows/{tool}/tests/nextflow.config`163 - `subworkflows/{tool}/tests/nf-test.config`164 - `subworkflows/{tool}/tests/.nftignore`165166---167168### Phase 3: Review & Customize169170**Goal:** Review generated files and make tool-specific adjustments.1711721. **Subworkflow `main.nf`** -- review and customize:173 - The `@input` GroovyDoc should match the subworkflow's take channel name174 - For the CSVTK_CONCAT pattern, verify the gather field and format are correct175 - If the subworkflow uses modules not in the standard pattern (e.g., calls other subworkflows), add the appropriate `@subworkflows` tag and adjust includes176 - The `@modules` tag should use underscore-delimited directory keys: `csvtk_concat`, `{tool}`1771782. **Test `nextflow.config`** -- verify it includes ALL module.configs for processes in the subworkflow:179 - The primary module's config180 - `csvtk/concat/module.config` if using CSVTK_CONCAT181 - Any other module configs1821833. **Test `main.nf.test`** -- verify:184 - Test data paths match the species/sample chosen185 - Database input lines are present if needed186 - Snapshot fields include the right output field names1871884. **Run the linter** to catch structural issues before proceeding:189 ```bash190 bash .agents/skills/add-bactopia-tool/scripts/run-bactopia-lint.sh {tool} --bactopia-path .191 ```192 This runs `bactopia-lint` scoped to the new subworkflow (and module if it exists).193 Fix any FAILs before moving on. Common issues:194 - S011: misaligned include braces in subworkflow195 - S019: citation key not found in `data/citations.yml`1961975. **Update `data/citations.yml`** -- add the tool citation entry in alphabetical order198 (if not already present from a prior `/add-module` run):199 ```yaml200 {tool}:201 name: "{ToolName}"202 link: "{github_url}"203 description: "{One-sentence description}"204 cite: "{Full citation text}"205 ```2062076. **List all created files** with full paths.2082097. **Remind the user** to run these follow-up steps in order:210 1. `/run-tests {tool} subworkflow --generate` -- generate snapshots and verify the subworkflow test passes (new subworkflows have no existing snapshots)211 2. The subworkflow needs a workflow entry point to be usable -- use `/add-bactopia-tool` if this is a standalone bactopia-tool212213 The `--generate` flag is required because newly scaffolded subworkflows have no214 snapshot files yet. Without it, nf-test will fail immediately on missing215 snapshots.216217---218219## Subworkflow Patterns220221The scaffold generates one of three patterns based on the `aggregation.strategy`:222223| Strategy | Pattern | Include | Emit |224|----------|---------|---------|------|225| `csvtk_concat` | CSVTK_CONCAT aggregation | `gatherCsvtk` from plugin | `sample_outputs` + `run_outputs` |226| `dedicated_summary` | Tool's own summary command | `gatherFields` from plugin | `sample_outputs` + `run_outputs` |227| `none` | No aggregation | No plugin | `sample_outputs` + `Channel.empty()` |228229**CSVTK_CONCAT** is the default and most common (~80% of subworkflows).230231## Edge Cases2322331. **Multi-module subworkflows** (e.g., snippy + snpdists + gubbins): The scaffold generates a single-module pattern. For complex orchestration, generate the scaffold then manually adjust the includes and channel wiring.2342352. **Composite subworkflows** that call other subworkflows: Add `@subworkflows` tag manually and adjust includes to point to `../../subworkflows/{name}/main` instead of `../../modules/{name}/main`.236237## Test Data Discovery238239Test data paths are discovered dynamically from existing module tests using:240```bash241bash .agents/skills/add-bactopia-tool/scripts/run-bactopia-scaffold.sh test-data --input-type {type} --bactopia-path . --pretty242```243244This scans `modules/*/tests/main.nf.test` for paths matching the input type and returns245pre-computed template variables. Always use the discovered paths -- never construct test246data paths manually. The output includes `test_data_path` (compressed, for subworkflow247tests), `test_uncompressed_path` (for module tests), `test_species`, and `test_sample_id`.248249Supported input types: `assembly`, `reads`, `assembly_reads`, `proteins`, `gff`, `genbank`.