This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is a Node-RED extension providing custom nodes for interacting with the Seqera Platform API. Users install this package in Node-RED to build automation workflows that launch, monitor, and manage Nextflow pipelines on Seqera Platform.
Key package details:
- Package name:
@seqera/node-red-seqera - Published to npm and distributed via Node-RED's palette manager
- Also available as Docker images:
ghcr.io/seqeralabs/node-red-seqera(base) andghcr.io/seqeralabs/node-red-seqera-studios(Seqera Studios)
# Install dependencies
npm install
# Run tests
npm test
# Run tests with coverage
npm run test:coverage
# Linting (uses pre-commit hooks)
pre-commit run --all-files
# No build step required - Node-RED loads .js files directly
# To test locally, install in your Node-RED user directory:
cd ~/.node-red
npm install /path/to/this/repoAll nodes follow a standard Node-RED registration pattern:
- Module export function receives
REDruntime object - Node constructor function receives config from editor and calls
RED.nodes.createNode(this, config) - Registration via
RED.nodes.registerType(type, constructor, options) - HTML counterpart (same filename but
.html) defines editor UI, help text, and default values
All Seqera nodes depend on a seqera-config node that stores:
- Base URL (default:
https://api.cloud.seqera.io) - API token (stored in credentials)
- Workspace ID
This config is referenced via node.seqeraConfig = RED.nodes.getNode(config.seqera).
nodes/_utils.js - Core API helpers:
buildHeaders(node, extraHeaders)- Constructs headers with Bearer token from seqera-configapiCall(node, method, url, options)- Axios wrapper that merges auth headers, logs failures, and re-throws errorshandleDatalinkAutoComplete(RED, req, res)- HTTP endpoint handler for Data Link name autocomplete (used by datalink-list and datalink-poll nodes)
nodes/datalink-utils.js - Data Link specific utilities:
evalProp(RED, node, msg, value, type)- Property evaluation helper supporting JSONata expressionsresolveDataLink(RED, node, msg, dataLinkName, options)- Resolves Data Link by name, returns IDs and metadatalistDataLink(RED, node, msg)- Core implementation for listing files/folders from Data Links with filtering and recursion
Nodes use Node-RED's typedInput system allowing properties to be:
- Static strings (
str) - Message properties (
msg) - JSONata expressions (
jsonata) - Flow/global context
- JSON literals
Evaluation helper (present in most nodes):
const evalProp = async (p, t, msg) => {
if (t === "jsonata") {
const expr = RED.util.prepareJSONataExpression(p, node);
return await new Promise((resolve, reject) => {
RED.util.evaluateJSONataExpression(expr, msg, (err, value) => {
if (err) return reject(err);
resolve(value);
});
});
}
return RED.util.evaluateNodeProperty(p, t, node, msg);
};Always evaluate properties inside the node.on("input", ...) handler so they reflect current message context.
All nodes preserve unrecognized input message properties in their output.
This is implemented using the spread operator pattern:
const outputMsg = {
...msg, // Spreads all input properties first
payload: response.data, // Then overwrites specific properties
workflowId: workflowId,
// etc.
};
send(outputMsg);Key behaviors:
- Any custom properties on the input
msgobject (e.g.,msg._context,msg.customId,msg.correlationId) are automatically copied to the output - Node-specific properties (like
payload,workflowId,datasetId,studioId) are set/overwritten as documented - This enables flow-wide context tracking and message correlation without modifying node code
- Works for all node types including monitor nodes with multiple outputs (all outputs receive the same passthrough properties)
Common use cases:
msg._context- Preserve context across multiple nodes in a flowmsg.correlationId- Track messages across parallel branchesmsg.userId- Maintain user session information through workflow- Any custom metadata needed for flow logic or debugging
- Launches pipelines via
/workflow/launchendpoint - Can resolve launchpad names (fetches pipeline config from
/pipelinesthen/pipelines/{id}/launch) - Supports two methods for providing parameters:
paramsKey(Params JSON): A JSON object that gets merged intolaunch.paramsTextparamsArray(Parameters list): Individual key-value pairs from editable list (highest precedence)
- Sets custom
runNameif provided - Supports resuming workflows via
resumeWorkflowId:- Fetches workflow details from
/workflow/{id}to get commitId - Fetches launch config from
/workflow/{id}/launchto get sessionId and resumeCommitId - If workflow ran tasks (has commitId), sets
resume: trueand includesrevisionfield - If workflow was cancelled before tasks (no commitId), sets
resume: falseand omitsrevisionfield
- Fetches workflow details from
- Returns
msg.workflowIdfor chaining with monitor node
- Polls workflow status at configurable interval (default 5s)
- Three outputs: Active (yellow), Succeeded (green), Failed (red)
- Stops polling when workflow reaches terminal state or
keepPollingis false - Status mapping:
submitted→ yellow,running→ blue,succeeded→ green,failed→ red,cancelled|unknown→ grey
- Adds dataset via POST
/datasetsthen uploads file via POST/datasets/{id}/upload - Supports CSV/TSV file types with MIME type selection
- Uses
form-datafor multipart upload - Returns
msg.datasetId
- Lists files/folders from Data Explorer links via
/data-linksand/data-browser - Filters by prefix (applied to both files/folders) and pattern (regex, files only)
- Supports recursion depth and max results
- Returns
msg.payload.files(full objects) andmsg.files(string array of paths)
- Automatically polls Data Link at configured intervals (default 15 min)
- Parses frequency as seconds,
MM:SS,HH:MM:SS, orDD-HH:MM:SS - Two outputs: "All results" (every poll) and "New results" (only new files detected)
- Tracks seen files in node context to detect changes
- Adds Seqera Studios via POST
/studios - Configures container, compute environment, resources (CPU/memory/GPU)
- Mounts Data Links specified in
mountDataarray - Returns
msg.studioId
- Polls Studio status at configurable interval (default 5s) with units (seconds/minutes/hours)
- Three outputs: All checks (every poll), Ready (running), Terminated (stopped/errored/buildFailed)
- Stops polling when Studio reaches terminal state or
keepPollingis false - Status mapping:
starting|building|stopping→ yellow,running→ blue,stopped→ green,errored|buildFailed→ red - Output 1 fires every poll
- Output 2 fires only once on transition to
running(not on every poll while running) - uses state transition detection - Output 3 fires on termination
- Tracks
previousStatusto detect state transitions and prevent duplicate ready notifications
Several nodes register HTTP endpoints on Node-RED's admin API for editor features:
GET /admin/seqera/pipelines/:nodeId- Launchpad/pipeline autocomplete for workflow-launchGET /admin/seqera/datalinks/:nodeId- Data Link autocomplete for datalink-list/pollGET /seqera-config/connectivity-check- Test API token validityGET /seqera-config/workspaces- Fetch organizations and workspaces for config UI
These endpoints handle cases where the node doesn't exist yet (during initial config) by extracting config from query params.
Nodes display status in the editor using:
node.status({
fill: "blue|yellow|green|red|grey",
shape: "ring|dot",
text: `status: ${formatDateTime()}`,
});Common pattern:
- Blue ring = in progress
- Yellow ring = intermediate step
- Green dot = success
- Red dot = error
- Grey dot = idle
- Use
node.error(message, msg)to report errors to Node-RED - Use
node.warn(obj)for non-fatal warnings (used inapiCallfor API failures) - Always set status to red dot on error
- Clear polling intervals on error (for monitor/poll nodes)
From README, minimum required roles:
- Launch workflow: Maintain
- Monitor workflow: View
- Add Dataset: Launch
- List/Poll Data Link Files: Maintain
- Add Studio: Maintain
For full automation, use Maintain role token.
Located in examples/ directory. Available via Node-RED's Import > Examples menu. See docs/examples/ for detailed descriptions.
nodes/ - Node implementation files (.js + .html pairs)
_utils.js - Core API helper functions (buildHeaders, apiCall, etc.)
datalink-utils.js - Data Link specific utilities (listDataLink, resolveDataLink)
config.js - Seqera configuration node
workflow-*.js - Workflow launch/monitor nodes
dataset-*.js - Dataset addition node
datalink-*.js - Data Link list/poll nodes
studios-*.js - Studio addition/monitor nodes
test/ - Mocha test files
helper.js - Shared test utilities and mock factories
*_spec.js - Test files for each node
examples/ - Example flows (.json)
docker/ - Dockerfiles and Node-RED config for containers
docs/ - Documentation and images
examples/ - Example flow documentation
- Create paired
.jsand.htmlfiles innodes/ - In
.js: export function receivingRED, define node constructor, register withRED.nodes.registerType - Reference
seqera-confignode vianode.seqeraConfig = RED.nodes.getNode(config.seqera) - Use
apiCallfrom_utils.jsfor all API requests - Implement
evalProphelper for typedInput property evaluation (or import fromdatalink-utils.jsfor Data Link nodes) - Handle
node.on("input", async function(msg, send, done))for message-triggered nodes - Use
node.status()to update visual state in editor - Register node in package.json under
node-red.nodes - Create corresponding HTML with
<script type="text/html" data-template-name="...">for editor UI - Add tests in
test/<node-name>_spec.jsusing shared helpers fromtest/helper.js