@meistrari/workflow-code
v1.0.0
Published
Code-first authoring API and routed tela workflow command implementation for Tela Workflow V3.
Downloads
400
Maintainers
Keywords
Readme
Workflow Code
Code-first authoring API and routed tela workflow command implementation for Tela Workflow V3.
Workflow Code lets you define Tela workflows in TypeScript, keep them in source control, validate them locally or in CI, and sync/publish reviewed workflow versions to Tela.
Install
pnpm add @meistrari/workflow-codeThe package provides:
- library import:
@meistrari/workflow-code - CLI command group:
tela workflow
There is no standalone workflow-code binary; all commands route through @meistrari/tela-cli.
Current MVP status: routed init, compile, and sync behavior exists. tela workflow init is the local project scaffold for Workflow Code: it creates safe starter files/scripts and never contacts Tela APIs. tela workflow create <target> is planned as an explicit remote provisioning command: create the remote workflow first, bind returned identities in config, generate local template files, then sync when possible. tela workflow compile [target] loads Workflow Code config, selects a workflow target by the config workflows map key, evaluates the target entrypoint, and emits an inspectable compiled Workflow V3 payload. It is non-mutating: it does not call Tela APIs, write state, or publish versions. tela workflow sync [target] compiles and consolidates the requested target, or all configured workflow prompts when no target is provided.
Quick start
Initialize a Workflow Code project scaffold:
tela workflow initInit creates workflow-code.config.ts, .env.example, a missing tsconfig.json, a .gitignore entry for dev-context lockfiles, adds @meistrari/workflow-code to devDependencies, and adds missing package.json scripts such as workflow:compile, workflow:codegen, workflow:sync, workflow:publish, workflow:run, and workflow:watch. Existing files and scripts are not overwritten by default; skipped or conflicting scaffold pieces are reported as structured diagnostics.
Pass repeatable --workflow <workflow-key> flags to scaffold workflow targets and source files:
tela workflow init --directory ./workflow-app --workflow invoice-processing --workflow reviewWithout workflow keys, init writes workflows: {} and does not create dangling source files or example targets. Init is interactive by default for target directory, workflow keys, git initialization, and dependency installation. The workflow-key prompt is the interactive abstraction of repeatable --workflow <workflow-key> flags and defaults to no keys; the git and dependency prompts default to no. Use --yes for non-interactive safe defaults: current directory, no workflow keys, no git init, and no dependency install. Use --workflow, --init-git / --no-init-git, --install-deps / --no-install-deps, and --package-manager bun|pnpm|npm|yarn to choose explicitly. When dependency installation is enabled and package.json is missing, init first runs the selected package manager's non-interactive init command, then merges Workflow Code scripts.
Workflow Code loads .env files before evaluating the TypeScript config. Use --env <path> to provide a custom dotenv file for a command.
A generated --workflow document-research source starts minimal:
import { build, workflow } from '@meistrari/workflow-code'
const workflowKey = workflow('document-research')
export default build(workflowKey, {
input: [],
nodes: [],
})Add MVP factories such as input, llm, agent, and code as your workflow grows.
Compile the selected workflow source locally:
tela workflow compiletela workflow compile [target] loads Workflow Code config, selects a workflow target by the config workflows map key, evaluates the target entrypoint, and emits an inspectable compiled Workflow V3 payload. It is non-mutating and offline: it does not require or validate remote projectId/promptId, call Tela APIs, write state, or publish versions. Keep using this positional compile selector.
In this release, compile auto-selects the only configured workflow. When multiple workflows are configured, pass positional target to choose one for compile. sync keeps the same positional target selector, and when omitted it syncs all configured workflows. run requires that positional target:
tela workflow sync
tela workflow sync invoice-processing
tela workflow publish invoice-processing
tela workflow run invoice-processingsync is implemented for configured prompts. Commands outside init, compile, and sync are unavailable in this release.
Sync
tela workflow sync [target] compiles Workflow Code targets and writes them to configured Tela prompts through the prompt-version lifecycle API. With target, sync runs only that configured workflow. Without target, sync runs every configured workflow. Sync requires an existing promptId in each active context binding or legacy target config.
Sync does not publish. It creates or replays a consolidated prompt version through POST /prompt-version/:id/edit, verifies the exact returned version with GET /prompt-version/:id, and records the result in .tela/workflows/<workflowKey>/contexts/<context>/lock.json.
If the remote prompt version changed since the last successful sync, the CLI asks:
Remote changed since last sync. Last sync version: v3 / Current version: v5. Continue and consolidate new version v6?Pass --yes to continue non-interactively. Without --yes in a non-interactive environment, sync fails before mutation.
Authoring model
A workflow source file exports one built declaration:
export default build(invoiceWorkflow, {
inputs: [document],
nodes: [extract, research],
})Workflow Code infers graph topology from ordered node arrays. You do not author raw Workflow V3 edge objects, endpoint pairs, edge IDs, or ports.
Rules:
- adjacent top-level
llm(),agent(), andcode()nodes run sequentially in the MVP - map bodies, condition cases, branch convergence, and
stop()placement are planned compiler features outside the implemented MVP subset
Inputs
const topic = input.text({ name: 'topic', required: true })
const document = input.file({
name: 'document',
required: true,
})Workflow input references compile to stable Workflow V3 input URI references. Run inputs use the author-facing input names you declared in source.
Modules
Implemented MVP Workflow Code module factories:
llm()agent()code()
Planned module factories outside the implemented MVP subset:
cropper()splitter()canvas()template()map()condition()stop()
Implemented module factories return typed node handles that can be placed in top-level nodes arrays and referenced by later modules. code() nodes capture a TypeScript handler for later Workflow runtime execution: local compile evaluates trusted declaration files, but does not call the handler. Instead, compile extracts supported handler source and source-visible closure dependencies, preserves supported package imports, merges default/inferred/user libraries, and emits generated code for the sandbox. Keep extracted handler/helper/type names away from generated runtime names such as execute, __workflowFn, and TelaInput; those names are reserved inside the generated code bundle.
References
Reference-capable fields receive target-scoped helpers:
const summarize = llm({
name: 'Summarize invoice',
input: {
prompt: ({ ref, paths }) =>
`Summarize ${ref(extract, paths(extract).invoiceNumber)}`,
},
})Use supported MVP refs with input and previous-node handles instead of raw IDs or hand-written URI strings. Supported forms are ref(input), ref(previousNode), ref(previousNode, paths(previousNode).field), and field-compatible format keys from Tela's English labels, such as .formats().parser, .formats().multimodal, or .formats().string.
Planned map example
const pages = splitter({
name: 'Split document pages',
input: {
file: ({ ref }) => ref(document).formats().parsed,
},
})
const extractPage = llm({
name: 'Extract page data',
input: {
prompt: ({ ref }) => `Extract line items from ${ref(pages).formats().parser}`,
},
})
const loopPages = map({
name: 'Loop pages',
input: {
over: ({ ref, paths }) => ref(pages, paths(pages).documents),
mapVariable: 'page',
},
nodes: [extractPage],
})Planned condition example
const route = condition({
name: 'Route invoice',
input: {
cases: {
approved: {
when: ({ ref, paths }) =>
ref(extract, paths(extract).total).lessThan(10_000),
nodes: [autoApprove],
},
default: [requestReview],
},
},
})
export default build(invoiceWorkflow, {
inputs: [document],
nodes: [extract, route, notifyRequester],
})notifyRequester runs after each non-terminating branch. If a branch ends with stop(), that branch is terminal.
CLI commands
Target command surface:
tela workflow init [--directory path] [--config path] [--workflow key...] [--yes] [--init-git|--no-init-git] [--install-deps|--no-install-deps] [--package-manager bun|pnpm|npm|yarn]
tela workflow create <target>
tela workflow codegen [target] [--dynamic] [--env path]
tela workflow compile [target] [--config path] [--env path] [--json]
tela workflow sync [target] [--config path] [--env path] [--yes] [--json]
tela workflow publish [target] [--env path] [--json]
tela workflow run <target> --input name=value [--env path] [--follow]
tela workflow watch [target] [--env path]init
Scaffolds a local Workflow Code project. Init creates the target directory when it does not exist; --directory <path> selects it and defaults to .. Init creates workflow-code.config.ts, .env.example, a missing tsconfig.json, a .gitignore entry for .tela/workflows/*/contexts/dev/lock.json, adds @meistrari/workflow-code to devDependencies, and adds missing package.json Workflow Code scripts inside that directory. Generated config references ./tsconfig.json, uses outDir: '.tela/workflows', and writes workflows: {} unless one or more --workflow <workflow-key> flags are passed or interactive workflow keys are entered.
Each --workflow <workflow-key> adds a config target and src/workflows/<workflow-key>.workflow.ts source file. Generated workflow source imports only from @meistrari/workflow-code, declares const workflowKey = workflow('<workflow-key>'), and default exports build(workflowKey, { input: [], nodes: [] }).
Init is interactive by default for target directory, workflow keys, git initialization, and dependency installation when a terminal prompt is available; the directory prompt runs first and defaults to ., then the workflow-key prompt accepts comma- or space-separated keys and defaults to none. The git and dependency prompts default to no. --yes runs non-interactively with safe defaults: current directory, no workflow keys, no git initialization, and no dependency installation. Use --directory <path>, repeatable --workflow <key>, --init-git / --no-init-git, --install-deps / --no-install-deps, and --package-manager bun|pnpm|npm|yarn to choose explicitly; Bun is the default package manager when installation is requested. If installation is enabled and package.json is missing, init runs the selected package manager's non-interactive init command before dependency installation.
Init never contacts Tela APIs, creates remote resources, writes lockfiles, creates generated artifacts, prints env values, or uses Workflow Code-specific auth/token storage. Existing config, workflow source, env files, tsconfig.json, .gitignore content, and package scripts are not overwritten by default; init reports skipped/conflicting paths and scripts and continues creating other non-conflicting pieces where safe. --json reports diagnostics plus written and skipped paths.
create
Creates a new remote Tela workflow, records the returned remote identity in workflow-code.config.ts, scaffolds template directories/source files for the new workflow target, and syncs when possible.
Order:
- Create workflow remotely in the selected Tela project/context.
- Add the remote identity data to
workflow-code.config.tsunder the newworkflows[target]entry. - Generate template directories and source files for the new workflow.
- If compile/sync preconditions are available, run sync so the remote workflow has a version matching local source.
Create is explicit remote provisioning and does not run as part of init. It preserves existing files/config entries by default, reports conflicts as diagnostics, and does not publish by default.
codegen
Generates TypeScript authoring support. Planned multi-target codegen may run for every configured workflow; current command selection should pass positional target when multiple workflows are configured. Offline generation uses local workflow source only. Dynamic generation enriches types with Tela metadata such as template variables, canvas variables, model IDs, tools, and remote output schemas.
Dynamic codegen uses each selected workflow's active Tela Local context binding and persists fetched remote content in .tela/workflows/{workflowKey}/contexts/{contextKey}/lock.json. If dynamic codegen runs without auth and a context lockfile already exists, it may reuse the persisted snapshot but must report the snapshot timestamp.
Planned generated metadata exposes remote() catalogs for canvases, workflows, templates, LLM models, Agent models, Agent skills, and Agent Tela tools. Generated name paths are locked to stable remote IDs/refs so sync/codegen can warn on title changes and fail rather than silently rebinding a path to a different resource. Vault helpers are independent: vault.asset() declares local upload dependencies for sync, and vault.ref() represents existing vault://... refs.
compile
tela workflow compile [target] loads Workflow Code config, selects a workflow target by the config workflows map key, evaluates the target entrypoint, and emits an inspectable compiled Workflow V3 payload. It is non-mutating: it does not call Tela APIs, write state, or publish versions.
Config loading evaluates workflow-code.config.ts after loading default .env files and any custom file passed with --env <path>. The --env flag is for dotenv files only; active Tela context selection remains owned by Tela Local auth/context state.
Source evaluation trust and reproducibility model
Workflow Code source evaluation is a local build step for trusted repositories. The workflow source files, local imports inside the source root, and installed npm packages imported while building declarations are trusted code. External package imports are loaded with Node createRequire() so package top-level code can run in the local compile process before exports are wrapped for VM use. Do not compile untrusted workflow source or untrusted installed dependencies.
For package reproducibility, the source hash records the exact installed package name/version and the package package.json snapshot. The reproducibility unit is the exact package version resolved from the lockfile/package manager, not arbitrary mutable local edits to files under node_modules at the same version. Use a clean install from a reviewed lockfile when reproducing a compile.
sync
Compiles local source and creates a consolidated Tela version through the API lifecycle contract. Without positional target, sync runs every configured workflow; pass target to sync only one workflow. Sync uses idempotency keys so retries are safe. Remote commands resolve the active Tela Local context through @meistrari/tela-local-config and select the matching contexts[...] binding from config for projectId and promptId.
Sync reads and writes one per-context lockfile per selected workflow at .tela/workflows/{workflowKey}/contexts/{contextKey}/lock.json. The lockfile records the selected context identity, last synced version, hashes, and the latest remote content snapshot used to detect remote divergence.
publish
Publishes Tela version(s) that match local compiled source. Planned multi-target publish may run for every configured workflow; current command selection should pass positional target when multiple workflows are configured. If no matching consolidated version exists for a selected workflow, publish syncs that workflow first.
run
Runs synced workflow version selected by required positional target. Text inputs accept strings. File inputs accept local paths or supported remote file references; local files are uploaded before the run starts.
watch
Watches local workflow files, recompiles on change, and syncs through the same lifecycle path as sync. Planned multi-target watch may cover every configured workflow; current command selection should pass positional target when multiple workflows are configured. Each watch cycle refreshes and persists remote content in the same active-context lockfile, so changing Tela contexts never reuses another context's remote state.
CI example
pnpm install --frozen-lockfile
tela workflow codegen
tela workflow compile invoice-processing --json
tela workflow sync --json
tela workflow publish --jsonUse authenticated commands only in trusted CI environments with Tela credentials configured.
Development in this repository
pnpm --filter @meistrari/workflow-code run typecheck
pnpm --filter @meistrari/workflow-code run test
pnpm --filter @meistrari/workflow-code run build
node apps/tela-cli/dist/index.js workflow helpWorkflow V3 graph/reference/lifecycle/action schema contracts, action IDs, and reference URI formatting are consumed from @meistrari/workflow-shared.
Implementation docs for contributors and agents live in ../../docs/workflow-code/README.md, including the generated metadata documentation suite starting at ../../docs/workflow-code/generated-metadata.md.
