Community collection of reusable Puppetflow flows and snippets, distributed through the built-in blueprint store.
0
stars
15
commits
JavaScript
primary language
Sep 4, 2026
updated
Public blueprints collection of Puppetflow flows and snippets, consumed by the in-app store via GitHub.
blueprints/
├── scaffold.js
└── blueprints/
└── [service]/
├── metadata.json # title, namespace, icon, author
├── icon.png # 128×128 px
├── flows/
│ └── [reference].js or [reference].json
└── snippets/
└── [reference].js or [reference].json
salesforce, gmail, linkedin...).js, valid JS identifier (e.g. scrapeProfile)// @title header in each flow/snippet file// @description header in each flow/snippet file{
"title": "My Service",
"namespace": "my_service",
"description": "Short description shown in the store",
"category": "scraping",
"color": "green",
"icon": "icon.png",
"author": {
"name": "Your name",
"homepage": "https://yoursite.com"
}
}
author and color are optional. title, namespace, description, category, and icon are required. namespace must match ^[a-z_][a-z0-9_]*$. category must be one of: auth, scraping, files, notifications, data. color can be one of green, blue, cyan, purple, pink, orange, amber, slate, white, or a custom six-digit hex color such as #ff4d8d.
Every .js file must start with @title and include @description before the code:
// @title Scrape LinkedIn profile data
// @description Extracts public profile details from a LinkedIn page.
// @input profileUrl [string]: "https://www.linkedin.com/in/example"
// @input includePosts [boolean]: true
// @input maxPosts [number]
async function run($page, $input) { ... }
Every Nodal .json flow must contain metadata.title and metadata.description before its graph:
{
"metadata": {
"title": "Scrape LinkedIn profile data",
"description": "Extracts public profile details from a LinkedIn page."
},
"graph": {
"nodes": [],
"edges": []
}
}
Declare flow inputs in the leading comment header with:
// @input name [type]: default
name must be a valid JavaScript identifier.type must be string, number, boolean, array, object, null, channel, mailbox-watcher, or ai-model.string input without a default is imported as ""; other types use null.null input accepts either no default or the explicit null value.${vars.KEY} references are resolved before export, including secret variables available to the user downloading the flow. Resolved values are written to the downloaded file in plaintext.Examples:
// @input username [string]: "john@example.com"
// @input retries [number]: 3
// @input enabled [boolean]: true
// @input tags [array]: ["billing", "monthly"]
// @input options [object]: {"includeArchived": false}
// @input model [ai-model]
// @input password [string]
// @input optionalValue [null]: null
For a Nodal JSON flow, place the same definitions in metadata.inputs:
{
"metadata": {
"title": "Example flow",
"description": "Example Nodal flow.",
"inputs": [
{"name": "username", "type": "string", "default": "john@example.com"},
{"name": "retries", "type": "number", "default": 3},
{"name": "password", "type": "string"},
{"name": "optionalValue", "type": "null", "default": null}
]
},
"graph": {
"nodes": [],
"edges": []
}
}
Library flows and snippets can call another snippet from the same blueprint without knowing its installed ID. Use the snippet's catalog convention:
$$<namespace>_<reference>(...)
namespace is the value from the blueprint's metadata.json.reference is the snippet filename without its extension. It is case-sensitive.For example, blueprints/metabase/snippets/MetabaseLoginCode.js is referenced from another Metabase item with:
await $$metabase_MetabaseLoginCode(username, password);
When imported from the library store, Puppetflow automatically installs the required snippets and replaces symbolic references with their generated IDs. Existing compatible snippets are reused. This resolution also applies to library updates, but not to standalone file imports.
# Validate all blueprints (exit 1 on errors, hook into CI)
npm run validate
# Create a new service
npm run new:service <name>
# Add a flow or snippet to an existing service
npm run new:flow <service> <reference>
npm run new:snippet <service> <reference>
kebab-caseicon.png provided (128×128 px)// ...)npm run validate passes with no errors15 commits
JavaScript
100.0%
Community collection of reusable Puppetflow flows and snippets, distributed through the built-in blueprint store.
0
stars
15
commits
JavaScript
primary language
Sep 4, 2026
updated
Public blueprints collection of Puppetflow flows and snippets, consumed by the in-app store via GitHub.
blueprints/
├── scaffold.js
└── blueprints/
└── [service]/
├── metadata.json # title, namespace, icon, author
├── icon.png # 128×128 px
├── flows/
│ └── [reference].js or [reference].json
└── snippets/
└── [reference].js or [reference].json
salesforce, gmail, linkedin...).js, valid JS identifier (e.g. scrapeProfile)// @title header in each flow/snippet file// @description header in each flow/snippet file{
"title": "My Service",
"namespace": "my_service",
"description": "Short description shown in the store",
"category": "scraping",
"color": "green",
"icon": "icon.png",
"author": {
"name": "Your name",
"homepage": "https://yoursite.com"
}
}
author and color are optional. title, namespace, description, category, and icon are required. namespace must match ^[a-z_][a-z0-9_]*$. category must be one of: auth, scraping, files, notifications, data. color can be one of green, blue, cyan, purple, pink, orange, amber, slate, white, or a custom six-digit hex color such as #ff4d8d.
Every .js file must start with @title and include @description before the code:
// @title Scrape LinkedIn profile data
// @description Extracts public profile details from a LinkedIn page.
// @input profileUrl [string]: "https://www.linkedin.com/in/example"
// @input includePosts [boolean]: true
// @input maxPosts [number]
async function run($page, $input) { ... }
Every Nodal .json flow must contain metadata.title and metadata.description before its graph:
{
"metadata": {
"title": "Scrape LinkedIn profile data",
"description": "Extracts public profile details from a LinkedIn page."
},
"graph": {
"nodes": [],
"edges": []
}
}
Declare flow inputs in the leading comment header with:
// @input name [type]: default
name must be a valid JavaScript identifier.type must be string, number, boolean, array, object, null, channel, mailbox-watcher, or ai-model.string input without a default is imported as ""; other types use null.null input accepts either no default or the explicit null value.${vars.KEY} references are resolved before export, including secret variables available to the user downloading the flow. Resolved values are written to the downloaded file in plaintext.Examples:
// @input username [string]: "john@example.com"
// @input retries [number]: 3
// @input enabled [boolean]: true
// @input tags [array]: ["billing", "monthly"]
// @input options [object]: {"includeArchived": false}
// @input model [ai-model]
// @input password [string]
// @input optionalValue [null]: null
For a Nodal JSON flow, place the same definitions in metadata.inputs:
{
"metadata": {
"title": "Example flow",
"description": "Example Nodal flow.",
"inputs": [
{"name": "username", "type": "string", "default": "john@example.com"},
{"name": "retries", "type": "number", "default": 3},
{"name": "password", "type": "string"},
{"name": "optionalValue", "type": "null", "default": null}
]
},
"graph": {
"nodes": [],
"edges": []
}
}
Library flows and snippets can call another snippet from the same blueprint without knowing its installed ID. Use the snippet's catalog convention:
$$<namespace>_<reference>(...)
namespace is the value from the blueprint's metadata.json.reference is the snippet filename without its extension. It is case-sensitive.For example, blueprints/metabase/snippets/MetabaseLoginCode.js is referenced from another Metabase item with:
await $$metabase_MetabaseLoginCode(username, password);
When imported from the library store, Puppetflow automatically installs the required snippets and replaces symbolic references with their generated IDs. Existing compatible snippets are reused. This resolution also applies to library updates, but not to standalone file imports.
# Validate all blueprints (exit 1 on errors, hook into CI)
npm run validate
# Create a new service
npm run new:service <name>
# Add a flow or snippet to an existing service
npm run new:flow <service> <reference>
npm run new:snippet <service> <reference>
kebab-caseicon.png provided (128×128 px)// ...)npm run validate passes with no errors15 commits
JavaScript
100.0%