
Ffcpe Custom Node Sdk
- 59 installs
- Updated June 1, 2026
- adobe/ffcpe-custom-node-sdk
ffcpe-custom-node-sdk is a Claude Code skill that helps Adobe App Builder developers install and use the ffcpe-custom-node packages to build FFCPE custom actions with a submit/status HTTP contract.
About
This skill helps Adobe App Builder developers build FFCPE custom actions with @adobe/ffcpe-custom-node-core and @adobe/ffcpe-custom-node-app-builder. It covers installing the packages, linking a local SDK checkout, the submit/status HTTP contract, implementing FfcpeNodeWorkerHandler, and handling Text/Image/Video/Json inputs and outputs for run-workflow. Developers use it when wiring or debugging a custom-action App Builder app that Workflow Builder invokes.
- Install and local-linking guide for the FFCPE custom-node SDK packages
- Covers the submit/status HTTP contract, worker handler, and Text/Image/Video/Json inputs
- Includes a Console-project bootstrap checklist for new App Builder projects
Ffcpe Custom Node Sdk by the numbers
- 59 all-time installs (skills.sh)
- Ranked #3,167 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Jul 28, 2026 (Skillselion catalog sync)
ffcpe-custom-node-sdk capabilities & compatibility
Free skill; needs an Adobe App Builder / Adobe I/O account to deploy and register actions
- Capabilities
- api development · sdk integration · openwhisk actions
- Use cases
- api development · devops
- Pricing
- Free
What ffcpe-custom-node-sdk says it does
Use this skill when assisting **consumers** of the NPM packages: teams shipping an App Builder application that Workflow Builder invokes as a **`custom-action`** (async submit + status polling).
npm install @adobe/ffcpe-custom-node-core @adobe/ffcpe-custom-node-app-builder
**Validate and register** with the CLI — never raw curl:
npx skills add https://github.com/adobe/ffcpe-custom-node-sdk --skill ffcpe-custom-node-sdkAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 59 |
|---|---|
| Last updated | June 1, 2026 |
| Repository | adobe/ffcpe-custom-node-sdk ↗ |
What it does
Install, link, and wire the FFCPE custom-node SDK packages to build an App Builder custom-action app with submit/status polling.
Who is it for?
Consumers of the FFCPE npm packages shipping an App Builder application that Workflow Builder invokes as a custom-action.
Skip if: Contributing to the SDK source monorepo (see README/CONTRIBUTING) or authoring catalog-entry.json and running aio ffcpe catalog.
When should I use this skill?
Wiring a custom-action app in App Builder, implementing FfcpeNodeWorkerHandler, debugging submit/statusUrl polling, or handling Text/Image/Video/Json inputs.
What you get
A correctly installed and linked FFCPE App Builder app with a worker handler and submit/status routes ready to register via the catalog CLI.
- Installed FFCPE SDK packages
- A worker handler implementation
- Registered custom-action via aio ffcpe catalog register
By the numbers
- Requires two npm packages: core and app-builder
- Register actions via 'aio ffcpe catalog register', never raw curl
Files
FFCPE custom actions on App Builder (@adobe/ffcpe-custom-node-core, @adobe/ffcpe-custom-node-app-builder)
Audience
Use this skill when assisting consumers of the NPM packages: teams shipping an App Builder application that Workflow Builder invokes as a `custom-action` (async submit + status polling).
For contributing to the SDK source repository (monorepo, Turbo, releases), see `README.md` (“Monorepo (contributors)”) and `CONTRIBUTING.md` next to the SDK sources (internal mirror or published repo checkout).
For scaffolding web/worker files, webpack, and `ext.config.yaml`, use `ffcpe-app-builder-actions`.
For `catalog-entry.json` authoring and `aio ffcpe catalog` (validate, register, list, update), install skills from [adobe/aio-cli-plugin-ffcpe](https://github.com/adobe/aio-cli-plugin-ffcpe): `ffcpe-catalog-entry-json` and `aio-ffcpe-cli`.
npx skills add adobe/aio-cli-plugin-ffcpe --all -yEnd-to-end checklist
0. Bootstrap Console project (new projects only) — create project + workspace via aio console, run aio app init --standalone-app, download workspace config, wire with aio app use <config>.json --overwrite --no-input. Clean up web-src/, scaffolded generic actions, and web: web-src from app.config.yaml. Replace webpack-config.js with the esbuild-loader + commonjs2 shape. Console project names: alphanumeric only, ≤20 chars (no hyphens); may differ from the OpenWhisk package name in YAML. See `ffcpe-app-builder-actions` → "Starting from scratch with init-bare" for the exact sequence. 1. Install SDK packages (npm or pnpm) and implement web + worker actions. Best practice: co-locate the catalog entry as `<action-name>.entry.json` next to *`<action-name>.web.** and **<action-name>.worker.` (see `ffcpe-app-builder-actions`). 2. Deploy the App Builder app; copy web action base URLs from deploy output; set catalog `submitEndpoint` / `statusEndpoint` to `{base}/submit` and `{base}/status`. 3. Author `<action-name>.entry.json` — ports must match worker input/output names; endpoints from deploy; `authentication: { "type": "ims_service_token" }` when using default `mountFfcpeNodeRoutes` auth (not `none` unless `authenticate: null` on routes). 4. Validate and register* with the CLI — never raw curl:
aio ffcpe catalog validate --file ./actions/my-action/my-action.entry.json
aio ffcpe catalog register --file ./actions/my-action/my-action.entry.jsonInstall packages
with npm:
npm install @adobe/ffcpe-custom-node-core @adobe/ffcpe-custom-node-app-builderor pnpm — set `auto-install-peers=true` in the app’s `.npmrc`, then:
pnpm add @adobe/ffcpe-custom-node-core @adobe/ffcpe-custom-node-app-builderExplicit peers — if you prefer every peer in `package.json`, or your tool does not auto-install peers (e.g. Yarn Classic):
npm install @adobe/ffcpe-custom-node-core @adobe/ffcpe-custom-node-app-builder hono hono-openwhisk-adapterpnpm add @adobe/ffcpe-custom-node-core @adobe/ffcpe-custom-node-app-builder hono hono-openwhisk-adapterTypical peers (confirm versions against your template and Adobe docs):
@adobe/aio-lib-core-logging,@adobe/aio-lib-state,@adobe/aio-lib-ims,openwhisk,hono,hono-openwhisk-adapter
Link a local SDK checkout
Use this when the consumer app should load `@adobe/ffcpe-custom-node-core` / `@adobe/ffcpe-custom-node-app-builder` from a nearby clone of the SDK monorepo instead of the registry.
1. In the SDK monorepo, install and build `dist/` for both packages:
pnpm install && pnpm run build
# or: npm install && npm run buildFor tight iteration, run `pnpm run dev` (or `npm run dev`) from the SDK root so `dist/` rebuilds on change.
2. In the consumer App Builder project, link core first, then app-builder:
pnpm:
pnpm link /path/to/ffcpe-custom-node-sdk/packages/core
pnpm link /path/to/ffcpe-custom-node-sdk/packages/app-buildernpm:
npm link /path/to/ffcpe-custom-node-sdk/packages/core
npm link /path/to/ffcpe-custom-node-sdk/packages/app-builder3. To restore registry packages:
pnpm unlink @adobe/ffcpe-custom-node-core @adobe/ffcpe-custom-node-app-builder && pnpm install
# or: npm unlink @adobe/ffcpe-custom-node-core @adobe/ffcpe-custom-node-app-builder && npm installOptional global link (pnpm): register each package with `pnpm link --global` from `packages/core` and `packages/app-builder`, then in the consumer `pnpm link --global @adobe/ffcpe-custom-node-core` and `pnpm link --global @adobe/ffcpe-custom-node-app-builder`. If *`workspace:** fails to resolve for app-builder, keep using directory links or add a consumer **pnpm.overrides** pinning **@adobe/ffcpe-custom-node-core** to the **packages/core`** path.
Full wording lives in the SDK `README.md` (“Use a local SDK checkout”).
Install agent skills
Skills live in the SDK repo under `skills/` and install via the open agent skills CLI. One canonical copy is symlinked into each agent (Claude Code, Cursor, etc.) so guidance stays identical.
From GitHub (consumer repo)
# List available skills
npx skills add adobe/ffcpe-custom-node-sdk --list
# Install all FFCPE skills (project-local)
npx skills add adobe/ffcpe-custom-node-sdk --all -y
# Install only this skill
npx skills add adobe/ffcpe-custom-node-sdk --skill ffcpe-custom-node-sdk -y
# Claude Code + Cursor
npx skills add adobe/ffcpe-custom-node-sdk --all -a claude-code -a cursor -y
# Global (all projects on this machine)
npx skills add adobe/ffcpe-custom-node-sdk --all -g -yFrom a local SDK checkout
npx skills add /path/to/ffcpe-custom-node-sdk/skills --all -ySee `skills/README.md` in this repo for update/remove commands and skill layout.
CLI plugin skills (separate repo):
npx skills add adobe/aio-cli-plugin-ffcpe --all -yReference skills by `name` in each `SKILL.md` frontmatter: `ffcpe-custom-node-sdk`, `ffcpe-app-builder-actions`, `aio-ffcpe-cli`, `ffcpe-catalog-entry-json`.
Catalog CLI (@adobe/aio-cli-plugin-ffcpe)
Install the Adobe I/O CLI plugin for catalog operations after deploy:
npm install -g @adobe/aio-cli
aio plugins:install @adobe/aio-cli-plugin-ffcpe
aio login
aio console org select| Command | Purpose |
|---|---|
| `aio ffcpe catalog validate -f ./actions/<action-name>/<action-name>.entry.json` | Local JSON validation (no API call) |
| `aio ffcpe catalog register -f ./actions/<action-name>/<action-name>.entry.json` | Register a new custom action |
| `aio ffcpe catalog inspect ACTIONTYPE` | Fetch one entry |
| `aio ffcpe catalog list` | List custom actions (add `--include-core` for Adobe built-ins) |
| `aio ffcpe catalog update ACTIONTYPE -f …` | Full PUT replace |
| `aio ffcpe catalog disable` / `enable` / `delete` | Lifecycle |
Use `--strict` on register/update to fail on validation warnings. Override API host with `AIO_FFCPE_CATALOG_BASE_URL` or `--base-url`. Prefer `aio ffcpe catalog` over hand-written HTTP — auth uses the same IMS session as `aio login`.
Align `customActionConfig.submitEndpoint` / `statusEndpoint` in catalog JSON with your deployed web action URLs and route paths from `mountFfcpeNodeRoutes`. Port `name` values in catalog `inputs` / `outputs` must match what the worker reads via `getTextInput`, `getImageInput`, etc.
Two OpenWhisk actions (recommended shape)
1. Web action — HTTP entry for FFCPE: `POST /submit`, `GET /status`. Build a Hono app, call `mountFfcpeNodeRoutes`, export `main` with `ToOpenWhiskAction` from hono-openwhisk-adapter. 2. Worker action — Long-running job: export `main` from `createFfcpeNodeWorker(handler, options)`.
Use `ext.config.yaml` (or equivalent) so the web action uses `web: "raw"` and `annotations.require-adobe-auth: false` (see `README.md` manifest example). Match `worker` / `web` package and action names to what `mountFfcpeNodeRoutes` receives.
Web route wiring (mountFfcpeNodeRoutes)
- Pass `worker: { package, name }` — target for async OpenWhisk invoke after submit.
- Pass `web: { package, name }` — required; used to build `statusUrl` returned to Workflow Builder. Omitting or empty strings throws at mount time.
- Optional `routes` — defaults `/submit` and `/status`; align with catalog `submitEndpoint` / `statusEndpoint` paths.
- Optional `authenticate` — defaults to IMS bearer +
x-api-keyvia `createImsInboundAuth`. Pass `null` to disable auth on those routes (only if product/security allows). - Optional `jobStore`, `loggerName`, `jobMetadata(submit)` — advanced; default store is aio-lib-state-backed.
Worker handler (createFfcpeNodeWorker)
- Implement `FfcpeNodeWorkerHandler`: async `({ jobId, inputs, params, logger, authContext, args })` — `inputs` is the validated FFCPE `input[]`; `params` is workflow parameters from run-workflow (submit `parameters`); `args` is the full worker invocation object (OpenWhisk `main(args)`).
- Return `{ status: "completed", outputs?: ActionOutput[] }` or `{ status: "failed", error: string }`.
- Use `requiredInputNames` in options to fail fast when submit payloads omit named inputs.
- Throw `FfcpeJobFailedError` only when intentionally mapping failures to the SDK’s failed-job behavior (the adapter already maps handler `failed` results).
Prefer `findInputByName`, `getTextInput`, etc., from `@adobe/ffcpe-custom-node-core`, and narrow with `TextInput`, `ImageInput`, `VideoInput`, `JsonInput`. Build outputs with `createTextOutput`, `createImageOutput`, `createVideoOutput`, `createJsonOutput` (and related helpers).
HTTP contract (what Workflow Builder expects)
Workflow Builder POSTs `{ inputs, parameters }` to `submitEndpoint` and polls status until `completed` or `failed`. Submit responses should include `jobId`, `status`, and ideally `statusUrl` for polling.
For header rules, response fields, and polling semantics, read `docs/custom-action-requests.md` from the SDK documentation bundle or source tree (same material ships beside the repo README for maintainers).
Security and robustness (custom-action authors)
- Treat `inputs` and `parameters` as untrusted; validate types, sizes, and URLs before fetching or processing assets.
- Never log tokens, API keys, or raw Authorization headers; keep `Logger` output minimal.
- Use HTTPS asset URLs where possible; fail closed on suspicious schemes or redirects if implementing custom fetch logic outside the SDK.
- Keep auth enabled on submit/status unless there is an explicit, reviewed reason to pass `authenticate: null`.
Advanced / escape hatches
- Core-only HTTP — `handleFfcpeSubmit`, `handleFfcpeStatus`, or `runWorkerJob` when not using Hono (still need `JobStore`, `JobOrchestrator`, `InboundAuth`, status URL builder).
- Custom orchestration or storage — implement core ports (`JobStore`, `JobOrchestrator`) and mirror the checklist in the upstream README section “Implementing for a different Cloud Functions Provider” (same ideas apply when forking adapter behavior).
Quick lookup
For import cheat sheets, `pnpm link`, and troubleshooting (status URL, web manifest), see references/quick-reference.md.
Quick reference — App Builder custom-action apps
Bootstrap (new project from scratch)
| Step | Command | Notes |
|---|---|---|
| Create Console project | aio console project create -n <name> -t "Title" --json | Alphanumeric only, ≤20 chars (no hyphens). Captures id for next steps. |
| Select project | aio console project select <name> | Stage + Production workspaces auto-created |
| Select workspace | aio console workspace select Stage --projectId <id> | Positional arg + --projectId; no --projectName flag |
| Init App Builder project | aio app init -y --no-login --standalone-app --no-install | Run inside your project directory |
| Download workspace config | aio console workspace download [dest.json] | Saves <orgId>-<project>-Stage.json — contains secrets; add to `.gitignore` before `git add` |
| Protect secrets | echo '<orgId>-<project>-Stage.json' >> .gitignore | Generated .gitignore does NOT cover this file; also verify .env* is present |
| Wire local app to Console | aio app use <orgId>-<project>-Stage.json --overwrite --no-input | Use `--overwrite --no-input` when .env already exists from init (avoids interactive hang) |
| Clean up scaffold | rm -rf web-src actions/generic actions/publish-events test e2e | init-bare generates these; a headless FFCPE app doesn't need them |
Fix app.config.yaml | Remove web: web-src line; replace actions with FFCPE web + worker pair(s) | Leaving web: web-src causes the frontend build step to fail |
| Replace webpack-config.js | Full replacement with esbuild-loader + libraryTarget: "commonjs2" | Generated file uses ts-loader and wrong output shape; see `ffcpe-app-builder-actions` skill |
| Install FFCPE packages | npm view @adobe/ffcpe-custom-node-core version then npm install @adobe/ffcpe-custom-node-core@latest @adobe/ffcpe-custom-node-app-builder@latest hono hono-openwhisk-adapter@latest | Always use latest published; do not pin stale ranges (e.g. 0.1.x). Add @adobe/aio-lib-files if workers emit image URLs |
| Build | aio app build | |
| Deploy | aio app deploy | Prints web action base URLs — append /submit and /status for catalog |
| Update catalog JSON | Edit <action-name>.entry.json endpoints from deploy output | See Deployed endpoint URLs below |
| Register catalog | aio console org select then aio ffcpe catalog register -f … | Use `update` if action type already registered |
Console CLI flag gotchas
Commands have inconsistent flag shapes — mismatches throw NonExistentFlagsError:
| Command | Uses |
|---|---|
aio console workspace create | --projectName <name> |
aio console workspace select | positional [NAME_OR_ID] + --projectId <id> |
aio console workspace list | --projectId <id> (not --projectName) |
aio console workspace download | optional positional [DESTINATION] |
Deployed endpoint URLs (catalog)
After `aio app deploy`, web actions print a base URL like:
https://3326322-myproject-stage.adobeioruntime.net/api/v1/web/my-package/my-action-webSet catalog endpoints to:
- `submitEndpoint`:
{base}/submit - `statusEndpoint`:
{base}/status
Notes:
- Path is `/api/v1/web/` (not
/apis/v1/). - Hostname namespace is lowercase (
demoqrffcpe-stage), independent of Console project casing (demoQrFfcpe). - Console project name (alphanumeric, ≤20) can differ from `runtimeManifest` package name (hyphens allowed).
---
Packages
| NPM | Role |
|---|---|
@adobe/ffcpe-custom-node-core | Contract types, input/output helpers, HTTP/runtime primitives, IMS inbound auth helpers |
@adobe/ffcpe-custom-node-app-builder | mountFfcpeNodeRoutes, createFfcpeNodeWorker, aio-lib-state JobStore, OpenWhisk orchestrator, buildStatusUrl, createAioLogger |
Local SDK (pnpm / npm link)
| Step | Command / note |
|---|---|
| Build SDK | From SDK monorepo root: `pnpm run build` or `npm run build` (use `pnpm run dev` / `npm run dev` while iterating). |
| Link into consumer (pnpm) | `pnpm link …/packages/core` then `pnpm link …/packages/app-builder` (core first). |
| Link into consumer (npm) | `npm link …/packages/core` then `npm link …/packages/app-builder` (core first). |
| Unlink | `pnpm unlink …` or `npm unlink …`, then reinstall. |
If global `pnpm link --global` breaks on *`workspace:**, use directory **pnpm link** / **npm link** or **pnpm.overrides** for **@adobe/ffcpe-custom-node-core** → **packages/core** path. Details: SDK **README.md`**.
Custom action file layout (recommended)
Co-locate each action’s web, worker, and catalog entry with the same `<action-name>` prefix:
actions/<action-name>/
<action-name>.web.ts
<action-name>.worker.ts
<action-name>.entry.json ← run-workflow catalog entry (aio ffcpe catalog validate/register)Example: `actions/resize-image/resize-image.entry.json` beside `resize-image.web.ts` and `resize-image.worker.ts`. See `ffcpe-app-builder-actions` and `ffcpe-catalog-entry-json`.
Catalog CLI (@adobe/aio-cli-plugin-ffcpe)
| Step | Command |
|---|---|
| Install Adobe I/O CLI | `npm install -g @adobe/aio-cli` |
| Install FFCPE plugin | `aio plugins:install @adobe/aio-cli-plugin-ffcpe` |
| Auth | `aio login`, `aio console org select` |
| Validate entry | `aio ffcpe catalog validate -f ./actions/<action-name>/<action-name>.entry.json` |
| Register | `aio ffcpe catalog register -f ./actions/<action-name>/<action-name>.entry.json` |
| List / inspect | `aio ffcpe catalog list`, `aio ffcpe catalog inspect ACTIONTYPE` |
Agent skills: `aio-ffcpe-cli`, `ffcpe-catalog-entry-json` — install with `npx skills add adobe/aio-cli-plugin-ffcpe --all -y`. Plugin repo: github.com/adobe/aio-cli-plugin-ffcpe.
Imports (typical)
From `@adobe/ffcpe-custom-node-core`
- Handler types:
FfcpeNodeWorkerHandler,FfcpeNodeWorkerResult,FfcpeInput,TextInput, … - Input helpers:
findInputByName,getTextInput,getImageInput, … - Outputs:
createTextOutput,createImageOutput,createVideoOutput,createJsonOutput, … - Errors:
FfcpeJobFailedError
From `@adobe/ffcpe-custom-node-app-builder`
mountFfcpeNodeRoutes,createFfcpeNodeWorker,buildStatusUrl,createAioLogger(as needed)
From `hono` / `hono-openwhisk-adapter`
Hono,ToOpenWhiskAction(web action export pattern)
mountFfcpeNodeRoutes(app, options) (summary)
| Option | Notes |
|---|---|
worker | { package, name } — OpenWhisk action invoked asynchronously |
web | { package, name } — required for correct `statusUrl` in submit response |
routes | Optional { submit?, status? }; default /submit, /status |
authenticate | Omit → default IMS; null → no auth |
jobStore, loggerName, jobMetadata | Optional overrides |
createFfcpeNodeWorker(handler, options?) (summary)
| Option | Notes |
|---|---|
requiredInputNames | Validates presence of input names after submit JSON is parsed |
jobStore, loggerName | Optional overrides |
Web action manifest (runtimeManifest)
Ensure the web action uses `web: "raw"` and `require-adobe-auth: false`:
my-web-action:
function: actions/my-web-action.ts
web: "raw"
runtime: nodejs:22
annotations:
require-adobe-auth: falseMisconfiguration often surfaces as wrong request/response mapping or broken status URLs.
Troubleshooting
| Symptom | Things to check |
|---|---|
| Workflow Builder never leaves “processing” | `statusUrl` reachable from Adobe infra; GET /status returns processing → completed/failed; auth headers match catalog |
| 401/403 on submit or status | IMS / x-api-key / InboundAuth vs catalog authentication. Default `mountFfcpeNodeRoutes` expects IMS → catalog should use `ims_service_token`, not `none`. Direct curl without auth will fail with Missing required header(s): Authorization, x-api-key — that is expected. |
aio app use hangs or prompts in agent/CI | Pass `--overwrite --no-input` when importing workspace config into a project that already has .env from init |
| Console project create fails | Name must be alphanumeric and ≤20 characters; no hyphens |
| Worker never runs | `worker.package` / `worker.name` match deployed action; OpenWhisk invoke permissions; async invoke errors in logs |
| Missing outputs | Handler returns `completed` with `outputs`; MIME/port/name fields match FFCPE expectations |
| Catalog register fails | Run `aio ffcpe catalog validate -f …`; check HTTPS endpoints, required `relatedActions` / `usage` fields; see `ffcpe-catalog-entry-json` skill |
| Action not in workflow UI | `workflowEnabled: true`, not `disabled`; run `aio ffcpe catalog list --workflow-enabled` |
Contract details
Full submit/status schema and polling behavior: `docs/custom-action-requests.md` in the SDK repo (or published doc mirror).
Related skills
FAQ
Which packages do I install for an FFCPE custom action?
Install @adobe/ffcpe-custom-node-core and @adobe/ffcpe-custom-node-app-builder, with hono declared as a peer.
How do I use a local SDK checkout instead of the registry?
Build dist/ in the SDK monorepo, then link core first and app-builder second in the consumer project; unlink and reinstall to restore registry packages.